emrg: gui renderer React migration Batch 0 — infra scaffold (Vite 8 + React 19 + TS strict + Vitest + SnapshotStore) - #991
Merged
Conversation
… React 19 + TS strict + Vitest + SnapshotStore) Renderer migration (rant 2026-08-26T12:16:48, design ~/.emrg/designs/gui-react-migration-design.md v0.1, D1-D7 decided): standalone emrg/gui/renderer/ package — no vanilla renderer change. - renderer/package.json: react/react-dom 19 + vite 8 + typescript 7 + vitest 4 + @testing-library (no @tiptap yet) - vite.config.ts: root src/ -> dist/index.html + assets/* (CSP script-src 'self' safe, base ./); vitest jsdom config - tsconfig.json: strict (D7) - src/: main.tsx, App.tsx (ErrorBoundary -> I18nProvider -> Shell), components/ErrorBoundary.tsx (vanilla error-boundary.js port), components/Shell.tsx, lib/snapshot-store.ts (D2, zero-dep store + useSyncExternalStore), lib/utils.ts (pure helpers port), lib/i18n.tsx (context skeleton; full dict in Batch 1), shell.css - tests: 19 vitest (5 snapshot-store + 9 utils + 3 ErrorBoundary + 2 App smoke) - CI: test.yml renderer step (npm ci + typecheck + test + build) - gui npm test pinned to test/*.test.js (node --test would otherwise pick up renderer vitest files); electron-builder excludes renderer toolchain from package - Agent.md: doc-count guard sync (262 gui + 19 renderer vitest) Verification: renderer typecheck/vitest/build green, gui 262 tests (254 pass + 8 integration skipped), pytest 1094 passed/1 skipped, import + CLI checks OK.
argszero
commented
Aug 26, 2026
argszero
left a comment
OwnerAuthor
There was a problem hiding this comment.
✅ LGTM — cycle cyc20260826-131007 (1/3)
Review: Batch 0 infra scaffold for the GUI renderer React migration (rant 2026-08-26T12:16:48, design doc D1–D7).
- CI: test + test-windows both green (actionlint gate #444 + doc-count guard #511 validated the workflow/Agent.md changes)
- External contracts untouched: window.emrg bridge, main.js, preload.js, daemon protocol — zero diff on those files
- Vite build emits dist/index.html + dist/assets/* (no inline script → CSP script-src 'self' safe; base ./ for file:// loadFile)
- tsconfig strict (D7); SnapshotStore (D2) is a clean zero-dep store + useSyncExternalStore hook
- gui npm test pinned to test/*.test.js — node --test otherwise auto-discovers renderer vitest files
- electron-builder excludes renderer toolchain from packaged app
- 19 vitest tests cover store/utils/ErrorBoundary/App; vanilla renderer untouched until Batch 5 (D3)
argszero
commented
Aug 26, 2026
argszero
left a comment
OwnerAuthor
There was a problem hiding this comment.
✅ LGTM — cycle cyc20260826-131914 (2/3)
Re-review: head bcf4963 unchanged since 1/3 vote; CI test + test-windows both green (actionlint gate + doc-count guard pass); MERGEABLE/CLEAN. Independent-cycle verification confirms the Batch 0 scaffold — no issues found.
Uh oh!
There was an error while loading. Please reload this page.
argszero added a commit
that referenced
this pull request
Aug 26, 2026
…ds/copywriting) + preload API-surface guard (#992) Renderer migration Batch 1 (design doc v0.1 §5, rant 2026-08-26T12:16:48, D1-D7 decided). Follows #991 (Batch 0) now merged. - renderer/src/lib/commands.ts: vanilla renderer/js/commands.js ported to TS (pure logic, no DOM/window deps) — COMMANDS registry (16), parseInput three-state, getCompletions prefix filter, hintText with injectable t - renderer/src/lib/copywriting.ts: vanilla renderer/js/copywriting.js ported to TS — toolPhrases/buildCopy/createCopywriting factory (injectable t, refresh() locale-switch rebuild) - renderer/src/lib/commands.test.ts + copywriting.test.ts: vitest tests mirroring the old node:test assertions (design: pure-logic tests migrate to Vitest with identical assertions); old test/commands.test.js stays until Batch 5 switch (D3/D6) - emrg/gui/test/preload-api.test.js: window.emrg API-surface guard — freezes the full 53-member contract (52 invoke + onEvent) with channel/event-name assertions (red line #1; closes gap found in cycle cyc20260826-131007: design doc said 46 methods but preload.js actually exposes 52 + onEvent, only spot checks existed before) - Agent.md: doc-count guard sync — gui 262→265 (+3 preload-api), renderer vitest 19→34 (+11 commands +4 copywriting), API surface 46→52+onEvent Verification: renderer typecheck clean, renderer vitest 34/34, gui npm test 265 (257 pass + 8 integration skipped), pytest 1094 passed/1 skipped, doc-count guard 4/4, import + CLI OK. Co-authored-by: EMRG Evolution <emrg@argszero.dev>
This was referenced Aug 27, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
GUI renderer React migration — Batch 0 (infrastructure scaffold)
Addresses the host rant 2026-08-26T12:16:48 (GUI renderer full React migration, route A full rewrite, decisions D1–D7 finalized) per the authoritative design doc
~/.emrg/designs/gui-react-migration-design.mdv0.1. This is the first of the multi-cycle relay batches (Batch 0–5).Batch 0 scope (design §5): standalone React scaffold inside
emrg/gui/renderer/— no vanilla renderer change. The oldrenderer/js/*.jsfiles,renderer/index.html,main.js,preload.js, and the daemon protocol stay byte-identical until the Batch 5 one-shot switch (decision D3).What's in this PR
renderer/package.json— React 19 + Vite 8 + TypeScript 7 (strict) + Vitest 4 + @testing-library.@tiptapdeliberately NOT installed yet (design: Batch 0 item 1).vite.config.ts—root: "src"→ outputrenderer/dist/index.html+dist/assets/*(decision D1). No inline scripts → CSPscript-src 'self'-safe;base: "./"formain.js loadFile(file://)later. Vitest (jsdom) config.tsconfig.json—strict: true(decision D7).src/React skeleton (design §4.1 component tree):main.tsx,App.tsx(ErrorBoundary → I18nProvider → Shell)components/ErrorBoundary.tsx— React port of the vanillaerror-boundary.js(rant 2026-08-25T21:13): full-screen overlay, 500-char summary, copy/reload buttons, built-in zh/en fallback (sits above the provider, cannot use context — matches vanilla)components/Shell.tsx— zero-risk placeholder layout (design Batch 0 item 4)lib/snapshot-store.ts— self-developed SnapshotStore (decision D2, grok-bot pattern, zero deps) +hooks/useSnapshotStore.ts(useSyncExternalStore)lib/utils.ts— pure helpers ported from vanillautils.js(escapeHtml/genRequestId/relTimewith injectable translate fn)lib/i18n.tsx— React i18n context skeleton (full 934-line dict migration is Batch 1)src/index.html— Vite entry template (distinct from the vanillarenderer/index.html)test.ymlstep:npm ci+typecheck+vitest+vite buildinemrg/gui/renderer(node 22, same as the existing GUI step)emrg/gui/package.jsonbuild.filesnow excludes the renderer toolchain (node_modules/dist/src/test/ config) from the packaged appnpm testpinned to"node --test \"test/*.test.js\""sonode --testno longer auto-discovers the renderer vitest filesExternal contracts preserved
window.emrgpreload bridge: untouched (46 invoke + onEvent methods)message_delta/done/tool_started/…)main.js/preload.js: zero diff; still loads the vanillarenderer/index.htmlVerification (local)
cd emrg/gui/renderer && npm run typecheck— clean (TS strict)cd emrg/gui/renderer && npm test— 19/19 passcd emrg/gui/renderer && npm run build—dist/index.html+dist/assets/*(CSP-safe)cd emrg/gui && EMRG_SKIP_INTEGRATION=1 npm test— 262 tests, 0 failurespytest tests/— 1094 passed, 1 skippedpython -c "from emrg.client.app import run_client"+python -m emrg --help— OKFollow-ups
Batches 1–5 (pure-logic migration → chat → sidebar/panels → dialogs → switch & cleanup) land in subsequent evolution cycles. This batch is self-contained: the vanilla renderer keeps working untouched.