feat(transcript): add identity, VS Code adapter, and HTML export - #9641
feat(transcript): add identity, VS Code adapter, and HTML export#9641water-in-stone wants to merge 18 commits into
Conversation
Establish a shared transcript model and document-mode projection so Web Shell, VS Code, and HTML export can consume the same stable conversation semantics without changing interactive rendering. - Preserve daemon and ACP segment identity across replay and normalization - Add export-safe previews and a versioned transcript document builder - Add document-mode Web Shell rendering with bounded Mermaid processing - Lock direct-daemon and ACP behavior with contract fixtures - Cover render and export equivalence in integration tests
Move transcript prevalidation onto real product paths while preserving the legacy VS Code timeline as the default fallback. - Add version-bound document HTML with strict CSP and schema checks - Add opt-in ACP projection with stable source identity - Reuse product export code across hosts and the integration runner - Remove test-only production probes and consolidate shared validation Note: Browser, host-action, VSIX, and packaging gates remain pending.
Keep the npm lockfile aligned with the VS Code and HTML export package manifests added by the transcript consumer migration. - Lock the VS Code Web Shell workspace dependency - Lock Web Templates SDK, Web Shell, and React build dependencies
|
Thanks for continuing the transcript contract work! The gate passes on template and problem, but the direction needs a maintainer's call before anyone sinks time into a 10k-line review.
⏸️ Deferring to @yiliang114 (who merged part 1, #9388) — needs a human call on: (a) whether this backup branch is a merge candidate now or should wait for the planned split, and (b) the public-contract additions (ACP Not verified: static gate only (unattended CI run); no code was built or executed. 中文说明感谢继续推进 transcript 契约工作!模板与问题真实性均通过 gate,但在投入 1 万行的评审之前,方向问题需要维护者拍板。
⏸️ 转交 @yiliang114(第一部分 #9388 的合入者)—— 需要人工决定:(a) 该备份分支是当前即可作为合入候选,还是应等待计划中的拆分;(b) 公共契约面的新增(ACP 未验证项: 仅静态 gate(无人值守 CI);未构建或执行任何代码。 — Qwen Code · qwen3.8-max Reviewed at |
…plit-20260818 # Conflicts: # packages/acp-bridge/src/transcript-replay.ts # packages/sdk-typescript/scripts/build.js # packages/sdk-typescript/src/daemon/ui/transcript.ts # packages/web-shell/client/components/MessageList.tsx # packages/web-shell/client/components/messages/GoalStatusMessage.tsx
🖼️ web-shell visual previewRendered against a mock daemon (no real backend): the PR base vs this PR head Screenshots · before / afterFull-resolution recordings (.webm) are attached to the workflow run. — Qwen Code · web-shell visuals |
🩺 serve daemon A/BBuilt the PR base vs this PR head ✅ No response changes against the PR base across 12 scenario(s). — Qwen Code · serve A/B |
|
@qwen-code-ci-bot I have updated the PR body and resolved all conflicts. Please take another look |
|
@qwen-code-ci-bot /review |
qqqys
left a comment
There was a problem hiding this comment.
Critical — the current head c5d8a53 fails the Ubuntu Node 22 check before tests run. This PR adds @qwen-code/web-shell to packages/vscode-ide-companion/package.json, but does not update packages/vscode-ide-companion/NOTICES.txt. The required notices verification regenerates that file with 9,311 additions and exits 1, blocking the PR. Please run npm run generate:notices --workspace=qwen-code-vscode-ide-companion and commit the generated NOTICES.txt. Evidence: https://github.com/QwenLM/qwen-code/actions/runs/32451973539/job/96682045074
|
The title
The body says "implements the second phase of the shared read-only chat transcript design", which matches the design doc MR2 scope — but the title only mentions export. Consider renaming to something that covers the full scope, e.g. Also, the branch name Lastly, CI is red: |
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
Partially reviewed — gaps disclosed.
Not explored to full depth (tool budget reached): chunk 27: executing transcriptToMessages.test.ts under vitest and running the web-shell typecheck (blocked by missing workspace install in the review worktree); chunk 11: executing the new/changed tests (worktree has no node_modules / dist and a full monorepo install + build exceeded the review budget; verification is static ag…; "agent reverse-audit (round 1)": verify vitest expect.poll default timeout against the maximum-document render time in test 2 — could not locate the poll implementation in the bundled vitest ….
Not reviewed: reverse audit — stopped before round 3 by the review time budget.
中文说明
仅完成部分审查,审查缺口已披露。
未探索到全部深度(达到工具调用预算):chunk 27:executing transcriptToMessages.test.ts under vitest and running the web-shell typecheck (blocked by missing workspace install in the review worktree);chunk 11:executing the new/changed tests (worktree has no node_modules / dist and a full monorepo install + build exceeded the review budget; verification is static ag…;"agent reverse-audit (round 1)":verify vitest expect.poll default timeout against the maximum-document render time in test 2 — could not locate the poll implementation in the bundled vitest …。
未审查:反向审计——评审时间预算不足,未能开始第 3 轮。
— qwen3.8-max via Qwen Code /review (v0.21.15)
Resolve review findings across document export and the VS Code ACP timeline while preserving default interactive and readonly semantics. - Preserve stable text and non-text identity across live and replay - Harden export projection, budgets, URL handling, CSP, and nonces - Make document rendering complete, inert, and browser-validated - Keep VS Code transcript scope, theme, copy, and flags reactive - Restore fixture, schema, hash, and compatibility contract locks Note: The overall gate remains failed pending VSIX, host-action, and packaged-artifact evidence.
|
Addressed the review feedback in
Validation completed locally: repository build and typecheck, focused CLI/Web Shell/VS Code/SDK/ACP tests, contract fixtures, HTML browser gate, ESLint, Prettier, and NOTICES idempotence. The frozen overall gate intentionally remains |
…eb-shell-adapter-before-split-20260818 # Conflicts: # packages/web-shell/client/components/MessageList.tsx # packages/web-shell/client/components/messages/AssistantMessage.tsx # packages/web-shell/client/components/messages/ToolGroup.tsx
…eb-shell-adapter-before-split-20260818
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
Partially reviewed — gaps disclosed.
Not reviewed: build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and the browser-gate half of chat-transcript-document.test.ts cannot execute there (Chromium binaries not installed — see finding R2-7); the Node-side halves were executed locally.
Not explored to full depth (tool budget reached): chunk 64: none — I chose not to run the two test files because this worktree has no node_modules and a full install exceeds this chunk's budget; the static verification…; chunk 22: could not execute packages/sdk-typescript/test/unit/daemonUi.test.ts — node_modules is not installed in this review worktree and dependency installation was o…; chunk 3: executing integration-tests/chat-transcript-contract.test.ts via vitest (worktree has no node_modules; requires npm ci + build + bundle); chunk 3: running tsc -p integration-tests/tsconfig.json over the rewritten tests (no node_modules; typing verified statically against lockfile TypeScript 5.9.3 instead…; chunk 13: none. (I did not execute the two unit test files because this shared review worktree has no node_modules and no built packages/core/dist ; a full install+bui….
Not reviewed: reverse audit — stopped before round 3 by the review time budget.
Deferred under the convergence posture (round 2, not a blocker) — recorded, not requested in this round:
packages/cli/src/ui/utils/export/export-transcript-document.ts:1594 — [review] Fence-language case divergence between builder and validator; sanitizer misses two URL shapespackages/cli/src/ui/utils/export/export-transcript-document.ts:2030 — [review] redactHomePaths misses /usr/home, /root, and custom home basespackages/web-shell/client/adapters/transcriptToMessages.ts:1560 — [review] Safe projection crashes on malformed typed previews (crafted-file trigger)integration-tests/chat-transcript-document.test.ts:525 — [review] Heap gate ?? 0 fallback passes vacuously if performance.memory is absentpackages/vscode-ide-companion/src/webview/App.tsx:1395 — [review] Copy message silently no-ops for rows without data-source-block-idspackages/web-shell/client/components/messages/Markdown.tsx:318 — [review] Mermaid queue: interactive starvation and post-timeout overlappackages/web-templates/src/export-html/src/document-main.tsx:86 — [review] DocumentError fail-closed path untestedpackages/vscode-ide-companion/src/webview/handlers/SessionMessageHandler.ts:1195 — [review] Resume-fallback scope desync on archived session idpackages/cli/src/ui/utils/export/export-transcript-document.ts:956 — [review] Link reference definitions last-wins vs renderer first-winsintegration-tests/chat-transcript-contract.test.ts:205 — [review] Closed-shape lock skips toolResultPreview inline branchesintegration-tests/chat-transcript-contract.test.ts:477 — [review] Identity gate vacuously satisfiable on empty candidatesintegration-tests/chat-transcript-document.test.ts:625 — [review] Gate report publishes the harness's own CSP probe violationintegration-tests/chat-transcript-document.test.ts:682 — [review] Zero-network gate asserts 4 of 12 CSP directivespackages/cli/src/ui/utils/export/export-transcript-document.ts:1016 — [review] Rich-task rewrite ignores fence segmentationpackages/sdk-typescript/src/daemon/ui/transcript.ts:1279 — [review] Shell block merging lacks the segmentId guardpackages/cli/src/ui/utils/export/export-transcript-document.ts:1621 — [review] Image titles containing ) escape all image gatespackages/vscode-ide-companion/src/webview/adapters/acpTranscriptAdapter.ts:44 — [review] compatible latch is irreversiblepackages/web-shell/client/adapters/transcriptToMessages.test.ts:2540 — [review] mergeToolCall safeToolProjection clauses unpinned by testspackages/web-shell/client/adapters/transcriptToMessages.ts:484 — [review] mid_turn_message_injected echoes lack sourceBlockIds
Mechanism health: this round did not close cleanly, so it withholds the incremental anchor — and the round it recovered had none either, so the next review re-reads the whole diff and will keep doing so until a round's marker carries an anchor again. (Stated, not acted on — this changes nothing about what the round posts.)
中文说明
仅完成部分审查,审查缺口已披露。
未审查:build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and the browser-gate half of chat-transcript-document.test.ts cannot execute there (Chromium binaries not installed — see finding R2-7); the Node-side halves were executed locally。
未探索到全部深度(达到工具调用预算):chunk 64:none — I chose not to run the two test files because this worktree has no node_modules and a full install exceeds this chunk's budget; the static verification…;chunk 22:could not execute packages/sdk-typescript/test/unit/daemonUi.test.ts — node_modules is not installed in this review worktree and dependency installation was o…;chunk 3:executing integration-tests/chat-transcript-contract.test.ts via vitest (worktree has no node_modules; requires npm ci + build + bundle);chunk 3:running tsc -p integration-tests/tsconfig.json over the rewritten tests (no node_modules; typing verified statically against lockfile TypeScript 5.9.3 instead…;chunk 13:none. (I did not execute the two unit test files because this shared review worktree has no node_modules and no built packages/core/dist ; a full install+bui…。
未审查:反向审计——评审时间预算不足,未能开始第 3 轮。
收敛姿态下延后(第 2 轮,非阻断)——已记录,本轮不要求修改:共 19 条(原文未翻译,列表见上方英文部分)。
机制健康:本轮未能干净收尾,因而扣留了增量锚点,而它恢复到的那一轮也没有锚点,因此下一次评审将重读整个 diff——并会一直如此,直到某一轮的标记重新带上锚点。(仅陈述,不据此行动——这不改变本轮发布的任何内容。)
— qwen3.8-max via Qwen Code /review (v0.21.15)
Close the latest review findings across transcript identity, VS Code rehydration, and the HTML export security boundary. - Terminate discrete ACP segments and bind automatic turn provenance - Reset VS Code transcript scopes across replay and reconnect lifecycles - Align Markdown sanitization and envelope budgets with document rendering - Run browser gates with Chromium and complete third-party notices
Close the latest review findings around document resource safety and recorded-user replay consistency. - Redact local home paths structurally without corrupting remote URLs - Sanitize nested Markdown images inside otherwise safe links - Advance merged segment provenance without duplicating separators - Keep recorded-user stable IDs anchored to durable record identity
…plit-20260818 # Conflicts: # packages/cli/src/acp-integration/session/Session.ts # packages/web-shell/client/components/MessageList.tsx # packages/web-shell/client/components/WebShellTranscript.tsx # packages/web-shell/client/components/messages/ToolGroup.test.tsx # packages/web-shell/client/components/messages/ToolGroup.tsx
Keep MR2A focused on the document export pipeline while preserving the legacy VS Code timeline. - Retain VS Code /export html as a real document consumer - Move live transcript adapters, identity wiring, and feature flag to MR2B - Remove the direct Web Shell dependency and restore baseline notices - Keep candidate identity evidence in integration-only helpers - Document the MR1, MR2A, and MR2B delivery boundaries
|
@qwen-code /resolve |
|
Qwen Code attempted to resolve merge conflicts but the run did not complete successfully. Check the workflow run for full logs. |
|
#9811 now owns the complete VS Code WebShell cutover and has been synchronized with current The reusable boundary we still need from this work is the stable transcript identity plus the document-only HTML export path. #9812 can retire The current head is still conflicting with |
…o main Resolves conflicts between PR QwenLM#9641 (water-in-stone: WebShell transcript identity, VS Code adapter, and HTML export) and main (QwenLM#9719 already merged). Strategy: main (QwenLM#9719) is authoritative for the adapter plumbing; preserve QwenLM#9641's identity projection and HTML export (renderMode/documentMode) while dropping the duplicate adapter implementation. Also fixes merge remnants: orphaned data-web-shell-transcript flag, duplicate onTranscriptUpdate declaration, stale useAcpTranscript.test.tsx rename, and duplicate @qwen-code/web-shell dependency.
|
Resolved the merge conflicts between this PR and #9719 (WebShell transcript UI, already merged to Strategy — kept
Result — force-pushed onto this branch as a fast-forward merge commit (
Note: Verification: web-shell 4269 tests passed, vscode-ide-companion 607 passed, typecheck clean (one pre-existing |
|
Qwen Code attempted to resolve merge conflicts but the run did not complete successfully. Check the workflow run for full logs. |
yiliang114
left a comment
There was a problem hiding this comment.
Reviewed at dbc3e7b4 (including the main-merge conflict resolution). One blocker inline: credentials embedded in URL userinfo leak into the HTML export verbatim, which breaks the PR's own one-way-boundary guarantee. Four non-blocking follow-ups are inline as well.
What I checked and found clean: untrusted content only enters the export through the JSON script envelope (escapeJsonForHtmlScriptData handles </script>/U+2028), the document CSP is default-src 'none' with only nonce'd scripts and data: images, Mermaid runs securityLevel: 'strict' with budgets in document mode, and sessionId is a forbidden envelope field with a final re-assert pass. The rendering surface itself looks sound — the leak below is on the redaction side.
|
The current head is blocked before the new export tests run:
These are separate from the remaining export-sanitization Critical. Fixing them should remove the current CI cascade and expose any actual document-export test failures. |
|
Commit
Focused verification: export document tests 31/31 passed, Web Shell library TypeScript check passed, Prettier/ESLint pre-commit passed, and |
yiliang114
left a comment
There was a problem hiding this comment.
The URL-credential export blocker is fixed in bff4e63. The focused export suite passes 31/31, the Web Shell library typecheck passes, and all review threads are resolved. CI is still running as the remaining merge gate.
|
Fixed the Ubuntu CI failure in Focused result: 9 passed, 1 platform-specific test skipped. |
|
Qwen Code review timed out. Qwen review timed out after 21600 seconds (of the 360-minute budget). This run already used the maximum 360 minute timeout. See workflow logs. |
|
@qwen-code /resolve |
|
Qwen Code attempted to resolve merge conflicts but the run did not complete successfully. Check the workflow run for full logs. |
# Conflicts: # packages/web-shell/client/components/messages/ToolGroup.tsx
…/backup-feat-web-shell-adapter-before-split-20260818
893f172 to
3d87d7a
Compare
|
Please do not rebase or force-push to an active PR as it invalidates existing review comments. Note for future reference, the bots always squash all changes into a single commit automatically as part of the integration. 中文请勿对活跃的 PR 执行 rebase 或 force-push,因为这会使已有的评审评论失效。另外,供日后参考:作为集成流程的一部分,机器人始终会自动将所有改动压缩(squash)为单个提交。 |
|
Qwen Code review did not complete successfully. The review pipeline failed before a review could be posted. A transient error is retried automatically; if you are seeing this, retry with |
What this PR does
This PR implements the second phase of the shared read-only chat transcript design for Web Shell, VS Code, Desktop, and HTML Export without introducing a new cross-host ChatPanel package or message model.
write_fileTurn Output diffs.failuntil scope/generation, host-action, VSIX, and packaging evidence is complete.Why it's needed
The existing hosts have different transcript and export paths, which creates duplicated replay/rendering logic, unstable identity across replay or history prepend, and a risk that future VS Code or HTML migrations drift from Web Shell behavior. HTML export additionally needs a one-way security boundary so runtime raw payloads, credentials, absolute paths, session identity, unsafe resources, and unbounded rendering work cannot leak into a portable document. This design provides repeatable contract evidence and real product consumers while preserving the default Web Shell, Desktop, and VS Code behavior during rollout.
Reviewer Test Plan
How to verify
npm run buildandnpm run typecheck; expect all workspace packages, the Web Shell library, the embedded document renderer, the CLI, and the VS Code companion to build and type-check.integration-tests, runnpx vitest run chat-transcript-contract.test.ts; expect fixture hashes, the canonical schema, raw-free document semantics, and stable identity for both direct-daemon and ACP to pass while the expected overall gate remainsfail.Evidence (Before & After)
No screenshots or recordings are included. Repeatable fixtures, hashes, capability decisions, focused package validation, direct-daemon/ACP identity results, product HTML build assertions, and integration-runner convergence are covered; the real Playwright Chromium gate now passes maximum-document open/search/copy/print, active CSP enforcement, zero unexpected network requests, and the real product HTML entry point.
Tested on
Environment (optional)
macOS 26.0, Node.js v22.22.3, npm 10.9.8, local non-sandboxed workspace.
Risk & Scope
fail.Linked Issues
Closes #9387
中文说明
What this PR does
本 PR 实现 Web Shell、VS Code、Desktop 与 HTML Export 共享只读聊天 transcript 设计的第二阶段,不新增跨宿主 ChatPanel 包或消息模型。
write_fileTurn Output 的完整 diff。fail。Why it's needed
现有宿主拥有不同的 transcript 与 export 路径,导致 replay/rendering 逻辑重复、replay 或历史 prepend 后 identity 不稳定,并使未来 VS Code 或 HTML 迁移存在偏离 Web Shell 行为的风险。HTML Export 还需要单向安全边界,防止运行时 raw payload、credential、绝对路径、session identity、不安全资源和无界渲染工作进入可移植文档。本设计在保持 Web Shell、Desktop 和 VS Code 默认行为不变的前提下,提供可重复的契约证据和真实产品消费者。
Reviewer Test Plan
How to verify
npm run build和npm run typecheck;预期所有 workspace packages、Web Shell library、内嵌 document renderer、CLI 和 VS Code companion 均可构建并通过类型检查。integration-tests中运行npx vitest run chat-transcript-contract.test.ts;预期 fixture hashes、canonical schema、raw-free document semantics,以及 direct-daemon/ACP 两条路径的 stable identity 均通过,同时 expected overall gate 仍保持fail。Evidence (Before & After)
本 PR 未包含 screenshot 或 recording。可重复 fixture、hash、capability decisions、聚焦包验证、direct-daemon/ACP identity、产品 HTML build assertions 和 integration-runner 收敛均有覆盖;真实 Playwright Chromium gate 已通过最大文档 open/search/copy/print、主动 CSP enforcement、零意外网络请求和真实产品 HTML 入口验证。
Tested on
Environment (optional)
macOS 26.0、Node.js v22.22.3、npm 10.9.8;Playwright Chromium 产品 browser gate 已完成。
Risk & Scope
fail。Linked Issues
N/A
Closes: #9387