* fix: handle native Windows skill update flow for Orca setup
- Rewrite npx skills update <skill> --global to the repo reinstall path on native Windows hosts.
- Keep the WSL runtime path unchanged so Linux/WSL setup behavior stays intact.
- Update the affected runtime helper tests to cover the Windows fallback.
- Adjust the orchestration pane test expectation to match the Windows-host command rewrite.
- Scope the change narrowly to the issue path to avoid impacting unrelated skill setup flows.
* fix: cover Windows skill update fallbacks
---------
Co-authored-by: Jinwoo Hong <73622457+Jinwoo-H@users.noreply.github.com>
* Fix ReDoS in terminal file-path link detection that froze the app (#5970)
A full-screen TUI such as ngrok, run through Windows ConPTY, emits its
dashboard as a single newline-free logical line that is almost entirely
alignment spaces. xterm accumulates it into one ~150k-char logical line,
and on every hover/redraw Orca's file-path link providers scan that line.
The spaced-path lookaheads (SPACED_PATH_WITH_SEPARATOR_REGEX and
LINE_ENDING_SPACED_PATH_REGEX) began with `[^...]*\s+`, where the negated
character class also matches whitespace. That overlap let the engine split
a long run of spaces in exponentially many ways before failing, so a
~5k-char prefix took ~25s and pegged the renderer main thread, freezing
the whole app. macOS uses a normal PTY and never builds that line, so it
was unaffected; disabling terminal GPU acceleration did not help.
Anchor the first lookahead segment at the first whitespace (add `\s` to
the negated class) so it can no longer overlap the following `\s+`. The
matches are identical; the scan drops from ~25,000ms to ~4ms.
Adds a regression test asserting extraction stays roughly linear on long
space-heavy lines.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* Fix terminal link ReDoS guards
* Trim terminal link padding
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Jinwoo Hong <73622457+Jinwoo-H@users.noreply.github.com>
Co-authored-by: Neil <neil@stably.ai>
* Adopt pending terminal tab reveals
* Materialize pending remote terminal tabs
Wait for mobile terminal creates to produce a ready PTY handle before resolving. If the renderer only publishes a pending tab shell, materialize a headless PTY into the same tab/leaf identity so later renderer focus adopts it instead of duplicating the tab.
Add a pane-key spawn reservation shared by runtime materialization and renderer pty:spawn so focus racing fallback reuses the winning PTY, including when SSH env stripping removes ORCA_PANE_KEY. Cover the pending-surface fallback and both overlapping spawn race directions with regression tests.
* Settle pane spawn reservation on any post-spawn failure
The per-paneKey spawn reservation was only settled on spawn error, persist
error, or final resolve. A throw in the post-spawn region (seedHeadlessTerminal,
registerPty, rememberPaneKeyForPty, track) rejected the IPC promise but left the
reservation in paneSpawnReservationsByPaneKey forever, so every later spawn for
that pane awaited a promise that never settled and hung.
Wrap each post-reservation body (both spawn paths) in a catch-all that rejects
the reservation with the real error and rethrows; reject is a no-op once
resolved. Remove the now-redundant inner reject calls. Add regression tests for
both paths.
* Tear down runtime-owned headless tabs on mobile session close
The renderer-attached branch of closeMobileSessionTab closed the renderer's
pane but never pruned mobileSessionTabsByWorktree or dropped the persisted
binding. For runtime-owned headless terminals — serve/SSH materialized, or a
pending shell the renderer never adopted, all introduced by the pending-surface
materialize fallback — syncMobileSessionTabs then re-hydrates the closed tab
from the persisted session, resurrecting it with a live PTY. "Close others" on
a paired client showed closed remote tabs reappearing with their sessions still
running.
Add isRuntimeOwnedHeadlessMobileTab (serve/SSH-owned, or no live PTY and absent
from the renderer graph). When the whole parent of such a tab is closed, route
through closeHeadlessMobileTerminalTab to kill the PTY, remove the persisted
binding, and prune+emit, then best-effort notify the renderer so no adopted
pane is left dead. Genuinely renderer-owned tabs and exact split-leaf closes
keep the existing path. Cover the serve parent close, renderer-published vs
runtime-unadopted pending tabs, and the serve split-leaf case with regressions.
* Tear down only headless tabs the renderer never published on mobile close
The close-others teardown discriminator returned false for any resolved
non-serve/ssh PTY, so headless tabs carrying a daemon session id
(<worktreeId>@@<shortUuid>) that the host materialized but the renderer never
published leaked into the session snapshot and the client mirrored them
(confirmed live: host published 5 tabs for a worktree the renderer showed 1 for).
That id shape is ALSO minted for ordinary renderer-owned daemon-backed local
terminals, so it can't classify ownership by shape — the renderer graph
(this.tabs) does. Classify a tab as runtime-owned when it is serve/ssh (always,
they're preserved + re-hydrated) or when the renderer graph never published it
(a leaked/unadopted shell); delegate everything the renderer graph lists,
including ordinary @@ local terminals and pending tabs.
Regression tests: renderer-owned @@ tab is delegated (not de-persisted); leaked
@@ tab the renderer never published is torn down + de-persisted.
* Style commit text area to match input tokens and fix disabled state
- Update borders and shadows to match standard input tokens.
- Style the disabled state explicitly to prevent Chromium's user-agent
styles from washing out the field outline.
- Add dark mode background styling overrides.
* Improve timeline items assertions in work-item-details test
Extract timelineItems to a local variable and add an explicit null check to prevent TypeScript compilation errors when calling the .at method.
- Add support for resuming agent sessions in their corresponding worktree
instead of defaulting exclusively to the active workspace.
- Implement "Jump to Original Pane" and "Jump to Worktree" actions to
quickly navigate to the session's workspace or terminal pane.
- Display worktree metadata and statuses (current, active, archived, or
unavailable) on session cards and inline details.
- Refactor launch actions, original pane lookup, and worktree mapping into
dedicated modules with comprehensive unit tests.
- Update internationalization files for all supported locales.
- Internationalize workspace/worktree creation button labels
- Add and improve translations for Spanish, Japanese, Korean, and
Chinese locales across settings, terminal, and agent descriptions
Extract combined diff cache matching logic to a dedicated module and enhance it to verify status, area, old path, and added/removed counts. This prevents restoring cached diff content when the underlying files have changed or been renamed.
* Add GitHub issue timeline activity feed to details dialog
Fetch and display issue timeline events (assignments, mentions, closes,
reopenings, and project board column moves) in a unified activity tab
within the GitHub item details dialog.
- Query the GitHub REST timeline endpoint up to a bounded 300 items.
- Merge comments and timeline events into a single sorted conversation.
- Render tailored icons, links, and localizable messages per event.
- Ensure issue reply targets are not incorrectly filtered by stale PR state.
- Correctly update local item state from details payload.
* Cap issue timeline pagination by supported activities
Count only mapped, supported timeline items instead of raw REST events
when checking the maximum item threshold. This prevents pagination from
stopping early when pages contain many unsupported event types.
* Only create worktree root directory on blur, not per keystroke
Persist worktreeBasePath on input blur instead of on every change.
The per-keystroke updateRepo calls triggered prepareLocalWorktreeRootForRepo
on each character, creating a new directory for every intermediate value
(./w, ./wo, ./wor, …) while the user was still typing.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Test that worktree path only persists on blur, not per keystroke
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Fix blur event dispatch in worktree path test
React delegates onBlur via focusout (which bubbles), not blur (which
doesn't). Dispatch focusout so the React handler is actually reached.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Update src/renderer/src/components/settings/RepositoryWorktreeDefaultsSection.test.tsx
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
* Apply suggestions
* Avoid no-op worktree path root preparation
Co-authored-by: Orca <help@stably.ai>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: Jinwoo-H <jinwoo0825@gmail.com>
Co-authored-by: Orca <help@stably.ai>
The new-workspace project dropdown pinned resolution to the host of the
currently-active workspace: handleProjectChange passed that host to
resolveWorkspaceCreationRepoId as a hard `hostId` constraint. Picking a project
set up only on a different host resolved to no repo
(`project-not-set-up-on-host`), and the `if (!nextRepoId) return` guard swallowed
the click — so the dropdown option did nothing and only projects on the current
host were selectable.
Treat the current host as a preference (focusedHostScope) and fall back to any
host the project is ready on. The strict projectId+hostId path used by the
explicit "Run on" host picker is unchanged.
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
* Wire terminal-initiated worktree navigation to back-and-forth stack
* Unify terminal-driven worktree activation and Cmd+J recency marking.
* Record worktree visits in the back/forward history stack unless navigating history.
* fix: focus terminal-initiated worktree tabs