Commit Graph
11496 Commits
Author SHA1 Message Date
Jinjing 418fbb3192 fix(mobile-ios): gate release on TestFlight distribution (#13419) 2026-08-10 01:47:36 -07:00
Neil eacb9a9fa4 perf(automations): keep output snapshot appends linear (#13469) 2026-08-10 01:36:08 -07:00
Brennan Benson 9060a88dde fix: contain unbroken dialog failure output (#13531) 2026-08-10 01:24:54 -07:00
Neil 131010277c [Perf-LH] Serialize relay JSON payloads once per publication (#13516)
* perf(relay): reuse serialized JSON payloads

* Defer bulk relay payload preparation until admission
2026-08-10 01:17:14 -07:00
d305e48547 fix(gitlab): guard against non-array API responses in MR/issue listing (#12911)
* fix(gitlab): guard against non-array API responses in MR/issue listing

fetchIssuesAsWorkItems and listMergeRequests parsed glab's JSON output
and called .map straight on it. When the GitLab API returns a JSON
object instead of an array (error body, unexpected shape) on a
successful exit, this crashed with a bare TypeError that got
misclassified as "Failed to load issues: JSON.parse(...).map is not
a function" instead of a useful message.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* fix(gitlab): cover listIssues and keep payloads out of error classification

The guard missed listIssues in issues.ts — the RPC-backed issue list that
produces the reported "Failed to load issues: JSON.parse(...).map is not a
function". Hoist the guard into glab-api-response.ts so both files share it.

The thrown message is fed to classifyGlabError, which substring-matches it.
A response payload is content, not a diagnostic: an MR titled "fix network
timeout" classified as network_error and the canned copy replaced the payload
the user needed. Report a GitLab error envelope by its own message, and mark
an opaque body so classification is skipped.

* test(gitlab): make the list-guard tests fail on the regressions they name

Two assertions were vacuous under mutation. The envelope test used a "403
Forbidden" message whose keyword matches earlier in the classifier chain than
its sibling payload, so leaking the payload into classification still passed;
it now uses a 404 envelope beside a "403 forbidden" sibling. No call-site test
carried a classifier keyword, so deleting the marker-error branch entirely
failed only one unit test; the MR API path now uses a keyword-bearing body.

Also give the non-list branch the same "Failed to load issues" prefix as every
other list error, cover the `{ error }` envelope field, and pin the thrown type.

* test(gitlab): pin the reported-payload bound

Removing the 300-char slice survived the whole suite, and the banner's
break-words now depends on it. Name the limit and assert both branches
truncate, plus the envelope falling through a blank message to `error`.

* test(gitlab): pin message-over-error envelope precedence

Swapping the lookup order passed the whole suite. Anchor the bound regex too
so it cannot match an incidental ": " near the end of a message.

---------

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
Co-authored-by: Brennan Benson <79079362+brennanb2025@users.noreply.github.com>
2026-08-10 01:10:12 -07:00
hwantageandBrennan Benson 14dc499aa5 fix(ai-vault): preserve agent metadata header on session row expansion (#10920)
* fix(ai-vault): preserve agent metadata header on session row expansion

* chore(tests): remove redundant comment in AiVaultSessionRow test

* test(ai-vault): add happy-dom environment and window.api shim to AiVaultSessionRow tests

* test(ai-vault): assert the expanded session row via the rendered row

Replaces the parallel static-markup harness and second fixture with the
file's existing Testing Library row render, so both suites share one
session fixture and one prop list. Raw HTML substring matches are gone:
the identity assertions now run inside the metadata grid, because the
details-toggle button's aria-label repeats the agent name and made the
old check pass with the fix reverted.

Tags the grid with a data-testid like the row's other query anchors
rather than walking up from a text node, adds cleanup() — the suite has
no globals: true, so rows leaked across tests — and guards that the
worktree badge renders once when expanded. SessionWorktreeLine loses an
export the row no longer imports.

---------

Co-authored-by: Brennan Benson <79079362+brennanb2025@users.noreply.github.com>
2026-08-10 01:07:17 -07:00
ce3ec4d5ce fix(repo-icon): keep a renamed fork's own owner avatar (#12271)
* fix(repo-icon): keep a renamed fork's own owner avatar

Fork repos always took the upstream owner's avatar, so a renamed fork
showed its parent project's logo. Same-name forks (personal copies)
still prefer the upstream owner; renamed forks now keep their origin
owner across auto-detect, the startup backfill, and the settings
avatar refresh.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(repo-icon): re-read repo state before backfill avatar write

The startup backfill computed icon updates from a pre-loop snapshot, so
an icon chosen in settings while the upstream/origin probes were pending
could be clobbered. Re-read the repo after the probes and only migrate
an icon that is still the auto-detected GitHub avatar.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* refactor(repo-icon): own the fork avatar rule in one shared selector

The renamed-fork rule was written out twice — once in the main-process
auto-detect and once in the renderer refresh — so the two copies could
drift. Move it next to `githubAvatarIcon` as `githubAvatarSlug`, which
collapses the renderer resolver to a single unbranched path.

Also stop swallowing a rejected origin probe: it cannot tell a renamed
fork from a same-name one, so degrading to the upstream owner would flip
a renamed fork's stored avatar back to the parent's. Letting it propagate
keeps the stored icon, matching how the non-fork path already behaved.

Adds coverage for the startup backfill, the third decision point the fix
claims, which had none.

* test(repo-icon): cover pending backfill icon change

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Brennan Benson <79079362+brennanb2025@users.noreply.github.com>
2026-08-10 01:06:32 -07:00
Brennan Benson 4e536a5232 Improve Agent Map hover and presence motion (#13407)
* feat(agent-map): improve hover and presence motion

* fix(agent-map): derive exiting popover state

* fix(agent-map): bound exit motion lifecycle

* perf(agent-map): avoid duplicate motion commits
2026-08-10 01:03:09 -07:00
Neil 75f5e2d964 perf(renderer): reuse prepared native chat messages (#13519) 2026-08-10 01:00:20 -07:00
Neil e78bf2b6ea [Perf-SS] Keep relay writer drains linear under deep backlogs (#13449)
* perf(relay): keep writer queue drains linear

* test(relay): cover replacement after consumed cursor
2026-08-10 00:59:51 -07:00
Brennan Benson 66aed16974 refactor(ui): consolidate toggle switches (#13432)
* refactor(ui): consolidate toggle switches

* fix(ui): label consolidated switches
2026-08-10 00:54:30 -07:00
Mark XianandBrennan Benson 80f23e31cb fix(file-explorer): open symlink files when stat fails (#11670)
* fix(file-explorer): open symlink files when stat fails

* fix(file-explorer): grant symlink targets path access on activation

Following a symlink out of the workspace was denied by the main-process
path allow-list, so both the stat and the file read failed. Activating the
row is explicit intent, so authorize the target the way terminal links and
Quick Open already do.

---------

Co-authored-by: Brennan Benson <79079362+brennanb2025@users.noreply.github.com>
2026-08-10 00:53:54 -07:00
Neil c5023fa0ab perf(main): skip impossible advertised URL scans (#13514) 2026-08-10 00:29:26 -07:00
Doyoon LeeandBrennan Benson 33dad13e64 fix: wrap unbroken auto-rename failure output (#12317)
* fix: wrap unbroken auto-rename failure output

* test(sidebar): cover unbroken auto-rename failure containment

happy-dom does no intrinsic sizing, so assert the two declarations that
keep an unbroken token from widening DialogContent's grid column. The
test fails when either min-w-0 or overflow-wrap:anywhere is reverted.

---------

Co-authored-by: Brennan Benson <79079362+brennanb2025@users.noreply.github.com>
2026-08-10 00:24:00 -07:00
Neil c498d763cd perf(renderer): unmount closed jump palette content (#13525) 2026-08-10 00:18:54 -07:00
Brennan Benson 8a3f704bd1 fix(agent-dashboard): highlight agents awaiting input (#13523)
* fix(agent-dashboard): highlight agents awaiting input

* test(agent-dashboard): cover status halo boundaries
2026-08-10 00:16:54 -07:00
Brennan Benson 0fa3a5bd1d Show directional lineage in agent map (#13503)
* Show directional lineage in agent map

* Route agent lineage links diagonally

* Guard agent map lineage path bounds

* Avoid chevrons in undersized lineage gaps
2026-08-10 00:16:21 -07:00
Neil abd160fadd perf(renderer): defer terminal quick command host work (#13517) 2026-08-09 23:43:58 -07:00
Jinjing f5d934a3f5 3c5f0060 (#13496)
* refactor(runtime): extract pure path-candidate, review-branch, and folder-workspace helpers from orca-runtime.ts

Mechanical move of three closed, pure module-scope clusters out of
orca-runtime.ts (37,608 -> 37,207 lines) into domain-named siblings:

- terminal-output-path-candidates.ts: PTY output path harvesting and the
  recent-candidate history bound (3 entry points + 15 private callees).
- selected-review-branch.ts: forge-agnostic selected-review predicates and
  lookup hints (GitHub/GitLab/Bitbucket/Azure DevOps/Gitea).
- runtime-folder-workspace.ts: folder-workspace id math and the repo+meta
  -> Worktree projection.

Bodies are token-identical to their previous form; the only production
changes are the moves, the new import statements, and `export` keywords.
The no-control-regex suppression travels with the path-candidate scanning
that needs it. No max-lines suppression was added and the ratchet is
unchanged.

Adds characterization tests for the two clusters that had no direct
coverage; the path-candidate cluster keeps its existing tests, repointed
at the new module.

* fix flaky timer on CI
2026-08-09 23:37:33 -07:00
Neil 73efab98f7 perf(orchestration): keep drift Git off main thread (#13440) 2026-08-09 23:26:28 -07:00
Neil 016df33f00 fix(github): complete PR reactions for CodeRabbit reviews (#13456)
* feat(github): add PR comment reaction controls

* feat(github): add full PR comment reaction picker

* fix(github): cover all reactable PR comment paths

* fix(github): reconcile comment reactions with main

* fix(github): preserve focus on failed reaction removal
2026-08-09 23:14:17 -07:00
Brennan Benson d6362deb04 feat(agent-hooks): support Prime Agent status in WSL (#13430) 2026-08-09 22:55:32 -07:00
Neil 7dce0442ab Add Caffeinate controls to the status bar (#13480)
* feat: add caffeinate status controls

* refactor: compact caffeinate status

* fix: harden caffeinate readiness
2026-08-09 22:52:11 -07:00
Neil 8859e73980 perf(main): retire stale worktree marker probes (#13437) 2026-08-09 22:24:33 -07:00
Neil f2b2ece831 perf(renderer): reuse locale collators (#13444) 2026-08-09 22:24:09 -07:00
Jinwoo HongandJinwoo-H 158212b8b3 feat(github): add PR comment reactions (#13470)
* feat(github): add PR comment reactions

* fix(github): harden comment reaction updates

---------

Co-authored-by: Jinwoo-H <Jinwoo-H@users.noreply.github.com>
2026-08-09 22:11:54 -07:00
Jinwoo Hong d9e84d88ef fix(persistence): salvage corrupt workspace session entries (#13431) 2026-08-09 21:39:24 -07:00
Neil 4cca31f36f fix(quick-open): compact Cmd+P file rows (#13454) 2026-08-09 21:21:18 -07:00
Neil 9ccec550c3 Add emoji picker to workspace editing and search (#13429)
* Add emoji picker to workspace editing and search

* fix(sidebar): scope sticky headers by host

* fix: address emoji picker review findings
2026-08-09 20:25:15 -07:00
Jinwoo Hong 6e63bbbb52 fix(computer-use): prevent repeated screen recording prompts (#13427) 2026-08-09 20:20:36 -07:00
OrcaWinandOrcaWin bdd763188f Fix Windows AI Vault resumes using the wrong shell (#13420)
* fix: use project shell for AI Vault resumes

* fix: preserve WSL cwd fallback semantics

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-08-09 19:52:16 -07:00
Jinwoo Hong ce8c3267b7 feat(terminal): add anchored link action popovers (#13414) 2026-08-09 19:27:01 -07:00
Neil 6c765d5ad3 refactor(mobile): remove native chat re-export facades (#13436) 2026-08-09 19:25:28 -07:00
Neil faaf3d2588 refactor(mobile): use shared diff and OSC implementations (#13433) 2026-08-09 19:16:26 -07:00
Jinwoo Hong a3ca887a3c fix(workspaces): start task agents on remote hosts (#13412) 2026-08-09 19:09:49 -07:00
Neil f3ea376b6b refactor(rate-limits): share initial account target policy (#13428) 2026-08-09 19:06:07 -07:00
Neil 8a33ce2536 [leas code] Simplify boolean guards (#13401)
* refactor: remove unreachable code

* refactor: simplify boolean guards
2026-08-09 19:04:05 -07:00
Jinjing 3b1017c4fb Add nightly cut (#13410)
* Add daily macOS dev build release channel

Publish once-daily signed macOS builds from main at a dedicated cadence,
separate from hourly (too noisy) and release branches (too infrequent).
Builds are notarized and installable via the updater, but unvetted —
published to stablyai/orca-daily rather than the main repo to avoid
evicting stable/RC entries from the releases feed.

* fix lint

* fix commit

* Add third token mint to daily macOS build workflow

The upload step's 2x45m retry budget can outlive the one-hour token, so a third
is minted after it for verify and cleanup operations. Release notes are moved to
a file to ensure consistency between draft creation and publish. Daily channel
description updated with specific UTC release time.
2026-08-09 19:01:35 -07:00
Neil 403c60bbad refactor(mobile): remove unused review code (#13421) 2026-08-09 18:55:36 -07:00
Neil 934faaec76 refactor: deduplicate Linear team readers (#13417) 2026-08-09 18:54:22 -07:00
Neil 8a38e2f3f8 refactor(renderer): reuse existing control paths (#13425) 2026-08-09 18:50:56 -07:00
OrcaWin 75650936f4 fix(source-control): hydrate Windows shell profile PATH (#13418) 2026-08-09 18:42:15 -07:00
JinjingandOrca b075a95b06 Strip liveness gate from AI Vault session delete (#13279)
* Strip liveness gate from AI Vault session delete

Delete now requires only path validation + user confirmation — no process
roster, no liveness check, no quiescence, no ownership ledger.

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

* Remove obsolete AI Vault liveness delete reliability gate

Session delete no longer checks process liveness, so drop the
manifest entry that still referenced the deleted test files.

* minor fix

---------

Co-authored-by: Orca <help@stably.ai>
2026-08-09 18:40:01 -07:00
cb6069ceea fix(ui): align toggle switch handle symmetrically in on state (#9714)
* fix(ui): align toggle switch handle symmetrically in on state

The switch handle (translate-x-4 / 16px) left a 6px gap on the right
in the on state while the off state had only a 2px gap on the left.
Accounting for border-box sizing (1px border each side reduces content
width to 34px), the correct on-position is translate-x-4.5 (18px) so
both sides have a 2px inset.

* docs: add JSDoc to exported functions in changed files for docstring coverage

* fix(ui): align toggle switch handle symmetrically in on state

The `h-5 w-9` switch track is `border-box` with a 1px border, leaving 34px
of content for the 14px `size-3.5` handle. `translate-x-0.5` insets the off
state by 2px, so the on state needs 34 - 14 - 2 = 18px. It used
`translate-x-4` (16px), leaving 4px on the right against 2px on the left.

Adds a boundary test so the offset cannot drift again across the 26
hand-rolled switch call sites, and drops the docstrings the original patch
added to satisfy a coverage bot (the surrounding files carry none).

Original patch by @sei0.

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

* test(ui): widen the switch-handle alignment guard to every h-5 w-9 track

Scan the renderer with the readdirSync walk and TypeScript AST already used by
no-top-level-translate.test.ts instead of shelling out to `git grep`, and find
each knob inside its own track rather than by scanning source text forward.

Why: gating on `role="switch"` silently skipped ClaudeUsageLoadingState.tsx (a
loading skeleton, so a div with no role) and HiddenExperimentalGroup.tsx, so
regressing the loading-state handle back to translate-x-4 left the guard green.

The guard now also fails when the premise behind 34 - 14 - 2 = 18px stops
holding: a track that loses its 1px border or gains padding, a conditional whose
two branches no longer pair off/on, and a track whose knob moved into a child
component where the scan would otherwise just stop seeing it.

---------

Co-authored-by: Neil <4138956+nwparker@users.noreply.github.com>
Co-authored-by: Orca <help@stably.ai>
Co-authored-by: Brennan Benson <79079362+brennanb2025@users.noreply.github.com>
2026-08-09 18:34:05 -07:00
Neil 1e72534709 refactor: deduplicate repository search entries (#13415) 2026-08-09 18:31:36 -07:00
Neil 65a5e8470a refactor: share GitHub link normalization (#13409) 2026-08-09 18:31:16 -07:00
Neil c56ff58dd7 test(mobile): centralize renderer setup (#13408) 2026-08-09 18:31:00 -07:00
Neil 954de38507 refactor(mobile): remove unused PR and review code (#13404) 2026-08-09 18:30:44 -07:00
Neil ced2719b26 refactor: remove unreachable code (#13400) 2026-08-09 18:29:32 -07:00
Brennan Benson b2e29a2247 Fix Ctrl+Z in Windows and Linux terminals (#13398)
* fix(terminal): preserve Windows undo chords

* fix(terminal): keep undo menu hints unregistered
2026-08-09 18:14:39 -07:00