qwen-code/integration-tests/tsconfig.json
易良 fe34a5cf22
refactor(vscode-ide-companion): complete the WebShell UI cutover (#9811)
* 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

* 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

* fix(vscode): match embedded chat layout to host

* fix(vscode): compact embedded chat styling

* fix(vscode): align embedded chat density with VS Code

* fix(vscode): complete embedded composer integration

* fix(vscode): restore user message editing after cutover

* 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>

---------

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>
2026-08-29 16:37:47 +00:00

165 lines
7.9 KiB
JSON

{
"extends": "../tsconfig.json",
"compilerOptions": {
"noEmit": true,
"allowJs": true,
// Nothing references this project and it emits nothing, but the root
// config turns `composite` on for the packages that do. Composite demands
// that every file in the program appear in `include`, and these tests
// import package sources across the repo by relative path, so inheriting
// it produced 300+ TS6307 "not listed within the file list" errors.
"composite": false,
// The root turns `noPropertyAccessFromIndexSignature` on, which forced
// bracket-access rewrites in production SDK sources just to satisfy this
// test program. Relax it here so
// packages keep their own compiler regime and the tests keep dot access.
"noPropertyAccessFromIndexSignature": false,
// Matches packages/cli. The suite drives browser-side code in
// `terminal-capture/` and pulls SDK sources that reference `WebSocket` /
// `HeadersInit`, none of which exist in the root's ES2023-only lib.
"lib": ["DOM", "DOM.Iterable", "ES2023"],
"baseUrl": ".",
// Resolve workspace packages from source so `tsc -p` here does not depend
// on whether someone had built them recently — a missing dist used to fail
// resolution outright and a stale one silently typechecked against old
// declarations. nodenext does no extension or index probing on
// substituted paths, so every subpath the program imports needs an
// explicit entry naming its source file; a bare wildcard falls through to
// the package exports map, i.e. back to dist. Keep these in sync with the
// packages' exports maps. The runtime vitest aliases
// (`integration-tests/vitest.config.ts`) still point at the built SDK
// bundle to exercise the published-bundle shape; these entries only affect
// type resolution.
//
// Keep notes like this OUT of `paths` itself: every value there must be an
// array, so a `"//"` string key makes tsc abort with TS5063 before it type
// checks a single file — which is how this project silently went unchecked.
"paths": {
// These tests import package sources by relative path
// (`../../packages/cli/src/...`), so those files get checked here too
// and must resolve their own imports.
"@qwen-code/qwen-code-core": ["../packages/core/src/index.ts"],
"@qwen-code/qwen-code-core/subSessionConstants": [
"../packages/core/src/tools/sub-session-constants.ts"
],
"@qwen-code/qwen-code-core/transcriptRecords": [
"../packages/core/src/utils/transcript-records.ts"
],
"@qwen-code/qwen-code-core/goalWire": [
"../packages/core/src/goals/goal-wire.ts"
],
"@qwen-code/qwen-code-core/memoryScopes": [
"../packages/core/src/memory/scopes.ts"
],
"@qwen-code/qwen-code-core/userPromptSubmitContext": [
"../packages/core/src/hooks/user-prompt-submit-context.ts"
],
"@qwen-code/sdk": ["../packages/sdk-typescript/src/index.ts"],
"@qwen-code/sdk/daemon": [
"../packages/sdk-typescript/src/daemon/index.ts"
],
"@qwen-code/sdk/daemon/transcript": [
"../packages/sdk-typescript/src/daemon/transcript.ts"
],
"@qwen-code/sdk/daemon/transports": [
"../packages/sdk-typescript/src/daemon/transports.ts"
],
"@qwen-code/sdk/daemon/types": [
"../packages/sdk-typescript/src/daemon/types.ts"
],
"@qwen-code/sdk/daemon/ui/transcript": [
"../packages/sdk-typescript/src/daemon/ui/transcript.ts"
],
"@qwen-code/acp-bridge": ["../packages/acp-bridge/src/index.ts"],
"@qwen-code/acp-bridge/bridge": ["../packages/acp-bridge/src/bridge.ts"],
"@qwen-code/acp-bridge/bridgeClient": [
"../packages/acp-bridge/src/bridgeClient.ts"
],
"@qwen-code/acp-bridge/bridgeErrors": [
"../packages/acp-bridge/src/bridgeErrors.ts"
],
"@qwen-code/acp-bridge/bridgeFileSystem": [
"../packages/acp-bridge/src/bridgeFileSystem.ts"
],
"@qwen-code/acp-bridge/bridgeOptions": [
"../packages/acp-bridge/src/bridgeOptions.ts"
],
"@qwen-code/acp-bridge/bridgeTypes": [
"../packages/acp-bridge/src/bridgeTypes.ts"
],
"@qwen-code/acp-bridge/channelControlTimeouts": [
"../packages/acp-bridge/src/channel-control-timeouts.ts"
],
"@qwen-code/acp-bridge/childHeapPolicy": [
"../packages/acp-bridge/src/child-heap-policy.ts"
],
"@qwen-code/acp-bridge/daemonEventTypes": [
"../packages/acp-bridge/src/daemonEventTypes.ts"
],
"@qwen-code/acp-bridge/daemonMemoryBudget": [
"../packages/acp-bridge/src/daemon-memory-budget.ts"
],
"@qwen-code/acp-bridge/eventBus": [
"../packages/acp-bridge/src/eventBus.ts"
],
"@qwen-code/acp-bridge/externalToolGuard": [
"../packages/acp-bridge/src/externalToolGuard.ts"
],
"@qwen-code/acp-bridge/logRedaction": [
"../packages/acp-bridge/src/logRedaction.ts"
],
"@qwen-code/acp-bridge/mcpTimeouts": [
"../packages/acp-bridge/src/mcpTimeouts.ts"
],
"@qwen-code/acp-bridge/sessionArtifacts": [
"../packages/acp-bridge/src/sessionArtifacts.ts"
],
"@qwen-code/acp-bridge/spawnChannel": [
"../packages/acp-bridge/src/spawnChannel.ts"
],
"@qwen-code/acp-bridge/status": ["../packages/acp-bridge/src/status.ts"],
"@qwen-code/acp-bridge/transcriptReplay": [
"../packages/acp-bridge/src/transcript-replay.ts"
],
"@qwen-code/acp-bridge/workspacePaths": [
"../packages/acp-bridge/src/workspacePaths.ts"
],
// qwen-serve-webui-live-journal-recovery.test.ts imports Web Shell's
// daemon bindings; map to source so typecheck does not depend on dist.
"@qwen-code/web-shell/daemon-react-sdk": [
"../packages/web-shell/client/daemon-react-sdk.ts"
],
// channel-plugin.test.ts and the plugin-example sources it imports
// both import `@qwen-code/channel-base`. Map it to source so the
// typecheck does not depend on channel-base's dist and both import
// sites share one declaration — mixing src and dist declarations
// produces duplicate-private-class errors.
"@qwen-code/channel-base": ["../packages/channels/base/src/index.ts"],
// cli's channel-registry.ts imports the nine builtin channel
// adapters and html.ts imports web-templates; without entries they
// resolve through their exports maps to dist, leaving the typecheck
// dependent on those packages being built.
"@qwen-code/channel-telegram": [
"../packages/channels/telegram/src/index.ts"
],
"@qwen-code/channel-weixin": ["../packages/channels/weixin/src/index.ts"],
"@qwen-code/channel-dingtalk": [
"../packages/channels/dingtalk/src/index.ts"
],
"@qwen-code/channel-dws": ["../packages/channels/dws/src/index.ts"],
"@qwen-code/channel-wecom": ["../packages/channels/wecom/src/index.ts"],
"@qwen-code/channel-feishu": ["../packages/channels/feishu/src/index.ts"],
"@qwen-code/channel-qqbot": ["../packages/channels/qqbot/src/index.ts"],
"@qwen-code/channel-github": ["../packages/channels/github/src/index.ts"],
"@qwen-code/channel-gitlab": ["../packages/channels/gitlab/src/index.ts"],
"@qwen-code/web-templates": ["../packages/web-templates/src/index.ts"],
// node-pty declares `types` at the top level but its `exports` map is a
// bare string with no `types` condition, so nodenext resolution never
// reaches the declarations and every pty handle degrades to `any` —
// which is what silently untyped the `data` / `exitCode` callbacks in
// test-helper.ts. Point at the shipped .d.ts directly.
"@lydell/node-pty": ["../node_modules/@lydell/node-pty/node-pty.d.ts"]
}
},
"include": ["**/*.ts", "**/*.tsx"]
}