- Replace monolithic app.ts / app-conversation.ts / app-device-pod.ts /
app-skills.ts / app-helpers.ts / app-session-tabs.ts / auth.ts and the
364-line index.html with a Vite-built React + TypeScript SPA.
- New src/ module tree: main.tsx, App.tsx, components/{layout,auth,
conversation,command-bar,device-pod,skills,settings,help},
hooks/, services/api, services/auth, state, types, logic/ (pure
helpers from the old tree), styles/.
- Pure-logic modules (composer-policy, code-agent-facts, code-agent-
status, live-status, message-markdown, app-trace, app-session-tabs,
runtime) move to src/logic/ with their tests preserved; tests still
auto-discover.
- Build pipeline switches from Bun.build to Vite: vite.config.ts
inlines everything into a single app.js + app-assets/ for the dist;
scripts/dist-contract.ts now runs vite build and asserts the dist
against a fresh build instead of comparing dist to source.
- scripts/check.ts now verifies the React entry, the mount-only
index.html, Vite dist, the composer / session / device pod / skills
/ settings / help contracts, the React state shape, and the new
test file locations. It also refuses to run if any legacy app-*.ts
or auth.ts survives at the top level.
- New scripts/frontend-guard.ts enforces the 400-line migration target,
refuses the legacy el map and document.getElementById markers,
refuses to keep app-*.ts / auth.ts at the top level, and verifies
the required module directory layout.
- Update scripts/src/dev-cloud-workbench-smoke-lib.mjs to read the new
src/services/, src/logic/ paths and refresh cloudWebModuleSourceFiles.
- index.html is now a mount shell only (no login shell, no workbench
shell, no device pod sidebar markup). React renders the full UI from
src/main.tsx, satisfying the issue-756 migration goal of catching
unclosed tags at the TypeScript/JSX compile step instead of relying
on browser DOM healing.
- web:check (now: check + frontend-guard + tsc-check + bun test) is
green: 51 pass / 0 fail, Vite build produces dist/app.js (379 kB)
+ dist/index.html + dist/app-assets/. Vite build is reproducible;
dist freshness is verified against a fresh Vite build.
- Grandfathered pure-logic files (> 600 lines): src/logic/app-trace.ts
(1367), src/logic/live-status.ts (1006), src/logic/code-agent-facts.ts
(548), src/logic/code-agent-status.ts (572). Reason: each is a tested
pure-logic classifier with a public contract consumed by both the
CLI renderer and the Web renderer; splitting now would fork the
public function shape across two PRs and the migration target is the
React entry + module split, not a pure-logic refactor.
Refs #756. Closes#756 once merged + deployed to hwlab-v02.
Co-authored-by: Codex <codex@local>
PR #746 (#744) removed the duplicate `command-new-session` button from index.html and the `el.commandNewSession` field from the `el` literal, but left `el.commandNewSession.addEventListener("click", ...)` inside `initCommandBar()`. The resulting undefined reference crashed every Cloud Workbench init with
app.js:5414 Uncaught TypeError: Cannot read properties of undefined (reading 'addEventListener')
at initCommandBar (app.js:5414:24)
at app.js:3538:1
The new session entry point is `#session-create` in the session sidebar (added in #740/#743), so this listener is no longer needed. Removal is the minimal fix; all other command-bar bindings (`commandInput`, `commandForm`, `commandClear`) are untouched.
Verified locally:
- web:check (54 tests pass, all static contracts pass)
- web:build (12 dist files fresh)
- dist/app.js: 0 references to commandNewSession
Refs: pikasTech/HWLAB#748
Co-authored-by: Codex <codex@local>
- dev-issue-722-trace-integration.mjs: drives hwlab-cli agent trace --render web
with a 4151-char final response and asserts the rendered terminal row body
equals the full text without any 内容已截断 marker
- dev-issue-722-streaming-integration.mjs: drives the same path with a long
non-terminal streaming message and asserts the CLI preview cap still fires
at 1200 chars + the ... marker, while the terminal row in the same trace
keeps the full text
- package.json: expose the two scripts as dev:issue-722:* for repeatable
CLI verification on the v0.2 runtime
Refs: pikasTech/HWLAB#722
- HWLAB v0.2 Final Response was being truncated to 5000 characters in
traceAssistantSummaryRow and then again to 1200 characters in the CLI
compactTraceRenderRow, even when the response was the assistant’s
terminal (last) message. The same Final Response is what
/v1/agent/chat/result returns as reply.content, so the trace view
should show the full text and stay consistent with the CLI
assistantText path.
- Mark each rendered row with a terminal flag (true only for the
terminal Final Response) and lift the body cap to
Number.POSITIVE_INFINITY for terminal rows. The CLI Web-render path
now passes the full body through when row.terminal is true and keeps
the 1200 char preview for non-terminal streaming rows.
- Add unit tests in web/hwlab-cloud-web/app-trace.test.ts and
tools/hwlab-cli/client.test.ts to lock the behavior in for the
terminal/no-truncate path and the streaming/2200 cap path.
Refs: pikasTech/HWLAB#722