* Add rerun action for failed automations
Adds a recoverable failed automation rerun action in the run detail view, with pending-state handling and focused view-state coverage.
Design doc: docs/failed-automation-rerun-action.md
* Rebuild Electron binary before PR tests
- Ensure Node-based unit tests can import `electron` after install blocks package postinstall
- Generate Electron's required `path.txt` in the PR workflow
Multiline quick commands should behave like a shell command list, not a series of already-queued PTY lines. When a foreground command reads stdin, raw newline delivery can be consumed before the shell sees later cd/pwd lines; terminal paste avoids that but shows the whole block as pasted input before execution.
Flatten newline-separated quick commands into a semicolon-delimited command list before active-pane dispatch and new-tab startup queuing. The shell parses the list once, so later commands run after earlier foreground commands exit and directory changes remain in the active shell.
Fixes#2844
Co-authored-by: Prethish-Complyance <prethish@complyance.io>
Co-authored-by: Orca <help@stably.ai>
* fix(computer-use): stop malformed numeric args from crashing the agent
requiredNumber only checked isFinite, and several request handlers cast the
resulting Double straight to Int/UInt32 (elementIndex, clickCount, pages,
from/toElementIndex, windowId, windowIndex). Int(Double) traps when the value
is outside the integer's representable range, so a single malformed request
such as `{"elementIndex": 1e300}` crashed the entire agent process, killing
all in-flight automation.
Add a bounded conversion helper in the Core library and route every untrusted
Double->integer cast through it. boundedInteger truncates toward zero like
Int(Double) but returns nil (via init(exactly:)) instead of trapping when the
value is non-finite or out of range; the request handlers then surface a clean
invalid_argument error (or resolve to nil for the optional window lookups).
The helper lives in the Core library because the test target cannot import the
executable target where the handlers live. A negative-control run confirms the
out-of-range test traps with the previous Int(Double) cast and passes with the
fix.
* review: close remaining numeric crash paths
- parse stale-element validation indexes through bounded conversion
- reject malformed window selectors instead of dropping the target window
- bound synthetic scroll wheel deltas and cover Int32 conversion
---------
Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com>
* Add per-file line counts to the source control sidebar
Show +N/-N (green/red) next to each file in the Changes, Untracked, and
Committed-on-branch sections so the magnitude of a change is visible at a
glance. Counts are computed per staging area via `git diff --numstat`;
untracked/new files count their full contents as additions and binary
files show no count.
Consolidate numstat parsing and binary-buffer detection into shared
modules reused by the local status path, the SSH/relay path, and the
existing branch-compare code. Include added/removed in the status-entry
equality check so the sidebar doesn't re-render on unchanged polls.
* fix: harden source control line counts
---------
Co-authored-by: Neil <4138956+nwparker@users.noreply.github.com>
Match single-token base-ref search against both leaf and ancestor segments for local and remote slash-named branches. Keeps the SSH relay argv in parity and adds regression coverage.
Fix shortcut dispatch so app commands follow the produced logical key for the active keyboard layout, while preserving intentional physical-code fallbacks for terminal byte paths and unavailable logical keys.\n\nCloses #2858
* fix(sidebar): keep scroll position stable when deleting a workspace
Deleting a workspace made the sidebar scroll and shift instead of just
removing the row. Two causes: the scroll-anchor restore fell straight to
scrollToIndex(align:'start') — snapping the anchor row to the viewport
top — whenever the post-delete virtual window briefly lacked the row's
DOM node; and scroll preservation was only wired to the context menu at
click time, never to the async removal that actually drops the row.
Restore now pins from the measured slot before that snapping fallback,
and removeWorktree records the top-row anchor in the same tick it removes
the row, covering every delete entry point (modal, card, SSH, batch).
* fix(sidebar): preserve delete scroll anchor
Keep virtualized scroll listener registration stable across row changes so cleanup cannot overwrite the pre-delete anchor after the row list mutates.
Add a regression test for the listener dependency contract.
---------
Co-authored-by: Neil <4138956+nwparker@users.noreply.github.com>