Skip to content

build: desktop-tabbed-app - #435

Merged
aryeh-stark merged 27 commits into
mainfrom
build/desktop-tabbed-app
Jul 27, 2026
Merged

build: desktop-tabbed-app#435
aryeh-stark merged 27 commits into
mainfrom
build/desktop-tabbed-app

Conversation

@stark-claude-21s

Copy link
Copy Markdown
Contributor

Stage-2 stark-build run. Spec: docs/specs/2026-07-27-desktop-tabbed-app-spec.md (spec PR #434, accepted-base 686807a). Run: /Users/aryeh/.claude/code-review/history/build/desktop-tabbed-app/20260727T082622Z

@stark-codex-21s

Copy link
Copy Markdown

Advisory review (codex, read-only, one-shot — findings are input for the human):

  • [P1] Cmd+N/menu tab switching can destroy the chat transcript. In openMainWindow, switching to a different tab calls existing.loadFile(..., { hash: tab }). loadFile performs a document navigation/reload, so the renderer context — and its in-memory transcript — is discarded. The spec only permits transcript loss when the main window is closed; switching tabs must preserve it. Evidence: apps/desktop/src/main/app-shell.ts, openMainWindow() existing-window branch.

@stark-claude-21s

Copy link
Copy Markdown
Contributor Author

stark-build run summary (run 20260727T082622Z, accepted-base 686807a, spec PR #434)

Task Status Commit
T1 ADR-0005 🟢 green 5efdd27 (runner-committed)
T2 brain stats 🔴 blocked (2 dispatches) 71adecb WIP — overview regen + contract-lint phase sets remain
T3 listGeminiModels 🟢 green 63a97ae
T4 renderer bundle 🟢 green d16bf64 (runner-committed)
T6 IPC expansion 🟢 green 826d96c
T5 main window shell 🔴 blocked (2 dispatches) cb199d4 WIP — 6 own-TDD tests red (main-window ×4, popover-open-atlas ×2)
T7–T14 ⏸ not dispatched every gate runs the desktop suite, which carries T5's reds — dispatches were guaranteed red

Closing e2e: RED at tools contract-lint (T2's derived-overview drift) — the honest divergence signal, no fix loop run. PR stays draft. Deviations mirrored into the spec's ## Deviations (PR #434). Advisory (codex): one P1, posted above. Evidence: ~/.claude/code-review/history/build/desktop-tabbed-app/20260727T082622Z/. Harness notes: max-turns was the dominant failure mode (5 of 8 dispatches); one runner harness bug (protected evidence path) fixed mid-run; concurrent machine load caused two false hang probes.

Next moves are the operator's: (a) resume with a fresh run for T2+T5 remainders (small, well-named deltas) then T7–T14, (b) finish T2/T5 interactively, or (c) rescope.

🤖 Generated with Claude Code

@stark-claude-21s

Copy link
Copy Markdown
Contributor Author

Round 2 close-out (operator-directed, scoped to the T2+T5 remainders):

Task Status Commit
T5R (shell remainder + advisory P1 fix) 🟢 green runner-committed — desktop 648 ✓, a11y 49 ✓; tab switch no longer navigates (transcript survives), new pinning test added
T2R (contract ceremony remainder) 🟢 green 4310d6e self-committed — overview regenerated, contract-lint phase sets updated, sweep edit finished

Closing e2e: GREEN (exit 0)pnpm -r build + pnpm -r test + contract check + a11y + package (Atlas.app built, bundled-CLI self-check passed). Round-1's two blocked deviations are resolved; the ledger in the spec's ## Deviations stands as history.

PR stays draft on purpose: 6 of 14 spec tasks are delivered (T1–T6). The window shell exists with working tabs/IPC/bundling, but T7–T14 (brain-invoke, config-tab port + dropdowns + detection, YAML editor, stats/chat/ingest panels, docs close-out) are not built. Operator decides whether to continue the run.

🤖 Generated with Claude Code

@stark-claude-21s

Copy link
Copy Markdown
Contributor Author

Round 3 summary (operator-directed: continue T7–T14):

Task Status Notes
T7 brain-invoke 🟢 dc2b562 688 tests
T8 config tab + dropdowns + key toggle 🟢 8a8e122 705 + 53 a11y
T9 detection wiring 🟢 0e014f2 740
T10 YAML editor 🟢 b1a214e substituted gate — see below
T11 stats tab 🟢 517ba01 803 + 72 a11y
T12 chat tab 🟢 2b59b24 825 + 79 a11y
T13 ingest tab 🔴 blocked WIP 489d679 — zero tests delivered in 2 attempts (one wrapper killed externally mid-run); ingest tab NOT delivered
T14 close-out ⏸ not dispatched depends on T1–T13; dishonest over a missing tab

Environment note: test/native-dependency.test.ts's real-pnpm install guard probe deadlocks under a second concurrent build runner on this machine (reproduced in isolation; twice >1h silent). T10–T13 gates ran typecheck + full-suite-minus-that-file + a11y; T10's diff is git-verified disjoint from that file's subject matter. The file must be re-proven in the full e2e before merge.

State: 12/14 green, suite 825 + 79 a11y at 2b59b24; T13 WIP carries one packaged-app-test failure (possibly stale dist-app, unattributed). PR stays draft. Deviations mirrored to the spec (PR #434). Remaining: T13 (real delivery), T14, full e2e incl. the excluded file.

🤖 Generated with Claude Code

…ingest registered for real

registerChatIpc/registerStatsIpc/registerIngestIpc had NO callers and no
production InvokePort existed: green suites, dead tabs (T11/T12 latent
deviation). app-shell gains engineInvoke + ingest deps with teardown;
index.ts binds startInvoke on the launch runtime's entrypoint resolution,
the native open panel (INGEST_EXTENSIONS filter) and nodePasteFilePort.
Behavioral registration cases + static index.ts gate in app-shell.test.ts.
@stark-claude-21s

Copy link
Copy Markdown
Contributor Author

RUN COMPLETE — 14/14 tasks green. Final commit 0711fcb.

T13 (ingest tab) closed interactively: the inherited pipeline module was sound; a second operator session contributed the three test files (3f8f460, 68 tests); this session closed the real gap — the engine-invocation wiring hole: registerChatIpc/registerStatsIpc/registerIngestIpc had NO callers and no production InvokePort existed, so the chat/stats/ingest tabs were dead at runtime behind green suites (T11/T12 latent deviation). app-shell + index.ts now bind them on the launch runtime's entrypoint resolution, with behavioral registration tests + a static index gate (69f6ba7).

T14 (docs + packaging): green by composition — non-desktop suites ✓, desktop suite minus one file 875 ✓, contract clean, a11y 86 ✓, full build ✓, packaged Atlas.app self-check ✓.

The one asterisk: test/native-dependency.test.ts's real-pnpm install probe was not re-run in-band for T14. Evidence instead: the file is byte-identical to accepted-base (protected + git-verified), passed in-band once today (the 893-test run), and CI re-proves it on this push. The probe is pathological on this host: nested-pnpm invocations hang it, each kill leaks a store-locking zombie install, and a stale index.db-wal compounded it (all ledgered in PROGRESS). Follow-up recommended: give the probe an isolated --store-dir.

Suite trajectory across the run: 565 → 875+ tests, 28 → 86 a11y. The human live-drive checklist from the spec's Verification section remains owner-run: Cmd+1..4, one chat message, one paste-ingest preview→apply, detect models, break + fix the YAML.

🤖 Generated with Claude Code

@stark-claude-21s

Copy link
Copy Markdown
Contributor Author

CI green across the board — both build-test legs (full suite including the native-dependency probe, on clean runners), both clean-install-no-rebuild legs, and accessibility. The T14 probe asterisk is closed: the host pathology was environmental, the code is proven. PR flipped ready. Remaining before merge: the operator live-drive (spec Verification fallback).

🤖 Generated with Claude Code

@aryeh-stark
aryeh-stark marked this pull request as ready for review July 27, 2026 18:18
…y CodeMirror, VS Code Dark+ palette

Live-drive feedback: the raw **bold** blob becomes a read-only CodeMirror
view with markdown grammar and a Dark+ token palette (all colors clear
4.5:1 on #1e1e1e). Injectable createAnswer seam keeps the fake-DOM suite
honest; degraded path (no seam / non-DOM mount) is the old plain text.
Adds @codemirror/lang-markdown + @codemirror/language + @lezer/highlight.
…injected style element was CSP-blocked

style-src 'self' blocked style-mod's <style> injection, so both editors
rendered with ZERO styling (no tokens, no theme) — shipped as 'the colors
do not work'. Styles-only relaxation, this document only; scripts stay
'self'; popover keeps the strict policy; the app-tabs CSP gate now asserts
per-directive. Probe-verified computed colors: bg #1e1e1e, tokens
#569cd6/#c586c0/#ce9178/#6796e6/#9d9d9d. Fallback catch logs loudly.
…n button

Live-drive round 3: the CodeMirror source view comes out; answers render
as actual bold/headings/lists/code, built exclusively via createElement +
textContent over the Lezer CommonMark tree (no markup sink; headings are
styled paragraphs so the model cannot join the app's outline; [[wikilinks]]
re-fused from the parser's bracket+Link reading). Copy button holds the
RAW markdown behind an injected clipboard seam; outcome announced via the
status line. Theme-aware light/dark via the app's own CSS vars.
…ing reached the screen

sections.ts escapes intra-heading slashes (%→%25, /→%2F) so breadcrumbs
stay splittable; citations rendered the wire form raw ('Role %2F
Relationship'). sectionPathText() is the display-side inverse per segment,
re-joined with ›.
… only above

The 2026-07-27 vault migration (87f5ede) versioned the typed-related shape
Atlas has required since #331 as schema_version 2, per the vault's shared
Schema-versions doctrine (brain-cli reads 1..built-with). Atlas's reader
pinned the literal 1 with an exact match and fail-closed the whole vault.
SCHEMA_VERSION → 2 in contracts (writers emit 2); the reader accepts 1..2
and errors only on a NEWER note, naming the upgrade.
…ut that note

Each citation row is now a button (accent-styled, aria-labelled 'Ask about
<note-id>') that fires ask(noteId): the query identity layer short-circuits
on the exact id, so the answer comes back grounded in that note. ask()
gains an optional explicit question; a citation click never clears the
composer's draft and respects the single-flight.
…ck asks about the note

The rendered answer's [[wikilinks]] drop their brackets and become the
same ask-about-this-note buttons the citations are (accent link styling,
'Ask about <id>' labels, composer draft untouched, single-flight held).
renderMarkdownAnswer gains an optional onNoteClick; without it the
wikilink stays a styled span.
…pport

'Cite each supporting note' read as per-claim stamping: a single-source
answer arrived with the same [[citation]] on every sentence. citedNoteIds
detects presence, not count, so once is enough.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant