Commit Graph
6382 Commits
Author SHA1 Message Date
Jinjing 088d613e55 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.
2026-07-10 22:53:39 -07:00
Jinjing af93ba949d 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.
2026-07-10 22:22:20 -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
Neil b681a2c54a perf(renderer): scope agent send-target control updates (#8055) 2026-07-10 20:51:18 -07:00
Neil fadb3f3730 perf(renderer): scope sidebar agent freshness by worktree (#8052) 2026-07-10 20:51:15 -07:00
Jinjing 5e100914d3 fix(mobile): recover terminal WebView/WebGL/viewport/theme state after iOS resume (#8196)
* fix(mobile): recover terminal state after iOS resume

* Refactor terminal record merge to extract snapshot-reconciliation helper

Split the inline merge logic in mergeTerminalRecordsByCurrentOrder into a
named mergeTerminalSnapshotWithKnownRecord function for clarity, preserving
the existing behavior of keeping the last known theme when a snapshot omits it.
2026-07-10 20:22:16 -07:00
NeilandOrca e825df8218 perf(memory): skip unrelated boot worktree scans (#8204)
* perf(memory): scope boot worktree scans to live sessions

* fix(memory): refresh daemon hydration snapshots

* fix(memory): rescan repos referenced only by the re-read snapshot

Repo selection previously came solely from the first daemon listing, so a
session that only became visible on the post-enumeration re-read (e.g. a
briefly unreachable adapter) could never be registered for the life of the
process. Loop enumeration until the latest daemon snapshot references no
unresolved repos, so selection and registration always share a snapshot.

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

---------

Co-authored-by: Orca <help@stably.ai>
2026-07-10 20:10:08 -07:00
2cfb028163 fix: Cap automationRuns retention to stop unbounded state file growth (#8119)
* Cap automationRuns retention to stop unbounded state file growth

`automationRuns` was the only unbounded durable collection in
`orca-data.json`, and the whole blob is re-serialized and rewritten on
every save. On a machine running four `* * * * *` automations it had
grown to 11,184 rows / 21 MB of a 28.5 MB file — all of them
`skipped_precheck` no-ops — so each synchronous `flush()` blocked the
Electron main thread for 190-210 ms and macOS filed 24 `disk writes`
diagnostic reports against Orca (12-30 MB/s sustained, 549 GB/session).

Prune to the newest 100 runs per automation, on load and on append. This
mirrors the retention that `pruneLocalTerminalScrollbackBuffers` and
`pruneWorkspaceSessionBrowserHistory` already apply to their
collections; `automationRuns` was simply missed.

The load-path prune marks state dirty, so an oversized file heals on
first load. Without that flag the shrink lives only in memory: the sole
load-time save trigger is `normalized.changed || loadNeedsSave ||
adaptedProjectGroups`, and `normalized` covers pane identity only. A
user who took the documented workaround (`automations edit --disabled`)
fires no runs, so nothing would ever rewrite the file.

Measured against the affected 28.5 MB file: flush() 190 ms -> 9 ms,
bytes written per save 28.5 MB -> 1.3 MB.

Pruning breaks the old `runNumber` derivation, which counted retained
runs, so every run after the cap would have been titled "run 101".
Carry the ordinal on the run itself and derive the next number from the
highest survivor. Legacy rows are numbered from the highest number their
automation already carries, not from their append position: a downgrade
to a pre-`runNumber` build appends unnumbered runs after pruned
survivors numbered 101+, and a position would reissue one of those,
giving two runs the same title.

Fixes #8118

* Never evict in-flight automation runs from retention

A dispatched run's completion can land hours later (renderer round-trip or
headless completion promise); pruning it makes updateAutomationRun throw
'Automation run not found.'. Only final-status runs are evictable now, with
the final-status predicate shared between retention and the service.

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

* Skip the usage write when retention evicted the run mid-collection

markDispatchResult finalizes a run, awaits usage collection, then writes
usage by id. The run is final during that await, so a concurrent
create-time prune can evict it and the write threw 'Automation run not
found.' — in the headless path that cascaded into an unhandled rejection.

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

* Pin backfill-before-prune ordering with true legacy fixture rows

The heal-on-load fixture rows carried runNumber, so swapping backfill and
prune passed every test while renumbering real legacy survivors 1..100 and
re-minting colliding titles. Seed unnumbered rows and assert healed ordinals.

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

---------

Co-authored-by: Neil <4138956+nwparker@users.noreply.github.com>
Co-authored-by: Orca <help@stably.ai>
2026-07-10 20:02:45 -07:00
Neil 66437d19c3 perf(hook-commands): skip unrelated store flushes (#8181) 2026-07-10 19:56:03 -07:00
Neil 5eda948a7a perf(agent-startup): skip unrelated store flushes (#8179) 2026-07-10 19:56:00 -07:00
Neil 0eafb0e626 perf(ai-vault): index visible session pane lookups (#8173)
* perf(ai-vault): index visible session pane lookups

* perf(ai-vault): build pane index lazily
2026-07-10 19:55:57 -07:00
Neil c7777e44a6 Reduce terminal redraw CPU on active TUIs (#8178) 2026-07-10 19:50:44 -07:00
Jinjing a916a93df3 Make explicit desktop take-back always release the mobile presence lock (#8200)
Previously a failed resize during reclaimTerminalForDesktop left the
override/lock in place (#7588 semantics), but for an explicit "take
back all terminals" gesture that could strand banners on background
panes whose resize can't converge. Now the take-back unconditionally
releases the driver and clears any held fit-override via a new
releaseDesktopTakeBack helper, while auto-restore and phone-initiated
paths keep the original keep-lock-on-failure behavior.

Also extract the local mapWithConcurrency helper out of
workspace-cleanup.ts into a shared, tested src/shared/map-with-concurrency.ts
and use it to bound concurrent desktop-fit reclaims in
terminal-fit-restore.ts.
2026-07-10 19:41:27 -07:00
Jinjing 5a8078e755 Improve search box on mobile (#8187)
* Redesign mobile search field as a shared, raised component

- Extract MobileSearchField from duplicated Search icon + TextInput + clear
  button markup in worktree list and tasks screens into a reusable component
- Give the field a raised bgRaised shell with focus/disabled states so it
  reads as a tappable control instead of blending into panel chrome
- Fix delayed autoFocus via InteractionManager + timeout so the keyboard
  reliably appears after the search bar opens
- Preserve per-screen clear behavior (preset/query fallback for GitHub,
  project-view filter) via configurable showClear/onClear props

* Simplify GitHub project search state checks and fix stuck clear button

- Extract `isGithubProjectSearch` to dedupe repeated `provider === 'github' && githubMode === 'project'` checks
- Fix showClear so an explicit empty applied override doesn't leave the clear button visible forever
2026-07-10 19:40:40 -07:00
632a3c18a6 feat(jira): sort Jira issues by key, issue, status, priority, assignee and updated (#7959)
* fix(jira): add sortable columns to Jira issues in task page

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* test(jira): add comprehensive tests for Jira issue sorting functionality

Add test coverage for the new Jira issue sorting features including:
- Priority weight calculation with fallback logic
- Sorting by key, title, priority, assignee, and updated date
- Issue grouping and section ordering after sorting
- Handling of edge cases like unassigned assignees and unknown priorities

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix: resolve coderabbit review comments on jira issue sorting

- Extract getJiraPriorityWeight and sorting logic into a shared jira-issue-sorter module.
- Fix grid column definitions on md viewports in TaskPage.tsx.
- Implement cancelled flags in useEffect hooks in TaskPage.tsx to guard against stale responses.
- Swapped priority weights mapping to blocker=99, lowest=1, missing=0 to sort ascending from lowest-to-highest priority using weightA - weightB.
- Focus-ring enhancements on sort button headers and aria-expanded/chevron fix on collapsible groups.
- Remove duplicate helpers from unit tests and verify the new sorting expectations.

* fix(jira): harden issue sorting review gaps

---------

Co-authored-by: Andres Van Reepingen <andres.vanreepingen@datacamp.com>
Co-authored-by: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Jinjing <6427696+AmethystLiang@users.noreply.github.com>
2026-07-10 19:39:17 -07:00
github-actions[bot] 6f4919c2e1 release: v1.4.135-rc.5 v1.4.135-rc.5 2026-07-11 02:32:52 +00:00
Jinjing 7adeb18f19 fix(cleanup): reconcile authoritative late removal results (#8194)
* fix(cleanup): reconcile late removal results

* fix(cleanup): report authoritative late removals
2026-07-10 19:31:47 -07:00
Jinjing 60c26af8b8 fix(linear): preserve mixed-version RPC filtering compatibility (#8192)
* fix(linear): guard mixed-version RPC filtering

* fix(linear): surface filter capability failures correctly

Prevent capability checks from pinning to rejected compatibility cache
entries, and rethrow typed attribute-filter unsupported errors from the
Linear store so TaskPage can show an upgrade message instead of an empty
filtered list.

* fix(runtime): refresh cached capability verdicts

* test(linear): mock isLinearIssueAttributeFilterUnsupportedError

Prevents the invalidation slice test from failing after the runtime
client gained this export, which was otherwise undefined in the mock.

* Fix cold-cache capability probes firing duplicate status.get calls

Coalesce concurrent status.get requests for the same environment by
publishing the in-flight probe to the compatibility cache before
awaiting it, so parallel capability checks share one RPC call. On
failure, drop the cache entry immediately since this probe always
re-fetches and must not leave a stale cached verdict.
2026-07-10 19:23:12 -07:00
e2b4bc2c2c feat(cli): make the CLI self-correcting and self-describing for agents (#6303)
* feat(cli): make the CLI self-correcting and self-describing for agents

Agents build a generalized model of how CLIs work and apply it to every
tool. When orca diverged — `rm` where git uses `remove` — a reasonable
first guess (`orca worktree remove`) dead-ended on a bare "Unknown
command" with no path forward. This makes the CLI degrade gracefully when
the orca-cli skill isn't loaded in context.

- First-class CommandSpec.aliases, resolved to the canonical path before
  dispatch (no new handler registrations). `worktree remove`/`delete` now
  resolve to `rm`; the ad-hoc `terminal focus` duplicate spec/handler is
  migrated onto the mechanism.
- Did-you-mean suggestions on unknown commands and unknown flags, ranked
  by edit distance over the live registry, surfaced in both stderr and
  --json error.data (reusing the existing nextSteps channel).
- `orca agent-context [--json]`: a versioned, machine-readable dump of the
  command schema. Pure local read (no RPC), so it works over SSH and when
  the app isn't running.
- CI guards: specs<->handlers parity, and a vocabulary policy that fails
  on new off-policy deletion/read verbs (existing ones grandfathered).

* Address PR review feedback (#6303)

- agent-context now emits each command's effective flag set (globals +
  conditional --page), not just allowedFlags, so the schema no longer
  under-reports --json/--help. Shared as effectiveAllowedFlags() between
  validation and the schema.
- Collision check now covers alias paths too, so a duplicate alias that
  would silently shadow a real command fails the build.

* fix(cli): harden agent recovery and introspection

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

---------

Co-authored-by: Jinwoo-H <jinwoo0825@gmail.com>
Co-authored-by: Orca <help@stably.ai>
2026-07-10 19:17:01 -07:00
Neil 3d3e0ea0b1 perf(file-explorer): batch and debounce ignored checks (#8103) 2026-07-10 19:10:01 -07:00
Neil 69776e8d2b Upgrade to TypeScript 7 and Electron 43 (#8189) 2026-07-10 19:08:12 -07:00
Jinjing aa9871183f fix(settings): isolate provider account discovery failures (#8190)
* Fix provider account discovery isolation

* fix(review): mark remote WSL provider accounts active correctly

Remote Windows lists host and WSL accounts together, but Active used the
forced host selection only, so selected WSL accounts never lit. Scope Active
to each account's own runtime slot, and cover reverse partial-load failures.

* fix(review): scope remote WSL account restart checks

* Fix WSL default-account row highlighting a stale "System default" badge

- The forced-host activeAccountId (Codex/Claude) could show as active alongside
  a genuinely active WSL account when a WSL distro is flattened to host scope,
  since the host default id stays null in that case.
- Derive activity from whether any visible row is active instead, and share a
  WSL_DEFAULT_DISTRO_KEY sentinel between the distro Select and the active-id
  resolver so they can't drift out of sync.

* Fix provider account isolation and remove-dialog stale state bugs

- Treat a failed provider's substituted empty roster as non-authoritative
  in fetchProviderAccountsSnapshot/watchProviderAccounts consumers
  (AccountsPane, StatusBar switchers), so a Codex/Claude fetch failure
  no longer wipes out the healthy provider's list or shows a false
  empty state.
- Capture the account's runtime slot when the remove-account dialog
  opens (removeCodexTarget/removeClaudeTarget) instead of re-deriving
  it from the live roster on confirm, since the roster can change
  underneath an open dialog and misroute the restart check.
- Compute "System default" active state against the full account
  roster when a remote owner's platform is unknown, since WSL rows
  fail-closed and hide from the visible list in that case.
- Guard the deferred onError emission with a closed check so an
  onSnapshot handler that closes the watcher doesn't trigger a second
  error callback.
2026-07-10 18:52:41 -07:00
Jinjing c41ca07e8e Fix WSL Codex auth timeout state (#8183) 2026-07-10 18:43:00 -07:00
Vitus ebeb947dee fix: normalize wrapper-prefixed OMP/Pi terminal titles (#8033)
Multiplexer/session wrappers prefix pane titles as "prefix | pane-title", pushing the Pi/OMP identity after " | ". Inspect each " | " suffix and prefer a re-ownable compatible identity over the wrapper text, so wrapped OMP/Pi titles normalize to the owner instead of flickering. Includes guard tests for braille-inner labels and no-identity wrappers.
2026-07-10 18:42:48 -07:00
Jinjing 7b6eb3cc06 fix: keep dispatch task preview after status normalization (#8185)
* fix: keep dispatch task preview after single-line status normalization

Agent-status prompts fold multi-KB dispatch preambles to ~200 single-line
chars, which previously kept only lifecycle boilerplate and dropped the
TASK body. Compact dispatch prompts to preserve task id + body, extract
that as the UI fallback before orchestration labels arrive, and prefer
richer labels once they match the live dispatch.

* fix: harden dispatch status prompt compaction

* fix: share dispatch task-marker parsing with UI preview helpers

Round-2 adversarial review found getOrcaDispatchTaskPreview still used
naive indexOf, so raw multi-line preambles with base-drift subjects
mentioning === TASK === could surface the wrong fallback label. Export
the standalone-line marker finder and use it on both compaction and UI
preview paths, with regression coverage for raw and single-line forms.
2026-07-10 18:32:51 -07:00
github-actions[bot] 7b6653e65d release: v1.4.135-rc.4 v1.4.135-rc.4 2026-07-11 01:27:50 +00:00
Jinwoo Hong e6906d60a2 STA-1598: Handle CRLF project headers during Codex config repair (#8197) 2026-07-10 18:26:16 -07:00
Neil 533992bdda fix(git): cache unsupported capabilities per host (#8109)
* fix(git): cache unsupported capabilities per host

Old Git worktree, ref-search, and merge-tree fallbacks retried unsupported flags on recurring operations, flooding subprocess traces. Centralize capability probing per native, WSL, and SSH execution host, coalesce concurrent probes, and retry periodically for in-place Git upgrades.

* fix(git): recognize real old-Git merge-tree rejection

* test(git): enforce real binary compatibility matrix

* fix(ci): preserve Git compatibility test ownership

* fix(git): retain supported capability state
2026-07-10 18:19:36 -07:00