Skip to content

feat(serve): add read-only status routes#4241

Merged
wenshao merged 5 commits into
mainfrom
feat/serve-readonly-status-routes
May 17, 2026
Merged

feat(serve): add read-only status routes#4241
wenshao merged 5 commits into
mainfrom
feat/serve-readonly-status-routes

Conversation

@doudouOUC

Copy link
Copy Markdown
Collaborator

Summary

  • What changed: Adds read-only daemon runtime status endpoints for workspace MCP servers, skills, model providers, session context, and session supported commands. The new surface is advertised through daemon capabilities and mirrored by typed SDK helpers.
  • Why it changed: proposal(serve): Mode B feature-priority roadmap toward v0.16 production-ready #4175 Wave 3 needs client UIs to inspect daemon-side runtime state without mutating sessions, changing existing route behavior, or starting ACP just because a workspace status route is polled.
  • Reviewer focus: Please check the idle workspace behavior (initialized: false without spawning ACP), unknown-session 404 mapping, and the status payload redaction boundary for MCP/provider/skill details.

Validation

  • Commands run:
    cd packages/cli && npx vitest run src/serve/server.test.ts src/serve/httpAcpBridge.test.ts src/acp-integration/acpAgent.test.ts src/acp-integration/session/Session.test.ts
    cd packages/sdk-typescript && npx vitest run test/unit/DaemonClient.test.ts test/unit/DaemonSessionClient.test.ts
    cd packages/core && npm run build
    cd packages/cli && npm run typecheck
    cd packages/sdk-typescript && npm run typecheck
    git diff --check
  • Prompts / inputs used: N/A.
  • Expected result: New read-only routes return typed snapshots, workspace routes do not spawn ACP while idle, session routes require a live session, SDK wrappers GET the documented URLs, and typecheck passes.
  • Observed result: CLI focused tests passed (4 files, 347 tests), SDK focused tests passed (2 files, 76 tests), both touched packages typechecked successfully, and git diff --check reported no whitespace issues.
  • Quickest reviewer verification path: Run the two focused vitest commands above, then inspect /capabilities for the five new feature tags and poll /workspace/mcp before creating a session to confirm initialized: false.
  • Evidence (output, logs, screenshots, video, JSON, before/after, etc.): The local command output showed all focused tests passing and both tsc --noEmit runs completing successfully.

Scope / Risk

  • Main risk or tradeoff: Status payloads intentionally expose only summarized runtime state. Deeper preflight diagnostics, mutation gating, dynamic capability registration, and plugin/ext routes remain out of scope.
  • Not covered / not validated: No Docker, Podman, Seatbelt, or Windows validation was run locally.
  • Breaking changes / migration notes: None. This is additive on the existing v1 capabilities envelope and serve protocol version.

Testing Matrix

🍏 🪟 🐧
npm run ⚠️ ⚠️
npx ⚠️ ⚠️
Docker ⚠️ ⚠️ ⚠️
Podman ⚠️ N/A N/A
Seatbelt ⚠️ N/A N/A

Testing matrix notes:

  • macOS validation covered focused vitest runs and package typechecks.
  • Windows/Linux/container sandbox validation was not run locally.

Linked Issues / Bugs

Related to #4175.

@github-actions

Copy link
Copy Markdown
Contributor

📋 Review Summary

This PR adds read-only daemon runtime status endpoints for workspace MCP servers, skills, model providers, session context, and session supported commands. The implementation is well-structured with comprehensive test coverage, proper type safety across CLI and SDK packages, and thoughtful security considerations around data redaction. The changes are additive and maintain backward compatibility with the existing v1 capabilities envelope.

🔍 General Feedback

  • Architecture: Clean separation between route handlers (server.ts), bridge interface (httpAcpBridge.ts), and ACP implementation (acpAgent.ts). The use of extMethod for extension methods is a good pattern for non-core functionality.
  • Type Safety: Excellent type mirroring between CLI (Serve* types in status.ts) and SDK (Daemon* types in types.ts), with proper schema versioning.
  • Testing: Strong test coverage with 347 CLI tests and 76 SDK tests passing. Tests cover idle workspace behavior, session encoding, and error scenarios.
  • Documentation: Protocol documentation (qwen-serve-protocol.md) is updated with detailed route specifications and examples.
  • Security Conscious: Status payloads intentionally exclude sensitive data (MCP env values, API keys, skill filesystem paths, hook definitions).

🎯 Specific Feedback

🟡 High

  • File: packages/cli/src/serve/httpAcpBridge.ts:2054-2070 - The requestWorkspaceStatus helper returns the idle fallback when liveChannelInfo() returns null, but there's no timeout race with getChannelClosedReject like in requestSessionStatus. This could potentially block indefinitely if the channel is in a transitional state. Consider adding the same timeout + channel-closed race pattern used for session status requests.

  • File: packages/cli/src/acp-integration/acpAgent.ts:643-666 - buildWorkspaceMcpStatus doesn't wrap its execution in a try-catch, unlike buildWorkspaceSkillsStatus which properly catches errors and returns them in an errors array. If getMCPServerStatus(name) throws for any server, the entire route will 500 instead of returning partial data with error cells.

🟢 Medium

  • File: packages/cli/src/serve/status.ts:14-20 - The SERVE_STATUS_EXT_METHODS constants use snake_case for method names (workspace/mcp, session/supported_commands) while the capability registry in capabilities.ts uses snake_case consistently. However, the URL paths use kebab-case (/workspace/mcp, /session/supported-commands). This inconsistency (supported_commands vs supported-commands) could cause confusion. Consider standardizing on one convention.

  • File: packages/sdk-typescript/src/daemon/DaemonClient.ts:293-326 - The three workspace status methods (workspaceMcp, workspaceSkills, workspaceProviders) have nearly identical implementations with only the URL and error message differing. Consider extracting a helper method to reduce duplication, similar to how sessionContext and sessionSupportedCommands could also be consolidated.

  • File: packages/cli/src/serve/server.ts:225-247 - The three workspace status route handlers are identical except for the bridge method called. Consider extracting to a helper function to reduce boilerplate and ensure consistent error handling patterns.

🔵 Low

  • File: packages/cli/src/serve/status.ts:88 - The ServeWorkspaceSkillsStatus interface has an optional errors?: ServeStatusCell[] field, but the SDK type in packages/sdk-typescript/src/daemon/types.ts:230 also has this field. The PR description mentions "errors is omitted when discovery succeeds" — consider documenting this in a JSDoc comment on the field itself for future maintainers.

  • File: packages/cli/src/acp-integration/acpAgent.ts:723-802 - buildWorkspaceProvidersStatus is quite complex (80 lines) with nested loops and multiple conditional branches. Consider extracting the provider model building logic into a separate helper method for better testability and readability.

  • File: packages/sdk-typescript/src/daemon/DaemonSessionClient.ts:187-194 - The new context() and supportedCommands() methods don't include JSDoc comments explaining their purpose or when to use them, unlike other methods in the class. Consider adding brief documentation.

  • File: docs/developers/qwen-serve-protocol.md:162-170 - The DaemonStatusCell type definition in the protocol docs shows the common status cell shape, but doesn't explicitly document all valid status values (ok, warning, error, disabled, not_started, unknown). Consider adding the union type to the docs for completeness.

✅ Highlights

  • Excellent Security Design: The explicit redaction boundary documented in status.ts and enforced in the builder methods prevents leakage of MCP env values, headers, OAuth/service-account details, provider API keys, skill filesystem paths, and hook definitions. This is a thoughtful security-first approach.

  • Idle Workspace Behavior: The intentional design that workspace routes return initialized: false without spawning ACP when the daemon is idle is a great performance optimization. This prevents unnecessary resource consumption from polling clients.

  • Proper Session ID Encoding: The session status routes correctly use encodeURIComponent(sessionId) in the SDK (DaemonClient.ts:413) to handle session IDs with special characters (e.g., slashes), and tests verify this behavior.

  • Comprehensive Test Coverage: The test suite thoroughly covers:

    • Idle workspace behavior (returning initialized: false)
    • Unknown session 404 mapping
    • Session ID URL encoding
    • Payload shapes matching documentation
    • Error handling paths
  • Clean Type Mirroring: The parallel type definitions between CLI (Serve*) and SDK (Daemon*) are well-maintained with consistent naming and structure, making it easy to verify they match.

  • Protocol Versioning: Using STATUS_SCHEMA_VERSION = 1 and the same versioning approach as the capabilities envelope ensures forward compatibility and clean evolution of the status routes.

@doudouOUC doudouOUC force-pushed the feat/serve-readonly-status-routes branch from a1e0b36 to b590c87 Compare May 17, 2026 10:41
@doudouOUC doudouOUC marked this pull request as ready for review May 17, 2026 10:58
Copilot AI review requested due to automatic review settings May 17, 2026 10:58

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a new set of read-only daemon runtime “status” endpoints to qwen serve, advertises them via serve capabilities, and mirrors them in the TypeScript SDK with typed helpers—enabling client UIs to inspect daemon/workspace/session state without mutating sessions or spawning ACP while idle.

Changes:

  • Added new HTTP GET routes for workspace and session status snapshots (/workspace/*, /session/:id/*) wired through the bridge with “idle workspace = initialized:false” behavior.
  • Implemented ACP ext-method handlers to produce redacted status payloads for MCP, skills, providers, session context, and supported commands.
  • Extended the TS SDK with new status wire types and client methods + unit tests; updated serve protocol docs to describe the new routes/capabilities.

Reviewed changes

Copilot reviewed 19 out of 19 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
packages/cli/src/serve/status.ts Defines serve-side status wire types + ext-method names + idle snapshot helpers.
packages/cli/src/serve/server.ts Adds the new read-only GET routes and wires them to the bridge.
packages/cli/src/serve/httpAcpBridge.ts Implements workspace/session status requests without spawning ACP when idle.
packages/cli/src/acp-integration/acpAgent.ts Implements ACP ext methods that build redacted status payloads.
packages/cli/src/acp-integration/session/Session.ts Refactors available-command snapshot building for reuse by status endpoints.
packages/sdk-typescript/src/daemon/types.ts Adds SDK-side typings for the new status payloads.
packages/sdk-typescript/src/daemon/DaemonClient.ts Adds SDK helper methods that GET the new status endpoints.
packages/sdk-typescript/src/daemon/DaemonSessionClient.ts Adds session-scoped wrappers for context + supported-commands status.
packages/cli/src/serve/capabilities.ts Advertises new capability tags for the status endpoints.
packages/cli/src/serve/server.test.ts Adds route-level tests for new status endpoints + 404 mapping.
packages/cli/src/serve/httpAcpBridge.test.ts Adds tests for idle behavior (no spawn) + ext-method routing.
packages/sdk-typescript/test/unit/DaemonClient.test.ts Adds tests for new DaemonClient status helpers (incl. encoded IDs).
packages/sdk-typescript/test/unit/DaemonSessionClient.test.ts Adds tests for new DaemonSessionClient status helpers.
docs/users/qwen-serve.md Documents the new read-only status routes for users.
docs/developers/qwen-serve-protocol.md Documents capability tags + wire shapes for the new status routes.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread docs/developers/qwen-serve-protocol.md
@github-actions

github-actions Bot commented May 17, 2026

Copy link
Copy Markdown
Contributor

Code Coverage Summary

Package Lines Statements Functions Branches
CLI 77.26% 77.26% 78.61% 80.5%
Core 79.25% 79.25% 81.92% 82.73%
CLI Package - Full Text Report
-------------------|---------|----------|---------|---------|-------------------
File               | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
-------------------|---------|----------|---------|---------|-------------------
All files          |   77.26 |     80.5 |   78.61 |   77.26 |                   
 src               |   75.73 |    69.15 |   80.55 |   75.73 |                   
  gemini.tsx       |   68.53 |     66.4 |   76.47 |   68.53 | ...29,946-949,957 
  ...ractiveCli.ts |      80 |    68.61 |   78.57 |      80 | ...1020,1058,1161 
  ...liCommands.ts |   74.51 |     72.5 |     100 |   74.51 | ...41-265,290,391 
  ...ActiveAuth.ts |     100 |     87.5 |     100 |     100 | 66-80             
 ...cp-integration |   68.67 |    70.19 |   73.46 |   68.67 |                   
  acpAgent.ts      |   70.98 |    70.38 |   79.54 |   70.98 | ...1350,1364-1372 
  authMethods.ts   |   12.19 |      100 |       0 |   12.19 | 11-31,34-38,41-50 
  errorCodes.ts    |       0 |        0 |       0 |       0 | 1-22              
  ...DirContext.ts |     100 |      100 |     100 |     100 |                   
 ...ration/service |   68.65 |    83.33 |   66.66 |   68.65 |                   
  filesystem.ts    |   68.65 |    83.33 |   66.66 |   68.65 | ...32,77-94,97-98 
 ...ration/session |   76.97 |    72.12 |   86.25 |   76.97 |                   
  ...ryReplayer.ts |   67.34 |     75.6 |   81.81 |   67.34 | ...54-269,282-283 
  Session.ts       |   76.32 |    70.86 |   88.46 |   76.32 | ...2537,2543-2546 
  ...entTracker.ts |   90.85 |    84.84 |      90 |   90.85 | ...35,199,251-260 
  index.ts         |       0 |        0 |       0 |       0 | 1-40              
  ...ssionUtils.ts |   84.21 |    77.77 |     100 |   84.21 | ...37-153,209-211 
  types.ts         |       0 |        0 |       0 |       0 | 1                 
 ...ssion/emitters |   96.01 |    90.75 |    92.3 |   96.01 |                   
  BaseEmitter.ts   |   76.92 |    66.66 |      80 |   76.92 | 23-24,39-40,55-56 
  ...ageEmitter.ts |     100 |    89.47 |     100 |     100 | 109,111           
  PlanEmitter.ts   |     100 |      100 |     100 |     100 |                   
  ...allEmitter.ts |   98.06 |     92.3 |     100 |   98.06 | 227-228,327,335   
  index.ts         |       0 |        0 |       0 |       0 | 1-10              
 ...ession/rewrite |   90.36 |    87.83 |   94.11 |   90.36 |                   
  LlmRewriter.ts   |      81 |       84 |     100 |      81 | ...,88-89,155-159 
  ...Middleware.ts |   95.83 |    85.71 |     100 |   95.83 | 119,127-129       
  TurnBuffer.ts    |     100 |      100 |     100 |     100 |                   
  config.ts        |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  types.ts         |       0 |        0 |       0 |       0 | 1                 
 src/auth          |    97.7 |    94.81 |   95.45 |    97.7 |                   
  allProviders.ts  |     100 |      100 |     100 |     100 |                   
  ...iderConfig.ts |    97.6 |    95.04 |     100 |    97.6 | ...61,411,433-434 
  types.ts         |       0 |        0 |       0 |       0 | 1                 
 src/auth/install  |   98.57 |    88.88 |     100 |   98.57 |                   
  ...nstallPlan.ts |   98.57 |    88.88 |     100 |   98.57 | 80,93             
 ...viders/alibaba |   96.96 |    66.66 |   66.66 |   96.96 |                   
  ...baStandard.ts |     100 |      100 |     100 |     100 |                   
  codingPlan.ts    |   93.67 |    66.66 |   66.66 |   93.67 | 83,87-89,94       
  tokenPlan.ts     |     100 |      100 |     100 |     100 |                   
 ...oviders/custom |     100 |      100 |     100 |     100 |                   
  ...omProvider.ts |     100 |      100 |     100 |     100 |                   
 ...roviders/oauth |    91.5 |    77.03 |   97.05 |    91.5 |                   
  openrouter.ts    |   84.37 |    33.33 |     100 |   84.37 | 43-48             
  ...outerOAuth.ts |    91.9 |    79.06 |   96.87 |    91.9 | ...53-655,699-701 
 ...ers/thirdParty |     100 |      100 |     100 |     100 |                   
  deepseek.ts      |     100 |      100 |     100 |     100 |                   
  idealab.ts       |     100 |      100 |     100 |     100 |                   
  minimax.ts       |     100 |      100 |     100 |     100 |                   
  modelscope.ts    |     100 |      100 |     100 |     100 |                   
  zai.ts           |     100 |      100 |     100 |     100 |                   
 src/commands      |   55.55 |    85.71 |   43.47 |   55.55 |                   
  auth.ts          |     100 |    83.33 |     100 |     100 | 11,14             
  channel.ts       |   56.66 |      100 |       0 |   56.66 | 15-19,27-34       
  extensions.tsx   |   96.55 |      100 |      50 |   96.55 | 37                
  hooks.tsx        |   66.66 |      100 |       0 |   66.66 | 20-24             
  mcp.ts           |   94.73 |      100 |      50 |   94.73 | 28                
  review.ts        |   51.85 |      100 |       0 |   51.85 | 24-35,38          
  serve.ts         |    10.3 |      100 |       0 |    10.3 | ...48-123,125-164 
 ...mmands/channel |   39.25 |    79.45 |      50 |   39.25 |                   
  ...l-registry.ts |    8.57 |      100 |       0 |    8.57 | 6-21,24-42        
  config-utils.ts  |      92 |      100 |   66.66 |      92 | 21-26             
  configure.ts     |    14.7 |      100 |       0 |    14.7 | 18-21,23-84       
  pairing.ts       |   26.31 |      100 |       0 |   26.31 | ...30,40-50,52-65 
  pidfile.ts       |   96.34 |    86.95 |     100 |   96.34 | 49,59,91          
  start.ts         |   30.98 |       52 |   69.23 |   30.98 | ...72-475,484-486 
  status.ts        |   17.85 |      100 |       0 |   17.85 | 15-26,32-76       
  stop.ts          |      20 |      100 |       0 |      20 | 14-48             
 ...nds/extensions |    84.5 |    88.95 |   81.81 |    84.5 |                   
  consent.ts       |   71.65 |    89.28 |   42.85 |   71.65 | ...85-141,156-162 
  disable.ts       |     100 |      100 |     100 |     100 |                   
  enable.ts        |     100 |      100 |     100 |     100 |                   
  install.ts       |    75.6 |    66.66 |   66.66 |    75.6 | ...39-142,145-153 
  link.ts          |     100 |      100 |     100 |     100 |                   
  list.ts          |     100 |      100 |     100 |     100 |                   
  new.ts           |     100 |      100 |     100 |     100 |                   
  settings.ts      |   99.15 |      100 |   83.33 |   99.15 | 151               
  uninstall.ts     |    37.5 |      100 |   33.33 |    37.5 | 23-45,57-64,67-70 
  update.ts        |   96.32 |      100 |     100 |   96.32 | 101-105           
  utils.ts         |   60.24 |    28.57 |     100 |   60.24 | ...81,83-87,89-93 
 ...les/mcp-server |       0 |        0 |       0 |       0 |                   
  example.ts       |       0 |        0 |       0 |       0 | 1-60              
 src/commands/mcp  |   92.29 |    86.08 |   88.88 |   92.29 |                   
  add.ts           |     100 |    98.03 |     100 |     100 | 293               
  list.ts          |   91.22 |    80.76 |      80 |   91.22 | ...19-121,146-147 
  reconnect.ts     |   76.72 |    71.42 |   85.71 |   76.72 | 35-48,153-175     
  remove.ts        |     100 |       80 |     100 |     100 | 21-25             
 ...ommands/review |   11.57 |      100 |       0 |   11.57 |                   
  cleanup.ts       |   17.94 |      100 |       0 |   17.94 | ...01-106,108-109 
  deterministic.ts |   13.75 |      100 |       0 |   13.75 | ...22-738,740-741 
  fetch-pr.ts      |   11.36 |      100 |       0 |   11.36 | ...80-201,203-204 
  load-rules.ts    |   11.32 |      100 |       0 |   11.32 | ...41-153,155-156 
  pr-context.ts    |    6.22 |      100 |       0 |    6.22 | ...97-312,314-315 
  presubmit.ts     |    9.35 |      100 |       0 |    9.35 | ...62-287,289-290 
 ...nds/review/lib |      30 |      100 |       0 |      30 |                   
  gh.ts            |   22.58 |      100 |       0 |   22.58 | ...49,53-54,62-69 
  git.ts           |   22.72 |      100 |       0 |   22.72 | 15-18,29-39,43-44 
  paths.ts         |   52.94 |      100 |       0 |   52.94 | ...26,37-38,42-43 
 src/config        |   92.89 |    85.31 |   88.09 |   92.89 |                   
  auth.ts          |   86.98 |    80.32 |     100 |   86.98 | ...26-227,243-244 
  config.ts        |   88.68 |     85.1 |      80 |   88.68 | ...1826,1828-1836 
  keyBindings.ts   |   96.55 |       50 |     100 |   96.55 | 193-196           
  ...idersScope.ts |      92 |       90 |     100 |      92 | 11-12             
  sandboxConfig.ts |   61.64 |    71.87 |   66.66 |   61.64 | ...54-68,73,77-89 
  settings.ts      |   85.76 |    87.25 |   89.18 |   85.76 | ...1148,1153-1156 
  ...ingsSchema.ts |     100 |      100 |     100 |     100 |                   
  ...tedFolders.ts |   96.22 |       94 |     100 |   96.22 | ...88-190,205-206 
 ...nfig/migration |   94.89 |    78.94 |   83.33 |   94.89 |                   
  index.ts         |   94.87 |    88.88 |     100 |   94.87 | 91-92             
  scheduler.ts     |   96.55 |    77.77 |     100 |   96.55 | 19-20             
  types.ts         |       0 |        0 |       0 |       0 | 1                 
 ...ation/versions |   94.74 |       96 |     100 |   94.74 |                   
  ...-v2-shared.ts |     100 |      100 |     100 |     100 |                   
  v1-to-v2.ts      |   81.75 |    90.19 |     100 |   81.75 | ...28-229,231-247 
  v2-to-v3.ts      |     100 |      100 |     100 |     100 |                   
  v3-to-v4.ts      |     100 |      100 |     100 |     100 |                   
 src/core          |     100 |      100 |     100 |     100 |                   
  auth.ts          |     100 |      100 |     100 |     100 |                   
  initializer.ts   |     100 |      100 |     100 |     100 |                   
  theme.ts         |     100 |      100 |     100 |     100 |                   
 src/dualOutput    |   63.09 |    64.51 |   55.55 |   63.09 |                   
  ...tputBridge.ts |   62.94 |    65.51 |   56.25 |   62.94 | ...22-323,331-334 
  ...utContext.tsx |     100 |      100 |     100 |     100 |                   
  index.ts         |       0 |        0 |       0 |       0 | 1-8               
 src/export        |       0 |        0 |       0 |       0 |                   
  index.ts         |       0 |        0 |       0 |       0 | 1-7               
 src/generated     |     100 |      100 |     100 |     100 |                   
  git-commit.ts    |     100 |      100 |     100 |     100 |                   
 src/i18n          |   81.47 |    75.94 |   65.71 |   81.47 |                   
  index.ts         |   63.68 |    69.56 |   53.84 |   63.68 | ...70-271,281-286 
  languages.ts     |   96.92 |    86.66 |     100 |   96.92 | 134-135,167,184   
  ...nslateKeys.ts |     100 |      100 |     100 |     100 |                   
  ...lationDict.ts |   93.33 |    66.66 |     100 |   93.33 | 15                
 src/i18n/locales  |     100 |      100 |     100 |     100 |                   
  ca.js            |     100 |      100 |     100 |     100 |                   
  de.js            |     100 |      100 |     100 |     100 |                   
  en.js            |     100 |      100 |     100 |     100 |                   
  fr.js            |     100 |      100 |     100 |     100 |                   
  ja.js            |     100 |      100 |     100 |     100 |                   
  pt.js            |     100 |      100 |     100 |     100 |                   
  ru.js            |     100 |      100 |     100 |     100 |                   
  zh-TW.js         |     100 |      100 |     100 |     100 |                   
  zh.js            |     100 |      100 |     100 |     100 |                   
 ...nonInteractive |   72.57 |    71.12 |   74.07 |   72.57 |                   
  session.ts       |   76.64 |     69.4 |   85.71 |   76.64 | ...23-824,833-843 
  types.ts         |    42.5 |      100 |   33.33 |    42.5 | ...80-581,584-585 
 ...active/control |   77.04 |    88.23 |      80 |   77.04 |                   
  ...rolContext.ts |    7.14 |        0 |       0 |    7.14 | 49-84             
  ...Dispatcher.ts |   91.66 |    91.83 |   88.88 |   91.66 | ...54-372,388,391 
  ...rolService.ts |       8 |        0 |       0 |       8 | 46-179            
 ...ol/controllers |    7.04 |       80 |   13.33 |    7.04 |                   
  ...Controller.ts |   19.32 |      100 |      60 |   19.32 | 81-118,127-210    
  ...Controller.ts |       0 |        0 |       0 |       0 | 1-56              
  ...Controller.ts |    3.96 |      100 |   11.11 |    3.96 | ...61-379,389-494 
  ...Controller.ts |   14.06 |      100 |       0 |   14.06 | ...82-117,130-133 
  ...Controller.ts |    5.21 |      100 |       0 |    5.21 | ...21-433,442-471 
 .../control/types |       0 |        0 |       0 |       0 |                   
  serviceAPIs.ts   |       0 |        0 |       0 |       0 | 1                 
 ...Interactive/io |   97.98 |    93.72 |   95.18 |   97.98 |                   
  ...putAdapter.ts |   97.89 |    92.82 |   98.07 |   97.89 | ...1303,1398-1399 
  ...putAdapter.ts |      96 |    91.66 |   85.71 |      96 | 51-52             
  ...nputReader.ts |     100 |    94.73 |     100 |     100 | 67                
  ...putAdapter.ts |   98.28 |      100 |      90 |   98.28 | 81-82,122-123     
  index.ts         |     100 |      100 |     100 |     100 |                   
 src/patches       |       0 |        0 |       0 |       0 |                   
  is-in-ci.ts      |       0 |        0 |       0 |       0 | 1-17              
 src/remoteInput   |   86.98 |       75 |   85.71 |   86.98 |                   
  ...utContext.tsx |     100 |      100 |     100 |     100 |                   
  ...putWatcher.ts |   88.12 |    76.08 |   91.66 |   88.12 | ...21-222,233-236 
  index.ts         |       0 |        0 |       0 |       0 | 1-8               
 src/serve         |    84.8 |    82.66 |   93.46 |    84.8 |                   
  auth.ts          |   88.49 |    88.37 |    87.5 |   88.49 | ...49-150,153-155 
  capabilities.ts  |     100 |     90.9 |     100 |     100 | 151               
  eventBus.ts      |   88.88 |    87.87 |   85.71 |   88.88 | ...38-446,524-526 
  httpAcpBridge.ts |   82.84 |    79.71 |   97.56 |   82.84 | ...3895,3926-3967 
  ...oryChannel.ts |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  loopbackBinds.ts |     100 |      100 |     100 |     100 |                   
  runQwenServe.ts  |   79.74 |    87.09 |   83.33 |   79.74 | ...51-467,492-494 
  server.ts        |   85.85 |       84 |    87.5 |   85.85 | ...1502,1567-1576 
  status.ts        |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/services      |   91.67 |    91.21 |   97.56 |   91.67 |                   
  ...mandLoader.ts |     100 |    93.75 |     100 |     100 | 93                
  ...killLoader.ts |     100 |    96.15 |     100 |     100 | 47                
  ...andService.ts |    98.7 |      100 |     100 |    98.7 | 107               
  ...mandLoader.ts |   86.83 |    83.87 |     100 |   86.83 | ...30-335,340-345 
  ...omptLoader.ts |   75.84 |    80.64 |   83.33 |   75.84 | ...10-211,277-278 
  ...mandLoader.ts |     100 |      100 |     100 |     100 |                   
  ...nd-factory.ts |   91.42 |    91.66 |     100 |   91.42 | 128,137-144       
  ...ation-tool.ts |     100 |    95.45 |     100 |     100 | 125               
  ...ndMetadata.ts |   98.21 |    96.66 |     100 |   98.21 | 83,87             
  commandUtils.ts  |      96 |     90.9 |     100 |      96 | 48                
  ...and-parser.ts |   90.69 |    85.71 |     100 |   90.69 | 63-66             
  ...ionService.ts |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...ght/generators |    85.9 |    85.61 |   90.47 |    85.9 |                   
  DataProcessor.ts |   85.63 |     85.6 |   92.85 |   85.63 | ...1122,1126-1133 
  ...tGenerator.ts |   98.21 |    85.71 |     100 |   98.21 | 46                
  ...teRenderer.ts |   45.45 |      100 |       0 |   45.45 | 13-51             
 .../insight/types |       0 |       50 |      50 |       0 |                   
  ...sightTypes.ts |       0 |        0 |       0 |       0 |                   
  ...sightTypes.ts |       0 |        0 |       0 |       0 | 1                 
 ...mpt-processors |   97.27 |    94.04 |     100 |   97.27 |                   
  ...tProcessor.ts |     100 |      100 |     100 |     100 |                   
  ...eProcessor.ts |   94.52 |    84.21 |     100 |   94.52 | 46-47,93-94       
  ...tionParser.ts |     100 |      100 |     100 |     100 |                   
  ...lProcessor.ts |   97.41 |    95.65 |     100 |   97.41 | 95-98             
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/services/tips |   97.35 |    83.07 |     100 |   97.35 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  tipHistory.ts    |   92.45 |       70 |     100 |   92.45 | ...22,144,151,160 
  tipRegistry.ts   |     100 |    95.23 |     100 |     100 | 33                
  tipScheduler.ts  |     100 |    91.66 |     100 |     100 | 55                
 src/test-utils    |   93.75 |    83.33 |      80 |   93.75 |                   
  ...omMatchers.ts |   69.69 |       50 |      50 |   69.69 | 32-35,37-39,45-47 
  ...andContext.ts |     100 |      100 |     100 |     100 |                   
  render.tsx       |     100 |      100 |     100 |     100 |                   
 src/ui            |   66.39 |    73.22 |   57.14 |   66.39 |                   
  App.tsx          |     100 |      100 |     100 |     100 |                   
  AppContainer.tsx |   65.03 |    64.98 |   52.94 |   65.03 | ...2951,2955-2959 
  ...tionNudge.tsx |    9.58 |      100 |       0 |    9.58 | 24-94             
  ...ackDialog.tsx |   29.23 |      100 |       0 |   29.23 | 25-75             
  ...tionNudge.tsx |    7.69 |      100 |       0 |    7.69 | 25-103            
  colors.ts        |   52.72 |      100 |   23.52 |   52.72 | ...52,54-55,60-61 
  constants.ts     |     100 |      100 |     100 |     100 |                   
  keyMatchers.ts   |   95.91 |    97.05 |     100 |   95.91 | 25-26             
  ...tic-colors.ts |     100 |      100 |     100 |     100 |                   
  ...inePresets.ts |   98.17 |    88.88 |     100 |   98.17 | ...12,239,387-389 
  textConstants.ts |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/ui/auth       |   55.06 |    51.13 |   35.48 |   55.06 |                   
  AuthDialog.tsx   |   64.26 |    44.44 |   16.66 |   64.26 | ...59,366-388,392 
  ...nProgress.tsx |       0 |        0 |       0 |       0 | 1-64              
  ...etupSteps.tsx |    39.5 |       32 |   38.46 |    39.5 | ...69,472,478,481 
  useAuth.ts       |   76.63 |    68.29 |     100 |   76.63 | ...48,493-499,560 
  ...rSetupFlow.ts |   44.61 |    33.33 |      50 |   44.61 | ...57-378,395-438 
 src/ui/commands   |   73.46 |    81.27 |   81.85 |   73.46 |                   
  aboutCommand.ts  |     100 |      100 |     100 |     100 |                   
  agentsCommand.ts |   83.78 |      100 |      60 |   83.78 | 30-32,42-44       
  ...odeCommand.ts |     100 |      100 |     100 |     100 |                   
  arenaCommand.ts  |   62.81 |    58.73 |   65.21 |   62.81 | ...91-596,681-689 
  authCommand.ts   |     100 |      100 |     100 |     100 |                   
  branchCommand.ts |     100 |      100 |     100 |     100 |                   
  btwCommand.ts    |   95.59 |    71.42 |     100 |   95.59 | 72,154-159        
  bugCommand.ts    |   81.13 |    71.42 |     100 |   81.13 | 60-69             
  clearCommand.ts  |      92 |    76.47 |     100 |      92 | 43-44,72-73,91-92 
  ...essCommand.ts |    64.7 |       50 |      75 |    64.7 | ...48-149,163-166 
  ...extCommand.ts |   34.78 |    22.22 |   45.45 |   34.78 | ...86-521,532-533 
  copyCommand.ts   |   98.28 |    94.89 |     100 |   98.28 | ...80,280,321,327 
  deleteCommand.ts |     100 |      100 |     100 |     100 |                   
  diffCommand.ts   |   99.02 |    86.11 |     100 |   99.02 | 222,226           
  ...ryCommand.tsx |   68.09 |    77.77 |   77.77 |   68.09 | ...56-261,315-323 
  docsCommand.ts   |     100 |    88.88 |     100 |     100 | 25                
  doctorCommand.ts |   95.06 |    88.28 |     100 |   95.06 | ...92-293,320-321 
  dreamCommand.ts  |      75 |    66.66 |   66.66 |      75 | 22-27,44-47       
  editorCommand.ts |     100 |      100 |     100 |     100 |                   
  exportCommand.ts |   98.25 |    91.02 |     100 |   98.25 | ...81,198-199,364 
  ...onsCommand.ts |   48.66 |     90.9 |   63.63 |   48.66 | ...05-109,159-211 
  forgetCommand.ts |   26.82 |      100 |      50 |   26.82 | 18-51             
  goalCommand.ts   |    93.1 |    84.61 |     100 |    93.1 | ...67-170,182-185 
  helpCommand.ts   |     100 |      100 |     100 |     100 |                   
  hooksCommand.ts  |    20.4 |       40 |      40 |    20.4 | ...48-180,204-205 
  ideCommand.ts    |   60.75 |    64.28 |   41.17 |   60.75 | ...05-306,310-324 
  initCommand.ts   |   84.33 |    72.72 |     100 |   84.33 | 68,82-87,89-94    
  ...ghtCommand.ts |   74.56 |    68.42 |     100 |   74.56 | ...31-245,250-273 
  ...ageCommand.ts |   92.17 |    82.69 |     100 |   92.17 | ...43,164,173-183 
  lspCommand.ts    |     100 |    86.95 |     100 |     100 | 31,101-102        
  ...elsCommand.ts |     100 |      100 |     100 |     100 |                   
  mcpCommand.ts    |     100 |      100 |     100 |     100 |                   
  memoryCommand.ts |     100 |      100 |     100 |     100 |                   
  modelCommand.ts  |   75.09 |    78.18 |      75 |   75.09 | ...20-225,262-267 
  ...onsCommand.ts |     100 |      100 |     100 |     100 |                   
  planCommand.ts   |   78.82 |    76.92 |     100 |   78.82 | 30-35,51-56,68-73 
  quitCommand.ts   |     100 |      100 |     100 |     100 |                   
  recapCommand.ts  |   21.81 |      100 |      50 |   21.81 | 24-73             
  ...berCommand.ts |   32.43 |      100 |      50 |   32.43 | 23-57             
  renameCommand.ts |   85.71 |    86.04 |     100 |   85.71 | ...02-209,216-221 
  ...oreCommand.ts |    92.3 |    87.87 |     100 |    92.3 | ...,83-88,129-130 
  resumeCommand.ts |     100 |      100 |     100 |     100 |                   
  rewindCommand.ts |      80 |      100 |      50 |      80 | 19-21             
  ...ngsCommand.ts |     100 |      100 |     100 |     100 |                   
  ...hubCommand.ts |   81.43 |    65.21 |      80 |   81.43 | ...70-173,176-179 
  skillsCommand.ts |   15.04 |      100 |      25 |   15.04 | ...90-106,109-136 
  statsCommand.ts  |   88.19 |    84.21 |     100 |   88.19 | ...,58-61,143-146 
  ...ineCommand.ts |     100 |      100 |     100 |     100 |                   
  ...aryCommand.ts |    6.46 |      100 |      50 |    6.46 | 31-329            
  tasksCommand.ts  |   77.22 |    72.13 |     100 |   77.22 | ...46-150,172-177 
  ...tupCommand.ts |     100 |      100 |     100 |     100 |                   
  themeCommand.ts  |     100 |      100 |     100 |     100 |                   
  toolsCommand.ts  |     100 |      100 |     100 |     100 |                   
  trustCommand.ts  |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
  vimCommand.ts    |   54.54 |      100 |      50 |   54.54 | 19-29             
 src/ui/components |   65.53 |    75.02 |   70.76 |   65.53 |                   
  AboutBox.tsx     |     100 |      100 |     100 |     100 |                   
  AnsiOutput.tsx   |   65.57 |      100 |      50 |   65.57 | 69-90             
  ApiKeyInput.tsx  |       0 |        0 |       0 |       0 | 1-97              
  AppHeader.tsx    |   89.39 |       75 |     100 |   89.39 | 35,37-42,44       
  ...odeDialog.tsx |     9.7 |      100 |       0 |     9.7 | 35-47,50-182      
  AsciiArt.ts      |     100 |      100 |     100 |     100 |                   
  ...Indicator.tsx |   14.63 |      100 |       0 |   14.63 | 18-56             
  ...TextInput.tsx |   77.01 |       76 |     100 |   77.01 | ...20,234-236,263 
  Composer.tsx     |    80.8 |     64.7 |     100 |    80.8 | ...85,103,154,167 
  ...entPrompt.tsx |     100 |      100 |     100 |     100 |                   
  ...ryDisplay.tsx |   75.89 |    62.06 |     100 |   75.89 | ...,88,93-108,113 
  ...geDisplay.tsx |   68.42 |    57.14 |     100 |   68.42 | 16-17,31-32,42-50 
  ...ification.tsx |   28.57 |      100 |       0 |   28.57 | 16-36             
  ...gProfiler.tsx |       0 |        0 |       0 |       0 | 1-36              
  ...ogManager.tsx |    12.2 |      100 |       0 |    12.2 | 64-490            
  ...ngsDialog.tsx |    8.44 |      100 |       0 |    8.44 | 37-195            
  ExitWarning.tsx  |     100 |      100 |     100 |     100 |                   
  ...hProgress.tsx |    87.8 |    33.33 |     100 |    87.8 | 28-31,56          
  ...ustDialog.tsx |     100 |      100 |     100 |     100 |                   
  Footer.tsx       |   79.54 |    54.54 |     100 |   79.54 | ...05-109,133-134 
  ...ngSpinner.tsx |   68.42 |       80 |      50 |   68.42 | 35-52,73,80-81    
  GoalPill.tsx     |   76.19 |    81.81 |     100 |   76.19 | 24-30,46-50       
  Header.tsx       |   98.62 |    94.28 |     100 |   98.62 | 162,164           
  Help.tsx         |   98.32 |    89.88 |     100 |   98.32 | ...24,381,447-448 
  ...emDisplay.tsx |    61.7 |       36 |     100 |    61.7 | ...42,345,348-354 
  ...ngeDialog.tsx |     100 |      100 |     100 |     100 |                   
  InputPrompt.tsx  |   82.75 |    78.96 |   83.33 |   82.75 | ...1425,1490,1540 
  ...Shortcuts.tsx |   20.87 |      100 |       0 |   20.87 | ...6,49-51,67-125 
  ...Indicator.tsx |     100 |    91.42 |     100 |     100 | 65,74             
  ...firmation.tsx |   91.42 |      100 |      50 |   91.42 | 26-31             
  MainContent.tsx  |   81.75 |       75 |     100 |   81.75 | ...70-274,282-286 
  ...elsDialog.tsx |   71.05 |    69.11 |   72.72 |   71.05 | ...77,590,601-603 
  MemoryDialog.tsx |    55.1 |    54.54 |   57.14 |    55.1 | ...56,368,381-383 
  ...geDisplay.tsx |       0 |        0 |       0 |       0 | 1-41              
  ModelDialog.tsx  |   80.12 |    63.55 |     100 |   80.12 | ...39-555,612-616 
  ...tsDisplay.tsx |     100 |    97.22 |     100 |     100 | 270               
  ...fications.tsx |   18.18 |      100 |       0 |   18.18 | 15-58             
  ...onsDialog.tsx |    2.13 |      100 |       0 |    2.13 | 62-133,148-1004   
  ...ryDisplay.tsx |     100 |      100 |     100 |     100 |                   
  ...icePrompt.tsx |   92.64 |    85.71 |     100 |   92.64 | 102-106,134-139   
  PrepareLabel.tsx |   91.66 |    77.27 |     100 |   91.66 | 73-75,77-79,110   
  ...atePrompt.tsx |    8.57 |      100 |       0 |    8.57 | 24-55,58-134      
  ...geDisplay.tsx |     100 |      100 |     100 |     100 |                   
  ...ngDisplay.tsx |   21.42 |      100 |       0 |   21.42 | 13-39             
  ...hProgress.tsx |   85.25 |    88.46 |     100 |   85.25 | 121-147           
  ...dSelector.tsx |   41.26 |    61.53 |   71.42 |   41.26 | ...74-472,476-520 
  ...ionPicker.tsx |   78.43 |    66.66 |     100 |   78.43 | ...20-422,444-466 
  ...onPreview.tsx |   92.42 |    84.37 |     100 |   92.42 | ...,70-71,143-145 
  ...ryDisplay.tsx |     100 |      100 |     100 |     100 |                   
  ...putPrompt.tsx |   72.56 |       80 |      40 |   72.56 | ...06-109,114-117 
  ...ngsDialog.tsx |   66.92 |    73.21 |     100 |   66.92 | ...12-820,826-827 
  ...ionDialog.tsx |    87.8 |      100 |   33.33 |    87.8 | 36-39,44-51       
  ...putPrompt.tsx |    15.9 |      100 |       0 |    15.9 | 20-63             
  ...Indicator.tsx |   57.14 |      100 |       0 |   57.14 | 12-15             
  ...MoreLines.tsx |      28 |      100 |       0 |      28 | 18-40             
  ...ionPicker.tsx |   17.59 |      100 |       0 |   17.59 | 55-172            
  StatsDisplay.tsx |     100 |      100 |     100 |     100 |                   
  ...ineDialog.tsx |   93.69 |    83.92 |     100 |   93.69 | ...11,273,293-295 
  ...yTodoList.tsx |   94.17 |       80 |     100 |   94.17 | 56-57,131-134     
  ...nsDisplay.tsx |   87.25 |       64 |     100 |   87.25 | ...45-147,154-156 
  ThemeDialog.tsx  |   89.95 |    46.15 |      75 |   89.95 | ...71-173,243-245 
  Tips.tsx         |   93.54 |       75 |     100 |   93.54 | 39-40             
  TodoDisplay.tsx  |     100 |      100 |     100 |     100 |                   
  ...tsDisplay.tsx |     100 |     87.5 |     100 |     100 | 31-32             
  TrustDialog.tsx  |     100 |    81.81 |     100 |     100 | 71-86             
  ...ification.tsx |   36.36 |      100 |       0 |   36.36 | 15-22             
  ...ackDialog.tsx |    7.84 |      100 |       0 |    7.84 | 24-134            
 ...nts/agent-view |   38.33 |    70.83 |   36.36 |   38.33 |                   
  ...atContent.tsx |    8.79 |      100 |       0 |    8.79 | 53-265,271-273    
  ...tChatView.tsx |   21.05 |      100 |       0 |   21.05 | 21-39             
  ...tComposer.tsx |    9.95 |      100 |       0 |    9.95 | 57-308            
  AgentFooter.tsx  |   17.07 |      100 |       0 |   17.07 | 28-66             
  AgentHeader.tsx  |   15.38 |      100 |       0 |   15.38 | 27-64             
  AgentTabBar.tsx  |    87.8 |    27.27 |     100 |    87.8 | ...,85,98-106,124 
  ...oryAdapter.ts |     100 |    91.83 |     100 |     100 | 103,109-110,138   
  index.ts         |       0 |        0 |       0 |       0 | 1-12              
 ...mponents/arena |   45.72 |    70.53 |   60.86 |   45.72 |                   
  ArenaCards.tsx   |   73.06 |    71.79 |   85.71 |   73.06 | ...83-185,321-326 
  ...ectDialog.tsx |   83.48 |    69.86 |   88.88 |   83.48 | ...88-392,409-410 
  ...artDialog.tsx |   10.15 |      100 |       0 |   10.15 | 27-161            
  ...tusDialog.tsx |    5.63 |      100 |       0 |    5.63 | 33-75,80-288      
  ...topDialog.tsx |    6.17 |      100 |       0 |    6.17 | 33-213            
 ...ackground-view |   75.63 |    84.49 |   85.29 |   75.63 |                   
  ...sksDialog.tsx |   70.92 |    80.48 |   76.19 |   70.92 | ...1118,1194-1196 
  ...TasksPill.tsx |   63.75 |    86.95 |     100 |   63.75 | 44,86-106,114-122 
  ...gentPanel.tsx |   99.53 |    93.18 |     100 |   99.53 | 123               
 ...nts/extensions |   45.28 |    33.33 |      60 |   45.28 |                   
  ...gerDialog.tsx |   44.31 |    34.14 |      75 |   44.31 | ...71-480,483-488 
  index.ts         |       0 |        0 |       0 |       0 | 1-9               
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...tensions/steps |   54.88 |    94.23 |   66.66 |   54.88 |                   
  ...ctionStep.tsx |   95.12 |    92.85 |   85.71 |   95.12 | 84-86,89          
  ...etailStep.tsx |    6.18 |      100 |       0 |    6.18 | 17-128            
  ...nListStep.tsx |   88.43 |    94.73 |      80 |   88.43 | 52-53,59-72,106   
  ...electStep.tsx |   13.46 |      100 |       0 |   13.46 | 20-70             
  ...nfirmStep.tsx |   19.56 |      100 |       0 |   19.56 | 23-65             
  index.ts         |     100 |      100 |     100 |     100 |                   
 ...mponents/hooks |   68.67 |    69.07 |   69.56 |   68.67 |                   
  ...etailStep.tsx |   74.68 |    66.66 |   66.66 |   74.68 | ...71-184,188-201 
  ...etailStep.tsx |    87.4 |    73.68 |     100 |    87.4 | 41-42,99-113,119  
  ...abledStep.tsx |     100 |      100 |     100 |     100 |                   
  ...sListStep.tsx |     100 |      100 |     100 |     100 |                   
  ...entDialog.tsx |   34.51 |    47.05 |   42.85 |   34.51 | ...78,482-495,499 
  constants.ts     |     100 |      100 |     100 |     100 |                   
  index.ts         |       0 |        0 |       0 |       0 | 1-13              
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...components/mcp |   20.98 |    86.36 |   83.33 |   20.98 |                   
  ...ealthPill.tsx |   68.42 |    85.71 |     100 |   68.42 | 40-46             
  ...entDialog.tsx |    3.64 |      100 |       0 |    3.64 | 41-717            
  constants.ts     |     100 |      100 |     100 |     100 |                   
  index.ts         |       0 |        0 |       0 |       0 | 1-30              
  types.ts         |     100 |      100 |     100 |     100 |                   
  utils.ts         |   95.83 |    88.88 |     100 |   95.83 | 16,20,109-110     
 ...ents/mcp/steps |   26.74 |    54.54 |   42.85 |   26.74 |                   
  ...icateStep.tsx |    5.88 |      100 |       0 |    5.88 | 40-55,58-296      
  ...electStep.tsx |   10.95 |      100 |       0 |   10.95 | 16-88             
  ...etailStep.tsx |    5.26 |      100 |       0 |    5.26 | 31-247            
  ...rListStep.tsx |   75.18 |    59.37 |     100 |   75.18 | ...53-158,169-173 
  ...etailStep.tsx |   10.41 |      100 |       0 |   10.41 | ...1,67-79,82-139 
  ToolListStep.tsx |   69.02 |       50 |     100 |   69.02 | ...22,125,134-143 
 ...nents/messages |   81.81 |     79.2 |   72.22 |   81.81 |                   
  ...ionDialog.tsx |   80.84 |     77.6 |    62.5 |   80.84 | ...98,516,534-536 
  BtwMessage.tsx   |     100 |      100 |     100 |     100 |                   
  ...upDisplay.tsx |   97.67 |    83.72 |     100 |   97.67 | 119,142,150       
  ...onMessage.tsx |   91.93 |    82.35 |     100 |   91.93 | 57-59,61,63       
  ...nMessages.tsx |   79.06 |      100 |      70 |   79.06 | ...51-264,268-280 
  DiffRenderer.tsx |   93.19 |    86.17 |     100 |   93.19 | ...09,237-238,304 
  ...tsDisplay.tsx |   97.82 |    77.27 |     100 |   97.82 | 87,89             
  ...usMessage.tsx |   58.41 |     7.69 |      50 |   58.41 | ...12-113,140-143 
  ...ssMessage.tsx |    12.5 |      100 |       0 |    12.5 | 18-59             
  ...edMessage.tsx |   16.66 |      100 |       0 |   16.66 | 22-38             
  ...sMessages.tsx |   55.67 |       40 |   28.57 |   55.67 | ...20-125,133-145 
  ...ryMessage.tsx |   14.28 |      100 |       0 |   14.28 | 23-62             
  ...onMessage.tsx |   81.02 |    69.23 |   33.33 |   81.02 | ...24-426,433-435 
  ...upMessage.tsx |      84 |    93.61 |     100 |      84 | ...56-383,405-420 
  ToolMessage.tsx  |   88.84 |    75.71 |    92.3 |   88.84 | ...44-749,776-778 
 ...ponents/shared |   85.36 |    78.48 |   95.77 |   85.36 |                   
  ...ctionList.tsx |   99.03 |    95.65 |     100 |   99.03 | 85                
  ...tonSelect.tsx |     100 |      100 |     100 |     100 |                   
  EnumSelector.tsx |     100 |    96.42 |     100 |     100 | 58                
  MaxSizedBox.tsx  |   83.01 |    86.25 |   88.88 |   83.01 | ...12-513,618-619 
  MultiSelect.tsx  |   84.31 |    74.19 |     100 |   84.31 | ...37,193-195,205 
  ...tonSelect.tsx |     100 |      100 |     100 |     100 |                   
  ...eSelector.tsx |     100 |       60 |     100 |     100 | 40-45             
  TextInput.tsx    |   77.01 |    48.78 |      80 |   77.01 | ...08-212,224-230 
  ...apsedTime.tsx |     100 |      100 |     100 |     100 |                   
  ...Indicator.tsx |     100 |      100 |     100 |     100 |                   
  text-buffer.ts   |   83.68 |    78.55 |   97.61 |   83.68 | ...2270-2272,2368 
  ...er-actions.ts |   86.71 |    67.79 |     100 |   86.71 | ...07-608,809-811 
 ...ents/subagents |   30.87 |        0 |       0 |   30.87 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  index.ts         |       0 |        0 |       0 |       0 | 1-11              
  reducers.tsx     |    12.1 |      100 |       0 |    12.1 | 33-190            
  types.ts         |     100 |      100 |     100 |     100 |                   
  utils.ts         |   10.95 |      100 |       0 |   10.95 | ...1,56-57,60-102 
 ...bagents/create |    9.13 |      100 |       0 |    9.13 |                   
  ...ionWizard.tsx |    7.28 |      100 |       0 |    7.28 | 34-299            
  ...rSelector.tsx |   14.75 |      100 |       0 |   14.75 | 26-85             
  ...onSummary.tsx |    4.26 |      100 |       0 |    4.26 | 27-331            
  ...tionInput.tsx |    8.63 |      100 |       0 |    8.63 | 23-177            
  ...dSelector.tsx |   33.33 |      100 |       0 |   33.33 | 20-21,26-27,36-63 
  ...nSelector.tsx |    37.5 |      100 |       0 |    37.5 | 20-21,26-27,36-58 
  ...EntryStep.tsx |   12.76 |      100 |       0 |   12.76 | 34-78             
  ToolSelector.tsx |    4.16 |      100 |       0 |    4.16 | 31-253            
 ...bagents/manage |   21.51 |    59.52 |   27.27 |   21.51 |                   
  ...ctionStep.tsx |   10.25 |      100 |       0 |   10.25 | 21-103            
  ...eleteStep.tsx |   20.93 |      100 |       0 |   20.93 | 23-62             
  ...tEditStep.tsx |   25.53 |      100 |       0 |   25.53 | ...2,37-38,51-124 
  ...ctionStep.tsx |   35.42 |    59.52 |     100 |   35.42 | ...20-432,437-439 
  ...iewerStep.tsx |   13.72 |      100 |       0 |   13.72 | 18-73             
  ...gerDialog.tsx |    6.74 |      100 |       0 |    6.74 | 35-341            
 ...mponents/views |   42.16 |    69.23 |   21.42 |   42.16 |                   
  ContextUsage.tsx |     4.7 |      100 |       0 |     4.7 | ...52-167,170-456 
  DoctorReport.tsx |     9.8 |      100 |       0 |     9.8 | 25-54,57-131      
  ...sionsList.tsx |   87.69 |    73.68 |     100 |   87.69 | 65-72             
  McpStatus.tsx    |   89.53 |    60.52 |     100 |   89.53 | ...72,175-177,262 
  SkillsList.tsx   |   27.27 |      100 |       0 |   27.27 | 18-35             
  ToolsList.tsx    |     100 |      100 |     100 |     100 |                   
 src/ui/contexts   |   77.11 |    77.66 |   80.35 |   77.11 |                   
  ...ewContext.tsx |    64.7 |    85.71 |      50 |    64.7 | ...22-225,231-241 
  AppContext.tsx   |      80 |       50 |     100 |      80 | 19-20             
  ...ewContext.tsx |   95.18 |    67.56 |      50 |   95.18 | ...94-195,222-226 
  ...deContext.tsx |     100 |      100 |     100 |     100 |                   
  ...igContext.tsx |   81.81 |       50 |     100 |   81.81 | 15-16             
  ...ssContext.tsx |   81.88 |    82.26 |     100 |   81.88 | ...1153,1159-1161 
  ...owContext.tsx |   89.28 |       80 |   66.66 |   89.28 | 34,47-48,60-62    
  ...deContext.tsx |     100 |      100 |      50 |     100 |                   
  ...onContext.tsx |   43.28 |     62.5 |    62.5 |   43.28 | ...56-259,263-266 
  ...gsContext.tsx |   83.33 |       50 |     100 |   83.33 | 17-18             
  ...usContext.tsx |     100 |      100 |     100 |     100 |                   
  ...ngContext.tsx |   71.42 |       50 |     100 |   71.42 | 17-20             
  ...utContext.tsx |   85.71 |      100 |   66.66 |   85.71 | 13-14             
  ...nsContext.tsx |   88.23 |       50 |     100 |   88.23 | 113-114           
  ...teContext.tsx |   86.66 |       50 |     100 |   86.66 | 177-178           
  ...deContext.tsx |   76.08 |    72.72 |     100 |   76.08 | 47-48,52-59,77-78 
 src/ui/editors    |   93.33 |    85.71 |   66.66 |   93.33 |                   
  ...ngsManager.ts |   93.33 |    85.71 |   66.66 |   93.33 | 49,63-64          
 src/ui/hooks      |   82.41 |    82.49 |   86.66 |   82.41 |                   
  ...dProcessor.ts |   83.12 |    82.56 |     100 |   83.12 | ...88-389,408-435 
  keyToAnsi.ts     |    3.92 |      100 |       0 |    3.92 | 19-77             
  ...dProcessor.ts |    94.8 |    70.58 |     100 |    94.8 | ...76-277,282-283 
  ...dProcessor.ts |   75.75 |    63.01 |   61.53 |   75.75 | ...84,908,927-931 
  ...amingState.ts |   12.22 |      100 |       0 |   12.22 | 54-157            
  ...agerDialog.ts |   88.23 |      100 |     100 |   88.23 | 20,24             
  ...ationFrame.ts |      32 |       60 |     100 |      32 | 42-44,51-90       
  ...odeCommand.ts |   58.82 |      100 |     100 |   58.82 | 28,33-48          
  ...enaCommand.ts |      85 |      100 |     100 |      85 | 23-24,29          
  ...aInProcess.ts |   19.81 |    66.66 |      25 |   19.81 | 57-175            
  ...Completion.ts |   92.77 |    89.09 |     100 |   92.77 | ...86-187,220-223 
  ...ifications.ts |   92.07 |    96.29 |     100 |   92.07 | 116-124           
  ...tIndicator.ts |     100 |    93.75 |     100 |     100 | 63                
  ...waySummary.ts |   96.22 |    69.69 |     100 |   96.22 | 125-127,169       
  ...ndTaskView.ts |   94.21 |    76.08 |     100 |   94.21 | 122-126,213,219   
  ...ketedPaste.ts |    23.8 |      100 |       0 |    23.8 | 19-37             
  ...nchCommand.ts |   94.36 |    74.35 |     100 |   94.36 | ...60,168-169,209 
  ...ompletion.tsx |   95.95 |    82.75 |     100 |   95.95 | ...22-223,225-226 
  ...dMigration.ts |   90.62 |       75 |     100 |   90.62 | 38-40             
  useCompletion.ts |    92.4 |     87.5 |     100 |    92.4 | 68-69,93-94,98-99 
  ...nitMessage.ts |     100 |      100 |     100 |     100 |                   
  ...extualTips.ts |   76.92 |       50 |     100 |   76.92 | 55,68,71-75,88-96 
  ...eteCommand.ts |   78.53 |    88.57 |     100 |   78.53 | ...96-104,112-113 
  ...ialogClose.ts |   15.38 |      100 |     100 |   15.38 | 83-148            
  ...oublePress.ts |   53.12 |       75 |     100 |   53.12 | 33-35,41-54       
  ...orSettings.ts |     100 |      100 |     100 |     100 |                   
  ...Completion.ts |   99.12 |     97.7 |     100 |   99.12 | 182-183           
  ...ionUpdates.ts |   93.45 |     92.3 |     100 |   93.45 | ...83-287,300-306 
  ...agerDialog.ts |   88.88 |      100 |     100 |   88.88 | 21,25             
  ...backDialog.ts |   54.47 |       50 |   33.33 |   54.47 | ...69-171,193-194 
  useFocus.ts      |     100 |      100 |     100 |     100 |                   
  ...olderTrust.ts |     100 |      100 |     100 |     100 |                   
  ...ggestions.tsx |   89.15 |     62.5 |      50 |   89.15 | ...22-124,149-150 
  ...miniStream.ts |   77.38 |    74.63 |   91.66 |   77.38 | ...2465,2478-2486 
  ...BranchName.ts |    90.9 |     92.3 |     100 |    90.9 | 19-20,55-58       
  ...oryManager.ts |   93.15 |    93.75 |     100 |   93.15 | 44,107-110        
  ...ooksDialog.ts |    87.5 |      100 |     100 |    87.5 | 19,23             
  ...stListener.ts |     100 |      100 |     100 |     100 |                   
  ...nAuthError.ts |   76.19 |       50 |     100 |   76.19 | 39-40,43-45       
  ...putHistory.ts |   92.59 |    85.71 |     100 |   92.59 | 63-64,72,94-96    
  ...storyStore.ts |     100 |    94.11 |     100 |     100 | 69                
  useKeypress.ts   |     100 |      100 |     100 |     100 |                   
  ...rdProtocol.ts |   36.36 |      100 |       0 |   36.36 | 24-31             
  ...unchEditor.ts |    9.67 |      100 |       0 |    9.67 | 11-32,39-90       
  ...gIndicator.ts |     100 |      100 |     100 |     100 |                   
  useLogger.ts     |   21.05 |      100 |       0 |   21.05 | 15-37             
  useMCPHealth.ts  |   63.15 |       75 |      50 |   63.15 | 42-52,64-67       
  ...elsCommand.ts |     100 |      100 |     100 |     100 |                   
  useMcpDialog.ts  |    87.5 |      100 |     100 |    87.5 | 19,23             
  ...moryDialog.ts |    87.5 |      100 |     100 |    87.5 | 19,23             
  ...oryMonitor.ts |     100 |      100 |     100 |     100 |                   
  ...ssageQueue.ts |     100 |      100 |     100 |     100 |                   
  ...delCommand.ts |     100 |       75 |     100 |     100 | 22                
  ...raseCycler.ts |   84.74 |    76.47 |     100 |   84.74 | ...49,52-53,69-71 
  ...derUpdates.ts |   86.38 |    77.19 |     100 |   86.38 | ...22,281-293,341 
  useQwenAuth.ts   |     100 |      100 |     100 |     100 |                   
  ...lScheduler.ts |    84.7 |    93.33 |     100 |    84.7 | ...71-276,372-382 
  ...oryCommand.ts |       0 |        0 |       0 |       0 | 1-7               
  ...umeCommand.ts |   97.08 |    83.33 |     100 |   97.08 | 103-104,133       
  ...ompletion.tsx |   90.59 |    83.33 |     100 |   90.59 | ...01,104,137-140 
  ...ectionList.ts |   96.98 |    95.69 |     100 |   96.98 | ...83-184,238-241 
  ...sionPicker.ts |   92.02 |    89.47 |     100 |   92.02 | ...99-501,503-505 
  ...earchInput.ts |     100 |      100 |     100 |     100 |                   
  ...ngsCommand.ts |   18.75 |      100 |       0 |   18.75 | 10-25             
  ...ellHistory.ts |   91.74 |    79.41 |     100 |   91.74 | ...74,122-123,133 
  ...oryCommand.ts |       0 |        0 |       0 |       0 | 1-73              
  ...Completion.ts |   82.67 |    85.41 |   94.73 |   82.67 | ...68-670,678-714 
  ...tateAndRef.ts |     100 |      100 |     100 |     100 |                   
  useStatusLine.ts |   97.67 |    91.66 |     100 |   97.67 | ...28-332,344-347 
  ...eateDialog.ts |   88.23 |      100 |     100 |   88.23 | 14,18             
  ...tification.ts |     100 |    85.71 |     100 |     100 | 47                
  ...alProgress.ts |   53.06 |       50 |   66.66 |   53.06 | ...53,61-68,79-85 
  ...rminalSize.ts |   76.19 |      100 |      50 |   76.19 | 21-25             
  ...emeCommand.ts |   67.01 |    29.41 |     100 |   67.01 | ...10-111,115-116 
  useTimer.ts      |   88.09 |    85.71 |     100 |   88.09 | 44-45,51-53       
  ...lMigration.ts |       0 |        0 |       0 |       0 |                   
  ...rustModify.ts |     100 |      100 |     100 |     100 |                   
  ...elcomeBack.ts |   87.36 |     90.9 |     100 |   87.36 | ...,94-96,114-115 
  vim.ts           |   83.77 |    80.31 |     100 |   83.77 | ...55,759-767,776 
 src/ui/layouts    |   89.72 |     87.5 |     100 |   89.72 |                   
  ...AppLayout.tsx |   89.88 |     87.5 |     100 |   89.88 | 51-53,93-98       
  ...AppLayout.tsx |   89.47 |     87.5 |     100 |   89.47 | 58-63             
 ...i/manageModels |   93.61 |       48 |     100 |   93.61 |                   
  manageModels.ts  |   93.61 |       48 |     100 |   93.61 | ...63-166,179,209 
 src/ui/models     |   80.24 |    79.16 |   71.42 |   80.24 |                   
  ...ableModels.ts |   80.24 |    79.16 |   71.42 |   80.24 | ...,61-71,123-125 
 ...noninteractive |     100 |      100 |    7.14 |     100 |                   
  ...eractiveUi.ts |     100 |      100 |    7.14 |     100 |                   
 src/ui/state      |   94.91 |    81.81 |     100 |   94.91 |                   
  extensions.ts    |   94.91 |    81.81 |     100 |   94.91 | 68-69,88          
 src/ui/themes     |   98.53 |    70.58 |     100 |   98.53 |                   
  ansi-light.ts    |     100 |      100 |     100 |     100 |                   
  ansi.ts          |     100 |      100 |     100 |     100 |                   
  atom-one-dark.ts |     100 |      100 |     100 |     100 |                   
  ayu-light.ts     |     100 |      100 |     100 |     100 |                   
  ayu.ts           |     100 |      100 |     100 |     100 |                   
  color-utils.ts   |     100 |      100 |     100 |     100 |                   
  default-light.ts |     100 |      100 |     100 |     100 |                   
  default.ts       |     100 |      100 |     100 |     100 |                   
  ...inal-theme.ts |   88.59 |    85.96 |     100 |   88.59 | ...57-261,266-270 
  dracula.ts       |     100 |      100 |     100 |     100 |                   
  github-dark.ts   |     100 |      100 |     100 |     100 |                   
  github-light.ts  |     100 |      100 |     100 |     100 |                   
  googlecode.ts    |     100 |      100 |     100 |     100 |                   
  no-color.ts      |     100 |      100 |     100 |     100 |                   
  qwen-dark.ts     |     100 |      100 |     100 |     100 |                   
  qwen-light.ts    |     100 |      100 |     100 |     100 |                   
  ...tic-tokens.ts |     100 |      100 |     100 |     100 |                   
  ...-of-purple.ts |     100 |      100 |     100 |     100 |                   
  theme-manager.ts |   87.98 |    82.89 |     100 |   87.98 | ...48-357,362-363 
  theme.ts         |     100 |    38.02 |     100 |     100 | ...34-449,457-461 
  xcode.ts         |     100 |      100 |     100 |     100 |                   
 src/ui/utils      |   83.92 |    82.91 |   92.56 |   83.92 |                   
  ...Colorizer.tsx |   79.53 |    83.78 |     100 |   79.53 | ...51-152,249-275 
  ...nRenderer.tsx |   68.83 |    70.14 |      50 |   68.83 | ...52-254,274-293 
  ...wnDisplay.tsx |   86.01 |    87.41 |     100 |   86.01 | ...87,704,729-754 
  ...idDiagram.tsx |   87.79 |    95.34 |     100 |   87.79 | 156-179           
  ...eRenderer.tsx |   92.08 |    80.45 |      95 |   92.08 | ...76-679,723-728 
  ...dWorkUtils.ts |     100 |      100 |     100 |     100 |                   
  ...boardUtils.ts |   59.61 |    58.82 |     100 |   59.61 | ...,86-88,107-149 
  commandUtils.ts  |    95.9 |    88.42 |     100 |    95.9 | ...62,164-165,289 
  computeStats.ts  |     100 |      100 |     100 |     100 |                   
  customBanner.ts  |   90.68 |    91.22 |     100 |   90.68 | ...13,324-327,334 
  displayUtils.ts  |   88.37 |    72.22 |     100 |   88.37 | 23,25,29,31,33    
  formatters.ts    |   95.23 |    98.27 |     100 |   95.23 | 117-120           
  gradientUtils.ts |     100 |      100 |     100 |     100 |                   
  highlight.ts     |     100 |      100 |     100 |     100 |                   
  ...oryMapping.ts |     100 |    94.28 |     100 |     100 | 29,51             
  historyUtils.ts  |   94.11 |       94 |     100 |   94.11 | 94-97             
  isNarrowWidth.ts |     100 |      100 |     100 |     100 |                   
  ...olDetector.ts |    8.23 |      100 |       0 |    8.23 | ...31-132,135-136 
  latexRenderer.ts |   94.95 |     73.8 |     100 |   94.95 | ...76-178,184-187 
  layoutUtils.ts   |     100 |      100 |     100 |     100 |                   
  ...ightLoader.ts |     100 |    89.47 |     100 |     100 | 81,110            
  ...nUtilities.ts |   69.84 |    85.71 |     100 |   69.84 | 75-91,100-101     
  ...ToolGroups.ts |   98.66 |    96.77 |     100 |   98.66 | 48-49             
  ...geRenderer.ts |   86.23 |    69.06 |   95.12 |   86.23 | ...1284,1324-1330 
  ...alRenderer.ts |   86.69 |     71.9 |     100 |   86.69 | ...1476,1513-1519 
  ...lsBySource.ts |     100 |    95.23 |     100 |     100 | 84                
  osc8.ts          |   94.71 |    87.41 |     100 |   94.71 | ...43,428,432-433 
  ...mConstants.ts |     100 |      100 |     100 |     100 |                   
  restoreGoal.ts   |   98.98 |    97.14 |     100 |   98.98 | 94                
  ...storyUtils.ts |   61.89 |    69.87 |      90 |   61.89 | ...76,424,429-451 
  ...ickerUtils.ts |     100 |      100 |     100 |     100 |                   
  ...izedOutput.ts |   94.94 |      100 |   88.88 |   94.94 | 112-117           
  ...wOptimizer.ts |     100 |    96.77 |     100 |     100 | 69                
  terminalSetup.ts |    4.37 |      100 |       0 |    4.37 | 44-393            
  textUtils.ts     |   97.35 |    94.38 |   91.66 |   97.35 | ...50-251,386-387 
  todoSnapshot.ts  |   89.11 |    93.33 |     100 |   89.11 | ...,66-78,180-181 
  updateCheck.ts   |     100 |    80.95 |     100 |     100 | 30-42             
 ...i/utils/export |   56.77 |     40.8 |   79.41 |   56.77 |                   
  collect.ts       |   55.92 |    50.58 |   86.36 |   55.92 | ...25-640,642-647 
  index.ts         |     100 |      100 |     100 |     100 |                   
  normalize.ts     |   57.47 |    20.51 |      80 |   57.47 | ...09-310,324-359 
  types.ts         |       0 |        0 |       0 |       0 | 1                 
  utils.ts         |      40 |      100 |       0 |      40 | 11-13             
 ...ort/formatters |    3.38 |      100 |       0 |    3.38 |                   
  html.ts          |    9.61 |      100 |       0 |    9.61 | ...28,34-76,82-84 
  json.ts          |      50 |      100 |       0 |      50 | 14-15             
  jsonl.ts         |     3.5 |      100 |       0 |     3.5 | 14-76             
  markdown.ts      |    0.94 |      100 |       0 |    0.94 | 13-295            
 src/utils         |   75.88 |    89.54 |   93.38 |   75.88 |                   
  acpModelUtils.ts |     100 |      100 |     100 |     100 |                   
  apiPreconnect.ts |   96.72 |    97.14 |     100 |   96.72 | 165-168           
  checks.ts        |   33.33 |      100 |       0 |   33.33 | 23-28             
  cleanup.ts       |   84.12 |    93.33 |      80 |   84.12 | 75,106-115        
  commands.ts      |     100 |      100 |     100 |     100 |                   
  commentJson.ts   |   87.17 |     90.9 |     100 |   87.17 | 64-73             
  ...Calculator.ts |     100 |      100 |     100 |     100 |                   
  deepMerge.ts     |     100 |       90 |     100 |     100 | 41-43,49          
  ...ScopeUtils.ts |   97.56 |    88.88 |     100 |   97.56 | 67                
  doctorChecks.ts  |   71.06 |       75 |     100 |   71.06 | ...95-301,325-341 
  ...putCapture.ts |   90.65 |    86.17 |     100 |   90.65 | ...72,370,372-373 
  ...arResolver.ts |   94.28 |       88 |     100 |   94.28 | 28-29,125-126     
  errors.ts        |   98.67 |    96.36 |     100 |   98.67 | 67-68             
  events.ts        |     100 |      100 |     100 |     100 |                   
  gitUtils.ts      |   91.91 |    84.61 |     100 |   91.91 | 78-81,124-127     
  ...AutoUpdate.ts |   90.76 |    93.33 |   88.88 |   90.76 | 103-114           
  ...lationInfo.ts |     100 |      100 |     100 |     100 |                   
  languageUtils.ts |   97.89 |    96.42 |     100 |   97.89 | 132-133           
  math.ts          |       0 |        0 |       0 |       0 | 1-15              
  ...iagnostics.ts |   94.57 |    83.01 |   88.88 |   94.57 | ...05,311,315-317 
  ...onfigUtils.ts |     100 |      100 |     100 |     100 |                   
  ...iveHelpers.ts |   96.79 |    93.28 |     100 |   96.79 | ...76-477,575,588 
  osc.ts           |    97.5 |      100 |   88.88 |    97.5 | 195-196           
  package.ts       |   88.88 |       80 |     100 |   88.88 | 33-34             
  processUtils.ts  |     100 |      100 |     100 |     100 |                   
  readStdin.ts     |   79.62 |       90 |      80 |   79.62 | 33-40,52-54       
  relaunch.ts      |   98.07 |    76.92 |     100 |   98.07 | 70                
  resolvePath.ts   |   66.66 |       25 |     100 |   66.66 | 12-13,16,18-19    
  sandbox.ts       |       0 |        0 |       0 |       0 | 1-1047            
  settingsUtils.ts |   82.89 |    90.67 |   89.47 |   82.89 | ...52-663,670-678 
  spawnWrapper.ts  |     100 |      100 |     100 |     100 |                   
  ...upProfiler.ts |   98.46 |    94.52 |     100 |   98.46 | 130-131,305       
  ...upWarnings.ts |     100 |      100 |     100 |     100 |                   
  stdioHelpers.ts  |     100 |       60 |     100 |     100 | 23,32             
  systemInfo.ts    |   90.32 |    89.65 |    87.5 |   90.32 | ...18-219,224-228 
  ...InfoFields.ts |   87.61 |       65 |     100 |   87.61 | ...22-123,144-145 
  ...iffPreview.ts |   94.11 |    83.33 |     100 |   94.11 | 13                
  ...entEmitter.ts |     100 |      100 |     100 |     100 |                   
  ...upWarnings.ts |   91.17 |    82.35 |     100 |   91.17 | 67-68,73-74,77-78 
  version.ts       |     100 |       50 |     100 |     100 | 11                
  windowTitle.ts   |     100 |      100 |     100 |     100 |                   
  ...WithBackup.ts |   63.15 |    81.25 |     100 |   63.15 | 93,118-157        
-------------------|---------|----------|---------|---------|-------------------
Core Package - Full Text Report
-------------------|---------|----------|---------|---------|-------------------
File               | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
-------------------|---------|----------|---------|---------|-------------------
All files          |   79.25 |    82.73 |   81.92 |   79.25 |                   
 src               |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
 src/__mocks__/fs  |       0 |        0 |       0 |       0 |                   
  promises.ts      |       0 |        0 |       0 |       0 | 1-48              
 src/agents        |   87.58 |    79.07 |   91.76 |   87.58 |                   
  ...transcript.ts |   92.25 |    85.71 |     100 |   92.25 | ...87,306-307,438 
  ...ent-resume.ts |    82.5 |     71.5 |   77.41 |    82.5 | ...1035-1039,1042 
  ...ound-tasks.ts |    95.4 |    86.48 |     100 |    95.4 | ...55-756,827-828 
  index.ts         |     100 |      100 |     100 |     100 |                   
 src/agents/arena  |   76.54 |    66.87 |   78.72 |   76.54 |                   
  ...gentClient.ts |   79.47 |    88.88 |   81.81 |   79.47 | ...68-183,189-204 
  ArenaManager.ts  |   75.37 |    63.37 |   78.26 |   75.37 | ...1860,1866-1867 
  arena-events.ts  |   64.44 |      100 |      50 |   64.44 | ...71-175,178-183 
  diff-summary.ts  |    87.5 |    72.34 |     100 |    87.5 | ...32-133,137-138 
  index.ts         |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...gents/backends |   76.29 |    86.15 |   73.04 |   76.29 |                   
  ITermBackend.ts  |   97.97 |    93.93 |     100 |   97.97 | ...78-180,255,307 
  ...essBackend.ts |   91.25 |    90.62 |   86.66 |   91.25 | ...94,249-269,328 
  TmuxBackend.ts   |    90.7 |    76.55 |   97.36 |    90.7 | ...87,697,743-747 
  detect.ts        |   31.25 |      100 |       0 |   31.25 | 34-88             
  index.ts         |     100 |      100 |     100 |     100 |                   
  iterm-it2.ts     |     100 |     92.1 |     100 |     100 | 37-38,106         
  tmux-commands.ts |    6.64 |      100 |    3.03 |    6.64 | ...93-363,386-503 
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...agents/runtime |   81.14 |     76.7 |   71.42 |   81.14 |                   
  agent-context.ts |     100 |      100 |     100 |     100 |                   
  agent-core.ts    |   76.49 |    72.35 |   60.86 |   76.49 | ...1608,1635-1682 
  agent-events.ts  |     100 |      100 |     100 |     100 |                   
  ...t-headless.ts |   81.19 |    71.73 |   60.86 |   81.19 | ...98-399,402-403 
  ...nteractive.ts |   79.71 |    79.62 |      75 |   79.71 | ...54,456,458,461 
  ...statistics.ts |   98.19 |    82.35 |     100 |   98.19 | 127,151,192,225   
  agent-types.ts   |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
 src/agents/tasks  |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/config        |   78.16 |    81.13 |      65 |   78.16 |                   
  config.ts        |   75.91 |    79.78 |   60.09 |   75.91 | ...3605,3616-3628 
  constants.ts     |     100 |      100 |     100 |     100 |                   
  models.ts        |     100 |      100 |     100 |     100 |                   
  storage.ts       |   95.01 |     90.9 |   90.47 |   95.01 | ...71-372,375-376 
 ...nfirmation-bus |   98.29 |    97.14 |     100 |   98.29 |                   
  message-bus.ts   |   98.14 |    97.05 |     100 |   98.14 | 42-43             
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/core          |   86.68 |    82.18 |   89.86 |   86.68 |                   
  baseLlmClient.ts |   92.35 |    80.85 |   86.66 |   92.35 | ...34,342-356,495 
  client.ts        |   85.49 |    77.12 |   84.84 |   85.49 | ...1735,1774-1777 
  ...tGenerator.ts |    72.1 |    61.11 |     100 |    72.1 | ...63,365,372-375 
  ...lScheduler.ts |   82.97 |    81.44 |   93.47 |   82.97 | ...2431,2483-2487 
  geminiChat.ts    |   89.32 |     84.8 |   91.48 |   89.32 | ...1454,1521-1522 
  geminiRequest.ts |     100 |      100 |     100 |     100 |                   
  ...htProtocol.ts |    9.09 |      100 |       0 |    9.09 | 34-42,45-49,52-87 
  logger.ts        |   87.33 |    87.02 |     100 |   87.33 | ...61-565,611-625 
  ...tyDefaults.ts |     100 |      100 |     100 |     100 |                   
  ...olExecutor.ts |   92.59 |       75 |      50 |   92.59 | 41-42             
  ...on-helpers.ts |   85.71 |    70.58 |     100 |   85.71 | ...90-191,205-214 
  ...issionFlow.ts |   98.59 |    94.73 |     100 |   98.59 | 93                
  prompts.ts       |   89.16 |    86.41 |   76.92 |   89.16 | ...-965,1168-1169 
  tokenLimits.ts   |     100 |    89.47 |     100 |     100 | 51-52             
  ...okTriggers.ts |   99.31 |    90.41 |     100 |   99.31 | 124,135           
  turn.ts          |   96.42 |    88.88 |     100 |   96.42 | ...00,413-414,462 
 ...ntentGenerator |   94.92 |    82.59 |   93.87 |   94.92 |                   
  ...tGenerator.ts |   96.48 |    84.28 |   92.59 |   96.48 | ...01,919-923,963 
  converter.ts     |   94.51 |    80.72 |     100 |   94.51 | ...06-607,617,823 
  index.ts         |       0 |        0 |       0 |       0 | 1-21              
  usage.ts         |     100 |      100 |     100 |     100 |                   
 ...ntentGenerator |   91.53 |    71.64 |   93.33 |   91.53 |                   
  ...tGenerator.ts |      90 |    70.96 |   92.85 |      90 | ...80-286,304-305 
  index.ts         |     100 |       80 |     100 |     100 | 50                
 ...ntentGenerator |    92.1 |    80.38 |   90.32 |    92.1 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...tGenerator.ts |   92.08 |    80.38 |   90.32 |   92.08 | ...85,895-896,924 
 ...ntentGenerator |   81.66 |    84.08 |    90.9 |   81.66 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  converter.ts     |   76.88 |    82.25 |    87.5 |   76.88 | ...1589,1610-1616 
  errorHandler.ts  |     100 |      100 |     100 |     100 |                   
  index.ts         |   52.38 |    44.44 |      50 |   52.38 | ...77,81-85,89-93 
  ...tGenerator.ts |    66.4 |    70.58 |   88.88 |    66.4 | ...51-157,168-169 
  pipeline.ts      |   93.67 |     84.9 |     100 |   93.67 | ...80-481,489,554 
  ...ureContext.ts |     100 |      100 |     100 |     100 |                   
  ...ingOptions.ts |       0 |        0 |       0 |       0 | 1                 
  ...CallParser.ts |   90.66 |    88.57 |     100 |   90.66 | ...15-319,349-350 
  ...kingParser.ts |     100 |    96.87 |     100 |     100 | 42                
  types.ts         |       0 |        0 |       0 |       0 | 1                 
 ...rator/provider |   96.69 |    89.17 |   95.45 |   96.69 |                   
  dashscope.ts     |   97.29 |    89.77 |   93.33 |   97.29 | ...81-282,358-359 
  deepseek.ts      |   95.55 |    90.56 |     100 |   95.55 | ...31-132,145-146 
  default.ts       |   94.62 |    86.36 |   85.71 |   94.62 | 86-87,157-159     
  index.ts         |     100 |      100 |     100 |     100 |                   
  minimax.ts       |     100 |      100 |     100 |     100 |                   
  mistral.ts       |   96.07 |    73.33 |     100 |   96.07 | 32-33             
  modelscope.ts    |     100 |      100 |     100 |     100 |                   
  openrouter.ts    |     100 |      100 |     100 |     100 |                   
  types.ts         |       0 |        0 |       0 |       0 |                   
 src/extension     |   60.56 |    79.46 |    78.4 |   60.56 |                   
  ...-converter.ts |   62.35 |    47.82 |      90 |   62.35 | ...90-791,800-832 
  ...ionManager.ts |   47.04 |    82.06 |    65.9 |   47.04 | ...1398,1408-1427 
  ...onSettings.ts |   93.46 |    93.05 |     100 |   93.46 | ...17-221,228-232 
  ...-converter.ts |   54.88 |    94.44 |      60 |   54.88 | ...35-146,158-192 
  github.ts        |   44.94 |    88.52 |      60 |   44.94 | ...53-359,398-451 
  index.ts         |     100 |      100 |     100 |     100 |                   
  marketplace.ts   |   97.29 |    93.75 |     100 |   97.29 | ...64,184-185,274 
  npm.ts           |   48.66 |    76.08 |      75 |   48.66 | ...18-420,427-431 
  override.ts      |   94.11 |    88.88 |     100 |   94.11 | 63-64,81-82       
  settings.ts      |   66.26 |      100 |      50 |   66.26 | 81-108,143-149    
  storage.ts       |     100 |      100 |     100 |     100 |                   
  ...ableSchema.ts |     100 |      100 |     100 |     100 |                   
  variables.ts     |   88.75 |    83.33 |     100 |   88.75 | ...28-231,234-237 
 src/followup      |   46.91 |     92.3 |   71.87 |   46.91 |                   
  followupState.ts |      96 |    89.74 |     100 |      96 | 159-161,218-219   
  index.ts         |     100 |      100 |     100 |     100 |                   
  overlayFs.ts     |   95.06 |       84 |     100 |   95.06 | 78,108,122,133    
  speculation.ts   |   13.22 |      100 |   16.66 |   13.22 | 88-458,518-568    
  ...onToolGate.ts |     100 |    96.29 |     100 |     100 | 93                
  ...nGenerator.ts |    38.4 |    95.12 |   33.33 |    38.4 | ...16-318,353-383 
 src/generated     |       0 |        0 |       0 |       0 |                   
  git-commit.ts    |       0 |        0 |       0 |       0 | 1-10              
 src/goals         |   88.38 |    81.14 |   94.11 |   88.38 |                   
  ...eGoalStore.ts |   81.57 |    92.85 |   81.81 |   81.57 | ...37-140,148-156 
  goalHook.ts      |   96.89 |    90.24 |     100 |   96.89 | 93-98             
  goalJudge.ts     |    83.4 |    73.13 |     100 |    83.4 | ...19-320,328-330 
  index.ts         |     100 |      100 |     100 |     100 |                   
 src/hooks         |   83.48 |    84.87 |   86.83 |   83.48 |                   
  ...okRegistry.ts |   86.48 |    77.08 |     100 |   86.48 | ...41-344,362-369 
  ...bortSignal.ts |     100 |      100 |     100 |     100 |                   
  ...terpolator.ts |   96.66 |    93.33 |     100 |   96.66 | 66-67             
  ...HookRunner.ts |   96.68 |    87.23 |     100 |   96.68 | 110-112,231-233   
  ...Aggregator.ts |    96.4 |    90.78 |     100 |    96.4 | ...91,293-294,367 
  ...entHandler.ts |   94.56 |    83.78 |   93.33 |   94.56 | ...38,795-796,806 
  hookPlanner.ts   |   84.13 |    76.59 |      90 |   84.13 | ...38,144,162-173 
  hookRegistry.ts  |   90.17 |    83.33 |     100 |   90.17 | ...33,352,356,360 
  hookRunner.ts    |   58.56 |    71.26 |   66.66 |   58.56 | ...48-749,758-759 
  hookSystem.ts    |   84.57 |      100 |   65.85 |   84.57 | ...21-622,628-629 
  ...HookRunner.ts |   75.51 |     61.9 |      80 |   75.51 | ...05-406,424-425 
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...HookRunner.ts |   93.63 |    89.47 |      90 |   93.63 | ...45-353,427-428 
  ...SkillHooks.ts |   78.75 |       75 |   66.66 |   78.75 | 62-66,137-152     
  ...oksManager.ts |   96.66 |    91.66 |     100 |   96.66 | ...90,209-210,223 
  ssrfGuard.ts     |   77.22 |    85.36 |     100 |   77.22 | ...57,261-267,273 
  stopHookCap.ts   |     100 |      100 |     100 |     100 |                   
  trustedHooks.ts  |       0 |        0 |       0 |       0 | 1-124             
  types.ts         |   91.18 |    92.04 |   85.71 |   91.18 | ...40-441,501-505 
  urlValidator.ts  |     100 |      100 |     100 |     100 |                   
 src/ide           |   74.28 |    83.39 |   78.33 |   74.28 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  detect-ide.ts    |     100 |      100 |     100 |     100 |                   
  ide-client.ts    |    64.2 |    81.48 |   66.66 |    64.2 | ...9-970,999-1007 
  ide-installer.ts |   89.06 |    79.31 |     100 |   89.06 | ...36,143-147,160 
  ideContext.ts    |     100 |      100 |     100 |     100 |                   
  process-utils.ts |   84.84 |    71.79 |     100 |   84.84 | ...37,151,193-194 
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/lsp           |   41.24 |    52.14 |   51.42 |   41.24 |                   
  ...nfigLoader.ts |   70.27 |    35.89 |   94.73 |   70.27 | ...20-422,426-432 
  ...ionFactory.ts |   42.69 |    79.16 |      50 |   42.69 | ...62-413,419-436 
  ...Normalizer.ts |   23.09 |    13.72 |   30.43 |   23.09 | ...04-905,909-924 
  ...verManager.ts |   25.31 |    62.06 |   41.66 |   25.31 | ...85-704,710-740 
  ...eLspClient.ts |   32.77 |       80 |   17.64 |   32.77 | ...84-288,294-295 
  ...LspService.ts |   48.49 |    67.16 |   65.71 |   48.49 | ...1352,1369-1379 
  constants.ts     |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/mcp           |   78.69 |    75.34 |   75.92 |   78.69 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  ...h-provider.ts |   86.95 |      100 |   33.33 |   86.95 | ...,93,97,101-102 
  ...h-provider.ts |   73.82 |    53.92 |     100 |   73.82 | ...88-895,902-904 
  ...en-storage.ts |   98.62 |    97.72 |     100 |   98.62 | 87-88             
  oauth-utils.ts   |   70.58 |    85.29 |    90.9 |   70.58 | ...70-290,315-344 
  ...n-provider.ts |   89.83 |    95.83 |   45.45 |   89.83 | ...43,147,151-152 
 .../token-storage |   79.52 |    86.66 |   86.36 |   79.52 |                   
  ...en-storage.ts |     100 |      100 |     100 |     100 |                   
  ...en-storage.ts |   82.87 |    82.35 |   92.85 |   82.87 | ...63-173,181-182 
  ...en-storage.ts |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...en-storage.ts |   68.14 |    82.35 |   64.28 |   68.14 | ...81-295,298-314 
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/memory        |   67.43 |       76 |   65.62 |   67.43 |                   
  const.ts         |     100 |      100 |     100 |     100 |                   
  dream.ts         |   65.65 |    73.33 |      50 |   65.65 | 50,107-148        
  ...entPlanner.ts |   57.84 |    72.72 |   33.33 |   57.84 | ...35,140-147,152 
  entries.ts       |   63.77 |    79.16 |      50 |   63.77 | ...72-180,183-189 
  extract.ts       |    95.2 |    79.16 |     100 |    95.2 | 81-86,125         
  ...entPlanner.ts |   63.08 |    65.71 |   41.17 |   63.08 | ...17,222-223,332 
  ...ionPlanner.ts |       0 |        0 |       0 |       0 | 1                 
  forget.ts        |    45.8 |    61.53 |   44.44 |    45.8 | ...04,211,214-346 
  indexer.ts       |   83.87 |    45.45 |     100 |   83.87 | ...50,56-57,69-70 
  manager.ts       |   75.31 |    81.04 |    75.6 |   75.31 | ...1278,1291-1293 
  memoryAge.ts     |   90.47 |    77.77 |     100 |   90.47 | 50-51             
  paths.ts         |   55.47 |    89.47 |   85.71 |   55.47 | ...,89-90,106-114 
  prompt.ts        |   93.36 |    71.42 |     100 |   93.36 | ...58,161,228-229 
  recall.ts        |   79.56 |    69.38 |   88.88 |   79.56 | ...40-245,269-280 
  ...ceSelector.ts |   91.86 |    77.27 |     100 |   91.86 | ...07,109-110,118 
  scan.ts          |   87.91 |    68.42 |     100 |   87.91 | ...47-48,58,82-87 
  ...entPlanner.ts |    11.5 |      100 |       0 |    11.5 | ...57-192,210-298 
  status.ts        |   10.52 |      100 |       0 |   10.52 | 41-98             
  store.ts         |   94.44 |    83.33 |     100 |   94.44 | 56-57,92-93       
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/mocks         |       0 |        0 |       0 |       0 |                   
  msw.ts           |       0 |        0 |       0 |       0 | 1-9               
 src/models        |   89.31 |    85.55 |    87.5 |   89.31 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  ...tor-config.ts |   90.24 |    91.42 |     100 |   90.24 | 142,148,151-160   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...nfigErrors.ts |   74.22 |       44 |   84.61 |   74.22 | ...,67-74,106-117 
  ...igResolver.ts |   98.63 |    92.53 |     100 |   98.63 | 161,323,329       
  modelRegistry.ts |     100 |    98.59 |     100 |     100 | 222               
  modelsConfig.ts  |   84.57 |    82.14 |   81.57 |   84.57 | ...1223,1252-1253 
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/output        |     100 |      100 |     100 |     100 |                   
  ...-formatter.ts |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/permissions   |   71.18 |    88.76 |   48.57 |   71.18 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...on-manager.ts |   81.42 |    86.66 |      80 |   81.42 | ...29-830,837-846 
  rule-parser.ts   |   95.99 |    93.22 |     100 |   95.99 | ...-864,1013-1015 
  ...-semantics.ts |   58.28 |    85.27 |    30.2 |   58.28 | ...1604-1614,1643 
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/prompts       |   83.63 |      100 |    87.5 |   83.63 |                   
  mcp-prompts.ts   |   18.18 |      100 |       0 |   18.18 | 11-19             
  ...t-registry.ts |     100 |      100 |     100 |     100 |                   
 src/qwen          |   86.01 |    79.48 |   97.18 |   86.01 |                   
  ...tGenerator.ts |   98.64 |    98.18 |     100 |   98.64 | 105-106           
  qwenOAuth2.ts    |   84.99 |    74.81 |   93.33 |   84.99 | ...,985-1001,1031 
  ...kenManager.ts |   83.76 |    76.22 |     100 |   83.76 | ...62-767,788-793 
 src/services      |   85.25 |    83.52 |   90.86 |   85.25 |                   
  ...ionTrailer.ts |     100 |      100 |     100 |     100 |                   
  ...llRegistry.ts |   98.44 |    91.83 |     100 |   98.44 | 268-269           
  ...ionService.ts |    95.6 |    96.36 |     100 |    95.6 | ...32,400,402-406 
  ...ingService.ts |   83.91 |       83 |   83.33 |   83.91 | ...1267,1284-1285 
  ...ttribution.ts |   91.73 |    87.71 |      90 |   91.73 | ...80-685,826-827 
  ...utSlimming.ts |     100 |    96.77 |     100 |     100 | 133,182           
  cronScheduler.ts |   97.56 |    92.98 |     100 |   97.56 | 62-63,77,155      
  ...eryService.ts |   80.43 |    95.45 |      75 |   80.43 | ...19-134,140-141 
  ...oryService.ts |   86.25 |    74.35 |    92.3 |   86.25 | ...46-655,696-699 
  fileReadCache.ts |     100 |      100 |     100 |     100 |                   
  ...temService.ts |      90 |    84.44 |   88.88 |      90 | ...89,191,269-276 
  ...ratedFiles.ts |      96 |    88.23 |     100 |      96 | 119-120,146-147   
  gitInit.ts       |     100 |      100 |     100 |     100 |                   
  gitService.ts    |   68.75 |     92.3 |   55.55 |   68.75 | ...12-122,125-129 
  ...reeService.ts |   73.79 |       70 |   94.87 |   73.79 | ...1365,1393-1394 
  ...ionService.ts |   98.13 |     97.8 |   95.45 |   98.13 | ...32-333,380-381 
  ...orRegistry.ts |   96.54 |    91.73 |     100 |   96.54 | ...70-471,622-623 
  sessionRecap.ts  |   12.04 |      100 |       0 |   12.04 | 49-160            
  ...ionService.ts |   90.19 |     78.7 |   96.66 |   90.19 | ...1285,1289-1290 
  sessionTitle.ts  |   93.87 |    69.81 |     100 |   93.87 | ...33-236,267-268 
  ...ionService.ts |   81.07 |    77.92 |   89.28 |   81.07 | ...1923,1929-1934 
  ...UseSummary.ts |   94.73 |    87.71 |     100 |   94.73 | ...73-175,225-226 
  ...reeCleanup.ts |   14.56 |      100 |   33.33 |   14.56 | 58-185            
 ...icrocompaction |   97.69 |    89.79 |     100 |   97.69 |                   
  microcompact.ts  |   97.69 |    89.79 |     100 |   97.69 | ...68,229,233,314 
 src/skills        |    87.5 |    83.86 |   94.23 |    87.5 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...activation.ts |     100 |     93.1 |     100 |     100 | 93,112            
  skill-load.ts    |   92.94 |    81.63 |     100 |   92.94 | ...06,226,238-240 
  skill-manager.ts |   83.31 |    79.66 |   90.32 |   83.31 | ...1120,1127-1131 
  skill-paths.ts   |   86.74 |    77.77 |     100 |   86.74 | ...00-101,106-107 
  symlinkScope.ts  |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/subagents     |   83.13 |    80.24 |   95.23 |   83.13 |                   
  ...tin-agents.ts |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...-selection.ts |     100 |      100 |     100 |     100 |                   
  ...nt-manager.ts |   77.21 |    72.09 |   92.85 |   77.21 | ...1180,1202-1203 
  types.ts         |     100 |      100 |     100 |     100 |                   
  validation.ts    |   92.46 |    95.18 |     100 |   92.46 | 51-56,69-74,78-83 
 src/telemetry     |   74.59 |     85.9 |   78.77 |   74.59 |                   
  config.ts        |     100 |      100 |     100 |     100 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  ...attributes.ts |   98.13 |       88 |     100 |   98.13 | 185-187           
  ...-exporters.ts |   46.37 |      100 |   44.44 |   46.37 | ...85,88-89,92-93 
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...t.circular.ts |       0 |        0 |       0 |       0 | 1-111             
  ...-processor.ts |   93.93 |    90.21 |   94.11 |   93.93 | ...75-280,299-300 
  ...t.circular.ts |       0 |        0 |       0 |       0 | 1-128             
  loggers.ts       |    51.9 |       64 |   57.77 |    51.9 | ...1214,1231-1251 
  metrics.ts       |    74.9 |    82.95 |   74.54 |    74.9 | ...58-978,981-992 
  sanitize.ts      |      80 |    83.33 |     100 |      80 | 35-36,41-42       
  sdk.ts           |   90.45 |    83.56 |   76.92 |   90.45 | ...17-318,338-342 
  ...on-context.ts |     100 |      100 |     100 |     100 |                   
  ...on-tracing.ts |   90.69 |    87.87 |     100 |   90.69 | ...67-471,482-485 
  ...etry-utils.ts |     100 |      100 |     100 |     100 |                   
  ...l-decision.ts |     100 |      100 |     100 |     100 |                   
  ...e-id-utils.ts |     100 |      100 |     100 |     100 |                   
  tracer.ts        |   98.61 |    89.36 |     100 |   98.61 | 53,104            
  types.ts         |   79.17 |    85.83 |   83.33 |   79.17 | ...1149,1152-1181 
  uiTelemetry.ts   |   92.97 |    96.96 |   81.25 |   92.97 | ...93-194,200-207 
 ...ry/qwen-logger |   68.24 |    79.56 |   64.91 |   68.24 |                   
  event-types.ts   |       0 |        0 |       0 |       0 |                   
  qwen-logger.ts   |   68.24 |    79.34 |   64.28 |   68.24 | ...1055,1093-1094 
 src/test-utils    |   93.16 |    95.91 |   76.47 |   93.16 |                   
  config.ts        |     100 |      100 |     100 |     100 |                   
  ...st-helpers.ts |   94.11 |       90 |     100 |   94.11 | 69-70             
  index.ts         |     100 |      100 |     100 |     100 |                   
  mock-tool.ts     |   91.19 |    97.14 |   72.41 |   91.19 | ...38,202-203,216 
  ...aceContext.ts |     100 |      100 |     100 |     100 |                   
 src/tools         |    77.8 |    81.31 |    86.3 |    77.8 |                   
  ...erQuestion.ts |   88.93 |    76.74 |    90.9 |   88.93 | ...39-340,347-348 
  cron-create.ts   |   97.75 |    88.88 |   83.33 |   97.75 | 30-31             
  cron-delete.ts   |   96.82 |      100 |   83.33 |   96.82 | 26-27             
  cron-list.ts     |   96.66 |      100 |   83.33 |   96.66 | 25-26             
  diffOptions.ts   |     100 |      100 |     100 |     100 |                   
  edit.ts          |   80.52 |    85.98 |   73.33 |   80.52 | ...15-716,803-853 
  ...r-worktree.ts |   82.43 |    68.75 |    87.5 |   82.43 | ...67-170,236-237 
  exit-worktree.ts |   83.47 |       84 |    90.9 |   83.47 | ...80-281,286-299 
  exitPlanMode.ts  |   85.09 |    85.71 |     100 |   85.09 | ...60-163,177-189 
  glob.ts          |   90.63 |    88.33 |   84.61 |   90.63 | ...28,171,302,305 
  grep.ts          |   79.19 |    85.71 |   78.94 |   79.19 | ...20,560,569-576 
  ls.ts            |   96.74 |    90.27 |     100 |   96.74 | 176-181,212,216   
  lsp.ts           |   72.77 |    60.09 |   90.32 |   72.77 | ...1211,1213-1214 
  ...nt-manager.ts |   69.73 |    75.29 |   71.42 |   69.73 | ...29-732,749-786 
  mcp-client.ts    |   33.18 |    77.41 |   66.66 |   33.18 | ...1490,1494-1497 
  mcp-tool.ts      |   90.98 |    88.88 |   96.42 |   90.98 | ...95-596,646-647 
  memory-config.ts |       0 |        0 |       0 |       0 | 1-47              
  ...iable-tool.ts |     100 |    84.61 |     100 |     100 | 102,109           
  monitor.ts       |   92.36 |    83.94 |      92 |   92.36 | ...29,558-561,574 
  ...nforcement.ts |   82.44 |       90 |     100 |   82.44 | 174-185,234-247   
  read-file.ts     |   95.07 |     88.6 |      90 |   95.07 | ...99,290-293,296 
  ripGrep.ts       |   94.59 |    85.71 |   93.33 |   94.59 | ...60,463,541-542 
  ...-transport.ts |    6.34 |      100 |       0 |    6.34 | 47-145            
  send-message.ts  |   89.32 |    91.66 |   83.33 |   89.32 | 44-45,68-76       
  shell.ts         |   72.96 |     79.6 |    91.3 |   72.96 | ...4216,4265-4271 
  skill-utils.ts   |     100 |      100 |     100 |     100 |                   
  skill.ts         |   88.11 |    91.17 |   84.61 |   88.11 | ...95,399,422-444 
  ...eticOutput.ts |   95.12 |      100 |      80 |   95.12 | 87-88             
  task-stop.ts     |   93.14 |    96.15 |   85.71 |   93.14 | 39-40,54-64       
  todoWrite.ts     |   89.17 |    82.05 |   92.85 |   89.17 | ...41-546,568-569 
  tool-error.ts    |     100 |      100 |     100 |     100 |                   
  tool-names.ts    |     100 |      100 |     100 |     100 |                   
  tool-registry.ts |   74.79 |       75 |   80.48 |   74.79 | ...92-793,801-802 
  tool-search.ts   |   95.19 |    86.48 |    92.3 |   95.19 | ...47-153,208-213 
  tools.ts         |   91.98 |    90.19 |   88.88 |   91.98 | ...50-451,467-473 
  web-fetch.ts     |   88.59 |    79.48 |    92.3 |   88.59 | ...12-313,315-316 
  write-file.ts    |   82.23 |    81.17 |   83.33 |   82.23 | ...65-668,680-715 
 src/tools/agent   |   75.01 |    82.55 |   74.62 |   75.01 |                   
  agent.ts         |   75.29 |    82.86 |    75.4 |   75.29 | ...2203,2265-2272 
  fork-subagent.ts |   69.62 |    71.42 |   66.66 |   69.62 | ...04-105,140-151 
 src/utils         |   88.98 |    87.55 |   93.68 |   88.98 |                   
  LruCache.ts      |       0 |        0 |       0 |       0 | 1-41              
  ...ssageQueue.ts |     100 |      100 |     100 |     100 |                   
  ...cFileWrite.ts |   77.96 |    80.48 |     100 |   77.96 | ...35,156,173-176 
  bareMode.ts      |   27.27 |      100 |       0 |   27.27 | 9-15,18-19        
  browser.ts       |    7.69 |      100 |       0 |    7.69 | 17-56             
  bundlePaths.ts   |     100 |      100 |     100 |     100 |                   
  ...igResolver.ts |     100 |      100 |     100 |     100 |                   
  ...engthError.ts |   89.11 |    86.66 |     100 |   89.11 | ...28-129,132-133 
  cronDisplay.ts   |   42.85 |    23.07 |     100 |   42.85 | 26-31,33-45,47-54 
  cronParser.ts    |   89.74 |    85.71 |     100 |   89.74 | ...,63-64,183-186 
  debugLogger.ts   |    95.9 |    93.84 |   94.73 |    95.9 | 106-107,214-218   
  editHelper.ts    |   93.63 |    83.52 |     100 |   93.63 | ...28-429,463-464 
  editor.ts        |   97.61 |    95.71 |     100 |   97.61 | ...70-271,273-274 
  ...arResolver.ts |   94.28 |    88.88 |     100 |   94.28 | 28-29,125-126     
  ...entContext.ts |     100 |    95.45 |     100 |     100 | 83                
  errorParsing.ts  |    97.7 |    97.05 |     100 |    97.7 | 72-73             
  ...rReporting.ts |   88.46 |       90 |     100 |   88.46 | 69-74             
  errors.ts        |   70.92 |    79.59 |   53.33 |   70.92 | ...03-219,223-229 
  fetch.ts         |   70.18 |    71.42 |   71.42 |   70.18 | ...42,148,161,186 
  fileUtils.ts     |   91.41 |    86.13 |      95 |   91.41 | ...1182,1186-1192 
  forkedAgent.ts   |    78.5 |    70.73 |   85.71 |    78.5 | ...30-436,441-447 
  formatters.ts    |   81.81 |       75 |     100 |   81.81 | 15-16             
  ...eUtilities.ts |   89.21 |    86.66 |     100 |   89.21 | 16-17,49-55,65-66 
  ...rStructure.ts |   94.36 |    94.28 |     100 |   94.36 | ...17-120,330-335 
  getPty.ts        |    12.5 |      100 |       0 |    12.5 | 21-34             
  gitDiff.ts       |   92.36 |    79.53 |     100 |   92.36 | ...55-856,928-929 
  ...noreParser.ts |    92.3 |    89.36 |     100 |    92.3 | ...15-116,186-187 
  gitUtils.ts      |   56.66 |    85.71 |      75 |   56.66 | ...2,72-73,97-148 
  iconvHelper.ts   |     100 |      100 |     100 |     100 |                   
  ...rePatterns.ts |     100 |      100 |     100 |     100 |                   
  ...ionManager.ts |     100 |     90.9 |     100 |     100 | 26                
  ...lPromptIds.ts |     100 |      100 |     100 |     100 |                   
  jsonl-utils.ts   |    74.1 |    90.76 |   58.33 |    74.1 | ...23-326,336-342 
  ...-detection.ts |     100 |      100 |     100 |     100 |                   
  ...iagnostics.ts |   96.87 |    91.83 |     100 |   96.87 | 214-219,272       
  ...yDiscovery.ts |    83.9 |    79.36 |     100 |    83.9 | ...16,319,411-414 
  ...tProcessor.ts |   93.63 |       90 |     100 |   93.63 | ...96-302,384-385 
  ...Inspectors.ts |   61.53 |      100 |      50 |   61.53 | 18-23             
  modelId.ts       |   98.55 |    96.87 |     100 |   98.55 | 103               
  ...kerChecker.ts |   88.75 |    85.71 |     100 |   88.75 | 69-70,87-93       
  notebook.ts      |   94.35 |    84.78 |     100 |   94.35 | ...10,122,174-176 
  openaiLogger.ts  |   88.05 |    84.09 |     100 |   88.05 | ...44-146,169-174 
  partUtils.ts     |     100 |    98.61 |     100 |     100 | 206               
  pathReader.ts    |     100 |      100 |     100 |     100 |                   
  paths.ts         |   93.21 |    91.86 |     100 |   93.21 | ...89-390,392-394 
  pdf.ts           |   93.68 |    87.05 |     100 |   93.68 | ...96-297,321-325 
  projectPath.ts   |     100 |      100 |     100 |     100 |                   
  ...ectSummary.ts |   89.39 |    72.41 |     100 |   89.39 | ...37-142,193-196 
  ...tIdContext.ts |     100 |      100 |     100 |     100 |                   
  proxyUtils.ts    |     100 |      100 |     100 |     100 |                   
  ...rDetection.ts |   58.57 |       76 |     100 |   58.57 | ...4,88-89,95-100 
  ...noreParser.ts |   85.45 |    85.18 |     100 |   85.45 | ...59,65-66,72-73 
  rateLimit.ts     |   92.55 |    85.92 |     100 |   92.55 | ...70-272,309-310 
  readManyFiles.ts |   87.96 |    86.95 |     100 |   87.96 | ...05-207,223-234 
  retry.ts         |   89.81 |    88.05 |     100 |   89.81 | ...29,350,357-358 
  ripgrepUtils.ts  |   46.79 |    84.37 |   66.66 |   46.79 | ...45-246,258-335 
  ...sDiscovery.ts |   97.42 |    92.85 |     100 |   97.42 | ...04,182-183,202 
  ...tchOptions.ts |   81.72 |    85.04 |   95.23 |   81.72 | ...11,536,565-574 
  runtimeStatus.ts |    97.5 |    88.57 |     100 |    97.5 | 167-168           
  safeJsonParse.ts |   74.07 |    83.33 |     100 |   74.07 | 40-46             
  ...nStringify.ts |     100 |      100 |     100 |     100 |                   
  ...aConverter.ts |   90.78 |    88.23 |     100 |   90.78 | ...41-42,93,95-96 
  ...aValidator.ts |   94.57 |    80.26 |     100 |   94.57 | ...04,213-216,270 
  ...r-launcher.ts |   76.92 |     91.3 |   66.66 |   76.92 | ...34,136,157-195 
  ...orageUtils.ts |   96.89 |    85.84 |     100 |   96.89 | ...51,367,447,466 
  shell-utils.ts   |   82.93 |    89.89 |     100 |   82.93 | ...1522,1529-1533 
  ...lAstParser.ts |   95.58 |    85.79 |     100 |   95.58 | ...1059-1061,1071 
  ...nlyChecker.ts |   95.75 |    92.39 |     100 |   95.75 | ...00-301,313-314 
  sideQuery.ts     |   98.73 |    94.59 |     100 |   98.73 | 111               
  ...pEventSink.ts |     100 |       80 |     100 |     100 | 61                
  ...tGenerator.ts |     100 |      100 |     100 |     100 |                   
  ...ameContext.ts |     100 |      100 |     100 |     100 |                   
  symlink.ts       |   77.77 |       50 |     100 |   77.77 | 44,54-59          
  ...emEncoding.ts |   96.36 |    91.17 |     100 |   96.36 | 59-60,124-125     
  terminalSafe.ts  |     100 |      100 |     100 |     100 |                   
  ...Serializer.ts |   98.72 |       90 |     100 |   98.72 | 42-43,134,201-203 
  testUtils.ts     |   53.33 |      100 |   33.33 |   53.33 | ...53,59-64,70-72 
  textUtils.ts     |      60 |      100 |   66.66 |      60 | 36-55             
  thoughtUtils.ts  |     100 |    92.85 |     100 |     100 | 71                
  ...-converter.ts |   94.59 |    85.71 |     100 |   94.59 | 35-36             
  tool-utils.ts    |    93.6 |     91.3 |     100 |    93.6 | ...58-159,162-163 
  truncation.ts    |     100 |       92 |     100 |     100 | 52,71             
  windowsPath.ts   |   89.47 |    79.31 |     100 |   89.47 | ...57-58,62,90-91 
  ...aceContext.ts |   93.71 |    89.28 |   93.33 |   93.71 | ...24-225,249-251 
  xml.ts           |     100 |      100 |     100 |     100 |                   
  yaml-parser.ts   |      92 |    84.61 |     100 |      92 | 49-53,65-69       
 ...ils/filesearch |   85.77 |    81.06 |   96.42 |   85.77 |                   
  crawlCache.ts    |     100 |      100 |     100 |     100 |                   
  crawler.ts       |   82.84 |    77.49 |   94.82 |   82.84 | ...1451,1485-1486 
  fileSearch.ts    |   93.58 |    87.32 |     100 |   93.58 | ...46-247,249-250 
  ignore.ts        |     100 |      100 |     100 |     100 |                   
  result-cache.ts  |     100 |     92.3 |     100 |     100 | 46                
 ...uest-tokenizer |   56.63 |    74.52 |   74.19 |   56.63 |                   
  ...eTokenizer.ts |   41.86 |    76.47 |   69.23 |   41.86 | ...70-443,453-507 
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...tTokenizer.ts |   68.39 |    69.49 |    90.9 |   68.39 | ...24-325,327-328 
  ...ageFormats.ts |      76 |      100 |   33.33 |      76 | 45-48,55-56       
  textTokenizer.ts |     100 |      100 |     100 |     100 |                   
  types.ts         |       0 |        0 |       0 |       0 | 1                 
-------------------|---------|----------|---------|---------|-------------------

For detailed HTML reports, please see the 'coverage-reports-22.x-ubuntu-latest' artifact from the main CI run.

@doudouOUC doudouOUC force-pushed the feat/serve-readonly-status-routes branch from b590c87 to 679b7cf Compare May 17, 2026 11:03
Comment thread packages/cli/src/acp-integration/acpAgent.ts Outdated
Comment thread packages/cli/src/acp-integration/acpAgent.ts Outdated
Comment thread packages/cli/src/acp-integration/acpAgent.ts
Comment thread packages/cli/src/acp-integration/acpAgent.ts Outdated
Comment thread packages/cli/src/acp-integration/acpAgent.ts Outdated
Comment thread packages/cli/src/acp-integration/acpAgent.ts Outdated
Comment thread packages/cli/src/acp-integration/acpAgent.ts
Comment thread packages/cli/src/acp-integration/session/Session.ts
Comment thread packages/cli/src/serve/httpAcpBridge.ts
Comment thread packages/cli/src/serve/server.ts
Add read-only daemon status endpoints for workspace MCP, skills, providers, session context, and session supported commands.

Expose matching typed SDK helpers and document the new additive v1 status surface.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
@doudouOUC doudouOUC force-pushed the feat/serve-readonly-status-routes branch from 679b7cf to ca58c8d Compare May 17, 2026 11:37

@wenshao wenshao left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No review findings. Downgraded from Approve to Comment: CI still running. — gpt-5.5 via Qwen Code /review

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Comment thread packages/cli/src/acp-integration/acpAgent.ts
Comment thread packages/cli/src/acp-integration/session/Session.ts
Comment thread packages/sdk-typescript/src/daemon/DaemonSessionClient.ts
Comment thread packages/cli/src/serve/server.ts

@wenshao wenshao left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Incremental review of changes since b590c87 (previous review).

The new changes — heartbeat route, maxQueued SSE query param, EventBus slow_client_warning, BoundedQueueEntry refactor, and SDK event types — are clean:

  • Heartbeat route validates client ID before bumping timestamps (prevents attacker watermark manipulation)
  • maxQueued param has thorough input validation with fail-closed 400 before SSE handshake
  • EventBus slow_client_warning has correct hysteresis logic (warn at 75%, re-arm at 37.5%) with per-entry forced tracking
  • All builds and focused tests pass (270 CLI tests, 103 SDK tests, 134 core tests)
  • ESLint clean on changed files

No new issues found in the incremental diff. The 10 previously-reported findings in acpAgent.ts, Session.ts, httpAcpBridge.ts, and server.ts remain unaddressed.

— glm-5.1 via Qwen Code /review

Comment thread packages/sdk-typescript/src/daemon/DaemonSessionClient.ts
wenshao
wenshao previously approved these changes May 17, 2026

@wenshao wenshao left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Second opinion review (mimo-v2-5-pro)

Thorough multi-dimensional analysis (correctness, security, code quality, performance, test coverage, build verification, attacker simulation, 3AM oncall, and maintainer perspectives). 6/9 agents completed successfully; all 491 tests pass across 9 test files.

Deterministic checks:

  • tsc: No new errors in PR source files (pre-existing errors in integration tests only)
  • eslint: Clean

Agent findings summary:

  • No new Critical or Important issues found beyond what the first review (deepseek-v4-pro) already identified
  • Two code-quality observations on pre-existing code (not postable as inline comments since they target unchanged lines):
    1. events.ts:345–368: permission_resolved and permission_already_resolved switch cases are identical — merge via fallthrough
    2. httpAcpBridge.ts:2855–2935: respondToPermission and respondToSessionPermission share ~10 lines of option-validation logic — extract shared helper

Filtered out (pre-existing / out-of-scope):

  • restoreSessionHandler missing res.on('close') detachClient — same pattern as POST /session happy path; consistent with existing architecture
  • Cross-session permission voting via non-session-scoped endpoint — pre-existing; the new session-scoped endpoint was designed to address this
  • TOCTOU in exportCommand.ts — outside PR scope
  • Session ID path traversal — consistent with existing routes; agent-level validation exists

Verdict: APPROVE — Well-structured PR with clean status route additions, proper capability advertisement, and comprehensive test coverage. The 11 inline comments from the first review are valid and should be addressed, but none are blockers for the overall design.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
wenshao
wenshao previously approved these changes May 17, 2026

@wenshao wenshao left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-verified on dd9a0d4 (force-push after conflict resolution + hardening commit 6244c89).

Local validation

Command Result
npm run build (core) exit 0
npm run typecheck (cli) exit 0
npm run typecheck (sdk-typescript) exit 0
npx vitest run cli (server / httpAcpBridge / acpAgent / Session) 396/396 passed (was 368 pre-hardening)
npx vitest run sdk (DaemonClient / DaemonSessionClient) 91/91 passed (was 84 pre-hardening)
git diff --check exit 0
GitHub CI Lint / CodeQL ×2 / Test (ubuntu) / Classify all green; Test (mac+win) still running

Diff since last approval (ca58c8ddd9a0d4)

  • 6244c894 fix(serve): harden read-only status snapshots — 208 net lines, primarily in acpAgent.ts (mcp/skill/provider snapshot edge cases), with +185 lines of test coverage; passes locally and adds the +28 cli / +7 sdk tests the totals reflect.
  • 8df48219 + dd9a0d42 — merge resolution against current main; capability registry, server routes, doc table, Session.ts helper refactor all merge cleanly. I re-ran npm run build on core before typecheck so the cross-package @qwen-code/qwen-code-core exports added on main (collectMemoryDiagnostics, mid_turn_user_message, plansDirectory) resolve correctly.

Remaining open nits (unchanged from prior round, intentionally non-blocking)

  • Session.ts:198 allocates an AbortController that is never wired to a cancellation path. Suggestion only; no functional impact on the read-only status routes this PR ships.
  • DaemonSessionClient.context() / supportedCommands() (sdk DaemonSessionClient.ts) don't forward this.clientId like the other session-scoped methods do. For read-only routes this is benign — there's no audit trail to attribute to a specific client — but the symmetry is worth a small follow-up.

Neither is a behavioral defect; both can fold into a Wave 3 follow-up.

LGTM.

@wenshao wenshao left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-approving on 11623de after the author addressed the two remaining nits — Session.ts unused AbortController removed; DaemonClient.sessionContext / DaemonSessionClient.context / supportedCommands now forward clientId for audit symmetry with the other session-scoped methods.

Local re-validation on 11623de: cli vitest 396/396, sdk vitest 91/91, cli + sdk typecheck both exit 0.

LGTM.

@wenshao wenshao merged commit 60fe594 into main May 17, 2026
41 checks passed
doudouOUC added a commit that referenced this pull request May 17, 2026
…ventBus changes (#4245)

- qwen-serve-routes.test.ts: expand expected features list to 24, adding
  slow_client_warning (#4237) and workspace_mcp/workspace_skills/
  workspace_providers/session_context/session_supported_commands (#4241).
  Matches EXPECTED_STAGE1_FEATURES in server.test.ts:76-101.
- qwen-serve-baseline.test.ts: update SSE backpressure assertion from 3
  to 4 frames (tick, tick, slow_client_warning, client_evicted). PR #4237
  changed EventBus to force-push a slow_client_warning synthetic frame
  when the per-subscriber queue reaches the 75% warn threshold, before
  the client_evicted terminal frame fires on overflow. Mirrors the unit
  test at eventBus.test.ts:103-122.

Both integration mirrors drifted because integration tests only run on
schedule / workflow_dispatch (release.yml:4-9), not PR CI. Fixes the
release run 25992130532 failure in both Docker and No-Sandbox jobs.

🤖 Generated with [Qwen Code](https://github.com/QwenLM/qwen-code)
doudouOUC added a commit that referenced this pull request May 18, 2026
…4250)

* refactor(serve): add FileSystemService boundary (#4175 PR 18)

Introduce a per-request workspace filesystem boundary inside the
`qwen serve` daemon. The boundary centralizes path canonicalization,
symlink-aware boundary checks, ignore/trust policy, size/binary
limits, and audit hooks behind a single typed surface — preparing
PR 19 (read-only file routes) and PR 20 (write/edit routes) to
share a guarded chokepoint instead of re-implementing path safety
per route.

Wave 4 PR 18 of #4175 — pure refactor, no new HTTP routes; depends
on PR 12 (#4241) and PR 15 (#4236), both merged.

New module under `packages/cli/src/serve/fs/`:

- `paths.ts` extracts `canonicalizeWorkspace` from `httpAcpBridge.ts`
  (re-exported there for backward compatibility) and adds:
  - `ResolvedPath` brand and `Intent` union (read/write/edit/list/
    glob/stat) with exhaustiveness checks at the trust gate
  - `hasSuspiciousPathPattern` — detects NTFS ADS, 8.3 short names,
    long-path prefixes, UNC paths, trailing dots, DOS device names,
    and three-or-more-dot path components (claude-code-style)
  - `findExistingAncestor` with explicit ENOTDIR rejection so a
    regular file in a path component throws `parse_error` rather
    than passing boundary inspection and 500-ing later
  - `resolveWithinWorkspace` running a chain-aware realpath check
    with ENOENT-tolerant ancestor walk for write/stat intents
- `errors.ts` defines `FsError` / `FsErrorKind` plus `wrapAsFsError`,
  which categorizes raw `fs.promises` errnos (EACCES → permission_
  denied, ELOOP → symlink_escape, ENOTDIR → parse_error, etc.) so
  body-level failures emit audit events instead of escaping
  uncategorized
- `policy.ts` carries `MAX_READ_BYTES` (256 KiB), `MAX_WRITE_BYTES`
  (5 MiB), `BINARY_PROBE_BYTES` (4 KiB), `shouldIgnore` (file/
  directory aware), and `assertTrustedForIntent` with an
  exhaustive switch over `Intent`
- `audit.ts` emits typed `fs.access` / `fs.denied` `BridgeEvent`
  frames with SHA-256-hashed paths, optional raw-path passthrough
  via `QWEN_AUDIT_RAW_PATHS=1`, and discriminator `kind` fields so
  SDK consumers can exhaustively narrow `event.data`
- `workspaceFileSystem.ts` — `WorkspaceFileSystem` interface +
  `createWorkspaceFileSystemFactory` with eight methods (resolve,
  stat, readText, readBytes, list, glob, writeText, edit). Every
  body method funnels failures through `recordAndWrap`, which
  wraps raw fs errors and always emits an `fs.denied` audit event
  before rethrowing. `readText` enforces `MAX_READ_BYTES` *before*
  delegating to the slurping core service so unbounded requests
  against multi-gigabyte files can no longer OOM the daemon.
  `glob` realpath-checks each hit against the canonical workspace
  and reports filtered escapes via a single aggregated `fs.denied`
  event with the dropped count
- `index.ts` is the barrel re-export PR 19/20 will import from

Modified files:

- `packages/cli/src/serve/httpAcpBridge.ts` — extracted
  `canonicalizeWorkspace` to `fs/paths.ts`; the bridge re-exports
  it so existing callers in `server.ts` and `runQwenServe.ts` keep
  working
- `packages/cli/src/serve/server.ts` — added
  `fsFactory?: WorkspaceFileSystemFactory` to `ServeAppDeps`;
  `createServeApp` builds a strict default (`trusted: false`,
  warn-once no-op `emit`) when none is injected so a future
  refactor that forgets `fsFactory` injection cannot silently
  allow writes against an untrusted workspace; factory parked on
  `app.locals` for PR 19/20 route handlers
- `packages/core/src/index.ts` — re-exports `Ignore`,
  `loadIgnoreRules`, and `LoadIgnoreRulesOptions` from
  `utils/filesearch/ignore.js` for cli consumption

411 serve tests pass; typecheck clean.

Engineering principles checklist:
- [x] Independently mergeable (no new routes, no new capability tag)
- [x] Backward compatible (no removed routes / event fields / CLI behavior)
- [x] Default off (no public surface change; PR 19/20 will activate routes)
- [x] qwen serve Stage 1 routes preserved
- [x] Gradual migration (PR 19/20 will adopt the boundary)
- [x] Reversible (single PR rollback)
- [x] Tests-first (101 unit tests across the new module + contract test)

🤖 Generated with [Qwen Code](https://github.com/QwenLM/qwen-code)

* fix(serve/fs): address PR review feedback (#4250)

Codex + Copilot review found 8 substantive issues against
7b0db4c; this commit fixes all of them. The first two are
P1 build-breakers introduced by the pre-commit `eslint --fix`
auto-promoting value imports to `import type` — 31 fs tests
were failing post-commit until this fix.

Issue list (links to PR comments at #4250):

1. Import type erased runtime values —
   workspaceFileSystem.ts:10-15. eslint's
   consistent-type-imports rule rewrote
   `import { Ignore, StandardFileSystemService, loadIgnoreRules,
   type WriteTextFileOptions }` -> `import type { ... }` because
   it saw type-only usage of `Ignore`. That erased
   `loadIgnoreRules` (called at runtime) and
   `StandardFileSystemService` (constructed at runtime), causing
   TS1361/TS2206 and runtime ReferenceErrors. Restored as a
   value import with inline `type` modifiers per-symbol and an
   eslint-disable line + comment so future autofixes don't
   repeat the regression.

2. Same import-type erasure in contract.test.ts:14 — `isFsError`
   was lumped under `import type` even though it's called at
   runtime. Same fix shape.

3. edit() OOM hole — workspaceFileSystem.ts. The earlier review
   pass added a pre-stat MAX_READ_BYTES gate to readText but
   missed edit, which fsp.readFile's the whole file before any
   size check. Multi-GB targets inside the workspace could OOM
   the daemon. Now stat-first; refuses above the cap with
   file_too_large; also rejects binary files (string indexOf
   over arbitrary bytes is meaningless).

4. glob accepted absolute / device patterns —
   workspaceFileSystem.ts. The ..-segment check stopped lexical
   traversal but /etc/** / C:\\Users\\foo\\** /
   \\\\server\\share\\** / //server/share/** still reached
   globAsync, walking outside the workspace before per-hit
   filtering dropped the results. Now rejects these patterns
   up-front with parse_error so no I/O happens outside.

5. glob ignore filter probed every hit as `file` —
   workspaceFileSystem.ts. The underlying `ignore` library
   needs a trailing-slash probe for dist/ / .git/-style
   directory patterns; probing as `file` silently leaked
   directory matches. Now lstats each hit and routes 'directory'
   vs 'file' to shouldIgnore so dir-only ignore rules actually
   match.

6. ReadTextOptions.line off-by-one — workspaceFileSystem.ts. The
   public option was documented as 1-based but forwarded as-is
   to readFileWithLineAndLimit, which is 0-based. A request with
   line: 1 returned content starting at the second line. Now
   converts 1-based -> 0-based at the boundary; doc clarified;
   truncation check uses the converted index.

7. ServeAppDeps.fsFactory JSDoc said trusted=true — server.ts:96.
   Stale from before the strict-default refactor in the same
   review pass. Rewrote to match the actual trusted: false +
   warn-once emit behavior.

8. MAX_READ_BYTES JSDoc said reads above cap return truncated —
   policy.ts:18. Stale from before the hard-cap refactor; now
   correctly states the cap throws file_too_large and that soft
   truncation only applies under the cap via enforceReadSize.

7 new tests cover the new behaviors:
- POSIX-absolute pattern rejection
- Win32 / UNC pattern rejection (4 variants)
- directory-pattern ignore (dist/)
- edit file-too-large
- edit binary refusal
- readText line: 1 returns from first line
- readText line: 2 starts from second line

418/418 serve tests pass; typecheck + eslint clean.

Deferred follow-ups (per PR review reply):
- glob maxResults is applied after globAsync materializes every
  match. A streaming iterator (glob.iterate) would bound the
  walk too. Non-trivial; tracked as a separate hardening
  follow-up since current behavior is correctness-safe (just
  not optimal under huge trees).
- Per-path glob escape hash in audit hint (currently aggregated
  count) — can revisit once PR 19 wires the routes and we see
  real audit volume.
- EVENT_SCHEMA_VERSION migration mechanism — orthogonal; the
  whole BridgeEvent schema lacks one and that's a Wave 5+
  concern.

🤖 Generated with [Qwen Code](https://github.com/QwenLM/qwen-code)

* fix(serve/fs): close 3 review-round-2 findings (#4250)

The wenshao + DeepSeek reviewer pass on a81ada4 surfaced 3 more
issues; this commit fixes them.

1. Dangling-symlink write escape (paths.ts) — Critical security
   bug. A request like `write /ws/escape` where `<ws>/escape` is
   a symlink whose target doesn't exist YET would pass the
   ENOENT-tolerant ancestor walk: realpath fails ENOENT, the
   walk-up returns `<ws>` as ancestor, the canonical becomes
   `<ws>/escape`, containment passes — but the eventual write
   follows the symlink and creates the file at the symlink
   target outside the workspace. lstat-then-readlink before the
   ancestor walk catches this; the symlink target is itself
   resolved via the deepest existing ancestor so macOS
   /private/var canonicalization stays consistent with
   boundCanonical (an absolute target inside the workspace
   tmpdir would otherwise have been false-flagged on macOS).

2. glob realpath catch over-reported symlink_escape
   (workspaceFileSystem.ts) — every realpath failure inside the
   per-hit boundary loop was counted as `symlink_escape`. EIO,
   EACCES, ENAMETOOLONG, EBUSY are environmental failures, not
   security events; mislabeling them poisoned the audit signal
   for operators trying to investigate genuine escape attempts.
   Now distinguished: ENOENT/ELOOP count as escapes; other
   errnos count as transient errors and emit a separate
   aggregated `fs.denied` with errorKind: 'permission_denied'.

3. policy.ts:enforceReadSize JSDoc said the boundary "intentionally
   does NOT throw" — stale after a81ada4's hard-cap refactor.
   Rewrote to clarify the helper is the soft truncation gate that
   only fires under the hard cap; readText itself enforces the
   hard cap with file_too_large via its pre-stat check. The
   readme/contract is now consistent with workspaceFileSystem.ts.

2 new tests:
- dangling symlink targeting outside-workspace path → symlink_escape
- dangling symlink targeting future-inside-workspace path → succeeds
  (ahead-of-mkdir flow for atomic-write-via-rename)

420/420 serve tests pass; typecheck clean.

Remaining tracked follow-ups (per PR review reply):
- list/glob brand cast (P2 deferred per PR description)
- glob audit pathHash hashes pattern not paths
- edit() TOCTOU read-modify-write race (atomic-via-temp + rename)
- wrapAsFsError ENOSPC/EIO mapping to a distinct kind
- runQwenServe → fsFactory injection integration test
- glob maxResults streaming (glob.iterate)

🤖 Generated with [Qwen Code](https://github.com/QwenLM/qwen-code)

* fix(serve/fs): cross-platform ENOTDIR detection (#4250 CI fix)

Windows CI test failure on a81ada4 surfaced a real cross-platform
bug in `findExistingAncestor`. POSIX returns `ENOTDIR` when
`fs.stat` traverses through a non-directory in a path component
(e.g. `${ws}/file.txt/leaf` where `file.txt` is a regular file).
**Windows returns `ENOENT` for the same case.** The errno-based
guard added in a81ada4 only branched on `ENOTDIR`, so the
Windows path silently fell through to the ancestor walk and the
boundary returned a "canonical" the eventual write could not
honor — `WorkspaceFileSystem - audit always emits on body errors >
rejects ENOTDIR ancestor walk with parse_error rather than
passing boundary` failed with `expected false to be true` on the
windows-latest runner.

Fix: switch from errno-based detection (platform-divergent) to
dirent-kind detection. After `fs.stat` succeeds during the
walk-up, if the existing ancestor is NOT a directory AND there
are unresolved tail components, throw `parse_error`. Both `ENOENT`
and `ENOTDIR` from `fs.stat` are now treated as "the *current*
path doesn't resolve, keep walking" — the post-walk kind check
fires regardless of which errno surfaced. Cross-platform-safe.

The local 110/110 fs tests still pass on macOS/Linux; the Windows
case will exercise the kind-check branch on next CI run.

macOS CI failures on the same workflow run (`InputPrompt.test.tsx`
placeholder reuse, `SettingsDialog.test.tsx` 5s timeout) are pre-
existing flaky UI tests, NOT touched by this PR.

🤖 Generated with [Qwen Code](https://github.com/QwenLM/qwen-code)

* fix(serve/fs): close 4 review-round-3 findings (#4250)

DeepSeek's third review pass (after b38e821) flagged four more
issues; this commit fixes all of them.

1. Multi-hop dangling symlink bypass (paths.ts) — Critical
   security fix. The earlier single-readlink fix at efd7a46
   was bypassed by chained dangling symlinks: <ws>/leak ->
   <ws>/middle -> /scratch/evil where every layer is a symlink
   and the final target doesn't exist. The fix only readlink'd
   the first hop (<ws>/middle), saw it was inside the workspace
   via findExistingAncestor, and let the chain through. The OS
   write at <ws>/leak would then follow both hops and create
   /scratch/evil. Now loops lstat + readlink up to
   MAX_ANCESTOR_HOPS, tracks visited inodes for cycle detection,
   and only validates containment on the fully-dereferenced
   leaf. Cycle detection rejects with symlink_escape; chains
   that exceed the hop bound also surface as symlink_escape
   with a "too long or contains a cycle" hint.

2. opts.line validation (workspaceFileSystem.ts) — the docstring
   committed to "1-based positive integer" but Infinity / floats
   / negative values flowed through to readFileWithLineAndLimit
   and degraded silently. Now enforces Number.isSafeInteger +
   line >= 1 at the boundary; everything else throws
   parse_error. Test covers Infinity, -Infinity, 0, -1, 1.5,
   NaN.

3. io_error FsErrorKind (errors.ts) — wrapAsFsError previously
   conflated EIO/EBUSY/ENAMETOOLONG/EMFILE/ENFILE/ENOSPC/ETXTBSY
   under permission_denied. Monitoring pipelines that key on
   errorKind for security alerting would page oncall on a full
   disk. New io_error kind (HTTP 503) maps the environmental-
   failure errnos with distinct hints. EACCES/EPERM stay on
   permission_denied (literal access denial); EIO (failing
   disk), EBUSY (busy file), ENAMETOOLONG (PATH_MAX),
   EMFILE/ENFILE (fd exhaustion), ENOSPC (df -h reporting
   100%), ETXTBSY (text-busy) all route to io_error.

4. glob audit kind taxonomy (workspaceFileSystem.ts) — three-way
   classification mirrors wrapAsFsError so the per-hit realpath
   catch surfaces ENOENT/ELOOP -> symlink_escape, EACCES/EPERM
   -> permission_denied, everything else -> io_error. Each
   class emits its own aggregated fs.denied event.

5. edit() matchedIgnore (workspaceFileSystem.ts) — readText and
   writeText both stamp matchedIgnore in their access audit;
   edit didn't, so operators monitoring fs.access events couldn't
   distinguish edits to .gitignore'd files (build artifacts,
   logs) from edits to tracked source. Added the same
   shouldIgnore + matchedIgnore plumbing that readText uses.

8 new tests:
- multi-hop dangling symlink (security)
- symlink cycle (security)
- ENOSPC/EIO/EBUSY/ETXTBSY/ENAMETOOLONG -> io_error mapping
- io_error -> HTTP 503
- EMFILE/ENFILE updated to io_error (was permission_denied)
- opts.line rejects Infinity/-Infinity/0/-1/1.5/NaN
- edit() audit records matchedIgnore on .log file

426/426 serve tests pass; typecheck clean.

Remaining tracked follow-ups (per PR review reply):
- list/glob brand cast (P2 deferred per PR description)
- glob audit pathHash hashes pattern not paths
- edit() TOCTOU read-modify-write race (atomic-via-temp + rename) — pinned to PR 20
- runQwenServe → fsFactory injection integration test — pinned to PR 19
- glob maxResults streaming (glob.iterate)

🤖 Generated with [Qwen Code](https://github.com/QwenLM/qwen-code)

* fix(serve/fs): close 3 review-round-4 critical findings (#4250)

DeepSeek's fourth review pass surfaced three more critical bugs;
all are fixed in-PR.

1. TOCTOU symlink substitution in readText/readBytes/edit
   (workspaceFileSystem.ts) — Critical. fsp.stat(p) and the
   subsequent lowFs.readTextFile(p) (or fsp.readFile / fsp.readFile
   for edit) are two separate syscalls. An attacker who can write
   into the workspace can swap p from a regular file to a symlink
   pointing outside between the two calls; pre-stat sees the
   original, the read follows the swap.

   Fix: assertInodeStableAfterRead(p, preIno) — after each read,
   re-lstat p; reject with symlink_escape if the path is now a
   symlink (post.isSymbolicLink()) or its inode changed (preIno
   !== post.ino, with a 0-ino fallback for procfs / virtual
   mounts that don't report meaningful inodes). Catches the
   swap-and-leave attack and the swap-and-keep-swapped attack.
   Residual race (attacker swaps back AFTER our read but BEFORE
   our lstat) is much smaller than the original window and
   outside PR 18's threat model; fd-based reading via
   fsp.open + fileHandle.read would close it entirely but
   requires a new variant of lowFs that takes a FileHandle —
   tracked as a follow-up.

2. UTF-8 truncation corruption in readText (workspaceFileSystem.ts)
   — Critical. buf.subarray(0, sizeOutcome.bytesToRead).toString
   ('utf-8') silently emits U+FFFD when bytesToRead falls
   mid-codepoint (CJK, emoji). A downstream consumer parsing
   JSON or source code over the truncated content would see
   broken trailing bytes; meta.truncated would be true but the
   prefix is corrupt. A subsequent edit() with the corrupted
   string as oldText would also fail to match the on-disk content.

   Fix: safeUtf8Truncate(buf, maxBytes) walks back from maxBytes
   through any continuation bytes (0b10xxxxxx), then verifies
   the leading byte's full sequence fits within the cap; drops
   the leading byte if it doesn't. The result is always a clean
   prefix at a valid codepoint boundary. Test pins '中文测试' (12
   bytes / 3 bytes per char) truncated at 7 bytes -> '中文' (no
   U+FFFD).

3. glob opts.cwd bypasses workspace boundary
   (workspaceFileSystem.ts) — Critical. opts.cwd was used
   directly as the glob root with no validation against
   boundWorkspace. ResolvedPath is a brand cast and a stale
   or forged value lets a glob('**/*', { cwd: '/etc' })
   enumerate files outside the workspace. The pattern-side
   absolute / UNC checks added in a81ada4 only constrain
   the *pattern*; cwd is the actual hazard.

   Fix: at the entry point of glob(), path.resolve cwd and
   isWithinRoot-check against boundWorkspace. Throws
   path_outside_workspace if cwd is outside, even when the
   pattern itself is harmlessly relative. Test pins the case
   with cwd: scratch (outside workspace).

3 new tests:
- readText with mid-operation symlink swap -> symlink_escape
- safeUtf8Truncate keeps CJK codepoints intact at 7-byte cap
- glob with opts.cwd outside workspace -> path_outside_workspace

429/429 serve tests pass; typecheck + eslint clean.

Remaining tracked follow-ups (Post-PR-18 hardening, in #4175):
- list/glob brand-cast contract (PR 19)
- runQwenServe → fsFactory injection contract test (PR 19)
- edit() write-side TOCTOU + atomic-via-temp + expectedHash (PR 20)
- glob audit pathHash (independent audit.ts commit)
- glob maxResults streaming (independent hardening)
- glob pattern preflight refactor to reuse hasSuspiciousPathPattern (cosmetic)

🤖 Generated with [Qwen Code](https://github.com/QwenLM/qwen-code)

* fix(serve/fs): close 7 review-round-5 findings (#4250)

DeepSeek round-5 surfaced 9 comments; 7 are real findings (the
other 2 — UTF-8 truncation + glob opts.cwd — already fixed in
5468342 from round-4 and replied-to inline). Stack on round-4.

1. edit() empty-oldText silent-prepend (workspaceFileSystem.ts) —
   Critical silent data corruption. JS `''.indexOf('')` returns 0,
   so without an empty-string guard
   `current.slice(0,0) + newText + current.slice(0)` = `newText +
   current` — silently prepends `newText` to the whole file with
   a success audit event. PR 20 routes that thread user-supplied
   `oldText` verbatim must not be able to trigger this. Now
   throws `parse_error` BEFORE the read with a hint explaining
   why empty matches are rejected.

2. DOS device name regex misses bare names + first-extension forms
   (paths.ts) — Windows attack surface. The earlier
   /\.(CON|PRN|AUX|NUL|COM[1-9]|LPT[1-9])$/i only caught the
   last-extension form (file.CON). NTFS reserves these names
   regardless of extension: CON, NUL, CON.txt, NUL.dat,
   CON.foo.bar are ALL reserved device handles. New regex
   /(^|\.)(CON|...|LPT[1-9])(\.|$)/i covers all four positions
   (bare / first-ext / last-ext / middle-ext) while still
   admitting legitimate substrings (BACON, concat.txt, precon.go).

3. Buffer.byteLength replaces Buffer.from for size-only checks
   (workspaceFileSystem.ts) — 5 MB heap allocation per write
   eliminated. `writeText` and `edit()` previously materialized
   the entire UTF-8 payload (up to MAX_WRITE_BYTES) just to read
   `.length`; `Buffer.byteLength(content, 'utf-8')` returns the
   count without allocating.

4. edit() error message includes oldText snippet
   (workspaceFileSystem.ts) — Production debuggability. The
   earlier hint was just "edit() expects oldText to appear
   verbatim in the file" — at 3 AM an operator can't tell whether
   the mismatch is whitespace, a stale file, or a wrong target.
   Now includes a JSON-quoted truncated snippet (max 80 chars +
   ellipsis) of the searched-for text.

5. recordAndWrap forwards FsError message into fs.denied audit
   (workspaceFileSystem.ts + audit.ts) — Audit observability gap.
   Audit consumers debugging an incident saw `errorKind` + `hint`
   but lost the underlying OS error detail (path, errno text,
   byte count). FsDeniedAuditPayload now carries an optional
   `message` field; recordAndWrap forwards `fs.message`
   automatically.

6. EISDIR / ENOTDIR distinct hints (errors.ts) — UX. Both shared
   the same hint "a path component is not a directory where one
   was expected" — for EISDIR (path IS a directory but a file was
   expected) the wording was reversed. Now distinct hints with
   the errno name explicitly cited.

7. kindFromStats / kindFromDirent merged into kindFromStatLike
   (workspaceFileSystem.ts) — duplicate function bodies removed.
   Both fs.Stats and fs.Dirent expose the same isFile /
   isDirectory / isSymbolicLink interface, and both targets
   (FsStat['kind'], FsEntry['kind']) are the same 4-value union.
   Single helper avoids drift if the union grows.

4 new tests:
- bare/multi-ext DOS device names (CON, NUL, CON.txt, CON.foo.bar)
  + legitimate substrings (BACON, concat, precon, contemplating)
- edit() empty oldText -> parse_error + file unchanged
- edit() not-found error includes searched snippet in hint
- fs.denied audit payload carries FsError message

Plus the 2 already-fixed items (UTF-8 boundary, glob opts.cwd)
have new test coverage from round-4.

433/433 serve tests pass; typecheck + eslint clean.

Stack: 7b0db4ca81ada4efd7a46b38e821911cb8e5468342 → THIS

🤖 Generated with [Qwen Code](https://github.com/QwenLM/qwen-code)

* fix(serve/fs): close 7 review-round-6 findings (#4250)

Round-6 review (wenshao + gpt-5.5) flagged 7 items including
two Critical and one privacy regression I introduced in round-5.

1. writeText / edit pre-write symlink guard
   (workspaceFileSystem.ts) — Critical, two reviewers (wenshao
   #CsBcq + gpt-5.5 #CsB3M) independently flagged.
   `atomicWriteFile` (`packages/core/src/utils/atomicFileWrite.ts`)
   resolves symlinks at write time, so a swap between the
   boundary's `resolve()` and `lowFs.writeTextFile()` would let
   the write follow the symlink to outside the workspace.
   `writeText` had no read phase, so its window was wider than
   `edit()`'s. New helper `assertNotSymlinkBeforeWrite(p)` lstats
   the path immediately before each `lowFs.writeTextFile` call;
   ENOENT is fine (ahead-of-create flow), but an actual symlink
   throws `symlink_escape`. Used in `writeText` AND `edit()`.
   Residual race after this guard but before the write completes
   is the deferred PR 20 atomic-via-temp follow-up.

2. recordAndWrap message field bypassed privacy mode
   (audit.ts) — Critical privacy regression I introduced at
   ebd9e78 (round-5). The new `FsDeniedAuditPayload.message`
   field forwarded `FsError.message` unconditionally — and many
   throw-sites embed `${p}` (absolute paths) or user-supplied
   `oldText` snippets into the message. Privacy-mode operators
   (without `QWEN_AUDIT_RAW_PATHS=1`) saw paths leak through the
   message field even though they explicitly disabled raw-path
   logging. Fixed: `message` is now gated behind `includeRawPaths`
   alongside `relPath`. Privacy mode = no path-bearing fields,
   period. Operators wanting forensic context opt in via
   `QWEN_AUDIT_RAW_PATHS=1` and accept both fields together.

3. glob opts.cwd via symlink (workspaceFileSystem.ts) — gpt-5.5
   #CsB3P. Textual `path.resolve(cwd) + isWithinRoot` admits
   `<ws>/link` even when `<ws>/link → /etc` is a symlink to
   outside; `globAsync` walks `/etc` before the per-hit filter
   drops results. Switched to `fsp.realpath(path.resolve(cwd))`
   so the containment check sees the actual walk root. ENOENT
   on cwd surfaces as `path_not_found`.

4. readText OOM via concurrent file growth
   (workspaceFileSystem.ts) — wenshao #CsBeE. The pre-stat
   `MAX_READ_BYTES` gate only sees the size at stat time; a
   concurrent writer can grow the file before the actual
   `readFileWithLineAndLimit` slurp. Added post-read
   `Buffer.byteLength(result.content) > MAX_READ_BYTES` check.
   The proper fix (fd-based read tying size + read to the same
   inode) is a hardening follow-up; this byte-length check is
   the defense-in-depth layer.

5. readBytes maxBytes can widen past MAX_READ_BYTES
   (policy.ts) — wenshao #CsBj5. `enforceReadBytesSize(st.size,
   opts.maxBytes)` used the caller-supplied `maxBytes` as the
   ceiling, replacing rather than clamping `MAX_READ_BYTES`. A
   future PR 19/20 route forwarding `req.query.maxBytes` could
   blindly bypass the daemon's 256 KiB safety cap. Now clamps
   via `Math.min(maxBytes, MAX_READ_BYTES)`.

6. ENOENT_TOLERATING_INTENTS docstring + test (paths.ts) —
   wenshao #CsBk3. The Intent docstring only mentioned `'write'`
   tolerating ENOENT; `'stat'` was in the set undocumented. A
   future maintainer removing `'stat'` thinking it was a
   copy-paste error would silently change behavior (stat on a
   concurrently-deleted path would throw `path_not_found` from
   the resolver instead of letting `fsp.lstat` throw `ENOENT`
   naturally). Amended docstring to call out `'stat'`'s rationale
   explicitly + added contract corpus case.

6 new tests:
- glob cwd via symlink to outside → path_outside_workspace
- writeText with mid-operation symlink swap → symlink_escape +
  outside file unchanged
- edit with mid-operation symlink swap → symlink_escape + outside
  file unchanged
- readBytes opts.maxBytes attempting widening → file_too_large
- fs.denied message field absent in privacy mode (default)
- fs.denied message field present in raw-paths mode (forensic)
- contract corpus: resolve('newdir/leaf', 'stat') succeeds for
  ENOENT path

439/439 serve tests pass; typecheck + eslint clean.

Stack: 7b0db4ca81ada4efd7a46b38e821911cb8e5468342ebd9e78 → THIS

🤖 Generated with [Qwen Code](https://github.com/QwenLM/qwen-code)

* fix(serve/fs): close 5 review-round-7 findings (#4250)

glm-5.1 round-7 review surfaced 6 items; 5 are real fixes, 1 was
already addressed in 7f4f30d (writeText pre-write symlink
guard — reviewer looked at ebd9e78 snapshot ~8h before the
round-6 fix). Stack on round-6.

1. edit() bypassed lowFs.readTextFile (workspaceFileSystem.ts) —
   Critical encoding round-trip corruption. The earlier
   `fsp.readFile(p, 'utf-8')` included the UTF-8 BOM verbatim in
   `current`, breaking `oldText` matching even when the user
   passed the exact source text from a previous read; lost
   iconv-supported codepage handling (GBK / Big5 / Shift_JIS),
   so non-UTF-8 files would mojibake into `current` and
   round-trip-corrupt on write-back; and the subsequent
   `lowFs.writeTextFile` passed no `_meta`, stripping the BOM
   and forcing UTF-8 on write-back even when the original was
   BOM'd or non-UTF-8. Fix: read via `lowFs.readTextFile` AND
   forward `readResult._meta` into the write-back. Test pins
   UTF-8 BOM round-trip end-to-end.

2. hasSuspiciousPathPattern multi-digit and POSIX false positive
   (paths.ts) — `/~\\d/` only matched single-digit; NTFS
   allocates `~10+` on >9 collisions. POSIX false-positives:
   editor swap files, backup tools used `~N` legitimately. Fixed
   to `/~\\d+/` and gated behind `process.platform === 'win32'`,
   matching the ADS-colon check.

3. canonicalizeWorkspace redundant per-request syscall
   (paths.ts) — Performance. Factory canonicalizes once at
   build; every `resolveWithinWorkspace` also ran realpathSync
   on the same path, blocking the event loop. Added
   CANONICAL_BOUND_CACHE Map keyed on the input string;
   steady-state size = 1 per `1 daemon = 1 workspace`.

4. readBytes opts.maxBytes API contract
   (workspaceFileSystem.ts) — Semantic mismatch. Parameter name
   promised window-read; impl only used it as a hard reject
   gate. Now truncates the buffer post-read so `readBytes(p,
   { maxBytes: 1024 })` on a 200 KB file returns 1 KB. Hard
   `MAX_READ_BYTES` cap still throws for files above it.

5. glob walks node_modules and .git unnecessarily
   (workspaceFileSystem.ts) — Performance. Without an `ignore`
   option, `globAsync` traversed every file under those dirs
   before our per-hit `shouldIgnore` filter. Now passes
   `ignore: ['**/node_modules/**', '**/.git/**']` to
   short-circuit traversal. Post-filter via `shouldIgnore`
   remains authoritative.

5 new tests:
- 8.3 short-name regex Windows / POSIX split
- readBytes truncates 2048-byte file to 1024 with maxBytes
- readBytes throws file_too_large only above hard cap
- edit() preserves UTF-8 BOM round-trip
- glob prunes node_modules and .git

442/442 serve tests pass; typecheck + eslint clean.

Stack: 7b0db4ca81ada4efd7a46b38e821911cb8e5468342ebd9e787f4f30d → THIS

🤖 Generated with [Qwen Code](https://github.com/QwenLM/qwen-code)

* fix(serve/fs): close 10 review-round-8/9 findings (#4250)

Two more review passes (gpt-5.5 + DeepSeek + wenshao) flagged 13
items; 10 are real fixes, 3 are reviewer-stale-snapshot or
already-tracked. Stack on round-7.

Critical (5):

1. paths.ts symlink-escape hint embedded the symlink target
   (gpt-5.5) — Privacy regression sibling to round-6 audit
   `message` gate. `recordDenied` always forwards `hint` into
   `fs.denied` even with `QWEN_AUDIT_RAW_PATHS` off; the hint
   `'symlink points to /Users/alice/secret'` leaks the
   attacker's intended exfiltration path through audit. Hint is
   now path-free; operators wanting the resolved target enable
   `QWEN_AUDIT_RAW_PATHS=1` and read it from `relPath` /
   `message`.

2. paths.ts dangling-symlink chain discarded its verified
   canonical (DeepSeek) — After the multi-hop walk validated
   `cursor → canonicalTarget` was inside the workspace, the
   code fell through to `findExistingAncestor(absolute)`,
   re-walking from the original input and discarding the
   verified result. An attacker swapping an intermediate
   symlink between the verification and the re-walk could
   produce a different canonical than the one validated. The
   verified `canonicalTarget` is now captured in
   `symlinkResolvedCanonical` and used directly; the
   `findExistingAncestor(absolute)` fallthrough only runs when
   no symlink was traversed.

3. workspaceFileSystem.ts readBytes missing post-read size
   check (DeepSeek) — Same TOCTOU shape as `readText`'s
   round-6 fix. The pre-stat `enforceReadBytesSize` sees the
   size at stat time; a concurrent appender keeps the same
   inode but grows the file past the cap before
   `fsp.readFile` returns. `assertInodeStableAfterRead`
   catches inode changes but not same-inode growth. Added a
   post-read `buf.length > MAX_READ_BYTES` check matching
   `readText`'s defense-in-depth pattern.

4. errors.ts wrapAsFsError default = permission_denied
   (DeepSeek) — Misclassified non-errno errors (`TypeError`,
   programmer-error throws, native module exceptions) as
   security denials, paging security oncall for what should
   be a developer ticket. New `internal_error` kind (HTTP
   500) is the new default; `permission_denied` reserved for
   actual `EACCES`/`EPERM`.

5. audit.ts AuditContext.sessionId not forwarded to
   BridgeEvent (DeepSeek) — Multi-session daemons couldn't
   trace audit events back to the session that triggered
   them. `originatorClientId` identifies the client, not the
   session. Added optional `sessionId` field to both
   `FsAccessAuditPayload` and `FsDeniedAuditPayload`,
   forwarded from `ctx.sessionId` when present.

Improvements (4):

6. workspaceFileSystem.ts glob cwd realpath redundant when
   cwd === boundWorkspace (wenshao) — `boundWorkspace` is
   already canonicalized by the factory (`realpathSync.native`
   at build time), so calling `fsp.realpath` per-request when
   no `opts.cwd` was supplied is a redundant async syscall.
   Added a short-circuit.

7. workspaceFileSystem.ts kindFromStatLike JSDoc orphaned
   (wenshao) — Inserting `assertNotSymlinkBeforeWrite` between
   the JSDoc and `kindFromStatLike` left the doc floating
   above the wrong function. IDE hovers showed the wrong
   description. Moved the doc back to its function.

8. workspaceFileSystem.ts shared mutable Ignore object
   (DeepSeek) — `createWorkspaceFileSystemFactory` builds one
   `Ignore` instance and shares it across every
   `WorkspaceFileSystemImpl` returned by `forRequest()`.
   `Ignore.add(): this` is a public mutator. A future
   "per-session ignore rules" feature calling `.add()` from a
   request handler would silently corrupt all concurrent
   sessions. `Object.freeze` turns the cross-request mutation
   into a `TypeError` rather than a silent leak.

9. server.ts createDefaultFsAuditEmit one-shot warned
   (DeepSeek) — Permanent silent no-op after the first event;
   only logged the event `type` with no pathHash / errorKind /
   intent. If PR 19 forgets the real factory injection, every
   write 403s and audit is silent past the first warning —
   exactly the regression the warning exists to surface.
   Periodic warning (every 100th drop) + first-event context
   (errorKind, intent, pathHash) makes the regression
   actionable in production logs.

Cleanup (1):

10. workspaceFileSystem.ts safeUtf8Truncate dead code
    (DeepSeek noted as "off-by-one") — The lead-byte
    seqLen-check block was dead code: `subarray(0, end)`
    already excludes the leading byte at `end`, so no
    further adjustment is ever needed. Removed the block;
    function is now 4 lines and still produces a valid
    codepoint prefix. Reviewer's suggested fix
    (`buf[end-1] → buf[end]`) was technically correct but
    redundant with the subarray cut.

Already-fixed (3 reviewer-stale-snapshot, reply + resolve):

- writeText pre-write symlink guard — fixed in 7f4f30d
- edit() read-modify-write race — already deferred to PR 20
  atomic-via-temp follow-up
- glob maxResults walk-bound — already follow-up #5

3 new tests + 2 updated:
- wrapAsFsError unknown errno → internal_error (default change)
- internal_error has HTTP 500
- non-Error throwables → internal_error (not permission_denied)
- readBytes post-stat growth → file_too_large
- existing wrapAsFsError test updated for new default

445/445 serve tests pass; typecheck + eslint clean.

Stack: 7b0db4ca81ada4efd7a46b38e821911cb8e5468342ebd9e787f4f30d1dc9d22 → THIS

🤖 Generated with [Qwen Code](https://github.com/QwenLM/qwen-code)

* fix(serve/fs): close 3 review-round-10 findings (#4250)

Round-10 review (wenshao) flagged 4 items, all marked
non-blocking by the reviewer. 3 are landed in-PR; 1 (glob
withFileTypes optimization) is moved to issue #4175 follow-ups
since the reviewer themselves recommended "test it on a 100K-file
workspace after PR 19 lands."

1. canonicalizeWorkspace docstring (paths.ts) — Documentation.
   The earlier FIXME warned about sync syscall blocking the
   event loop without mentioning the `CANONICAL_BOUND_CACHE`
   added in 1dc9d22 brings steady-state cost to zero. Future
   reviewers reading the FIXME again would re-flag the
   already-mitigated concern. Added a paragraph noting cache hit
   rate = 100% under the `1 daemon = 1 workspace` model so
   per-request blocking only happens at boot or on fresh
   workspace values (e.g. tests).

2. enforceReadBytesSize dead `maxBytes` parameter (policy.ts) —
   Round-7 changed `readBytes` to use post-read truncation for
   the soft window cap, leaving the function's `maxBytes`
   parameter unused at the only callsite. The
   `Math.min(maxBytes, MAX_READ_BYTES)` clamp branch became dead
   code. Reviewer's option 1: tighten the signature to
   `enforceReadBytesSize(fileBytes: number): void`. Done — the
   function is now purely the hard-cap enforcer its name
   implies; soft-window truncation lives in the orchestrator's
   `buf.subarray(0, opts.maxBytes)` post-read step where it's
   visible alongside the cap check it complements.

3. relForAudit cross-drive sentinel (audit.ts) — Windows-only
   privacy edge case. `path.relative('C:\\ws', 'D:\\evil')`
   returns `'D:\\evil'` (an absolute path) because Win32 can't
   express cross-drive relatives. Even when raw-paths mode is
   ENABLED, the audit `relPath` field would carry the off-drive
   absolute path, exposing the attacker's drive letter +
   directory. Added a `path.isAbsolute(rel)` post-check that
   substitutes a `<cross-drive>` sentinel — audit consumers see
   the cross-drive case distinctly without leaking the offending
   path. This was previously P2 deferred in PR 18's description
   ("Windows cross-drive path.relative"); reviewer's "few lines
   beats deferring" assessment was right.

Tracked as follow-up (not in this commit):

4. glob withFileTypes optimization — Replace per-hit `lstat`
   (line ~664) with `glob` v10's `withFileTypes: true` so each
   hit comes back as a `Path` object with `isDirectory()` /
   `isFile()` / `isSymbolicLink()` already available. Saves N
   syscalls in large workspaces. Non-trivial restructure (return
   type changes from `string[]` to `Path[]`). Reviewer
   themselves marked "[performance / non-blocking]" and said
   "test it on a 100K-file workspace after PR 19 lands so we
   know whether it's worth it." Added to issue #4175 body's
   Post-PR-18 hardening follow-ups.

446/446 serve tests pass; typecheck + eslint clean.

Stack: 7b0db4ca81ada4efd7a46b38e821911cb8e5468342ebd9e787f4f30d1dc9d22a33d459 → THIS

🤖 Generated with [Qwen Code](https://github.com/QwenLM/qwen-code)
@yiliang114 yiliang114 added the skip-changelog Exclude from release notes label May 20, 2026
xaelistic pushed a commit to xaelistic/qwen-code that referenced this pull request Jun 7, 2026
Co-authored-by: matt korwel <matt.korwel@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

skip-changelog Exclude from release notes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants