Skip to content

feat(serve): add runtime context injection for per-turn system-reminders - #5847

Closed
callmeYe wants to merge 29 commits into
mainfrom
worktree-feat+runtime-context
Closed

feat(serve): add runtime context injection for per-turn system-reminders#5847
callmeYe wants to merge 29 commits into
mainfrom
worktree-feat+runtime-context

Conversation

@callmeYe

@callmeYe callmeYe commented Jun 25, 2026

Copy link
Copy Markdown
Collaborator

What this PR does

Adds a per-session key-value RuntimeContext store that external callers (daemon API, SDK) can populate with session-scoped dynamic context. Entries are injected as <system-reminder> blocks on every UserQuery/Cron turn, providing a runtime-mutable layer between the static system prompt and the conversation — analogous to the append mechanism in the Claude Agent SDK, but updatable mid-session.

Full stack: Config store → per-turn injection in sendMessageStream → ACP ext-method → bridge implementation → daemon HTTP route POST /session/:id/runtime-context → SDK DaemonClient / DaemonSessionClient.

Why it's needed

The Claude Agent SDK distinguishes between static system prompts (systemPrompt, append) and dynamic conversation context (CLAUDE.md injected into conversation, not the system prompt). Qwen Code currently lacks an equivalent mechanism for session-scoped dynamic context that can be set at session creation and updated mid-session without modifying QWEN.md.

Use cases include: operator identity injection, per-session rule overlays, dynamic configuration that varies by session but shouldn't be persisted to project-level files. This keeps QWEN.md stable as a project-level configuration file while enabling session-level customization through the daemon/SDK API.

Reviewer Test Plan

How to verify

  1. Config store: Run npx vitest run packages/core/src/config/config.test.ts -t "RuntimeContext" — 10 unit tests covering CRUD, key/value/count validation, return-value accuracy, and prototype-chain isolation.
  2. Handler tests: Run npx vitest run packages/cli/src/acp-integration/acpAgent.test.ts -t "sessionRuntimeContext" — 6 tests covering happy path, removal, rejection, and error cases.
  3. Daemon route: Start qwen serve, create a session, then curl -X POST /session/:id/runtime-context -d '{"entries":{"operator":"Alice","rules":"No prod changes"}}'. Verify the response contains { keys, rejected }.
  4. Per-turn injection: Send a prompt after setting runtime context — the model should see <system-reminder> blocks containing [key] value formatted content.
  5. Capability: GET /capabilities should include session_runtime_context in the feature list.

Evidence (Before & After)

N/A — new feature, no UI changes.

Tested on

OS Status
🍏 macOS
🪟 Windows ⚠️
🐧 Linux ⚠️

Environment (optional)

Unit tests + integration tests. Integration testing requires a running daemon.

Risk & Scope

  • Main risk or tradeoff: Per-turn injection adds a small token overhead per turn when runtime context is set. Content is typically small, so the cost is negligible compared to existing date/plan-mode/arena reminders.
  • Not validated / out of scope: initialRuntimeContext on BridgeSpawnRequest (session-creation-time seeding) is designed but not wired — will land in a follow-up.
  • Breaking changes / migration notes: None. Purely additive — no existing behavior is changed.
中文说明

这个 PR 做了什么

新增了一个会话级键值 RuntimeContext 存储,外部调用方(daemon API、SDK)可以填充会话作用域的动态上下文。条目在每个 UserQuery/Cron 轮次以 <system-reminder> 块注入,提供了一个介于静态系统提示词和对话之间的、运行时可修改的层——类似 Claude Agent SDKappend 机制,但支持会话中途更新。

完整链路:Config 存储 → sendMessageStream 中按轮注入 → ACP ext-method → bridge 实现 → daemon HTTP 路由 POST /session/:id/runtime-context → SDK DaemonClient / DaemonSessionClient

为什么需要

Claude Agent SDK 区分静态系统提示词(systemPromptappend)和动态对话上下文(CLAUDE.md 作为对话内容注入,而非系统提示词)。Qwen Code 目前缺少一个等价机制——能在会话创建时设置、且在会话中途通过 API 更新的会话级动态上下文。

使用场景包括:操作人身份注入、按会话的规则叠加、因会话而异但不应持久化到项目级文件的动态配置。这让 QWEN.md 保持稳定作为项目级配置文件,同时通过 daemon/SDK API 实现会话级定制。

评审测试计划

如何验证

  1. Config 存储:运行 npx vitest run packages/core/src/config/config.test.ts -t "RuntimeContext" — 10 个单元测试覆盖增删改查、key/value/count 校验、返回值准确性和原型链隔离。
  2. Handler 测试:运行 npx vitest run packages/cli/src/acp-integration/acpAgent.test.ts -t "sessionRuntimeContext" — 6 个测试覆盖正常路径、删除、拒绝和错误场景。
  3. Daemon 路由:启动 qwen serve,创建会话,然后 curl -X POST /session/:id/runtime-context -d '{"entries":{"operator":"Alice","rules":"No prod changes"}}'。验证响应包含 { keys, rejected }
  4. 按轮注入:设置 runtime context 后发送 prompt——模型应看到包含 [key] value 格式内容的 <system-reminder> 块。
  5. 能力声明GET /capabilities 应在功能列表中包含 session_runtime_context

证据(前后对比)

不适用——新功能,无 UI 变更。

测试平台

OS 状态
🍏 macOS
🪟 Windows ⚠️
🐧 Linux ⚠️

风险与范围

  • 主要风险或权衡:设置了 runtime context 时每轮会增加少量 token 开销。内容通常较小,相比现有的日期/plan-mode/arena 提醒可忽略不计。
  • 未验证/超出范围:BridgeSpawnRequest 上的 initialRuntimeContext(会话创建时预设)已设计但未接线——将在后续 PR 落地。
  • 破坏性变更/迁移说明:无。纯新增功能,不改变任何现有行为。

@github-actions

github-actions Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Code Coverage Summary

Package Lines Statements Functions Branches
CLI 80.55% 80.55% 86.41% 81.29%
Core 85.87% 85.87% 87.33% 85.29%
CLI Package - Full Text Report
-------------------|---------|----------|---------|---------|-------------------
File               | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
-------------------|---------|----------|---------|---------|-------------------
All files          |   80.55 |    81.29 |   86.41 |   80.55 |                   
 src               |   80.35 |    78.16 |   84.21 |   80.35 |                   
  cli.ts           |   94.31 |    82.35 |     100 |   94.31 | ...67-468,478-479 
  gemini.tsx       |   71.24 |    75.95 |      80 |   71.24 | ...1047-1051,1172 
  ...ractiveCli.ts |   77.38 |     74.9 |   74.07 |   77.38 | ...2039-2041,2076 
  ...liCommands.ts |   88.34 |    83.87 |      90 |   88.34 | ...63,480,514,635 
  ...ActiveAuth.ts |     100 |     87.5 |     100 |     100 | 66-80             
 ...cp-integration |   63.27 |    68.79 |   85.91 |   63.27 |                   
  acpAgent.ts      |   63.02 |    68.62 |   85.85 |   63.02 | ...9082-9084,9100 
  authMethods.ts   |      92 |       60 |     100 |      92 | 33-34             
  errorCodes.ts    |       0 |        0 |       0 |       0 | 1-22              
  ...ion-skills.ts |     100 |    88.23 |     100 |     100 | 17,32             
  ...DirContext.ts |     100 |      100 |     100 |     100 |                   
 ...ration/service |   97.04 |    95.71 |   93.33 |   97.04 |                   
  filesystem.ts    |   97.04 |    95.71 |   93.33 |   97.04 | ...21-122,238-239 
 ...ration/session |   86.63 |    80.45 |   91.17 |   86.63 |                   
  ...ryReplayer.ts |   77.91 |    87.01 |   86.66 |   77.91 | ...20-435,448-449 
  Session.ts       |   87.08 |    79.66 |   92.42 |   87.08 | ...6042,6069-6073 
  ...entTracker.ts |   91.53 |    89.47 |   88.88 |   91.53 | ...32,196,270-279 
  index.ts         |       0 |        0 |       0 |       0 | 1-40              
  ...ssionUtils.ts |      85 |    84.84 |     100 |      85 | ...49-165,221-223 
  tasksSnapshot.ts |   94.21 |     87.5 |     100 |   94.21 | 65-71             
  types.ts         |       0 |        0 |       0 |       0 | 1                 
 ...ssion/emitters |   96.69 |    94.56 |   96.96 |   96.69 |                   
  BaseEmitter.ts   |     100 |    84.61 |     100 |     100 | 23,27             
  ...ageEmitter.ts |   95.37 |    95.74 |     100 |   95.37 | 48-55             
  PlanEmitter.ts   |     100 |      100 |     100 |     100 |                   
  ...allEmitter.ts |   98.46 |    94.84 |     100 |   98.46 | 321-322,423,431   
  index.ts         |       0 |        0 |       0 |       0 | 1-10              
 ...ession/rewrite |    91.3 |    88.09 |   94.44 |    91.3 |                   
  LlmRewriter.ts   |      81 |       84 |     100 |      81 | ...,88-89,155-159 
  ...Middleware.ts |   96.74 |    86.84 |     100 |   96.74 | 135,143-145       
  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      |   88.57 |    73.52 |   64.51 |   88.57 |                   
  auth.ts          |     100 |    83.33 |     100 |     100 | 11,14             
  channel.ts       |   55.88 |      100 |       0 |   55.88 | 17-21,29-38       
  extensions.tsx   |   96.77 |      100 |      50 |   96.77 | 39                
  hooks.tsx        |   66.66 |      100 |       0 |   66.66 | 20-24             
  mcp.ts           |   95.45 |      100 |      50 |   95.45 | 31                
  review.ts        |   96.29 |      100 |      50 |   96.29 | 38                
  serve.ts         |   86.42 |    67.64 |     100 |   86.42 | ...00-603,617-621 
  sessions.ts      |     100 |      100 |      50 |     100 |                   
  update.ts        |   98.11 |    94.44 |   66.66 |   98.11 | 81-82             
 ...mmands/channel |   82.23 |    86.65 |   84.55 |   82.23 |                   
  ...l-registry.ts |    6.52 |      100 |       0 |    6.52 | 6-33,36-54        
  ...entry-path.ts |      75 |       50 |     100 |      75 | 8-9               
  config-utils.ts  |   95.26 |    95.58 |     100 |   95.26 | ...63-266,358-359 
  configure.ts     |    14.7 |      100 |       0 |    14.7 | 18-21,23-84       
  daemon-worker.ts |   95.85 |    87.89 |   96.87 |   95.85 | ...60-761,765-766 
  ...classifier.ts |   97.59 |    92.85 |     100 |   97.59 | 47-48             
  pairing.ts       |   26.31 |      100 |       0 |   26.31 | ...30,40-50,52-65 
  pidfile.ts       |   96.77 |    88.46 |     100 |   96.77 | ...77-178,242-243 
  proxy.ts         |     100 |      100 |     100 |     100 |                   
  reload.ts        |   72.97 |    80.95 |      75 |   72.97 | 64-76,85-91       
  runtime.ts       |   77.39 |    86.66 |     100 |   77.39 | ...45-149,179-181 
  start.ts         |   75.21 |    75.28 |   66.66 |   75.21 | ...38,544-547,559 
  status.ts        |   75.38 |       40 |     100 |   75.38 | 35-37,47-48,61-72 
  stop.ts          |   39.02 |    33.33 |     100 |   39.02 | 17-19,28-54       
 ...nds/extensions |   87.25 |     89.3 |   85.24 |   87.25 |                   
  consent.ts       |   72.53 |       90 |   42.85 |   72.53 | ...86-142,157-163 
  disable.ts       |     100 |      100 |     100 |     100 |                   
  enable.ts        |     100 |      100 |     100 |     100 |                   
  install.ts       |   85.05 |    83.33 |      75 |   85.05 | ...05-208,211-220 
  link.ts          |     100 |      100 |     100 |     100 |                   
  list.ts          |     100 |     87.5 |     100 |     100 | 18                
  new.ts           |     100 |      100 |     100 |     100 |                   
  settings.ts      |   99.15 |      100 |   83.33 |   99.15 | 151               
  sources.ts       |   93.42 |    87.09 |   92.85 |   93.42 | ...4-66,96-98,167 
  uninstall.ts     |    37.5 |      100 |   33.33 |    37.5 | 23-45,57-64,67-70 
  update.ts        |   96.29 |      100 |     100 |   96.29 | 101-105           
  utils.ts         |      75 |    53.84 |     100 |      75 | ...27-131,133-137 
 ...les/mcp-server |       0 |        0 |       0 |       0 |                   
  example.ts       |       0 |        0 |       0 |       0 | 1-60              
 ...amples/starter |       0 |        0 |       0 |       0 |                   
  example.ts       |       0 |        0 |       0 |       0 | 1-64              
 src/commands/mcp  |   90.15 |    84.39 |   83.33 |   90.15 |                   
  add.ts           |    99.3 |    96.07 |     100 |    99.3 | 154-155           
  approve.ts       |   76.19 |     87.5 |   66.66 |   76.19 | ...,89-99,114-124 
  list.ts          |   92.59 |    83.87 |      80 |   92.59 | ...62-164,180-181 
  reconnect.ts     |   78.73 |    66.66 |   85.71 |   78.73 | 42-55,168-190     
  remove.ts        |     100 |       80 |     100 |     100 | 21-25             
 ...ommands/review |   43.18 |    51.89 |   37.14 |   43.18 |                   
  cleanup.ts       |   20.28 |      100 |       0 |   20.28 | ...,94-99,101-102 
  fetch-pr.ts      |   10.13 |      100 |       0 |   10.13 | ...33-360,362-363 
  load-rules.ts    |   26.41 |      100 |   16.66 |   26.41 | ...41-153,155-156 
  plan-diff.ts     |   73.43 |      100 |   66.66 |   73.43 | 95-111            
  pr-context.ts    |   58.19 |     47.5 |   55.55 |   58.19 | ...80-395,397-398 
  presubmit.ts     |   67.75 |       32 |   83.33 |   67.75 | ...37-238,277-302 
 ...nds/review/lib |   90.63 |    92.75 |   70.73 |   90.63 |                   
  diff-plan.ts     |    98.7 |    92.52 |     100 |    98.7 | ...21,244,270-271 
  gh.ts            |   22.58 |      100 |       0 |   22.58 | ...49,53-54,62-69 
  git.ts           |   72.72 |      100 |      40 |   72.72 | ...,61-62,101-106 
  heavy.ts         |     100 |      100 |     100 |     100 |                   
  merge-base.ts    |     100 |      100 |     100 |     100 |                   
  paths.ts         |   52.94 |      100 |       0 |   52.94 | ...26,37-38,42-43 
  report.ts        |   92.13 |    86.66 |     100 |   92.13 | 170-171,173-177   
 ...mands/sessions |   91.56 |    86.95 |   83.33 |   91.56 |                   
  common.ts        |     100 |      100 |     100 |     100 |                   
  list.ts          |   90.96 |    86.66 |   81.81 |   90.96 | 208-219,221-222   
 src/config        |   94.15 |    87.54 |   95.23 |   94.15 |                   
  auth.ts          |   89.35 |    83.56 |     100 |   89.35 | ...97-298,314-315 
  ...eMcpImport.ts |   87.91 |    81.52 |     100 |   87.91 | ...63-371,453-454 
  config.ts        |   87.58 |    86.08 |   84.37 |   87.58 | ...2298,2300-2308 
  ...heme-names.ts |     100 |      100 |     100 |     100 |                   
  environment.ts   |   94.18 |     89.4 |   94.73 |   94.18 | ...22-626,642-643 
  ...le-watcher.ts |   90.42 |    85.36 |      95 |   90.42 | ...92,295-297,342 
  ...resh-state.ts |   90.57 |    97.29 |   93.75 |   90.57 | 133-138,142-148   
  ...ime-reload.ts |     100 |    69.69 |     100 |     100 | ...12-113,122-123 
  hot-reload.ts    |     100 |    89.74 |     100 |     100 | 47,160,220        
  keyBindings.ts   |    97.1 |       50 |     100 |    97.1 | 214-217           
  ...ngsAdapter.ts |     100 |    94.11 |     100 |     100 | 64                
  ...ig-watcher.ts |   95.17 |    83.05 |     100 |   95.17 | ...78,200,292-293 
  mcpApprovals.ts  |   96.55 |    95.65 |     100 |   96.55 | 223-224,229-231   
  mcpJson.ts       |     100 |      100 |     100 |     100 |                   
  mcpServers.ts    |   92.85 |     87.5 |     100 |   92.85 | 46-47             
  ...idersScope.ts |      92 |     90.9 |     100 |      92 | 11-12             
  ...abledTools.ts |     100 |      100 |     100 |     100 |                   
  ...comparison.ts |     100 |      100 |     100 |     100 |                   
  ...n-settings.ts |   99.15 |    93.75 |     100 |   99.15 | 63                
  sandboxConfig.ts |   61.64 |    71.87 |   66.66 |   61.64 | ...54-68,73,77-89 
  ...ings-cache.ts |   96.52 |    93.93 |     100 |   96.52 | 90-91,201-202     
  settings.ts      |   89.79 |     89.5 |   89.65 |   89.79 | ...61,963,965-966 
  ...ingsSchema.ts |     100 |      100 |     100 |     100 |                   
  ...ngsWatcher.ts |   95.54 |    88.34 |     100 |   95.54 | ...28,277-278,293 
  ...d-env-keys.ts |     100 |      100 |     100 |     100 |                   
  ...paths-lite.ts |   89.47 |       88 |     100 |   89.47 | 43-44,53-54,56-57 
  ...tedFolders.ts |   93.78 |    94.78 |     100 |   93.78 | ...43-344,380-391 
 ...nfig/migration |   95.23 |    78.94 |   83.33 |   95.23 |                   
  index.ts         |   95.65 |    88.88 |     100 |   95.65 | 117-118           
  scheduler.ts     |   96.55 |    77.77 |     100 |   96.55 | 19-20             
  types.ts         |       0 |        0 |       0 |       0 | 1                 
 ...ation/versions |   94.91 |      100 |     100 |   94.91 |                   
  ...-v2-shared.ts |     100 |      100 |     100 |     100 |                   
  v1-to-v2.ts      |   81.75 |      100 |     100 |   81.75 | ...28-229,231-247 
  v2-to-v3.ts      |     100 |      100 |     100 |     100 |                   
  v3-to-v4.ts      |     100 |      100 |     100 |     100 |                   
  v5-to-v4.ts      |      96 |      100 |     100 |      96 | 94-95,99          
 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    |   69.39 |    66.66 |   63.15 |   69.39 |                   
  ...tputBridge.ts |   69.48 |     67.3 |    64.7 |   69.48 | ...82-383,391-394 
  ...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          |    86.9 |    80.45 |    93.1 |    86.9 |                   
  index.ts         |   73.45 |    77.77 |      90 |   73.45 | ...70-271,294-299 
  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 |   78.99 |    76.11 |   81.03 |   78.99 |                   
  session.ts       |   83.18 |       75 |   93.47 |   83.18 | ...63-964,973-983 
  types.ts         |    42.5 |      100 |   33.33 |    42.5 | ...00-601,604-605 
 ...active/control |   75.88 |    88.46 |      80 |   75.88 |                   
  ...rolContext.ts |    6.45 |        0 |       0 |    6.45 | 56-95             
  ...Dispatcher.ts |   91.69 |       92 |   88.88 |   91.69 | ...49-367,384,387 
  ...rolService.ts |     7.4 |        0 |       0 |     7.4 | 46-185            
 ...ol/controllers |   34.74 |     51.8 |   42.42 |   34.74 |                   
  ...Controller.ts |   39.49 |      100 |      80 |   39.49 | 88-92,127-210     
  ...Controller.ts |       0 |        0 |       0 |       0 | 1-56              
  ...Controller.ts |   46.62 |    52.94 |   54.54 |   46.62 | ...24-633,648-653 
  ...Controller.ts |   14.06 |      100 |       0 |   14.06 | ...82-117,130-133 
  ...Controller.ts |   24.52 |       40 |   33.33 |   24.52 | ...64-476,485-514 
 .../control/types |       0 |        0 |       0 |       0 |                   
  serviceAPIs.ts   |       0 |        0 |       0 |       0 | 1                 
 ...Interactive/io |   97.49 |    93.84 |   95.23 |   97.49 |                   
  ...putAdapter.ts |   97.13 |    92.89 |   98.07 |   97.13 | ...1314,1409-1410 
  ...putAdapter.ts |      96 |    91.66 |   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   |   87.31 |    75.32 |   88.23 |   87.31 |                   
  ...utContext.tsx |     100 |      100 |     100 |     100 |                   
  ...putWatcher.ts |   88.01 |       76 |   93.33 |   88.01 | ...49-350,361-364 
  index.ts         |       0 |        0 |       0 |       0 | 1-8               
 src/serve         |    86.7 |    84.75 |   89.95 |    86.7 |                   
  ...tp-enabled.ts |     100 |      100 |     100 |     100 |                   
  ...ion-bridge.ts |     100 |      100 |     100 |     100 |                   
  auth.ts          |    93.4 |    93.15 |     100 |    93.4 | ...16-317,320-322 
  ...em-adapter.ts |     100 |      100 |     100 |     100 |                   
  capabilities.ts  |     100 |    96.96 |     100 |     100 | 494               
  ...cp-command.ts |     100 |      100 |     100 |     100 |                   
  ...-selection.ts |     100 |      100 |     100 |     100 |                   
  ...ebhook-ipc.ts |    98.5 |    86.66 |     100 |    98.5 | 47                
  ...worker-env.ts |     100 |      100 |     100 |     100 |                   
  ...supervisor.ts |   97.25 |     89.2 |   96.29 |   97.25 | ...,790,1011-1015 
  ...ub-session.ts |   92.04 |    77.77 |     100 |   92.04 | ...36-445,470,508 
  daemon-logger.ts |   98.31 |    87.32 |   96.55 |   98.31 | 119-120,205       
  ...trics-ring.ts |     100 |      100 |     100 |     100 |                   
  ...s-provider.ts |   68.04 |    52.77 |     100 |   68.04 | ...44-249,282-290 
  daemon-status.ts |   98.12 |    87.91 |     100 |   98.12 | ...58-960,962-963 
  debug-mode.ts    |     100 |      100 |     100 |     100 |                   
  demo.ts          |     100 |      100 |     100 |     100 |                   
  env-snapshot.ts  |    91.3 |       80 |     100 |    91.3 | ...24-127,205-212 
  ...-path-argv.ts |     100 |      100 |     100 |     100 |                   
  ...h-settings.ts |   94.39 |    88.75 |     100 |   94.39 | ...22,700,716,726 
  fast-path.ts     |   91.28 |    81.98 |   95.45 |   91.28 | ...64-473,539-540 
  index.ts         |       0 |        0 |       0 |       0 | 1-143             
  ...e-observer.ts |   89.89 |    83.24 |      96 |   89.89 | ...11-512,541-543 
  ...back-binds.ts |     100 |    88.88 |     100 |     100 | 32                
  ...sion-audit.ts |     100 |      100 |   93.33 |     100 |                   
  rate-limit.ts    |   92.77 |    88.42 |     100 |   92.77 | ...93-295,307-309 
  ...qwen-serve.ts |   79.35 |    81.17 |   70.41 |   79.35 | ...4389,4434-4437 
  ...tup-errors.ts |     100 |      100 |     100 |     100 |                   
  ...-keepalive.ts |   95.91 |    90.72 |     100 |   95.91 | ...26,486-488,524 
  ...-lifecycle.ts |     100 |      100 |     100 |     100 |                   
  server.ts        |   95.78 |    93.71 |   82.35 |   95.78 | ...1328,1385-1389 
  ...on-helpers.ts |      90 |      100 |     100 |      90 | 14                
  ...t-event-id.ts |     100 |    91.66 |     100 |     100 | 12                
  ...-admission.ts |   97.87 |    88.23 |     100 |   97.87 | 56                
  types.ts         |     100 |      100 |     100 |     100 |                   
  ...erver-name.ts |     100 |      100 |     100 |     100 |                   
  ...ion-limits.ts |     100 |      100 |     100 |     100 |                   
  ...l-resolver.ts |   90.32 |    66.66 |     100 |   90.32 | 16,45-46          
  ...ell-static.ts |   91.07 |     86.2 |     100 |   91.07 | ...79-182,216-219 
  ...ace-agents.ts |   57.12 |    67.04 |    86.2 |   57.12 | ...1820,1830-1840 
  ...ace-inputs.ts |     100 |      100 |     100 |     100 |                   
  ...-constants.ts |     100 |      100 |     100 |     100 |                   
  ...-summaries.ts |   86.66 |       50 |     100 |   86.66 | 11,19             
  ...ace-memory.ts |   82.19 |    73.86 |     100 |   82.19 | ...82-489,549-556 
  ...ers-status.ts |   97.32 |    81.19 |     100 |   97.32 | ...61,164,297-303 
  ...e-registry.ts |   84.71 |     90.9 |   92.85 |   84.71 | ...29-230,236-237 
  ...ber-errors.ts |     100 |    95.37 |     100 |     100 | 53,93-94,172,192  
  ...e-remember.ts |   97.75 |    93.58 |     100 |   97.75 | ...50,254-259,293 
  ...te-runtime.ts |   92.24 |    89.74 |     100 |   92.24 | 53-54,59,83-88    
  ...ls-mapping.ts |     100 |      100 |     100 |     100 |                   
  ...lls-status.ts |     100 |    94.44 |     100 |     100 | 102               
 ...serve/acp-http |   74.54 |    77.75 |   92.21 |   74.54 |                   
  ...r-registry.ts |     100 |    95.45 |     100 |     100 | 191               
  client-mcp-ws.ts |   54.85 |    58.62 |   72.72 |   54.85 | ...99-300,304-305 
  ...n-registry.ts |   97.59 |    88.95 |   97.56 |   97.59 | 1015,1035-1049    
  dispatch.ts      |   68.43 |    73.34 |     100 |   68.43 | ...4403,4451-4457 
  index.ts         |   79.76 |    78.89 |   84.61 |   79.76 | ...1920,1951-1953 
  json-rpc.ts      |     100 |    96.96 |     100 |     100 | 92                
  safe-ws-send.ts  |   52.94 |    71.42 |     100 |   52.94 | 33-42,47-55       
  sse-stream.ts    |   93.96 |    88.57 |   84.61 |   93.96 | ...57-159,161-163 
  ...ort-stream.ts |       0 |        0 |       0 |       0 | 1                 
  ws-stream.ts     |   91.86 |       80 |     100 |   91.86 | 45,50,96,100-103  
 src/serve/auth    |   86.86 |     79.6 |   93.87 |   86.86 |                   
  device-flow.ts   |   96.35 |    80.45 |   97.61 |   96.35 | ...1358,1453,1519 
  ...w-provider.ts |   44.24 |    74.07 |   71.42 |   44.24 | ...23-284,297,301 
 ...rve/cdp-tunnel |   85.73 |    73.17 |    97.5 |   85.73 |                   
  ...r-emulator.ts |   88.57 |    63.63 |     100 |   88.57 | ...72-175,194-195 
  ...verse-link.ts |      88 |    76.19 |     100 |      88 | ...28-329,420-423 
  ...l-registry.ts |     100 |      100 |     100 |     100 |                   
  cdp-ws.ts        |   76.28 |    61.29 |    87.5 |   76.28 | ...13-217,223-228 
 ...nel/acceptance |       0 |        0 |       0 |       0 |                   
  ...mcp-smoke.mjs |       0 |        0 |       0 |       0 | 1-119             
  ...cceptance.mjs |       0 |        0 |       0 |       0 | 1-473             
  real-tab.mjs     |       0 |        0 |       0 |       0 | 1-218             
 src/serve/fs      |   85.68 |    80.06 |     100 |   85.68 |                   
  audit.ts         |     100 |    96.15 |     100 |     100 | 204               
  errors.ts        |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...x-registry.ts |     100 |      100 |     100 |     100 |                   
  paths.ts         |   77.64 |     73.6 |     100 |   77.64 | ...65,594-598,611 
  policy.ts        |   90.32 |    89.18 |     100 |   90.32 | 142-150           
  ...ile-system.ts |   85.19 |     78.6 |     100 |   85.19 | ...2094,2104-2105 
 src/serve/routes  |   83.16 |    76.92 |   93.23 |   83.16 |                   
  a2ui-action.ts   |   99.49 |    94.52 |    87.5 |   99.49 | 250               
  capabilities.ts  |     100 |      100 |     100 |     100 |                   
  ...l-webhooks.ts |   93.56 |    81.81 |     100 |   93.56 | ...42,292,332,334 
  daemon-status.ts |   85.18 |    83.33 |     100 |   85.18 | 95-102            
  health-demo.ts   |    92.3 |    83.33 |     100 |    92.3 | 55-59             
  permission.ts    |     100 |     92.3 |     100 |     100 | 50,98             
  ...uled-tasks.ts |   82.67 |    83.57 |     100 |   82.67 | ...79-787,851-852 
  ...on-runtime.ts |   95.65 |    81.81 |     100 |   95.65 | 72-74             
  session.ts       |    83.6 |    79.84 |   92.85 |    83.6 | ...2739,2842-2876 
  sse-events.ts    |   86.25 |     88.6 |   77.77 |   86.25 | ...81,387,404-407 
  usage-stats.ts   |     100 |    95.65 |     100 |     100 | 116               
  ...space-auth.ts |    83.7 |       75 |     100 |    83.7 | ...23,328,340-344 
  ...el-control.ts |     100 |    83.33 |     100 |     100 | 39                
  ...extensions.ts |   84.51 |    72.96 |   86.36 |   84.51 | ...68-970,989-992 
  ...-file-read.ts |   92.32 |       80 |     100 |   92.32 | ...94-595,598-599 
  ...file-write.ts |   84.44 |    64.13 |     100 |   84.44 | ...73-275,355-357 
  ...-lifecycle.ts |   96.85 |       75 |     100 |   96.85 | 130-131,161-162   
  ...management.ts |   75.91 |       80 |     100 |   75.91 | ...57-162,177-185 
  ...cp-control.ts |   69.87 |     61.9 |     100 |   69.87 | ...46-452,461-462 
  ...ermissions.ts |   74.66 |    68.42 |     100 |   74.66 | ...25-233,254-271 
  ...e-settings.ts |   62.39 |    52.63 |     100 |   62.39 | ...15-420,429-439 
  ...tup-github.ts |   77.52 |    70.27 |   84.21 |   77.52 | ...87,309,352-353 
  ...ace-status.ts |   75.33 |    56.33 |     100 |   75.33 | ...34-335,359-360 
  ...pace-tools.ts |   74.82 |    69.23 |     100 |   74.82 | ...41-146,175-176 
  ...pace-trust.ts |   76.08 |       50 |   66.66 |   76.08 | ...01-206,214-215 
  ...pace-voice.ts |   87.09 |     82.6 |    90.9 |   87.09 | ...96,322-323,452 
 src/serve/server  |    88.2 |    87.78 |   94.28 |    88.2 |                   
  access-log.ts    |   97.72 |    95.45 |     100 |   97.72 | 51                
  ...er-helpers.ts |   63.82 |    77.96 |   81.81 |   63.82 | ...16,330,332-347 
  ...w-registry.ts |    98.8 |    86.95 |     100 |    98.8 | 107               
  ...r-handlers.ts |   97.14 |    71.42 |     100 |   97.14 | 16                
  ...r-response.ts |   81.83 |    71.85 |     100 |   81.83 | ...47,569,632-641 
  fs-factory.ts    |     100 |    92.59 |     100 |     100 | 33,41,100,156     
  ...t-deadline.ts |     100 |      100 |     100 |     100 |                   
  ...iter-setup.ts |      65 |    73.33 |   33.33 |      65 | 30-35,38-43,47-48 
  ...st-helpers.ts |   94.77 |    94.73 |     100 |   94.77 | ...31-133,387-392 
  self-origin.ts   |   76.19 |       80 |     100 |   76.19 | 45-54             
  ...e-features.ts |   93.06 |    91.66 |     100 |   93.06 | 130-136           
  ...on-archive.ts |   89.13 |    89.47 |    87.5 |   89.13 | ...17-422,494-504 
  ...ion-export.ts |     100 |    84.61 |     100 |     100 | 60,84             
  session-list.ts  |    93.2 |     90.3 |     100 |    93.2 | ...37-552,554-560 
  telemetry.ts     |   96.89 |    96.34 |     100 |   96.89 | ...57-259,349-351 
 src/serve/voice   |   79.61 |    89.42 |    82.6 |   79.61 |                   
  ...ice-config.ts |   96.77 |       30 |     100 |   96.77 | 85-86             
  voice-ws.ts      |   76.61 |    95.74 |      80 |   76.61 | ...94,409,447-449 
 ...kspace-service |   93.05 |    80.64 |   96.77 |   93.05 |                   
  index.ts         |   92.83 |    80.32 |   96.42 |   92.83 | ...02,925-929,932 
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/services      |   92.03 |    88.73 |   98.24 |   92.03 |                   
  ...mandLoader.ts |     100 |    88.88 |     100 |     100 | 103-116           
  ...killLoader.ts |     100 |    93.33 |     100 |     100 | 48,67             
  ...andService.ts |   98.73 |      100 |     100 |   98.73 | 107               
  ...mandLoader.ts |   86.83 |    83.87 |     100 |   86.83 | ...30-335,340-345 
  ...omptLoader.ts |   77.17 |    83.82 |   83.33 |   77.17 | ...43,168,210-211 
  ...mandLoader.ts |     100 |    97.36 |     100 |     100 | 66                
  ...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.23 |    96.72 |     100 |   98.23 | 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 |                   
  ...low-loader.ts |     100 |    96.15 |     100 |     100 | 88                
  setup-github.ts  |    90.5 |    81.81 |     100 |    90.5 | ...35-436,443-444 
  types.ts         |     100 |      100 |     100 |     100 |                   
  ...e-keyterms.ts |   98.64 |    95.71 |     100 |   98.64 | 116,142-143       
  voice-model.ts   |     100 |      100 |     100 |     100 |                   
  voice-service.ts |   85.99 |    87.09 |     100 |   85.99 | ...68,275,329-343 
  ...e-settings.ts |     100 |    95.45 |     100 |     100 | 19                
  ...ranscriber.ts |   90.56 |    82.35 |   95.83 |   90.56 | ...40-642,645-647 
 ...ght/generators |    88.3 |    85.49 |   92.59 |    88.3 |                   
  DataProcessor.ts |   88.22 |    85.48 |      95 |   88.22 | ...1341,1345-1352 
  ...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.27 |    84.61 |     100 |   97.27 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  tipHistory.ts    |   92.59 |       70 |     100 |   92.59 | ...24,146,153,162 
  tipRegistry.ts   |     100 |      100 |     100 |     100 |                   
  tipScheduler.ts  |     100 |    91.66 |     100 |     100 | 55                
 src/startup       |   88.08 |    82.52 |      90 |   88.08 |                   
  ...p-prefetch.ts |   98.75 |       95 |   85.71 |   98.75 | 44,168            
  ...reeStartup.ts |   80.53 |     74.6 |     100 |   80.53 | ...94,403,409-412 
 src/test-utils    |   94.04 |    83.33 |      80 |   94.04 |                   
  ...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            |   70.06 |    72.76 |   62.82 |   70.06 |                   
  App.tsx          |   33.33 |       75 |   33.33 |   33.33 | 32-86             
  AppContainer.tsx |   71.31 |    69.24 |   61.53 |   71.31 | ...3922,3926-3930 
  ...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.14 |     100 |   95.91 | 25-26             
  ...tic-colors.ts |     100 |      100 |     100 |     100 |                   
  ...ractiveUI.tsx |   57.47 |    31.57 |      40 |   57.47 | ...32-233,238-243 
  ...inePresets.ts |   96.27 |    83.87 |     100 |   96.27 | ...97,402,410-412 
  textConstants.ts |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/ui/auth       |   58.45 |    66.18 |   51.06 |   58.45 |                   
  AuthDialog.tsx   |   59.01 |     42.1 |   16.66 |   59.01 | ...25,332-354,358 
  ...nProgress.tsx |       0 |        0 |       0 |       0 | 1-64              
  ...etupSteps.tsx |   60.03 |    70.73 |   57.69 |   60.03 | ...87,791,800,803 
  useAuth.ts       |    94.6 |    73.52 |     100 |    94.6 | ...21-222,241-247 
  ...rSetupFlow.ts |   43.18 |    33.33 |      50 |   43.18 | ...78-399,416-459 
 src/ui/commands   |    80.1 |    82.72 |   88.48 |    80.1 |                   
  aboutCommand.ts  |     100 |      100 |     100 |     100 |                   
  agentsCommand.ts |   83.78 |      100 |      60 |   83.78 | 30-32,42-44       
  ...odeCommand.ts |   89.47 |    81.25 |     100 |   89.47 | 92-93,95-100      
  arenaCommand.ts  |   62.81 |    58.73 |   65.21 |   62.81 | ...90-595,680-688 
  authCommand.ts   |     100 |      100 |     100 |     100 |                   
  branchCommand.ts |     100 |      100 |     100 |     100 |                   
  btwCommand.ts    |   94.32 |    77.41 |     100 |   94.32 | 35-36,114-119     
  bugCommand.ts    |     100 |    77.77 |     100 |     100 | 27,61             
  cdCommand.ts     |    92.1 |     84.9 |     100 |    92.1 | ...4-69,94-99,178 
  clearCommand.ts  |    80.9 |    70.83 |     100 |    80.9 | ...24-125,133-142 
  ...essCommand.ts |   67.95 |    55.88 |      75 |   67.95 | ...86-187,201-204 
  ...astCommand.ts |   70.86 |    74.07 |      75 |   70.86 | ...,61-93,117-122 
  ...ig-command.ts |   93.12 |    88.42 |     100 |   93.12 | ...07-315,321-323 
  ...extCommand.ts |   67.46 |    69.69 |   84.61 |   67.46 | ...53-586,597-598 
  copyCommand.ts   |   98.49 |    95.78 |     100 |   98.49 | ...80,280,321,327 
  deleteCommand.ts |     100 |      100 |     100 |     100 |                   
  diffCommand.ts   |     100 |     87.5 |     100 |     100 | ...61,224-225,238 
  ...ryCommand.tsx |   81.43 |     88.4 |    90.9 |   81.43 | ...59-264,311-318 
  docsCommand.ts   |     100 |     90.9 |     100 |     100 | 25                
  doctorCommand.ts |   65.37 |    81.88 |   94.11 |   65.37 | ...85-535,538-672 
  dreamCommand.ts  |   85.45 |    88.88 |     100 |   85.45 | 58-65             
  editorCommand.ts |     100 |      100 |     100 |     100 |                   
  ...rt-command.ts |   82.97 |    78.57 |     100 |   82.97 | 47-52,67-70,91-96 
  exportCommand.ts |   98.25 |    91.02 |     100 |   98.25 | ...81,198-199,364 
  ...onsCommand.ts |    50.3 |    48.14 |   69.23 |    50.3 | ...08,262-314,375 
  forgetCommand.ts |     100 |       90 |     100 |     100 | 59                
  forkCommand.ts   |     100 |    94.11 |     100 |     100 | 96,147            
  goalCommand.ts   |   91.13 |    83.72 |      90 |   91.13 | ...78-181,193-196 
  helpCommand.ts   |     100 |      100 |     100 |     100 |                   
  ...oryCommand.ts |     100 |      100 |     100 |     100 |                   
  hooksCommand.ts  |   81.13 |    65.71 |   85.71 |   81.13 | ...,86-93,131-132 
  ideCommand.ts    |   60.75 |    64.28 |   41.17 |   60.75 | ...05-306,310-324 
  ...figCommand.ts |   52.83 |    81.25 |      70 |   52.83 | ...74-319,321-330 
  initCommand.ts   |   84.33 |    72.72 |     100 |   84.33 | 68,82-87,89-94    
  ...ghtCommand.ts |   77.87 |    71.42 |     100 |   77.87 | ...44-245,250-272 
  ...ageCommand.ts |   92.17 |    82.69 |     100 |   92.17 | ...39,159,168-178 
  lspCommand.ts    |     100 |    86.95 |     100 |     100 | 31,101-102        
  mcpCommand.ts    |     100 |      100 |     100 |     100 |                   
  memoryCommand.ts |     100 |      100 |     100 |     100 |                   
  modelCommand.ts  |    81.1 |     89.5 |   88.23 |    81.1 | ...80-793,827-832 
  ...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             
  ...ns-command.ts |   98.83 |    81.81 |     100 |   98.83 | 100               
  ...berCommand.ts |     100 |     87.5 |     100 |     100 | 46                
  renameCommand.ts |   85.71 |    86.04 |     100 |   85.71 | ...02-209,216-221 
  ...oreCommand.ts |    90.9 |    86.04 |     100 |    90.9 | ...41-146,176-177 
  resumeCommand.ts |     100 |      100 |     100 |     100 |                   
  rewindCommand.ts |   81.25 |      100 |      50 |   81.25 | 20-22             
  ...ngsCommand.ts |     100 |      100 |     100 |     100 |                   
  ...hubCommand.ts |   89.47 |       75 |      80 |   89.47 | 54-59             
  skillsCommand.ts |   78.82 |    81.81 |     100 |   78.82 | 37-52,78,97       
  statsCommand.ts  |    90.6 |    77.95 |     100 |    90.6 | ...91-694,785-792 
  ...ineCommand.ts |     100 |      100 |     100 |     100 |                   
  ...aryCommand.ts |    6.43 |      100 |      50 |    6.43 | 31-330            
  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 |                   
  ...te-command.ts |     100 |    92.59 |     100 |     100 | 69,118            
  vimCommand.ts    |   54.54 |      100 |      50 |   54.54 | 19-29             
  voice-command.ts |   93.57 |       88 |     100 |   93.57 | 35,97-102         
  ...owsCommand.ts |   91.82 |    78.87 |   66.66 |   91.82 | ...59-160,169-174 
 src/ui/components |   68.47 |    78.56 |   74.62 |   68.47 |                   
  AboutBox.tsx     |     100 |      100 |     100 |     100 |                   
  ...ateScreen.tsx |   97.29 |     87.5 |   66.66 |   97.29 | 49                
  AnsiOutput.tsx   |   65.57 |      100 |      50 |   65.57 | 69-90             
  ApiKeyInput.tsx  |       0 |        0 |       0 |       0 | 1-97              
  AppHeader.tsx    |    88.7 |       75 |     100 |    88.7 | 36,38-43,45       
  ...odeDialog.tsx |   87.24 |    72.22 |   33.33 |   87.24 | ...85,233-238,245 
  AsciiArt.ts      |     100 |      100 |     100 |     100 |                   
  ...Indicator.tsx |   95.65 |    66.66 |     100 |   95.65 | 27,52             
  ...TextInput.tsx |   86.72 |    86.66 |     100 |   86.72 | ...00-302,355-359 
  Composer.tsx     |   94.39 |    66.66 |     100 |   94.39 | ...-71,83,138,151 
  ...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 
  CronPill.tsx     |     100 |    93.75 |     100 |     100 | 18                
  ...ification.tsx |      84 |       60 |     100 |      84 | 23-24,40-42       
  ...gProfiler.tsx |       0 |        0 |       0 |       0 | 1-36              
  ...ogManager.tsx |       0 |        0 |       0 |       0 | 1-596             
  DiffDialog.tsx   |   31.17 |    19.51 |   30.76 |   31.17 | ...07-712,722-735 
  ...ngsDialog.tsx |       0 |        0 |       0 |       0 | 1-195             
  EffortDialog.tsx |   97.36 |      100 |     100 |   97.36 | 55-56             
  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       |    77.6 |    61.11 |     100 |    77.6 | ...17-222,240-244 
  ...ngSpinner.tsx |   68.42 |    85.71 |      50 |   68.42 | 35-52,73,80-81    
  GoalPill.tsx     |   83.33 |    76.92 |     100 |   83.33 | 24-30             
  Header.tsx       |   98.65 |    94.73 |     100 |   98.65 | 173,175           
  Help.tsx         |   98.32 |       90 |     100 |   98.32 | ...24,381,447-448 
  ...emDisplay.tsx |   74.35 |    62.19 |      75 |   74.35 | ...72,475,478-484 
  ...ngeDialog.tsx |     100 |      100 |     100 |     100 |                   
  InputPrompt.tsx  |   81.76 |    80.27 |   77.77 |   81.76 | ...2074,2100,2160 
  ...Shortcuts.tsx |   20.87 |      100 |       0 |   20.87 | ...6,49-51,67-125 
  ...Indicator.tsx |   98.18 |    97.82 |     100 |   98.18 | 161-162           
  ...firmation.tsx |   91.42 |      100 |      50 |   91.42 | 26-31             
  MainContent.tsx  |   98.18 |    94.64 |   66.66 |   98.18 | 90,168-172,474    
  MemoryDialog.tsx |   86.59 |    80.15 |     100 |   86.59 | ...34-435,485,553 
  ...geDisplay.tsx |       0 |        0 |       0 |       0 | 1-41              
  ModelDialog.tsx  |   86.41 |       73 |     100 |   86.41 | ...74,876,881-897 
  ...tsDisplay.tsx |     100 |    97.22 |     100 |     100 | 270               
  ...fications.tsx |       0 |        0 |       0 |       0 | 1-58              
  ...onsDialog.tsx |       0 |        0 |       0 |       0 | 1-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 |       0 |        0 |       0 |       0 | 1-134             
  ...geDisplay.tsx |     100 |      100 |     100 |     100 |                   
  ...ngDisplay.tsx |       0 |        0 |       0 |       0 | 1-39              
  ...hProgress.tsx |   85.25 |    88.46 |     100 |   85.25 | 121-147           
  ...dSelector.tsx |   92.79 |    82.65 |     100 |   92.79 | ...19-323,354-370 
  ...ionPicker.tsx |   83.66 |    72.13 |     100 |   83.66 | ...96,402,444-466 
  ...onPreview.tsx |   93.58 |    84.21 |     100 |   93.58 | ...,70-71,195-197 
  ...ryDisplay.tsx |     100 |      100 |     100 |     100 |                   
  ...putPrompt.tsx |   72.56 |       80 |      40 |   72.56 | ...06-109,114-117 
  ...tedDialog.tsx |     100 |      100 |     100 |     100 |                   
  ...ngsDialog.tsx |   71.27 |    73.89 |   69.23 |   71.27 | ...1240,1246-1247 
  ...ionDialog.tsx |    92.3 |    96.15 |   33.33 |    92.3 | 60-63,68-75,164   
  ...putPrompt.tsx |    15.9 |      100 |       0 |    15.9 | 20-63             
  ...Indicator.tsx |   57.14 |      100 |       0 |   57.14 | 12-15             
  ...MoreLines.tsx |       0 |        0 |       0 |       0 | 1-40              
  ...iewDialog.tsx |   97.78 |    87.67 |     100 |   97.78 | ...97,305-307,324 
  ...tsDisplay.tsx |   95.86 |       75 |     100 |   95.86 | 67-71             
  ...ionPicker.tsx |       0 |        0 |       0 |       0 | 1-172             
  ...tivityTab.tsx |    3.94 |      100 |       0 |    3.94 | 27-275            
  StatsDialog.tsx  |    8.64 |      100 |       0 |    8.64 | ...76-111,130-322 
  StatsDisplay.tsx |     100 |      100 |     100 |     100 |                   
  ...ciencyTab.tsx |    78.9 |    56.52 |     100 |    78.9 | ...26,213,262-288 
  ...atmapView.tsx |    8.98 |      100 |       0 |    8.98 | 20-107            
  ...essionTab.tsx |    5.46 |      100 |       0 |    5.46 | 24-215            
  ...ineDialog.tsx |    93.5 |    85.18 |     100 |    93.5 | ...05,267,287-289 
  ...yTodoList.tsx |   96.33 |    88.23 |     100 |   96.33 | 137-140           
  ...nsDisplay.tsx |    92.9 |       85 |     100 |    92.9 | ...04,207,234-236 
  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             
  ...criptView.tsx |   98.27 |    84.21 |     100 |   98.27 | 45,53             
  TrustDialog.tsx  |     100 |    81.81 |     100 |     100 | 71-86             
  ...ification.tsx |       0 |        0 |       0 |       0 | 1-22              
  ...Indicator.tsx |    92.5 |     87.5 |     100 |    92.5 | 50-53             
  ...ackDialog.tsx |       0 |        0 |       0 |       0 | 1-134             
  ...xitDialog.tsx |   80.36 |    43.47 |      60 |   80.36 | ...24-238,248-251 
  ...odeVisuals.ts |   97.22 |    85.71 |     100 |   97.22 | 25                
  ...s-helpers.tsx |   66.25 |    81.25 |      50 |   66.25 | 25-32,46-53,62-72 
 ...nts/agent-view |   53.72 |    70.87 |   42.85 |   53.72 |                   
  ...atContent.tsx |    9.09 |      100 |       0 |    9.09 | 54-275,281-283    
  ...tChatView.tsx |   21.05 |      100 |       0 |   21.05 | 21-39             
  ...tComposer.tsx |   64.78 |    29.41 |   33.33 |   64.78 | ...51,269,277-279 
  AgentFooter.tsx  |   15.38 |      100 |       0 |   15.38 | 28-65             
  AgentHeader.tsx  |   15.38 |      100 |       0 |   15.38 | 27-64             
  AgentTabBar.tsx  |    87.9 |    63.88 |     100 |    87.9 | ...88,110-118,136 
  ...oryAdapter.ts |     100 |    91.83 |     100 |     100 | 103,109-110,138   
  index.ts         |       0 |        0 |       0 |       0 | 1-12              
 ...mponents/arena |   42.38 |    68.69 |   73.68 |   42.38 |                   
  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 |       0 |        0 |       0 |       0 | 1-164             
  ...tusDialog.tsx |       0 |        0 |       0 |       0 | 1-288             
  ...topDialog.tsx |       0 |        0 |       0 |       0 | 1-213             
 ...ackground-view |   81.04 |    80.44 |   90.56 |   81.04 |                   
  ...sksDialog.tsx |   75.72 |    75.15 |      80 |   75.72 | ...1687,1709-1715 
  ...TasksPill.tsx |   67.03 |     86.2 |     100 |   67.03 | ...02-122,130-138 
  ...gentPanel.tsx |   97.14 |    86.45 |     100 |   97.14 | 132,455-459,527   
  agent-forest.ts  |    99.2 |    93.93 |     100 |    99.2 | 256               
  ...Visibility.ts |     100 |      100 |     100 |     100 |                   
  ...e-overlay.tsx |    88.2 |    76.47 |     100 |    88.2 | ...36-138,140-142 
 ...nts/extensions |   84.58 |    78.18 |   83.33 |   84.58 |                   
  ...gerDialog.tsx |   82.46 |    77.77 |     100 |   82.46 | ...89,191-198,258 
  TabBar.tsx       |   97.29 |    88.88 |     100 |   97.29 | 33                
  index.ts         |       0 |        0 |       0 |       0 | 1-12              
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...tensions/steps |   46.15 |    84.74 |   58.82 |   46.15 |                   
  ...ctionStep.tsx |   95.12 |    92.85 |   85.71 |   95.12 | 84-86,89          
  ...etailStep.tsx |       0 |        0 |       0 |       0 | 1-145             
  ...nListStep.tsx |   75.13 |    88.09 |   66.66 |   75.13 | ...52,173,202-208 
  ...electStep.tsx |       0 |        0 |       0 |       0 | 1-83              
  ...nfirmStep.tsx |   16.32 |      100 |       0 |   16.32 | 28-74             
  index.ts         |       0 |        0 |       0 |       0 | 1-11              
 ...xtensions/tabs |   66.18 |    67.65 |   66.66 |   66.18 |                   
  DiscoverTab.tsx  |   57.21 |     63.2 |   55.55 |   57.21 | ...98,661-665,669 
  InstalledTab.tsx |   71.62 |    68.65 |   83.33 |   71.62 | ...68,773-774,811 
  SourcesTab.tsx   |   69.25 |     70.4 |   66.66 |   69.25 | ...16,535,607-619 
 ...tensions/views |   23.73 |    44.82 |       5 |   23.73 |                   
  ...tionsView.tsx |    6.02 |      100 |       0 |    6.02 | 52-65,68-368      
  ...tionsView.tsx |   43.45 |    44.82 |    6.66 |   43.45 | ...98-405,408-420 
  ...etailView.tsx |    9.56 |      100 |       0 |    9.56 | 40-67,70-158      
 ...mponents/hooks |   86.85 |    81.37 |   91.89 |   86.85 |                   
  ...rListBody.tsx |   95.29 |    85.18 |     100 |   95.29 | 95-98             
  ...etailStep.tsx |   75.32 |    71.42 |      60 |   75.32 | ...56-169,173-186 
  ...etailStep.tsx |     100 |      100 |     100 |     100 |                   
  ...rListStep.tsx |     100 |      100 |     100 |     100 |                   
  ...entHeader.tsx |     100 |    85.71 |     100 |     100 | 47                
  ...rListStep.tsx |     100 |      100 |     100 |     100 |                   
  ...etailStep.tsx |     100 |      100 |     100 |     100 |                   
  ...abledStep.tsx |     100 |      100 |     100 |     100 |                   
  ...sListStep.tsx |     100 |      100 |     100 |     100 |                   
  ...entDialog.tsx |   72.29 |    70.49 |     100 |   72.29 | ...51,563-568,572 
  constants.ts     |     100 |      100 |     100 |     100 |                   
  index.ts         |       0 |        0 |       0 |       0 | 1-13              
  ...erGrouping.ts |     100 |      100 |     100 |     100 |                   
  sourceLabels.ts  |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...components/mcp |   40.96 |    61.53 |   70.58 |   40.96 |                   
  ...ealthPill.tsx |   68.42 |    85.71 |     100 |   68.42 | 40-46             
  ...entDialog.tsx |      33 |    26.19 |      40 |      33 | ...81,883,896-902 
  ...valDialog.tsx |   15.06 |      100 |       0 |   15.06 | 40-109            
  constants.ts     |     100 |      100 |     100 |     100 |                   
  index.ts         |       0 |        0 |       0 |       0 | 1-35              
  types.ts         |     100 |      100 |     100 |     100 |                   
  utils.ts         |      97 |       95 |     100 |      97 | 24,113-114        
 ...ents/mcp/steps |   54.25 |    74.31 |   57.14 |   54.25 |                   
  ...icateStep.tsx |    5.65 |      100 |       0 |    5.65 | 40-66,69-308      
  ...electStep.tsx |   10.95 |      100 |       0 |   10.95 | 16-88             
  ...etailStep.tsx |     100 |      100 |     100 |     100 |                   
  ...eListStep.tsx |   99.09 |    97.36 |     100 |   99.09 | 71                
  ...etailStep.tsx |    64.8 |    62.26 |   33.33 |    64.8 | ...75-284,295-317 
  ...rListStep.tsx |   88.46 |    81.25 |     100 |   88.46 | ...63,169,174-179 
  ...etailStep.tsx |    10.3 |      100 |       0 |    10.3 | ...1,67-79,82-140 
  ToolListStep.tsx |   69.29 |       50 |     100 |   69.29 | ...23,126,135-144 
 ...nents/messages |   87.56 |    84.09 |   80.68 |   87.56 |                   
  ...ionDialog.tsx |   86.88 |    81.25 |      80 |   86.88 | ...21,539,557-559 
  BtwMessage.tsx   |     100 |      100 |     100 |     100 |                   
  ...upDisplay.tsx |     100 |     88.7 |     100 |     100 | ...36,246,294,300 
  ...onMessage.tsx |   91.93 |    82.35 |     100 |   91.93 | 57-59,61,63       
  ...nMessages.tsx |   90.07 |    88.23 |    90.9 |   90.07 | ...22-328,385-391 
  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.6 |    88.46 |     100 |    95.6 | ...48,150,183-188 
  ...ssMessage.tsx |    12.5 |      100 |       0 |    12.5 | 18-59             
  ...edMessage.tsx |   16.66 |      100 |       0 |   16.66 | 22-38             
  ...sMessages.tsx |   58.65 |       50 |    37.5 |   58.65 | ...20-125,146-158 
  ...ryMessage.tsx |   14.28 |      100 |       0 |   14.28 | 23-62             
  ...onMessage.tsx |   82.31 |    74.02 |   33.33 |   82.31 | ...69-471,478-480 
  ...upMessage.tsx |    98.3 |    95.23 |     100 |    98.3 | 182-185,412       
  ToolMessage.tsx  |   91.49 |    83.62 |    92.3 |   91.49 | ...38-843,870-872 
 ...ponents/shared |   85.62 |    81.93 |   94.89 |   85.62 |                   
  ...ctionList.tsx |     100 |      100 |      75 |     100 |                   
  ...tonSelect.tsx |     100 |      100 |     100 |     100 |                   
  EnumSelector.tsx |     100 |    96.42 |     100 |     100 | 58                
  ...rBoundary.tsx |     100 |      100 |     100 |     100 |                   
  MaxSizedBox.tsx  |   83.01 |    86.25 |   88.88 |   83.01 | ...12-513,618-619 
  MultiSelect.tsx  |   93.58 |       75 |     100 |   93.58 | ...43,199-201,211 
  ...tonSelect.tsx |     100 |      100 |     100 |     100 |                   
  ...ontroller.tsx |     100 |    83.33 |     100 |     100 | 73,93-95          
  ...eSelector.tsx |     100 |       60 |     100 |     100 | 40-45             
  ...lableList.tsx |    82.7 |    84.84 |     100 |    82.7 | 46-64,71-74       
  StaticRender.tsx |   72.72 |      100 |     100 |   72.72 | 31-33             
  TextInput.tsx    |    80.8 |    67.24 |      80 |    80.8 | ...36-240,252-258 
  ...ontroller.tsx |     100 |    81.81 |     100 |     100 | 59-62             
  ...apsedTime.tsx |     100 |      100 |     100 |     100 |                   
  ...Indicator.tsx |     100 |      100 |     100 |     100 |                   
  ...lizedList.tsx |   88.57 |    85.11 |      90 |   88.57 | ...15,745-773,875 
  text-buffer.ts   |   85.94 |    81.73 |   97.91 |   85.94 | ...2651,2749-2750 
  ...er-actions.ts |   73.93 |    67.22 |     100 |   73.93 | ...32-733,934-936 
 ...ponents/skills |       0 |        0 |       0 |       0 |                   
  ...gerDialog.tsx |       0 |        0 |       0 |       0 | 1-678             
 ...ents/subagents |       0 |        0 |       0 |       0 |                   
  constants.ts     |       0 |        0 |       0 |       0 | 1-71              
  index.ts         |       0 |        0 |       0 |       0 | 1-11              
  reducers.tsx     |       0 |        0 |       0 |       0 | 1-190             
  types.ts         |       0 |        0 |       0 |       0 | 1-125             
  utils.ts         |       0 |        0 |       0 |       0 | 1-102             
 ...bagents/create |       0 |        0 |       0 |       0 |                   
  ...ionWizard.tsx |       0 |        0 |       0 |       0 | 1-299             
  ...rSelector.tsx |       0 |        0 |       0 |       0 | 1-85              
  ...onSummary.tsx |       0 |        0 |       0 |       0 | 1-331             
  ...tionInput.tsx |       0 |        0 |       0 |       0 | 1-177             
  ...dSelector.tsx |       0 |        0 |       0 |       0 | 1-63              
  ...nSelector.tsx |       0 |        0 |       0 |       0 | 1-58              
  ...EntryStep.tsx |       0 |        0 |       0 |       0 | 1-78              
  ToolSelector.tsx |       0 |        0 |       0 |       0 | 1-253             
 ...bagents/manage |   14.04 |    53.19 |    37.5 |   14.04 |                   
  ...ctionStep.tsx |       0 |        0 |       0 |       0 | 1-103             
  ...eleteStep.tsx |       0 |        0 |       0 |       0 | 1-62              
  ...tEditStep.tsx |       0 |        0 |       0 |       0 | 1-124             
  ...ctionStep.tsx |   35.42 |    59.52 |     100 |   35.42 | ...20-432,437-439 
  ...iewerStep.tsx |       0 |        0 |       0 |       0 | 1-73              
  ...gerDialog.tsx |       0 |        0 |       0 |       0 | 1-341             
 ...mponents/views |   69.77 |    72.38 |   61.11 |   69.77 |                   
  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.87 |    73.68 |     100 |   87.87 | 69-76             
  McpStatus.tsx    |   92.01 |     73.8 |     100 |   92.01 | ...36,175-177,262 
  SkillsList.tsx   |   20.51 |      100 |       0 |   20.51 | 17-20,27-57       
  ToolsList.tsx    |     100 |      100 |     100 |     100 |                   
 src/ui/contexts   |   82.14 |    79.27 |   84.37 |   82.14 |                   
  ...ewContext.tsx |   64.83 |    88.88 |      50 |   64.83 | ...16-219,225-235 
  AppContext.tsx   |      80 |       50 |     100 |      80 | 19-20             
  ...ewContext.tsx |   92.45 |    62.79 |      50 |   92.45 | ...69-270,272-276 
  ...igContext.tsx |   81.81 |       50 |     100 |   81.81 | 15-16             
  ...ssContext.tsx |   83.11 |    83.33 |     100 |   83.11 | ...1284,1292-1294 
  ...owContext.tsx |   91.07 |    81.81 |     100 |   91.07 | 47-48,60-62       
  ...deContext.tsx |     100 |      100 |      50 |     100 |                   
  ...onContext.tsx |   78.68 |    73.77 |   91.66 |   78.68 | ...86-389,398-401 
  ...gsContext.tsx |     100 |      100 |     100 |     100 |                   
  ...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             
  ...edContext.tsx |     100 |      100 |      50 |     100 |                   
  ...nsContext.tsx |   88.88 |       50 |     100 |   88.88 | 147-148           
  ...teContext.tsx |   86.66 |       50 |     100 |   86.66 | 233-234           
  ...deContext.tsx |      80 |     87.5 |      75 |      80 | ...11-112,118-120 
 src/ui/daemon     |   88.27 |    73.27 |   95.45 |   88.27 |                   
  ...ui-adapter.ts |   88.27 |    73.27 |   95.45 |   88.27 | ...66,784-785,871 
 src/ui/editors    |       0 |        0 |       0 |       0 |                   
  ...ngsManager.ts |       0 |        0 |       0 |       0 | 1-67              
 src/ui/hooks      |   83.71 |    81.71 |   88.38 |   83.71 |                   
  ...dProcessor.ts |   81.49 |    80.95 |     100 |   81.49 | ...33-734,740-745 
  ...ention-ref.ts |   97.67 |       84 |     100 |   97.67 | 63                
  keyToAnsi.ts     |    3.92 |      100 |       0 |    3.92 | 19-77             
  ...esourceRef.ts |     100 |      100 |     100 |     100 |                   
  ...dProcessor.ts |   94.62 |    73.58 |     100 |   94.62 | ...86-287,292-293 
  ...dProcessor.ts |   85.14 |    66.27 |   81.81 |   85.14 | ...1400,1421-1425 
  ...rt-command.ts |     100 |      100 |     100 |     100 |                   
  ...sced-flush.ts |     100 |      100 |     100 |     100 |                   
  ...oice-input.ts |   92.36 |    81.95 |   66.66 |   92.36 | ...00,502-503,658 
  ...amingState.ts |   12.22 |      100 |       0 |   12.22 | 54-157            
  ...agerDialog.ts |   88.23 |      100 |     100 |   88.23 | 20,24             
  ...dScrollbar.ts |     100 |      100 |     100 |     100 |                   
  ...ationFrame.ts |      52 |    63.63 |     100 |      52 | ...59,67-70,76-87 
  ...odeCommand.ts |   58.82 |      100 |     100 |   58.82 | 28,33-48          
  ...enaCommand.ts |      85 |      100 |     100 |      85 | 23-24,29          
  ...aInProcess.ts |   27.92 |       80 |      25 |   27.92 | ...69-170,173-175 
  ...Completion.ts |   89.83 |    88.97 |     100 |   89.83 | ...49-456,496-505 
  ...ifications.ts |   86.91 |    96.29 |     100 |   86.91 | 116-130           
  ...tIndicator.ts |   88.28 |    81.08 |     100 |   88.28 | ...66,175,179-187 
  ...waySummary.ts |   96.22 |    69.69 |     100 |   96.22 | 125-127,169       
  ...ndTaskView.ts |   94.73 |    76.59 |     100 |   94.73 | 162-166,255,261   
  ...chedScroll.ts |     100 |      100 |     100 |     100 |                   
  ...ketedPaste.ts |    23.8 |      100 |       0 |    23.8 | 19-37             
  ...nchCommand.ts |   93.37 |     73.8 |     100 |   93.37 | ...37,186,259-262 
  ...ompletion.tsx |   96.75 |    81.81 |     100 |   96.75 | ...78-279,289-290 
  ...dMigration.ts |    92.1 |    88.88 |     100 |    92.1 | 42-44             
  useCompletion.ts |   94.11 |    89.65 |     100 |   94.11 | ...32-133,137-138 
  ...nitMessage.ts |     100 |      100 |     100 |     100 |                   
  ...extualTips.ts |   78.26 |       50 |     100 |   78.26 | ...2,75-79,96-104 
  ...eteCommand.ts |   78.53 |    88.57 |     100 |   78.53 | ...96-104,112-113 
  ...ialogClose.ts |   36.11 |       10 |     100 |   36.11 | ...89-195,202-207 
  useDiffData.ts   |       0 |        0 |       0 |       0 | 1-87              
  ...oublePress.ts |   53.12 |       75 |     100 |   53.12 | 33-35,41-54       
  ...orSettings.ts |     100 |      100 |     100 |     100 |                   
  ...Completion.ts |   99.12 |     97.7 |     100 |   99.12 | 182-183           
  ...ionUpdates.ts |    93.5 |     92.3 |     100 |    93.5 | ...87-291,304-310 
  ...agerDialog.ts |   88.88 |      100 |     100 |   88.88 | 21,25             
  ...backDialog.ts |    63.9 |    76.47 |   66.66 |    63.9 | ...66-168,190-191 
  useFocus.ts      |     100 |      100 |     100 |     100 |                   
  ...olderTrust.ts |     100 |      100 |     100 |     100 |                   
  ...ggestions.tsx |   96.47 |    78.94 |     100 |   96.47 | 121,155-156       
  ...miniStream.ts |   83.36 |     80.2 |   95.65 |   83.36 | ...3589,3674-3682 
  ...BranchName.ts |     100 |    91.66 |     100 |     100 | 30                
  ...oryManager.ts |   98.01 |    98.36 |     100 |   98.01 | 139-142           
  ...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 |       0 |        0 |       0 |       0 | 1-90              
  ...gIndicator.ts |     100 |    96.66 |     100 |     100 | 109               
  useLogger.ts     |      16 |      100 |       0 |      16 | 15-45             
  useMCPHealth.ts  |   63.15 |       80 |      50 |   63.15 | 42-52,64-67       
  ...cpApproval.ts |   93.12 |    86.11 |     100 |   93.12 | ...24-127,139-140 
  useMcpDialog.ts  |    87.5 |      100 |     100 |    87.5 | 19,23             
  ...moryDialog.ts |    87.5 |      100 |     100 |    87.5 | 19,23             
  ...oryMonitor.ts |   83.14 |    78.57 |     100 |   83.14 | 54-63,74-79       
  ...ssageQueue.ts |     100 |      100 |     100 |     100 |                   
  ...delCommand.ts |     100 |    92.85 |     100 |     100 | 48                
  ...ouseEvents.ts |   94.31 |     97.5 |   83.33 |   94.31 | 76-80             
  ...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.95 |    77.41 |   91.66 |   86.95 | ...70,311-323,371 
  useQwenAuth.ts   |     100 |      100 |     100 |     100 |                   
  ...lScheduler.ts |   88.72 |    92.15 |     100 |   88.72 | ...75-280,395-405 
  ...oryCommand.ts |       0 |        0 |       0 |       0 | 1-7               
  ...tleRepaint.ts |     100 |      100 |     100 |     100 |                   
  ...umeCommand.ts |   93.66 |    72.41 |     100 |   93.66 | ...17,155,196-201 
  ...ompletion.tsx |   90.67 |    83.33 |     100 |   90.67 | ...02,105,138-141 
  ...ectionList.ts |   97.12 |    96.22 |     100 |   97.12 | ...92-193,247-250 
  ...sionPicker.ts |   92.87 |    90.35 |     100 |   92.87 | ...99-501,503-505 
  ...earchInput.ts |     100 |    97.29 |     100 |     100 | 82                
  ...ngsCommand.ts |   18.75 |      100 |       0 |   18.75 | 10-25             
  ...ellHistory.ts |   93.28 |    80.95 |     100 |   93.28 | ...96,153-154,164 
  ...oryCommand.ts |       0 |        0 |       0 |       0 | 1-73              
  ...agerDialog.ts |   88.23 |      100 |     100 |   88.23 | 20,24             
  ...Completion.ts |   82.85 |    85.13 |   94.73 |   82.85 | ...78-680,688-724 
  ...tateAndRef.ts |     100 |      100 |     100 |     100 |                   
  ...tatsDialog.ts |     100 |      100 |     100 |     100 |                   
  useStatusLine.ts |   97.13 |    93.33 |     100 |   97.13 | ...78-382,478-485 
  ...eateDialog.ts |   88.23 |      100 |     100 |   88.23 | 14,18             
  ...mInProcess.ts |   27.35 |       80 |      25 |   27.35 | ...82-183,186-188 
  ...tification.ts |     100 |     87.5 |     100 |     100 | 50                
  ...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      |   97.59 |    94.73 |     100 |   97.59 | 17-18             
  ...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 | 47-48,72          
  vim.ts           |      74 |    67.56 |   69.23 |      74 | ...1854-1861,1869 
 src/ui/layouts    |    90.9 |    90.62 |     100 |    90.9 |                   
  ...AppLayout.tsx |   90.72 |       90 |     100 |   90.72 | 57-59,101-106     
  ...AppLayout.tsx |   91.17 |    91.66 |     100 |   91.17 | 70-75             
 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 |    6.66 |     100 |                   
  ...eractiveUi.ts |     100 |      100 |    6.66 |     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.5 |    73.17 |     100 |    98.5 |                   
  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   |   99.23 |    97.05 |     100 |   99.23 | 277-278           
  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 |   88.68 |    84.52 |     100 |   88.68 | ...83-392,397-398 
  theme.ts         |     100 |    38.02 |     100 |     100 | ...34-449,457-461 
  xcode.ts         |     100 |      100 |     100 |     100 |                   
 src/ui/utils      |   84.86 |    84.05 |   93.71 |   84.86 |                   
  ...Colorizer.tsx |   80.42 |    85.41 |     100 |   80.42 | ...00-201,298-324 
  ...nRenderer.tsx |   68.83 |    70.14 |      50 |   68.83 | ...52-254,274-293 
  ...wnDisplay.tsx |   92.55 |    93.33 |     100 |   92.55 | ...56,896,943-961 
  ...idDiagram.tsx |   87.79 |    95.34 |     100 |   87.79 | 156-179           
  ...eRenderer.tsx |   92.68 |    82.35 |   95.23 |   92.68 | ...34-737,790-795 
  ...odeDisplay.ts |   94.28 |    85.71 |     100 |   94.28 | 23,40             
  asciiCharts.ts   |   96.77 |    87.62 |     100 |   96.77 | 173-180,281       
  ...dWorkUtils.ts |     100 |      100 |     100 |     100 |                   
  ...boardUtils.ts |   51.92 |    72.72 |   91.66 |   51.92 | ...21,624-633,636 
  commandUtils.ts  |    96.1 |    88.77 |     100 |    96.1 | ...73,175-176,320 
  computeStats.ts  |     100 |      100 |     100 |     100 |                   
  customBanner.ts  |   90.68 |    91.22 |     100 |   90.68 | ...13,324-327,334 
  displayUtils.ts  |   90.38 |    73.91 |     100 |   90.38 | 23,25,29,31,33    
  formatters.ts    |    95.4 |    98.41 |     100 |    95.4 | 123-126           
  gradientUtils.ts |     100 |      100 |     100 |     100 |                   
  highlight.ts     |     100 |      100 |     100 |     100 |                   
  ...gap-notice.ts |     100 |      100 |     100 |     100 |                   
  ...oryMapping.ts |     100 |       95 |     100 |     100 | 44,103            
  historyUtils.ts  |    95.4 |    95.08 |     100 |    95.4 | 96-99             
  input-mouse.ts   |     100 |    85.71 |     100 |     100 | 48,93             
  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 |                   
  list-mouse.ts    |     100 |      100 |     100 |     100 |                   
  ...ightLoader.ts |     100 |       95 |     100 |     100 | 81                
  ...nUtilities.ts |   95.72 |    94.23 |     100 |   95.72 | 90-92,137-138     
  ...t-position.ts |     100 |     87.5 |     100 |     100 | 85                
  ...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                
  mouse.ts         |   92.85 |    73.77 |     100 |   92.85 | ...38,145,149-152 
  osc8.ts          |   94.84 |    88.74 |     100 |   94.84 | ...57,442,446-447 
  ...red-height.ts |   96.85 |    95.31 |     100 |   96.85 | 71-73,201-203     
  ...mConstants.ts |     100 |      100 |     100 |     100 |                   
  restoreGoal.ts   |   99.02 |    97.56 |     100 |   99.02 | 106               
  ...storyUtils.ts |   71.02 |    78.86 |   93.75 |   71.02 | ...03-525,655-656 
  ...ickerUtils.ts |     100 |      100 |     100 |     100 |                   
  ...evel-label.ts |   77.77 |    66.66 |     100 |   77.77 | 18,22-24          
  ...are-cursor.ts |   89.47 |    85.71 |     100 |   89.47 | 39-44             
  ...ataService.ts |   93.17 |     79.1 |     100 |   93.17 | ...14,227,254-256 
  ...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     |   94.27 |    90.74 |   94.11 |   94.27 | ...89-290,450-451 
  ...background.ts |     100 |      100 |     100 |     100 |                   
  todoSnapshot.ts  |   89.33 |    93.47 |     100 |   89.33 | ...,66-78,180-181 
  updateCheck.ts   |     100 |       80 |     100 |     100 | 37-49,120         
  ...ow-keyword.ts |     100 |      100 |     100 |     100 |                   
 ...i/utils/export |   74.23 |    56.04 |   94.59 |   74.23 |                   
  collect.ts       |   71.21 |    63.06 |      96 |   71.21 | ...88-631,653-654 
  index.ts         |     100 |      100 |     100 |     100 |                   
  normalize.ts     |   78.57 |    44.92 |     100 |   78.57 | ...40-345,357-359 
  types.ts         |       0 |        0 |       0 |       0 | 1                 
  utils.ts         |     100 |      100 |     100 |     100 |                   
 ...ort/formatters |   52.92 |    42.42 |   71.42 |   52.92 |                   
  html.ts          |   84.61 |       50 |     100 |   84.61 | ...53,57-58,62-63 
  json.ts          |     100 |      100 |     100 |     100 |                   
  jsonl.ts         |   82.45 |    28.57 |     100 |   82.45 | ...48,50-51,65-66 
  markdown.ts      |   36.32 |       40 |      50 |   36.32 | ...16-219,233-295 
 src/ui/voice      |   81.12 |    73.04 |    79.1 |   81.12 |                   
  ...d-recorder.ts |     6.2 |      100 |       0 |     6.2 | ...33-159,162-163 
  ...o-recorder.ts |   84.61 |    93.33 |   57.14 |   84.61 | ...16-117,131-136 
  ...me-session.ts |   91.14 |     64.7 |   92.85 |   91.14 | ...76,282,292-295 
  sox-recorder.ts  |    92.7 |    71.87 |     100 |    92.7 | ...34-135,153-154 
  ...ailability.ts |     100 |      100 |     100 |     100 |                   
  ...e-keyterms.ts |     100 |      100 |     100 |     100 |                   
  voice-model.ts   |     100 |      100 |     100 |     100 |                   
  ...e-recorder.ts |   88.29 |    67.74 |   81.81 |   88.29 | ...,98-99,112,115 
  voice-refine.ts  |     100 |    93.33 |     100 |     100 | 92                
  ...ream-retry.ts |     100 |    88.88 |     100 |     100 | 18                
  ...am-session.ts |   87.45 |    63.33 |   81.81 |   87.45 | ...03,320-322,339 
  ...ranscriber.ts |     100 |      100 |     100 |     100 |                   
 src/utils         |   75.88 |    88.17 |   89.59 |   75.88 |                   
  acpModelUtils.ts |   95.49 |    94.23 |     100 |   95.49 | 44,68-69,73-74    
  apiPreconnect.ts |   96.72 |    97.05 |     100 |   96.72 | 165-168           
  ...ol-call-id.ts |    92.3 |    83.33 |     100 |    92.3 | 26-27             
  checks.ts        |   33.33 |      100 |       0 |   33.33 | 23-28             
  cleanup.ts       |   82.53 |    93.33 |      80 |   82.53 | 74,105-115        
  commands.ts      |   96.96 |    97.95 |     100 |   96.96 | 123-125           
  commentJson.ts   |   90.51 |     92.1 |     100 |   90.51 | 67-76,116         
  ...Calculator.ts |     100 |      100 |     100 |     100 |                   
  cpuProfiler.ts   |   70.73 |    73.23 |   88.88 |   70.73 | ...27,430-431,438 
  deepMerge.ts     |     100 |       90 |     100 |     100 | 41-43,49          
  ...ScopeUtils.ts |   97.56 |    88.88 |     100 |   97.56 | 67                
  doctorChecks.ts  |   70.31 |    74.57 |     100 |   70.31 | ...95-301,325-341 
  ...putCapture.ts |   90.65 |    86.17 |     100 |   90.65 | ...72,370,372-373 
  ...arResolver.ts |   97.14 |    96.55 |     100 |   97.14 | 125-126           
  errors.ts        |   90.85 |    96.36 |    92.3 |   90.85 | 69-70,298-310     
  events.ts        |     100 |      100 |     100 |     100 |                   
  ...on-mention.ts |   88.48 |     82.6 |     100 |   88.48 | ...56-160,164-168 
  gitUtils.ts      |    92.7 |    84.09 |     100 |    92.7 | ...07-110,158-161 
  ...AutoUpdate.ts |   92.89 |    94.59 |   88.88 |   92.89 | 148-159           
  ...tyWarnings.ts |     100 |      100 |     100 |     100 |                   
  ...lationInfo.ts |   97.45 |       94 |     100 |   97.45 | ...17,334-335,380 
  languageUtils.ts |   98.47 |    97.72 |     100 |   98.47 | 153-154           
  math.ts          |       0 |        0 |       0 |       0 | 1-15              
  ...er-mention.ts |     100 |    66.66 |     100 |     100 | 14,30,44-46       
  ...iagnostics.ts |   94.57 |    83.01 |   88.88 |   94.57 | ...05,311,315-317 
  ...serMessage.ts |     100 |      100 |     100 |     100 |                   
  ...onfigUtils.ts |   94.19 |    90.97 |     100 |   94.19 | ...28,434,437-441 
  ...iveHelpers.ts |   95.33 |    92.08 |     100 |   95.33 | ...51-452,550,563 
  osc.ts           |    97.5 |      100 |   88.88 |    97.5 | 195-196           
  package.ts       |   88.88 |    85.71 |     100 |   88.88 | 31-32             
  processUtils.ts  |     100 |      100 |     100 |     100 |                   
  readStdin.ts     |   93.67 |    94.11 |   85.71 |   93.67 | 79-83             
  relaunch.ts      |   93.22 |    81.25 |     100 |   93.22 | 65-67,80          
  resolvePath.ts   |     100 |      100 |     100 |     100 |                   
  runBudget.ts     |   99.35 |    96.77 |     100 |   99.35 | 119               
  sandbox-path.ts  |     100 |      100 |     100 |     100 |                   
  sandbox.ts       |   11.46 |    23.52 |   16.66 |   11.46 | ...5-763,770-1047 
  ...xImageName.ts |     100 |    77.77 |     100 |     100 | 10,18             
  sandboxMounts.ts |     100 |      100 |     100 |     100 |                   
  sessionPaths.ts  |   90.84 |    90.56 |     100 |   90.84 | ...81-182,185-186 
  settingsUtils.ts |   82.37 |    88.75 |      90 |   82.37 | ...20-738,745-753 
  spawnWrapper.ts  |     100 |      100 |     100 |     100 |                   
  ...ate-verify.ts |     100 |      100 |     100 |     100 |                   
  ...one-update.ts |   40.22 |    77.44 |   62.16 |   40.22 | ...1181,1184-1203 
  ...upProfiler.ts |   98.47 |    94.66 |     100 |   98.47 | 132-133,308       
  ...upWarnings.ts |     100 |      100 |     100 |     100 |                   
  stdioHelpers.ts  |     100 |       60 |     100 |     100 | 23,32             
  systemInfo.ts    |   95.12 |    90.27 |     100 |   95.12 | ...54-255,260-264 
  ...InfoFields.ts |    87.5 |    65.85 |     100 |    87.5 | ...24-125,146-147 
  ...alSequence.ts |     100 |    97.61 |     100 |     100 | 60                
  ...iffPreview.ts |   94.11 |    83.33 |     100 |   94.11 | 13                
  ...entEmitter.ts |     100 |      100 |     100 |     100 |                   
  ...ansionHook.ts |     100 |      100 |     100 |     100 |                   
  ...upWarnings.ts |   87.75 |       75 |     100 |   87.75 | 47-48,53-54,57-58 
  version.ts       |     100 |    66.66 |     100 |     100 | 11                
  ...ingHandler.ts |     100 |      100 |     100 |     100 |                   
  windowTitle.ts   |   95.45 |    93.33 |     100 |   95.45 | 54-55             
  ...WithBackup.ts |   65.04 |    77.77 |     100 |   65.04 | 97,112,133-172    
 ...s/housekeeping |   91.63 |    91.02 |      95 |   91.63 |                   
  cleanup.ts       |   95.77 |    95.83 |     100 |   95.77 | 70-72             
  ...eractionAt.ts |     100 |      100 |     100 |     100 |                   
  scheduler.ts     |   91.91 |    90.47 |    87.5 |   91.91 | 58-62,73,131-135  
  throttledOnce.ts |   86.66 |     86.2 |     100 |   86.66 | ...99,105,137-138 
-------------------|---------|----------|---------|---------|-------------------
Core Package - Full Text Report
-------------------|---------|----------|---------|---------|-------------------
File               | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
-------------------|---------|----------|---------|---------|-------------------
All files          |   85.87 |    85.29 |   87.33 |   85.87 |                   
 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        |   90.37 |    83.44 |   95.36 |   90.37 |                   
  ...transcript.ts |    92.6 |     87.5 |     100 |    92.6 | ...46,365-366,497 
  ...ent-resume.ts |   83.52 |    72.79 |   79.41 |   83.52 | ...1284-1288,1291 
  ...ound-tasks.ts |   96.53 |     90.4 |     100 |   96.53 | ...1353,1373-1376 
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...ent-result.ts |    96.8 |    92.68 |     100 |    96.8 | 106,129-131       
  ...n-registry.ts |   95.65 |    89.28 |     100 |   95.65 | ...12-413,485-489 
  ...w-snapshot.ts |   91.86 |       75 |     100 |   91.86 | ...54,178,185-187 
 src/agents/arena  |   76.25 |     67.5 |   78.94 |   76.25 |                   
  ...gentClient.ts |   79.47 |    88.88 |   81.81 |   79.47 | ...68-183,189-204 
  ArenaManager.ts  |   75.01 |    64.22 |   78.57 |   75.01 | ...1874,1880-1881 
  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 |   77.89 |    84.85 |   76.28 |   77.89 |                   
  ITermBackend.ts  |   97.97 |    93.93 |     100 |   97.97 | ...78-180,255,307 
  ...essBackend.ts |   90.17 |    84.12 |   93.33 |   90.17 | ...71,673,675-676 
  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 |   88.49 |    85.84 |   83.54 |   88.49 |                   
  agent-context.ts |     100 |      100 |     100 |     100 |                   
  agent-core.ts    |   79.97 |    76.22 |      68 |   79.97 | ...2030,2057-2104 
  agent-events.ts  |     100 |      100 |     100 |     100 |                   
  ...t-headless.ts |   87.93 |    79.06 |   63.63 |   87.93 | ...00-401,404-405 
  ...nteractive.ts |   81.01 |    82.35 |   76.66 |   81.01 | ...33,535-538,541 
  ...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 |                   
  ...ool-policy.ts |   98.34 |      100 |    92.3 |   98.34 | 81-82             
  ...low-budget.ts |     100 |      100 |     100 |     100 |                   
  ...ow-journal.ts |   91.76 |    75.86 |     100 |   91.76 | ...38-139,179-181 
  ...chestrator.ts |   91.79 |    87.79 |   82.35 |   91.79 | ...1774,1823-1826 
  ...ow-prompts.ts |     100 |      100 |     100 |     100 |                   
  ...ow-sandbox.ts |   96.87 |    94.51 |     100 |   96.87 | ...24-325,330-331 
  ...flow-saved.ts |   96.51 |    94.36 |     100 |   96.51 | 134-135,234-237   
  ...flow-stall.ts |    97.9 |    83.33 |     100 |    97.9 | 138-139,236       
 src/agents/tasks  |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/agents/team   |   81.86 |    84.09 |    87.4 |   81.86 |                   
  TeamManager.ts   |    72.1 |     79.6 |   78.84 |    72.1 | ...1628,1651-1652 
  identity.ts      |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...sionBridge.ts |     100 |      100 |     100 |     100 |                   
  mailbox.ts       |   94.76 |    86.36 |   92.85 |   94.76 | 86-87,348-354     
  ...ptAddendum.ts |     100 |      100 |     100 |     100 |                   
  tasks.ts         |   88.85 |    82.56 |   96.29 |   88.85 | ...-990,1034-1035 
  team-events.ts   |   60.52 |      100 |      50 |   60.52 | ...37-141,148-152 
  teamHelpers.ts   |   92.02 |    94.91 |   95.23 |   92.02 | ...31-332,368-378 
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...eam/test-utils |   94.39 |    94.26 |   98.21 |   94.39 |                   
  ...on-harness.ts |   96.49 |    84.21 |     100 |   96.49 | 128-129,141-142   
  fake-agent.ts    |   98.49 |    95.08 |     100 |   98.49 | 201-203           
  fake-backend.ts  |   86.46 |    97.61 |   95.83 |   86.46 | 124-146           
 src/config        |   80.62 |    85.37 |   70.95 |   80.62 |                   
  approval-mode.ts |     100 |      100 |     100 |     100 |                   
  ...xtDefaults.ts |     100 |      100 |     100 |     100 |                   
  config.ts        |   79.39 |    84.83 |   68.32 |   79.39 | ...6704,6708-6709 
  constants.ts     |     100 |      100 |     100 |     100 |                   
  models.ts        |     100 |      100 |     100 |     100 |                   
  storage.ts       |   94.63 |    91.86 |   89.58 |   94.63 | ...15-416,419-420 
 ...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          |   90.47 |     85.6 |    92.5 |   90.47 |                   
  baseLlmClient.ts |   87.19 |    79.68 |      80 |   87.19 | ...18,631,685-687 
  client.ts        |   89.89 |    83.61 |   90.76 |   89.89 | ...2870,2966-2967 
  ...tGenerator.ts |   88.07 |       75 |     100 |   88.07 | ...89-393,401-405 
  ...lScheduler.ts |   89.71 |    84.34 |   95.65 |   89.71 | ...4840,4868-4879 
  geminiChat.ts    |   90.41 |    86.98 |    95.4 |   90.41 | ...3850,3917-3918 
  geminiRequest.ts |     100 |      100 |     100 |     100 |                   
  ...MediaLimit.ts |     100 |    95.83 |     100 |     100 | 96                
  ...htProtocol.ts |    9.09 |      100 |       0 |    9.09 | ...9,62-66,69-110 
  logger.ts        |   87.41 |    87.02 |     100 |   87.41 | ...64-568,614-628 
  ...tyDefaults.ts |     100 |      100 |     100 |     100 |                   
  ...olExecutor.ts |   92.59 |       75 |      50 |   92.59 | 41-42             
  ...on-helpers.ts |   87.61 |    76.92 |     100 |   87.61 | ...00-201,215-224 
  ...issionFlow.ts |   98.79 |       96 |     100 |   98.79 | 97                
  prompts.ts       |   88.93 |    89.55 |   72.72 |   88.93 | ...-910,1113-1114 
  ...ing-effort.ts |     100 |      100 |     100 |     100 |                   
  ...t-profiler.ts |   96.82 |     80.3 |   88.23 |   96.82 | ...08,115-116,121 
  ...port-retry.ts |     100 |      100 |     100 |     100 |                   
  tokenLimits.ts   |     100 |    91.42 |     100 |     100 | 87,122-123        
  ...allIdUtils.ts |   98.23 |     92.1 |     100 |   98.23 | 36,45             
  ...okTriggers.ts |   99.45 |    92.43 |     100 |   99.45 | 182,193           
  ...terruption.ts |     100 |       92 |     100 |     100 | 86,104            
  turn.ts          |   98.49 |    91.17 |     100 |   98.49 | ...93,621-622,668 
 ...ntentGenerator |   95.75 |       85 |      95 |   95.75 |                   
  ...tGenerator.ts |   97.04 |    85.21 |   94.11 |   97.04 | ...1223,1251-1253 
  converter.ts     |   95.37 |    84.82 |     100 |   95.37 | ...7,843,998-1000 
  index.ts         |       0 |        0 |       0 |       0 | 1-21              
  usage.ts         |     100 |      100 |     100 |     100 |                   
 ...ntentGenerator |   89.93 |    71.83 |   93.33 |   89.93 |                   
  ...tGenerator.ts |    88.3 |    71.21 |   92.85 |    88.3 | ...19-325,343-344 
  index.ts         |     100 |       80 |     100 |     100 | 50                
 ...ntentGenerator |   94.61 |    84.69 |    92.1 |   94.61 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...tGenerator.ts |   94.51 |    83.39 |   91.66 |   94.51 | ...1113-1114,1142 
  ...tDetection.ts |     100 |      100 |     100 |     100 |                   
 ...ntentGenerator |   90.04 |    86.41 |   94.56 |   90.04 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  converter.ts     |   88.77 |    83.53 |   96.29 |   88.77 | ...1575,1744-1759 
  errorHandler.ts  |     100 |      100 |     100 |     100 |                   
  index.ts         |   60.31 |       75 |      50 |   60.31 | ...71,74-78,90-94 
  ...tGenerator.ts |    66.4 |    70.58 |   88.88 |    66.4 | ...51-157,168-169 
  pipeline.ts      |   96.32 |    88.54 |     100 |   96.32 | ...16-917,925,993 
  ...ureContext.ts |     100 |      100 |     100 |     100 |                   
  ...ingOptions.ts |       0 |        0 |       0 |       0 | 1                 
  ...CallParser.ts |   91.66 |    89.24 |     100 |   91.66 | ...89-390,427-428 
  ...kingParser.ts |     100 |    96.87 |     100 |     100 | 42                
  types.ts         |       0 |        0 |       0 |       0 | 1                 
 ...rator/provider |   96.47 |    89.51 |   96.49 |   96.47 |                   
  dashscope.ts     |   97.43 |    91.72 |   94.73 |   97.43 | ...70-371,513-514 
  deepseek.ts      |   94.91 |    89.36 |     100 |   94.91 | ...31-132,145-146 
  default.ts       |    97.5 |    96.55 |   88.88 |    97.5 | 123-124,198       
  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 |                   
  types.ts         |       0 |        0 |       0 |       0 |                   
  utils.ts         |     100 |      100 |     100 |     100 |                   
  zai.ts           |   92.13 |    82.14 |     100 |   92.13 | ...,39-40,135-137 
 src/extension     |   80.33 |    79.52 |   88.15 |   80.33 |                   
  ...-converter.ts |   78.29 |    70.87 |     100 |   78.29 | ...1108,1153-1154 
  corruptFile.ts   |     100 |       50 |     100 |     100 | 40-45             
  ...-converter.ts |    73.8 |       75 |     100 |    73.8 | 44-54             
  ...me-refresh.ts |     100 |      100 |     100 |     100 |                   
  ...ionManager.ts |   69.44 |    68.27 |   68.33 |   69.44 | ...1667,1689-1690 
  ...references.ts |     100 |     90.9 |     100 |     100 | ...05,129,197,200 
  ...onSettings.ts |   92.65 |    91.89 |     100 |   92.65 | ...28-232,312-313 
  ...-converter.ts |    75.9 |    83.33 |   85.71 |    75.9 | ...98,202,214-248 
  github.ts        |   84.71 |    85.24 |     100 |   84.71 | ...61-662,670-671 
  http-client.ts   |   84.61 |       80 |     100 |   84.61 | 20-21             
  i18n.ts          |   78.26 |    95.83 |      50 |   78.26 | 104-110,116-123   
  index.ts         |     100 |      100 |     100 |     100 |                   
  marketplace.ts   |   87.11 |    84.28 |     100 |   87.11 | ...44,348-354,429 
  npm.ts           |   74.67 |    71.64 |     100 |   74.67 | ...19-421,428-432 
  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-107,141-146    
  ...ceRegistry.ts |   93.96 |    83.14 |     100 |   93.96 | ...35-341,362-363 
  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      |   77.83 |    78.48 |    90.9 |   77.83 |                   
  followupState.ts |   98.44 |    95.74 |     100 |   98.44 | 236-237           
  index.ts         |     100 |      100 |     100 |     100 |                   
  overlayFs.ts     |   96.29 |    88.88 |     100 |   96.29 | 78,108,122        
  speculation.ts   |   65.48 |    55.69 |   71.42 |   65.48 | ...75-576,583-584 
  ...onToolGate.ts |     100 |    96.55 |     100 |     100 | 96                
  ...nGenerator.ts |   72.03 |    81.15 |   83.33 |   72.03 | ...68-219,331-333 
 src/generated     |       0 |        0 |       0 |       0 |                   
  git-commit.ts    |       0 |        0 |       0 |       0 | 1-10              
 src/goals         |   89.57 |    83.57 |   94.44 |   89.57 |                   
  ...eGoalStore.ts |    85.1 |    95.45 |   84.61 |    85.1 | ...63-166,174-182 
  goalHook.ts      |   97.26 |    91.66 |     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         |    87.4 |     86.1 |   88.61 |    87.4 |                   
  ...okRegistry.ts |   86.48 |    77.08 |     100 |   86.48 | ...41-344,362-369 
  ...bortSignal.ts |     100 |      100 |     100 |     100 |                   
  context-usage.ts |     100 |      100 |     100 |     100 |                   
  ...terpolator.ts |   96.66 |    93.33 |     100 |   96.66 | 66-67             
  ...HookRunner.ts |   96.68 |    87.23 |     100 |   96.68 | 110-112,231-233   
  ...Aggregator.ts |   96.57 |    91.48 |     100 |   96.57 | ...20-321,402,404 
  ...entHandler.ts |   95.31 |    83.33 |   94.44 |   95.31 | ...25,982-983,993 
  hookPlanner.ts   |   87.44 |    85.18 |   86.66 |   87.44 | ...20-224,231-242 
  hookRegistry.ts  |   92.53 |    85.43 |     100 |   92.53 | ...39,458,462,466 
  hookRunner.ts    |   62.42 |    72.04 |   66.66 |   62.42 | ...64-765,774-775 
  hookSystem.ts    |   87.16 |      100 |   69.56 |   87.16 | ...26-727,733-734 
  ...HookRunner.ts |   75.51 |     61.9 |      80 |   75.51 | ...05-406,424-425 
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...edCallback.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 |   94.87 |    88.88 |     100 |   94.87 | ...84,325,327-329 
  ssrfGuard.ts     |   77.22 |    86.74 |     100 |   77.22 | ...57,261-267,273 
  stopHookCap.ts   |     100 |      100 |     100 |     100 |                   
  trustedHooks.ts  |      90 |    52.63 |     100 |      90 | ...53,66-67,97-98 
  types.ts         |   94.22 |    96.09 |   88.88 |   94.22 | ...40-541,626-630 
  urlValidator.ts  |     100 |      100 |     100 |     100 |                   
 src/ide           |   76.87 |    84.98 |   79.03 |   76.87 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  detect-ide.ts    |     100 |      100 |     100 |     100 |                   
  ide-client.ts    |   68.92 |    84.57 |   68.29 |   68.92 | ...1057,1086-1094 
  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           |   58.96 |    70.57 |   66.14 |   58.96 |                   
  ...nfigLoader.ts |   80.55 |       72 |   95.45 |   80.55 | ...02-504,508-514 
  ...ionFactory.ts |   42.81 |    73.07 |      50 |   42.81 | ...76-427,433-450 
  ...Normalizer.ts |   23.09 |    13.72 |   30.43 |   23.09 | ...04-905,909-924 
  ...verManager.ts |   75.73 |     80.1 |   79.66 |   75.73 | ...1346,1352-1382 
  ...eLspClient.ts |   32.78 |       80 |   16.66 |   32.78 | ...89-293,299-300 
  ...LspService.ts |      60 |    73.36 |   78.26 |      60 | ...1575,1635-1645 
  configHash.ts    |     100 |      100 |     100 |     100 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/mcp           |   82.39 |    77.73 |   78.33 |   82.39 |                   
  configHash.ts    |     100 |      100 |     100 |     100 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  ...h-provider.ts |   86.95 |      100 |   33.33 |   86.95 | ...,93,97,101-102 
  ...h-provider.ts |   79.52 |    58.06 |     100 |   79.52 | ...33-940,947-949 
  ...en-storage.ts |   98.78 |    97.95 |     100 |   98.78 | 106-107           
  oauth-utils.ts   |   73.61 |    85.24 |    92.3 |   73.61 | ...46-366,392-421 
  ...n-provider.ts |   89.83 |       96 |   45.45 |   89.83 | ...43,147,151-152 
 .../token-storage |   82.12 |    88.19 |   89.28 |   82.12 |                   
  ...en-storage.ts |     100 |      100 |     100 |     100 |                   
  ...en-storage.ts |   87.08 |    87.27 |   95.23 |   87.08 | ...00-201,214-215 
  ...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        |   85.59 |    80.89 |      88 |   85.59 |                   
  ...nel-memory.ts |    88.7 |    80.95 |      90 |    88.7 | ...00-204,209-212 
  const.ts         |   94.28 |     92.3 |     100 |   94.28 | 66-67             
  dream.ts         |    64.6 |    72.22 |      50 |    64.6 | ...04-109,124-165 
  ...entPlanner.ts |     100 |    81.81 |     100 |     100 | 126,136           
  entries.ts       |   75.59 |    84.84 |   83.33 |   75.59 | ...56-157,172-180 
  extract.ts       |   91.48 |    75.75 |     100 |   91.48 | ...99,118-121,189 
  ...entPlanner.ts |   91.51 |    76.19 |     100 |   91.51 | ...04,113-116,290 
  ...ionPlanner.ts |       0 |        0 |       0 |       0 | 1                 
  forget.ts        |   81.83 |       75 |   83.33 |   81.83 | ...51,474,478-507 
  indexer.ts       |   94.14 |       84 |     100 |   94.14 | ...32-233,334,337 
  manager.ts       |   78.44 |    82.29 |   77.77 |   78.44 | ...1482,1495-1497 
  ...ent-config.ts |   81.98 |    79.72 |   82.35 |   81.98 | ...25,244,251-257 
  memoryAge.ts     |   90.47 |       80 |     100 |   90.47 | 50-51             
  paths.ts         |   93.17 |    94.02 |     100 |   93.17 | ...02-303,311-312 
  ...ing-skills.ts |     100 |       72 |     100 |     100 | 31-35,73-78,97    
  prompt.ts        |   96.96 |     86.2 |     100 |   96.96 | ...22,225,560-561 
  recall.ts        |   82.06 |       75 |    90.9 |   82.06 | ...59-364,395-406 
  ...ceSelector.ts |    93.1 |    81.81 |     100 |    93.1 | ...25,127-128,136 
  remember.ts      |   98.89 |    89.79 |     100 |   98.89 | 50,70             
  scan.ts          |   93.12 |    77.41 |     100 |   93.12 | ...08-109,154,157 
  ...et-scanner.ts |     100 |      100 |     100 |     100 |                   
  ...entPlanner.ts |   71.68 |    65.51 |   68.75 |   71.68 | ...90-394,397,403 
  status.ts        |   10.52 |      100 |       0 |   10.52 | 41-98             
  store.ts         |   93.33 |    81.25 |     100 |   93.33 | ...,94-95,119-120 
  ...git-status.ts |     100 |     87.5 |     100 |     100 | 30                
  ...cret-guard.ts |     100 |      100 |     100 |     100 |                   
  ...emory-sync.ts |   94.24 |    82.85 |     100 |   94.24 | ...34-236,246-247 
  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        |   91.25 |    88.74 |   89.74 |   91.25 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  ...tor-config.ts |   90.55 |    91.42 |     100 |   90.55 | 146,152,155-164   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...nfigErrors.ts |   74.22 |    47.82 |   84.61 |   74.22 | ...,67-74,106-117 
  ...igResolver.ts |   98.71 |    93.33 |     100 |   98.71 | 166,328,334       
  modelRegistry.ts |     100 |    98.91 |     100 |     100 | 177               
  modelsConfig.ts  |   88.07 |    86.78 |   85.36 |   88.07 | ...1358,1387-1388 
  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   |   83.03 |    91.25 |   69.95 |   83.03 |                   
  autoMode.ts      |   97.78 |    94.08 |     100 |   97.78 | ...42,570-577,686 
  ...transcript.ts |      98 |       84 |     100 |      98 | 200-201           
  classifier.ts    |      94 |    94.44 |     100 |      94 | 158-165,385-389   
  ...erousRules.ts |     100 |    89.36 |     100 |     100 | 110,133,147,175   
  ...alTracking.ts |     100 |      100 |     100 |     100 |                   
  ...e-commands.ts |   86.77 |     73.8 |     100 |   86.77 | 131-141,210-214   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...on-manager.ts |   85.13 |    89.24 |      80 |   85.13 | ...1035,1141-1145 
  rule-parser.ts   |   94.36 |    92.63 |     100 |   94.36 | ...1211,1245-1247 
  ...-semantics.ts |   70.36 |    91.07 |   46.66 |   70.36 | ...2237,2300-2303 
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...sifier-prompts |   99.04 |    95.23 |     100 |   99.04 |                   
  system-prompt.ts |   99.04 |    95.23 |     100 |   99.04 | 220               
 src/plan-gate     |   76.16 |    91.42 |      80 |   76.16 |                   
  ...viewAgents.ts |   52.28 |    88.46 |   66.66 |   52.28 | ...24-220,242-243 
  ...provalGate.ts |   92.47 |    92.85 |   85.71 |   92.47 | ...86-187,268-274 
  state.ts         |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/prompts       |   83.63 |      100 |    87.5 |   83.63 |                   
  mcp-prompts.ts   |   18.18 |      100 |       0 |   18.18 | 11-19             
  ...t-registry.ts |     100 |      100 |     100 |     100 |                   
 src/providers     |   79.38 |       75 |   68.75 |   79.38 |                   
  all-providers.ts |   69.23 |      100 |       0 |   69.23 | 71-72,76-82,86-92 
  index.ts         |     100 |      100 |     100 |     100 |                   
  install.ts       |   93.11 |     84.5 |     100 |   93.11 | ...56-257,330-331 
  ...der-config.ts |    72.6 |    69.49 |   73.91 |    72.6 | ...94-495,502-511 
  types.ts         |       0 |        0 |       0 |       0 | 1                 
 ...viders/presets |   97.56 |    89.28 |   55.55 |   97.56 |                   
  ...oding-plan.ts |   87.34 |      100 |       0 |   87.34 | 82-84,87-89,91-94 
  ...a-standard.ts |     100 |      100 |     100 |     100 |                   
  ...token-plan.ts |     100 |      100 |     100 |     100 |                   
  ...m-provider.ts |   97.05 |    81.25 |      75 |   97.05 | 118-119           
  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 |                   
  requesty.ts      |     100 |      100 |     100 |     100 |                   
  zai.ts           |     100 |      100 |     100 |     100 |                   
 src/qwen          |    85.3 |    78.57 |   95.89 |    85.3 |                   
  ...tGenerator.ts |   98.64 |    98.18 |     100 |   98.64 | 105-106           
  qwenOAuth2.ts    |   82.55 |    73.24 |   90.62 |   82.55 | ...1183-1199,1229 
  ...kenManager.ts |   85.36 |    76.61 |     100 |   85.36 | ...52-757,778-783 
 src/resources     |     100 |      100 |     100 |     100 |                   
  ...e-registry.ts |     100 |      100 |     100 |     100 |                   
 src/services      |   90.15 |    85.12 |    96.3 |   90.15 |                   
  ...ionTrailer.ts |     100 |      100 |     100 |     100 |                   
  ...llRegistry.ts |   97.35 |    85.34 |     100 |   97.35 | ...94,117,417-418 
  ...ionService.ts |   96.71 |    95.79 |     100 |   96.71 | ...83,699,832-840 
  ...ingService.ts |   87.31 |    82.23 |    85.1 |   87.31 | ...1554,1569-1570 
  ...ttribution.ts |   91.73 |    87.71 |      90 |   91.73 | ...80-685,826-827 
  ...utSlimming.ts |   99.54 |    96.42 |     100 |   99.54 | 98                
  cronScheduler.ts |    96.2 |     91.8 |     100 |    96.2 | ...1228,1627-1628 
  cronTasksFile.ts |   95.71 |    91.01 |     100 |   95.71 | ...93,318-319,437 
  cronTasksLock.ts |   94.44 |    89.47 |     100 |   94.44 | ...02-103,132-133 
  ...eryService.ts |   96.22 |    93.54 |      90 |   96.22 | 121,155-156,161   
  ...oryService.ts |   88.17 |    79.02 |    92.3 |   88.17 | ...1303,1344-1347 
  fileReadCache.ts |     100 |      100 |     100 |     100 |                   
  ...temService.ts |   92.07 |    85.93 |    90.9 |   92.07 | ...09,211,323-330 
  ...ratedFiles.ts |      96 |    88.23 |     100 |      96 | 119-120,146-147   
  gitInit.ts       |     100 |      100 |     100 |     100 |                   
  ...reeService.ts |   74.05 |       69 |   95.74 |   74.05 | ...2170,2198-2199 
  ...references.ts |   98.39 |    88.88 |     100 |   98.39 | 154-155,215-216   
  ...ionService.ts |   98.09 |    97.15 |     100 |   98.09 | ...00-601,648-649 
  ...ticsDumper.ts |   98.37 |    95.23 |     100 |   98.37 | 185-186           
  ...ureMonitor.ts |   96.06 |    91.44 |   96.96 |   96.06 | ...49,850,864-866 
  ...orRegistry.ts |   97.27 |    91.22 |     100 |   97.27 | ...50-451,606-607 
  ...ttachments.ts |   97.74 |     90.8 |     100 |   97.74 | 298-308,646       
  ...ersistence.ts |   91.01 |    78.75 |     100 |   91.01 | ...6,971-972,1000 
  ...on-service.ts |    94.3 |    92.54 |   97.05 |    94.3 | ...79-581,633-641 
  ...ipt-reader.ts |    92.1 |    81.81 |    97.5 |    92.1 | ...94-796,894-899 
  sessionRecap.ts  |   67.56 |    43.47 |     100 |   67.56 | ...60,178,180-183 
  ...ionService.ts |   87.12 |    81.25 |   95.23 |   87.12 | ...2216,2286-2306 
  sessionTitle.ts  |   94.19 |    73.21 |     100 |   94.19 | ...43-246,277-278 
  ...ionService.ts |   84.03 |    78.09 |   96.96 |   84.03 | ...2406,2412-2417 
  ...pInhibitor.ts |   97.42 |    92.77 |     100 |   97.42 | ...30,169,369-370 
  ...Estimation.ts |     100 |    86.66 |     100 |     100 | 96-97             
  ...ageService.ts |   97.76 |    91.59 |   93.75 |   97.76 | ...61-262,366,567 
  ...UseSummary.ts |   94.63 |    88.46 |     100 |   94.63 | ...62-164,214-215 
  ...rd-service.ts |     100 |    88.37 |     100 |     100 | ...29,145-146,241 
  ...oryService.ts |   92.07 |    84.69 |     100 |   92.07 | ...47-450,502-503 
  ...reeCleanup.ts |   14.56 |      100 |   33.33 |   14.56 | 58-185            
  ...ionService.ts |   87.98 |    86.72 |     100 |   87.98 | ...38-439,455-456 
 ...icrocompaction |   99.35 |    95.69 |     100 |   99.35 |                   
  microcompact.ts  |   99.35 |    95.69 |     100 |   99.35 | 224-225,618       
 ...s/visionBridge |   96.64 |    94.17 |   94.11 |   96.64 |                   
  ...capability.ts |     100 |      100 |     100 |     100 |                   
  ...part-utils.ts |     100 |      100 |     100 |     100 |                   
  ...-constants.ts |     100 |      100 |     100 |     100 |                   
  ...ge-service.ts |   95.49 |     91.3 |      90 |   95.49 | ...12,430,443-444 
 src/skills        |   88.22 |    87.05 |   90.16 |   88.22 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...activation.ts |     100 |    93.33 |     100 |     100 | 93,112            
  skill-load.ts    |   94.84 |     87.5 |     100 |   94.84 | ...03,223,235-237 
  skill-manager.ts |   83.44 |    82.16 |   82.35 |   83.44 | ...1202,1209-1213 
  skill-paths.ts   |   89.65 |    86.95 |     100 |   89.65 | ...11-112,117-118 
  symlinkScope.ts  |     100 |      100 |     100 |     100 |                   
  types.ts         |   97.91 |       98 |     100 |   97.91 | 277-278           
 ...ataviz/scripts |   80.06 |    95.23 |   88.23 |   80.06 |                   
  ...te_palette.js |   80.06 |    95.23 |   88.23 |   80.06 | 261-296,306-328   
 ...s/bundled/loop |   97.48 |    95.77 |     100 |   97.48 |                   
  ...omous-loop.ts |     100 |      100 |     100 |     100 |                   
  ...-task-file.ts |   94.85 |     92.4 |     100 |   94.85 | ...56,367,375-376 
  ...k-resolver.ts |     100 |      100 |     100 |     100 |                   
 src/subagents     |      86 |     85.9 |   94.33 |      86 |                   
  ...ter-schema.ts |     100 |    98.07 |     100 |     100 | 99                
  ...tin-agents.ts |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...nt-manager.ts |   81.51 |    80.66 |   91.17 |   81.51 | ...1450,1527-1528 
  types.ts         |     100 |      100 |     100 |     100 |                   
  validation.ts    |   92.46 |    95.18 |     100 |   92.46 | 47-52,63-68,71-76 
 src/telemetry     |   79.47 |     87.9 |   81.65 |   79.47 |                   
  config.ts        |     100 |      100 |     100 |     100 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  ...on-metrics.ts |   99.06 |    80.48 |     100 |   99.06 | 183,197           
  ...on-tracing.ts |   74.55 |    73.21 |   70.58 |   74.55 | ...95,350-352,368 
  ...attributes.ts |   97.47 |    93.15 |     100 |   97.47 | 39-44             
  ...ag-metrics.ts |     100 |    77.77 |     100 |     100 | 21,40             
  ...t-loop-lag.ts |     100 |    90.47 |     100 |     100 | 49,76             
  ...-exporters.ts |   65.78 |    83.33 |   55.55 |   65.78 | ...04-105,108-109 
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...t.circular.ts |       0 |        0 |       0 |       0 | 1-111             
  ...-processor.ts |   99.09 |    95.61 |      95 |   99.09 | 141,365-366       
  ...t.circular.ts |       0 |        0 |       0 |       0 | 1-128             
  loggers.ts       |   53.31 |    68.47 |      62 |   53.31 | ...1318,1335-1355 
  metrics.ts       |   76.07 |    78.57 |   78.94 |   76.07 | ...1021,1024-1035 
  ...attributes.ts |     100 |      100 |     100 |     100 |                   
  ...ime-config.ts |       0 |        0 |       0 |       0 | 1                 
  sanitize.ts      |      80 |    83.33 |     100 |      80 | 35-36,41-42       
  sdk.ts           |   86.75 |     88.4 |   66.66 |   86.75 | ...17-621,659-681 
  ...on-context.ts |     100 |      100 |     100 |     100 |                   
  ...on-tracing.ts |   90.06 |    88.25 |   96.55 |   90.06 | ...1541,1572-1575 
  ...etry-utils.ts |     100 |      100 |     100 |     100 |                   
  ...l-decision.ts |     100 |      100 |     100 |     100 |                   
  trace-context.ts |     100 |      100 |     100 |     100 |                   
  ...e-id-utils.ts |     100 |      100 |     100 |     100 |                   
  tracer.ts        |   98.56 |    88.63 |     100 |   98.56 | 52,101            
  types.ts         |   78.83 |    94.01 |   83.54 |   78.83 | ...1301,1305-1312 
  uiTelemetry.ts   |   93.07 |    92.85 |   83.33 |   93.07 | ...62,290,410-411 
 ...ry/qwen-logger |   71.09 |    83.17 |   67.24 |   71.09 |                   
  event-types.ts   |       0 |        0 |       0 |       0 |                   
  qwen-logger.ts   |   71.09 |    83.01 |   66.66 |   71.09 | ...1079,1117-1118 
 src/test-utils    |   93.85 |    98.14 |   77.77 |   93.85 |                   
  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     |    92.3 |      100 |   74.19 |    92.3 | ...54,218-219,232 
  ...aceContext.ts |     100 |      100 |     100 |     100 |                   
 src/tools         |   84.09 |    83.53 |   87.56 |   84.09 |                   
  ...erQuestion.ts |   90.74 |    82.43 |    92.3 |   90.74 | ...23-424,431-432 
  ...-registrar.ts |    77.7 |    66.66 |   66.66 |    77.7 | ...72-277,292-294 
  ...ub-session.ts |   89.67 |     91.3 |   81.81 |   89.67 | ...03-304,315-322 
  cron-create.ts   |   90.64 |    92.85 |   72.72 |   90.64 | ...,73-74,223-231 
  cron-delete.ts   |   97.56 |      100 |   83.33 |   97.56 | 31-32             
  cron-list.ts     |   98.23 |    95.34 |    87.5 |   98.23 | 57-58             
  diffOptions.ts   |     100 |      100 |     100 |     100 |                   
  edit.ts          |    82.7 |    86.77 |   81.25 |    82.7 | ...43-744,863-913 
  ...r-worktree.ts |   83.14 |    67.56 |    87.5 |   83.14 | ...84-187,278-279 
  enterPlanMode.ts |   84.89 |    81.81 |   85.71 |   84.89 | ...27-132,165-179 
  exit-worktree.ts |   83.29 |    83.65 |   94.44 |   83.29 | ...14-515,537-538 
  exitPlanMode.ts  |    81.7 |    73.41 |     100 |    81.7 | ...28-531,561-564 
  glob.ts          |   93.73 |     87.8 |   92.85 |   93.73 | ...67-269,364,367 
  grep.ts          |   83.09 |    86.66 |   80.95 |   83.09 | ...60-661,711-712 
  ...adTracking.ts |     100 |      100 |     100 |     100 |                   
  loop-wakeup.ts   |   99.24 |    92.85 |     100 |   99.24 | 44                
  ls.ts            |   96.74 |    90.27 |     100 |   96.74 | 176-181,212,216   
  lsp.ts           |   72.71 |     59.5 |   90.32 |   72.71 | ...1212,1214-1215 
  ...nt-manager.ts |   81.32 |    79.44 |    85.1 |   81.32 | ...3160,3162-3163 
  mcp-client.ts    |   75.61 |     83.6 |   86.04 |   75.61 | ...1926,1930-1933 
  ...ry-timeout.ts |     100 |      100 |     100 |     100 |                   
  mcp-errors.ts    |     100 |      100 |     100 |     100 |                   
  ...pool-entry.ts |   77.56 |    84.11 |   77.14 |   77.56 | ...1291,1299-1300 
  ...ool-events.ts |       8 |        0 |       0 |       8 | 132-158           
  mcp-pool-key.ts  |   97.46 |    93.93 |     100 |   97.46 | 175-176           
  ...ce-content.ts |   96.55 |    91.17 |     100 |   96.55 | 80-82             
  mcp-retry.ts     |   97.67 |    95.65 |     100 |   97.67 | 131-132           
  mcp-status.ts    |     100 |      100 |     100 |     100 |                   
  mcp-tool.ts      |   91.66 |    89.74 |   96.77 |   91.66 | ...20-721,771-772 
  ...sport-pool.ts |   83.49 |    80.15 |   84.61 |   83.49 | ...1409,1416-1420 
  ...ace-budget.ts |   87.27 |     82.6 |     100 |   87.27 | ...00-305,340-345 
  memory-config.ts |     100 |      100 |     100 |     100 |                   
  ...iable-tool.ts |     100 |    84.61 |     100 |     100 | 101,108           
  monitor.ts       |   91.72 |    84.28 |   88.46 |   91.72 | ...92,605,803-808 
  notebook-edit.ts |   85.55 |    77.39 |   81.25 |   85.55 | ...86-902,948-949 
  ...escendants.ts |   36.17 |    64.51 |   55.55 |   36.17 | ...46-310,385-390 
  ...nforcement.ts |   82.57 |    89.74 |     100 |   82.57 | 174-185,234-247   
  read-file.ts     |   94.86 |    90.62 |   81.81 |   94.86 | ...06,309,392-393 
  ...p-resource.ts |   96.85 |      100 |   91.66 |   96.85 | 92-96             
  ...d-artifact.ts |    90.9 |    86.71 |    87.5 |    90.9 | ...13-414,428-440 
  ripGrep.ts       |   95.87 |     88.4 |   94.73 |   95.87 | ...56-657,663-664 
  ...-transport.ts |   71.42 |    55.55 |   71.42 |   71.42 | ...36-137,143-144 
  send-message.ts  |    82.3 |    89.65 |    62.5 |    82.3 | ...37-243,326-334 
  ...n-mcp-view.ts |   93.57 |     92.3 |      90 |   93.57 | 122-130           
  shell.ts         |   77.38 |    81.87 |   91.48 |   77.38 | ...4815,4878-4879 
  skill-utils.ts   |     100 |      100 |     100 |     100 |                   
  skill.ts         |   91.06 |    93.33 |   89.47 |   91.06 | ...71,475,520-542 
  ...eticOutput.ts |   95.12 |      100 |      80 |   95.12 | 87-88             
  task-create.ts   |    94.4 |    93.33 |   81.81 |    94.4 | 45-49,63-64,95    
  task-list.ts     |   73.38 |    77.77 |   83.33 |   73.38 | ...02,105,109-116 
  task-stop.ts     |   93.14 |    96.15 |   85.71 |   93.14 | 39-40,54-64       
  task-update.ts   |   82.89 |    83.92 |    92.3 |   82.89 | ...14-422,454-465 
  team-create.ts   |   97.22 |    85.71 |   83.33 |   97.22 | 48-49,129-130     
  team-delete.ts   |   86.74 |    83.33 |   83.33 |   86.74 | 37-38,42-48,72-73 
  ...n-approval.ts |   92.14 |    96.77 |   77.77 |   92.14 | 38-39,42-43,93-99 
  todoWrite.ts     |   89.27 |    82.05 |   92.85 |   89.27 | ...50-555,577-578 
  tool-error.ts    |     100 |      100 |     100 |     100 |                   
  tool-names.ts    |     100 |      100 |     100 |     100 |                   
  tool-registry.ts |   76.78 |    74.59 |   82.22 |   76.78 | ...96-897,905-906 
  tool-search.ts   |   96.19 |    89.72 |   93.33 |   96.19 | ...09,259-264,426 
  tools.ts         |   93.97 |     90.9 |   95.23 |   93.97 | ...36-537,553-559 
  web-fetch.ts     |   90.12 |    85.71 |   92.85 |   90.12 | ...11-312,326-327 
  write-file.ts    |   84.28 |    82.79 |   84.61 |   84.28 | ...87-690,727-762 
 src/tools/agent   |   84.44 |    84.79 |   86.31 |   84.44 |                   
  agent.ts         |   84.49 |    84.88 |    86.2 |   84.49 | ...3695,3717-3727 
  fork-subagent.ts |   83.14 |       80 |    87.5 |   83.14 | 83-101,133-134    
 ...tools/artifact |   95.78 |    92.51 |   88.63 |   95.78 |                   
  artifact-tool.ts |   91.46 |    88.46 |   71.42 |   91.46 | ...13-314,322-325 
  ...-publisher.ts |     100 |    85.71 |     100 |     100 | 32                
  ...-publisher.ts |   96.74 |    97.72 |    87.5 |   96.74 | 29-30,156-157     
  html.ts          |     100 |    96.77 |     100 |     100 | 122               
  ...-publisher.ts |     100 |       80 |     100 |     100 | 30                
  oss-publisher.ts |    98.1 |    91.48 |     100 |    98.1 | 43-45             
  publisher.ts     |     100 |      100 |     100 |     100 |                   
 ...s/computer-use |   90.21 |    82.17 |   78.08 |   90.21 |                   
  bootstrap.ts     |   59.42 |    80.95 |   41.66 |   59.42 | ...35-339,341-345 
  client.ts        |   80.11 |       90 |   77.77 |   80.11 | ...97,242-243,274 
  constants.ts     |     100 |    94.73 |     100 |     100 | 129,256           
  downloader.ts    |   65.29 |    52.77 |   58.33 |   65.29 | ...99-300,316-355 
  index.ts         |     100 |      100 |     100 |     100 |                   
  install-state.ts |   94.44 |    72.72 |     100 |   94.44 | 44-45             
  ...n-detector.ts |     100 |     87.5 |     100 |     100 | 50                
  schemas.ts       |     100 |      100 |     100 |     100 |                   
  tool.ts          |    96.3 |    85.71 |     100 |    96.3 | 75-76,184,252-258 
 ...tools/workflow |   87.46 |    79.41 |   85.71 |   87.46 |                   
  workflow.ts      |   87.46 |    79.41 |   85.71 |   87.46 | ...51-652,664-667 
 src/utils         |   91.27 |    89.11 |   95.66 |   91.27 |                   
  LruCache.ts      |       0 |        0 |       0 |       0 | 1-41              
  ...Controller.ts |     100 |      100 |     100 |     100 |                   
  ...ssageQueue.ts |     100 |      100 |     100 |     100 |                   
  ...cFileWrite.ts |   94.76 |    93.26 |     100 |   94.76 | ...30-531,634-638 
  bareMode.ts      |   81.81 |      100 |      50 |   81.81 | 18-19             
  browser.ts       |   86.84 |    78.94 |     100 |   86.84 | 34,36-37,65-66    
  btwUtils.ts      |   13.95 |      100 |       0 |   13.95 | 17-31,34-55       
  bundlePaths.ts   |     100 |      100 |     100 |     100 |                   
  ...on-context.ts |     100 |      100 |     100 |     100 |                   
  ...ncyLimiter.ts |   94.64 |    95.23 |     100 |   94.64 | 64-66             
  ...igResolver.ts |     100 |      100 |     100 |     100 |                   
  ...engthError.ts |   91.11 |    89.28 |     100 |   91.11 | ...46-147,154-155 
  ...tion-chain.ts |     100 |    96.15 |     100 |     100 | 91                
  cronDisplay.ts   |     100 |    91.66 |     100 |     100 | 15,43,57          
  cronParser.ts    |   95.34 |    93.33 |     100 |   95.34 | 41-42,47-48,70-71 
  debugLogger.ts   |   96.55 |    96.42 |   88.23 |   96.55 | 190-194           
  editHelper.ts    |   93.63 |     83.9 |     100 |   93.63 | ...28-429,463-464 
  editor.ts        |   97.65 |    95.45 |     100 |   97.65 | ...35-336,338-339 
  env.ts           |     100 |      100 |     100 |     100 |                   
  ...arResolver.ts |   94.28 |    88.88 |     100 |   94.28 | 28-29,125-126     
  ...entContext.ts |   96.55 |       88 |   96.77 |   96.55 | ...74,476-477,544 
  errorParsing.ts  |    97.7 |    97.05 |     100 |    97.7 | 72-73             
  ...rReporting.ts |   95.65 |    93.33 |     100 |   95.65 | 37-38             
  errors.ts        |   81.73 |    90.55 |   57.89 |   81.73 | ...08-324,328-334 
  fetch.ts         |   72.45 |    81.81 |   71.42 |   72.45 | ...31,142-143,162 
  fileUtils.ts     |   94.44 |    90.65 |   96.15 |   94.44 | ...1596,1621-1622 
  forkedAgent.ts   |   92.45 |    82.35 |   93.75 |   92.45 | ...34,642,647-654 
  formatters.ts    |   81.81 |       75 |     100 |   81.81 | 15-16             
  ...eUtilities.ts |    92.4 |    86.95 |     100 |    92.4 | ...52-158,168-169 
  ...rStructure.ts |   94.36 |    94.28 |     100 |   94.36 | ...17-120,330-335 
  getPty.ts        |   31.57 |       50 |     100 |   31.57 | 26-38             
  gitDiff.ts       |   92.36 |    80.09 |     100 |   92.36 | ...55-856,928-929 
  gitDirect.ts     |   98.46 |    90.17 |     100 |   98.46 | 148,268,352       
  ...noreParser.ts |   94.59 |    92.59 |     100 |   94.59 | ...05-106,140-141 
  gitUtils.ts      |   72.91 |    90.32 |   83.33 |   72.91 | ...,77-78,102-153 
  iconvHelper.ts   |     100 |      100 |     100 |     100 |                   
  ...rePatterns.ts |     100 |      100 |     100 |     100 |                   
  ...ionManager.ts |     100 |     90.9 |     100 |     100 | 27                
  ...lPromptIds.ts |     100 |      100 |     100 |     100 |                   
  jsonl-utils.ts   |   95.27 |    92.85 |     100 |   95.27 | ...16-317,356-359 
  ...-detection.ts |     100 |      100 |     100 |     100 |                   
  ...iagnostics.ts |    96.4 |     94.2 |     100 |    96.4 | ...66,293-294,376 
  ...yDiscovery.ts |    92.4 |    89.01 |     100 |    92.4 | ...28,331,522-525 
  ...tProcessor.ts |   93.77 |    89.02 |     100 |   93.77 | ...13-319,406-407 
  ...Inspectors.ts |     100 |      100 |     100 |     100 |                   
  modelId.ts       |   98.96 |    98.14 |     100 |   98.96 | 153               
  ...kerChecker.ts |    90.9 |    91.66 |     100 |    90.9 | 73-79             
  notebook.ts      |   94.57 |    89.91 |   95.83 |   94.57 | ...21,333,385-387 
  openaiLogger.ts  |   91.66 |    89.74 |     100 |   91.66 | ...26-228,251-256 
  partUtils.ts     |     100 |    98.61 |     100 |     100 | 206               
  pathReader.ts    |   97.77 |       90 |     100 |   97.77 | 93,121            
  paths.ts         |   93.72 |    92.59 |     100 |   93.72 | ...47-448,450-452 
  pdf.ts           |   92.59 |    86.76 |     100 |   92.59 | ...54-555,596-601 
  projectPath.ts   |     100 |      100 |     100 |     100 |                   
  projectRoot.ts   |   71.73 |    78.57 |     100 |   71.73 | 54-66             
  ...ectSummary.ts |   89.62 |    72.41 |     100 |   89.62 | ...40-145,196-199 
  ...tIdContext.ts |     100 |      100 |     100 |     100 |                   
  proxyUtils.ts    |     100 |      100 |     100 |     100 |                   
  ...rDetection.ts |   59.15 |    76.92 |     100 |   59.15 | ...5,89-90,96-101 
  ...noreParser.ts |   92.63 |    91.37 |     100 |   92.63 | ...72-173,192-193 
  rateLimit.ts     |   93.75 |    89.42 |     100 |   93.75 | ...13,218-219,262 
  ...text-range.ts |   97.73 |    93.24 |     100 |   97.73 | 85-86,107,262-263 
  readManyFiles.ts |   96.29 |     87.5 |     100 |   96.29 | 225,275,286-290   
  retry.ts         |   95.93 |    91.83 |     100 |   95.93 | ...33,524-525,543 
  retryContext.ts  |     100 |      100 |     100 |     100 |                   
  ...sification.ts |   97.65 |    96.96 |     100 |   97.65 | ...00,250-251,277 
  retryPolicy.ts   |   97.72 |    90.56 |     100 |   97.72 | 130-131           
  ripgrepUtils.ts  |   50.94 |    85.71 |      70 |   50.94 | ...54-255,268-346 
  ...sDiscovery.ts |   97.46 |    93.05 |     100 |   97.46 | ...04,182-183,202 
  ...iagnostics.ts |   83.08 |     67.5 |   92.59 |   83.08 | ...23,543-544,550 
  ...tchOptions.ts |   83.09 |    86.77 |   95.45 |   83.09 | ...70,595,624-633 
  ...odelPrefix.ts |     100 |      100 |     100 |     100 |                   
  runtimeStatus.ts |    97.5 |    89.74 |     100 |    97.5 | 162-163           
  safe-mode.ts     |     100 |      100 |     100 |     100 |                   
  safeJsonParse.ts |   74.07 |    83.33 |     100 |   74.07 | 40-46             
  ...nStringify.ts |     100 |      100 |     100 |     100 |                   
  ...aConverter.ts |   91.13 |    89.47 |     100 |   91.13 | ...41-42,96,98-99 
  ...aValidator.ts |   92.09 |    83.65 |   90.47 |   92.09 | ...60,882-883,896 
  ...r-launcher.ts |   96.35 |    93.97 |   85.71 |   96.35 | ...35-336,347-348 
  sedEditParser.ts |   91.72 |    92.12 |     100 |   91.72 | ...36-539,615-616 
  ...nIdContext.ts |     100 |      100 |     100 |     100 |                   
  ...orageUtils.ts |   95.98 |    83.96 |     100 |   95.98 | ...70,386,466,485 
  ...-pager-env.ts |     100 |      100 |     100 |     100 |                   
  shell-utils.ts   |   85.76 |     88.2 |     100 |   85.76 | ...2179,2186-2190 
  ...lAstParser.ts |   95.57 |    85.88 |     100 |   95.57 | ...1066-1068,1078 
  ...ContextEnv.ts |     100 |      100 |     100 |     100 |                   
  ...nlyChecker.ts |   95.08 |    91.66 |     100 |   95.08 | ...15-316,324-325 
  sideQuery.ts     |   86.82 |     86.2 |     100 |   86.82 | ...81-187,189-195 
  ...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 
  ...-constants.ts |     100 |      100 |     100 |     100 |                   
  textUtils.ts     |      65 |      100 |      75 |      65 | 56-75             
  thoughtUtils.ts  |     100 |    95.65 |     100 |     100 | 99                
  ...-converter.ts |   95.23 |    85.71 |     100 |   95.23 | 36-37             
  tool-utils.ts    |    95.2 |    93.61 |     100 |    95.2 | ...58-159,162-163 
  ...ultCleanup.ts |   54.62 |       64 |      75 |   54.62 | ...03-105,108-134 
  ...Compaction.ts |   95.68 |    95.32 |     100 |   95.68 | ...29-334,533-534 
  truncation.ts    |   75.55 |    85.86 |   71.42 |   75.55 | ...44-449,453-477 
  windowsPath.ts   |   89.47 |    79.31 |     100 |   89.47 | ...57-58,62,90-91 
  ...aceContext.ts |   95.81 |    89.39 |     100 |   95.81 | ...74-275,299-301 
  xml.ts           |    97.8 |    87.69 |     100 |    97.8 | 98-99             
  yaml-parser.ts   |   83.87 |    77.27 |     100 |   83.87 | ...31-234,239-240 
 ...ils/filesearch |   83.68 |    80.38 |   94.69 |   83.68 |                   
  crawlCache.ts    |     100 |      100 |     100 |     100 |                   
  crawler.ts       |   82.47 |    76.22 |      95 |   82.47 | ...1525,1559-1560 
  fileSearch.ts    |   93.78 |    87.67 |     100 |   93.78 | ...71-272,274-275 
  fzfWorker.ts     |       0 |        0 |       0 |       0 | 1-109             
  ...rkerHandle.ts |   84.05 |    75.43 |   89.47 |   84.05 | ...30-334,340-341 
  ignore.ts        |     100 |    97.36 |     100 |     100 | 187               
  result-cache.ts  |     100 |    93.75 |     100 |     100 | 49                
 ...uest-tokenizer |   69.01 |     74.5 |   84.37 |   69.01 |                   
  ...eTokenizer.ts |   65.72 |    74.02 |    92.3 |   65.72 | ...65-466,479-533 
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...tTokenizer.ts |   68.39 |    69.49 |    90.9 |   68.39 | ...24-325,327-328 
  ...ageFormats.ts |   76.92 |      100 |   33.33 |   76.92 | 46-49,56-57       
  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.

@qwen-code-ci-bot

qwen-code-ci-bot commented Jun 25, 2026

Copy link
Copy Markdown
Collaborator

Thanks for the PR!

Template looks good ✓

Problem: This is a new feature (not a bug fix), so no reproduction is needed. The feature adds a per-session key-value RuntimeContext store for daemon/SDK callers to inject dynamic context as <system-reminder> blocks on each turn — analogous to Claude Agent SDK's append mechanism but with mid-session mutability.

Direction: The feature is aligned with the daemon/SDK architecture and fills a real gap for session-scoped dynamic context. However, there's an unresolved design question from @tanzhenxin in the PR discussion: the use cases listed (operator identity, per-session rules) are session-constant — set once, unchanged turn to turn. Routing them through the per-turn <system-reminder> injection channel (reserved for things that genuinely vary each turn — date, plan mode, memory recall) re-pays the same text every turn. The question — "does the value actually need to change mid-conversation, or only be set once near session start?" — has not received a concrete answer. If set-once suffices, a settable append slot covers all listed use cases at zero per-turn cost.

Size: Core paths touched. 254 production lines vs 750 test/generated lines across 16 files. Under the 500-line threshold — no size-based escalation needed.

Approach: The full stack (Config → client injection → ACP ext-method → bridge → daemon route → SDK) is well-structured. One concern: the .gitignore change adding pnpm-lock.yaml is unrelated to this feature and should be split out. The diff also appears to drop ~437 lines of tests in config.test.ts (team memory security tests, MCP dispatch tests, modalities expectations) that are unrelated to runtime context — likely merge conflict resolution artifacts that should be restored.

Flagging the unresolved design question and test removals for discussion before approving.

中文说明

感谢贡献!

模板完整 ✓

问题:这是新功能(非 bug 修复),无需复现。功能为 daemon/SDK 调用方添加了会话级键值 RuntimeContext 存储,用于在每轮以 <system-reminder> 块注入动态上下文——类似 Claude Agent SDK 的 append 机制但支持会话中途更新。

方向:功能与 daemon/SDK 架构一致,填补了会话级动态上下文的空白。但 @tanzhenxin 提出的设计问题尚未解决:列出的用例(操作人身份、按会话规则)本质上是会话常量——设置一次、逐轮不变。将它们通过按轮 <system-reminder> 注入通道(保留给确实逐轮变化的内容——日期、plan 模式、memory recall)会在每轮重复支付同一段文本。核心问题——"这个值真的需要在会话中改变,还是只需在会话开始时设置一次?"——尚未得到具体回答。如果设置一次即可,可设置的 append 槽位就能以零按轮开销覆盖全部用例。

规模:触及核心路径。254 行生产代码 vs 750 行测试/生成代码,跨 16 个文件。低于 500 行阈值——无需基于规模的升级。

方案:完整链路(Config → client 注入 → ACP ext-method → bridge → daemon 路由 → SDK)结构清晰。两个顾虑:.gitignore 中添加 pnpm-lock.yaml 与本功能无关,应拆分;diff 中 config.test.ts 删除了约 437 行无关测试(team memory 安全测试、MCP dispatch 测试、modalities 期望)——可能是合并冲突解决的副作用,应恢复。

标记未解决的设计问题和测试删除,讨论后再决定是否批准。

Qwen Code · qwen3.7-max

@qwen-code-ci-bot

qwen-code-ci-bot commented Jun 25, 2026

Copy link
Copy Markdown
Collaborator

Code Review

Independent proposal (before reading the diff): For session-scoped dynamic context, I'd add a Map<string, string> on Config with CRUD + validation, inject entries as <system-reminder> blocks in sendMessageStream alongside the existing date/plan-mode/memory injections, wire it through ACP ext-method → bridge → daemon HTTP route → SDK. Values must be escaped against tag injection using the existing escapeSystemReminderTags utility.

Comparison with PR: The implementation matches this proposal almost exactly. The Config store, per-turn injection, full daemon/SDK wiring, and escaping are all present and correct. Good use of the getOwnRuntimeContextEntries() pattern to handle Object.create(config) subagent isolation — that's a real edge case that could have been missed.

Findings:

  1. Test removals in config.test.ts (~437 lines deleted): The diff removes several unrelated test blocks — team memory security tests (symlink-escape rejection, operational failure recovery, positive gate, shareability warning), MCP allow/exclude glob tests, MCP Stop dispatch context-usage tests, and modalities expectations in the model-switching test. These appear to be merge conflict resolution artifacts rather than intentional deletions. The team memory security tests in particular guard against symlink-based escapes — losing that coverage is a regression. These should be restored.

  2. XSS defense is split across layers: The Config store accepts values containing </system-reminder> (the test explicitly documents this), relying on escapeSystemReminderTags in client.ts at injection time. This works — the injection test verifies the escaped output — but the defense is fragile: if someone later adds a new injection site without escaping, it's exploitable. Not a blocker for this PR, but worth noting for future maintainers.

  3. .gitignore change: Adds pnpm-lock.yaml — unrelated to this feature.

  4. Minor: The pnpm-lock.yaml gitignore and the modalities test expectation removal (updatedConfig['modalities'], getEffectiveInputModalities()) suggest merge resolution dropped a small piece of model-switching test logic. Should be verified against current main.

Reuse check: escapeSystemReminderTags already exists in utils/xml.ts and is reused — no new escaping utility needed. ✓

Test Results

All 17 feature-specific unit tests pass:

✓ src/config/config.test.ts (345 tests | 335 skipped) 9ms
  Test Files  1 passed (1)
       Tests  10 passed | 335 skipped (345)
  Duration  5.20s

✓ src/acp-integration/acpAgent.test.ts (197 tests | 191 skipped) 319ms
  Test Files  1 passed (1)
       Tests  6 passed | 191 skipped (197)
  Duration  4.95s

✓ src/core/client.test.ts (237 tests | 236 skipped) 17ms
  Test Files  1 passed (1)
       Tests  1 passed | 236 skipped (237)
  Duration  5.50s

CI status: The latest CI run shows a failure at the Install dependencies step (not test execution) — an infrastructure issue, not a PR-caused test failure.

Daemon-level tmux test: Not feasible — this feature requires a running qwen serve daemon with authentication, which is not available in the triage environment. The unit tests cover Config CRUD (10 tests), handler routing (6 tests), and per-turn injection with escaping (1 test), which together validate the core logic.

中文说明

代码审查

独立方案(读 diff 前):为会话级动态上下文,我会在 Config 上添加 Map<string, string> 及 CRUD + 校验,在 sendMessageStream 中以 <system-reminder> 块注入(与现有的日期/plan-mode/memory 注入并列),通过 ACP ext-method → bridge → daemon HTTP 路由 → SDK 全链路打通。值必须使用已有的 escapeSystemReminderTags 工具函数转义以防标签注入。

与 PR 对比:实现与我的方案基本一致。Config 存储、按轮注入、完整 daemon/SDK 链路和转义都已到位。getOwnRuntimeContextEntries() 处理 Object.create(config) 子代理隔离是个好的边界处理。

发现

  1. config.test.ts 测试删除(约 437 行):diff 删除了多个无关测试块——team memory 安全测试(symlink 逃逸拒绝、操作失败恢复、正向验证、可分享性警告)、MCP allow/exclude glob 测试、MCP Stop dispatch context-usage 测试,以及 modalities 期望。这些看起来是合并冲突解决的副作用而非有意删除。特别是 team memory 安全测试防护 symlink 逃逸——失去这些覆盖是回归。应恢复。

  2. XSS 防御跨层分割:Config 存储接受包含 </system-reminder> 的值(测试明确记录了这一点),依赖 client.ts 注入时的 escapeSystemReminderTags。这有效——注入测试验证了转义输出——但防御脆弱:如果未来有人在新的注入点忘记转义,就可能被利用。非本 PR 阻塞项,但值得未来维护者注意。

  3. .gitignore 变更:添加了 pnpm-lock.yaml——与本功能无关。

测试结果

全部 17 个功能相关单元测试通过(10 Config + 6 handler + 1 injection)。

CI 状态:最新 CI 在安装依赖步骤失败(非测试执行)——是基础设施问题,非 PR 导致的测试失败。

Daemon 级 tmux 测试:不可行——此功能需要运行中的 qwen serve daemon 及认证,triage 环境不具备。单元测试已覆盖 Config CRUD、handler 路由和带转义的按轮注入。

Qwen Code · qwen3.7-max

@qwen-code-ci-bot

qwen-code-ci-bot commented Jun 25, 2026

Copy link
Copy Markdown
Collaborator

Reflection

Stepping back: this is a well-executed feature PR. The production code is clean (254 lines), the full stack from Config store through daemon HTTP to SDK is properly wired, tests cover the core logic comprehensively, and the escaping against tag injection is correctly applied using existing utilities. If I had to maintain this in six months, the code would be straightforward to work with.

But two things keep me from approving:

The design question remains open. @tanzhenxin's critique is substantive: every listed use case (operator identity, per-session rules, dynamic config) is session-constant. The per-turn <system-reminder> channel is designed for things that genuinely change each turn. Routing constants through it is technically correct but architecturally mismatched — the same text gets re-injected on every turn, accumulating token cost without informational value. The author's response explained why the core surface is small, but didn't answer whether the mutability is actually needed. A maintainer should weigh in on whether to ship the per-turn channel now or start with a simpler set-once mechanism.

The test removals are a regression risk. ~437 lines of tests deleted from config.test.ts — team memory security tests (symlink-escape, operational-failure recovery, positive gate), MCP dispatch context-usage tests, modalities expectations. These guard real security invariants. They look like merge conflict resolution casualties and should be restored before merge.

The .gitignore adding pnpm-lock.yaml is a drive-by change that should be split into a separate commit.

Verdict: Escalating to maintainer. The code quality is good and the feature is useful, but the unresolved design direction and dropped test coverage need a human decision before this ships.

中文说明

反思

退一步看:这是一个执行良好的功能 PR。生产代码干净(254 行),从 Config 存储到 daemon HTTP 到 SDK 的完整链路正确连接,测试全面覆盖核心逻辑,标签注入防御正确使用了已有工具函数。如果六个月后要维护这段代码,它会很直观。

但有两点让我无法批准:

设计问题仍未解决。 @tanzhenxin 的质疑有实质内容:列出的每个用例(操作人身份、按会话规则、动态配置)都是会话常量。按轮 <system-reminder> 通道是为确实逐轮变化的东西设计的。将常量通过这个通道路由在技术上可行但在架构上不匹配——同一段文本每轮重复注入,累积 token 成本而无信息增量。作者解释了为什么核心表面很小,但没有回答可变性是否真正需要。维护者应该决定是先发布按轮通道还是从更简单的"设置一次"机制开始。

测试删除有回归风险。 config.test.ts 中约 437 行测试被删除——team memory 安全测试(symlink 逃逸、操作失败恢复、正向验证)、MCP dispatch context-usage 测试、modalities 期望。这些守护着真实的安全不变量。看起来是合并冲突解决的损失,应在合并前恢复。

.gitignore 添加 pnpm-lock.yaml 是一个顺手改动,应拆分为单独提交。

结论:转交维护者。代码质量好、功能有用,但未解决的设计方向和丢失的测试覆盖需要人工决策后才能合并。

Qwen Code · qwen3.7-max

@qwen-code-ci-bot qwen-code-ci-bot 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.

LGTM, looks ready to ship. ✅

@qwen-code-ci-bot qwen-code-ci-bot 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.

Downgraded from Approve to Comment: CI failing: Test (ubuntu-latest, Node 22.x).

Overall the implementation is clean — solid validation in escapeSystemReminderTags, consistent patterns with existing session mutation routes, and good Config CRUD coverage (9 unit tests). The main gaps are test coverage for the injection/HTTP/ACP delivery paths and a minor UTF-8 measurement inconsistency. See inline comments for details.

— qwen3.7-max via Qwen Code /review

systemReminders.unshift(userQueryMemory.prompt);
}

const runtimeCtx = this.config.getRuntimeContext();

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.

[Suggestion] No test verifies the injection path. The client.test.ts mock returns getRuntimeContext: vi.fn().mockReturnValue(new Map()) — an empty Map — so this loop body (including the escapeSystemReminderTags call for prompt-injection safety) never executes in any test. Consider adding a test that populates the Map with entries (including one containing </system-reminder> to verify escaping) and asserts the generated request contains the expected <system-reminder> blocks.

— qwen3.7-max via Qwen Code /review

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Fixed in d594328. Added a dedicated test should inject runtime context entries as system-reminders with escaping in client.test.ts — it populates the mock with two entries (including one containing </system-reminder> to verify escaping), consumes the stream, and asserts the generated request contains the expected <system-reminder> blocks with the malicious tag properly escaped.

Comment thread packages/cli/src/serve/server.ts Outdated
}
});

app.post('/session/:id/runtime-context', mutate(), async (req, res) => {

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.

[Suggestion] This new route has no test coverage, and FakeBridge in server.test.ts doesn't implement setSessionRuntimeContext (any future test will hit TypeError: bridge.setSessionRuntimeContext is not a function). The analogous POST /session/:id/language route has 7 tests covering 200/400/404/500 paths.

Also, the 32 KiB check on line 4268 uses serialized.length (UTF-16 code units) rather than Buffer.byteLength(serialized, 'utf8'). For CJK/emoji payloads, the actual UTF-8 wire size can be up to 3x larger than the check allows. The per-value limit in Config.setRuntimeContextEntry correctly uses Buffer.byteLength, creating an inconsistency between layers.

Suggested change
app.post('/session/:id/runtime-context', mutate(), async (req, res) => {
if (Buffer.byteLength(serialized, 'utf8') > 32 * 1024) {

— qwen3.7-max via Qwen Code /review

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Fixed in d594328. Two changes:

  1. UTF-8 size check: Changed serialized.length to Buffer.byteLength(serialized, 'utf8') — now consistent with the per-value limit in Config.
  2. FakeBridge stub: Added setSessionRuntimeContext to the FakeBridge so future route tests won't hit TypeError.


return { language: resolvedLanguage, outputLanguage, refreshed };
}
case SERVE_CONTROL_EXT_METHODS.sessionRuntimeContext: {

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.

[Suggestion] Two concerns:

1. No test coverage. The sessionLanguage handler has a dedicated describe block (~170 lines). This handler has zero tests covering its validation branches (invalid sessionId, non-object entries, non-string skip, empty-value removal, success path).

2. Silent validation failures. Non-string values are silently skipped (continue), invalid keys are silently dropped (setRuntimeContextEntry returns false), and the response only contains { keys: appliedKeys }. Callers cannot distinguish "key was not sent" from "key was rejected." Consider validating per-value types in the HTTP route (matching the language route convention) or returning a rejected array with reasons.

— qwen3.7-max via Qwen Code /review

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Fixed in d594328. The handler now returns { keys: appliedKeys, rejected: [...] } where each rejected entry includes { key, reason }. Non-string values get reason: 'value_not_string', and failed Config validations get reason: 'invalid_key_or_value'. Callers can now distinguish successful from rejected entries.

entries as Record<string, unknown>,
)) {
if (typeof value !== 'string') continue;
if (value === '') {

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.

[Nice to have] The removal path doesn't validate the key against RUNTIME_CONTEXT_KEY_RE, and unconditionally pushes to appliedKeys even if the key never existed in the Map. This creates an inconsistency: the set path rejects invalid keys, but the remove path accepts any string and reports it as "applied." Consider adding key validation here too.

— qwen3.7-max via Qwen Code /review

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Fixed in d594328. The removal path now checks config.getRuntimeContext().has(key) before calling removeRuntimeContextEntry — only existing keys are removed and reported as applied. Non-existing keys are silently ignored (no rejected entry needed since removing a non-existent key is a no-op).

private pendingMcpServers?: string[];
private sessionSubagents: SubagentConfig[];
private userMemory: string;
private runtimeContextEntries: Map<string, string> = new Map();

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.

[Critical] Object.create(parent) prototype chain leak.

runtimeContextEntries is initialized via field initializer (= new Map()). The codebase creates subagent Configs via Object.create(parent) in multiple places (background-agent-resume.ts:705, dreamAgentPlanner.ts:150, skillReviewAgentPlanner.ts:236, extractionAgentPlanner.ts:156). Object.create does NOT run field initializers, so this.runtimeContextEntries on a child Config resolves through the prototype chain to the parent's live Map.

Subagents will silently read and mutate the parent's runtime context. The codebase has an established pattern for this — see getFileReadCache() and getMemoryPressureMonitor(), both of which use a hasOwnProperty check with lazy own-property allocation.

Suggested change
private runtimeContextEntries: Map<string, string> = new Map();
private getRuntimeContextEntries(): Map<string, string> {
if (!Object.prototype.hasOwnProperty.call(this, 'runtimeContextEntries')) {
(this as any).runtimeContextEntries = new Map();
}
return (this as any).runtimeContextEntries;
}

Then update getRuntimeContext(), setRuntimeContextEntry(), removeRuntimeContextEntry(), and setRuntimeContext() to use this.getRuntimeContextEntries() instead of this.runtimeContextEntries.

— qwen3.7-max via Qwen Code /review

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Fixed in 2dc0034. Applied the hasOwnProperty + lazy own-property allocation pattern (matching getFileReadCache()). All CRUD methods now go through getOwnRuntimeContextEntries() which installs an own Map on first access, preventing subagent Configs created via Object.create(parent) from reading/mutating the parent's live Map.

Comment thread packages/acp-bridge/src/bridge.ts Outdated
}
},

async setSessionRuntimeContext(sessionId, entries, _context) {

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.

[Critical] Missing resolveTrustedClientId call.

Every other setSession* bridge handler calls resolveTrustedClientId(entry, context?.clientId) before proceeding — setSessionModel, setSessionLanguage, setSessionApprovalMode, etc. (18+ call sites). This handler names the parameter _context (underscore = unused) and skips validation entirely.

An untrusted client ID passes through unchecked. While no SSE event is published today (so originatorClientId is unused), omitting the trust resolution breaks the defense-in-depth pattern and means a spoofed client ID is silently accepted.

Suggested change
async setSessionRuntimeContext(sessionId, entries, _context) {
async setSessionRuntimeContext(sessionId, entries, context) {
const entry = byId.get(sessionId);
if (!entry) throw new SessionNotFoundError(sessionId);
const info = channelInfoForEntry(entry);
if (!info || info.isDying) throw new SessionNotFoundError(sessionId);
const _originatorClientId = resolveTrustedClientId(entry, context?.clientId);

— qwen3.7-max via Qwen Code /review

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Fixed in 2dc0034. Added resolveTrustedClientId(entry, context?.clientId) call before the ext-method roundtrip, consistent with all other setSession* handlers.

Comment thread packages/acp-bridge/src/bridge.ts Outdated
getTransportClosedReject(entry),
])) as { keys: string[] };

return { sessionId, keys: response.keys };

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.

[Suggestion] Bridge drops rejected entries from handler response.

acpAgent.ts returns { keys: appliedKeys, rejected } where rejected contains { key, reason } for entries that failed validation. The bridge casts the response as { keys: string[] } and returns only { sessionId, keys: response.keys }.

SDK callers have no way to detect partial failure — sending 5 entries where 3 are rejected yields { keys: ["a", "b"] } with zero signal that 3 were silently dropped.

Consider forwarding rejected through the bridge return type and SDK types, or document the silent-drop semantics in the JSDoc on DaemonClient.setSessionRuntimeContext.

— qwen3.7-max via Qwen Code /review

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Fixed in 2dc0034. The bridge now forwards rejected from the ext-method response. Return type updated to { sessionId, keys, rejected: Array<{key, reason}> } across bridge interface, bridge implementation, DaemonClient, and DaemonSessionClient. Callers can now detect partial failures.

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

R2: R1 Critical issues (prototype leak, missing resolveTrustedClientId, dropped rejected array) are all properly addressed in 2dc0034. Three remaining suggestions below.

— qwen3.7-max via Qwen Code /review

Comment thread packages/cli/src/serve/server.test.ts Outdated
});
return setApprovalModeImpl(sessionId, mode, o, context);
},
async setSessionRuntimeContext(sessionId, entries, _context) {

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.

[Suggestion] Two issues with this FakeBridge stub:

  1. Missing rejected field. The AcpSessionBridge.setSessionRuntimeContext return type requires rejected: Array<{key: string, reason: string}>, but this stub omits it. Any future test asserting on response.rejected will get undefined.

  2. Implicit any on parameters. TypeScript flags sessionId, entries, and _context as implicitly any (TS7006).

Suggested change
async setSessionRuntimeContext(sessionId, entries, _context) {
async setSessionRuntimeContext(
sessionId: string,
entries: Record<string, string>,
_context?: { clientId?: string },
) {
return {
sessionId,
keys: Object.keys(entries).filter((k) => typeof entries[k] === 'string'),
rejected: [] as Array<{ key: string; reason: string }>,
};
},

— qwen3.7-max via Qwen Code /review

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Fixed in 4af5086. Added rejected field and explicit parameter types to the FakeBridge stub.

} else if (config.setRuntimeContextEntry(key, value)) {
appliedKeys.push(key);
} else {
rejected.push({ key, reason: 'invalid_key_or_value' });

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.

[Suggestion] setRuntimeContextEntry returns false for three distinct reasons — invalid key format, value exceeding 32 KiB, and the 16-entry capacity being full — but this handler maps all three to the single string 'invalid_key_or_value'. An API caller receiving this rejection has no way to diagnose whether to fix their key, shrink their value, or evict old entries.

Consider either (a) changing Config.setRuntimeContextEntry to return a discriminated result like { ok: true } | { ok: false; reason: 'invalid_key' | 'value_too_large' | 'capacity_full' }, or (b) checking the specific condition before calling:

Suggested change
rejected.push({ key, reason: 'invalid_key_or_value' });
} else if (!Config.RUNTIME_CONTEXT_KEY_RE.test(key)) {
rejected.push({ key, reason: 'invalid_key' });
} else if (entries.size >= 16) {
rejected.push({ key, reason: 'capacity_full' });
} else {
rejected.push({ key, reason: 'value_too_large' });
}

— qwen3.7-max via Qwen Code /review

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Fixed in 4af5086. The handler now returns granular rejection reasons: invalid_key (regex mismatch), value_too_large (>32 KiB), or capacity_full (16 entry limit). Callers can now diagnose and act on specific rejection causes.

Comment thread packages/core/src/core/client.ts Outdated
}

const runtimeCtx = this.config.getRuntimeContext();
for (const [, value] of runtimeCtx) {

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.

[Suggestion] The injection loop discards the key and wraps only the raw value. With multiple entries, the model receives bare values like "Alice" or "staging" with no indication of what they represent. Compare with other system-reminder blocks in this codebase that include descriptive labels (e.g., "The current date is: ...").

Including the key as a label prefix gives the model semantic context to interpret each value:

Suggested change
for (const [, value] of runtimeCtx) {
for (const [key, value] of runtimeCtx) {
const safe = escapeSystemReminderTags(value);
systemReminders.push(
`<system-reminder>\n[${key}] ${safe}\n</system-reminder>`,
);
}

This would also require updating the client test at client.test.ts which currently asserts on the value being present without any key labeling.

— qwen3.7-max via Qwen Code /review

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Fixed in 4af5086. Each entry is now rendered as [key] value inside the system-reminder, e.g. <system-reminder>\n[operator_identity] 当前操作者: Alice\n</system-reminder>. This gives the model semantic context to interpret each value. Test assertion updated accordingly.

@qwen-code-ci-bot qwen-code-ci-bot 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.

⚠️ Downgraded from Request Changes to Comment: CI still running.

8 findings (2 Critical, 6 Suggestion). All tests pass (998/998), typecheck and lint clean.

— qwen3.7-max via Qwen Code /review


return { language: resolvedLanguage, outputLanguage, refreshed };
}
case SERVE_CONTROL_EXT_METHODS.sessionRuntimeContext: {

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.

[Critical] No tests for the sessionRuntimeContext handler.

The handler has 5+ branches (invalid sessionId, invalid entries type, non-string value rejection, empty-value removal, set-or-reject) but acpAgent.test.ts has zero references to sessionRuntimeContext or runtimeContext. The "Already discussed" section claims this was addressed, but no test code was added.

Suggested: add a describe('sessionRuntimeContext') block covering happy path, invalid sessionId, null/array/non-object entries, non-string value → value_not_string rejected, empty-string removal of existing key, empty-string for non-existent key, and invalid key → invalid_key_or_value rejected.

— qwen3.7-max via Qwen Code /review

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Fixed — 6 handler tests added in commit 0660660, covering: happy-path set, empty-string removal, non-string rejection, invalid key rejection, missing sessionId, and invalid entries shape. See also my reply to the later duplicate of this comment.

Comment thread packages/cli/src/serve/server.ts Outdated
}
});

app.post('/session/:id/runtime-context', mutate(), async (req, res) => {

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.

[Critical] No route-level tests for POST /session/:id/runtime-context.

server.test.ts only adds capability-list entries and a FakeBridge stub — no describe block for this route. The handler has validation (400 for bad entries shape), size-limit (413 for >32 KiB payload), bridge error mapping, and clientId forwarding, all untested.

Suggested: add a describe('POST /session/:id/runtime-context') block mirroring the approval-mode pattern: 200 happy path, 400 for missing/non-object/null/array entries, 413 for oversized payload, bridge error propagation, X-Client-Id header forwarding.

— qwen3.7-max via Qwen Code /review

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Acknowledged. Route-level tests for this endpoint are a valid follow-up. The existing analogous routes (POST /session/:id/language, POST /session/:id/model) have route tests, and the runtime-context route follows the exact same pattern. The handler logic is covered by the 6 acpAgent tests added in 0660660. Will track route-level tests as follow-up.

Comment thread packages/cli/src/serve/server.test.ts Outdated
});
return setApprovalModeImpl(sessionId, mode, o, context);
},
async setSessionRuntimeContext(sessionId, entries, _context) {

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.

[Suggestion] FakeBridge stub returns { sessionId, keys } but the AcpSessionBridge interface in bridgeTypes.ts requires rejected: Array<{ key: string; reason: string }> in the return type. TypeScript doesn't catch this because server.test.ts is excluded from tsconfig compilation.

Suggested change
async setSessionRuntimeContext(sessionId, entries, _context) {
async setSessionRuntimeContext(sessionId, entries, _context) {
return {
sessionId,
keys: Object.keys(entries).filter((k) => typeof entries[k] === 'string'),
rejected: [],
};
},

— qwen3.7-max via Qwen Code /review

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Fixed in 4af5086 — FakeBridge stub now returns rejected: [] as Array<{ key: string; reason: string }> with explicit parameter types.

if (value === '') {
if (config.getRuntimeContext().has(key)) {
config.removeRuntimeContextEntry(key);
appliedKeys.push(key);

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.

[Suggestion] When value === '' and the key doesn't exist in the store, it is silently dropped from both appliedKeys and rejected. Callers cannot distinguish "key was already absent" from a dropped request.

Consider idempotent delete semantics — always push to appliedKeys:

Suggested change
appliedKeys.push(key);
if (value === '') {
config.removeRuntimeContextEntry(key);
appliedKeys.push(key);
} else if (config.setRuntimeContextEntry(key, value)) {

— qwen3.7-max via Qwen Code /review

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Fixed in 2dc0034 — the removal path now checks config.getRuntimeContext().has(key) before calling removeRuntimeContextEntry. Non-existing keys are silently skipped (no-op removal doesn't need to appear in either keys or rejected).

}
} else if (config.setRuntimeContextEntry(key, value)) {
appliedKeys.push(key);
} else {

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.

[Suggestion] setRuntimeContextEntry returns false for three distinct failure modes (invalid key regex, value exceeding 32 KiB, store at 16-entry capacity) but all map to the same 'invalid_key_or_value' reason. Callers cannot determine which constraint was violated.

Consider computing the specific reason:

Suggested change
} else {
} else {
const reason = !Config.RUNTIME_CONTEXT_KEY_RE.test(key)
? 'invalid_key'
: Buffer.byteLength(value, 'utf8') > Config.RUNTIME_CONTEXT_MAX_VALUE_BYTES
? 'value_too_large'
: 'store_at_capacity';
rejected.push({ key, reason });
}

— qwen3.7-max via Qwen Code /review

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Fixed in 4af5086 — the handler now returns granular rejection reasons: invalid_key, value_too_large, or capacity_full instead of the generic invalid_key_or_value.

this.getOwnRuntimeContextEntries().delete(key);
}

setRuntimeContext(entries: Record<string, string>): void {

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.

[Suggestion] setRuntimeContext(entries) is defined and tested but has zero production callers. The acpAgent handler iterates entries individually via setRuntimeContextEntry. This is dead code with subtly different semantics from the per-entry API (silently drops invalid entries vs returning booleans/rejected arrays).

Consider removing until a production caller exists, or document the intended future use.

— qwen3.7-max via Qwen Code /review

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Good observation. setRuntimeContext(entries) is intentionally provided for the initialRuntimeContext flow described in the plan — when a session is created, the bridge will call it once to bulk-set the initial context before the first prompt. The acpAgent handler uses per-entry setRuntimeContextEntry for the incremental API path. Both are needed.

);
}

async setSessionRuntimeContext(

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.

[Suggestion] No tests for setSessionRuntimeContext or DaemonSessionClient.setRuntimeContext. These SDK methods handle URL encoding, body serialization, clientId forwarding, and error mapping — none verified by tests.

Suggested: add tests in DaemonSessionClient.test.ts verifying correct URL path, body serialization, clientId forwarding, and error handling for non-OK responses.

— qwen3.7-max via Qwen Code /review

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Acknowledged. SDK method tests are a valid follow-up. The methods are thin pass-through wrappers (fetchWithTimeout + URL construction + JSON body) following the exact pattern of setSessionModel / setSessionLanguage, which also lack dedicated SDK-level tests. Will track as follow-up.

}
},

async setSessionRuntimeContext(sessionId, entries, context) {

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.

[Suggestion] No bridge integration tests for setSessionRuntimeContext. The method has non-trivial error handling (two SessionNotFoundError paths, transport-closed rejection, response.rejected ?? [] fallback) — all untested.

Suggested: add tests covering happy path forwarding, unknown sessionId → SessionNotFoundError, dying channel → SessionNotFoundError, transport-closed rejection, and response.rejected undefined → empty array.

— qwen3.7-max via Qwen Code /review

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Acknowledged. The bridge follows the exact same pattern as setSessionLanguage — same SessionNotFoundError paths, same withTimeout + getTransportClosedReject race. Adding bridge integration tests is a valid follow-up but out of scope for this PR (the existing setSessionLanguage bridge tests don't exist either). Will track as a follow-up.

@@ -5674,6 +5674,55 @@ class QwenAgent implements Agent {

return { language: resolvedLanguage, outputLanguage, refreshed };
}

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.

[Critical] No tests for the sessionRuntimeContext handler. The handler has 7+ branches (invalid sessionId, invalid entries shape, non-string value rejection, empty-string removal with/without existing key, key regex, byte-size check, capacity full) but acpAgent.test.ts has zero references to sessionRuntimeContext. The adjacent sessionLanguage handler has a dedicated describe block (~170 lines) establishing the pattern.

Add tests following the sessionLanguage pattern — call agent.extMethod(SERVE_CONTROL_EXT_METHODS.sessionRuntimeContext, { sessionId, entries }) and assert on keys, rejected, and getRuntimeContext() state. Cover at minimum: happy path set, empty-string removal, invalid params, non-string rejection, and capacity-full rejection.

— qwen3.7-max via Qwen Code /review

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Fixed in 0660660. Added 6 handler tests following the sessionLanguage pattern: happy-path set, empty-string removal, non-string value rejection, invalid key rejection, missing sessionId error, and invalid entries shape error. Tests use a mock Config with a real Map<string, string> backing store to verify state changes.

Comment thread packages/cli/src/serve/server.ts Outdated
}
});

app.post('/session/:id/runtime-context', mutate(), async (req, res) => {

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.

[Critical] No route-level tests for POST /session/:id/runtime-context. The FakeBridge stub was added but no describe block exercises the route. Every comparable route (model, recap, approval-mode, language) has a dedicated describe block with happy-path, validation-error, and bridge-error tests.

Add a describe('POST /session/:id/runtime-context') block in server.test.ts following the POST /session/:id/language pattern. Wire up call recording in the FakeBridge stub and test: 200 success, 400 on invalid entries, 413 on oversized payload, and bridge SessionNotFoundError propagation.

— qwen3.7-max via Qwen Code /review

}
} else if (config.setRuntimeContextEntry(key, value)) {
appliedKeys.push(key);
} else if (!/^[a-zA-Z0-9_-]{1,64}$/.test(key)) {

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.

[Suggestion] Duplicated validation logic. The rejection-reason chain re-inlines /^[a-zA-Z0-9_-]{1,64}$/ and 32 * 1024 as literals, duplicating Config.RUNTIME_CONTEXT_KEY_RE and Config.RUNTIME_CONTEXT_MAX_VALUE_BYTES. If either Config constant changes, the handler's rejection reasons silently diverge — reporting invalid_key for a key Config accepted, or vice versa.

Consider having setRuntimeContextEntry return a structured result ({ ok: true } | { ok: false; reason: string }) instead of a bare boolean, so the handler never re-derives the rejection reason. Alternatively, expose the constants from Config (they're currently private static readonly).

— qwen3.7-max via Qwen Code /review

this.getOwnRuntimeContextEntries().delete(key);
}

setRuntimeContext(entries: Record<string, string>): void {

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.

[Suggestion] setRuntimeContext(entries) is defined and tested but has zero production callers. The ACP handler iterates entries individually via setRuntimeContextEntry/removeRuntimeContextEntry. The SDK's DaemonSessionClient.setRuntimeContext goes through the HTTP route, which also uses per-entry methods. This Config method is dead code with subtly different semantics (silent drops invalid entries without reporting them).

Either remove it (inlining the test setup), or wire it into the ACP handler and align its return value with the per-entry path's { keys, rejected } shape.

— qwen3.7-max via Qwen Code /review

const bootConfig = makeRuntimeCtxConfig();
runAcpAgent(
bootConfig as unknown as Config,
{ merged: { mcpServers: {} } } as unknown as LoadedSettings,

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.

[Critical] All 6 tests in the sessionRuntimeContext handler describe block crash with TypeError: mcpServers is not iterable at acpAgent.ts:6975. setupAgent calls agent.newSession({}) without providing an mcpServers array, so the production code's for (const server of mcpServers) throws on undefined.

This is why CI's Test (ubuntu-latest, Node 22.x) check is red.

Suggested change
{ merged: { mcpServers: {} } } as unknown as LoadedSettings,
runAcpAgent(
bootConfig as unknown as Config,
{ merged: { mcpServers: [] } } as unknown as LoadedSettings,
{} as CliArgs,
);

Also fix the loadSettings mock at the same location — use mcpServers: [] instead of mcpServers: {}.

— qwen3.7-max via Qwen Code /review

Comment thread packages/cli/src/serve/server.ts Outdated
}

const serialized = JSON.stringify(entries);
if (Buffer.byteLength(serialized, 'utf8') > 32 * 1024) {

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.

[Critical] The server enforces a 32 KiB cap on JSON.stringify(entries) (the entire serialized object, including keys, braces, and quotes), while Config.setRuntimeContextEntry enforces a 32 KiB cap on each individual value. These are different measurements.

A payload of 16 entries with ~2 KiB values each totals ~34 KiB serialized and is rejected here with HTTP 413, even though every individual entry passes Config's per-value check. Conversely the error message "runtime context payload exceeds 32 KiB limit" implies a per-entry contract that does not exist.

Either (1) rename this constant to RUNTIME_CONTEXT_MAX_PAYLOAD_BYTES and give it a distinct value (e.g. 48 KiB) that accommodates realistic multi-entry payloads, documenting it as the transport-envelope limit, or (2) drop this check and let Config be the single authority.

— qwen3.7-max via Qwen Code /review

'permission_mediation',
'non_blocking_prompt',
'session_language',
'session_runtime_context',

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.

[Critical] POST /session/:id/runtime-context (server.ts:4249) has no route-level test coverage despite the fakeBridge.setSessionRuntimeContext stub being added on line 1318. Comparable routes like POST /session/:id/approval-mode (line 6730) and POST /session/:id/language (line 6952) have full describe blocks exercising success, validation failure (400), and bridge-error paths.

The new route has four branches — 400 for invalid entries, 413 for oversized payload, 200 success via bridge, and the sendBridgeError catch — none of which are verified. Regressions in body validation, the 32 KiB pre-check, clientId header forwarding, or error mapping will go undetected until integration testing.

Suggested: add a describe('POST /session/:id/runtime-context', ...) block following the approval-mode pattern, covering (1) valid entries returning 200 with the bridge response, (2) entries: null / array returning 400, (3) serialized body > 32 KiB returning 413, (4) bridge throwing returning the sendBridgeError status code.

— qwen3.7-max via Qwen Code /review

} else if (
Buffer.byteLength(value, 'utf8') > 32 * 1024
) {
rejected.push({ key, reason: 'value_too_large' });

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.

[Suggestion] The value_too_large and capacity_full rejection-reason branches are untested. Existing handler tests cover value_not_string and invalid_key, but not these two.

The reason-mapping logic here re-derives the failure cause by re-running the same regex (/^[a-zA-Z0-9_-]{1,64}$/) and size (32 * 1024) checks Config already performed internally. If the regex or byte limit in Config ever drifts from what the handler inlines, SDK consumers silently receive wrong rejected[].reason values.

Two suggested tests:

  1. Send { validkey: 'x'.repeat(32 * 1024 + 1) } and assert rejected[0].reason === 'value_too_large'.
  2. Pre-fill 16 entries via the mock Config map, send a 17th valid entry, and assert rejected[0].reason === 'capacity_full'.

Longer-term, consider having Config.setRuntimeContextEntry return a discriminated result ({ ok: true } | { ok: false; reason: string }) so the handler doesn't have to re-validate, and export RUNTIME_CONTEXT_KEY_RE / RUNTIME_CONTEXT_MAX_VALUE_BYTES from config.ts so the constants have a single source of truth.

— qwen3.7-max via Qwen Code /review

this.getOwnRuntimeContextEntries().delete(key);
}

setRuntimeContext(entries: Record<string, string>): void {

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.

[Suggestion] setRuntimeContext(entries) silently drops entries that fail validation (clear()s the store, then iterates and only stores passing entries) and returns void. This is inconsistent with setRuntimeContextEntry (returns boolean) and with the ACP handler (returns { keys, rejected: [...] }).

A future caller passing 16 entries where 2 have invalid keys will atomically destroy the existing context and silently lose the 2 bad entries with no feedback. Today this method has no production caller — only config.test.ts exercises it — so it's a dormant footgun rather than a live bug.

Options:

  1. Change the return type to { applied: string[]; rejected: Array<{ key: string; reason: string }> }, matching the handler's contract.
  2. Remove the method entirely if no production caller is planned — setRuntimeContextEntry already covers the use case.
  3. At minimum, document the silent-drop behavior in JSDoc and add a comment warning future callers.

— qwen3.7-max via Qwen Code /review

if (!entry) throw new SessionNotFoundError(sessionId);
const info = channelInfoForEntry(entry);
if (!info || info.isDying) throw new SessionNotFoundError(sessionId);
resolveTrustedClientId(entry, context?.clientId);

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.

[Suggestion] setSessionRuntimeContext does not publish any SSE event on success, unlike the comparable setSessionLanguage (publishes language_changed at line 4042), setSessionModel (publishes model_switched), and setSessionApprovalMode (publishes approval_mode_changed). Connected SSE clients (browser UI, IDE status bars) cannot react to runtime-context mutations — they must poll to learn about changes.

Also: resolveTrustedClientId(entry, context?.clientId) is called for validation, but its return value is discarded. If no event is planned, the call serves no purpose (validation would still throw InvalidClientIdError whether or not the return is captured, but the originatorClientId propagation that other handlers rely on is lost).

If events are intentionally omitted for this mutation, add a comment explaining why (mirroring the pattern at generateSessionRecap line 4279: "recap is informational-only today — no SSE broadcast"). Otherwise, publish a runtime_context_changed event carrying keys and the resolved originatorClientId.

— qwen3.7-max via Qwen Code /review

}

const runtimeCtx = this.config.getRuntimeContext();
for (const [key, value] of runtimeCtx) {

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.

[Suggestion] The injection loop iterates the runtime-context Map and wraps each value with escapeSystemReminderTags(value). This escape function only neutralizes literal <system-reminder> / </system-reminder> tag strings (confirmed in xml.ts:152). Other trusted envelope tags used elsewhere in the conversation — <task-notification> (backgroundShellRegistry), <available_skills> (environmentContext), <task-id>, <summary> — pass through verbatim inside the injected <system-reminder> body.

A malicious trusted caller (MCP server, ACP peer, daemon plugin) could set a runtime-context value containing literal <task-notification>...</task-notification> markup. The model, which already treats these tags as authoritative system metadata in other parts of the conversation, may act on the fabricated notification.

Mitigation: runtime context is set by a trusted controller (daemon API / SDK via resolveTrustedClientId), not by the end user directly, so exploitability is bounded by trust in connected clients. If the trust boundary is ever relaxed (e.g., untrusted MCP-sourced context), switch to escapeXml(value) here — runtime-context values are opaque metadata and never need raw XML that the model should parse.

Also consider reserving a key prefix (e.g. qwen- or _) for internal/system keys, and rejecting user-supplied keys that match — keys like system, operator, admin, instructions imply elevated authority when rendered as [system] ... inside a system-reminder.

— qwen3.7-max via Qwen Code /review

Comment thread packages/cli/src/serve/server.ts Outdated
}

const serialized = JSON.stringify(entries);
if (Buffer.byteLength(serialized, 'utf8') > 32 * 1024) {

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.

[Suggestion] The HTTP route caps the total serialized payload at 32 KiB, but Config allows 16 entries × 32 KiB each = 512 KiB theoretical max store. A legitimate 10-entry request with ~4 KiB per value (~40 KiB total) gets 413'd here even though every individual value passes the per-value limit. Meanwhile the ACP ext-method path has no aggregate check, so the same payload succeeds through that transport.

Consider either raising this cap to MAX_ENTRIES × MAX_VALUE_BYTES (512 KiB), or defining a separate named constant (e.g. RUNTIME_CONTEXT_MAX_PAYLOAD_BYTES) if the tighter limit is intentional — but document the intentional mismatch so future maintainers don't assume it's a bug.

— qwen3.7-max via Qwen Code /review

rejected.push({ key, reason: 'capacity_full' });
}
}
return { keys: appliedKeys, rejected };

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.

[Suggestion] Zero logging on runtime context mutations. Every other control-plane handler in this file (language, approval mode, model switch, recap) has at least a debug log or status endpoint. When a session's model starts behaving unexpectedly due to an injected <system-reminder>, the oncall engineer has no way to trace which entries were set/updated/rejected.

Suggested change
return { keys: appliedKeys, rejected };
debugLogger?.debug?.(`[runtime-ctx] session=${sessionId} applied=${appliedKeys.length} rejected=${rejected.length} keys=[${appliedKeys.join(',')}]`);
return { keys: appliedKeys, rejected };

— qwen3.7-max via Qwen Code /review

}
} else if (config.setRuntimeContextEntry(key, value)) {
appliedKeys.push(key);
} else if (!/^[a-zA-Z0-9_-]{1,64}$/.test(key)) {

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.

[Suggestion] The key regex /^[a-zA-Z0-9_-]{1,64}$/ and byte limit 32 * 1024 are duplicated inline here, separate from Config.RUNTIME_CONTEXT_KEY_RE and Config.RUNTIME_CONTEXT_MAX_VALUE_BYTES (both private static readonly). If either limit changes in Config, this reason-determination cascade silently diverges — e.g., a key that Config now accepts would still get reported as 'invalid_key'.

The root cause is that setRuntimeContextEntry returns boolean — no reason for the rejection. A cleaner fix would be to change it to return { ok: true } | { ok: false; reason: string }, eliminating the need for the caller to re-validate:

// In Config:
setRuntimeContextEntry(key: string, value: string): { ok: boolean; reason?: string }

// Then in this handler:
const result = config.setRuntimeContextEntry(key, value);
if (!result.ok) rejected.push({ key, reason: result.reason! });

— qwen3.7-max via Qwen Code /review

systemReminders.unshift(userQueryMemory.prompt);
}

const runtimeCtx = this.config.getRuntimeContext();

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.

[Suggestion] Key not escaped in system-reminder injection template.

The value is properly sanitized via escapeSystemReminderTags(value), but the key is interpolated directly into the template as [${key}] without escaping. While keys are validated by /^[a-zA-Z0-9_-]{1,64}$/ at the external input boundary, getRuntimeContext() returns the mutable Map (typed as ReadonlyMap but ReadonlyMap is compile-time only). Any internal code with Config access can call .set() on the returned Map, bypassing validation entirely.

Defense-in-depth: escape the key at the injection point, matching the value treatment:

Suggested change
const runtimeCtx = this.config.getRuntimeContext();
const runtimeCtx = this.config.getRuntimeContext();
for (const [key, value] of runtimeCtx) {
const safeKey = escapeSystemReminderTags(key);
const safe = escapeSystemReminderTags(value);
systemReminders.push(
`<system-reminder>\n[${safeKey}] ${safe}\n</system-reminder>`,
);
}

— qwen3.7-max via Qwen Code /review

return this.runtimeContextEntries;
}

getRuntimeContext(): ReadonlyMap<string, string> {

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.

[Suggestion] getRuntimeContext() returns the mutable Map and silently isolates subagents.

Two concerns:

  1. Mutable Map despite ReadonlyMap type. ReadonlyMap is compile-time only — at runtime, callers can .set(), .delete(), .clear() the returned Map, bypassing all validation (key regex, size limit, entry count). Returning new Map(this.getOwnRuntimeContextEntries()) would provide actual defense-in-depth.

  2. Silent subagent isolation. The hasOwnProperty guard in getOwnRuntimeContextEntries() (introduced to fix the Object.create(parent) prototype chain leak) also prevents subagent Configs — created via Object.create(parent) in InProcessBackend.ts:401 and subagent-manager.ts:882 — from reading the parent's runtime context through the prototype chain. Subagents get a fresh empty Map. This is inconsistent with how userMemory and other session-level state propagates to subagents.

If subagent isolation is intentional, make it explicit (e.g., a comment or a dedicated getRuntimeContextForSubagent() method). If subagents should see the parent's context, return a read-only copy that walks the prototype for reads but blocks writes.

— qwen3.7-max via Qwen Code /review

);
}

async setRuntimeContext(

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.

[Suggestion] setRuntimeContext does incremental merge, but the name implies full replacement.

The full-stack path (DaemonSessionClient → HTTP route → bridge → acpAgent handler) iterates entries and calls config.setRuntimeContextEntry(key, value) per key — an additive upsert. A caller who does setRuntimeContext({ newKey: 'val' }) after a prior setRuntimeContext({ oldKey: 'val' }) will find both keys present, not just newKey.

Meanwhile, Config.setRuntimeContext() — which does a clear-and-replace — exists but has zero production callers (dead code). The naming inconsistency (set vs actual merge behavior) and the unused replace method suggest the design intent is unclear.

Consider either: (a) wiring Config.setRuntimeContext() in the handler before iterating (matching the "set" name), or (b) renaming to updateRuntimeContext / patchRuntimeContext and adding explicit clearRuntimeContext() and getRuntimeContext() SDK methods.

— qwen3.7-max via Qwen Code /review

).rejects.toThrow(/sessionId/);
});

it('throws on invalid entries shape', async () => {

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.

[Suggestion] The entries validation in the handler has three distinct OR branches (typeof entries !== 'object', entries === null, Array.isArray(entries)), but the existing "throws on invalid entries shape" test passes entries: 'not-an-object' which only hits the first branch. entries: null and entries: [1, 2] each exercise untested code paths. Consider adding test cases for null and array inputs to cover all validation branches.

— qwen3.7-max via Qwen Code /review

expect(config.getRuntimeContext().get('key-0')).toBe('updated');
});

it('should bulk-set entries', () => {

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.

[Suggestion] The existing bulk-set test covers only the happy path with 2 valid entries. The bulk setRuntimeContext method has its own inline validation that silently drops entries failing key regex, byte-size limit, or 16-entry capacity — a different contract from setRuntimeContextEntry (singular, returns boolean). Specific untested scenarios:

  • Bulk-set exceeding 16 entries (does it stop at 16?)
  • Bulk-set with invalid keys mixed in (silently skipped while valid keys stored?)
  • Bulk-set with empty-string values (value && skips them, but the singular method treats empty string as deletion)

The behavioral asymmetry between bulk and singular methods is worth explicit test coverage.

— qwen3.7-max via Qwen Code /review

systemReminders.unshift(userQueryMemory.prompt);
}

const runtimeCtx = this.config.getRuntimeContext();

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.

[Suggestion] Runtime context entries are injected only in GeminiClient.sendMessageStream. Subagents (AgentCore.createChat), background agents (background-agent-resume.ts), and memory planners (skillReviewAgentPlanner.ts, extractionAgentPlanner.ts, dreamAgentPlanner.ts) all create GeminiChat directly and bypass this injection path. If runtime context (e.g., operator identity) is intended to apply to the entire session including subagent turns, a second injection point is needed — either in GeminiChat.sendMessageStream or in the subagent system prompt building path.

— qwen3.7-max via Qwen Code /review

@callmeYe
callmeYe force-pushed the worktree-feat+runtime-context branch from 11713a7 to db94452 Compare June 25, 2026 15:12

@qwen-code-ci-bot qwen-code-ci-bot 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.

⚠️ Downgraded from Approve to Comment: CI failing: Test (ubuntu-latest, Node 22.x).

1 finding (Suggestion). Build and all 1177 tests pass locally. Deterministic analysis clean (typecheck and eslint).

— qwen3.7-max via Qwen Code /review

) {
rejected.push({ key, reason: 'value_too_large' });
} else {
rejected.push({ key, reason: 'capacity_full' });

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.

[Suggestion] The else clause here unconditionally produces capacity_full as the rejection reason. This cascade re-derives the failure cause by re-running Config's validation checks inline (key regex, byte length), then assumes anything left must be capacity. If Config.setRuntimeContextEntry ever adds a fourth validation rule (e.g., reserved key prefix, value charset restriction), the new failure would silently fall through to capacity_full — misleading API consumers about the real cause.

Consider having setRuntimeContextEntry return a structured result instead of a bare boolean:

Suggested change
rejected.push({ key, reason: 'capacity_full' });
const result = config.setRuntimeContextEntry(key, value);
if (result.ok) {
appliedKeys.push(key);
} else {
rejected.push({ key, reason: result.reason });
}

This eliminates the fragile re-derivation and makes the rejection reason authoritative from the Config layer.

— qwen3.7-max via Qwen Code /review

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

[Critical] TypeScript does not pass on the reviewed head. qwen review deterministic reports five tsc errors in packages/cli/src/serve/server.test.ts (including the fake bridge no longer matching AcpSessionBridge / DaemonWorkspaceService, plus extension mock return-type mismatches). These diagnostics are outside the added diff lines, so they cannot be anchored inline, but the branch needs to typecheck cleanly before merge.

— GPT-5 via Qwen Code /review

);
}

requestToSend = [...systemReminders, ...requestToSend];

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.

[Critical] These generated runtime-context reminders are prepended to requestToSend, and GeminiChat.sendMessageStream persists that full user content into chat history before sending. After a caller updates or removes a key, the old <system-reminder>[key] ...</system-reminder> remains in prior user turns and is sent again on future requests, so stale rules or operator data can keep influencing the model and continue being sent to the provider. Treat runtime context as a request-only overlay, or tag/filter these generated reminder parts before committing user content to history, and add a set -> send -> remove/update -> send regression test.

— GPT-5 via Qwen Code /review

rejected: Array<{ key: string; reason: string }>;
}> {
return await this.fetchWithTimeout(
`${this.baseUrl}/session/${encodeURIComponent(sessionId)}/runtime-context`,

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.

[Critical] This new SDK method goes through this.transport.fetch(...), but ACP HTTP/WS transports do not hit the REST Express route directly; they first map URL-shaped calls through acpRouteTable.ts. There is no /session/:id/runtime-context mapping and no matching _qwen/session/runtime_context dispatcher, so clients using negotiateTransport() can select ACP and get a synthesized 404 even though the REST route works. Add the route-table entry, ACP dispatch handler, and transport tests for this API.

— GPT-5 via Qwen Code /review

const config = session.getConfig();
const appliedKeys: string[] = [];
const rejected: Array<{ key: string; reason: string }> = [];
for (const [key, value] of Object.entries(

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.

[Critical] Processing the batch strictly in object order makes capacity handling depend on caller key order. If the store already has 16 entries and a caller sends { newKey: 'v', oldKey: '' }, newKey is rejected as capacity_full before oldKey is removed; the same logical update succeeds if the deletion appears first. Apply empty-string removals before non-empty sets, or compute capacity against the post-removal store, so a single batch has deterministic semantics.

— GPT-5 via Qwen Code /review

@qwen-code-ci-bot qwen-code-ci-bot 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.

⚠️ Downgraded from Approve to Comment: CI still running.

No new findings in this re-review. 9 parallel review agents + verification + reverse audit confirmed that all significant concerns are already covered by prior review comments.

Build & tests: ✅ Build passes. All 17 new tests pass (10 Config RuntimeContext, 1 client injection, 6 acpAgent handler). ESLint clean. 5 pre-existing tsc errors in server.test.ts at unchanged lines (not caused by this PR).

Note: The prior Critical comment about test crashes (mcpServers is not iterable at acpAgent.test.ts:7552) appears stale — verified that line 7560 passes mcpServers: [] and all 6 handler tests pass successfully.

— qwen3.7-max via Qwen Code /review

@tanzhenxin

tanzhenxin commented Jun 26, 2026

Copy link
Copy Markdown
Collaborator

Thanks — the need itself is clear: sessions sharing a qwen serve instance want their own context without writing to the project-level QWEN.md. I'd like to step back to the layering, though, since I think that's where this decision really sits.

The way I think about it: qwen-code core is a single-session engine. It runs one conversation for one caller, with one set of context — the system prompt plus QWEN.md memory — and it's deliberately agnostic about who's driving it or how many other sessions exist. That agnosticism is exactly what lets the same engine sit behind the interactive CLI, the SDK, a subagent, or the daemon without change. qwen serve is the layer that turns that single-session engine into a multi-tenant service: many concurrent sessions, multiple clients, per-client identity and isolation. Concurrency and per-tenant state are its job, by design.

RuntimeContext — context that differs per session, varies per client, and mutates at runtime — is multi-tenant state in exactly that sense. A single-session user never reaches for it; they edit QWEN.md or pass append. The need only appears once several tenants share one engine, which is precisely the world qwen serve exists to manage. So conceptually this is a daemon concept — and the daemon already owns the rest of the per-session state.

Putting it in core inverts that layering: the engine starts carrying a notion that exists only because of the layer above it. Once, it's harmless; as a habit, it's how a clean, embeddable engine slowly turns into one that has to know about every consumer's needs.

So the real question, before any implementation: is there something that genuinely requires this to live in the engine rather than at the serve boundary? If there is, let's name it and weigh it. If not, I'd keep core single-session-pure and own this in the daemon, where the per-tenant state already lives.

中文

感谢提交——需求本身很清楚:共享同一个 qwen serve 实例的会话,需要各自独立的上下文,同时又不去改动项目级的 QWEN.md。不过我想先退回到分层这一层来看,因为我觉得这个决定的关键正在于此。

我的理解是这样的:qwen-code core 是一个单会话引擎。它为单个调用方运行一段对话,只有一套上下文——系统提示词加上 QWEN.md memory——并且它刻意对"是谁在驱动它、外面还存在多少其他会话"保持无感知。正是这种无感知,才让同一个引擎能够不加改动地分别支撑交互式 CLI、SDK、子代理(subagent)以及 daemon。而 qwen serve 是把这个单会话引擎变成多租户服务的那一层:大量并发会话、多个客户端、按客户端的身份与隔离。并发与按租户的状态,本就是它的职责。

RuntimeContext——按会话不同、随客户端变化、并在运行时可变的上下文——正是这种意义上的多租户状态。单会话用户从不需要它;他们改 QWEN.md 或传 append 就够了。这个需求只有在多个租户共享一个引擎时才会出现,而这恰恰是 qwen serve 存在的意义。所以从概念上讲,这是一个 daemon 层的概念——而且 daemon 本就已经持有其余的按会话状态。

把它放进 core 会让分层倒置:引擎开始承载一个仅仅因为上层才存在的概念。偶尔一次无伤大雅;一旦成为习惯,一个干净、可嵌入的引擎就是这样慢慢变成一个不得不了解每个消费方需求的引擎。

所以在动手实现之前,真正要问的是:是否存在某种东西,确实要求它必须落在引擎里、而不能放在 serve 边界?如果有,我们把它点出来、一起权衡。如果没有,我倾向于让 core 保持纯单会话,把这件事交给 daemon——按租户的状态本就都在那里。

@callmeYe

Copy link
Copy Markdown
Collaborator Author

@tanzhenxin Thanks for the thoughtful layering analysis — I agree with the framing and have updated the PR description accordingly (removed all daemon-specific business context, repositioned as a generic SDK-level capability aligned with the Claude Agent SDK's system prompt modification patterns).

On the core vs daemon question — you're right that this is conceptually multi-tenant state. Let me lay out why the current implementation touches core, and whether the alternative works:

Why core today:

The injection point is GeminiClient.sendMessageStream() — the systemReminders[] assembly at the start of each UserQuery/Cron turn. This is deep inside core, and the daemon layer has no hook into this assembly pipeline. The existing per-turn injections (date, plan mode, arena, memory recall) all live here because this is the only place where per-turn user-message prepends happen.

The daemon-only alternative would be:

  1. Hook-based (UserPromptSubmit) — a hook fires every turn and could inject additional_context. But hooks are configured at session init via settings files, not via API. The daemon can't say "for this session, inject this text on every turn" without writing a hook config, which is a file-system side effect with its own problems.

  2. appendSystemPrompt — works for creation-time context but can't be updated mid-session (it's readonly on Config). And it goes into the system instruction, affecting prompt cache.

  3. enqueueMidTurnMessage — only works during active turns, and injects as a user message in the conversation history (not a per-turn system reminder that the model sees as framework context).

None of these give "external caller sets key-value context that appears as <system-reminder> on every subsequent turn and can be updated mid-session."

The minimal core surface:

The actual core footprint is intentionally tiny — a Map<string, string> field on Config (with hasOwnProperty isolation for Object.create subagents) + 4 lines in sendMessageStream. Config already carries other externally-set mutable state (userMemory, approvalMode, fastModel, runtimeMcpServers). The Map is agnostic about who sets it — it doesn't know about tenants, clients, or the daemon. The daemon/bridge/SDK layers own the transport for setting it.

That said, I'm open to restructuring if there's a cleaner boundary. One option: move the Map storage to the bridge layer and use the existing SessionStart hook applySessionStartContext path to push it into the system instruction (accepting the prompt-cache tradeoff). Would that be preferable?


Also noting: I've updated the PR description to remove all references to specific downstream consumers and reposition this as a generic capability — analogous to Claude Agent SDK's append but with mid-session mutability. The comparison table in the description now frames it against Claude SDK and Codex CLI patterns.

@tanzhenxin

Copy link
Copy Markdown
Collaborator

Thanks — this is a strong reply, and it moved me off part of my position. Let me drop what doesn't hold and sharpen what does.

You're right that the layering objection isn't the real issue. Config is instantiated per session, so a map on it is one session's state, not multi-tenancy leaking into the engine — and append already establishes that core legitimately carries context an external caller hands it. I'll set the core-vs-daemon framing aside.

But following your own "append, but mutable" framing is exactly what makes me hesitate on the mechanism, for two reasons.

First, what this carries — operator identity, per-session rules — is session-constant: set once, unchanged turn to turn. Per-turn <system-reminder> injection is the channel core reserves for things that genuinely vary each turn — date, plan mode, memory recall. Routing a constant through it re-pays the same text on every turn and, after the tenth repetition, reads more like noise than framing. Session constants belong in the system instruction, stated once — which is exactly where append already puts them.

Second, the append precedent points at the smaller design, not this one. append is a single string set once in the system instruction. The only thing a per-turn KV channel adds over simply making that slot settable (plus a refreshSystemInstruction) is mutating the value mid-conversation without a cache bust. So the whole design rests on one question I don't think we've answered yet:

Does the value actually need to change mid-conversation, or only be set once near session start?

The PR's own shape points to the latter: creation-time seeding (initialRuntimeContext) is deferred to a follow-up while the runtime-mutation path ships first. If the data is fundamentally set-once, that ordering is backwards — and a settable append / creation-time context param covers every case you list (operator identity, per-session overlays) at zero per-turn cost and without a new keyed-store contract for core to carry.

So I'd suggest right-sizing it: start with the set-once capability, and add the per-turn mutable channel when a concrete mid-conversation update actually shows up. Could you point to a case where the value must change during a conversation, rather than be fixed when the session opens? If there's a solid one, let's design around that trigger specifically. If not, I'd land the minimal version now and keep the door open.

中文

感谢回复——这是一个很有分量的回应,也让我放下了之前的一部分判断。我先把站不住的部分撤掉,把站得住的部分讲清楚。

你说得对,分层并不是真正的症结。Config 本来就是按会话实例化的,所以挂在它上面的一个 map 是单个会话的状态,而非多租户渗进引擎——而且 append 已经确立了一点:core 合理地承载外部调用方交给它的上下文。core-vs-daemon 这个框架我就不再坚持了。

但顺着你自己"append,但可变"的说法往下走,恰恰是让我对这个机制有所犹豫的地方,有两点:

第一,它承载的东西——操作人身份、按会话的规则——是会话级常量:设置一次,逐轮不变。而按轮的 <system-reminder> 注入,是 core 留给那些确实逐轮变化的东西的通道——日期、plan 模式、memory recall。把一个常量塞进这个通道,会在每一轮重复支付同一段文本,重复到第十次之后,它读起来更像噪声而非框架性提示。会话级常量应该放进 system instruction、只陈述一次——而这恰恰就是 append 已经放置它们的地方。

第二,append 这个先例指向的是更小的设计,而不是当前这个。append 是在 system instruction 里只设置一次的单个字符串。一个按轮的 KV 通道,相比"把这个槽位变成可设置(再加一次 refreshSystemInstruction)"所多出来的,仅仅是:在会话进行中改动这个值、且不触发 prompt cache 失效。所以整个设计都押在一个我认为还没回答的问题上:

这个值真的需要在会话进行中改变吗,还是只需在会话开始时设置一次?

这个 PR 自身的形态指向后者:创建时预设(initialRuntimeContext)被推迟到后续 PR,而运行时改动这条路径先落地。如果这份数据本质上是"设置一次",那这个先后顺序是反的——而一个可设置的 append / 创建时的 context 参数,就能覆盖你列出的全部场景(操作人身份、按会话的规则叠加),且没有任何按轮开销,也不必让 core 去维护一个新的键值存储契约。

所以我建议把它收到合适的尺寸:先做"设置一次"的能力,等到真的出现一个会话进行中需要更新的具体场景时,再加上按轮的可变通道。你能否举出一个值必须在会话进行中改变、而不是在会话开启时就固定下来的例子?如果有扎实的例子,我们就针对那个触发点来专门设计;如果没有,我倾向于先把最小版本落地,同时给后续留好口子。

wenshao
wenshao previously approved these changes Jun 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 issues found. LGTM.

— GPT-5 via Qwen Code /review

@wenshao

wenshao commented Jun 26, 2026

Copy link
Copy Markdown
Collaborator

@qwen-code /resolve

@qwen-code-dev-bot

Copy link
Copy Markdown
Collaborator

Qwen Code resolved the merge conflicts and pushed the branch update.

Merge Conflict Resolution Summary

PR #5847: feat(serve): add runtime context injection for per-turn system-reminders

Conflicts Found

Two files had content conflicts when merging origin/main into the PR branch:

  1. packages/cli/src/serve/server.ts — 2 conflict regions
  2. packages/sdk-typescript/scripts/build.js — 1 conflict region

Root Cause

Main branch commit 2199382ae ("refactor(cli): Split serve server routes (#5809)") extracted route handlers and helper functions from the monolithic server.ts into separate files:

  • server/telemetry.tsresolveDaemonTelemetryRoute, daemonTelemetryMiddleware
  • server/prompt-deadline.tsPromptDeadlineExceededError, resolvePromptDeadlineMs
  • server/request-helpers.ts, server/fs-factory.ts, server/session-list.ts — other helpers
  • routes/session.ts, routes/workspace-auth.ts, etc. — route registration functions

The PR branch still had all this code inline in server.ts, causing large structural conflicts.

Resolutions

1. packages/cli/src/serve/server.ts

  • Conflict 1 (extracted functions, ~220 lines): Took main's side (empty). The inlined resolveDaemonTelemetryRoute, daemonTelemetryMiddleware, PromptDeadlineExceededError, and resolvePromptDeadlineMs were already properly imported from their new extracted locations via auto-merged import statements.
  • Conflict 2 (extracted routes, ~1400 lines): Took main's side (empty). The inlined route registrations (device-flow, auth, workspace routes, MCP restart, etc.) were already registered via registerSessionRoutes(), registerWorkspaceAuthRoutes(), etc. from the auto-merged import statements.

2. packages/sdk-typescript/scripts/build.js

  • Both branches added a comment about bumping the bundle size from 130KB to 131KB — one for "session runtime context APIs" (PR), one for "workspace MCP resources drill-down" (main). Kept both comments since both features are present; bundle size stay

@qwen-code-ci-bot qwen-code-ci-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Re-review with qwen3.7-max — no new findings. All significant concerns are already covered by prior review comments. Downgraded from Approve to Comment: CI still running.

Build & tests: Build passes, all 17 new tests pass (10 Config RuntimeContext + 6 ACP handler + 1 client injection), eslint clean. 7 pre-existing tsc errors in server.test.ts and integration-tests are not caused by this PR.

Needs Human Review:

  • The entries === null and Array.isArray(entries) validation branches in the handler have no dedicated test coverage (the single invalid-entries test sends a string).
  • The bulk setRuntimeContext() test only covers valid entries; silent-discard behavior for invalid entries is unpinned.

— qwen3.7-max via Qwen Code /review

@wenshao

wenshao commented Jun 28, 2026

Copy link
Copy Markdown
Collaborator

@qwen-code /resolve

@qwen-code-dev-bot

Copy link
Copy Markdown
Collaborator

Qwen Code resolved the merge conflicts and pushed the branch update.

Merge Conflict Resolution Summary

PR: #5847 - feat(serve): add runtime context injection for per-turn system-reminders

Conflicts Encountered

Two test files had conflicts when merging origin/main into the PR branch:

  1. packages/cli/src/acp-integration/acpAgent.test.ts
  2. packages/core/src/config/config.test.ts

Nature of Conflicts

Both conflicts were additive — the PR branch and main branch added new, independent test blocks at the same location in the file. These were not true semantic conflicts, just positional overlaps.

Resolution Strategy

Kept both sides — all new test blocks from both the PR branch and main branch were preserved.

File 1: acpAgent.test.ts

  • PR branch (HEAD) added: describe('sessionRuntimeContext handler', ...) — tests for the runtime context injection feature
  • Main branch added: describe('deliverClientMcpMessage — reverse tool channel (#5626)', ...) — tests for MCP message delivery

Resolution: Kept both describe blocks. Added proper closing braces for the PR's describe block before the main's describe block starts.

File 2: config.test.ts

  • PR branch (HEAD) added: describe('RuntimeContext', ...) — unit tests for RuntimeContext API (set/get/delete/validation/limits)
  • Main branch added: describe('MCP Stop dispatch with context usage data', ...) — tests for context usage validation in MCP hooks

Resolution: Kept both describe blocks. Added proper closing braces for the PR's describe block before the main's describe block starts.

Files Modified

Only the two conflicting test files were modified:

  • packages/cli/src/acp-integration/acpAgent.test.ts
  • packages/core/src/config/config.test.ts

Commit

Created merge commit: chore: resolve merge conflicts with main (runtime context tests)

The resolution preserves all functionality from both branches without any code loss.

@qwen-code-dev-bot

Copy link
Copy Markdown
Collaborator

Qwen Code resolved the merge conflicts and pushed the branch update.

Merge Conflict Resolution Summary — PR #5847

Base branch

main (fetched as origin/main, head at 82fb6a4f0)

Conflicted files

1. packages/core/src/config/config.test.ts

Conflict: The PR branch (HEAD) had no new content at the insertion point (lines 396–397 were empty between <<<<<<< HEAD and =======). Meanwhile, origin/main added ~240 lines of new test describe blocks:

  • getMaxSubagentDepth — tests for subagent nesting depth defaults, clamping, flooring, and caps
  • getTeamMemoryEnabled — tests for team memory toggle via setting, env var, and bare mode
  • getCronRecurringMaxAgeDays — tests for cron max-age config, env override, Infinity mapping, and construction-time resolution
  • getTeamMemorySyncEnabled — tests for team memory sync toggle

Resolution: Took main's additions entirely. The PR branch had nothing to contribute at this location — these are new features that landed on main after the PR branched off.

2. packages/sdk-typescript/scripts/build.js

Conflict: Both sides bumped the MAX_DAEMON_BROWSER_BUNDLE_BYTES constant from 133KB:

  • HEAD (PR): 133 → 134 → 135KB (for session runtime context APIs)
  • main: 133 → 136 → 137KB (for session artifacts, sessionless workspace memory forget/dream APIs, and EventBus byte-backlog telemetry validation)

Resolution: Took main's value of 137KB. The merged codebase includes both sets of features, and main's budget already accounts for a larger accumulated surface. The PR's runtime context APIs add ~1KB on top; if the actual bundle exceeds 137KB, the PR's CI will catch it and the author can bump the budget in a follow-up commit.

Commit

merge: sync with main (Conventional Commit format, matching the project's existing merge commit convention)

@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 of the runtime-context feature. The core mechanism (Config store → per-turn injection with escapeSystemReminderTags → ACP ext-method → daemon route → SDK) is coherent and value-escaping is handled correctly. My main concern is a large, unrelated test deletion that appears accidental; the rest are cleanup/scope notes.

🤖 Reviewed with Claude Code (Opus 4.8)

});
});

describe('Server Config (config.ts)', () => {

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.

This PR removes ~450 lines of test coverage unrelated to runtime-context. Deleted here: describe('matchesServerPattern') / matchesAnyServerPattern, the team-memory security-gating tests (including the TeamMemoryRootSecurityError symlink-escape refusal — a security regression guard), describe('computer use settings'), and the modalities hot-switch assertions in Model Switching.

All of the code under test still exists in config.ts (matchesServerPattern @668, getComputerUseIdleTimeoutMs @5087, getEffectiveInputModalities @3063, the team-memory sync gate in refreshHierarchicalMemory), so this is live coverage being dropped — most likely a bad rebase/merge artifact rather than an intentional change. Please restore these blocks; the runtime-context tests should be purely additive.

}
} else if (config.setRuntimeContextEntry(key, value)) {
appliedKeys.push(key);
} else if (!/^[a-zA-Z0-9_-]{1,64}$/.test(key)) {

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.

The rejection-reason classification re-implements Config's validation constants (/^[a-zA-Z0-9_-]{1,64}$/ and 32 * 1024) that already exist as Config.RUNTIME_CONTEXT_KEY_RE / RUNTIME_CONTEXT_MAX_VALUE_BYTES. If those limits change in config.ts, this handler will silently misclassify the reason (e.g. report capacity_full for a value that is actually too large, or invalid_key under a widened regex). Consider having setRuntimeContextEntry return a typed reason instead of a boolean so there's a single source of truth for both the accept/reject decision and its cause.


private getOwnRuntimeContextEntries(): Map<string, string> {
if (
!Object.prototype.hasOwnProperty.call(this, 'runtimeContextEntries')

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.

getOwnRuntimeContextEntries guards with hasOwnProperty('runtimeContextEntries') and lazily re-creates the Map, but the field is initialized inline (private runtimeContextEntries: Map<...> = new Map()), so every constructed Config already has it as an own property — the guard never fires. Unless there's a real path that builds Config without running field initializers (Object.create/prototype reuse), this helper can collapse to return this.runtimeContextEntries;.

Comment thread .gitignore
.codegraph
.qwen/computer-use/installed.json
.playwright-mcp/
pnpm-lock.yaml

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.

pnpm-lock.yaml looks unrelated to this feature — the repo uses npm (package-lock.json). If it leaked in from a local pnpm setup, please drop it to keep the PR scoped to runtime-context.


app.post(
'/session/:id/runtime-context',
mutate(),

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.

[Suggestion] This route uses mutate() (non-strict auth gate). Most comparable persistent session-state routes in this file use mutate({ strict: true }) — including approval-mode (L1691), shell (L1575), artifacts (L637), continue (L756), goal/clear (L745), and rewind (L1664). However, model (L1364), language (L1733), and recap (L1394) also use the non-strict mutate(), so this follows an existing subset of the convention.

The concern is that runtime context values are injected as <system-reminder> blocks on every future model turn — unlike a model or language switch, which are one-time settings. Any local process on the machine (compromised dependency, co-tenant, malicious npm package) can POST persistent instructions that the model sees as trusted context on every subsequent turn indefinitely. This makes runtime context a higher-value injection target than a model name or language preference.

Consider using mutate({ strict: true }) to match the majority of persistent-state routes, or add a code comment explaining why non-strict is intentional for this route.

Suggested change
mutate(),
mutate({ strict: true }),

— qwen3.7-max via Qwen Code /review

@wenshao

wenshao commented Jul 7, 2026

Copy link
Copy Markdown
Collaborator

@qwen-code /triage

@wenshao

wenshao commented Jul 7, 2026

Copy link
Copy Markdown
Collaborator

@qwen-code /resolve

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
@wenshao

wenshao commented Jul 7, 2026

Copy link
Copy Markdown
Collaborator

@qwen-code /resolve

@qwen-code-dev-bot

Copy link
Copy Markdown
Collaborator

Qwen Code resolved the merge conflicts and pushed the branch update.

Merge Conflict Resolution Summary — PR #5847

Base branch

main (merged origin/main at bd6816b7a into qwen-resolve/pr-5847)

Conflict

File: packages/core/src/config/config.test.ts

What conflicted: After the disabledTools describe block (around line 5663), origin/main added two new describe blocks — visibleTools (4 tests) and computer use settings (2 tests) — while the PR branch had nothing at that location. The PR branch was forked before these test blocks existed on main, so git could not auto-merge the insertion point.

How resolved: Accepted main's additions (the two new describe blocks). The PR (feat(serve): add runtime context injection for per-turn system-reminders) does not touch visibleTools or computerUseIdleTimeoutMs functionality, so there was no semantic conflict — these are purely additive tests from main that the PR branch simply didn't have yet. The three conflict marker lines (<<<<<<< ours, =======, >>>>>>> theirs) were removed, keeping main's content intact.

Auto-merged files (no manual intervention needed)

  • .gitignore
  • integration-tests/cli/qwen-serve-routes.test.ts
  • packages/acp-bridge/src/bridgeTypes.ts
  • packages/cli/src/acp-integration/acpAgent.test.ts
  • packages/cli/src/acp-integration/acpAgent.ts
  • packages/cli/src/serve/routes/session.ts
  • packages/cli/src/serve/server.test.ts
  • packages/core/src/config/config.ts
  • packages/core/src/core/client.test.ts
  • packages/core/src/core/client.ts
  • packages/sdk-typescript/src/daemon/DaemonClient.ts

Commit

22a19e0cfmerge: sync with main

@qwen-code-dev-bot

Copy link
Copy Markdown
Collaborator

Qwen Code did not run conflict resolution for this request.

PR #5847 does not currently have merge conflicts with main.

@qwen-code-ci-bot qwen-code-ci-bot 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.

⚠️ Downgraded from Request Changes to Comment: CI failing: Post Coverage Comment (ubuntu-latest, 22.x), Test (ubuntu-latest, Node 22.x).

Build failure: SDK browser bundle exceeds 137 KiB limit by 90 bytes — the new DaemonClient.setSessionRuntimeContext and DaemonSessionClient.setRuntimeContext methods push the bundle to 140,378 bytes (MAX_DAEMON_BROWSER_BUNDLE_BYTES = 140,288). Build fails at assertBrowserSafeBundle. Fix: bump the limit or reduce dead code.

Missing test: No test exercises the sessionRuntimeContext handler with a valid-but-nonexistent sessionId. The existing "missing sessionId" test is caught by the typeof guard before reaching sessionOrThrow. The most common production error path (stale SDK session ID) is untested.

— qwen3.7-max via Qwen Code /review

);
}

async setSessionRuntimeContext(

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.

[Critical] SDK browser bundle size limit exceeded.

The new setSessionRuntimeContext method (and its DaemonSessionClient wrapper) push the browser daemon SDK bundle to 140,378 bytes, exceeding MAX_DAEMON_BROWSER_BUNDLE_BYTES (137 × 1024 = 140,288) by 90 bytes. The build fails at assertBrowserSafeBundle in packages/sdk-typescript/scripts/build.js:222.

Suggested change
async setSessionRuntimeContext(
// In packages/sdk-typescript/scripts/build.js, bump the limit:
const MAX_DAEMON_BROWSER_BUNDLE_BYTES = 138 * 1024;

— qwen3.7-max via Qwen Code /review

return false;
}
const entries = this.getOwnRuntimeContextEntries();
if (!value) {

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.

[Suggestion] !value is a falsy check, but the documented deletion semantic is value === '' (empty string). This means hypothetical falsy non-strings (0, false) would also trigger deletion.

The bulk companion setRuntimeContext (line 4666) uses value && (truthy guard), which skips falsy values instead of deleting — creating divergent behavior for the same input across the two methods.

Suggested change
if (!value) {
if (value === '') {
entries.delete(key);
return true;
}

And in setRuntimeContext, replace value && with value !== '' &&.

— qwen3.7-max via Qwen Code /review

getWorkspaceContext: vi.fn().mockReturnValue({}),
getDebugMode: vi.fn().mockReturnValue(false),
getRuntimeContext: vi.fn().mockReturnValue(runtimeCtxMap),
setRuntimeContextEntry: vi

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.

[Suggestion] Mock omits the !value deletion branch that exists in production Config. When called with value === '', the mock falls through to runtimeCtxMap.set(key, '') (stores empty string), while production Config does entries.delete(key) (removes the entry).

Today this is harmless because the handler routes empty strings through removeRuntimeContextEntry. But a future refactor consolidating the handler's set/delete paths into a single setRuntimeContextEntry call would let mock-based tests pass while production behavior diverges.

Suggested change
setRuntimeContextEntry: vi
setRuntimeContextEntry: vi
.fn()
.mockImplementation((key: string, value: string) => {
if (!/^[a-zA-Z0-9_-]{1,64}$/.test(key)) return false;
if (!value) { runtimeCtxMap.delete(key); return true; }
if (Buffer.byteLength(value, 'utf8') > 32 * 1024) return false;
if (!runtimeCtxMap.has(key) && runtimeCtxMap.size >= 16) return false;
runtimeCtxMap.set(key, value);
return true;
}),

— qwen3.7-max via Qwen Code /review

@wenshao

wenshao commented Jul 7, 2026

Copy link
Copy Markdown
Collaborator

@qwen-code /triage

@qwen-code-ci-bot qwen-code-ci-bot 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.

Stepping back to reflect on the full picture.

The runtime context injection feature itself is well-designed and cleanly implemented. The approach — Config KV store, per-turn system-reminder injection with proper tag escaping, ACP ext-method, bridge, daemon route, SDK — follows existing patterns in the codebase. The 17 new unit tests are thorough and all pass. The capability declaration is properly registered. If this PR contained only the feature code, it would be straightforward to approve.

But the PR carries significant baggage that blocks merge:

1. Build failure. The SDK bundle size guard trips (140378 > 140288 bytes). This is a hard blocker — npm run build must pass. The fix is straightforward (bump the limit in scripts/build.js), but it needs to happen in this PR since the PR's own SDK additions caused the overflow.

2. Test coverage regressions. The 437 lines of test deletions include:

  • matchesServerPattern / matchesAnyServerPattern — still exported and used in 3 production files, now untested.
  • Team memory security tests — symlink-escape gate, untrusted-workspace isolation, sync gate proofs. These protect against real security scenarios.
  • buildContextUsage and modalities assertions — unrelated functionality.

Removing tests for code that's still in production is a coverage regression, not cleanup. If these tests are genuinely obsolete (e.g., the functions were refactored elsewhere), the PR body should explain why. As-is, it reads as drive-by cleanup bundled with a feature.

3. Scope. The .gitignore addition (pnpm-lock.yaml) and the modalities test change are small but clearly unrelated. They belong in separate PRs.

My recommendation: Split this into two PRs:

  • PR A: Runtime context feature only (config store, injection, handler, route, SDK, capability, tests). Bump the SDK bundle size limit.
  • PR B: Test cleanup (with justification for each deletion, especially the security tests and the still-active matchesServerPattern tests).

The feature code is ready — once the scope is tightened and the build passes, this should merge cleanly.

中文说明

退一步反思整体情况。

运行时上下文注入功能本身设计良好、实现干净。方案——Config KV 存储、按轮 system-reminder 注入(带正确的标签转义)、ACP ext-method、bridge、daemon 路由、SDK——遵循代码库现有模式。17 个新单元测试全面且全部通过。能力声明正确注册。如果这个 PR 只包含功能代码,审批会很直接。

但 PR 夹带了显著阻碍合并的包袱:

1. 构建失败。 SDK 包大小限制触发(140378 > 140288 字节)。这是硬阻塞——npm run build 必须通过。修复很简单(提高 scripts/build.js 中的限制),但需要在这个 PR 中完成,因为是 PR 自身的 SDK 新增代码导致了溢出。

2. 测试覆盖退化。 437 行测试删除包括:

  • matchesServerPattern / matchesAnyServerPattern — 仍在 3 个生产文件中导出和使用,现在没有测试。
  • Team memory 安全测试 — 符号链接逃逸门控、不可信工作区隔离、同步门控证明。这些防护真实的安全场景。
  • buildContextUsage 和 modalities 断言 — 不相关的功能。

删除仍在生产中使用的代码的测试是覆盖退化,不是清理。如果这些测试确实过时了(例如函数在其他地方被重构了),PR 正文应该解释原因。目前看来像是与功能捆绑的顺手清理。

3. 范围。 .gitignore 新增(pnpm-lock.yaml)和 modalities 测试变更虽小但明显不相关。应该放在单独的 PR 中。

我的建议: 拆成两个 PR:

  • PR A: 仅运行时上下文功能(config 存储、注入、处理器、路由、SDK、能力声明、测试)。提高 SDK 包大小限制。
  • PR B: 测试清理(为每个删除提供理由,尤其是安全测试和仍在使用中的 matchesServerPattern 测试)。

功能代码已就绪——一旦范围收紧、构建通过,应该可以顺利合并。

Qwen Code · qwen3.7-max

@wenshao

wenshao commented Jul 7, 2026

Copy link
Copy Markdown
Collaborator

@qwen-code /triage

@qwen-code-ci-bot qwen-code-ci-bot 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 findings at this HEAD. 9 parallel review agents + verification + reverse audit confirmed that all significant concerns are already covered by prior review comments. Build passes, all 17 new tests pass, typecheck and lint clean.

— qwen3.7-max via Qwen Code /review

@qwen-code-ci-bot qwen-code-ci-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Re-review with qwen3.7-max — 2 confirmed Critical findings (both already covered by prior review threads, inline comments skipped to avoid duplicates). 2 low-confidence Suggestions for human review.

Confirmed Critical (existing threads):

  1. config.test.ts test deletion — 24 unrelated tests deleted for unchanged production code (matchesServerPattern, MCP glob, team memory security gating, modalities). Covered by prior comments at lines 15, 18, 352, 6028.
  2. SDK setRuntimeContext naming mismatch — name implies replace but does merge. Covered by prior comments at line 452.

Needs Human Review (low confidence):

  • No error boundary around runtime context injection in client.ts:2316 — a crash in escapeSystemReminderTags would kill the entire turn rather than skipping entries gracefully.
  • Zero observability at injection point — no debug log when runtime context entries are injected, making 3 AM debugging harder.

Build passes, all 17 new tests pass, typecheck and lint clean. — qwen3.7-max via Qwen Code /review

@qwen-code-ci-bot

Copy link
Copy Markdown
Collaborator

Suggestions — commit a1c3b8e6b

File Issue Suggested fix
packages/core/src/core/client.ts:2316 No error boundary around runtime context injection — crash kills entire turn Wrap injection block in try/catch, log warning and skip entries on failure
packages/core/src/core/client.ts:2316 Zero observability at injection point — no debug log when entries are injected Add logger.debug('Injected %d runtime context entries', runtimeCtx.size)

Low-confidence findings — needs human review.

— qwen3.7-max via Qwen Code /review

@wenshao

wenshao commented Jul 11, 2026

Copy link
Copy Markdown
Collaborator

🧪 Local validation report (maintainer)

Built this PR from source and ran the reviewer test plan against a real qwen serve daemon, backed by a local request-capturing OpenAI server so the outbound model request could be inspected directly.

Verdict: the storage + API layer is solid, but the core feature — per-turn injection — does not work end-to-end. Test-plan step 4 ("the model should see <system-reminder> blocks") does not hold: runtime context set through the daemon API never reaches the model.

Environment

Node v22.23.1 · macOS (darwin 24.6) · npm run build && npm run bundle · daemon driven over HTTP with a fake OpenAI backend.

Results

# Check Result
1 Config store unit tests (config.test.ts -t RuntimeContext) ✅ 10/10
2 ACP handler unit tests (acpAgent.test.ts -t sessionRuntimeContext) ✅ 6/6
3 Client injection unit test (client.test.ts) ✅ 1/1
4 Capability envelope test (server.test.ts) ✅ 1/1
5 GET /capabilities advertises session_runtime_context ✅ live daemon
6 POST /session/:id/runtime-context happy path → {keys, rejected} ✅ live daemon
7 Validation: invalid_key, value_not_string, capacity_full, empty-string removal, update-at-capacity ✅ live daemon
8 Guards: 400 invalid_entries, 413 payload_too_large, 401 no-token ✅ live daemon
9 Per-turn injection reaches the model (test-plan step 4) does not inject

❌ Blocking issue: runtime context is stored but never injected in the daemon path

With runtime context {operator, rules} set on a live session, I fired a real prompt and captured the exact request the daemon sent to the model. The set keys appear 0 times — the system prompt, the skills reminder and the user prompt are all present, but no runtime-context <system-reminder> block is.

Root-caused with a per-instance config trace:

[RTC] setRuntimeContextEntry      pid=29584 cfg#153809 key=operator     ← route writes to config
[RTC] setRuntimeContextEntry      pid=29584 cfg#153809 key=rules
[RTC] getRuntimeContext           pid=29584 cfg#153809 size=2 keys=["operator","rules"]   ← turn's config HAS it
[RTC] GeminiChat.sendMessageStream ... config.runtimeContext.size=2  (GeminiChat does NOT inject)  ← daemon turn path
[RTC] GeminiClient.sendMessageStream — NEVER CALLED                    ← the ONLY path that injects

Root cause — the injection was added to the wrong sendMessageStream.

  • The injection loop lives in GeminiClient.sendMessageStreampackages/core/src/core/client.ts:2321.
  • But the daemon / ACP / SDK path — which is the only surface that can set runtime context (acpAgent.ts handler + POST /session/:id/runtime-context) — executes turns through GeminiChat.sendMessageStream, called from packages/cli/src/acp-integration/session/Session.ts:2528. That method contains no injection.
  • Meanwhile GeminiClient.sendMessageStream is only reached by the interactive TUI (useGeminiStream) and headless CLI (nonInteractiveCli) — neither of which has any way to set runtime context.

So the writer set and the injector set never intersect. The value is stored on the correct config instance (the trace above confirms cfg#153809 has size=2 at turn time), yet it is never serialized into the model request under any real usage. All the unit coverage passes because client.test.ts exercises GeminiClient.sendMessageStream in isolation — a path the daemon never takes.

Suggested direction

Inject the runtime-context reminders on the path the daemon actually runs — e.g. inside GeminiChat.sendMessageStream, or at the Session.ts prompt-assembly point before chat.sendMessageStream(...) — ideally via a helper shared with GeminiClient.sendMessageStream so the two paths can't drift again. An integration test that asserts the reminder is present in the outbound model request (real daemon + fake model) would lock this down; the current tests can't catch it because they never cross the daemon boundary.

How this was reproduced

A temporary integration test spun up a real qwen serve daemon with OPENAI_BASE_URL pointed at a local capturing server (the repo's own integration-tests/fake-openai-server.ts), set runtime context via DaemonClient.setSessionRuntimeContext, sent a prompt, then asserted on fakeServer.requests[].body.messages. All instrumentation has been reverted; nothing in this PR was modified.

Happy to share the throwaway repro test if useful. The storage/validation/API design itself looks clean and well-tested — it's purely the injection wiring that's misplaced.

🇨🇳 中文说明(点击展开)

🧪 本地验证报告(维护者)

我从源码构建了本 PR,并对着真实的 qwen serve daemon 执行了 reviewer 测试计划,模型侧接到一个本地的、可捕获请求的 OpenAI 假服务器上,从而能直接检查发往模型的出站请求。

结论:存储 + API 层是扎实的,但核心功能——按轮注入——端到端并不生效。 测试计划第 4 步("模型应看到 <system-reminder> 块")不成立:通过 daemon API 设置的 runtime context 从未到达模型。

环境

Node v22.23.1 · macOS · npm run build && npm run bundle · 通过 HTTP 驱动 daemon,模型侧为假 OpenAI 后端。

结果

# 检查项 结果
1 Config 存储单测(config.test.ts -t RuntimeContext ✅ 10/10
2 ACP handler 单测(acpAgent.test.ts -t sessionRuntimeContext ✅ 6/6
3 Client 注入单测(client.test.ts ✅ 1/1
4 能力声明单测(server.test.ts ✅ 1/1
5 GET /capabilities 声明 session_runtime_context ✅ 真实 daemon
6 POST /session/:id/runtime-context 正常路径 → {keys, rejected} ✅ 真实 daemon
7 校验:invalid_keyvalue_not_stringcapacity_full、空串删除、满容量下更新 ✅ 真实 daemon
8 防护:400 invalid_entries413 payload_too_large401 无 token ✅ 真实 daemon
9 按轮注入真正到达模型(测试计划第 4 步) 未注入

❌ 阻断性问题:runtime context 被存储了,但在 daemon 路径下从未被注入

在一个活跃会话上设置 {operator, rules} 后,我发送了一次真实 prompt,并捕获了 daemon 发往模型的确切请求。所设置的 key 出现次数为 0——system prompt、skills 提醒、用户 prompt 都在,但没有任何 runtime-context 的 <system-reminder> 块。

用逐实例的 config 追踪定位到根因:

[RTC] setRuntimeContextEntry      pid=29584 cfg#153809 key=operator     ← 路由写入 config
[RTC] setRuntimeContextEntry      pid=29584 cfg#153809 key=rules
[RTC] getRuntimeContext           pid=29584 cfg#153809 size=2 keys=["operator","rules"]   ← 该轮的 config 确实有值
[RTC] GeminiChat.sendMessageStream ... config.runtimeContext.size=2  (GeminiChat 不做注入)  ← daemon 的真正执行路径
[RTC] GeminiClient.sendMessageStream — 从未被调用                       ← 唯一做注入的路径

根因——注入被加到了错误的 sendMessageStream 上。

  • 注入循环位于 GeminiClient.sendMessageStream——packages/core/src/core/client.ts:2321
  • 但 daemon / ACP / SDK 路径——也就是唯一设置 runtime context 的入口(acpAgent.ts handler + POST /session/:id/runtime-context)——是通过 GeminiChat.sendMessageStream 执行每一轮的,调用点在 packages/cli/src/acp-integration/session/Session.ts:2528。该方法里没有任何注入逻辑。
  • GeminiClient.sendMessageStream 只会被交互式 TUI(useGeminiStream)和 headless CLI(nonInteractiveCli)走到——这两者都没有任何设置 runtime context 的途径。

因此写入方集合与注入方集合永不相交。值确实被存到了正确的 config 实例上(上面的追踪显示轮次执行时 cfg#153809size=2),但在任何真实使用下都不会被序列化进模型请求。所有单测都通过,是因为 client.test.ts 单独测的是 GeminiClient.sendMessageStream——而 daemon 从不走这条路径。

建议方向

把 runtime-context 提醒注入到 daemon 真正执行的路径上——例如放进 GeminiChat.sendMessageStream,或在 Session.ts 调用 chat.sendMessageStream(...) 之前的 prompt 组装处;最好抽成一个与 GeminiClient.sendMessageStream 共用的 helper,避免两条路径再次漂移。再补一个断言"提醒出现在出站模型请求里"的集成测试(真实 daemon + 假模型)来兜底;现有测试无法覆盖,因为它们从不跨越 daemon 边界。

复现方式

一个临时集成测试拉起真实 qwen serve daemon,把 OPENAI_BASE_URL 指向本地捕获服务器(仓库自带的 integration-tests/fake-openai-server.ts),通过 DaemonClient.setSessionRuntimeContext 设置 runtime context,发送 prompt,然后对 fakeServer.requests[].body.messages 做断言。所有插桩均已回退,未改动本 PR 的任何代码。

需要的话我可以把这个一次性复现测试贴出来。存储/校验/API 的设计本身很干净、测试也充分——问题纯粹在于注入的接线位置放错了。


🤖 Report generated by an automated local validation run (build + real-daemon E2E + outbound-request capture). Figures above are from actual captured output.

@qwen-code-ci-bot qwen-code-ci-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Re-review at this HEAD — no new findings. 10 parallel review agents + verification + reverse audit confirmed all significant concerns are already covered by prior review comments. Build passes, all 17 new tests pass (10 Config RuntimeContext, 6 acpAgent handler, 1 client injection), typecheck clean.

Open Criticals checked against current code:

Critical Status
config.test.ts — ~650 lines of unrelated tests deleted still stands
config.test.ts:6028 — modalities assertions removed still stands
DaemonClient.ts — SDK method bypasses acpRouteTable still stands
acpAgent.ts:7217 — batch processing order non-deterministic still stands
client.ts:2324 — runtime-context persisted in chat history still stands
acpAgent.test.ts:11298 — mcpServers not iterable fixed
DaemonClient.ts — SDK browser bundle size cannot tell

— qwen3.7-max via Qwen Code /review

@yiliang114 yiliang114 added this to the v1.0.0 milestone Jul 13, 2026

@wenshao wenshao left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Re-review with qwen3.7-max — no new findings. 12 parallel review agents + verification confirmed that all significant concerns are already covered by prior review comments.

Open Critical re-check at this HEAD:

  • Fixed: test crash (mcpServers is not iterable) — setupAgent() now passes mcpServers: [] (line 11306). Missing closing braces — file properly terminated with });.
  • Still stands: deleted test coverage (~650 lines for matchesServerPattern, MCP glob filtering, team memory sync gating), modalities assertions removed from model-switch test, batch processing order dependency on object key order, chat history persistence of runtime-context reminders.
  • Cannot tell: SDK route table mapping (requires runtime verification beyond static diff analysis), SDK browser bundle size (CI shows all 28 checks passing).

Build & tests: Build passes, all 6 sessionRuntimeContext handler tests pass. Config and client tests blocked by pre-existing @xterm/headless ESM interop issue (not introduced by this PR).

— qwen3.7-max via Qwen Code /review

@wenshao

wenshao commented Jul 14, 2026

Copy link
Copy Markdown
Collaborator

@callmeYe Thanks for your work on this — since the thread has been quiet for a couple of weeks, let me summarize where the review stands and what it would take to move forward.

The need itself is real and worth supporting. Sessions sharing one qwen serve instance should be able to carry their own context without touching the project-level QWEN.md. That part of the direction has consensus. Three things block the PR in its current shape, though:

1. The core design question is still unanswered

@tanzhenxin's question from Jun 26 remains open: is there a concrete case where the value must change mid-conversation, rather than be fixed when the session opens? Every use case named so far (operator identity, per-session rule overlays) is session-constant. For those, a settable append / session-creation context parameter covers everything at zero per-turn token cost — without the new keyed-store contract (capability tag, daemon route, ACP ext-method, SDK methods) that we'd have to maintain indefinitely.

Unless a solid mid-session-mutation scenario shows up, I'd like to right-size this to the set-once capability first and add the mutable per-turn channel when a concrete trigger appears. That also sidesteps the ToolResult-turn staleness contract I flagged earlier.

2. The blocking wiring bug from the Jul 11 validation report is still present

The current diff still injects only in GeminiClient.sendMessageStream (packages/core/src/core/client.ts), while the daemon/ACP/SDK path — the only surface that can set runtime context — executes turns through GeminiChat.sendMessageStream. The writer set and the injector set never intersect, so the feature does not work end-to-end in any real usage. If the per-turn design stays, the fix needs:

  • injection on the path the daemon actually runs, ideally via a helper shared with GeminiClient.sendMessageStream so the two paths can't drift again;
  • an integration test asserting the reminder appears in the outbound model request (real daemon + fake model backend) — the current unit tests cannot catch this class of bug because they never cross the daemon boundary.

3. The diff now deletes ~437 lines of unrelated tests from config.test.ts

I compared the deletions against current main: the removed tests (the matchesServerPattern glob suite, MCP allow/exclude filtering tests, the refreshHierarchicalMemory untrusted-workspace team-memory safety tests, and more) all still exist on main and have nothing to do with this feature. This looks like accumulated collateral from the repeated bot /resolve conflict resolutions on this long-lived branch. The PR currently shows as MERGEABLE, so merging as-is would silently drop that coverage — including trust-boundary safety tests. These need to be restored regardless of the design outcome.

Suggested path

Given the branch has been through 10+ conflict syncs and the diff has picked up resolution damage, my suggestion is to open a fresh, minimal PR against latest main with the set-once capability (session-creation context / settable append), reusing this PR's storage and validation work — which is genuinely solid and well-tested. If you do have a concrete mid-session mutation use case, please share it and we can design around that trigger specifically.

中文

@callmeYe 感谢你在这个 PR 上的投入——鉴于讨论已经沉寂了两周左右,我来总结一下评审的现状,以及推进下去需要满足的条件。

需求本身是真实且值得支持的。 共享同一个 qwen serve 实例的会话,应该能携带各自的上下文,而不必改动项目级的 QWEN.md。这一点方向上是有共识的。但目前形态下有三件事阻碍这个 PR 继续推进:

1. 核心设计问题仍未被回答

@tanzhenxin 6 月 26 日的问题仍然悬而未决:是否存在一个具体场景,要求这个值必须在会话进行中变更,而不是在会话开启时就固定下来? 目前列出的所有用例(操作人身份、按会话的规则叠加)都是会话级常量。对这类数据,一个可设置的 append / 会话创建时的 context 参数即可全部覆盖,且没有任何按轮 token 开销——也不需要引入一套我们必须长期维护的新键值存储契约(capability 标签、daemon 路由、ACP 扩展方法、SDK 方法)。

除非出现一个扎实的"会话中期必须变更"的场景,我倾向于先把它收缩为 set-once 能力,等具体触发点出现后再增加按轮可变通道。这也顺带绕开了我之前标记的 ToolResult 轮次上下文陈旧的契约问题。

2. 7 月 11 日验证报告指出的阻断性接线问题仍然存在

当前 diff 的注入仍然只在 GeminiClient.sendMessageStreampackages/core/src/core/client.ts),而 daemon / ACP / SDK 路径——唯一能设置 runtime context 的入口——是通过 GeminiChat.sendMessageStream 执行每一轮的。写入方集合与注入方集合永不相交,因此该功能在任何真实使用下都无法端到端生效。如果保留按轮注入的设计,修复需要:

  • 把注入放到 daemon 真正执行的路径上,最好抽成一个与 GeminiClient.sendMessageStream 共用的 helper,避免两条路径再次漂移;
  • 增加一个断言"提醒出现在出站模型请求里"的集成测试(真实 daemon + 假模型后端)——现有单测无法捕获这类问题,因为它们从不跨越 daemon 边界。

3. 当前 diff 会从 config.test.ts 误删约 437 行无关测试

我把删除内容与当前 main 做了对照:被删除的测试(matchesServerPattern glob 套件、MCP allow/exclude 过滤测试、refreshHierarchicalMemory 的非受信工作区 team-memory 安全测试等)在 main 上都仍然存在,且与本特性无关。这看起来是这个长期分支上多轮机器人 /resolve 解冲突累积的附带损伤。PR 当前状态为 MERGEABLE,按现状合并会静默删掉这些覆盖——其中包含信任边界的安全测试。无论设计走向如何,这些测试都必须恢复。

建议路径

考虑到该分支已经历 10+ 次冲突同步、diff 已带上解冲突损伤,我的建议是:基于最新 main 重开一个最小化的新 PR,实现 set-once 能力(会话创建时 context / 可设置的 append),并复用本 PR 中确实扎实、测试充分的存储与校验部分。如果你确实有一个具体的会话中期变更场景,欢迎提出来,我们可以针对那个触发点专门设计。

@callmeYe

Copy link
Copy Markdown
Collaborator Author

Closing this PR after re-evaluating both the use case and the current branch.

The underlying requirement is still valid: an embedding client may need to update conversation-scoped rules or contextual state while a session remains active. The latest accepted snapshot should take effect on the next safe user turn, remain isolated to that session, and leave persistent workspace instructions unchanged.

However, this branch should not be merged as-is:

  • The daemon/ACP setter path and the model injection path are not connected end to end, so a successful update does not currently reach the outbound model request.
  • The long-running branch accumulated unrelated test deletions and conflict-resolution damage.
  • The contract needs to be redesigned around session-scoped snapshot replacement, explicit update and removal semantics, session isolation, and a defined safe turn boundary instead of arbitrary KV entries injected on every turn.

Any follow-up should be a fresh, minimal PR based on current main, with an end-to-end daemon test that verifies the runtime context in the actual outbound model request. Tool and skill availability should remain outside this generic context contract because capability changes also require runtime enforcement.

Thanks everyone for the detailed reviews and feedback.

@callmeYe callmeYe closed this Jul 14, 2026
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.

7 participants