Commit Graph
5433 Commits
Author SHA1 Message Date
Merge Sim be6891a08e feat(native-chat): support structured Claude sessions 2026-08-31 17:44:30 -07:00
Jinwoo Hong 26031ca317 fix(browser): scroll oversized viewport presets (#17569)
* fix(browser): scroll oversized viewport presets

* fix(browser): preserve guest wheel scrolling at viewport edges

* fix(browser): keep viewport scroll state synchronized

* test: assert partial viewport wheel forwarding
2026-08-31 20:39:58 -04:00
Brennan BensonandMerge Sim 1a47b9ee85 fix(remote): distinguish SSH transport from runtime availability (#17710)
* fix(remote): distinguish transport from runtime availability

* fix(remote): preserve transport diagnostics for unavailable runtime

* fix(remote): propagate transport diagnostics to host setups

* fix(remote): keep unavailable runtimes out of ready setups

* fix(remote): preserve unavailable runtime state in settings

* fix(remote): preserve reconnecting runtime state

* fix(remote): guard stale settings connectivity

* fix(remote): preserve diagnostics after main merge

* fix(i18n): preserve translations during runtime status merge

* fix(remote): refresh settings row health from store

* fix(remote): refresh settings row health from store

* fix(remote): clear diagnostics generations in tests

* fix(settings): refresh runtime availability summary

* refactor(runtime): split status slice types

* refactor(runtime): reuse status app state type

---------

Co-authored-by: Merge Sim <sim@local>
2026-08-31 17:37:53 -07:00
Neil fa0180dc61 perf(renderer): avoid combined-diff tree rebuilds during progressive loads (#17643)
* perf(renderer): avoid combined-diff tree rebuilds during progressive loads

* fix(renderer): preserve collapsed combined-diff tree boundaries

* perf(renderer): skip unfiltered combined-diff flatten when hiding viewed files

* fix(renderer): keep reordered viewed keys in the combined-diff delta

The incremental viewedSectionKeys delta walked indices issuing a delete
then an add, so a key added at index i and deleted as the previous key at
a later index was silently dropped. Fall back to a full recompute when any
index's key differs; the progressive-load fast path (stable keys, flipping
loading state) is unchanged.
2026-08-31 17:14:34 -07:00
Neil c558d7e083 Activate terminal splits before inherited CWD resolution (#17601)
* perf(terminal): activate splits before cwd resolution

* test(terminal): prove split focus before cwd publish

* fix(terminal): release stale split cwd fence

* test(terminal): add visible split activation latency benchmark

* docs(reliability): clarify split benchmark provenance

* fix: preserve deferred split handoffs across remounts

* fix: fence late deferred split closes

* docs(reliability): record exact split benchmark runs

* test(reliability): fail benchmark on artifact write errors

* test(reliability): attribute split activation phases

* docs(reliability): record schema-v2 split benchmark

* refactor(terminal): collapse duplicated split-handoff and write-queue paths

- Drop the discardDeferredSplitPaneHandoff alias for its identical clear twin.
- Fold the deferred-cwd resolve/reject settle handlers into one applier.
- Extract settlePaneCwdDeferredSpawn for the repeated read-clear-write pattern.
- Share one head-index FIFO primitive between the ordinary and reply queues.

* fix(terminal): stop retaining a promise reaction per acknowledged write

Racing every accepted write against one queue-lifetime cancel promise kept a
reaction record alive until that promise settled: 200k acknowledged writes
retained 88.6MB, now 0.1MB. Give each in-flight write its own cancel, and
split the shared FIFO primitive into its own module.

Also sanitize the split-latency benchmark report at its single serialization
point so shared artifacts no longer carry the machine-local repo path or
unbounded cleanup error text.

* fix(terminal): settle deferred split input when the spawn is abandoned

An abandoned deferred spawn returns before transport.connect(), so nothing
drained the pre-connect buffer: sendInputAccepted's promise never settled and
a paste into that pane hung forever. Clear the buffer on the abandon fence.

Also re-derive the pre-connect retention cap from the clipboard-paste ceiling
rather than the 16MB single-write ceiling; it is held twice per pane across up
to 64 deferred splits, so 5.59M code units guarded the wrong thing.

* fix(terminal): release the deferred cwd fence on a rejected reattach

A daemon createOrAttach can turn an apparent fresh spawn into a reattach; when
that reattach is refused the spawn ends with deferredSplitSpawn/pendingCwd
still set, permanently arming the pre-bind detach refusal. The release no-ops
when a PTY did bind, so it only fires where the fence would otherwise leak.

The stale-generation return above is deliberately left alone: a newer connect
already owns the pane there, and the fence is not generation-scoped.
2026-08-31 16:45:36 -07:00
Brennan BensonandMerge Sim 59facfb71e Show live tool progress in native chat (#17597)
* Show live tool progress in native chat

* fix(native-chat): scope live tool indicator to current turn

* fix(native-chat): settle orphaned live tool rows

* fix(native-chat): keep live tools running without lifecycle metadata

* fix(native-chat): keep working status stable during streaming

* fix(native-chat): anchor turn status below prompts

* fix(native-chat): preserve turn status and legacy tool activity

* fix(native-chat): limit turn status UI to structured Codex

---------

Co-authored-by: Merge Sim <sim@local>
2026-08-31 16:31:30 -07:00
Jinwoo Hong 8f15f217a2 Preserve user-set workspace names across branch changes (#17448)
* fix(worktrees): preserve user workspace names across branch changes

* test(worktrees): cover pinned rename metadata

* fix(workspaces): address display-name review edge cases

* fix(workspaces): keep automatic names fresh across refreshes

* fix(workspaces): preserve legacy CLI labels

* fix(workspaces): preserve display-name provenance across hosts

* fix(workspaces): honor legacy display-name provenance

* fix(workspaces): fence display-name refresh races

* fix(workspaces): accept peer renames from provenance-less hosts

The old-host preserve fence kept a pinned local label on every refresh,
which also suppressed a legitimate rename another client persisted
through the same host until app restart. Narrow it to labels the host
re-derived itself (branch short name, or path basename when detached);
any other changed label in a mode-less response is explicit meta a peer
wrote there. Stale prior-label responses stay covered by the downstream
staleness fence, in-flight writes by the pending fence.

* refactor(workspaces): unify display-name pin derivation

Three call sites (renderer optimistic update, local IPC updateMeta
handler, remote worktree.set handler) each restated the same formula;
a future edit to one would silently skew provenance between paths.
2026-08-31 19:08:05 -04:00
Jinwoo Hong 02a7742406 fix(artifacts): raise desktop sharing limit to 5 MiB (#17708)
* fix(artifacts): raise desktop sharing limit to 5 MiB

* fix(artifacts): enforce recovery content limit

* fix(artifacts): bound recovery request envelopes

* fix(artifacts): clarify oversized request error
2026-08-31 16:51:11 -04:00
Brennan BensonandMerge Sim 9477b5fcbb feat(ssh): batch process evidence in PTY inventory (#17525)
* feat(ssh): batch process evidence in PTY inventory

* fix(ssh): accept Linux kernel process rows and make no-evidence polling push-driven

* fix(ssh): preserve process evidence polling semantics

---------

Co-authored-by: Merge Sim <sim@local>
2026-08-31 12:44:41 -07:00
Jinjing 68de1be517 fix: satisfy GitLab hook and test lint gates (#17694)
* fix: satisfy GitLab hook and test lint gates

* Rename electron-vite target config to .cts

The .cts extension keeps the config as CommonJS, allowing electron-vite
to load each parallel target without sharing its timestamp-named ESM
temp file.
2026-08-31 12:33:50 -07:00
Brennan BensonandMerge Sim aabcc57366 fix(runtime): publish remote control outages to host surfaces (#17531)
* fix(runtime): publish remote control diagnostics to renderer

* test(runtime): account for diagnostics bridge listener

* fix(i18n): add runtime connection state labels

* test(runtime): clean up shared control connection

* fix(runtime): fence diagnostics by shared-control capability

* fix(runtime): preserve authoritative transport state

* fix(runtime): preserve diagnostic overlay lifecycle

* fix(runtime): avoid publishing unchanged diagnostics state

---------

Co-authored-by: Merge Sim <sim@local>
2026-08-31 12:25:17 -07:00
Jinwoo Hong bbbb59e18c test: cover quick commands, catalog links, and long discard dialogs (#17489) 2026-08-31 14:56:15 -04:00
Jinjing 393992cbe7 Add show-more button for recent tabs in empty-query palette (#17693)
* feat: add show-more button for recent tabs in empty-query palette

* Reveal all recent tabs in one show-more click, limit badges to 9

The show-more button now expands the entire recent tabs list instead of
paging through it. Badges are limited to the first 9 rows since only
those digit positions are addressable in the keyboard chord.
2026-08-31 09:23:47 -07:00
Jinjing d5d3c4898a perf(diff): defer large diffs until user loads them (#17521)
* perf(diff): defer large diffs until user loads them

Rendering very large diffs would freeze the UI. Diffs exceeding
MAX_AUTOMATIC_DIFF_CHANGED_LINES now show a prompt allowing users
to load them on demand instead of automatically rendering.

* perf(diff): defer large diffs until user loads them

Diffs with >10,000 changed lines are now deferred and only rendered when
the user explicitly clicks "Load diff" in a prompt. This improves initial
render performance for large file changes while maintaining full access
when needed.

* perf(diff): defer large diffs until user loads them

Prevents UI freeze when opening files with very large diffs by
deferring render until the user explicitly loads them.

* fix(diff-view): defer loading large untracked files and refactor fallbac

Split on-demand load decision logic to distinguish tracked vs untracked files — large untracked files now properly defer loading while untracked images remain automatic. Extract fallback height computation into a dedicated function to centralize the logic for render-limited and in-flight-loading states, reducing code duplication and clarifying when to use bounded fallback heights.

* fix(diff-view): defer loading large SVG files

SVG renders as source text in the diff view rather than a preview, so should defer like other text files. Also fix Windows e2e test cleanup by using post-Electron shutdown.
2026-08-31 09:20:12 -07:00
NeilandBrennan Benson fbe94ceff6 fix: close readiness gaps found by merged-change audit (#17159)
* fix(ssh): fence stale kills and retired pane replay

* fix(ssh): support cancellable interactive authentication

* fix(ssh): await remote catalog before snapshot adoption

* fix(pty): contain Windows ConPTY input failures

* fix(power): avoid redundant macOS display blocking

* perf(editor): narrow markdown override subscriptions

* fix(quick-open): close directory handles after reads

* refactor(linux): remove unused proc socket scanner

* fix(usage): apply flat Sonnet 4.6 pricing

* ci: prime Node next native test cache

* docs(skills): resolve snapshot cleanup data path

* fix(ssh): recover install locks after host reboot

* test(ssh): recognize boot-aware install locks

* test(ssh): prove previous-boot lock recovery live

* test(wire): pin pre-metadata release coverage

* fix(terminal): preserve remote tab ownership through recovery races

* test(runtime): fence replaced terminal handles in agent guard

* fix(ssh): preserve remote snapshot authority across polls

* fix(pty): contain late ConPTY output EPIPE

* test(pty): register Windows exit watcher before kill

* fix: close SSH and tab readiness race gaps

* fix(tabs): retain headless order and placeholder titles

* fix(build): avoid parallel electron-vite config race

* test(windows): avoid MSYS temp path rewriting

* test(windows): avoid killing exited PTY

* fix(pty): avoid late ConPTY input teardown race

* fix(terminal): sync reconnect error ownership after commit

* fix(runtime): use canonical worktree identity comparison

* test(ssh): assert complete cold-hydration baseline

* test(windows): invoke quoted retention fixture via PowerShell

* test(windows): read ConPTY grid through mode con

* fix(terminal): publish PTY replacements atomically

* fix(terminal): infer stale identity on reattach

* fix(terminal): fence stale pane PTY callbacks

* fix(terminal): fence stale pane binds after rebind

* fix(terminal): reject stale pane transport callbacks

* fix(terminal): fence mirrored reattach spawn callbacks

* fix(terminal): replace stale pane PTYs on remount

* fix(ci): size the Windows launcher-compile test budget from measurement

`native-smoke (windows-latest)` fails ~4.5% of runs on
`preserves a multiline argument through the compiled remote launcher`
with "Test timed out in 15000ms" — on unrelated PRs, for reasons that
have nothing to do with them. Across 176 sampled attempts it is the only
red that job produced, and it hit seven different PRs in two days:
#16900, #16904, #16915, #16955 (twice), #16979, #17014, #17085.

The test is six process creations: powershell.exe forks csc.exe, then
the freshly compiled orca.exe forks node.exe, twice. Hosted Windows
runners periodically slow process creation down, and this test amplifies
that far harder than anything else in the job. Comparing the 80 attempts
where it ran under 3s against the 12 where it ran over 12s, its own
median goes 2198ms -> 15917ms (7.2x) while the same file's
powershell-only test moves 556 -> 686ms (1.2x), the cmd.exe and Git Bash
process tests in the neighbouring file move 1.4x, and the other 35 files
put together move 1.5x.

Measured across those 176 attempts: 1881ms to 35438ms, p50 4264ms,
correlation +0.881 with the job's total Vitest duration. 8 of 176 (4.5%)
exceeded the 15s cap; 2 of 176 (1.1%) also exceeded the shared 30s
testTimeout, so deleting the override and inheriting the config is not
enough on its own. 60s clears all 176 with 1.7x headroom on the worst.

This is slow, not hung. Every body here is synchronous spawnSync, so
Vitest cannot interrupt one — the timer fires only after the body
returns and the reported duration is real elapsed time. That is why a
failure reads `× ... 22464ms` under `Test timed out in 15000ms`. The
work finished; the stopwatch was short. Seven reruns at one identical
head measured 2053 / 4680 / 5551 / 8732 / 13506 / 14868 / 21937ms — the
last of those would have been red on code that had not changed.

The 15s came from #8897, which raised this test off Vitest's built-in 5s
default because the job then ran bare `pnpm vitest run`. #8909 landed
3h27m later and pointed the job at config/vitest.config.ts, which is the
real fix for that. The constant stayed behind and has been the binding
budget ever since.

* fix(terminal): fence stale remount reattach ownership

* fix(terminal): reconcile mounted pane identity after replacement

* fix(terminal): fence stale reattach fallback ownership

* fix(terminal): fence deferred SSH reattach ownership

* fix(terminal): fence stale split pane ownership callbacks

* fix(terminal): keep stale spawns from consuming startup

---------

Co-authored-by: Brennan Benson <79079362+brennanb2025@users.noreply.github.com>
2026-08-31 08:17:40 -07:00
Neil 6bbed15a11 fix(worktree): gate agent activation on the live surface census, not renderer state (STA-5701) (#17428)
* fix(worktree): gate agent activation on the live surface census, not renderer state (STA-5701)

* fix(worktree): seed a pane when the surface census cannot prove ownership (STA-5701)

Failing closed must not also fail silent. When the census is unverifiable
the sweep adopts nothing and mints nothing, yet the gate still reported
'adopted' — and both callers suppress their own seeding on any outcome but
'empty', so the workspace ended with zero surfaces. The sweep now reports
whether any live PTY holds a surface and the gate hands the caller its seed
when none does. Also folds equivalent workspace-path spellings in the census
index and in exact-surface binding, so a host row spelled differently is
neither dropped (mint a duplicate) nor unbindable (no pane).

* fix(worktree): name the live PTYs the surface census declined (STA-5701)

The adoption sweep can leave a live PTY without a surface — an unreadable
census, two host surfaces claiming one PTY, or a host-named leaf the
persisted layout does not have. The gate already stops reporting 'adopted'
in that case so the caller seeds a shell, but the decline itself was mute.

- adoptLiveWorkspacePtySurfaces now returns { surfaced, declinedPtyIds }
  and the gate warns with the workspace and the PTY ids left unsurfaced.
- Pin the host-named-leaf decline, which had no test either way.
- Pin the superseded-inventory race in terminal.list: a concurrent refresh
  makes hostScope.hostIds empty, which is what makes the renderer's
  'unverifiable' verdict reachable on a plain local machine.
2026-08-31 01:40:54 -07:00
Neil 6cc9319d87 perf(wsl): warn at project-add when the tree sits on a Windows drive (#17636)
* perf(wsl): warn at project-add when the tree sits on a Windows drive

Worktree placement now puts new workspaces inside the distro, but a project
whose own tree is on C:\ still pays the 9p/drvfs crossing on every git command
it runs — measured at ~20x for a clean `git status` against the same tree on
ext4. Nothing in the UI says so, so the project just feels slow.

Warn once, right after the add succeeds, naming the distro the project's git
actually runs in. The advisory is wrapped so it can never fail the add.

Two path shapes cross the boundary and both warn: a Windows drive path under a
WSL project runtime, and the UNC spelling of a distro's own drvfs mount
(\\wsl.localhost\Ubuntu\mnt\c\...), which crosses it however the runtime is set.
A tree already inside the distro, a drive path under Windows-host git, a plain
UNC share, and every POSIX/SSH path stay silent.

* chore(i18n): register the WSL filesystem boundary advisory keys in en.json
2026-08-30 23:48:50 -07:00
Jinwoo Hong 46fa1a98d0 fix(browser): show reload loading feedback (#17635) 2026-08-31 02:46:17 -04:00
Neil 017811f0de perf(renderer): memoize active worktree editor files (#17484)
Reuse the filtered editor-file projection while Terminal rerenders without changing its inputs.
2026-08-30 23:40:45 -07:00
Neil c55121231a fix(remote): re-activate the pending host surface on paired PTY attach (STA-5291) (#17429) 2026-08-30 23:21:18 -07:00
Neil 900fce25cd perf(renderer): cache active terminal chrome projection (#17480) 2026-08-30 23:05:28 -07:00
Neil 435a5e2490 perf(renderer): index folder workspace host ownership (#17468) 2026-08-30 23:05:12 -07:00
Neil d20679e609 perf(renderer): cache project host setup projection reads (#17463) 2026-08-30 23:04:59 -07:00
Neil fb271f2f3b perf(renderer): cache startup action selector (#17458) 2026-08-30 23:04:37 -07:00
Neil 8e132880be perf(renderer): stabilize window visibility action selector (#17457) 2026-08-30 23:04:25 -07:00
Neil 225b28199a perf(renderer): avoid remote PTY selector allocations (#17454) 2026-08-30 23:04:17 -07:00
Neil 3cb44480c1 perf(renderer): narrow app root settings subscriptions (#17451) 2026-08-30 23:04:03 -07:00
Jinwoo Hong 87d9bc12c0 fix(persistence): stop rejected UI trailing flush loops (#17378)
* test(sta-5938): pin persisted UI rejection retry behavior

* fix(persistence): bound rejected UI trailing flushes
2026-08-31 01:47:49 -04:00
Jinjing 5897b7b4f5 ui: highlight completed downloads with success styling (#17617)
Completed downloads now display with a success background and text color to make their completion status more visually obvious.
2026-08-30 21:27:34 -07:00
Brennan BensonandMerge Sim 91cc834584 fix(remote): preserve standing host reconnect intent (#17067)
* fix(remote): preserve standing host reconnect intent

* chore(lint): merge duplicate imports flagged by the native code-quality audit

* fix(remote): fence stale capability runtime identities

* fix(remote): release capability evidence on host removal

---------

Co-authored-by: Merge Sim <sim@local>
2026-08-30 21:17:06 -07:00
Jinjing 3060cf73b9 fix(tasks): restore scroll position when reopening GitHub item details (#17524)
Track scroll-restore generation to invalidate stale callbacks that were
resetting the scroll position to 0 when reopening a detail page. Prevent
restoration while a detail page is open.

Update automation test to use runtime.call RPC instead of removed preload
CRUD method. Hide browser import hint in E2E profile to prevent overlay from
intercepting test setup clicks.
2026-08-30 20:28:35 -07:00
Neil ad5ba2572e perf(dashboard): build sidebar bucket counts without cards (#17497)
* perf(dashboard): build sidebar bucket counts without cards

* fix dashboard bucket parity for unified agent tabs

* docs(dashboard): clarify count projection comment

* refactor(dashboard): share bucket projection derivation
2026-08-30 20:12:41 -07:00
Neil 8eaae88bf1 perf(agent-status): coalesce deferred freshness scans (#17496) 2026-08-30 19:50:42 -07:00
Neil 947c8d3864 perf(renderer): cache structured session tab projection (#17477) 2026-08-30 19:50:21 -07:00
Neil f55f9352df fix(perf): index mirrored agent tab mappings for cleanup (#17476) 2026-08-30 19:49:39 -07:00
Brennan BensonandMerge Sim 728691173e feat(native-chat): preview pending image attachments (#17517)
* feat(native-chat): preview pending image attachments

* fix(native-chat): preserve remote image previews

* fix(editor): clear pinned image cache state on dispose

* fix(native-chat): defer offscreen image previews

---------

Co-authored-by: Merge Sim <sim@local>
2026-08-30 19:49:01 -07:00
Jinjing 68bb227a11 fix(tasks): preserve GitHub list scroll restoration (#17547) 2026-08-30 19:25:46 -07:00
m4air ce9482b4db fix(jira): negotiate user-field support with remote hosts 2026-08-30 19:16:14 -07:00
Jinjing 0d8785b916 Prevent stale search commits from timer race conditions (#17495)
Validate scheduled values match current state before executing idle
timeout callbacks. Use useLayoutEffect to synchronously update refs,
preventing outdated searches when rapid keystrokes overwrite timers.
2026-08-30 19:07:01 -07:00
a651e81843 refactor(agents): remove dead hook IPC and derive shared agent defaults (#16089)
* refactor(agent-hooks): drop the unused per-agent hook status IPC surface

No renderer, CLI, or mobile caller invoked window.api.agentHooks.*Status; main
already reads install status through MANAGED_AGENT_HOOK_STATUS_READERS. The
14 handlers had also drifted (kimiStatus existed in main/preload but not in
AgentHooksApi or the web stub).

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

* refactor(tui-agent-config): default launchCmd and expectedProcess to detectCmd

32 of 36 entries repeated the binary name three times. Entries are now
authored in a source form where both default to detectCmd and resolved once
at module load, so TUI_AGENT_CONFIG keeps its exact shape for consumers
(verified equal to the previous table).

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

* refactor(mobile): derive the agent order, labels, and picker from src/shared

The mobile mirror (and its regex-over-desktop-source parity test) predates
mobile importing runtime values from src/shared, which it now does in a dozen
modules. Only the favicon-domain map stays mobile-local because desktop's lives
in the renderer catalog next to bundled ?url imports. The parity test now
imports the real registries and also checks label parity.

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

* test(web): align preload surface after hook IPC removal

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Brennan Benson <79079362+brennanb2025@users.noreply.github.com>
2026-08-30 19:02:14 -07:00
Jinjing fe82569b97 Stabilize Tiptap editor instance across prop changes (#17526)
- Change useEditor dependency array to empty, preventing recreation
- Tiptap now updates live options instead of reparsing initial content
- Preserves selection, undo history, and document across rerenders
- Add tests verifying editor stability and option handling
2026-08-30 19:00:05 -07:00
Aldin SaracevicandClaude Opus 5 df48337d72 fix(jira): scope reporter seed and keep multi-user fields on the text path
Review follow-ups on the create-field shaping:

- Seed only `reporter`. isVisibleJiraCreateField matches every required
  non-system field, so the previous filter also pre-filled required custom
  user pickers (Reviewer, Requested by) that Jira never defaults.
- Skip the seed when the target project is on another site. The viewer
  comes from the active site, and the host shapes against the target's
  client, so a foreign accountId is rejected on Cloud and can silently
  resolve to a different person by username on Server/DC.
- Render JiraUserPicker only for scalar user fields. It holds one user, so
  an array-of-user field collapsed to a single member; those keep the
  existing comma-separated text path, which still reaches toUserFieldValue's
  array branch.

Adds docstrings across the touched Jira functions to satisfy the
docstring-coverage pre-merge check.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HdMzQN6T3jRVahCK2sNyur
2026-08-30 18:55:40 -07:00
Aldin Saracevic 634478c620 fix(jira): shape user-typed create fields and seed reporter with viewer
- Jira rejects a bare string for reporter/user-picker fields on issue
  create, so shape customFields values into {accountId}/{name} objects
  for keys the caller flags via userFieldKeys.
- Seed required user fields with the authenticated viewer by default
  and add a searchable user picker (jira.searchUsers) so users aren't
  forced into free text for reporter/custom user fields.
2026-08-30 18:55:40 -07:00
a0d36f5290 fix(agents): keep OMP identity and forward ask/approval events (#15713)
* fix(agents): keep OMP identity and forward ask/approval events (STA-4130)

A live OMP pane was re-owned as Pi because the generic pi-compatible
fallback always won, ask events blocked without a question payload, and
OMP suppressed tool_approval_* unless an extension registered handlers.

Mark Pi as the title-group fallback so a specific OMP identity is not
downgraded, publish OMP ask input as the existing questions envelope, and
forward tool_approval_requested/resolved onto blocked/working.

STA-4130
Related to #14278

Co-authored-by: devatnull <59279509+devatnull@users.noreply.github.com>

* fix(agents): keep launch Pi ownership over OMP wrapper frames (STA-4130)

The pi-compatible fallback treated every generic Pi owner as inferred, so an
explicit launch-Pi pane (and a launchless Pi pane with an OMP-shaped title)
was re-owned as OMP. Launch provenance now stays authoritative; only an
inferred status-frame owner yields to a specific sibling, and same-group
titles no longer count as reuse.

STA-4130

* fix(agents): drop Pi wrapper idle titles while OMP hook is active (STA-4130)

Title-completion suppression compared pick-a-winner ownership, so a Pi ready
frame looked like a different agent than a live OMP hook and fired a spurious
task-complete notification. Reuse checks now use the title-identity group.

STA-4130

* fix(agents): restore OMP approval forwarding after merge

* fix(agents): restore title-owner API after merge

* test(agents): update identity inventory ratchet

---------

Co-authored-by: devatnull <59279509+devatnull@users.noreply.github.com>
Co-authored-by: Merge Sim <sim@local>
2026-08-30 18:51:24 -07:00
Brennan BensonandMerge Sim e54cfc1901 fix(omp): read Pi/OMP static state-title markers and retire stale spinners (#14602)
* fix(omp): read Pi/OMP static state-title markers and retire stale spinners

OMP 17.2.12 replaced its animated braille title frames with static markers
on WSL/ConPTY (`π : working`, `π > idle`, `π ! needs input`). Orca read all
three as idle, so a working OMP pane lost its status, and a synthetic title
spinner started by an earlier hook kept rotating after its status row was
gone.

Classify the markers from one shared table so a later upstream punctuation
change is a row, not a reparse, and stop the spinner when the hook row it
stands in for is cleared or dismissed.

Fixes #13890

* test(omp): preserve static state titles during normalization

---------

Co-authored-by: Merge Sim <sim@local>
2026-08-30 18:50:56 -07:00
SahirandClaude Fable 5 60a7ac3804 feat(browser): edit a page annotation's comment and intent inline in the tray (#17511)
* feat(browser): edit a page annotation's comment and intent inline in the tray

Fixing a typo in a browser annotation required deleting it and re-picking
the element in the page. Each tray row now has a hover-revealed edit
button that swaps the row to an inline editor (comment textarea seeded
with the current text, intent toggle, Save/Cancel), reusing the compose
card's submit shortcut and length budget. Edits route through a new
updateBrowserPageAnnotation store action that no-ops on a missing id and
sanitizes the merged annotation exactly like the add path.

Escape inside the editor cancels only the row edit: the annotate mode's
window-level capture listener now exempts the edit container, since
stopPropagation from a descendant cannot reach a capture listener.

Editing is deliberately limited to comment and intent: element targets,
cross-navigation persistence, and the prompt builder are untouched (the
builder reads live off the array, so edited text flows through).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017rEaTnSaSneEMEJvebzM53

* test(browser): pin the annotate-mode Escape exemption for annotation edits

The data-slot annotation-edit clause in useGrabMode's capture keydown
listener had no test that dispatched a keydown through it, so deleting
the clause left the suite green. These tests invoke the real registered
capture handler with an Escape whose target sits inside (and outside) an
annotation-edit container; the inside case uses a button, which
isEditableKeyboardTarget does not cover, so only the exemption clause
can keep grab mode alive. Removing the clause now fails the suite.

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-30 18:44:37 -07:00
OrcaWinandm4air a4bf9bb1e8 fix(settings): allow Escape to close from controls (#17516)
docs(orchestration): clarify terminal worktree selection

Co-authored-by: m4air <m4air@m4airs-Air.localdomain>
2026-08-30 18:38:41 -07:00
Brennan BensonandMerge Sim 50871aee2b Show remote host failure details in a submenu (#17062)
* Show remote host failure details in submenu

* chore(i18n): sync catalog for remote host submenu strings

* fix(status-bar): keep remote host actions accessible

* fix(status-bar): preserve submenu keyboard navigation

* fix(status-bar): drop the submenu chevron on remote host rows

The panel sits at the screen edge, so Radix collision-flips the submenu to the
left. A right-pointing chevron then points away from where the menu opens.
hideChevron is opt-in, so the 21 other SubTrigger consumers are unchanged.

---------

Co-authored-by: Merge Sim <sim@local>
2026-08-30 18:17:15 -07:00
Brennan BensonandMerge Sim f2e9ba453c fix(agent-hooks): route reminted pane keys to canonical identity (STA-3993) (#15714)
* fix(agent-hooks): route reminted pane keys to canonical identity (STA-3993)

Spawn was stripping $$<base32>:L$$ ORCA_PANE_KEY values (and the launch
token) instead of rewriting them to the metadata-proven tab:leaf key, so
OMP hooks never entered last-status.json and sleeping rows stayed working.

Alias that exact remint form onto the canonical pane so later posts still
route, and keep unmatched tokens from stamping another pane.

* fix(agent-hooks): keep reminted pane-key aliases first-pane-wins

Remint tokens have no embedded tab identity, so a later spawn that reused
the same $$ token with a different tab/leaf was overwriting the alias and
routing leftover hook posts onto the new pane. Refuse destination changes
for that form while still allowing same-pane pty id updates.

* fix(agent-hooks): keep pane alias limit import valid after refactor

* fix(agent-hooks): bound pane alias destination keys

* fix(ssh): keep pane identity env stripped when hooks disabled

---------

Co-authored-by: Merge Sim <sim@local>
2026-08-30 17:54:13 -07:00
Brennan BensonandMerge Sim b2eec5980b fix(native-chat): route app menu image paste in codex chat (#17498)
Co-authored-by: Merge Sim <sim@local>
2026-08-30 17:35:24 -07:00