feat(ui): rebuild desktop renderer on a shared trace graph and design tokens

Replace the full-innerHTML render loop with a static shell plus
per-region updates, so composer drafts, fold state, focus, and scroll
survive streaming turns. Fold session events into one trace graph
consumed by Chat, Trajectory, Waterfall, and the shared inspector
drawer, with live ACP updates patched into a keyed live-turn region.

Align the visual system with a tokenized design spec: a 4px spacing
base with fixed control/row height steps, foreground-derived text
tiers and borders (color-mix), neutral interaction overlays, tiered
motion durations with a reduced-motion collapse, hover-revealed
scrollbars, and drawer-aware layout elasticity. Localize trajectory
role chips and row previews.

The renderer entry (app.ts) joins the coverage exclude list as a
self-executing DOM bootstrap: jsdom lifecycle specs exercise its
behavior, and extractable logic lives in covered modules
(trace-graph.ts, renderer-content.ts).
This commit is contained in:
NI0317
2026-07-19 01:37:04 +08:00
parent 382708b1c0
commit c4584b5c19
16 changed files with 4866 additions and 1798 deletions

View File

@@ -8,11 +8,16 @@ const packageRoot = resolve(here, '..')
const repoRoot = resolve(packageRoot, '../../..')
const viteUrl = process.env.DSH_DESKTOP_VITE_URL ?? 'http://127.0.0.1:5174'
const vite = spawn(resolve(repoRoot, 'node_modules/.bin/vite'), [
const packageBin = resolve(packageRoot, 'node_modules/.bin')
const vite = spawn(resolve(packageBin, 'vite'), [
'--host',
'127.0.0.1',
'--port',
'5174',
// Fail fast instead of silently moving ports: Electron loads the URL below,
// so a relocated Vite would leave the window pointing at a stale instance.
'--strictPort',
], {
cwd: packageRoot,
env: { ...process.env },
@@ -25,7 +30,7 @@ let electron
const startElectron = () => {
if (electronStarted) return
electronStarted = true
electron = spawn(resolve(repoRoot, 'node_modules/.bin/electron'), ['src/main.mjs'], {
electron = spawn(resolve(packageBin, 'electron'), ['src/main.mjs'], {
cwd: packageRoot,
env: { ...process.env, VITE_DEV_SERVER_URL: viteUrl },
stdio: 'inherit',
@@ -48,8 +53,6 @@ vite.on('exit', (code, signal) => {
if (!electronStarted) process.exit(code ?? (signal === null ? 0 : 1))
})
setTimeout(startElectron, 2500)
process.on('SIGINT', () => {
electron?.kill('SIGINT')
vite.kill('SIGINT')