The update->add conversion for native Windows (skills update is unreliable
there, PR #6307) silently stopped matching when update commands gained the
non-interactive npx --yes ... --yes shape, and the new managed-skill flow
bypassed it entirely:
- Widen the renderer normalizer regex to match both command shapes, so all
settings panels convert again on win32
- Build update-kind manual commands host-platform-aware in the main process
(the modal command executes on the host, and web clients can't know the
host platform from the browser)
- Make the background auto-update runner reinstall from the repo source on
win32 instead of spawning the unreliable skills update
- Pin the normalizer tests to the real shared command constants so a future
shape change can't silently strand the regex again
Co-authored-by: Orca <help@stably.ai>
* fix: detect valid repos when git rev-parse can't confirm
isGitRepo() has depended entirely on a successful `git rev-parse`
since 18ed7b27d, with catch blocks that collapse every failure into
"not a git repository". When that subprocess fails for a reason
unrelated to repo-ness — a transient spawn / git-shim hiccup in the
packaged app, main-process resource pressure, or a config-level error —
a real repository is silently downgraded to a plain folder. The folder
scanner already tolerates this via a `.git` marker, so the scan reports
"git_repo" but the subsequent addRepo throws, producing the spurious
"Open as Folder" prompt for a valid repo.
Keep `git rev-parse` as the authoritative positive signal, but on any
non-positive result fall back to a validated `.git` marker instead of
returning false: `.git` dir must contain HEAD, a `.git` file must point
at a gitdir, and bare roots need HEAD + objects/ + refs/. A garbage
`.git` file and an empty `.git/` are still rejected, preserving the
validation 18ed7b27d added. Logs a warning when recovery via the marker
happens so the underlying probe failure stays visible.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix: address review feedback on repo detection
- isGitRepo: warn at most once per session when recovering a repo via
the .git marker, so a broken-git scan can't flood main-process logs.
- repo-detection test: delete PATH instead of assigning "undefined" when
it was originally unset, avoiding a corrupted PATH for later tests.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix: harden git repo marker fallback
Co-authored-by: Orca <help@stably.ai>
---------
Co-authored-by: Omar Shahine <10343873+omarshahine@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Jinwoo-H <jinwoo0825@gmail.com>
Co-authored-by: Orca <help@stably.ai>
* fix: reordered default columns in kanban board
* Introduce dedicated flag to repair reversed default workspace statuses
- Add `_workspaceStatusesReorderedDefaultRepaired` to decouple the
one-shot repair from the initial status order migration.
- Ensure the repair runs for users who saved the reversed default
payload (with "Done" on the left) during a short-lived broken build.
- Support both "Completed" and "Done" labels when identifying default
status shapes to migrate or repair.
---------
Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com>
* Resolve and open file links from native chat messages
- Add `onLinkClick` and `allowFileUriLinks` props to `CommentMarkdown`
to support intercepting links and enabling file URI navigation.
- Resolve relative paths, line/column suffixes, and file URIs from
native chat messages against the active worktree context.
- Handle clicked links in `NativeChatView` by opening the target file in
the editor (or system default via Shift+click).
- Refactor markdown renderers and parse utilities into standalone,
reusable modules to share between terminal and chat components.
* Fix file link resolution and click event propagation
Ensure file links open correctly by falling back to repo-scoped
worktrees if a known worktree lacks a path. Also, stop propagation
on markdown anchor clicks to prevent triggering outer card click
handlers.
Previously, the terminal pane would always perform a clear screen on PTY
attach before replaying the eager buffer. This cleared restored scrollback
unconditionally, even when there was no active terminal content to replay
(e.g., when the buffer was empty or only contained window titles and
agent status metadata).
Now, eager buffers are parsed to determine if they contain display-affecting
content. The attach-time clear is skipped for empty or metadata-only
replays, preserving the restored scrollback history. Trailing partial
control sequences are also trimmed to prevent swallowing live terminal output.
* Add terminal SSH reconnect overlay
* Publish returned SSH connection state to store on reconnect
Write the returned connection state immediately into the renderer store
to ensure the deferred terminal reattach can resume without waiting for
the state-change IPC to land.
Also translate SSH reconnect overlay strings in the non-English locales
and update the overlay visibility condition to use isVisible.
* Delete SSH terminal reconnect empty pane design document
Remove the design document detailing the SSH terminal reconnect empty pane
overlay problem, design, and data flow, as it is no longer needed.
* Add keyboard shortcut to toggle the Quick Commands menu
- New `tab.openQuickCommandsMenu` keybinding action (no default binding)
- TabBarQuickCommandsMenu listens for the binding and toggles open/closed
- Scoped to the active tab group naturally since the component only mounts when its group is focused
* Show keyboard shortcut in Quick Commands menu trigger tooltip
* Add tests
* expand tests
* Expand keyboard toggle to call handleOpenChange and skip repeated keys
- Replace `setMenuOpen` toggle with `handleOpenChange(!menuOpen)` so closing
via keyboard runs the same reset logic (query, focus frame, value override)
- Guard against key-repeat events to prevent rapid toggling on held key
- Wrap `handleOpenChange` in `useCallback` so it's stable enough to include
in the `useEffect` dependency array without causing spurious re-registrations
- Update tests to reflect that re-running the effect between presses is
required for the close path, and add a repeat-event test
* Add docstring to withShortcutHint func
* review: harden quick commands menu shortcut
Co-authored-by: Orca <help@stably.ai>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Jinwoo-H <jinwoo0825@gmail.com>
Co-authored-by: Orca <help@stably.ai>
Handle expected Monaco Delayer cancellation during renderer cleanup so ignored trigger promises do not surface as unhandled rejections. Adds regression coverage for the DisposableStore teardown path from the crash report.
Keep the synthetic floating workspace local while a remote runtime is active, including terminal/browser creation, activation, close, and remote snapshot handling.
Maintainer follow-ups:
- require worktreeId for runtime-session terminal create payloads
- add renderer-backed terminal create reply sender regression coverage
- merge current main and keep the WSL readDir breadcrumb test aligned with main's Windows-only handler coverage
Fix native Windows CJK terminal repaint and ConPTY wrap metadata handling.\n\nNormalize filesystem realpath results before authorization so WSL UNC roots compare consistently in CI.
Fix native-chat tool-run summaries so Windows-style file paths display their basename instead of the full backslash path.
Also reuse the renderer basename helper so trailing Windows paths keep a useful summary hint.
* Apply #6826: reclaim xterm focus after window blur (verbatim)
Co-authored-by: Orca <help@stably.ai>
* Improve #6826 focus reclaim: pane-scoped helper + cross-platform focus-steal guard
- Reclaim the exact split helper that owned focus at blur, not the first
helper in the container (a single TerminalPane hosts all splits as siblings).
- Defer the reclaim refocus to the next frame on every platform and only
take focus if nothing newer grabbed it, matching the existing macOS guard,
so a click into the sidebar/dialog during reactivation isn't yanked back.
- Skip reclaim if the released helper was detached before refocus.
Co-authored-by: Orca <help@stably.ai>
---------
Co-authored-by: Orca <help@stably.ai>
* Harden merged #6830 daemon degraded-mode handling
- shutdownFallbackSessions is now best-effort: a single un-killable local PTY
no longer throws and aborts the daemon restart (which would leave the user's
recovery path unusable, recreating the original lockup). Logs and continues.
- checkPtySpawnHealth retries once (timeout raised 2s->4s) so a transient stall
on a busy machine right after an upgrade does not mis-classify a healthy
daemon as unable to spawn PTYs and silently drop new terminals to the local
provider without daemon persistence.
- Surface degraded mode: DegradedDaemonPtyProvider exposes isDegraded, and
pty:management:listSessions returns { degraded } so the session UI can warn
instead of it being a silent console.warn. Clearer actionable warn message.
Refs #6814.
Co-authored-by: Orca <help@stably.ai>
* Add #6814 daemon failure-mode classification test
Drives the real DaemonServer + checkDaemonHealth over a real socket to lock in
the healthy / degraded(pty-spawn-unhealthy) / wedged(unreachable) / unreachable
classification. Documents the load-bearing boundary that the degraded-daemon
fallback rescues a degraded daemon but NOT a fully wedged one.
Co-authored-by: Orca <help@stably.ai>
* Add degraded flag to web preload listSessions stub (typecheck parity)
Co-authored-by: Orca <help@stably.ai>
---------
Co-authored-by: Orca <help@stably.ai>
* fix(win): fall back to software rendering after repeated GPU crashes
On old/flaky GPU drivers the GPU child process crashes
(STATUS_BREAKPOINT / ANGLE-D3D init failure) within seconds of launch,
repeatedly — Windows crash clusters F0BDNADU79Q (Win11) and
F0BDNRZ5MDG (Win10). GPU child deaths are intentionally suppressed as
recoverable churn, so Orca never reacted and the GPU kept crashing every
launch with no self-healing path.
Track GPU child crashes in a post-launch window (3 / 30s). On the
threshold, record a gpu_fallback_engaged breadcrumb, persist a marker
file in userData, and relaunch once. The marker is read before
app.whenReady() resolves (the Store isn't available that early) so
app.disableHardwareAcceleration() + --disable-gpu take effect, then it's
consumed/cleared so the fallback applies to exactly one launch and can't
relaunch-loop. Records gpu_fallback_applied on the software-render boot.
Pure logic lives in GpuCrashFallbackTracker and the marker read/write
module, both unit-tested; the index.ts wiring is thin. Desktop only —
headless serve already uses software rendering where needed.
* fix(win): harden GPU crash fallback policy
---------
Co-authored-by: Neil <neil@stably.ai>
- Update the PR state badge icon to dynamically match merged, closed, or draft states.
- Simplify PR merge direction layout using branch tags and a directional arrow.
- Add author avatars to the PR metadata row.
- Prevent scrolled task rows from bleeding through sticky elements by adjusting header z-indexes and applying opaque hover/surface backgrounds.
- Refine padding, text size, and spacing across the PR and task views.
The OOM reports (F0BDMD16LJ2 and the taifunk many-worktree sessions)
show memory creeping over long sessions with churning worktrees. One
contributor: in pr-refresh-coordinator, many local worktrees that track
the same linked PR coalesce into a single queue entry whose 'aliases'
map keeps one entry per worktree. Aliases were only pruned when a
candidate was re-enqueued as invalid — never when a worktree was simply
removed/closed — so the maps grew unbounded across a session.
Add pruneWorktreePRRefreshAliases(worktreeId) and call it from
removeWorktreeMetadataAndTransientState (the existing central
worktree-removal cleanup, alongside removeWorktreeMeta /
forgetWorktree / deleteWorktreeHistoryDir). It drops the removed
worktree's aliases, deletes the queue entry when none remain, and
rebinds the representative candidate if the removed worktree owned it.
Covered by 3 new coordinator tests (accumulate-then-prune, keep-entry-
on-remaining-aliases with candidate rebind, no-op for unknown worktree)
plus two test-only inspection helpers.
Co-authored-by: Neil <neil@stably.ai>