mirror of
https://github.com/stablyai/orca.git
synced 2026-09-25 00:02:35 +00:00
98fdbc4adee2b1d5d23cd24ea5d818eebef59691
8
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
71bbab72e1 |
fix(commit-message): keep Windows paths intact in agent command overrides (#14984)
* fix(commit-message): keep Windows paths intact in agent command overrides `tokenizeCustomCommandTemplate` applies POSIX backslash-escape rules on every platform. On Windows `\` is the path separator, so a native absolute path in an agent command override is silently destroyed: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -> C:WindowsSystem32WindowsPowerShellv1.0powershell.exe which is then reported as not found on PATH. The agent *startup* path already routes Windows shells to the Windows tokenizer, but the commit-message AI path still calls the generic tokenizer directly, so overrides, extra CLI args and custom commands there are all affected. The tokenizer gains an explicit `'escape' | 'literal'` mode rather than reading `process.platform`, because the same template can be parsed on one host and executed on another. `'escape'` stays the default, so POSIX behaviour — where `foo\ bar` is deliberately one token — is unchanged. `'literal'` is selected only where the command provably runs on native Windows: a LOCAL target, on win32, with no WSL distro. A WSL target runs a Linux binary inside the distro, and a remote target runs on a host whose platform this process cannot see; both keep POSIX escaping. Fixes #11375 * test: pin the platform decision for literal-backslash parsing commandBackslashMode is the only place that reads the platform, so it is where this can be wrong in the direction that matters — applying Windows rules to a command that will actually run under a POSIX shell. WSL and remote targets are pinned explicitly; both were previously untested. |
||
|
|
e77e1fe850 |
fix(claude): guard cold-restore resume selectors (#13868)
* fix(claude): guard cold-restore resume selectors Persisted Claude default args or a custom command can carry their own --resume/-r/--continue/-c selectors (a bare picker default or a stale id). Cold restore appended the authoritative --resume <id> after them, typing a command with competing selectors into the restored pane (#12982). buildAgentResumeStartupPlan now routes Claude through a selector guard that tokenizes the base with the existing startup tokenizer, strips selectors in option position only (value-taking options keep dash-leading values), and appends exactly one authoritative selector, inserting before Claude's own -- terminator when present. Splicing is span-based so untouched bytes stay verbatim, wrapper commands are left alone, and any tokenization failure falls back to the previous append-only behavior. Launch paths, other agents, persistence, and the wire are unchanged. * fix(claude): harden resume selector guard against false matches Round-1 review findings: locate the claude executable by command position (index 0, after a wrapper --, or behind NAME=value assignments) so an argument merely ending in /claude can never be mistaken for it; stop matching the joined -r<id> form, which was ambiguous with dash-leading option values and forced an unmaintainable arity table (now deleted). Ambiguous shapes degrade to the pre-guard append-only behavior. * fix(claude): fail resume guard open on chained shell syntax Round-2 review findings: an unquoted operator or newline after the claude token means the base chains other commands, and splicing across that boundary handed the selector to the wrong command — detect it and fall back to plain appending. Also recognize claude behind PowerShell's & call operator, decouple the test oracle from the implementation's selector predicate, add Windows tokenizer span tests, and rename the module after its public API. * fix(claude): flag bare shell operators inside the tokenizers Round-3 review findings: the guard's operator scan compared raw source to token value, so one quote or escape anywhere in a token hid a shell-active operator outside the quotes and the splice crossed a live command boundary, losing the resume entirely. Both tokenizers now flag tokens carrying an unquoted, unescaped operator byte (or a word-leading # comment on posix/powershell) on their spans, where quote state actually lives, and the guard fails open on that flag. Also strengthens the redirect fail-open test to carry a stale selector, re-tokenizes each raw span in the shell span tests, and documents agent-resume-argv-drop as codex-only. * fix(claude): flag expansions and clamp separator backoff Round-4 review findings: unquoted multi-token expansions (backtick, $(, ${) split across whitespace, so removing only the recognized selector token left a broken construct tail — both tokenizers now raise the span flag (renamed bareShellSyntax) for those openers, on cmd also for operators between single quotes, which cmd does not treat as quoting. The separator backoff is clamped to the previous token's span end so a token ending in an escaped space can no longer donate its escape to the appended selector. * fix(claude): treat cmd single-quoted regions as unmodelable Round-5 review finding: cmd.exe has no single-quote syntax, so the Windows tokenizer's grouping of a single-quoted region diverges from what cmd parses — literal argv like 'claude ...--resume... old' was being read as a real selector and stripped, and a literal '--' as claude's terminator. Flag any cmd single-quoted token as bareShellSyntax so the guard fails open. * fix(claude): flag quoted expansions and scope assignment prefixes Round-6 review findings: the span flag was only evaluated in the unquoted branch, so an expansion opener inside double quotes went unflagged — and inside $(…)/backticks a nested quote re-opens a context this tokenizer does not model, so the splice could cut mid-construct (syntax error, or a silently mutated substitution body). Both tokenizers now flag those, and the flag is renamed divergesFromShell to say what it means. Restrict the NAME=value command-position prefix to posix, where that syntax exists. Drops two branches proven dead. * fix(claude): model shell-literal escapes and scan the whole base Round-7 review findings: (1) the divergence scan started after the claude token, so an expansion opened in a prefix — $(x; npx -- claude --resume s) — had its closer spliced away, producing a base bash cannot parse; it now covers every token including the executable, exempting only PowerShell's leading call operator. (2) posix drops a double-quoted backslash the shell keeps literal, and the Windows escape branch ran inside quoted regions where cmd/PowerShell keep the escape byte literal — both now flagged, so a literal can never be misread as a selector. (3) an unquoted line continuation hid a selector inside a token and skipped the newline gap check. Also removes a third provably dead branch and collapses the cut floor into the cut itself. * fix(claude): flag escapes the tokenizer models but the shell removes Round-8 review findings, all one family — escapes whose token value hides a selector the shell would see: a double-quoted line continuation (bash deletes both bytes), posix $'…'/$"…" quoting, a windows escaped newline, and a trailing unpaired escape. The last one was previously written off as pre-fix-identical, but once stripping happens the dangling escape swallows the separator and no exact --resume reaches claude at all — strictly worse than appending, so it must fail open. Also folds the three gap predicates into one scan. * fix(claude): stop over-flagging a literal dollar sign Round-9 review findings from both lanes: inside double quotes only $( and ${ open an expansion — $' and $" are literal there — and a trailing $ was flagged unconditionally because JS ''.includes('') is true. Both made the guard fail open on modelable bases, leaving the stale selector to compete, so #12982 went unfixed for them. Separately, cmd strips ^ before the child re-splits on the bare whitespace, so an escaped separator hides two real arguments and must fail open rather than drop one. * fix(claude): fail open on cmd caret-quotes and bare PowerShell syntax Round-10 review findings, both Windows-only (a bash oracle cannot reach them): cmd strips a caret before a quote and the child's parser then reads a bare quote delimiter, so the tokenizer's word boundaries stop matching argv — one case turned a working resume into no resume at all, another let a stale selector survive the splice. And bare (…)/{…} are live PowerShell syntax in argument position, so splicing through them emitted unbalanced output that PowerShell cannot parse. * fix(claude): fail open on the PowerShell stop-parsing token Round-11 review finding: after a bare --%, PowerShell passes the rest of the line to the child literally, so the guard stripped a real selector and then appended quoting that arrives as literal bytes — claude ends up with no exact --resume at all, worse than leaving the stale one. Quoted "--%" and cmd, where the token is ordinary, still splice. * fix(claude): model cmd backslash-escaped quotes Round-11 review finding: an odd run of backslashes before a quote makes it a literal byte to the child's CommandLineToArgvW parser, not a delimiter, so the tokenizer's word boundaries stopped matching argv. Orca manufactures that pattern itself — quoteStartupArg wraps every token in quotes without escaping a trailing backslash — so a pasted Windows path was enough to move the selector into a desynced region and leave claude with no resume flag. Also replaces a caret test case that was byte-identical before and after its own fix, and merges two stacked comment blocks. * fix(claude): fail open on PowerShell double-quoted escape sequences Round-12 finding: PowerShell expands backtick escapes only inside double quotes, so a sequence there produces a token value argv never sees — the guard could strip "-`r" plus the argument after it. Also narrows the stop-parsing comment: a quoted --% can engage stop-parsing before a parameter token, where the base is already mangled either way. * fix(claude): flag PowerShell escape sequences in bare arguments too Round-13 finding: the previous commit gated on quote === '"', but PowerShell's tokenizer calls Backtick() from ScanGenericToken, so it expands these sequences in unquoted arguments as well — bare -`r really is a control character, not -r. The guard read it as a selector and dropped it plus the argument after it. Widening to all PowerShell contexts measures 0 under-flag and 0 over-flag across the full printable matrix; the backtick-escaped-space idiom still splices. Also swaps a test case that was byte-identical with and without its own fix. * fix(claude): drop a token-leading PowerShell backtick before whitespace Round-14 observations, all pre-existing and measured: PowerShell drops a token-leading backtick together with the whitespace after it, emitting no token, so the tokenizer's extra token shifted the locator; and a backtick before a bare CR is a line continuation too. Flagging both takes the lane's 329k-base sweep from 87 bad to 0 with no new failures and the must-splice list byte-unchanged. Also corrects a comment that no longer listed every PowerShell divergence. * docs(claude): correct the bare-CR rationale in the tokenizer comment Round-15 verified against a real PowerShell 7.6.4 engine: a backtick before a bare CR is not a line continuation there — pwsh keeps the CR in the token. The flag stays because 5.1 is unverified and failing open costs nothing, but the comment now says that rather than claiming continuation. |
||
|
|
b01df38590 |
Show agent CLI failure output for branch auto-naming and generation instead of parsing per-CLI error formats (#8045)
* Surface the Pi CLI's real error when branch auto-naming and commit generation fail Pi failures (missing provider credentials, HTTP 4xx/5xx, connection errors) previously collapsed to the generic 'Pi CLI command failed with code 1.' because extractAgentErrorMessage only recognized Error:-prefixed lines. Add two stderr-only extraction passes for pi's failure formats and narrow the unix-path redactor so pi's /login remedy token survives redaction. Fixes the OP variant of STA-1492 (#7808). * Replace per-CLI failure parsing with sanitized raw output excerpts Every agent CLI formats errors differently, and the parsing passes only ever covered the vendors someone had already debugged (the pi passes fixed pi and nothing else). Show the output itself instead: a positional excerpt (first two non-empty lines plus the last one) of stderr, falling back to stdout when stderr is silent, path-redacted and capped as before. Exit-0 runs with empty stdout now stay 'returned an empty <result>' instead of misreporting a command failure. The sanitizer also strips Cf characters (bidi overrides) now that provider-controlled bodies flow through verbatim, and OSC sequences are stripped alongside CSI. * Keep the full CLI output of failed branch-name generation for on-demand viewing The persisted rename-failed badge carries only a sanitized excerpt (it syncs to paired clients), so the complete diagnosis was previously buried in the main-process log. Failed generations now capture their full stdout/stderr (bounded to 64 KiB per stream, head and tail) into a main-memory-only store keyed by worktree — never persisted or synced. The rename-failed dialog fetches it on demand and shows it in place of the excerpt, ANSI/control/bidi-stripped; after a restart or on paired web clients it falls back to the excerpt. Renderer-bound generation results explicitly drop the capture so IPC payload shapes are unchanged. * Cover the rename-failed dialog's full-output fetch and excerpt fallback * Split the folder-workspace title rename flow into its own module first-work-branch-rename.ts sat at the max-lines ceiling; the folder title flow is a self-contained concept and main's concurrent additions to this file pushed the CI merge ref over the limit. * Harden the failure-output capture and dialog against review findings - Flatten bounded captures so V8 sliced strings no longer retain the multi-megabyte parent stream in the capture map (128 MiB -> ~4 MiB in a 32-entry probe). - Require an OSC terminator and stop its char class at newlines so an unterminated/boundary-truncated sequence can no longer swallow the omission marker and diagnostic tail. - Exclude stdout from the persisted branch-name failure detail (it can echo the prompt into synced metadata); the full local-only capture still keeps it for the dialog. - Refetch and reset the dialog's full output when the persisted error changes so an open dialog never shows or copies a stale run. - Report signal-terminated generators (null exit code) as 'was terminated before exiting' instead of 'code null'. * Redact JSON-escaped Windows drive paths without breaking scheme URLs Provider JSON bodies double backslashes (C:\\Users\\name), which slipped past the drive-letter redaction into the persisted, client-synced failure excerpt. Allow repeated backslashes only — a URL's :// must stay single so remedy links survive. * Fix branch rename failure IPC re-registration --------- Co-authored-by: Brennan Benson <brennanbenson@Brennans-MacBook-Pro.local> |
||
|
|
972078f2c4 |
Fix paste ownership, input bounds, and IPC validation
Supersedes #5745, #5746, and #5747. |
||
|
|
256e0ef81a |
Handle buffer overflows gracefully and truncate diffs fairly (#5083)
- Gracefully fall back to file-name summaries when staged diffs exceed node/ssh execution maxBuffer limits, preventing generation failures. - Split oversized diffs by file and allocate budget via water-filling, ensuring single huge files do not starve smaller human changes. - Clip truncated diff sections on line boundaries to avoid half-lines. |
||
|
|
e4ac0df51d |
Clean up auto branch rename settings (#3378)
Co-authored-by: Orca <help@stably.ai> |
||
|
|
03b889512b |
feat: expand ai commit agent support (#1928)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: brennanb2025 <brennankbenson@gmail.com> |
||
|
|
b030257c3b |
feat(source-control): AI commit message generation (#1487)
Co-authored-by: Orca <help@stably.ai> Co-authored-by: brennanb2025 <brennankbenson@gmail.com> |