mirror of
https://github.com/QwenLM/qwen-code.git
synced 2026-09-11 03:08:00 +00:00
* feat(transcript): add cross-host document export pipeline 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 * feat(transcript): wire real VS Code and HTML export consumers 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. * build(deps): sync transcript workspace dependencies 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 * feat(vscode-ide-companion): reuse WebShell transcript UI behind experimental flag Bridge ACP session/update notifications into the shared SDK daemon transcript reducer and render the result with the WebShell transcript component, gated on qwen-code.experimental.webShellTranscript (default off). The WebShell renderer and its heavy transitive dependencies (echarts, mermaid, shiki, codemirror, katex) are lazily loaded via esbuild code splitting, so the default configuration keeps the ~700KB webview bundle unchanged. * fix(vscode-ide-companion): grant wasm-unsafe-eval for shiki WASM when WebShell transcript enabled * fix(transcript): harden export and identity paths 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. * feat(vscode-ide-companion): adopt WebShell transcript as default timeline Drop the experimental flag and the legacy MessageList renderer. The companion timeline now always renders through the shared WebShell transcript component, fed by ACP session/update notifications via the SDK daemon transcript reducer (lazy loaded through esbuild code splitting). The flag-gated wiring is removed: the qwen-code.experimental.webShellTranscript setting, the conditional CSP/body attribute in WebViewContent, and the legacy MessageList path in App.tsx (~850 lines). The webview CSP now grants wasm-unsafe-eval unconditionally for Shiki's Oniguruma WASM. * fix(vscode-ide-companion): reset WebShell transcript state on session switch The experimental useAcpTranscript hook only consumed transcriptUpdate messages, so its reducer state survived session boundaries. When the extension switched sessions it kept the webview mounted and replayed the newly-selected session through ACP, causing the previous session's blocks to merge with the new replay (e.g. user text "alpha" from session A leaked into session B as "alphabeta"). Reset both the reducer state and the rendered blocks on the same boundaries the legacy message flow uses: qwenSessionSwitched (sent before the ACP replay of the selected session) and conversationCleared (new session). Adds a regression test that replays two sessions with a switch between them. * fix(vscode-ide-companion): harden WebShell transcript session boundaries - reset the transcript on `conversationLoaded` too, closing the same cross-session leak the previous commit fixed for `qwenSessionSwitched` and `conversationCleared` (agent reconnect posts only this boundary) - track the active session id and drop late `transcriptUpdate` frames whose `sessionId` no longer matches, so a previous session's trailing frames cannot contaminate the next session's timeline - seed the transcript from cached messages carried by `qwenSessionSwitched` so offline restores and load-failure fallbacks render their history instead of a blank timeline - dispatch `assistant.done` on `streamEnd`/`sessionLoadComplete` so the final assistant/thought block of a turn (or history replay) does not stay `streaming: true` forever * fix(transcript): harden identity and document export 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 * fix(vscode-ide-companion): adopt live ACP session id after load-failure fallback * fix(vscode-ide-companion): echo user prompt into WebShell transcript * fix(vscode-ide-companion): keep WebShell transcript expanded and clear of the composer * fix(vscode-ide-companion): surface local error and interrupt notices in the transcript area * fix(vscode-ide-companion): restore file-link opening from the WebShell transcript * fix(vscode-ide-companion): restore contributed copy commands for the WebShell transcript * fix(vscode-ide-companion): add localOnly marker to TextMessage state type * fix(vscode-ide-companion): restore /insight progress card and report link in the transcript UI * fix(vscode-ide-companion): finalize in-flight tools on timeout and pin session-switch seeding guard Map streamEnd reasons timeout/session_expired onto the reducer's error reason so abandoned mid-tool turns no longer spin forever (ceuI). Add qwenSessionSwitched cases with no messages field and an empty cache array; the no-messages case fails when the seeding guard is forced true, pinning its false side (ceuN). * fix(vscode-ide-companion): remove unreachable editMessage backend and dead submit options The user-message edit/rewind UI was dropped in the WebShell-transcript migration, leaving editTargetTurnIndex/onSubmitted options in useMessageSubmit and the full editMessage/rewind flow in SessionMessageHandler unreachable. Remove the dead options, the editMessage dispatch case, the rewind/snapshot flow with its recovery branches, and their tests (R1-8 direction b). * fix(vscode-ide-companion): drop write-only loadingMessage bookkeeping The waiting-message renderer was removed with the WebShell transcript migration and the user prompt is echoed into the timeline at send time (bd09e19d86), so the loadingMessage string was write-only dead state. Keep the isWaitingForResponse flag (submit gating / cancel) and pin its API surface (R1-19 direction b). * fix(vscode-ide-companion): align waiting-flag pin test with the argument-less setter * fix(transcript): simplify adapters and preserve segment boundaries Reduce the shared transcript review surface while keeping the VS Code and HTML Export consumers and their security gates intact. - Merge VS Code feature state into the ACP transcript hook - Collect source identity once and strip it at the compatibility boundary - Remove test-only export adapters, gate reports, and duplicate helpers - Keep shell output separated when stable producer segments change - Mark third-party notices as generated review content * fix(transcript): address cross-host review regressions * fix(vscode-ide-companion): echo attached images into the transcript timeline The prompt carries pasted/attached images as ACP resource_link blocks, which the transcript reducer cannot render (no inline data), so user images vanished from the timeline while the attach path stayed alive. Read each saved prompt image back from disk and echo it alongside the text echo as an inline user_message_chunk image part (the daemon-echo content shape), which the shared reducer folds into the user block and the WebShell renderer already displays. Unreadable images are skipped without breaking the send. * fix(vscode-ide-companion): track live VS Code theme for the transcript webShellTheme was snapshotted once at mount via useMemo with an empty dependency array, so switching the VS Code color theme left the timeline on the stale theme (VS Code updates data-vscode-theme-kind on <body> in place without reloading the webview). Hold the theme in state and refresh it with a MutationObserver on the body theme attributes. * fix(vscode-ide-companion): copy every transcript block kind and map ambiguous row keys - Copy All Messages now includes tool, shell, user_shell, and status blocks via getBlockCopyText, matching the pre-PR copyAllMessages handler which included formatted tool calls (review 5001842059 S-1). - findBlockByRowKey prefers an exact id match and otherwise the longest matching block id, so one block id that dash-prefixes a sibling (e.g. `a` vs `a-1`) can no longer capture the sibling's row key (S-4). * fix(vscode-ide-companion): drop whitespace-only cached transcript rows cachedMessageToNotification rejected empty strings but admitted whitespace-only content, which the reducer turns into an empty block when seeding history from cached rows. Reject content that trims to nothing (review 5001842059 S-2). * fix(vscode-ide-companion): ship missing third-party notices in NOTICES.txt Extend generate-notices.js so the regenerated NOTICES.txt carries the attribution texts it previously only pointed at or dropped: - Append license files from a package's licenses/ directory (echarts' Apache LICENSE references licenses/LICENSE-d3 for its embedded d3-derived files; the BSD-3-Clause text is now shipped). - Append a package's NOTICE file when present (Apache-2.0 §4(d)), covering echarts' Apache Software Foundation attribution. - Accept string-form package.json repository values (full URLs and GitHub shorthand) instead of emitting "(No repository found)". - Fall back to the standard MIT text (copyright holder from package.json metadata) for MIT-declared packages that ship no license file. * fix(vscode-ide-companion): show a recoverable error state when the transcript chunk fails to load * test(vscode-ide-companion): gate the transcript blocks wiring into the WebShell renderer * test(vscode-ide-companion): gate the transcriptUpdate forwarding from agent to webview * docs(vscode): plan complete Web Shell cutover * docs(webui): plan legacy package retirement * docs(webui): link cutover prerequisite * feat(vscode-ide-companion): reuse WebShell transcript UI behind experimental flag Bridge ACP session/update notifications into the shared SDK daemon transcript reducer and render the result with the WebShell transcript component, gated on qwen-code.experimental.webShellTranscript (default off). The WebShell renderer and its heavy transitive dependencies (echarts, mermaid, shiki, codemirror, katex) are lazily loaded via esbuild code splitting, so the default configuration keeps the ~700KB webview bundle unchanged. * fix(vscode-ide-companion): grant wasm-unsafe-eval for shiki WASM when WebShell transcript enabled * feat(vscode-ide-companion): adopt WebShell transcript as default timeline Drop the experimental flag and the legacy MessageList renderer. The companion timeline now always renders through the shared WebShell transcript component, fed by ACP session/update notifications via the SDK daemon transcript reducer (lazy loaded through esbuild code splitting). The flag-gated wiring is removed: the qwen-code.experimental.webShellTranscript setting, the conditional CSP/body attribute in WebViewContent, and the legacy MessageList path in App.tsx (~850 lines). The webview CSP now grants wasm-unsafe-eval unconditionally for Shiki's Oniguruma WASM. * fix(vscode-ide-companion): reset WebShell transcript state on session switch The experimental useAcpTranscript hook only consumed transcriptUpdate messages, so its reducer state survived session boundaries. When the extension switched sessions it kept the webview mounted and replayed the newly-selected session through ACP, causing the previous session's blocks to merge with the new replay (e.g. user text "alpha" from session A leaked into session B as "alphabeta"). Reset both the reducer state and the rendered blocks on the same boundaries the legacy message flow uses: qwenSessionSwitched (sent before the ACP replay of the selected session) and conversationCleared (new session). Adds a regression test that replays two sessions with a switch between them. * fix(vscode-ide-companion): harden WebShell transcript session boundaries - reset the transcript on `conversationLoaded` too, closing the same cross-session leak the previous commit fixed for `qwenSessionSwitched` and `conversationCleared` (agent reconnect posts only this boundary) - track the active session id and drop late `transcriptUpdate` frames whose `sessionId` no longer matches, so a previous session's trailing frames cannot contaminate the next session's timeline - seed the transcript from cached messages carried by `qwenSessionSwitched` so offline restores and load-failure fallbacks render their history instead of a blank timeline - dispatch `assistant.done` on `streamEnd`/`sessionLoadComplete` so the final assistant/thought block of a turn (or history replay) does not stay `streaming: true` forever * fix(vscode-ide-companion): adopt live ACP session id after load-failure fallback * fix(vscode-ide-companion): echo user prompt into WebShell transcript * fix(vscode-ide-companion): keep WebShell transcript expanded and clear of the composer * fix(vscode-ide-companion): surface local error and interrupt notices in the transcript area * fix(vscode-ide-companion): restore file-link opening from the WebShell transcript * fix(vscode-ide-companion): restore contributed copy commands for the WebShell transcript * fix(vscode-ide-companion): add localOnly marker to TextMessage state type * fix(vscode-ide-companion): restore /insight progress card and report link in the transcript UI * fix(vscode-ide-companion): finalize in-flight tools on timeout and pin session-switch seeding guard Map streamEnd reasons timeout/session_expired onto the reducer's error reason so abandoned mid-tool turns no longer spin forever (ceuI). Add qwenSessionSwitched cases with no messages field and an empty cache array; the no-messages case fails when the seeding guard is forced true, pinning its false side (ceuN). * fix(vscode-ide-companion): remove unreachable editMessage backend and dead submit options The user-message edit/rewind UI was dropped in the WebShell-transcript migration, leaving editTargetTurnIndex/onSubmitted options in useMessageSubmit and the full editMessage/rewind flow in SessionMessageHandler unreachable. Remove the dead options, the editMessage dispatch case, the rewind/snapshot flow with its recovery branches, and their tests (R1-8 direction b). * fix(vscode-ide-companion): drop write-only loadingMessage bookkeeping The waiting-message renderer was removed with the WebShell transcript migration and the user prompt is echoed into the timeline at send time (bd09e19d86), so the loadingMessage string was write-only dead state. Keep the isWaitingForResponse flag (submit gating / cancel) and pin its API surface (R1-19 direction b). * fix(vscode-ide-companion): align waiting-flag pin test with the argument-less setter * fix(vscode-ide-companion): echo attached images into the transcript timeline The prompt carries pasted/attached images as ACP resource_link blocks, which the transcript reducer cannot render (no inline data), so user images vanished from the timeline while the attach path stayed alive. Read each saved prompt image back from disk and echo it alongside the text echo as an inline user_message_chunk image part (the daemon-echo content shape), which the shared reducer folds into the user block and the WebShell renderer already displays. Unreadable images are skipped without breaking the send. * fix(vscode-ide-companion): track live VS Code theme for the transcript webShellTheme was snapshotted once at mount via useMemo with an empty dependency array, so switching the VS Code color theme left the timeline on the stale theme (VS Code updates data-vscode-theme-kind on <body> in place without reloading the webview). Hold the theme in state and refresh it with a MutationObserver on the body theme attributes. * fix(vscode-ide-companion): copy every transcript block kind and map ambiguous row keys - Copy All Messages now includes tool, shell, user_shell, and status blocks via getBlockCopyText, matching the pre-PR copyAllMessages handler which included formatted tool calls (review 5001842059 S-1). - findBlockByRowKey prefers an exact id match and otherwise the longest matching block id, so one block id that dash-prefixes a sibling (e.g. `a` vs `a-1`) can no longer capture the sibling's row key (S-4). * fix(vscode-ide-companion): drop whitespace-only cached transcript rows cachedMessageToNotification rejected empty strings but admitted whitespace-only content, which the reducer turns into an empty block when seeding history from cached rows. Reject content that trims to nothing (review 5001842059 S-2). * fix(vscode-ide-companion): ship missing third-party notices in NOTICES.txt Extend generate-notices.js so the regenerated NOTICES.txt carries the attribution texts it previously only pointed at or dropped: - Append license files from a package's licenses/ directory (echarts' Apache LICENSE references licenses/LICENSE-d3 for its embedded d3-derived files; the BSD-3-Clause text is now shipped). - Append a package's NOTICE file when present (Apache-2.0 §4(d)), covering echarts' Apache Software Foundation attribution. - Accept string-form package.json repository values (full URLs and GitHub shorthand) instead of emitting "(No repository found)". - Fall back to the standard MIT text (copyright holder from package.json metadata) for MIT-declared packages that ship no license file. * fix(vscode-ide-companion): show a recoverable error state when the transcript chunk fails to load * test(vscode-ide-companion): gate the transcript blocks wiring into the WebShell renderer * test(vscode-ide-companion): gate the transcriptUpdate forwarding from agent to webview * docs(vscode): plan complete Web Shell cutover * fix(transcript): harden export sanitization and user identity 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 * refactor(web-shell): own daemon React bindings * fix(webui): preserve package entry filenames * refactor(vscode): complete WebShell UI cutover * chore(vscode): refresh third-party notices * fix(vscode): fill embedded chat viewport * test(web-shell): disambiguate workspace visual locator * docs: clarify webui retirement prerequisites * fix(transcript): resolve export and CI blockers * fix(vscode): match embedded chat layout to host * fix(vscode): compact embedded chat styling * test(ci): cover dual Playwright installs * fix(vscode): align embedded chat density with VS Code * fix(vscode): complete embedded composer integration * refactor: retire legacy webui package * chore: refresh lockfile after webui removal * fix(vscode): restore user message editing after cutover * refactor: narrow webui retirement to export and removal * fix(vscode): complete WebShell feature parity * test(vscode-ide-companion): repair host-wiring tests for the WebShell cutover * refactor(vscode-ide-companion): replace webui build scanner with an ESLint boundary rule The bespoke recursive source scanner reimplemented a dependency-boundary check on every extension build. A scoped no-restricted-imports rule enforces the same boundary on every lint run with less custom code; the manifest dependency entry was already removed by the cutover. * fix(web-shell): keep ChatEditor commands prop referentially stable (#9811) The `additionalSlashCommands = []` destructure default allocated a fresh array on every App render, invalidating the `commands` useMemo and breaking ChatEditor memoization on every transcript-only re-render. Default to a module-level constant instead, matching the existing EMPTY_* convention. Also align the /skills completion expectation with the autoSubmit field the completion source intentionally emits for leaf skill items. * fix(vscode): distinguish the VS Code channel and localize its chrome The companion now drives Web Shell against a shared `qwen serve` daemon, so the CLI, the browser Web Shell, and this extension all create sessions in the same workspace catalog. Web Shell recorded `'default'` for every surface, leaving VS Code conversations indistinguishable from terminal and browser ones — the panel's history listed sessions the user never opened here, and nothing attributed a session back to the editor. Give Web Shell a `sessionSourceType` prop (defaulting to today's `'default'`) and have the companion stamp `'vscode'` on the sessions it creates, then scope the history dropdown to that source. The host also supplies a stable daemon `clientId`, which the bootstrap previously declared but never sent. Web Shell localizes its own surface from the `language` signal while the companion's chrome was hardcoded English, so a zh-CN panel rendered a Chinese transcript under an English header, history dropdown, onboarding screen, and account dialog. Route that chrome through a small string table driven by the same signal, including the host-only slash entries. Also fix accessibility defects in the history dropdown: rename and delete were revealed on hover alone and unreachable by keyboard, date headers sat inside `role="listbox"` as invalid non-option children, arrow-key roving stopped at group boundaries, `aria-modal` had no focus trap, and a primed "Delete?" survived both search changes and the pointer leaving the row. Formatting: `FileMessageHandler` and `SessionMessageHandler` were left unformatted earlier in this branch and failed the Prettier gate. * refactor(vscode): drop code orphaned by the WebShell cutover The webview entry now renders EmbeddedApp against the daemon, which left the ACP-era hook layer unreachable: nothing imports acpTranscriptAdapter, useWebViewMessages, useAcpTranscript, useToolCalls, useSessionManagement, useMessageHandling, useFileContext, useImage, or the permissionTypes added by this branch. A reachability walk from webview/index.tsx reaches eight modules; every reference to the rest comes from inside the orphaned set itself, so it deletes as a closed unit. EmbeddedWebShell goes with them. It was the host-driven entry point from the earlier stage of this branch, superseded when EmbeddedApp moved to WebShellWithProviders, and has had no consumer since — only its own DOM test and a barrel export. Also harden the daemon process lifecycle. `start()` returned the cached runtime without comparing the workspace, so in a multi-root window the second folder's chat silently reused a daemon bound to the first and scoped every session, history page, and prompt to the wrong root. Bind the daemon to its workspace and respawn on a change, keep a superseded child's late exit from tearing down its successor, and report a post-startup exit to the webview instead of leaving it fetching against a dead port. * docs(vscode): describe the daemon architecture the cutover actually ships The design doc still recorded the plan this branch started from: keep ACP as the runtime boundary, add no daemon server or loopback port, and treat "replacing ACP with daemon HTTP/SSE" as a non-goal. The final stage did exactly that, so the document argued against the code beneath it. Record the decision and its consequences instead — two processes per workspace, a daemon shared with the CLI and browser Web Shell, the vscode source type that keeps the panel's history its own, workspace rebinding in multi-root windows, and the turn-driven host features that stopped firing. * fix(vscode): repair round-2 review findings on the web-shell cutover (#9811) - closeDiff now resolves workspace-relative paths the same way showDiff does, so permission-cycle diffs opened from daemon-relative paths can actually be matched and closed - a superseded or disposed daemon child no longer reports its exit as a crash of the live daemon - authCancelled no longer hides an already-authenticated session behind onboarding; only an unknown auth state settles to unauthenticated - selection-only activeEditorChanged events no longer undo an explicit active-file exclusion - prepareSubmit dedupes mentions in both path spaces and matches typed references on a whole-reference boundary - permission diffs open only from the SDK's authoritative file_diff preview (writes included, model-controlled toolCall mining removed) - the webview HTML carries VS Code's locale so chrome strings localize - discontinued qwen-oauth models are no longer re-applied through the new-session initial-model route * fix(vscode): repair round-3 critical findings on the web-shell cutover (#9811) Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(web-shell): import daemon-react-sdk from web-shell instead of webui The cutover branch dropped the ./daemon-react-sdk export from @qwen-code/webui, but the TerminalPanel merged in from main still imports it, breaking the web-shell vite build (Missing "./daemon-react-sdk" specifier). Point the import and its test mock at @qwen-code/web-shell/daemon-react-sdk, which re-exports the same useWorkspace hook and matches every other web-shell call site. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(vscode): close WebShell UI regression gaps Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(vscode): initialize WebShell refs explicitly Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(vscode): narrow queued prompt edits Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(release): enumerate actual npm workspaces Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(web-shell): include hasOlderHistory in the render-item callback deps The renderItem useCallback reads hasOlderHistory to gate the edit action but omitted it from its dependency array, failing CI's react-hooks/exhaustive-deps gate. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(web-shell): report each connection error once to stop the inline onError re-render loop (#10454) * fix(web-shell): report each connection error once to stop the onError re-render loop While a connection error persists (e.g. the daemon is unreachable), the error-notification effect re-fires whenever the onError callback identity changes. Hosts such as the VS Code embedded app pass an inline onError and update their own state when it fires, so every notification triggers a host re-render that hands the effect a fresh callback identity — re-notifying the same persistent error forever (#10406). Track the last reported connection.error value in a ref and notify only when the value changes, resetting the tracker once the connection recovers. This guards every inline-callback consumer, not just memoized hosts. Fixes #10406 Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(web-shell): only stamp the dedup ref once an onError handler exists Stamping lastReportedConnectionErrorRef before delivery meant a host that attaches onError after a persistent connection error appeared never received it: the no-op delivery already marked the error as reported. Guard on the handler first and add a regression test covering the late-attach case (red when the guard is removed). Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * docs(web-shell): document the onError dedup contract and fix comment wording Describe the reported-once-per-distinct-error semantics, the reset on recovery, and that replacing the handler mid-error does not re-deliver. Reword the effect and test comments to describe the host class instead of naming the VS Code embedded app, which passes a useCallback handler. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * test(vscode): mirror the web-shell value-dedup in the EmbeddedApp mock The WebShellWithProviders mock re-notified on every onError identity change, mirroring the loop App.tsx can no longer produce. Rewrite it to report each distinct error value once (resetting on recovery), keep the loop guard as a regression tripwire, exercise it with a changing callback identity plus a post-delivery effect re-run, and refresh the handleShellError comment that still cited the old loop as the memoization reason. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * test(vscode): cast the captured onError prop for the mock wrapper CapturedProps is an unknown index signature, so the destructured onError needs the same cast the previous mock applied inline to stay callable under tsc. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * test(vscode): bail the EmbeddedApp mock before stamping when no onError exists The mirrored dedup effect stamped lastReportedError and counted a notification even when no handler was attached, while App.tsx returns before stamping on that path. Add the same early return so a handler attached mid-error still receives the persistent error, and pin the no-handler no-stamp behavior with a test that fails if the guard is removed. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> --------- Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(web-shell): remove duplicate history dependency Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(vscode): close remaining WebShell cutover regressions Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(vscode): keep permission diff handling host-scoped Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * test(vscode): remove orphaned completion trigger test Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * test(web-shell): update daemon SDK mock import Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(export): reject unsupported legacy JSONL Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * docs(transcript): record the legacy HTML renderer deletion evidence The contract prevalidation doc is this design's single normative source (§0.1), so retiring the legacy renderer has to be written back into it. Three places had drifted: - §2.1's consumer table still said the HTML Export path "keeps legacy compatibility for public calls without records". `toHtml` now requires records and the legacy branch is gone. - §14's completion gate said the legacy HTML renderer is removed only once there is deletion evidence. New §12.4 records that evidence — no product consumer left, signature tightened, fallback explicitly rejected rather than silently degraded, and a `check:no-webui` guard against reintroduction — and keeps the VS Code legacy timeline half of the gate untouched. - §10.7 promised credential removal without stating its scope. Spell out that it is http(s) only, and that non-navigable schemes, bare flag credentials and `code` / `inlineCode` nodes ship verbatim, so the document boundary is not read as a general secret scanner. Also comment the two export format signatures: `records` is required because HTML projects from original records, and the other formatters ignore the argument. Docs and comments only; no build or test was run locally. * fix(docs): correct web-shell SDK hook names, daemon dir table, followup wiring - daemon-client-adapters/web-shell.md: use the names the barrel actually exports (useActions/useConnection/usePendingPermissions/ useTranscriptBlocks) in the import example and minimal React shape - daemon/14-cli-tui-adapter.md: rewrite the packages/web-shell/client/daemon/ file table to the real layout (session/DaemonSessionProvider.tsx; the transcript adapter now lives in client/adapters/ and only exports extractPendingPermission) - users/features/followup-suggestions.md: suggestion generation is automatic server-side; Web Shell hosts need no trigger wiring Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> Patrol-Run: qwen-pr-closeout/jmtngpuscjl * fix(scripts): catch bare packages/webui references in check:no-webui Widen the second forbidden pattern to /packages\/webui\b/g so references followed by spaces, punctuation, or end-of-line are flagged (CI step text, YAML list items, parenthesized mentions), while lookalikes such as packages/webuix stay clean. Extract the detection into containsForbiddenReference() and pin it with scripts/tests fixtures, following the check-tui-dep-direction export convention. The current tree still scans clean: node scripts/check-no-webui-dependency.js exits 0. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> Patrol-Run: qwen-pr-closeout/jmtngpuscjl * fix(docs): drop dead Adapter Matrix citation and stale Chromatic line - 16-vscode-ide-adapter.md: 01-architecture.md has no "Adapter Matrix" section (headings verified at HEAD); drop the dead citation tail and keep the verified embedding claim (R1-11). - terminal-capture/motivation.md: Chromatic retired with the webui package; point the "complement" item at the Playwright-based Web Shell visual tests already shown in this file's diagram (R1-12). Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> Patrol-Run: qwen-pr-closeout/jmtntktgsk8 * fix(comments): correct stale webui-era notes in SDK test and followup state - daemonUi.test.ts: the referenced previewMarkdown/rawOutput preservation test does not exist in web-shell (transcriptAdapter.test.ts only covers extractPendingPermission); rewrite the note to say the enrichment path retired with the webui package instead of citing a nonexistent test (R1-6). Wording avoids the retired package literal so check:no-webui still passes. - followupState.ts: no web-shell file imports this module (its daemon followup hook keeps its own FollowupState/controller; the only createFollowupController consumer is the CLI Ink hook); fix the module purpose comment and the createFollowupController docblock accordingly (R1-13). Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> Patrol-Run: qwen-pr-closeout/jmtntktgsk8 * fix(export): load transcript renderer from unpkg (#11035) * fix(export): load transcript renderer from CDN * fix(export): harden CDN renderer loading * fix(export): host transcript renderer on project OSS * fix(export): serve npm renderer through unpkg * fix(release): verify export renderer before VSIX packaging * docs(daemon): retire the stale ACPAdapter and web-ui.md pointers R1-2/R1-4 from the review round: the Consumers note still claimed the old ACPAdapter host postMessage path "remains available" while this PR deletes the only ACPAdapter, and the migration-status bullet still pointed at web-ui.md after this PR renamed it to web-shell.md. Both lines now state what ships: the postMessage path retired with packages/webui (webviews embed Web Shell, matching 16-vscode-ide-adapter.md), and the adapter design doc is web-shell.md. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * docs: avoid retired webui path reference * fix: close WebUI retirement review gaps --------- Co-authored-by: heyang.why <heyang.why@alibaba-inc.com> Co-authored-by: Shaojin Wen <shaojin.wensj@alibaba-inc.com> Co-authored-by: qwen-code-dev-bot <qwen-code-dev@service.alibaba.com> Co-authored-by: yiliang114 <jinjing.zzj@gmail.com> Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
120 lines
4 KiB
JavaScript
120 lines
4 KiB
JavaScript
/**
|
|
* @license
|
|
* Copyright 2025 Google LLC
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
import { execSync } from 'node:child_process';
|
|
import { existsSync } from 'node:fs';
|
|
import { dirname, join } from 'node:path';
|
|
import { fileURLToPath } from 'node:url';
|
|
|
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
const root = join(__dirname, '..');
|
|
|
|
// npm install if node_modules was removed (e.g. via npm run clean or scripts/clean.js)
|
|
if (!existsSync(join(root, 'node_modules'))) {
|
|
execSync('npm install', { stdio: 'inherit', cwd: root });
|
|
}
|
|
|
|
// build all workspaces/packages in dependency order
|
|
execSync('npm run generate', { stdio: 'inherit', cwd: root });
|
|
|
|
// --cli-only: skip packages not needed by the CLI bundle. Web Shell still
|
|
// builds because the HTML export publishes its document renderer with npm.
|
|
const cliOnly = process.argv.includes('--cli-only');
|
|
|
|
// Build in dependency order:
|
|
// 1. core (foundation package, includes test-utils)
|
|
// 2. channel-base (base channel infrastructure - used by channel adapters and cli)
|
|
// 3. channel adapters (depend on channel-base)
|
|
// 4. audio-capture (native microphone backend used by cli)
|
|
// 5. acp-bridge (depends on core - used by cli)
|
|
// 6. sdk (build-time devDep on acp-bridge for shared constants, used by cli channel worker)
|
|
// 7. web-shell (document renderer used by web-templates)
|
|
// 8. web-templates (embeddable web templates - used by cli)
|
|
// 9. cli (depends on core, acp-bridge, web-templates, channel packages, sdk)
|
|
// 10. vscode-ide-companion
|
|
// 11. external-context integrations (private Qwen extensions)
|
|
const buildOrder = [
|
|
'packages/core',
|
|
'packages/channels/base',
|
|
'packages/channels/telegram',
|
|
'packages/channels/weixin',
|
|
'packages/channels/dingtalk',
|
|
'packages/channels/dws',
|
|
'packages/channels/wecom',
|
|
'packages/channels/feishu',
|
|
'packages/channels/qqbot',
|
|
'packages/channels/github',
|
|
// gitlab is a builtin of the cli channel registry like its siblings; it
|
|
// used to build only transitively via cli's tsconfig project reference.
|
|
'packages/channels/gitlab',
|
|
'packages/channels/plugin-example',
|
|
'packages/audio-capture',
|
|
'packages/node-repl',
|
|
'packages/acp-bridge',
|
|
'packages/sdk-typescript',
|
|
'packages/web-shell',
|
|
'packages/web-templates',
|
|
'packages/cli',
|
|
...(cliOnly
|
|
? []
|
|
: [
|
|
'packages/qwen-live',
|
|
'packages/vscode-ide-companion',
|
|
'packages/chrome-extension',
|
|
'integrations/external-context',
|
|
'integrations/external-context-mem0',
|
|
]),
|
|
];
|
|
|
|
for (const workspace of buildOrder) {
|
|
const command =
|
|
workspace === 'packages/audio-capture'
|
|
? `npm run build:ts --workspace=${workspace}`
|
|
: `npm run build --workspace=${workspace}`;
|
|
execSync(command, { stdio: 'inherit', cwd: root });
|
|
|
|
// After cli is built, generate the JSON Schema for settings
|
|
// so the vscode-ide-companion extension can provide IntelliSense
|
|
if (workspace === 'packages/cli') {
|
|
execSync('node --import tsx/esm scripts/generate-settings-schema.ts', {
|
|
stdio: 'inherit',
|
|
cwd: root,
|
|
});
|
|
}
|
|
}
|
|
|
|
// also build container image if sandboxing is enabled
|
|
// skip (-s) npm install + build since we did that above
|
|
try {
|
|
execSync('node scripts/sandbox_command.js -q', {
|
|
stdio: 'inherit',
|
|
cwd: root,
|
|
});
|
|
if (
|
|
process.env.BUILD_SANDBOX === '1' ||
|
|
process.env.BUILD_SANDBOX === 'true'
|
|
) {
|
|
execSync('node scripts/build_sandbox.js -s', {
|
|
stdio: 'inherit',
|
|
cwd: root,
|
|
});
|
|
}
|
|
} catch {
|
|
// ignore
|
|
}
|