Commit Graph
6407 Commits
Author SHA1 Message Date
Neil fcdcab7cd4 Release simulator launch pending guard on tab creation failure (#7682) 2026-07-11 01:28:22 -07:00
Neil 5da02b0105 Bound GitHub project picker browse cache (#7681) 2026-07-11 01:27:59 -07:00
Neil 5952ad0623 Bound custom pet blob cache (#7671) 2026-07-11 01:27:32 -07:00
Neil 2ddb976f8a Fix local preflight context cache leak (#7669) 2026-07-11 01:26:53 -07:00
Neil a5486b1351 Fix Codex title index cache leak (#7667) 2026-07-11 01:26:26 -07:00
Andre CristoandJinwoo Hong f6f497f50c fix(win): resume quoted cmd.exe startup commands via stdin, not /K (#7978)
* fix(win): resume quoted cmd.exe startup commands via stdin, not /K

Resuming an AI Vault session into a cmd.exe tab on Windows failed with
"'...' is not recognized as an internal or external command" and never
ran the resume. The queued command for a cmd live shell is the
self-contained `cmd /d /s /c "cd /d ""cwd"" && claude ""--resume"" ""id"""`
form, which is correct when typed into cmd's interactive parser (its ""
doubling is cmd's convention). But the local PTY provider embedded it in
the `/K` launch argument, where node-pty's C-runtime argv escaping emits
backslash-escaped quotes (\") that cmd.exe cannot parse — the command
arrived as `\"cd /d \"\"cwd\"\" && ...` and was rejected wholesale.

Unlike PowerShell's -EncodedCommand, cmd.exe has no robust argv-quoting
path, so any startup command containing a double quote now falls back to
stdin delivery, where cmd's interactive parser handles the "" doubling
correctly (verified end-to-end against a real ConPTY via node-pty).
Quote-free commands keep the `/K` fast path.

* fix(win): preserve cmd resume command contracts

* fix(win): match copied resume commands to shell

---------

Co-authored-by: Jinwoo Hong <73622457+Jinwoo-H@users.noreply.github.com>
2026-07-11 00:59:17 -07:00
Neil 9f078567e5 Update mobile 0.0.26 Android download links (#8246) 2026-07-11 00:48:01 -07:00
Neil 61f2e79f8b Bump mobile app.json to 0.0.27 (#8245) mobile-ios-v0.0.27 2026-07-11 00:45:05 -07:00
Brennan BensonandOrcaWin 4572b0a446 perf(worktrees): remove redundant creation probes (#7161)
Co-authored-by: OrcaWin <alpha-eng@stably.ai>
2026-07-11 00:41:28 -07:00
OrcaWin fa691a0dc8 fix(win): bound renderer launch-failed recovery (#8234) 2026-07-11 00:15:44 -07:00
Neil 76c0365110 Cancel stale mode 2031 retries across resubscribe (#8214) 2026-07-11 00:06:32 -07:00
Neil 15213c15e6 Send hidden terminal query replies without batching (#8213) 2026-07-11 00:05:54 -07:00
Neil cf04845f5b fix(mobile): keep TypeScript 6 for Expo Metro bundling (#8243) mobile-ios-v0.0.26 mobile-android-v0.0.26 2026-07-11 00:04:03 -07:00
github-actions[bot] 350ed02f41 Update README downloads badge 2026-07-11 07:01:18 +00:00
Rod BoevandJinjing 04a040801b fix(terminal): detect PR links with ANSI resets (#8216)
* fix(terminal): detect PR links with ANSI resets (#8126)

* fix(terminal): safely normalize PR link styling

---------

Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com>
2026-07-10 23:41:20 -07:00
github-actions[bot] 588dba6354 release: v1.4.136-rc.0 v1.4.136-rc.0 2026-07-11 06:35:57 +00:00
Brennan BensonandBrennan Benson 31cff75a7b feat(agent-status): show Claude subagent child rows and gate premature done (#8211)
* feat(agent-status): show Claude subagent child rows and gate premature done

A Claude pane that spawned background subagents/teammates showed a green
done check the moment the lead's turn ended, even while a background
review loop was still running. Orca now tracks the pane's live children
from Claude hook events and:

- keeps the pane 'working' while at least one child is working (Stop is
  gated; Claude wakes the lead when a child finishes, so the pane
  resolves to done on the follow-up Stop with an empty roster)
- renders the children as indented child rows under the pane's sidebar
  row (name/type + working/idle dot), reusing the existing lineage UI

Tracking is lifecycle-primary: SubagentStart/SubagentStop/TeammateIdle
(newly registered hooks) plus child-origin tool events (they carry
agent_id) own the roster. Stop's background_tasks is folded only where
unambiguous — verified live on Claude Code 2.1.207 that teammates report
status "running" while idle-alive and their task ids never match
lifecycle agent_ids, so the list cannot decide teammate working-ness.

Child-origin events no longer overwrite the lead's tool/prompt caches
(a live AskUserQuestion card survives child churn); a child's own
PermissionRequest records waitingAgentId so only that child's progress
or death clears the wait. The interrupted flag survives the gated
window, inferred interrupts sync the lead record and refuse while a
child works, and hydration reseeds the roster after a restart.

* fix(agent-status): drop identity icon on subagent child rows

The child's agentType carries its NAME (e.g. "pr-reviewer"), which is not
an iconable agent and rendered the unknown "?" glyph. Nesting under the
parent row already conveys identity.

* fix(agent-status): restore displaced lead state and reconcile phantom subagents

Four review findings from the adversarial pass on the subagent child-row
feature:

- Stash the lead state a child-induced wait displaces
  (ClaudeLeadTurnState.stateBeforeWait) and restore it when the wait
  clears, instead of inventing 'working' — a lead that had already
  stopped left the pane spinning forever after the roster drained,
  since the done-gate only ever downgrades done → working.
- Tag snapshot-seeded and background_tasks-recreated roster entries
  (backgroundTasksAuthoritative) and demote them when a PRESENT
  background_tasks list omits their id. A phantom child seeded before a
  restart could otherwise gate the pane 'working' indefinitely in teams
  sessions, whose task list is never empty. Live activity clears the
  tag so lifecycle-tracked teammates keep their state.
- Match teammate ids with a hyphen-free suffix after `a<name>-` so
  TeammateIdle for "lane" cannot idle "lane-hooks"'s rows or clear its
  pending permission wait.
- Route turn-boundary events (Stop/StopFailure/UserPromptSubmit) that
  carry a KNOWN child agent_id through the child-driven re-emit instead
  of adopting them as lead state, and tie the prompt-cache new-turn
  reset to lead-origin events so child refreshes can't blank the
  prompt label.

---------

Co-authored-by: Brennan Benson <brennanbenson@Brennans-MacBook-Pro.local>
2026-07-10 23:34:49 -07:00
JinjingandOrca 2e48495273 Prevent mobile screen locking during voice dictation. (#7746)
* Prevent mobile screen locking during voice dictation

Integrate expo-keep-awake to prevent the mobile device from locking or
sleeping while a voice dictation session is active.

- Modularize useMobileDictation logic into separate helper files for
  keep-awake, audio chunking, session state, and desktop startup.
- Acquire keep-awake lock only after successfully establishing a
  desktop session to avoid locking on stale start attempts.
- Release the keep-awake lock on all completion, cancellation, error,
  and unmount paths.
- Add source invariant unit tests to verify keep-awake ownership and
  strict cleanup ordering.

* serialize keep-awake operations and avoid stale dictation start races

- Implement a global execution queue and tag tracking for keep-awake
  operations to prevent concurrent races and stale deactivations.
- Track failed native deactivations and retry them when a replacement
  hook owner mounts or starts a new dictation session.
- Ensure stale or canceled desktop dictation starts do not reset the
  UI state or propagate outdated start/keep-awake failures.
- Reuse the audio chunk queue wiring in useMobileDictation to avoid
  allocating new closure objects on the high-frequency microphone path.
- Add comprehensive unit tests for the keep-awake and desktop start hooks.

* Commit native recording during dictation session startup

Commit native recording in the same continuation as the final session
stale check. This prevents a queued cancellation from resurrecting the
microphone recording after cleanup has already run. If microphone
initialization fails or throws, acquired resources (like keep-awake
locks and the remote desktop session) are properly rolled back.

* Make keep-awake acquisition best-effort with a bounded startup timeout

- Recording start no longer blocks (or fails) on keep-awake acquisition:
  a hung or failing native call is capped at a short budget and logged
  instead of delaying or aborting dictation.
- Add native-call timeouts, orphan-tag tracking, and reacquire/drain
  logic in mobile-dictation-keep-awake.ts so Activity recreation on
  Android and stale tags no longer wedge the keep-awake queue.
- Add useMobileDictationForegroundKeepAwake to refresh the wake tag on
  Android foreground and retry failed refreshes/deactivations.
- Hold the wake tag through chunk drain and the finish RPC so a screen
  lock can't suspend the app before the transcript arrives, and keep
  cleanup running even if native recording shutdown throws.
- Loosen expo-keep-awake to a caret range to unblock the patch pulling
  in these native fixes.

* Fix cancellation races in mobile dictation keep-awake handling

- Run wake-lock release and dictation cancel concurrently on stale
  starts so a hung acquisition no longer delays the native cancel
- Guard foreground reacquire retries with a run token so a stale
  retry chain can't deactivate a wake lock reacquired by a newer
  AppState transition

* Update source invariant test for concurrent stale-start cleanup

Co-authored-by: Orca <help@stably.ai>

---------

Co-authored-by: Orca <help@stably.ai>
2026-07-10 23:31:56 -07:00
JinjingandOrca 931e402e93 Fix tui-idle detection for cursor-agent lanes with dismissed trust dialog (#8220)
* Fix tui-idle detection for Cursor Agent lanes with dismissed trust dialo

Cursor Agent's persistent TUI never emits an idle OSC title, so a
dismissed trust dialog stayed in scrollback and kept the wait blocked
even once Cursor reached its idle "→" prompt. Detect Cursor's active
prompt (busy or idle) to clear a stale trust hit, and detect its idle
state specifically (prompt present, no braille spinner) to satisfy
tui-idle, so busy lanes keep polling instead of returning a stale
blocked result.

* Add test coverage for Cursor Agent trust-dialog banner detection

Verify lastIndexOf picks the later ready banner over an earlier
"Cursor Agent" mention in the trust dialog body, for both the
idle-resolution and busy-detection cases.

* chore(i18n): sync localization catalog for aiVaultSessionLogOpen keys

Pre-existing gap from #8205 (ai-vault view log) that fails `pnpm lint`'s
localization-catalog check on origin/main; unrelated to the tui-idle fix but
committed here to unblock CI lint on this branch.

Co-authored-by: Orca <help@stably.ai>

---------

Co-authored-by: Orca <help@stably.ai>
2026-07-10 23:25:46 -07:00
Rod BoevandJinjing b677b2a209 fix(github): recover oversized issue creation (#8217)
* fix(github): recover oversized issue creation (#7704)

* fix(github): preserve partial issue creation

---------

Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com>
2026-07-10 23:16:13 -07:00
Jinjing 66cad529a2 Improve chinese translation 2 (#8219)
* Improve zh/ja/ko/es translations for missing and untranslated i18n strin

- Translates several previously English-only entries (locked workspace, host removal, subagent labels, org/profile switcher dialogs) that were left untranslated in each locale file
- Fixes zh/ja/ko/es JSON EOF newline formatting

* Improve zh/ja/ko/es translation quality and terminology consistency

- Fix mistranslated/untranslated strings (English leftovers in es/ja,
  incorrect "role"→"forbidden" wording in ko)
- Standardize terminology: 子代理→子智能体, 中立→中性 (zh); 하위
  에이전트→서브에이전트 (ko); align count-phrase word order with
  natural ko/ko phrasing (e.g. "N개 X" → "X N개")
2026-07-10 23:06:56 -07:00
Jinjing 026516f323 the-sandbox-flag-is-2 (#8236)
* Fix mobile source control drawer overflow and branch-compare state loss

- Render BottomDrawer in a native Modal so it covers the full viewport
  even when mounted inside a ScrollView.
- Move the conflict/Abort row onto its own line so it never overflows
  the branch card, and enlarge the Abort hit target.
- Show the committed-on-branch footer even when the changed-files
  SectionList has no sections, since RN skips ListFooterComponent for
  empty sections.
- Stop branch-compare state from collapsing to idle/error on transient
  base-ref resolution failures when a ready result should be preserved.

* Add mobile source control drawer reload screenshot

Attaches an evidence screenshot for the mobile source control drawer overflow / branch-compare state loss fix.

* Remove stray temp screenshot file

Accidentally committed debug artifact from mobile source control drawer work; not needed in the repo.
2026-07-10 23:04:38 -07:00
Jinwoo HongandOrca 5b1fcb0ff0 Fix task workspace handoff after switching workspaces (#8226)
Co-authored-by: Orca <help@stably.ai>
2026-07-10 22:56:33 -07:00
JinjingandOrca 6a176b89fc fix(source-control): keep push enabled for same-repo linked review with real upstream (#8202)
* fix(source-control): keep push enabled for same-repo linked review with real upstream

Push/Force Push (and Pull/Sync/Publish) were wrongly disabled when a branch
had a genuine git upstream but an open linked PR whose push target had not
yet hydrated. `hasUsableHostedReviewPushTarget` hard-returned false for any
resolvable review link without a hydrated `pushTarget`, so
`resolveHostedReviewActionUpstreamStatus` synthesized `hasUpstream:false`
and the whole remote menu treated the branch as unpublished.

A same-repo review's head IS the checked-out branch, so a real upstream
already tracking that branch is that head and is safe to use before the
resolver hydrates a target. Treat that upstream as usable; keep blocking the
fork-head/cross-repo case (upstream tracks a differently-named head) and the
no-upstream case until the resolver proves the real target. Provider-agnostic
(GitHub PR / GitLab MR) and covers the SSH linked-review path.

Adds regression tests to source-control-hosted-review-push-target.test.ts and
a composed pipeline test in source-control-dropdown-items.test.ts.

* docs(source-control): trim verbose comments on linked-review push-target fix

Co-authored-by: Orca <help@stably.ai>

* refactor(source-control): use canonical gitRefTargetsBranchName for linked-review upstream match

Replace the hand-rolled upstreamTracksBranch leaf-split with the shared
gitRefTargetsBranchName primitive, which trims and rejects malformed
remote-qualified refs. The remote stays unknown until the resolver hydrates
the push target, so this remains a branch-leaf match; the strict remote+branch
check takes over once the target is known.

Co-authored-by: Orca <help@stably.ai>

---------

Co-authored-by: Orca <help@stably.ai>
2026-07-10 22:45:32 -07:00
NeilandOrca 4f7fe78921 perf(mobile): stop polling live worktree names (#8051)
* perf(mobile): replace worktree name polling with events

* fix(worktrees): push rename invalidation to remote clients

worktrees:updateMeta deliberately skips the renderer notifier (PR #209),
but paired mobile clients no longer poll for titles, so a manual rename
would never reach them. Emit the remote-only worktreesChanged client
event (with resolved-cache invalidation), gated on displayName so
per-click isUnread writes stay event-free.

Co-authored-by: Orca <help@stably.ai>

* test(worktrees): add missing runtimeStub type member for typecheck

Co-authored-by: Orca <help@stably.ai>

* fix(worktrees): derive rename event repoId with the shared non-throwing parser

getRepoIdFromWorktreeId matches the mobile client's event filter exactly
and cannot throw after the meta write already persisted.

Co-authored-by: Orca <help@stably.ai>

---------

Co-authored-by: Orca <help@stably.ai>
2026-07-10 22:44:59 -07:00
OrcaWin c869891b37 test(e2e): defer large repo cleanup until shutdown (#8228) 2026-07-10 22:43:12 -07:00
Siddiqui QamarandJinwoo Hong e3f0b99f4a fix: detect noisy Windows ARM64 SSH platforms (#7965)
* fix: detect noisy Windows ARM64 SSH platforms

- Scan remote platform probe output line-by-line for supported OS/arch markers.

- Handle PowerShell/OpenSSH first-use CLIXML or banner noise before Windows ARM64.

- Add regression coverage for noisy Windows ARM64 detection.

* fix: harden SSH platform probe markers

---------

Co-authored-by: Jinwoo Hong <73622457+Jinwoo-H@users.noreply.github.com>
2026-07-10 22:31:53 -07:00
Neil 4df9457530 Fix delayed terminal color-scheme replies leaking into fish (#8206)
* fix(terminal): send mode 2031 replies immediately

* docs(terminal): name mode 2031 color replies accurately
2026-07-10 21:24:27 -07:00
Jinjing c5044042ea Ai vault view log live tail (#8205)
* Add read-only View Log tabs so AI Vault agent sessions open inside Orca'

- Adds a `readOnly` flag on OpenFile that hard-blocks edits, autosave, dirty
  state, rename, and drafts, and persists/restores it safely across sessions
- Wires AI Vault's View Log/Open Log actions to open logs as permanent
  read-only local tabs instead of shelling out to the OS, gated to
  local, single-file, non-synthetic session paths
- Registers a dedicated `jsonl` Monaco language (JSON-style coloring without
  whole-document JSON validation) and forces read-only tabs to render as raw
  source, bypassing markdown/mermaid/csv/notebook viewers

* Add live-tail streaming for local AI Vault View Log tabs

- Extend the fs:readFile snapshot path with byte-stable file identity so a
  read-only tab can resume appending exactly where the snapshot left off.
- Add a ranged local log tail reader plus IPC (read/start/stop watch) that
  streams only newly appended bytes, detects truncation/rotation, and
  cleans up watchers on tab close or renderer destruction.
- Add a renderer-side UTF-8/line-boundary decoder and useLocalLogTail hook
  that appends completed lines into the existing Monaco model, falling
  back to a full reload on reset/rotation, keeping snapshot behavior
  unchanged when liveTail is not opted in.
- Thread the new `liveTail` flag through OpenFile/PersistedOpenFile,
  workspace session persistence/restore, and the AI Vault "View Log" open
  path so live tail survives restarts and stays read-only-safe.

* Remove stale planning brief for the live-tail feature

The AI-VAULT-VIEW-LOG-LIVE-TAIL.md pick-up brief is no longer needed now that the live-tail streaming work has landed (c7fdef7b1).
2026-07-10 21:22:18 -07:00
Neil 20c9e09cca test(renderer): restore terminal-create fixture parity (#8208) 2026-07-10 21:18:56 -07:00
Neil 6b7732d511 perf: skip terminal wait scans for ordinary output (#8169)
* perf: skip terminal wait scans for ordinary output

* test: record terminal wait performance gate

* docs: clarify terminal wait allocation proof
2026-07-10 21:10:29 -07:00
Neil 84d375ae06 perf: avoid rescanning idle serve-sim PTY output (#8166)
* perf: avoid scanning idle serve-sim PTY output

* test: record serve-sim PTY performance gate

* fix(renderer): dedupe connection context import
2026-07-10 21:04:59 -07:00
b902f19b0d fix(terminal): send CSI-u Shift+Enter to Droid on Windows (#7620) (#7668)
* fix(terminal): send CSI-u Shift+Enter to kitty TUIs (droid) on Windows (#7620)

On Windows, Shift+Enter was always sent as the Alt+Enter byte ESC+CR (added in
#2418 for Codex, which reads win32-input-mode and ignores CSI-u). droid speaks
the kitty keyboard protocol, parses CSI-u directly, and treats ESC+CR as a plain
Enter — so Shift+Enter SUBMITTED the message instead of inserting a newline.
droid works in other terminals (Windows Terminal, Warp) because those honor
win32-input-mode / kitty; Orca (xterm.js) withholds kitty from local Windows
ConPTY panes and emits neither.

Make the Windows Shift+Enter byte pane-aware: latch whether a pane's program
advertised the kitty keyboard protocol (query CSI ? u, push CSI > .. u, or set
CSI = .. u) and send CSI-u (\x1b[13;2u) to those panes, keeping the
Codex-compatible ESC+CR for win32-input-mode-only TUIs. Non-Windows is unchanged
(always CSI-u).

Verified end-to-end against the real droid and Codex CLIs through the actual
production functions: droid now newlines, Codex still newlines.

* fix(terminal): route Windows Shift+Enter safely for Droid

---------

Co-authored-by: Neil <neil@stably.ai>
Co-authored-by: Neil <4138956+nwparker@users.noreply.github.com>
2026-07-10 21:00:31 -07:00
Neil 2a01b41638 perf(main): make worktree path dedupe linear (#8177) 2026-07-10 20:52:24 -07:00
Neil 435de94102 perf(main): avoid hosted-review IPC fanout (#8171) 2026-07-10 20:52:22 -07:00
Neil 943fc781bb perf(runtime): reuse unchanged PTY path history (#8163) 2026-07-10 20:52:17 -07:00
Neil 90afbc3cf3 perf(status-bar): avoid resource badge rebuilds on title churn (#8152) 2026-07-10 20:52:15 -07:00
Neil 141b9b7de2 perf(renderer): gate agent completion coordinator sync (#8149) 2026-07-10 20:52:13 -07:00
Neil a4fb828b3c perf(renderer): scope folder review cache projections (#8136)
* perf(renderer): scope folder review cache projections

* fix(renderer): keep checks selector notifications constant-time
2026-07-10 20:51:59 -07:00
Neil 3afea9e9f2 perf(renderer): scope Markdown worktree path subscriptions (#8111) 2026-07-10 20:51:56 -07:00
Neil e0207cb360 perf(renderer): scope editor draft subscriptions by panel (#8105)
* perf(renderer): scope editor draft subscriptions by panel

* fix(renderer): keep conflict overview drafts live
2026-07-10 20:51:54 -07:00
Neil d617bda234 perf(renderer): scope active review cache subscriptions (#8097) 2026-07-10 20:51:51 -07:00
Neil 8b1054de19 perf(renderer): index runtime owner lookups (#8089) 2026-07-10 20:51:49 -07:00
Neil e5be88342d perf(renderer): reuse connection context indexes (#8085)
* perf(renderer): reuse connection context indexes

* perf(renderer): reuse connection indexes in tab bars

* perf(renderer): reuse worktree index for diff comments

* perf(renderer): index remaining diff comment selectors
2026-07-10 20:51:47 -07:00
Neil e085a84df8 perf(renderer): keep pre-handler PTY buffering linear (#8082) 2026-07-10 20:51:44 -07:00
Neil 65b7d9a532 perf(renderer): compact ignored Cursor title effects (#8080) 2026-07-10 20:51:31 -07:00
Neil 106009a90c perf(renderer): index terminal unified tab reads (#8076) 2026-07-10 20:51:28 -07:00
Neil 09196ba086 perf(renderer): scope floating workspace collections (#8071) 2026-07-10 20:51:26 -07:00
Neil 74e68afbb2 perf(renderer): share terminal agent type index (#8066) 2026-07-10 20:51:23 -07:00
Neil 818e182a0c perf(renderer): gate worktree list review caches (#8061) 2026-07-10 20:51:20 -07:00