Skip to content

feat(serve): prompt absolute deadline + SSE writer idle timeout (#4514 T2.9)#4530

Merged
doudouOUC merged 1 commit into
daemon_mode_b_mainfrom
feat/serve-t2.9-prompt-deadline-writer-idle-timeout
May 26, 2026
Merged

feat(serve): prompt absolute deadline + SSE writer idle timeout (#4514 T2.9)#4530
doudouOUC merged 1 commit into
daemon_mode_b_mainfrom
feat/serve-t2.9-prompt-deadline-writer-idle-timeout

Conversation

@doudouOUC

@doudouOUC doudouOUC commented May 26, 2026

Copy link
Copy Markdown
Collaborator

Summary

Closes T2.9 from issue #4514. Two opt-in flags that close the long-running / remote-deployment gaps the 15s heartbeat + AbortSignal don't cover. Both default off → single-user loopback workflows bit-for-bit unchanged.

  • --prompt-deadline-ms <n> (env QWEN_SERVE_PROMPT_DEADLINE_MS) — server-side wallclock cap on POST /session/:id/prompt. On expiry, daemon aborts the AbortController and returns 504 with errorKind: 'prompt_deadline_exceeded'. Per-prompt body field deadlineMs can SHORTEN below the cap but never EXTEND. Closes the FIXME(stage-2) at httpAcpBridge.ts about a buggy agent holding the FIFO open indefinitely.
  • --writer-idle-timeout-ms <n> (env QWEN_SERVE_WRITER_IDLE_TIMEOUT_MS) — per-SSE-connection idle deadline. When no write has flushed for n ms (heartbeat or real event), daemon emits a terminal client_evicted frame with reason: 'writer_idle_timeout' and closes. Closes the "Stage 2 may add" gap at the SSE handler.

Conditional capability tags prompt_absolute_deadline / writer_idle_timeout appear only when configured, so SDK consumers pre-flight before sending deadlineMs (silently dropped on older daemons).

Design rationale

  • Why Math.min cap, not absolute server enforcement: operators stay the upper bound. A client can ask for a tighter deadline (e.g. an IDE wanting to bail out after 30s on a 5-min server cap) but cannot loosen one a deployment has chosen.
  • Why direct res.write in the idle path (not through the writeChain): the chain may already be stuck on the very drain we're trying to detect. Writing directly gives the terminal frame a chance to land; if it can't, the next res.end() tears the socket down.
  • Why a second timer alongside the 15s heartbeat: heartbeat = "try to ping every 15s"; idle timeout = "if no flush SUCCEEDED for n ms, force-evict." A writerIdleTimeoutMs < 15000 is documented as a no-op because the next heartbeat refresh races ahead.
  • Why kept off by default: preserves the pre-PR contract bit-for-bit. SDKs that don't pre-flight the new tags see the same surface they did before.

Files touched

Package Files What
acp-bridge src/status.ts, src/status.test.ts Add 2 error kinds; update the ordering-pin test
sdk-typescript src/daemon/types.ts, src/daemon/DaemonClient.ts, test/unit/daemon-public-surface.test.ts Mirror kinds in DAEMON_ERROR_KINDS; add deadlineMs to PromptRequest; drift-insurance test
cli src/commands/serve.ts, src/serve/runQwenServe.ts, src/serve/types.ts, src/serve/capabilities.ts, src/serve/server.ts, src/serve/server.test.ts yargs flags + env fallback; ServeOptions fields; conditional capability tags; deadline timer in prompt handler; idle timer in SSE handler; 13 new test cases
docs docs/users/qwen-serve.md Document both flags + update the "phantom SSE connections" known-gap callout

Test plan

  • npm run typecheck clean across cli + sdk-typescript + acp-bridge
  • packages/cli/src/serve/server.test.ts — 243/243 pass (13 new T2.9 cases)
  • packages/acp-bridge — 44/44 pass (ordering-pin test updated)
  • packages/sdk-typescript — 422/422 pass (drift-insurance test added)
  • CI lint/format/build
  • Manual smoke on a built qwen serve binary (deadline path):
    • qwen serve --port 18280 --prompt-deadline-ms 5000 → send a prompt that runs > 5s → expect 504 with errorKind
  • Manual smoke (idle path):
    • qwen serve --port 18280 --writer-idle-timeout-ms 30000 → hold a slow SSE consumer → expect close after ~30s with client_evicted{reason: 'writer_idle_timeout'}

Backward compatibility

Both flags default unset. Existing tests pass without changes. SDK consumers ignoring the new capability tags see the same wire contract as before — a missing prompt_absolute_deadline tag means the request deadlineMs field is silently dropped, matching the protocol's "additive to v=1" rule.

Tracking issue: #4514

🤖 Generated with Qwen Code


📝 描述准确性更新(2026-05-31,作者自查)

更正:命中 deadline 实际为非阻塞 202 + SSE errorKind,而非硬 504;bridge 侧绝对 deadline 仍未实现(per-session FIFO 占用未根除),route 级 race 只保证快速回客户端。

@github-actions

Copy link
Copy Markdown
Contributor

📋 Review Summary

This PR implements issue #4514 T2.9, adding two opt-in flags (--prompt-deadline-ms and --writer-idle-timeout-ms) to close long-running/remote-deployment gaps that the existing 15s heartbeat + AbortSignal don't cover. The implementation is well-designed with careful attention to backward compatibility, capability advertising, and proper error handling. Both flags default to off, preserving existing behavior for single-user loopback workflows.

🔍 General Feedback

  • Strong design rationale: The documentation clearly explains why each design decision was made (Math.min capping, direct res.write in idle path, separate timer alongside heartbeat, opt-in by default)
  • Consistent error taxonomy: New error kinds (prompt_deadline_exceeded, writer_idle_timeout) follow the existing pattern and are mirrored across acp-bridge, CLI, and SDK
  • Good capability advertising: Conditional capability tags (prompt_absolute_deadline, writer_idle_timeout) allow SDK consumers to feature-detect before relying on new behavior
  • Comprehensive test coverage: 13 new test cases in server.test.ts, plus updates to acp-bridge and SDK tests
  • Excellent documentation: The qwen-serve.md updates clearly explain the new flags with a helpful comparison table

🎯 Specific Feedback

🟢 Medium

  • File: packages/cli/src/serve/server.ts (prompt handler) - The resolvePromptDeadlineMs function is exported for testing, which is good, but consider adding a unit test file specifically for this utility function to ensure the capping logic is thoroughly tested edge cases (undefined serverMs, undefined requestMs, zero values, NaN, negative values, etc.)

  • File: packages/cli/src/serve/server.ts (SSE handler) - The idle timer polling interval calculation (Math.floor(writerIdleTimeoutMs / 4) bounded by [250ms, 5s]) is reasonable, but consider documenting why 1/4 of the budget was chosen as the polling frequency. A brief comment about the trade-off between detection latency and CPU overhead would help future maintainers.

  • File: packages/cli/src/commands/serve.ts - The new CLI flags should be added to the yargs builder. Based on the diff, I don't see the actual flag definitions in the portion I reviewed. Ensure the flags are properly documented with:

    • type: 'number'
    • Validation for positive integers
    • Clear descriptions matching the table in qwen-serve.md
    • Environment variable fallbacks (QWEN_SERVE_PROMPT_DEADLINE_MS, QWEN_SERVE_WRITER_IDLE_TIMEOUT_MS)

🔵 Low

  • File: packages/cli/src/serve/server.ts - The sendDeadlineResponseIfFired function checks !res.writableEnded before sending the 504 response, which is correct. Consider adding a brief comment explaining why this guard is necessary (prevents writing to a closed response, which could happen if the success path already sent a response).

  • File: packages/cli/src/serve/server.ts - The idle timeout handler writes directly via res.write() bypassing writeWithBackpressure with a good comment explaining why. Consider extracting this terminal frame write into a small helper function (e.g., writeTerminalFrame) that could be reused if similar direct-write scenarios arise in the future.

  • File: packages/sdk-typescript/src/daemon/DaemonClient.ts - The deadlineMs field is added to PromptRequest with good documentation about capability pre-flight. Consider adding a type-level constraint (e.g., deadlineMs?: number | undefined with a JSDoc @minimum 1 or similar) to encourage consumers to use positive integers, though runtime validation on the server side is the primary defense.

  • File: docs/users/qwen-serve.md - The documentation mentions "values < 15000 are effectively no-ops" for the writer idle timeout. Consider making this more explicit by either:

    1. Adding server-side validation that rejects values < 15000 with a clear error message, or
    2. Documenting the recommended minimum (e.g., "Recommended minimum: 60000ms (1 minute) to avoid racing the heartbeat")

✅ Highlights

  • Excellent backward compatibility: Both flags default to unset/off, preserving bit-for-bit the existing contract. SDK consumers that don't pre-flight the new capability tags see the same wire contract as before.

  • Thoughtful error response design: The PromptDeadlineExceededError class carries the deadlineMs value, and the 504 response includes both code and errorKind fields for easy SDK branching.

  • Good separation of concerns: The resolvePromptDeadlineMs function is extracted and exported for unit testing, demonstrating good testability practices.

  • Proper cleanup patterns: Both the deadline timer and idle timer are properly cleaned up in finally blocks and response close handlers, with unref() calls to prevent blocking shutdown.

  • Comprehensive capability advertising: The conditional capability tags follow the established pattern from mcp_guardrails and other features, making it easy for SDK consumers to adopt incrementally.

  • Strong security posture: The deadline validation rejects malformed values with a 400 response before touching the AbortController, and the idle timeout writes directly to give the terminal frame a chance to land even when the write chain is stuck.

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 two opt-in reliability controls to qwen serve for remote/long-running deployments: a server-enforced prompt wallclock deadline and an SSE writer idle-timeout, including capability tags for feature detection and cross-package error-kind mirroring (acp-bridge ↔ SDK).

Changes:

  • Add --prompt-deadline-ms / QWEN_SERVE_PROMPT_DEADLINE_MS and --writer-idle-timeout-ms / QWEN_SERVE_WRITER_IDLE_TIMEOUT_MS plumbing (CLI → ServeOptions → server behavior) and conditional capability tags.
  • Extend serve/SDK error-kind taxonomies (prompt_deadline_exceeded, writer_idle_timeout) and add deadlineMs to the SDK PromptRequest type.
  • Add/extend tests and docs to describe and lock the new behavior/capabilities.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
packages/sdk-typescript/test/unit/daemon-public-surface.test.ts Adds drift-insurance assertions for new DAEMON_ERROR_KINDS entries.
packages/sdk-typescript/src/daemon/types.ts Appends new daemon error kinds mirroring serve taxonomy.
packages/sdk-typescript/src/daemon/DaemonClient.ts Adds optional deadlineMs field to PromptRequest typing/docs.
packages/cli/src/serve/types.ts Introduces promptDeadlineMs and writerIdleTimeoutMs on ServeOptions (with docs).
packages/cli/src/serve/server.ts Implements prompt deadline abort/reply scaffolding and SSE writer idle-timeout eviction.
packages/cli/src/serve/server.test.ts Adds unit/integration tests covering capability advertising and timer behaviors.
packages/cli/src/serve/runQwenServe.ts Parses env fallbacks + validates the new numeric options at boot.
packages/cli/src/serve/capabilities.ts Registers new capability tags and predicates for conditional advertisement.
packages/cli/src/commands/serve.ts Adds yargs options/help text for new flags and passes them into runQwenServe.
packages/acp-bridge/src/status.ts Appends new serve error kinds for shared taxonomy.
packages/acp-bridge/src/status.test.ts Updates ordering-pin test to include the new kinds.
docs/users/qwen-serve.md Documents new flags and updates the known-gap section for phantom SSE connections.

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

Comment thread packages/cli/src/serve/server.ts Outdated
Comment thread packages/cli/src/serve/server.ts Outdated
Comment thread packages/cli/src/serve/types.ts Outdated
Comment thread packages/cli/src/commands/serve.ts Outdated
Comment thread docs/users/qwen-serve.md Outdated
doudouOUC added a commit that referenced this pull request May 26, 2026
Follow-ups surfaced by an independent simplify-review pass on the
initial T2.9 commit. No behavior change; tests still 243/243.

- server.ts: gate per-chunk `lastWriteAt = Date.now()` behind a
  `trackWriterIdle` boolean derived once from `opts.writerIdleTimeoutMs`.
  Skips the timestamp on every SSE frame when the flag is unset (the
  default), which matters for chatty tool-output streams (hundreds-
  to-thousands of writes per session).
- runQwenServe.ts: extract `isPositiveIntegerMs` predicate; collapse
  the two new option-validation blocks and the env parser onto one
  source of truth.
- server.test.ts: extract `abortableBridgePromptImpl()` helper; the
  3 new T2.9 prompt-deadline tests had verbatim copies of the
  "Promise that resolves on abort" snippet.
- server.ts + capabilities.ts: trim two repetitive call-site
  comments + one speculative "hypothetical future sentinel" comment
  whose value was already covered by the helper JSDoc / boot-time
  validation.

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

github-actions Bot commented May 26, 2026

Copy link
Copy Markdown
Contributor

Code Coverage Summary

Package Lines Statements Functions Branches
CLI 77.39% 77.39% 80.27% 79.97%
Core 80.32% 80.32% 82.57% 83.02%
CLI Package - Full Text Report
-------------------|---------|----------|---------|---------|-------------------
File               | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
-------------------|---------|----------|---------|---------|-------------------
All files          |   77.39 |    79.97 |   80.27 |   77.39 |                   
 src               |   75.52 |    68.65 |   78.94 |   75.52 |                   
  gemini.tsx       |   69.03 |    66.15 |   77.77 |   69.03 | ...43,960-963,975 
  ...ractiveCli.ts |   78.73 |    66.89 |   73.33 |   78.73 | ...1284-1285,1321 
  ...liCommands.ts |    74.9 |     75.6 |     100 |    74.9 | ...41-265,290,391 
  ...ActiveAuth.ts |     100 |     87.5 |     100 |     100 | 66-80             
 ...cp-integration |   61.97 |    65.24 |   78.12 |   61.97 |                   
  acpAgent.ts      |   63.32 |    65.35 |   83.05 |   63.32 | ...2112,2126-2134 
  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 |   75.88 |    72.05 |   86.25 |   75.88 |                   
  ...ryReplayer.ts |   67.34 |     75.6 |   81.81 |   67.34 | ...54-269,282-283 
  Session.ts       |   74.93 |    70.81 |   88.46 |   74.93 | ...2658,2664-2667 
  ...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/commands      |   43.58 |    85.71 |   43.47 |   43.58 |                   
  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         |     7.3 |      100 |       0 |     7.3 | ...58-184,186-307 
 ...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.89 |    88.52 |   81.81 |   84.89 |                   
  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         |   65.06 |    31.25 |     100 |   65.06 | ...85,87-91,93-97 
 ...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.56 |    84.55 |   89.36 |   92.56 |                   
  auth.ts          |   86.98 |    80.32 |     100 |   86.98 | ...26-227,243-244 
  config.ts        |   86.68 |    83.49 |   81.48 |   86.68 | ...1935,1937-1945 
  keyBindings.ts   |   96.55 |       50 |     100 |   96.55 | 193-196           
  ...ngsAdapter.ts |     100 |    94.11 |     100 |     100 | 64                
  ...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 | ...90-591,594-595 
 ...active/control |   76.79 |    88.23 |      80 |   76.79 |                   
  ...rolContext.ts |    6.89 |        0 |       0 |    6.89 | 50-86             
  ...Dispatcher.ts |   91.66 |    91.83 |   88.88 |   91.66 | ...54-372,388,391 
  ...rolService.ts |       8 |        0 |       0 |       8 | 46-179            
 ...ol/controllers |   27.25 |    35.71 |   36.66 |   27.25 |                   
  ...Controller.ts |   36.97 |       80 |      80 |   36.97 | ...15-117,127-210 
  ...Controller.ts |       0 |        0 |       0 |       0 | 1-56              
  ...Controller.ts |    33.7 |    34.48 |   44.44 |    33.7 | ...57-466,481-486 
  ...Controller.ts |   14.06 |      100 |       0 |   14.06 | ...82-117,130-133 
  ...Controller.ts |   21.97 |    28.57 |   27.27 |   21.97 | ...39-451,460-489 
 .../control/types |       0 |        0 |       0 |       0 |                   
  serviceAPIs.ts   |       0 |        0 |       0 |       0 | 1                 
 ...Interactive/io |   98.01 |    93.77 |   95.23 |   98.01 |                   
  ...putAdapter.ts |   97.89 |    92.82 |   98.07 |   97.89 | ...1303,1398-1399 
  ...putAdapter.ts |      96 |     90.9 |   85.71 |      96 | 51-52             
  ...nputReader.ts |     100 |    94.73 |     100 |     100 | 67                
  ...putAdapter.ts |   98.38 |      100 |   90.47 |   98.38 | 83-84,124-125     
  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         |   80.17 |    79.68 |   93.68 |   80.17 |                   
  auth.ts          |   88.49 |    88.63 |     100 |   88.49 | ...49-150,153-155 
  capabilities.ts  |     100 |    93.33 |     100 |     100 | 304               
  ...usProvider.ts |   67.01 |    51.42 |     100 |   67.01 | ...40-245,278-286 
  debugMode.ts     |     100 |      100 |     100 |     100 |                   
  demo.ts          |     100 |      100 |     100 |     100 |                   
  envSnapshot.ts   |    92.3 |       84 |     100 |    92.3 | 108-111,170-177   
  eventBus.ts      |     100 |      100 |     100 |     100 |                   
  httpAcpBridge.ts |   79.62 |    78.84 |   96.38 |   79.62 | ...4253,4284-4325 
  ...oryChannel.ts |     100 |      100 |     100 |     100 |                   
  index.ts         |       0 |        0 |       0 |       0 | 1-106             
  loopbackBinds.ts |     100 |      100 |     100 |     100 |                   
  runQwenServe.ts  |   78.15 |    90.62 |   66.66 |   78.15 | ...85-801,826-828 
  server.ts        |   87.74 |    84.26 |   94.59 |   87.74 | ...2752,2817-2826 
  status.ts        |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
  ...paceAgents.ts |   64.87 |    70.45 |    90.9 |   64.87 | ...1306,1316-1326 
  ...paceMemory.ts |   87.13 |    78.46 |     100 |   87.13 | ...54-361,421-428 
 src/serve/auth    |   86.54 |    78.75 |   93.75 |   86.54 |                   
  deviceFlow.ts    |   96.33 |    79.51 |    97.5 |   96.33 | ...1526,1630,1700 
  ...owProvider.ts |   45.23 |    74.07 |      75 |   45.23 | ...90-359,375,379 
 src/serve/fs      |   84.85 |    79.75 |     100 |   84.85 |                   
  audit.ts         |     100 |    96.15 |     100 |     100 | 201               
  errors.ts        |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  paths.ts         |   77.82 |    77.08 |     100 |   77.82 | ...64,493-497,510 
  policy.ts        |   90.32 |    89.18 |     100 |   90.32 | 142-150           
  ...FileSystem.ts |   83.55 |    76.22 |     100 |   83.55 | ...1859,1886-1887 
 src/serve/routes  |   89.41 |       70 |     100 |   89.41 |                   
  ...ceFileRead.ts |   94.41 |    76.92 |     100 |   94.41 | ...28-329,390-392 
  ...eFileWrite.ts |    82.1 |    60.52 |     100 |    82.1 | ...42-244,247-249 
 src/services      |   91.66 |    91.21 |   97.56 |   91.66 |                   
  ...mandLoader.ts |     100 |    93.75 |     100 |     100 | 92                
  ...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.34 |    84.84 |     100 |   97.34 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  tipHistory.ts    |   92.45 |       70 |     100 |   92.45 | ...22,144,151,160 
  tipRegistry.ts   |     100 |      100 |     100 |     100 |                   
  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            |   65.51 |    73.04 |   60.34 |   65.51 |                   
  App.tsx          |     100 |      100 |     100 |     100 |                   
  AppContainer.tsx |   63.66 |     64.7 |      50 |   63.66 | ...3151,3155-3159 
  ...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        |      60 |      100 |   35.29 |      60 | ...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       |   52.97 |    51.21 |   42.42 |   52.97 |                   
  AuthDialog.tsx   |   62.87 |     42.1 |   18.18 |   62.87 | ...03,310-332,336 
  ...nProgress.tsx |       0 |        0 |       0 |       0 | 1-64              
  ...etupSteps.tsx |    39.4 |       32 |   38.46 |    39.4 | ...68,471,477,480 
  useAuth.ts       |   94.55 |    73.52 |     100 |   94.55 | ...19-220,239-245 
  ...rSetupFlow.ts |   43.45 |    33.33 |      50 |   43.45 | ...68-389,406-449 
 src/ui/commands   |   75.97 |    81.52 |   83.82 |   75.97 |                   
  aboutCommand.ts  |     100 |      100 |     100 |     100 |                   
  agentsCommand.ts |   83.78 |      100 |      60 |   83.78 | 30-32,42-44       
  ...odeCommand.ts |   89.04 |    81.25 |     100 |   89.04 | 91-92,94-99       
  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 |   65.06 |    67.24 |   84.61 |   65.06 | ...39-574,585-586 
  copyCommand.ts   |   98.28 |    94.89 |     100 |   98.28 | ...80,280,321,327 
  deleteCommand.ts |     100 |      100 |     100 |     100 |                   
  diffCommand.ts   |     100 |     87.5 |     100 |     100 | ...61,224-225,238 
  ...ryCommand.tsx |   76.87 |    79.03 |   88.88 |   76.87 | ...59-264,318-326 
  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 |   49.33 |     90.9 |   63.63 |   49.33 | ...06-110,163-215 
  forgetCommand.ts |   26.82 |      100 |      50 |   26.82 | 18-51             
  goalCommand.ts   |   91.41 |    84.44 |      90 |   91.41 | ...86-189,201-204 
  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        
  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 |   37.06 |       50 |      50 |   37.06 | ...99-115,118-145 
  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 |   62.34 |    75.09 |   64.85 |   62.34 |                   
  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.06 |       75 |     100 |   89.06 | 37,39-44,46       
  ...odeDialog.tsx |     9.7 |      100 |       0 |     9.7 | 35-47,50-182      
  AsciiArt.ts      |     100 |      100 |     100 |     100 |                   
  ...Indicator.tsx |   13.04 |      100 |       0 |   13.04 | 18-61             
  ...TextInput.tsx |   77.01 |       76 |     100 |   77.01 | ...20,234-236,263 
  Composer.tsx     |    81.6 |     64.7 |     100 |    81.6 | ...90,108,160,173 
  ...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 |   11.98 |      100 |       0 |   11.98 | 65-508            
  DiffDialog.tsx   |    2.47 |      100 |       0 |    2.47 | 68-732            
  ...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       |   76.59 |    48.64 |     100 |   76.59 | ...35-136,175-180 
  ...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 |       90 |     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  |   80.76 |    79.62 |   83.33 |   80.76 | ...1456,1588,1638 
  ...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 
  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 |   83.66 |    72.13 |     100 |   83.66 | ...96,402,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.27 |    71.16 |      75 |   66.27 | ...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 | ...47-149,156-158 
  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            
  ...xitDialog.tsx |   80.36 |    43.47 |      60 |   80.36 | ...24-238,248-251 
 ...nts/agent-view |   38.31 |    70.83 |   36.36 |   38.31 |                   
  ...atContent.tsx |    8.79 |      100 |       0 |    8.79 | 53-265,271-273    
  ...tChatView.tsx |   21.05 |      100 |       0 |   21.05 | 21-39             
  ...tComposer.tsx |   10.28 |      100 |       0 |   10.28 | 58-311            
  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,95-103,121 
  ...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.6 |    82.71 |   85.29 |    75.6 |                   
  ...sksDialog.tsx |   70.99 |    80.58 |   76.19 |   70.99 | ...1120,1196-1198 
  ...TasksPill.tsx |   63.75 |    86.95 |     100 |   63.75 | 44,86-106,114-122 
  ...gentPanel.tsx |    97.4 |    86.31 |     100 |    97.4 | 123,434-438       
 ...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 | 20-131            
  ...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 |    83.1 |    80.33 |    75.6 |    83.1 |                   
  ...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 |   76.31 |     42.1 |   66.66 |   76.31 | ...99,101,124,155 
  ...tsDisplay.tsx |    95.1 |    88.05 |     100 |    95.1 | ...29,131,164-169 
  ...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 |   82.63 |    92.85 |     100 |   82.63 | ...85-412,434-449 
  ToolMessage.tsx  |   88.84 |    75.71 |    92.3 |   88.84 | ...44-749,776-778 
 ...ponents/shared |   86.23 |    79.33 |   95.94 |   86.23 |                   
  ...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.77 |    48.78 |      80 |   77.77 | ...14-218,230-236 
  ...apsedTime.tsx |     100 |      100 |     100 |     100 |                   
  ...Indicator.tsx |     100 |      100 |     100 |     100 |                   
  text-buffer.ts   |   85.38 |       80 |   97.77 |   85.38 | ...2437,2535-2536 
  ...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 |   70.21 |    67.32 |    64.7 |   70.21 |                   
  ContextUsage.tsx |   70.88 |    63.88 |      80 |   70.88 | ...20-426,463-557 
  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.45 |    77.46 |   80.35 |   77.45 |                   
  ...ewContext.tsx |    64.7 |    85.71 |      50 |    64.7 | ...22-225,231-241 
  AppContext.tsx   |      80 |       50 |     100 |      80 | 19-20             
  ...ewContext.tsx |   93.03 |    64.28 |      50 |   93.03 | ...31-232,259-263 
  ...deContext.tsx |     100 |      100 |     100 |     100 |                   
  ...igContext.tsx |   81.81 |       50 |     100 |   81.81 | 15-16             
  ...ssContext.tsx |   82.31 |    82.84 |     100 |   82.31 | ...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 | 118-119           
  ...teContext.tsx |   86.66 |       50 |     100 |   86.66 | 194-195           
  ...deContext.tsx |   76.08 |    72.72 |     100 |   76.08 | 47-48,52-59,77-78 
 src/ui/daemon     |   90.76 |    73.73 |   95.45 |   90.76 |                   
  ...TuiAdapter.ts |   90.76 |    73.73 |   95.45 |   90.76 | ...53,771-772,858 
 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.18 |    82.19 |   86.87 |   82.18 |                   
  ...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.81 |    89.09 |     100 |   92.81 | ...86-187,224-227 
  ...ifications.ts |   92.07 |    96.29 |     100 |   92.07 | 116-124           
  ...tIndicator.ts |   83.49 |    70.96 |     100 |   83.49 | ...60,168,170-178 
  ...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.96 |    83.87 |     100 |   95.96 | ...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 |   77.27 |       50 |     100 |   77.27 | ...2,75-79,93-101 
  ...eteCommand.ts |   78.53 |    88.57 |     100 |   78.53 | ...96-104,112-113 
  ...ialogClose.ts |   13.33 |      100 |     100 |   13.33 | 82-173            
  useDiffData.ts   |   11.62 |      100 |       0 |   11.62 | 44-87             
  ...oublePress.ts |   53.12 |       75 |     100 |   53.12 | 33-35,41-54       
  ...orSettings.ts |     100 |      100 |     100 |     100 |                   
  ...Completion.ts |   99.12 |    97.67 |     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 |   57.89 |    71.42 |      50 |   57.89 | ...66-168,190-191 
  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 |   78.06 |    75.47 |   91.66 |   78.06 | ...2573,2586-2594 
  ...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       
  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 
  ...rredEditor.ts |   58.33 |    22.22 |     100 |   58.33 | 23-27,29-33       
  ...derUpdates.ts |   86.49 |    77.96 |    90.9 |   86.49 | ...26,288-300,348 
  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.87 |    90.35 |     100 |   92.87 | ...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.7 |    85.41 |   94.73 |    82.7 | ...69-671,679-715 
  ...tateAndRef.ts |     100 |      100 |     100 |     100 |                   
  useStatusLine.ts |   96.09 |    90.37 |     100 |   96.09 | ...62-365,450-457 
  ...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 |                   
  useTurnDiffs.ts  |   95.12 |    78.57 |     100 |   95.12 | 133-134,156-157   
  ...elcomeBack.ts |   87.36 |     90.9 |     100 |   87.36 | ...,94-96,114-115 
  ...reeSession.ts |   93.75 |       70 |     100 |   93.75 | 44-45,87          
  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             
 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 |   14.28 |     100 |                   
  ...eractiveUi.ts |     100 |      100 |   14.28 |     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.98 |       83 |   92.61 |   83.98 |                   
  ...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 | 35,57             
  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.73 |    87.75 |     100 |   94.73 | ...49,434,438-439 
  ...mConstants.ts |     100 |      100 |     100 |     100 |                   
  restoreGoal.ts   |   98.98 |    97.05 |     100 |   98.98 | 98                
  ...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.61 |    94.84 |   92.85 |   97.61 | ...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         |   77.21 |    90.21 |   94.07 |   77.21 |                   
  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  |   70.98 |       75 |     100 |   70.98 | ...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        |   90.85 |    96.36 |    92.3 |   90.85 | 69-70,298-310     
  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           
  ...tyWarnings.ts |     100 |      100 |     100 |     100 |                   
  ...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    
  runBudget.ts     |   99.35 |    96.77 |     100 |   99.35 | 122               
  sandbox.ts       |       0 |        0 |       0 |       0 | 1-1047            
  sessionPaths.ts  |   90.84 |    90.56 |     100 |   90.84 | ...81-182,185-186 
  settingsUtils.ts |   82.51 |    91.66 |   89.74 |   82.51 | ...76-694,701-709 
  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    |   95.12 |    89.06 |     100 |   95.12 | ...43-244,249-253 
  ...InfoFields.ts |    87.5 |       65 |     100 |    87.5 | ...24-125,146-147 
  ...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                
  ...ingHandler.ts |     100 |      100 |     100 |     100 |                   
  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          |   80.32 |    83.02 |   82.57 |   80.32 |                   
 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        |   88.06 |    79.77 |   92.13 |   88.06 |                   
  ...transcript.ts |   92.25 |    85.71 |     100 |   92.25 | ...87,306-307,438 
  ...ent-resume.ts |    82.8 |    71.63 |   77.41 |    82.8 | ...1059-1063,1066 
  ...ound-tasks.ts |   95.76 |    87.57 |     100 |   95.76 | ...26-827,898-899 
  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.78 |    77.83 |   73.04 |   81.78 |                   
  agent-context.ts |     100 |      100 |     100 |     100 |                   
  agent-core.ts    |   76.81 |    72.89 |   63.63 |   76.81 | ...1614,1641-1688 
  agent-events.ts  |     100 |      100 |     100 |     100 |                   
  ...t-headless.ts |   84.48 |    78.04 |   63.63 |   84.48 | ...00-401,404-405 
  ...nteractive.ts |   80.07 |    80.76 |   74.07 |   80.07 | ...53,455,457,460 
  ...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.4 |    82.24 |   65.07 |    78.4 |                   
  config.ts        |   76.28 |    81.09 |   60.43 |   76.28 | ...3869,3880-3892 
  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          |   87.87 |    83.53 |   92.07 |   87.87 |                   
  baseLlmClient.ts |   87.24 |    76.47 |    87.5 |   87.24 | ...82,484-494,503 
  client.ts        |   87.42 |    80.57 |   86.36 |   87.42 | ...2072,2111-2114 
  ...tGenerator.ts |    72.1 |    61.11 |     100 |    72.1 | ...63,365,372-375 
  ...lScheduler.ts |   85.36 |    82.08 |   94.73 |   85.36 | ...3209,3270-3281 
  geminiChat.ts    |   91.04 |    87.25 |   97.22 |   91.04 | ...2703,2770-2771 
  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 |   86.48 |    72.22 |     100 |   86.48 | ...97-198,212-221 
  ...issionFlow.ts |   98.59 |       95 |     100 |   98.59 | 93                
  prompts.ts       |   89.24 |    86.41 |   76.92 |   89.24 | ...-972,1175-1176 
  tokenLimits.ts   |     100 |    89.47 |     100 |     100 | 51-52             
  ...okTriggers.ts |   99.33 |    90.47 |     100 |   99.33 | 156,167           
  turn.ts          |   96.46 |    88.88 |     100 |   96.46 | ...21,434-435,483 
 ...ntentGenerator |   94.93 |    82.59 |   93.87 |   94.93 |                   
  ...tGenerator.ts |   96.49 |    84.28 |   92.59 |   96.49 | ...04,922-926,966 
  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 |   93.86 |    82.98 |    90.9 |   93.86 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...tGenerator.ts |   93.72 |    81.27 |   90.32 |   93.72 | ...29,939-940,968 
  ...tDetection.ts |     100 |      100 |     100 |     100 |                   
 ...ntentGenerator |    81.7 |    84.27 |   90.78 |    81.7 |                   
  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         |   54.54 |    68.75 |      50 |   54.54 | ...79,87-91,95-99 
  ...tGenerator.ts |    66.4 |    70.58 |   88.88 |    66.4 | ...51-157,168-169 
  pipeline.ts      |   93.69 |     84.9 |     100 |   93.69 | ...61-462,470,538 
  ...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.67 |    88.42 |   96.07 |   96.67 |                   
  dashscope.ts     |   97.38 |    90.21 |   93.33 |   97.38 | ...93-294,370-371 
  deepseek.ts      |   94.91 |    89.36 |     100 |   94.91 | ...31-132,145-146 
  default.ts       |   95.79 |    89.65 |   88.88 |   95.79 | 122-123,193-195   
  index.ts         |     100 |      100 |     100 |     100 |                   
  mimo.ts          |   94.11 |    66.66 |     100 |   94.11 | 29,52-53          
  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 |                   
  utils.ts         |     100 |      100 |     100 |     100 |                   
 src/extension     |   62.34 |    79.57 |   80.31 |   62.34 |                   
  ...-converter.ts |   66.21 |    52.45 |     100 |   66.21 | ...85-786,795-827 
  ...ionManager.ts |   47.05 |    82.19 |    65.9 |   47.05 | ...1400,1410-1429 
  ...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        |   46.41 |     87.3 |   63.63 |   46.41 | ...68-374,413-466 
  index.ts         |     100 |      100 |     100 |     100 |                   
  marketplace.ts   |   97.31 |    93.75 |     100 |   97.31 | ...65,185-186,275 
  npm.ts           |   59.01 |    71.69 |    87.5 |   59.01 | ...23-425,432-436 
  override.ts      |   94.11 |    88.88 |     100 |   94.11 | 63-64,81-82       
  redaction.ts     |     100 |      100 |     100 |     100 |                   
  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      |   55.57 |    84.14 |   81.25 |   55.57 |                   
  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.02 |      100 |   16.66 |   13.02 | 89-464,524-575    
  ...onToolGate.ts |     100 |    96.42 |     100 |     100 | 94                
  ...nGenerator.ts |    71.6 |    72.13 |   83.33 |    71.6 | ...88-246,316-318 
 src/generated     |       0 |        0 |       0 |       0 |                   
  git-commit.ts    |       0 |        0 |       0 |       0 | 1-10              
 src/goals         |   89.57 |    83.45 |   94.44 |   89.57 |                   
  ...eGoalStore.ts |    85.1 |    95.45 |   84.61 |    85.1 | ...63-166,174-182 
  goalHook.ts      |   97.26 |    91.48 |     100 |   97.26 | 100-105           
  goalJudge.ts     |   84.33 |    74.28 |     100 |   84.33 | ...57-358,366-368 
  index.ts         |     100 |      100 |     100 |     100 |                   
 src/hooks         |   83.67 |    85.34 |   86.72 |   83.67 |                   
  ...okRegistry.ts |   86.48 |    77.08 |     100 |   86.48 | ...41-344,362-369 
  ...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.6 |    86.07 |   93.33 |    94.6 | ...42,799-800,810 
  hookPlanner.ts   |   88.19 |       85 |    90.9 |   88.19 | ...68-170,188-199 
  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 |   96.37 |     90.9 |      90 |   96.37 | 342-350,424-425   
  ...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.21 |    92.13 |   85.71 |   91.21 | ...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        |   70.97 |    75.71 |    69.1 |   70.97 |                   
  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        |   77.54 |    69.38 |   88.88 |   77.54 | ...53-258,282-293 
  ...ceSelector.ts |   91.86 |    77.27 |     100 |   91.86 | ...15,117-118,126 
  scan.ts          |   87.91 |    68.42 |     100 |   87.91 | ...47-48,58,82-87 
  ...entPlanner.ts |   58.02 |    66.66 |   56.25 |   58.02 | ...47-268,344-389 
  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 |                   
  ...ontextFile.ts |   79.38 |    81.03 |   81.81 |   79.38 | ...58-272,286-291 
 src/mocks         |       0 |        0 |       0 |       0 |                   
  msw.ts           |       0 |        0 |       0 |       0 | 1-9               
 src/models        |   89.35 |    85.67 |    87.5 |   89.35 |                   
  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.66 |    92.85 |     100 |   98.66 | 162,324,330       
  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   |   74.62 |    88.85 |   58.28 |   74.62 |                   
  autoMode.ts      |   61.59 |    93.54 |   83.33 |   61.59 | ...00-238,340-356 
  ...transcript.ts |      98 |       84 |     100 |      98 | 200-201           
  classifier.ts    |   92.89 |     87.5 |     100 |   92.89 | 146-153,333-337   
  ...erousRules.ts |     100 |    89.36 |     100 |     100 | 110,133,147,175   
  ...alTracking.ts |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...on-manager.ts |    78.3 |    85.24 |   82.14 |    78.3 | ...-917,1023-1027 
  rule-parser.ts   |   96.06 |    93.22 |     100 |   96.06 | ...-875,1024-1026 
  ...-semantics.ts |   58.28 |    85.27 |    30.2 |   58.28 | ...1604-1614,1643 
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...sifier-prompts |   98.18 |       90 |     100 |   98.18 |                   
  system-prompt.ts |   98.18 |       90 |     100 |   98.18 | 150               
 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/providers     |   77.46 |    70.94 |   60.71 |   77.46 |                   
  all-providers.ts |      68 |      100 |       0 |      68 | 68-69,73-79,83-89 
  index.ts         |     100 |      100 |     100 |     100 |                   
  install.ts       |   98.87 |    87.27 |     100 |   98.87 | 268-269           
  ...der-config.ts |   66.11 |    55.93 |   63.15 |   66.11 | ...08-409,416-425 
  types.ts         |       0 |        0 |       0 |       0 | 1                 
 ...viders/presets |   97.26 |    86.36 |      50 |   97.26 |                   
  ...oding-plan.ts |   87.17 |      100 |       0 |   87.17 | 81-83,86-88,90-93 
  ...a-standard.ts |     100 |      100 |     100 |     100 |                   
  ...token-plan.ts |     100 |      100 |     100 |     100 |                   
  ...m-provider.ts |   97.01 |    81.25 |      75 |   97.01 | 120-121           
  deepseek.ts      |     100 |      100 |     100 |     100 |                   
  idealab.ts       |     100 |      100 |     100 |     100 |                   
  minimax.ts       |     100 |      100 |     100 |     100 |                   
  modelscope.ts    |     100 |      100 |     100 |     100 |                   
  openrouter.ts    |     100 |      100 |     100 |     100 |                   
  zai.ts           |     100 |      100 |     100 |     100 |                   
 src/qwen          |   83.87 |    77.23 |   95.83 |   83.87 |                   
  ...tGenerator.ts |   98.64 |    98.18 |     100 |   98.64 | 105-106           
  qwenOAuth2.ts    |   80.85 |    70.27 |   90.32 |   80.85 | ...1169-1185,1215 
  ...kenManager.ts |   83.76 |    76.22 |     100 |   83.76 | ...62-767,788-793 
 src/services      |   85.63 |    83.47 |   91.37 |   85.63 |                   
  ...ionTrailer.ts |     100 |      100 |     100 |     100 |                   
  ...llRegistry.ts |   98.44 |    91.83 |     100 |   98.44 | 268-269           
  ...ionService.ts |   98.44 |    97.45 |     100 |   98.44 | 536,538-542       
  ...ingService.ts |   83.88 |    83.33 |   83.33 |   83.88 | ...1266,1283-1284 
  ...ttribution.ts |   91.73 |    87.71 |      90 |   91.73 | ...80-685,826-827 
  ...utSlimming.ts |     100 |    96.77 |     100 |     100 | 139,188           
  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.18 |    76.76 |   91.17 |   86.18 | ...1150,1191-1194 
  fileReadCache.ts |     100 |      100 |     100 |     100 |                   
  ...temService.ts |   91.27 |    82.69 |    90.9 |   91.27 | ...94,196,294-301 
  ...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.83 |    69.31 |    97.5 |   73.83 | ...1460,1488-1489 
  ...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.65 |      100 |       0 |   12.65 | 44-150            
  ...ionService.ts |   90.47 |     79.2 |   96.87 |   90.47 | ...1324,1328-1329 
  sessionTitle.ts  |   93.87 |    71.15 |     100 |   93.87 | ...33-236,267-268 
  ...ionService.ts |   81.07 |    77.92 |   89.28 |   81.07 | ...1923,1929-1934 
  ...Estimation.ts |     100 |      100 |     100 |     100 |                   
  ...UseSummary.ts |   94.63 |    88.46 |     100 |   94.63 | ...62-164,214-215 
  ...reeCleanup.ts |   14.56 |      100 |   33.33 |   14.56 | 58-185            
  ...ionService.ts |   84.21 |    79.41 |     100 |   84.21 | ...22-223,239-240 
 ...icrocompaction |   98.05 |     91.8 |     100 |   98.05 |                   
  microcompact.ts  |   98.05 |     91.8 |     100 |   98.05 | ...19,289,293,391 
 src/skills        |   88.51 |    85.75 |   94.54 |   88.51 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...activation.ts |     100 |     93.1 |     100 |     100 | 93,112            
  skill-load.ts    |      94 |    86.56 |     100 |      94 | ...08,228,240-242 
  skill-manager.ts |   84.26 |    80.87 |   90.32 |   84.26 | ...1155,1162-1166 
  skill-paths.ts   |   89.15 |    86.36 |     100 |   89.15 | ...00-101,106-107 
  symlinkScope.ts  |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/subagents     |   82.61 |    78.89 |   95.23 |   82.61 |                   
  ...tin-agents.ts |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...nt-manager.ts |   77.15 |    71.36 |    93.1 |   77.15 | ...1178,1200-1201 
  types.ts         |     100 |      100 |     100 |     100 |                   
  validation.ts    |   92.46 |    95.18 |     100 |   92.46 | 51-56,69-74,78-83 
 src/telemetry     |   76.84 |     87.3 |   79.86 |   76.84 |                   
  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       |   75.03 |    82.95 |   74.54 |   75.03 | ...8-988,991-1002 
  ...attributes.ts |     100 |      100 |     100 |     100 |                   
  sanitize.ts      |      80 |    83.33 |     100 |      80 | 35-36,41-42       
  sdk.ts           |   93.01 |    88.23 |   80.95 |   93.01 | ...58-559,579-583 
  ...on-context.ts |     100 |      100 |     100 |     100 |                   
  ...on-tracing.ts |   92.75 |    88.26 |     100 |   92.75 | ...27-930,934-937 
  ...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,108            
  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         |   78.94 |    81.43 |   85.71 |   78.94 |                   
  ...erQuestion.ts |   88.93 |    76.74 |    90.9 |   88.93 | ...39-340,347-348 
  cron-create.ts   |   88.11 |    88.88 |    62.5 |   88.11 | ...,43-44,165-172 
  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          |   81.02 |    84.07 |      75 |   81.02 | ...15-716,826-876 
  ...r-worktree.ts |   82.95 |    67.56 |    87.5 |   82.95 | ...82-185,276-277 
  exit-worktree.ts |   84.23 |    85.96 |   91.66 |   84.23 | ...92-293,298-312 
  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 |   84.36 |    82.74 |   84.21 |   84.36 | ...2099-2103,2142 
  mcp-client.ts    |   33.18 |    77.65 |   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       |   91.36 |    83.94 |   88.46 |   91.36 | ...61,574,770-775 
  notebook-edit.ts |   85.11 |    76.42 |   81.25 |   85.11 | ...54-870,916-917 
  ...nforcement.ts |   82.57 |       90 |     100 |   82.57 | 174-185,234-247   
  read-file.ts     |    95.4 |    90.32 |      90 |    95.4 | ...99,298-301,304 
  ripGrep.ts       |   94.59 |    85.71 |   93.33 |   94.59 | ...60,463,541-542 
  ...-transport.ts |    6.34 |        0 |       0 |    6.34 | 47-145            
  send-message.ts  |   84.68 |    91.66 |    62.5 |   84.68 | ...,82-90,167-170 
  shell.ts         |   73.05 |    79.66 |   91.42 |   73.05 | ...4216,4265-4271 
  skill-utils.ts   |     100 |      100 |     100 |     100 |                   
  skill.ts         |   88.35 |    91.42 |   86.66 |   88.35 | ...12,416,439-461 
  ...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.85 |    76.85 |   80.95 |   74.85 | ...30-831,839-840 
  tool-search.ts   |   95.19 |    86.48 |    92.3 |   95.19 | ...47-153,208-213 
  tools.ts         |   90.49 |    90.19 |   84.21 |   90.49 | ...78-479,495-501 
  web-fetch.ts     |   88.84 |       80 |   92.85 |   88.84 | ...12-313,315-316 
  write-file.ts    |   82.65 |    80.45 |   84.61 |   82.65 | ...65-668,696-731 
 src/tools/agent   |   75.07 |    80.49 |   73.61 |   75.07 |                   
  agent.ts         |   75.33 |    80.72 |   74.24 |   75.33 | ...2474,2483-2486 
  fork-subagent.ts |   69.62 |    71.42 |   66.66 |   69.62 | ...04-105,140-151 
 src/utils         |   89.13 |    87.66 |   93.61 |   89.13 |                   
  LruCache.ts      |       0 |        0 |       0 |       0 | 1-41              
  ...Controller.ts |     100 |      100 |     100 |     100 |                   
  ...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 |     87.5 |     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.93 |   94.73 |    95.9 | 106-107,214-218   
  editHelper.ts    |   93.63 |    83.52 |     100 |   93.63 | ...28-429,463-464 
  editor.ts        |    97.6 |     95.4 |     100 |    97.6 | ...25-326,328-329 
  ...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.54 |    79.59 |      50 |   70.54 | ...15-231,235-241 
  fetch.ts         |   70.18 |    71.42 |   71.42 |   70.18 | ...42,148,161,186 
  fileUtils.ts     |    91.5 |    86.25 |   95.23 |    91.5 | ...1191,1195-1201 
  forkedAgent.ts   |   80.68 |    78.12 |   83.33 |   80.68 | ...39-545,550-556 
  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      |   73.64 |    90.32 |   83.33 |   73.64 | ...,78-79,103-154 
  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.4 |     90.9 |     100 |    96.4 | ...66,293-294,376 
  ...yDiscovery.ts |   88.27 |    83.87 |     100 |   88.27 | ...76,279,407-410 
  ...tProcessor.ts |    93.2 |    89.18 |     100 |    93.2 | ...82-288,370-371 
  ...Inspectors.ts |   61.53 |      100 |      50 |   61.53 | 18-23             
  modelId.ts       |   98.95 |    98.21 |     100 |   98.95 | 148               
  ...kerChecker.ts |   90.78 |    91.66 |     100 |   90.78 | 73-79             
  notebook.ts      |   94.57 |    89.83 |   95.83 |   94.57 | ...21,333,385-387 
  openaiLogger.ts  |   90.85 |    87.87 |     100 |   90.85 | ...97-199,222-227 
  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 |                   
  projectRoot.ts   |   71.73 |    78.57 |     100 |   71.73 | 54-66             
  ...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.59 |       84 |     100 |   87.59 | ...09-211,227-238 
  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 
  ...iagnostics.ts |   83.08 |     67.5 |   92.59 |   83.08 | ...23,543-544,550 
  ...tchOptions.ts |   81.72 |    85.04 |   95.23 |   81.72 | ...18,543,572-581 
  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.71 |    97.14 |     100 |   98.71 | 110               
  ...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.9 |     100 |      92 | 49-53,65-69       
 ...ils/filesearch |   86.21 |    81.61 |   96.42 |   86.21 |                   
  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 added a commit that referenced this pull request May 26, 2026
…review fold-in)

Two Copilot review findings on #4530, both genuine and within the PR's scope.

1. **Prompt deadline must be guaranteed**, not contingent on bridge cooperation.
   Old shape: `await bridge.sendPrompt(...)` after `abort.abort()`. A buggy
   agent that ignores AbortSignal could keep the HTTP request open
   indefinitely; the 504 would never fire — defeating T2.9's whole
   purpose (the PR description explicitly claims it closes the
   `FIXME(stage-2)` at `httpAcpBridge.ts:2689`, but it didn't).
   New shape: `Promise.race(bridge.sendPrompt, deadlinePromise)`. The
   deadline timer rejects the race independently; the 504 lands on
   schedule regardless of agent behavior. The orphaned bridge promise
   gets a tail-attached `.catch(() => undefined)` so its eventual
   rejection (minutes later, when the buggy agent finally settles)
   doesn't surface as unhandledRejection. `abort.abort` still fires
   as best-effort wind-down so a cooperative agent frees its FIFO slot.

2. **Writer-idle-timeout docs were wrong** about values <15s being
   "no-ops". The idle timer checks elapsed-since-last-flush
   independently of the heartbeat; with no real events, a
   `--writer-idle-timeout-ms 10000` evicts a healthy idle SSE
   connection at 10s, BEFORE the first 15s heartbeat ever refreshes
   `lastWriteAt`. Updated 4 spots (server.ts comment, types.ts
   JSDoc, serve.ts CLI help, docs/users/qwen-serve.md table) to
   recommend ≥30000ms for production and warn that smaller values
   will evict healthy connections — useful for tests / short dev
   sessions, dangerous in production.

Tests:
- New `still emits 504 when the bridge IGNORES the abort signal
  (race contract)` test: fakeBridge returns a never-settling
  Promise; route still returns 504 within budget. Locks the new
  Promise.race contract.
- All 244 existing tests still pass (was 243; +1 new).

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

@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.

Review Summary

Well-structured PR — the two features (prompt deadline + SSE writer idle timeout) are cleanly separated, backward-compatible (off by default), and the core logic is correct. Timer cleanup paths are thorough (every exit path covered, .unref() as defense-in-depth), the Math.min capping contract is sound, and the capability tag conditional advertisement follows the established pattern. Build passes, 292/292 tests pass.

Deterministic analysis: tsc clean, eslint clean (0 findings).

Test Coverage Gaps (pattern)

Several new code paths lack test coverage. Consolidating into one item since the pattern is the same — new private functions / validation blocks without corresponding tests:

  • parseDeadlineEnv (runQwenServe.ts:41-52) — no tests at all. Five branches (undefined, empty/whitespace, NaN, float, negative) are all uncovered.
  • runQwenServe startup validation (runQwenServe.ts:346-365) — the boot-time TypeError for invalid promptDeadlineMs / writerIdleTimeoutMs is not tested. The existing mcpClientBudget tests at lines 3519-3530 provide a ready-made pattern.
  • sendDeadlineResponseIfFired catch-path (server.ts:1336) — E2E tests use a prompt impl that resolves on abort; the catch-path call is never exercised.
  • deadlineMs body validation (server.ts:1215-1228) — only deadlineMs: -5 is tested. The typeof, isFinite, and isInteger branches are uncovered.
  • Writer idle timer with active writes — tests cover idle (no events) and disabled (no flag), but not the case where active writes refresh lastWriteAt and eviction should NOT fire.

Needs Human Review

  • Possibly: Date.now() is not monotonic — an NTP forward-step could cause a false-positive SSE eviction. performance.now() would be immune. Low risk in practice (NTP corrections are usually sub-second, and the codebase already uses Date.now() for all timing), but worth considering for new code.

— qwen3.7-max via Qwen Code /review

Comment thread packages/cli/src/serve/server.ts Outdated
Comment thread packages/cli/src/serve/server.ts Outdated
Comment thread packages/cli/src/serve/runQwenServe.ts Outdated
Comment thread packages/cli/src/serve/server.ts Outdated
Comment thread packages/cli/src/serve/server.ts
Comment thread packages/acp-bridge/src/status.ts
doudouOUC added a commit that referenced this pull request May 26, 2026
Per wenshao's review on #4530, accepted 3 of 6 [Suggestion]s and
added test coverage for the gaps called out in the review summary.
Pushed back on 3 (separate reply thread per comment with the
reasoning). No behavior change for the default-off case; existing
244 tests pass + 25 new.

Accepts:
- `sendDeadlineResponseIfFired` now writes a stderr breadcrumb with
  the session id before sending the 504 — symmetric with the SSE
  writer-idle eviction log. Operators triaging a 504 spike can now
  `grep "prompt deadline fired"` for the affected session instead
  of staring at an empty daemon log. Threaded `sessionId` through
  the helper signature + the direct catch-path 504 path.
- `parseDeadlineEnv` no longer treats whitespace-only env vars as
  silently "unset". `QWEN_SERVE_PROMPT_DEADLINE_MS=" "` now hits
  the standard "must be a positive integer" boot error — matches
  the JSDoc's "fail loud on typo" promise. Drove `Number('')` /
  `Number(' ')` through the existing positive-integer rejection.
- Upper-bound validation at `MAX_TIMER_DELAY_MS = 2_147_483_647`
  (2^31 - 1 ms, ~24.8 days). Node silently compresses `setTimeout` /
  `setInterval` delays past this to 1ms with a TimeoutOverflowWarning,
  so an operator setting `--prompt-deadline-ms 2592000000` (30 days)
  would otherwise see every prompt 504 instantly. Reject loudly at
  boot with a clear error pointing at the cap. Applied to
  `promptDeadlineMs`, `writerIdleTimeoutMs`, and the env-var parser
  for both.

Test coverage (5 gaps from review summary):
- `parseDeadlineEnv` end-to-end via env-var setting: 6 malformed
  cases (empty / whitespace / NaN-string / float / negative / zero)
  + an over-cap case + a happy-path case that asserts the
  capability tag flips on via the env fallback alone.
- `runQwenServe` boot validation for `promptDeadlineMs` and
  `writerIdleTimeoutMs`: zero / negative / float / NaN via
  `it.each` (mirrors the existing `mcpClientBudget` test shape at
  L3525).
- `runQwenServe` boot rejection of over-cap deadlines on both
  options.
- Catch-path branch of `sendDeadlineResponseIfFired`: new test
  where the bridge throws a bare `AbortError` (no typed reason),
  exercising the defense-in-depth path that still emits 504 by
  reading `signal.reason`.
- `deadlineMs` body validation: `it.each` covering every reachable
  branch (negative / zero / float / string / boolean / object).
  NaN/Infinity intentionally absent (JSON.stringify converts them
  to null, which the validator correctly treats as "absent").
- SSE writer idle with ACTIVE writes: new test where events at
  ~100ms intervals refresh `lastWriteAt` and the 300ms idle timer
  doesn't fire.

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

Copy link
Copy Markdown
Collaborator Author

Thanks for the thorough review, @wenshao. Folded in 3 of 6 [Suggestion]s + the test coverage gaps in c258bad; pushed back on 3 with the reasoning inline on each comment (#2, #5, #6). Summary:

Accepted

Test coverage gaps closed (25 new tests, total now 269)

  • parseDeadlineEnv end-to-end via env-var setting (6 malformed + 1 over-cap + 1 happy path)
  • runQwenServe boot validation for both options via it.each (zero/negative/float/NaN + over-cap)
  • sendDeadlineResponseIfFired catch-path: bridge throws bare AbortError, helper still emits 504 via signal.reason
  • deadlineMs body validation: every reachable branch (NaN/Infinity intentionally absent — JSON.stringify converts both to null, validator correctly treats as "absent")
  • SSE writer idle with ACTIVE writes refreshing lastWriteAt

Deferred

  • TypeError in Authentication Selection Interface #5 hardcoded v: 1 — pre-existing inconsistency in same file; deserves its own cross-cutting refactor
  • OpenAI API Error: 401 Incorecct API Key provided #6 prompt_deadline_exceeded vs writer_idle_timeout naming — existing SERVE_ERROR_KINDS already mixes both forms (init_timeout / budget_exhausted); current shape maps to semantics
  • Date.now() vs performance.now() — acknowledged as low-risk per your note; codebase precedent. Worth a separate hardening pass if the NTP-step concern bites in production.

Pushed as c258bad, ready for re-review when you have a moment.

@doudouOUC doudouOUC self-assigned this May 26, 2026
@doudouOUC doudouOUC requested a review from wenshao May 26, 2026 05:48
@wenshao

wenshao commented May 26, 2026

Copy link
Copy Markdown
Collaborator

本地真实测试报告(merge 参考)

按 PR body 的 Test plan 完成静态检查 + 三个相关 vitest suite + PR 自己列出的两条未勾的 Manual smoke(deadline 路径 + SSE idle 路径)。两个 opt-in flag 在真 daemon 上行为完全符合 PR 描述:deadline 在 ~5ms 精度内触发 504 + prompt_deadline_exceeded,SSE 在 idle 时长越过阈值时发出 client_evicted{writer_idle_timeout} 终止帧。可以合并。

测试环境

测试 commit b6508eff1 (refactor(serve): T2.9 simplify pass — share MAX_TIMEOUT_MS, dedupe 504 emitter, trim test boilerplate)
平台 macOS arm64 (Darwin 25.4.0)
Node v22.17.0
Worktree /Users/wenshao/Work/git/qwen-code/.qwen/tmp/review-pr-4530(基于 pull/4530/head

1. 静态检查与单测

命令 结果 PR body 声明
npx tsc --noEmit -p packages/cli CLI=0 typecheck clean
npx tsc --noEmit -p packages/core CORE=0
npx eslint <14 个 touched files> ESLINT=0
npx vitest run packages/cli/src/serve/server.test.ts 269/269 243(review 期间增加 26 个 case)
cd packages/acp-bridge && npx vitest run 44/44 44/44 ✅
cd packages/sdk-typescript && npx vitest run 422/422 422/422 ✅

server.test.ts 实际数比 PR body 声明的多出 26 个,是 review 期间补的(fix(serve): T2.9 race-guarantee + accurate writer-idle docs (Copilot …) / feat(serve): T2.9 wenshao review fold-in — 3 accepts + test coverage / refactor(serve): T2.9 simplify pass — share MAX_TIMEOUT_MS, dedupe 504 emitter, trim test boilerplate)。

2. Manual smoke — 启动 daemon

cd <worktree>
node packages/cli/dist/index.js serve \
  --port 18530 \
  --prompt-deadline-ms 1500 \
  --writer-idle-timeout-ms 3000 \
  --max-sessions 4

备注(非阻塞):用 npm run dev -- serve ... 启动会失败——daemon 用 plain node spawn 子进程跑 packages/cli/index.ts,子进程没继承 tsx loader 导致 ERR_UNKNOWN_FILE_EXTENSION ".ts",HttpAcpBridge 10s 后超时。改用 node packages/cli/dist/index.js serve ...(即 PR body Test plan 里写的"a built qwen serve binary")即可。这是 dev 脚本的盲区,与本 PR 无关。

2.1 capability 标签(条件性出现)

$ curl -sS http://127.0.0.1:18530/capabilities | jq '.features | map(select(. | test("prompt_absolute_deadline|writer_idle_timeout")))'
[
  "prompt_absolute_deadline",
  "writer_idle_timeout"
]

✅ 两个 capability 标签因为对应 flag 被设置而出现——SDK 消费方据此 pre-flight,符合 PR body 中"silently dropped on older daemons / additive to v=1"的契约。

2.2 创建 session(用于后续两条 smoke)

$ curl -sS -X POST http://127.0.0.1:18530/session -H 'content-type: application/json' -d '{}' | jq .
{
  "sessionId": "a143185f-ca17-48ed-8a01-24003a917928",
  "workspaceCwd": "/Users/wenshao/Work/git/qwen-code/.qwen/tmp/review-pr-4530",
  "attached": false,
  "clientId": "client_44494c8c-a9d6-4b8a-b635-2991939ea891",
  "createdAt": "2026-05-26T06:00:32.547Z"
}

3. Manual smoke 1 — --prompt-deadline-ms 路径

PR body Test plan 第一条 unchecked 项:

qwen serve --port 18280 --prompt-deadline-ms 5000 → send a prompt that runs > 5s → expect 504 with errorKind

我把阈值缩到 1500ms 以加速验证(同时也跑了 Math.min 上下界两个 case)。

3.1 Server cap 触发(无 per-request deadlineMs

$ curl -sS -w '\nHTTP=%{http_code} TIME=%{time_total}\n' \
    -X POST http://127.0.0.1:18530/session/$SESSION/prompt \
    -H 'content-type: application/json' \
    -d '{"prompt":[{"type":"text","text":"请用大约500字详细描述什么是分布式共识算法,写完整不要省略。"}]}'

{"error":"prompt exceeded the 1500ms deadline","code":"prompt_deadline_exceeded","errorKind":"prompt_deadline_exceeded","deadlineMs":1500}
HTTP=504 TIME=1.505510

逐项核对:

  • HTTP 504 ✅
  • code: "prompt_deadline_exceeded"
  • errorKind: "prompt_deadline_exceeded" ✅(PR 把 codeerrorKind 都暴露,便于不同消费方对接)
  • deadlineMs: 1500 ✅(实际生效的 deadline,不是请求方提的 hint)
  • 实测 wallclock 1.505s——deadline 计时器在 1500ms 阈值到达后5ms 内触发 504 响应,精度足够

3.2 Per-request deadlineMs 可以缩短 server cap

$ curl ... -d '{"prompt":[{...}],"deadlineMs":500}'

{"error":"prompt exceeded the 500ms deadline","code":"prompt_deadline_exceeded","errorKind":"prompt_deadline_exceeded","deadlineMs":500}
HTTP=504 TIME=0.503195

✅ 客户端把 deadline 缩到 500ms(< 1500ms server cap)后,daemon 在 503ms 触发 504,deadlineMs 字段也变成 500——证明取较小者生效。

3.3 Per-request deadlineMs 不能延长 server cap(Math.min 闸口)

$ curl ... -d '{"prompt":[{...}],"deadlineMs":10000}'

{"error":"prompt exceeded the 1500ms deadline","code":"prompt_deadline_exceeded","errorKind":"prompt_deadline_exceeded","deadlineMs":1500}
HTTP=504 TIME=1.504083

✅ 客户端尝试设 10s(> 1500ms server cap)→ daemon 仍在 1.5s 触发,deadlineMs 字段是 1500——Math.min 闸口正确把"运维定的上限"作为硬底线。这正是 PR body Design rationale 第一条:

Why Math.min cap, not absolute server enforcement: operators stay the upper bound. A client can ask for a tighter deadline … but cannot loosen one a deployment has chosen.

4. Manual smoke 2 — --writer-idle-timeout-ms 路径

PR body Test plan 第二条 unchecked 项:

qwen serve --port 18280 --writer-idle-timeout-ms 30000 → hold a slow SSE consumer → expect close after ~30s with client_evicted{reason: 'writer_idle_timeout'}

我把阈值缩到 3000ms(< 15s 心跳)以加速复现——这正是 server.test.ts 用 200ms 阈值做 unit 测试的同源思路;PR body 自己也写了"values below 15s WILL evict otherwise-healthy idle streams before the first heartbeat fires (intentional only for tests / short-lived dev sessions)"。

$ curl -sS -N -m 8 "http://127.0.0.1:18530/session/$SESSION/events"
retry: 3000

event: client_evicted
data: {"v":1,"type":"client_evicted","data":{"reason":"writer_idle_timeout","errorKind":"writer_idle_timeout","idleForMs":3004,"timeoutMs":3000}}

# elapsed wall: 3.15s — connection closed by daemon, curl exited normally (no -m 8 timeout hit)

逐项核对:

  • 终止帧 event: client_evicted ✅(复用既有 SSE 终止 taxonomy)
  • data.reason: "writer_idle_timeout"
  • data.errorKind: "writer_idle_timeout" ✅(与 acp-bridge 的 SERVE_ERROR_KINDS 对得上,packages/acp-bridge/src/status.test.ts 16 个用例锁定排序)
  • data.timeoutMs: 3000 ✅(配置阈值原样回显)
  • data.idleForMs: 3004 ✅(实际 idle 时长,4ms 抖动——给运维 debug 用)
  • 帧落地后 daemon 主动关流(curl 在 3.15s 收到 EOF,远早于 -m 8 超时)✅

PR body 解释了"为什么不走 writeChain 直接 res.write":避免 chain 卡在它正在试图检测的同一个 drain 上。从这次 smoke 看,daemon 给 in-flight 终止帧落到 wire 上的能力是稳的(即使 idleForMs 已超阈值)。

5. 与 PR 承诺逐项对账

PR body / Issue #4514 T2.9 声称 验证
两个 flag 都是 opt-in,未启用时单用户 loopback 行为不变 ✅ 默认未传时 capability 不带这两个 tag(间接由 packages/cli/src/serve/capabilities.ts 的条件输出测试覆盖)
--prompt-deadline-ms 触发 504 + errorKind: prompt_deadline_exceeded ✅ 3.1
请求体 deadlineMs 可以缩短至 server cap 以下 ✅ 3.2
请求体 deadlineMs 不能延长(Math.min 闸口) ✅ 3.3
--writer-idle-timeout-ms 在 idle 越过阈值时触发 client_evicted 终止帧,reason: writer_idle_timeout ✅ 4
errorKind 命名空间稳定(SERVE_ERROR_KINDS 锁定) ✅ acp-bridge 44/44,sdk-typescript 422/422 包含 drift-insurance test
Conditional capability 标签 prompt_absolute_deadline / writer_idle_timeout 仅在 flag 启用时出现 ✅ 2.1 实测两个标签都出现在 features 列表
env fallback(QWEN_SERVE_PROMPT_DEADLINE_MSQWEN_SERVE_WRITER_IDLE_TIMEOUT_MS packages/cli/src/serve/runQwenServe.ts 单测覆盖(在 server.test.ts 的 269 用例里),手测未跑 env 路径

6. 结论

  • ✅ PR body Test plan 全部本地复现通过
  • ✅ 之前未勾的两条 Manual smoke 全部跑通:
    • Deadline 路径:1500ms 阈值 → 504 在 1.505s 触发;500ms 缩短能生效;10000ms 试图延长被 Math.min 截到 1500ms(三个 case)
    • SSE idle 路径:3000ms 阈值 → client_evicted{writer_idle_timeout} 终止帧在 idleForMs=3004ms 落地,daemon 主动关流
  • ✅ Conditional capability 标签按 flag 出现,符合 SDK pre-flight 契约
  • ✅ Error 命名空间在 acp-bridge / sdk-typescript / server 三个 package 之间保持一致

从本地真实测试角度,该 PR 可以合并。 两个 flag 都满足"opt-in、可观测、与既有 15s 心跳互不打架、定时精度达毫秒级"的 T2.9 目标,没有看到副作用回流到默认 loopback 工作流。

Comment thread packages/cli/src/serve/httpAcpBridge.ts Outdated
Comment thread packages/cli/src/serve/server.ts Outdated
Comment thread packages/cli/src/serve/server.ts Outdated
Comment thread packages/cli/src/serve/server.ts Outdated
Comment thread packages/cli/src/serve/runQwenServe.ts
Comment thread packages/cli/src/serve/server.ts Outdated
Comment thread packages/cli/src/serve/server.test.ts Outdated
Comment thread packages/cli/src/serve/runQwenServe.ts Outdated
Comment thread packages/cli/src/serve/server.test.ts
Comment thread packages/cli/src/serve/server.ts Outdated
doudouOUC added a commit that referenced this pull request May 26, 2026
Folded in all 5 items from wenshao's CHANGES_REQUESTED review on
PR #4530. One Critical bug fix + 4 Suggestions, all real. 273/273
tests pass (was 269, +4 new including a Critical regression test).

Critical (the block reason):
- `server.ts` prompt-handler catch block: the early-return on
  `err instanceof PromptDeadlineExceededError && !res.writableEnded`
  used the AND-guard for both the body AND the return. When the
  client disconnected in the same tick the deadline fired,
  writableEnded was already true → guard failed → fell through to
  the AbortError branch (false; it's not a DOMException) → reached
  `sendBridgeError` which called `res.status(500).json(...)` on
  the already-ended response → `ERR_STREAM_WRITE_AFTER_END` could
  crash the daemon. Fix: split the guard so `return` always fires
  on `PromptDeadlineExceededError`; only the JSON write is gated
  on writableEnded. Added regression test that destroys the client
  socket mid-prompt and asserts no uncaught throw on the deadline
  race (`returns cleanly when client disconnects in the same tick
  the deadline fires`).

Suggestions:
- `server.ts` SSE eviction: wrapped `writeStderrLine` + `res.end()`
  in defensive try/catch. If stderr EPIPEs or `res.end()` throws
  on a destroyed socket, the exception would have escaped the
  interval callback, `cleanup()` would never run, the heartbeat +
  idle timers would never clear, and each subsequent tick would
  re-throw → permanent uncaughtException loop. Now: any throw on
  either is swallowed, cleanup runs unconditionally.
- `server.ts` `sendDeadlineResponseIfFired` JSDoc: rewrote to
  match the actual call shape — "**called once** from the
  AbortError catch branch as defense-in-depth" — instead of the
  stale "BOTH success and catch path" claim left over from before
  the Promise.race rewrite.
- `httpAcpBridge.ts` orphan-promise comment: removed the
  inaccurate "or the next prompt arrives" reclaim path. The next
  prompt actually chains BEHIND the orphan via
  `entry.promptQueue` (L2754 / L2664) and blocks on its eventual
  settlement — the FIFO is NOT self-healing from a buggy-agent
  orphan; only session close reclaims.
- `runQwenServe.ts` (via tests): closed the
  `QWEN_SERVE_WRITER_IDLE_TIMEOUT_MS` env-var test gap. Added 3
  tests mirroring the prompt-deadline triad (invalid / over-cap /
  happy-path) so a copy-paste error reading the wrong env-var
  name in `runQwenServe`'s plumbing fails CI loudly.

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

Copy link
Copy Markdown
Collaborator Author

@wenshao 谢谢你完整跑了 PR body 里那两条没勾的 Manual smoke + 三个 Math.min 边界 case + capability tag 条件出现 — 报告比我自己 pre-merge 该做的还细致。"deadline 5ms 内触发 504" / "SSE eviction 帧 idleForMs=3004 落地后主动关流" 都是我没在单测覆盖到的实际 wallclock 精度,留作以后类似 PR 的 acceptance baseline。

5 项 inline 全部 fold-in 在 a1a8182(273/273 tests 过):

Critical #3 — 你说的对,writableEnded race 走到 sendBridgeErrorERR_STREAM_WRITE_AFTER_END 了。拆掉 AND-guard、改成 return 永远 fire;新增回归测试 destroys client socket mid-prompt 抓这条 race。

Suggestion #1/#2/#4 — 三个都是真问题:httpAcpBridge.ts 的 FIFO 链描述错误(next prompt 是 chain BEHIND orphan,不是 reclaim);SSE eviction 的 stderr+end 没 try/catch,EPIPE 会让 cleanup 漏掉 → 永久 uncaughtException loop;sendDeadlineResponseIfFired 的 JSDoc 是 Promise.race 改造前的残留。都修了。

Suggestion #5 — 补了 QWEN_SERVE_WRITER_IDLE_TIMEOUT_MS 的 invalid/over-cap/happy-path 三件套,与 PROMPT_DEADLINE_MS 对齐;copy-paste error 读错 env 名的失败现在 CI 抓得住。

PR 已 push a1a818236,请 dismiss 一下 CHANGES_REQUESTED 再 review。

备注:你提到 npm run dev -- serve ... 因为 ts-loader 不继承导致 ERR_UNKNOWN_FILE_EXTENSION ".ts" 那个,确实是 dev 脚本的盲区,跟本 PR 无关。值得单独开个 issue 跟踪一下\——SDK 集成测试场景可能也会踩到。

@wenshao

wenshao commented May 26, 2026

Copy link
Copy Markdown
Collaborator

✅ 本地真实测试验证报告 (PR #4530)

环境:Linux 6.12 / Node 22 / 本地 tmux + curl 真实 HTTP/SSE 探测 / 已 checkout PR 分支 HEAD a1a818236

一、自动化测试

项目 命令 结果
packages/cli server.test.ts vitest run src/serve/server.test.ts 273 / 273 通过(PR 描述写的 243,本地实际更多)
packages/acp-bridge 全套 vitest run 44 / 44 通过
packages/sdk-typescript 全套 vitest run 422 / 422 通过
Typecheck × 3 包 tsc --noEmit on cli + sdk-typescript + acp-bridge 0 errors ×3
完整 build npm run build 成功(产物 dist/cli.js v0.16.1)
qwen serve --help 命令暴露 grep prompt-deadline-ms / writer-idle-timeout-ms 两个 flag 都正确出现,描述完整

合计 739 个单测全通过

二、tmux 真机 HTTP 探测

启动 node dist/cli.js serve --port 18280 ...curl 直接打 daemon。

1. 条件 capability tag 仅在对应 flag 配置时出现

启动参数 prompt_absolute_deadline writer_idle_timeout require_auth
baseline(无 flag) ABSENT ABSENT ABSENT
--prompt-deadline-ms 5000 PRESENT ABSENT ABSENT
--writer-idle-timeout-ms 3000 ABSENT PRESENT ABSENT
两个 flag 都设 PRESENT PRESENT ABSENT
QWEN_SERVE_PROMPT_DEADLINE_MS=4000(仅 env,无 CLI) PRESENT ABSENT ABSENT

✅ Tag = 行为开关的契约成立;env var fallback 也能驱动 tag。

2. --prompt-deadline-ms 504 路径

--prompt-deadline-ms 5000,发一个明显跑超 5s 的 prompt:

$ curl -X POST .../session/<id>/prompt -d '{"prompt":[...]}'

Wall: 5017ms
HTTP_CODE=504
{
  "error":"prompt exceeded the 5000ms deadline",
  "code":"prompt_deadline_exceeded",
  "errorKind":"prompt_deadline_exceeded",
  "deadlineMs":5000
}

✅ HTTP 504、errorKind / code 字段完整、deadlineMs 回声配置值、Wall 时间 ≈ 5000ms。

3. Per-prompt deadlineMsMath.min 语义

服务端 cap = 5000ms:

请求 body Wall 生效 deadline
{deadlineMs: 2000} 2013ms 2000ms ← 客户端可以收紧
{deadlineMs: 30000} 5010ms 5000ms ← 客户端无法放宽,cap 胜
deadlineMs 5017ms 5000ms

Math.min(serverCap, requestedDeadline) 行为完全符合设计文档。

4. --writer-idle-timeout-ms SSE 驱逐路径

--writer-idle-timeout-ms 3000,连一个 SSE 不动:

$ curl -N .../session/<id>/events

event: session_update
data: {"id":1,"v":1,"type":"session_update","data":{...}}   ← 初始 frame,重置 lastWriteAt

event: client_evicted
data: {
  "v":1,
  "type":"client_evicted",
  "data":{
    "reason":"writer_idle_timeout",
    "errorKind":"writer_idle_timeout",
    "idleForMs":3712,
    "timeoutMs":3000
  }
}

Wall: 3765ms   ← 3000ms 超时 + ~750ms poll grace(1/4 budget 检查间隔)

✅ 终态 frame 含 reason + errorKind + idleForMs + timeoutMs;socket 主动关闭;时序符合「(timeout + ≤1/4 budget) 内一定 evict」契约。

5. Legacy 契约保护(未设 flag)

--writer-idle-timeout-ms 启动 → SSE 静连 6s 未触发 client_evicted

Wall: 6011ms
PASS: no client_evicted frame in 6s

✅ Default-off 兑现,未引入回归。

6. CLI flag 优先于 env var

$ QWEN_SERVE_PROMPT_DEADLINE_MS=10000 qwen serve ... --prompt-deadline-ms 3000

Wall: 3013ms
HTTP_CODE=504 deadlineMs=3000   ← CLI 3000ms 胜,没用 env 的 10000ms

7. Boot-time 入参校验

启动 输出
--prompt-deadline-ms -5 Invalid promptDeadlineMs: -5. Must be a positive integer (milliseconds).
--prompt-deadline-ms 0 Invalid promptDeadlineMs: 0. Must be a positive integer (milliseconds).
--prompt-deadline-ms 99999999999 Invalid promptDeadlineMs: 99999999999. Exceeds maximum JS timer delay of 2147483647 ms (~24.8 days); Node would silently compress longer delays to 1ms.

✅ 负值 / 零 / MAX_TIMEOUT_MS 上限都给出清晰错误,避免「Node 静默压成 1ms」的隐藏坑(这条 >MAX_TIMEOUT_MS 的检查特别值得 —— 操作员要是一年一年地传 deadline,没这道闸他根本不知道 timer 立刻就走完了)。

8. stderr 操作员断点

每条触发路径都有 1 行可 grep 的 stderr:

qwen serve: prompt deadline fired (session 6e3bdf83-...) — deadlineMs=5000
qwen serve: prompt deadline fired (session 6e3bdf83-...) — deadlineMs=2000   ← body 收紧
qwen serve: prompt deadline fired (session 6e3bdf83-...) — deadlineMs=5000   ← body 想放宽,cap 胜
qwen serve: evicting SSE client (session 7f387b1d-...) — writer idle for 3712ms > 3000ms timeout

✅ load balancer 看到 504 spike → grep session id → 直接定位是 deadline 触发还是 bridge 真错。

三、设计要点验证

设计承诺(PR 描述) 真实测试观察
默认关闭,对 loopback 单用户「比特对比特相同」 ✅ baseline 路径未 evict、未额外 tag
Math.min 上限:客户端能收紧不能放宽 ✅ 2000ms 生效 / 30000ms 被砍到 5000ms
仅当 flag 设置时才 advertise tag(SDK 可 pre-flight) ✅ 4 种组合表全对
504 与 client_evicted 是「硬保证」(不依赖 agent 协作) ✅ 即便 agent 还在 count to 100,504 仍然准时落地
client_evicted{reason: 'writer_idle_timeout'} 复用现有 taxonomy ✅ 与 eventBus.ts 同 type,多一个 reason
入参校验在 boot 时 loud-fail,不静默 ✅ 三种坏值都被挡

四、风险与注意点

  1. writer-idle-timeout-ms < 15000 会拦截 healthy 连接:源码里 --help 文案 + 注释都明确写了「production 选 30000~300000,<15s 仅供测试」。本次 3000ms 探测就是利用这一点快速 reproduce —— 文档清楚,不算坑。
  2. Orphan bridge promise tail-catch:deadline race 赢以后,underlying bridgePromise 会变成 orphan(agent 可能几分钟后才报 abort)。代码在 bridgePromise.catch(() => undefined) 处兜了一次,避免 unhandledRejection。本次 504 之后 daemon 进程持续观察 30s+ 未见 Node warning。
  3. Boot 时 MAX_TIMEOUT_MS 上限校验:避免 Node 把 >2^31-1 ms 静默压成 1ms 的坑 —— 操作员设大值时立即报错。难得见这种「替框架的隐式行为兜底」的代码。
  4. prompt_deadline_exceeded 在 bridge stderr 里以 Request was aborted. 出现:这是 ACP 客户端报 code: -32603, message: 'Internal error', data.details: 'Request was aborted.' —— 跟 daemon 自己的 qwen serve: prompt deadline fired ... 是同事件的两边,相互印证。下游写监控时记得 join。

五、结论

维度 结论
单测(3 包 ×全套) 739/739 通过
Typecheck × 3 包 0 errors
--prompt-deadline-ms 504 路径 + 错误体 完全符合设计
--writer-idle-timeout-ms SSE 驱逐 + 终态 frame 完全符合设计
Math.min body / server 协商语义 验证 3 种组合都正确
条件 capability tag 5 种启动组合下都正确 advertise
Env var fallback / CLI 优先级 都验证
Boot 校验 / 边界 都验证
Default-off legacy 契约 验证未引入回归

建议:可合并。 两条新增 flag 的「硬保证 + opt-in + 完整可观测面」都在真实 HTTP 探测里被复现;PR 描述里手动 smoke 的两条 TODO(504 + client_evicted)都已闭环。

Comment thread packages/cli/src/serve/server.ts Outdated
Comment thread packages/cli/src/serve/types.ts Outdated
Comment thread packages/cli/src/serve/server.ts
Comment thread packages/cli/src/serve/server.ts
Comment thread packages/cli/src/serve/server.ts
Comment thread packages/cli/src/serve/server.ts
wenshao
wenshao previously approved these changes May 26, 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.

No new high-confidence issues found in this round. The timer cleanup is thorough, race conditions (deadline vs client disconnect vs bridge settlement) are well-handled with proper guards, Promise.race semantics are correct, and the test coverage is extensive (294 tests, all passing). CI green 26/26.

5 low-confidence findings identified but not posted as inline comments (need human review):

  • Log injection via unsanitized sessionId in new writeStderrLine calls — matches existing file-wide pattern (lines 905, 1870, 2114, 2839 also skip safeLogValue), so this is a pre-existing file-wide concern rather than PR-specific.
  • Inconsistent error class in parseDeadlineEnv (Error vs TypeError) — zero functional impact, purely stylistic.
  • 3 test gaps: deadlineMs: null body, deadlineMs with server flag unset, orphan bridgePromise.catch rejection path.

— qwen3.7-max via Qwen Code /review

doudouOUC added a commit that referenced this pull request May 26, 2026
Address remaining actionable PR #4530 review feedback: remove the unreachable prompt-deadline defense helper, keep writer-idle timeout arithmetic-only ranges unrestricted by the JS timer cap, strip route-only deadlineMs before forwarding prompt bodies, harden deadline stderr logging, clarify docs, and cover drain-path writer-idle refresh.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
@doudouOUC doudouOUC requested a review from chiga0 May 26, 2026 09:27

@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 high-confidence issues found in this round (R5 at 5bc40c7371). The incremental changes since R4 are clean: removed dead sendDeadlineResponseIfFired code, stripped deadlineMs from forwarded body, removed incorrect timer-cap validation for writerIdleTimeoutMs, added try/catch around stderr logging in emitPromptDeadline504, and 5 new test cases (stderr failure, drain-path refresh, deadlineMs stripping, writerIdleTimeoutMs over-cap acceptance, env-var over-cap acceptance). Timer cleanup is thorough, race conditions well-handled, 294 tests pass, CI green 30/30. 5 low-confidence Needs Human Review items (stale JSDoc cross-ref, JSDoc omits MAX_TIMEOUT_MS cap, 3 test gaps) reported in terminal only. — qwen3.7-max via Qwen Code /review

@doudouOUC doudouOUC requested a review from yiliang114 May 26, 2026 12:15

@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 new issues found in R6 review (qwen3.7-max). All 9 review agents + reverse audit confirm: timer lifecycle, race conditions, validation parity, and test coverage are solid. 296 tests pass, tsc + eslint clean. — qwen3.7-max via Qwen Code /review

@doudouOUC doudouOUC changed the base branch from main to daemon_mode_b_main May 26, 2026 16:02
doudouOUC added a commit that referenced this pull request May 26, 2026
Follow-ups surfaced by an independent simplify-review pass on the
initial T2.9 commit. No behavior change; tests still 243/243.

- server.ts: gate per-chunk `lastWriteAt = Date.now()` behind a
  `trackWriterIdle` boolean derived once from `opts.writerIdleTimeoutMs`.
  Skips the timestamp on every SSE frame when the flag is unset (the
  default), which matters for chatty tool-output streams (hundreds-
  to-thousands of writes per session).
- runQwenServe.ts: extract `isPositiveIntegerMs` predicate; collapse
  the two new option-validation blocks and the env parser onto one
  source of truth.
- server.test.ts: extract `abortableBridgePromptImpl()` helper; the
  3 new T2.9 prompt-deadline tests had verbatim copies of the
  "Promise that resolves on abort" snippet.
- server.ts + capabilities.ts: trim two repetitive call-site
  comments + one speculative "hypothetical future sentinel" comment
  whose value was already covered by the helper JSDoc / boot-time
  validation.

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

Two Copilot review findings on #4530, both genuine and within the PR's scope.

1. **Prompt deadline must be guaranteed**, not contingent on bridge cooperation.
   Old shape: `await bridge.sendPrompt(...)` after `abort.abort()`. A buggy
   agent that ignores AbortSignal could keep the HTTP request open
   indefinitely; the 504 would never fire — defeating T2.9's whole
   purpose (the PR description explicitly claims it closes the
   `FIXME(stage-2)` at `httpAcpBridge.ts:2689`, but it didn't).
   New shape: `Promise.race(bridge.sendPrompt, deadlinePromise)`. The
   deadline timer rejects the race independently; the 504 lands on
   schedule regardless of agent behavior. The orphaned bridge promise
   gets a tail-attached `.catch(() => undefined)` so its eventual
   rejection (minutes later, when the buggy agent finally settles)
   doesn't surface as unhandledRejection. `abort.abort` still fires
   as best-effort wind-down so a cooperative agent frees its FIFO slot.

2. **Writer-idle-timeout docs were wrong** about values <15s being
   "no-ops". The idle timer checks elapsed-since-last-flush
   independently of the heartbeat; with no real events, a
   `--writer-idle-timeout-ms 10000` evicts a healthy idle SSE
   connection at 10s, BEFORE the first 15s heartbeat ever refreshes
   `lastWriteAt`. Updated 4 spots (server.ts comment, types.ts
   JSDoc, serve.ts CLI help, docs/users/qwen-serve.md table) to
   recommend ≥30000ms for production and warn that smaller values
   will evict healthy connections — useful for tests / short dev
   sessions, dangerous in production.

Tests:
- New `still emits 504 when the bridge IGNORES the abort signal
  (race contract)` test: fakeBridge returns a never-settling
  Promise; route still returns 504 within budget. Locks the new
  Promise.race contract.
- All 244 existing tests still pass (was 243; +1 new).

🤖 Generated with [Qwen Code](https://github.com/QwenLM/qwen-code)
doudouOUC added a commit that referenced this pull request May 26, 2026
Per wenshao's review on #4530, accepted 3 of 6 [Suggestion]s and
added test coverage for the gaps called out in the review summary.
Pushed back on 3 (separate reply thread per comment with the
reasoning). No behavior change for the default-off case; existing
244 tests pass + 25 new.

Accepts:
- `sendDeadlineResponseIfFired` now writes a stderr breadcrumb with
  the session id before sending the 504 — symmetric with the SSE
  writer-idle eviction log. Operators triaging a 504 spike can now
  `grep "prompt deadline fired"` for the affected session instead
  of staring at an empty daemon log. Threaded `sessionId` through
  the helper signature + the direct catch-path 504 path.
- `parseDeadlineEnv` no longer treats whitespace-only env vars as
  silently "unset". `QWEN_SERVE_PROMPT_DEADLINE_MS=" "` now hits
  the standard "must be a positive integer" boot error — matches
  the JSDoc's "fail loud on typo" promise. Drove `Number('')` /
  `Number(' ')` through the existing positive-integer rejection.
- Upper-bound validation at `MAX_TIMER_DELAY_MS = 2_147_483_647`
  (2^31 - 1 ms, ~24.8 days). Node silently compresses `setTimeout` /
  `setInterval` delays past this to 1ms with a TimeoutOverflowWarning,
  so an operator setting `--prompt-deadline-ms 2592000000` (30 days)
  would otherwise see every prompt 504 instantly. Reject loudly at
  boot with a clear error pointing at the cap. Applied to
  `promptDeadlineMs`, `writerIdleTimeoutMs`, and the env-var parser
  for both.

Test coverage (5 gaps from review summary):
- `parseDeadlineEnv` end-to-end via env-var setting: 6 malformed
  cases (empty / whitespace / NaN-string / float / negative / zero)
  + an over-cap case + a happy-path case that asserts the
  capability tag flips on via the env fallback alone.
- `runQwenServe` boot validation for `promptDeadlineMs` and
  `writerIdleTimeoutMs`: zero / negative / float / NaN via
  `it.each` (mirrors the existing `mcpClientBudget` test shape at
  L3525).
- `runQwenServe` boot rejection of over-cap deadlines on both
  options.
- Catch-path branch of `sendDeadlineResponseIfFired`: new test
  where the bridge throws a bare `AbortError` (no typed reason),
  exercising the defense-in-depth path that still emits 504 by
  reading `signal.reason`.
- `deadlineMs` body validation: `it.each` covering every reachable
  branch (negative / zero / float / string / boolean / object).
  NaN/Infinity intentionally absent (JSON.stringify converts them
  to null, which the validator correctly treats as "absent").
- SSE writer idle with ACTIVE writes: new test where events at
  ~100ms intervals refresh `lastWriteAt` and the 300ms idle timer
  doesn't fire.

🤖 Generated with [Qwen Code](https://github.com/QwenLM/qwen-code)
@doudouOUC doudouOUC force-pushed the feat/serve-t2.9-prompt-deadline-writer-idle-timeout branch from 5bc40c7 to ebfbc40 Compare May 26, 2026 16:06
doudouOUC added a commit that referenced this pull request May 26, 2026
Folded in all 5 items from wenshao's CHANGES_REQUESTED review on
PR #4530. One Critical bug fix + 4 Suggestions, all real. 273/273
tests pass (was 269, +4 new including a Critical regression test).

Critical (the block reason):
- `server.ts` prompt-handler catch block: the early-return on
  `err instanceof PromptDeadlineExceededError && !res.writableEnded`
  used the AND-guard for both the body AND the return. When the
  client disconnected in the same tick the deadline fired,
  writableEnded was already true → guard failed → fell through to
  the AbortError branch (false; it's not a DOMException) → reached
  `sendBridgeError` which called `res.status(500).json(...)` on
  the already-ended response → `ERR_STREAM_WRITE_AFTER_END` could
  crash the daemon. Fix: split the guard so `return` always fires
  on `PromptDeadlineExceededError`; only the JSON write is gated
  on writableEnded. Added regression test that destroys the client
  socket mid-prompt and asserts no uncaught throw on the deadline
  race (`returns cleanly when client disconnects in the same tick
  the deadline fires`).

Suggestions:
- `server.ts` SSE eviction: wrapped `writeStderrLine` + `res.end()`
  in defensive try/catch. If stderr EPIPEs or `res.end()` throws
  on a destroyed socket, the exception would have escaped the
  interval callback, `cleanup()` would never run, the heartbeat +
  idle timers would never clear, and each subsequent tick would
  re-throw → permanent uncaughtException loop. Now: any throw on
  either is swallowed, cleanup runs unconditionally.
- `server.ts` `sendDeadlineResponseIfFired` JSDoc: rewrote to
  match the actual call shape — "**called once** from the
  AbortError catch branch as defense-in-depth" — instead of the
  stale "BOTH success and catch path" claim left over from before
  the Promise.race rewrite.
- `httpAcpBridge.ts` orphan-promise comment: removed the
  inaccurate "or the next prompt arrives" reclaim path. The next
  prompt actually chains BEHIND the orphan via
  `entry.promptQueue` (L2754 / L2664) and blocks on its eventual
  settlement — the FIFO is NOT self-healing from a buggy-agent
  orphan; only session close reclaims.
- `runQwenServe.ts` (via tests): closed the
  `QWEN_SERVE_WRITER_IDLE_TIMEOUT_MS` env-var test gap. Added 3
  tests mirroring the prompt-deadline triad (invalid / over-cap /
  happy-path) so a copy-paste error reading the wrong env-var
  name in `runQwenServe`'s plumbing fails CI loudly.

🤖 Generated with [Qwen Code](https://github.com/QwenLM/qwen-code)
doudouOUC added a commit that referenced this pull request May 26, 2026
Address remaining actionable PR #4530 review feedback: remove the unreachable prompt-deadline defense helper, keep writer-idle timeout arithmetic-only ranges unrestricted by the JS timer cap, strip route-only deadlineMs before forwarding prompt bodies, harden deadline stderr logging, clarify docs, and cover drain-path writer-idle refresh.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
…T2.9)

Squashed: 8 commits for clean rebase onto daemon_mode_b_main.

🤖 Generated with [Qwen Code](https://github.com/QwenLM/qwen-code)
@doudouOUC doudouOUC force-pushed the feat/serve-t2.9-prompt-deadline-writer-idle-timeout branch from ebfbc40 to 3013196 Compare May 26, 2026 16:50
@doudouOUC doudouOUC dismissed yiliang114’s stale review May 26, 2026 17:08

merge to daemon_mode_b_main

@doudouOUC doudouOUC merged commit 3b785cf into daemon_mode_b_main May 26, 2026
@doudouOUC doudouOUC deleted the feat/serve-t2.9-prompt-deadline-writer-idle-timeout branch May 26, 2026 17:09
doudouOUC added a commit that referenced this pull request May 27, 2026
Squashed feature work from daemon_mode_b_main branch, rebased onto
latest main to establish proper merge-base and clean PR diff.

Original commits:
- perf(core): F2 cleanup PR A — R9/W11/W12/R10 (post-merge follow-ups) (#4411)
- refactor(acp-bridge): F1 test split — lift bridge.test.ts (6861 LOC) to acp-bridge (#4445)
- fix(core): F2 cleanup PR B — self-heal observability (W133-a + W134) (#4460)
- feat(sdk/daemon-ui): unified completeness follow-up to #4328 (#4353)
- docs(serve): v0.16-alpha known limits + SDK QWEN_SERVER_TOKEN env fallback (PR 27) (#4473)
- docs(deploy): local launch templates for v0.16-alpha (PR 30a) (#4483)
- feat(daemon+sdk): cross-client real-time sync completeness (#4484)
- feat(serve): add POST /session/:id/recap (#4504)
- feat(daemon): add voterClientId to permission_resolved (A4) (#4539)
- feat(serve): --allow-origin <pattern> CORS allowlist (T2.4 #4514) (#4527)
- feat(daemon): in-session model switch reaches the bus (A1) (#4546)
- feat(serve): prompt absolute deadline + SSE writer idle timeout (#4514 T2.9) (#4530)
- Feat/daemon react cli (#4380)
doudouOUC added a commit that referenced this pull request May 27, 2026
…T2.9) (#4530)

Squashed: 8 commits for clean rebase onto daemon_mode_b_main.

🤖 Generated with [Qwen Code](https://github.com/QwenLM/qwen-code)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants