Commit Graph
7469 Commits
Author SHA1 Message Date
Merge Sim 04e4eeab5a fix(ipc): tighten the canonical envelope stripper for caller-prefixed message-less envelopes
Adds a failing-first regression test proven by ablation. Produced by the #17237
review loop; kept on the review branch rather than pushed to the PR branch.
2026-08-30 16:58:16 -07:00
Brennan Benson bc53c7ab1a fix(ipc): keep the class-prefix strip case-sensitive
`stripErrorClassPrefix` took a case-insensitive flag from the two AccountsPane
copies it replaced, which widened `LinuxPackageInstallRecoveryCard` — that site
matched `/^Error:\s*/` on main. The only thing this trims is
`Error.prototype.toString()` output, which V8 always writes as `Error: `, so the
flag could never match a real class prefix the case-sensitive pattern misses; it
could only eat the lowercase severity marker git, rpm, dpkg and pip put in front
of a real reason. `IPC_ENVELOPE`'s own `\w*Error:` group in the same module is
already case-sensitive.

All three call sites now agree, and the card matches main again.
2026-08-29 20:12:30 -07:00
Brennan Benson ac484307c9 refactor(ipc): route every renderer IPC failure through the canonical stripper
`extractIpcErrorMessage` kept its own regex on the grounds that 18 call sites
depended on its fail-open behaviour. It has 30, all user-facing, and its regex
handed users the wrapper for two envelope shapes, dropped the caller's own
prefix, truncated multi-line reasons at the first newline, and leaked the
handler's error class name.

It now delegates to the canonical stripper and owns no pattern. Four sites whose
fallback was the stringified rejection get readable copy instead, so an envelope
with nothing behind it can no longer reach a user through the fallback either.
Falling back logs the rejection, which none of these sites did before.

Two censuses back it: one enumerates the 30 call sites, one holds the envelope
to a single owning file.
2026-08-29 20:12:30 -07:00
Brennan Benson b2eb055a9c refactor(ipc): make the canonical envelope stripper the only one
#17230 added stripIpcInvokeEnvelope as a canonical home for Electron's IPC
wrapper. It was the sixth implementation, not the first: nine other files
carried ten hand-rolled copies, and they disagreed.

Measured against a shared corpus, the copies split four ways. An envelope whose
tail has no "Error: " prefix — Electron builds that tail from the main side's
error.toString(), so a rejected non-Error produces one — was left fully visible
by quick-open. A message-less handler failure rendered the bare word "Error" in
the Linux recovery card, the voice download toast and the AI Vault scan row; an
empty tail rendered an empty string in all three. Every copy was anchored at ^,
so an envelope a caller had prefixed with its own context stayed on screen. The
two AccountsPane copies were scoped to their own channel, so a rejection from
any other channel kept its wrapper.

All ten now route through one stripper, moved to src/shared because
ai-vault-scan-error-message is imported by main and cannot reach a renderer-only
module. The canonical regex additionally covers "Error occurred in handler for",
which AccountsPane stripped and the canonical one did not, and a separate
stripErrorClassPrefix keeps the bare "Error: " trim that three sites had — that
prefix is Error.prototype.toString(), not the envelope, and an existing Linux
card test caught its loss.

Nothing is swallowed. The three sites that gained a null fallback now
console.warn the original rejection, which none of them logged before, and
Electron still logs the handler's original error with its stack in main.

extractIpcErrorMessage keeps its own fail-open regex and its 18 call sites are
untouched: it returns the tail verbatim and never returns null.

A census test pins the envelope to the two files that own it, so a seventh copy
fails CI. It lists nine offenders against the pre-fix tree.
2026-08-29 20:12:30 -07:00
Brennan Benson a9cbc76065 fix(workspaces): stop a failed delete showing Electron's IPC envelope
A workspace delete that the classifier does not recognise fell through to a
branch that renders the failure string verbatim. For an IPC rejection that
string is Electron's own wrapper — "Error invoking remote method
'worktrees:remove': ..." — so a safe refusal read as a broken app.

Adds stripIpcInvokeEnvelope to the canonical ipc-error module: it returns the
reason behind the wrapper, or null when the wrapper carried no readable reason
(Electron builds the tail from the main side's error.toString(), so a
message-less handler failure arrives as a bare class name). The eight
user-facing sites in the delete flow now route through one copy function that
falls back to a human sentence on null.

Nothing is swallowed: deleteStateByWorktreeId keeps the raw string, the
renderer still console.warns the rejection, and Electron itself logs the
handler's original error with its stack in the main process.

extractIpcErrorMessage keeps its fail-open contract byte-for-byte so its 18
existing call sites are unaffected.
2026-08-29 20:12:29 -07:00
Neil 8ff8e8a5f3 Split hosted review creation checks (#17152)
* Split speech session lifecycle

* Split terminal output scheduler pipeline

* Split mobile browser pane modules

* Prune resolved max-lines suppressions

* Split pane tree equalization logic

* Extract mobile troubleshoot screen styles

* Split external automation manager

* Split main window service attachments

* Split hosted review creation checks

* Fix F3-speech for #17123

* Fix F1-cycle for #17131
2026-08-29 20:08:36 -07:00
Neil ecee14bdbc Split main window service attachments (#17151)
* Split speech session lifecycle

* Split terminal output scheduler pipeline

* Split mobile browser pane modules

* Prune resolved max-lines suppressions

* Split pane tree equalization logic

* Extract mobile troubleshoot screen styles

* Split external automation manager

* Split main window service attachments

* Fix F3-speech for #17123

* Fix F1-cycle for #17131
2026-08-29 20:08:08 -07:00
Neil 7b5bed9550 Split external automation manager (#17149)
* Split speech session lifecycle

* Split terminal output scheduler pipeline

* Split mobile browser pane modules

* Prune resolved max-lines suppressions

* Split pane tree equalization logic

* Extract mobile troubleshoot screen styles

* Split external automation manager

* Fix F3-speech for #17123

* Fix F1-cycle for #17131
2026-08-29 20:07:46 -07:00
Neil 11a0deb8ee Split pane tree equalization logic (#17145)
* Split speech session lifecycle

* Split terminal output scheduler pipeline

* Split mobile browser pane modules

* Prune resolved max-lines suppressions

* Split pane tree equalization logic

* Fix F3-speech for #17123

* Fix F1-cycle for #17131
2026-08-29 20:07:03 -07:00
Neil 871601b6fe Prune resolved max-lines suppressions (#17142)
* Split speech session lifecycle

* Split terminal output scheduler pipeline

* Split mobile browser pane modules

* Prune resolved max-lines suppressions

* Fix F3-speech for #17123

* Fix F1-cycle for #17131
2026-08-29 20:06:41 -07:00
Neil e39c22c1ce Split terminal output scheduler pipeline (#17131)
* Split speech session lifecycle

* Split terminal output scheduler pipeline

* Fix F3-speech for #17123

* Fix F1-cycle for #17131
2026-08-29 20:04:35 -07:00
Neil 53eb21b448 Split speech session lifecycle (#17123)
* Split speech session lifecycle

* Fix F3-speech for #17123
2026-08-29 20:04:04 -07:00
Neil 162df6e5e9 fix(crash): suppress Linux namespace SIGTERM reports (#17315) 2026-08-29 19:43:23 -07:00
NeilandOrcaWin 3457acb647 fix(memory): hydrate retained PTYs before diagnostics (#17308)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-08-29 19:42:56 -07:00
Neil 4e9ef12861 test(persistence): give the 130k-leaf pane alias scale test headroom (#17323)
The test runs ~9-15s locally but times out against the 30s default on a
loaded CI shard, flaking the node 24 test shard and the verify gate.
2026-08-29 19:41:01 -07:00
Jinjing 0a995cc30d Fix md file rendering 2 (#17295)
* Improve markdown rich mode: distinguish HTML tags from placeholders

- Consolidate size limit and unsupported content checks into single function
- Refine HTML/JSX detection to validate against rehype-sanitize's known tag names
- Allow bare placeholders like `<id>` and `<project-id>` in rich mode rendering

* Add decision explainer for markdown rich-mode rendering fix

* rm html explainer
2026-08-29 18:14:03 -07:00
Neil de851d5ca7 perf(terminals): drop disposed queued inspections (#17187) 2026-08-29 16:25:30 -07:00
Neil 7ae916cebd perf(worktrees): batch-prune stale local metadata (#17278) 2026-08-29 16:06:15 -07:00
Neil 9c777ca89e perf(renderer): gate pending agent-status retries (#17254) 2026-08-29 16:03:35 -07:00
Neil 1fe558dd28 perf(automations): narrow status observer updates (#17249) 2026-08-29 16:02:29 -07:00
Neil e258785884 perf(terminal): index accepted input pane ownership (#17287) 2026-08-29 16:02:10 -07:00
Neil 79aea81173 perf(renderer): index unread completion tabs (#17246) 2026-08-29 16:01:42 -07:00
Neil be68aa2718 perf(browser): release popup origin bar contents (#17234) 2026-08-29 16:01:39 -07:00
Neil 5e3c4f391c perf(terminal): bound stalled setup-split polling (#17228) 2026-08-29 16:01:36 -07:00
Neil ad499df893 perf(markdown): reuse rich eligibility state (#17219) 2026-08-29 16:01:33 -07:00
Neil 7879dead69 perf(ssh): cache legacy worktree clean fallback (#17213) 2026-08-29 16:01:29 -07:00
Neil eb6cd67219 perf(editor): skip unchanged review-note reflows (#17212) 2026-08-29 16:01:27 -07:00
Neil 80a0595449 perf(startup): stop rescanning persisted pane tabs (#17179)
* perf(startup): index persisted pane tabs once

* perf(startup): lazily resolve persisted pane tabs
2026-08-29 16:01:23 -07:00
Neil bf884ea866 perf(startup): skip disabled diagnostic serialization (#17176) 2026-08-29 16:01:20 -07:00
Neil 0645729f68 perf(worktrees): resolve watcher targets concurrently (#17166) 2026-08-29 16:01:16 -07:00
Jinjing 2214d29f15 fix(browser): close guest-owned split tab (#17281)
* fix(browser): close guest-owned split tab

* fix: check sourceId before toggling floating panel on close

The empty-panel toggle is the ambient fallback only. Guest-initiated
closes (with sourceId) target the main workspace and should not toggle
the panel.

* test(browser-split-shortcuts): remove terminal-mirrors close test and un

Removes test case that verified Cmd+W closes guest-owned browser splits when
active-tab mirrors point to a terminal, along with the helper function and
unused fixture properties that only that test required.
2026-08-29 15:43:36 -07:00
Jinjing 8b01cf1a48 Clarify automation history unavailability and improve recovery UX (#17284)
* Clarify automation history unavailability and improve recovery UX

- Improve error message to explain run history is unavailable due to host
  version requirements, not automation failure
- Hide misleading "0 runs" count badge when history is unavailable
- Deep-link "update server" recovery actions to specific runtime environment
  in settings instead of pane root
- Add test coverage for run count hiding and recovery targeting

* Watch for deep-linked settings targets that render asynchronously

Some settings panes (such as Remote Orca Servers) fetch and render their
rows asynchronously. Deep links can name targets that don't exist yet,
but the scroll effect has no way to know when they finally mount. Add a
MutationObserver-based watcher to detect when async rows appear and
trigger scrolling.
2026-08-29 15:07:38 -07:00
Neil b826b3fa5b feat(editor): raise rich Markdown size limit to 600 KB (#17288) 2026-08-29 15:03:36 -07:00
JahyunBaek e3757a1d30 fix(worktree): ignore orphan remote-tracking refs in branch conflicts (#16699)
Refs #16646

Unify native, WSL, and direct SSH conflict checks behind the execution host, remove the duplicated SSH classifier, and cover orphan/configured remote behavior across both paths.
2026-08-29 14:36:24 -07:00
Neil 7655d20f04 fix(terminal): complete OMP stale cwd recovery (#17154) 2026-08-29 14:34:50 -07:00
JahyunBaekandClaude Opus 5 aa95bdb11a test(shared): stop two suites asserting POSIX separators on Windows (#16511)
Both files describe paths with POSIX literals while their subjects compose
paths through `node:path`, so the assertions only hold where the separator
happens to be `/`.

`node-markdown-document-discovery` keys its fake tree at `/repo/docs` and
`/repo/one`, but `discoverMarkdownRelativePaths` descends with
`join(absoluteDirectoryPath, entry.name)` — `\repo\docs` on win32. The child
lookup misses, `readDirectory` yields nothing, and the walk stops at the root:
`docs/guide.mdx` disappears and the depth-limit case never reaches its limit,
so it resolves `[]` instead of rejecting. Keying the children with `join` walks
the tree the subject actually walks.

`git-fetch-head-lock` expects `cwd: '/tmp/repo'` from a subject that returns
`path.resolve(cwd, 'repo')`, which is `C:\tmp\repo` on win32. Asserting through
`path.resolve` pins the behaviour — that `-C` and `--git-dir` are resolved
against the cwd — rather than the separator of whichever machine runs the suite.

Verified on Windows 11: the two files go from 3 failed / 12 passed to
14 passed / 1 skipped, and the wider `src/shared` run shows no regression.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-29 14:23:22 -07:00
Jinjing 67fa855b6c Make worktree palette hint rows keyboard-clickable (#17272)
* Make worktree palette hint rows keyboard-clickable

Hint entries like "See more" are now CommandItems that can be navigated with arrow keys and activated with Enter, instead of being non-interactive divs. This allows keyboard-only users to access the expand actions without mouse interaction.

* Make worktree palette "See more" keyboard-navigable

Preserve cursor position when expanding via keyboard: auto-select the first
newly revealed item at the previous index and restore input focus.
2026-08-29 14:15:45 -07:00
Neil 2dfaa676d8 chore: update oxlint and oxfmt (#17150) 2026-08-29 14:13:35 -07:00
Neil 78bba0772a perf(markdown): cache repeated syntax highlighting (#17158) 2026-08-29 13:59:45 -07:00
Neil 0bf5361c92 perf(markdown): update code highlighting incrementally (#17147) 2026-08-29 13:52:16 -07:00
Neil eb00123a81 perf(markdown): skip unmatched list tokenizer scans (#17134) 2026-08-29 13:43:27 -07:00
Neil 7c0c9cee57 perf(markdown): skip closed-search update renders (#17162)
* perf(markdown): skip closed-search update renders

* test(markdown): stress closed-search updates
2026-08-29 13:41:33 -07:00
Jinjing 9940355f6e Improve worktree palette layout with flex-1 titles (#17273)
Adds flex-1 to palette open tab titles so they expand to fill
available space, making better use of the palette's horizontal layout.
2026-08-29 13:33:35 -07:00
Neil fb6c2800ee fix(gpu): capture hardware identity in crash reports (#16973)
* fix(gpu): capture hardware identity in crash reports

* fix(gpu): order bounded crash diagnostics before fallback

* fix(gpu): keep fallback persistence ahead of diagnostics
2026-08-29 02:41:53 -07:00
Junhyeok Chae 314dcba98b feat(i18n): localize Agent Dashboard to Korean (#17121)
- Translate Agent Dashboard column headers (Needs You / Working / Idle), board title, and total count.
- Translate empty-column placeholder, "You" message badge, terminal preview actions, and error-boundary copy.
- Resolves English fallback in the Agent Dashboard (dashboardPopout) under the Korean locale; only "Done" was previously translated.
2026-08-29 02:38:32 -07:00
Neil c5591d0893 fix(gpu): persist the safe-graphics marker before the restart prompt (#16945)
* wip: gpu-startup-recovery

* fix(gpu): offer hardware retry after safe recovery
2026-08-29 02:29:15 -07:00
Neil 9db319dc06 fix(terminal): recover OMP from stale working directories (#17128)
* fix(terminal): recover OMP from stale cwd

* fix(terminal): harden OMP cwd recovery
2026-08-29 02:27:44 -07:00
Neil 8d3e32a2ff Fix setup-provisioned skills missing at agent startup (#17124)
* fix(setup): let repos gate agent startup

* test(setup): update runner call expectations
2026-08-29 01:53:31 -07:00
Neil fec82b9bc8 test: widen updater schedule boundary margin (#17130) 2026-08-29 01:49:02 -07:00
Neil d73d36bc99 test: stabilize process and transcript liveness checks (#17126) 2026-08-29 01:45:20 -07:00