Skip to content

fix(cli): complete image routing across entry points - #7206

Merged
wenshao merged 38 commits into
mainfrom
cx/6988-routing-completion
Aug 1, 2026
Merged

fix(cli): complete image routing across entry points#7206
wenshao merged 38 commits into
mainfrom
cx/6988-routing-completion

Conversation

@yiliang114

@yiliang114 yiliang114 commented Jul 19, 2026

Copy link
Copy Markdown
Collaborator

What this PR does

Completes local image @ reference routing across all three entry points (TUI, ACP, and non-interactive CLI). Aliases and canonical targets are validated against workspace boundaries, ignore rules, MIME types, and file-identity checks before routing. Image turns then go through the full-turn agent or vision bridge, failing closed on unsupported or fallback paths.

Why it's needed

Issue #6988 identified that the non-interactive CLI and ACP paths did not route image turns through the same capability-aware logic as the TUI. This left @-referenced images silently dropped or mishandled outside the TUI, and skipped security validation (TOCTOU, symlink escape, MIME spoofing) on all paths.

Reviewer Test Plan

How to verify

  1. In a workspace with a local image file, run the non-interactive CLI with an @/absolute/path/to/image.png reference — confirm it produces a Read card and one outbound image payload (same as TUI behavior).
  2. Attempt @ references to symlinked files escaping the workspace, non-image MIME types, and gitignored paths — confirm all are rejected.
  3. Run npm run test --workspace=packages/core and npm run test --workspace=packages/cli — all pass.

Evidence (Before & After)

tmux UI verification: absolute @ image resolved to a Read card and one outbound image payload (full report in PR conversation). Deterministic visual routing verified with an isolated local provider and temporary QWEN_HOME.

Tested on

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

Environment (optional)

Unit + integration tests, tmux real-user session, isolated local provider with temporary QWEN_HOME.

Risk & Scope

  • Main risk or tradeoff: fail-closed on unsupported paths means previously-silent image drops now surface as explicit errors; this is intentional but may surprise scripts relying on the old silent behavior.
  • Not validated / out of scope: Windows and Linux local testing; remote/URL image routing (unchanged).
  • Breaking changes / migration notes: none — behavior only tightens validation; no API surface changes.

Linked Issues

References #6988

中文说明

本 PR 做了什么

在 TUI、ACP 和非交互式 CLI 三个入口统一完成本地图片 @ 引用的路由。对别名和规范化目标执行工作区边界、ignore 规则、MIME 类型和文件身份校验后再路由。图片轮次通过 full-turn agent 或 vision bridge 处理,不支持或 fallback 路径一律 fail closed。

为什么需要

Issue #6988 指出非交互式 CLI 和 ACP 路径没有像 TUI 一样走能力感知路由,导致 @ 引用的图片被静默丢弃或错误处理,且所有路径均缺少安全校验(TOCTOU、符号链接逃逸、MIME 伪造)。

审阅测试计划

如何验证

  1. 在含本地图片的工作区中,用非交互式 CLI 发送 @/absolute/path/to/image.png 引用——确认产生 Read 卡片和一个出站图片 payload(与 TUI 行为一致)。
  2. 尝试 @ 引用逃逸工作区的符号链接文件、非图片 MIME 类型、gitignore 路径——确认全部被拒绝。
  3. 运行核心和 CLI 测试套件——全部通过。

证据(前后对比)

tmux UI 验证:绝对路径 @ 图片解析为 Read 卡片和一个出站图片 payload(完整报告见 PR 对话)。使用隔离本地 provider 和临时 QWEN_HOME 验证确定性视觉路由。

测试环境

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

环境(可选)

单元 + 集成测试、tmux 真实用户会话、隔离本地 provider + 临时 QWEN_HOME

风险与范围

  • 主要风险/权衡:不支持路径 fail-closed 意味着之前静默丢弃图片的行为现在会显式报错;这是有意为之,但依赖旧静默行为的脚本可能受影响。
  • 未验证/不在范围内:Windows 和 Linux 本地测试;远程/URL 图片路由(未改动)。
  • 破坏性变更/迁移说明:无——行为仅收紧校验,无 API 表面变更。

关联 Issue

引用 #6988

@github-actions

github-actions Bot commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

Code Coverage Summary

Package Lines Statements Functions Branches
CLI 83.28% 83.28% 89.4% 82.58%
Core 87.52% 87.52% 89.11% 86.16%
CLI Package - Full Text Report
-------------------|---------|----------|---------|---------|-------------------
File               | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
-------------------|---------|----------|---------|---------|-------------------
All files          |   83.28 |    82.58 |    89.4 |   83.28 |                   
 src               |   84.33 |    81.45 |   88.29 |   84.33 |                   
  cli.ts           |   96.03 |    84.61 |     100 |   96.03 | ...37-538,548-549 
  gemini.tsx       |   72.21 |    76.81 |   80.76 |   72.21 | ...1253-1257,1378 
  ...ractiveCli.ts |   86.32 |    82.26 |    87.5 |   86.32 | ...2477,2483,2535 
  ...liCommands.ts |   88.34 |     83.6 |      90 |   88.34 | ...63,480,514,635 
  ...ActiveAuth.ts |     100 |     87.5 |     100 |     100 | 66-80             
 ...cp-integration |   69.97 |    72.73 |   89.81 |   69.97 |                   
  acpAgent.ts      |   69.64 |     72.6 |   89.84 |   69.64 | ...62,11367-11369 
  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             
  generation.ts    |    97.1 |    81.25 |     100 |    97.1 | 109,112           
  ...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 |   91.62 |    86.58 |    96.5 |   91.62 |                   
  Session.ts       |   91.21 |    85.47 |   96.03 |   91.21 | ...9238,9265-9269 
  ...entTracker.ts |   91.87 |    89.18 |   88.88 |   91.87 | ...33,197,280-289 
  ...stop-guard.ts |     100 |    98.07 |     100 |     100 | 37,127            
  ...eplay-page.ts |    93.1 |    90.72 |     100 |    93.1 | 71,82-85,111-121  
  ...y-replayer.ts |   98.53 |    95.52 |     100 |   98.53 | 238-240           
  index.ts         |       0 |        0 |       0 |       0 | 1-40              
  ...ssionUtils.ts |   89.76 |    86.76 |     100 |   89.76 | ...54-270,326-328 
  tasksSnapshot.ts |    94.3 |     87.5 |     100 |    94.3 | 65-71             
  ...on-tracker.ts |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...ssion/emitters |   95.68 |     93.7 |   96.66 |   95.68 |                   
  ...ageEmitter.ts |   95.34 |    94.11 |     100 |   95.34 | 52-59             
  PlanEmitter.ts   |     100 |    83.33 |     100 |     100 | 59                
  base-emitter.ts  |   78.26 |       75 |     100 |   78.26 | 23-24,26-28       
  index.ts         |       0 |        0 |       0 |       0 | 1-10              
  ...ll-emitter.ts |   99.17 |    97.43 |     100 |   99.17 | 352-353           
 ...ession/rewrite |    91.8 |    89.13 |   94.44 |    91.8 |                   
  LlmRewriter.ts   |    82.4 |     86.2 |     100 |    82.4 | ...,88-89,166-170 
  ...Middleware.ts |   96.96 |    88.09 |     100 |   96.96 | 144,152-154       
  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      |   89.15 |    73.75 |   64.51 |   89.15 |                   
  auth.ts          |     100 |    83.33 |     100 |     100 | 11,14             
  channel.ts       |   55.55 |      100 |       0 |   55.55 | 18-22,30-40       
  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        |   98.03 |      100 |      50 |   98.03 | 62                
  serve.ts         |    87.1 |    68.22 |     100 |    87.1 | ...46-649,663-667 
  sessions.ts      |     100 |      100 |      50 |     100 |                   
  update.ts        |   98.13 |    94.44 |   66.66 |   98.13 | 82-83             
 ...mmands/channel |   86.99 |    87.02 |   89.67 |   86.99 |                   
  channel-cwd.ts   |     100 |      100 |     100 |     100 |                   
  ...l-registry.ts |      80 |    84.61 |      80 |      80 | 37-40,49-52,63-66 
  ...entry-path.ts |      75 |       50 |     100 |      75 | 8-9               
  config-utils.ts  |   95.87 |    96.35 |     100 |   95.87 | ...08-213,271-274 
  configure.ts     |    14.7 |      100 |       0 |    14.7 | 18-21,23-84       
  daemon-worker.ts |   93.89 |    85.33 |   94.11 |   93.89 | ...1209,1216-1217 
  loop-runtime.ts  |   91.66 |      100 |      50 |   91.66 | 15,22             
  ...classifier.ts |   98.49 |    96.51 |     100 |   98.49 | 115-116,161       
  ...tact-store.ts |   93.51 |    87.65 |     100 |   93.51 | ...71,288-289,337 
  pairing.ts       |   72.85 |      100 |      50 |   72.85 | 22-28,57-68       
  pidfile.ts       |   95.55 |       90 |     100 |   95.55 | ...50-251,315-316 
  proxy.ts         |     100 |      100 |     100 |     100 |                   
  reload.ts        |    77.5 |    86.95 |      75 |    77.5 | 72-84,93-97       
  runtime.ts       |   82.43 |    86.44 |     100 |   82.43 | ...87-191,251-253 
  set.ts           |   75.72 |    85.71 |      50 |   75.72 | 65-83,111-116     
  start.ts         |   75.05 |    73.17 |   76.92 |   75.05 | ...31,537-540,552 
  ...ure-format.ts |   93.65 |    82.45 |     100 |   93.65 | ...42,48-49,74-75 
  status.ts        |   78.57 |    59.25 |   66.66 |   78.57 | ...36-137,150-161 
  stop.ts          |   57.83 |    82.35 |      50 |   57.83 | ...3,74-76,85-111 
 ...nds/extensions |   88.82 |    87.64 |   87.09 |   88.82 |                   
  consent.ts       |   72.53 |       90 |   42.85 |   72.53 | ...86-142,157-163 
  disable.ts       |     100 |       90 |     100 |     100 | 30                
  enable.ts        |     100 |    91.66 |     100 |     100 | 38                
  install.ts       |   82.95 |    81.57 |      75 |   82.95 | ...96-199,202-211 
  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     |   74.57 |       40 |   66.66 |   74.57 | 45-47,60-67,70-73 
  update.ts        |   96.71 |    97.05 |     100 |   96.71 | 114-118           
  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.17 |    84.39 |   83.33 |   90.17 |                   
  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.85 |    66.66 |   85.71 |   78.85 | 42-55,169-191     
  remove.ts        |     100 |       80 |     100 |     100 | 21-25             
 ...ommands/review |    85.1 |    86.35 |   85.85 |    85.1 |                   
  agent-prompt.ts  |   90.88 |    92.78 |      96 |   90.88 | ...1268,1738-1807 
  capture-local.ts |   68.57 |     90.9 |      75 |   68.57 | 107-111,158-189   
  ...k-coverage.ts |   48.38 |    14.28 |   66.66 |   48.38 | ...21-226,239-249 
  cleanup.ts       |   90.25 |    83.14 |   83.33 |   90.25 | ...77-482,484-485 
  ...ent-status.ts |   93.03 |    83.87 |   83.33 |   93.03 | 291,531-551       
  ...ose-review.ts |   95.85 |    91.25 |   93.75 |   95.85 | ...1439,1467-1489 
  fetch-pr.ts      |   74.02 |    53.57 |      50 |   74.02 | ...98,332,402-407 
  load-rules.ts    |   26.41 |      100 |   16.66 |   26.41 | ...41-153,155-156 
  parse-args.ts    |   99.27 |       96 |     100 |   99.27 | 345,417           
  plan-diff.ts     |   64.04 |      100 |   66.66 |   64.04 | 127-163           
  pr-context.ts    |   84.44 |    79.38 |   91.66 |   84.44 | ...29-910,939-941 
  presubmit.ts     |   83.75 |    92.72 |   88.88 |   83.75 | ...77-578,655-685 
  ...ve-anchors.ts |   77.02 |    88.46 |      75 |   77.02 | ...70-175,187-204 
  run.ts           |   81.14 |    86.17 |    90.9 |   81.14 | ...13,429-477,490 
  script-lint.ts   |   83.67 |    78.41 |   88.88 |   83.67 | ...59-773,775-797 
  submit.ts        |   76.74 |    82.05 |   81.81 |   76.74 | ...03-639,641-642 
  test-efficacy.ts |   87.11 |    83.43 |   93.33 |   87.11 | ...1394,1402-1422 
 ...nds/review/lib |   95.77 |    93.13 |   95.74 |   95.77 |                   
  agent-briefs.ts  |   98.68 |      100 |       0 |   98.68 | 520-521           
  anchors.ts       |     100 |    94.79 |     100 |     100 | ...33,169,178,225 
  coverage.ts      |   95.47 |    94.25 |   95.45 |   95.47 | ...98,335,433-450 
  diff-flags.ts    |     100 |        0 |     100 |     100 | 63                
  diff-plan.ts     |   98.73 |    93.01 |     100 |   98.73 | ...41,264,290-291 
  effort.ts        |     100 |      100 |     100 |     100 |                   
  gh.ts            |    85.6 |    88.37 |   71.42 |    85.6 | ...20,257-258,285 
  git.ts           |   97.64 |    95.65 |     100 |   97.64 | 180-181           
  heavy.ts         |     100 |      100 |     100 |     100 |                   
  inline-counts.ts |     100 |      100 |     100 |     100 |                   
  local-diff.ts    |    84.4 |    88.46 |     100 |    84.4 | ...63-473,475-483 
  merge-base.ts    |     100 |      100 |     100 |     100 |                   
  path-rules.ts    |     100 |      100 |     100 |     100 |                   
  paths.ts         |     100 |    85.71 |     100 |     100 | 70                
  prompt-record.ts |   94.73 |    88.23 |     100 |   94.73 | ...28,151-152,156 
  receipt.ts       |     100 |      100 |     100 |     100 |                   
  report.ts        |   94.38 |    93.75 |     100 |   94.38 | 173-177           
  roster.ts        |     100 |    94.23 |     100 |     100 | 143,161,206       
  shell-quote.ts   |     100 |      100 |     100 |     100 |                   
  test-utils.ts    |     100 |      100 |     100 |     100 |                   
  transcripts.ts   |   96.27 |    93.18 |     100 |   96.27 | ...83,269-270,294 
  workspaces.ts    |   97.76 |     91.2 |     100 |   97.76 | 186-187,212-213   
 ...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.36 |    88.89 |   95.94 |   94.36 |                   
  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 
  compile-cache.ts |     100 |      100 |     100 |     100 |                   
  config.ts        |   89.06 |    88.57 |   85.71 |   89.06 | ...2420,2422-2430 
  ...cy-monitor.ts |   88.75 |    76.19 |     100 |   88.75 | ...3,90-92,98,101 
  ...ust-policy.ts |   83.04 |    88.28 |     100 |   83.04 | ...39,253,352-353 
  ...heme-names.ts |     100 |      100 |     100 |     100 |                   
  environment.ts   |   94.33 |    89.61 |   94.73 |   94.33 | ...35-639,655-656 
  ...le-watcher.ts |   90.86 |    83.65 |   95.83 |   90.86 | ...23-325,370,418 
  ...resh-state.ts |   90.57 |    97.29 |   93.75 |   90.57 | 137-142,146-152   
  ...ime-reload.ts |     100 |    69.69 |     100 |     100 | ...12-113,122-123 
  hot-reload.ts    |     100 |    89.13 |     100 |     100 | 47,172-178,238    
  keyBindings.ts   |   97.41 |       50 |     100 |   97.41 | 239-242           
  ...ngsAdapter.ts |     100 |    94.11 |     100 |     100 | 64                
  ...ig-watcher.ts |   95.17 |    83.05 |     100 |   95.17 | ...78,200,292-293 
  ...er-secrets.ts |   98.97 |    96.96 |     100 |   98.97 | 85                
  mcpApprovals.ts  |   96.55 |    95.55 |     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 |      95 |    94.73 |     100 |      95 | 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 |   98.26 |    97.14 |     100 |   98.26 | 201-202           
  settings.ts      |   90.99 |     92.3 |      90 |   90.99 | ...1006,1008-1009 
  ...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 |                   
  ...l-settings.ts |     100 |      100 |     100 |     100 |                   
  ...paths-lite.ts |   89.47 |       88 |     100 |   89.47 | 43-44,53-54,56-57 
  ...tedFolders.ts |   93.35 |    94.11 |     100 |   93.35 | ...90-391,427-438 
 ...nfig/migration |   95.23 |    77.77 |   83.33 |   95.23 |                   
  index.ts         |   95.65 |     87.5 |     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    |    71.8 |    70.31 |   66.66 |    71.8 |                   
  ...tputBridge.ts |   71.95 |    70.96 |   68.42 |   71.95 | ...08-409,417-420 
  ...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/hooks         |     100 |      100 |     100 |     100 |                   
  ...elete-hook.ts |     100 |      100 |     100 |     100 |                   
 src/i18n          |   85.98 |    81.92 |   89.65 |   85.98 |                   
  index.ts         |   73.45 |    77.77 |      90 |   73.45 | ...70-271,294-299 
  languages.ts     |   93.07 |     92.3 |   85.71 |   93.07 | ...35,164-169,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 |      80 |    76.31 |   81.35 |      80 |                   
  session.ts       |   84.08 |    75.27 |   93.61 |   84.08 | ...1007,1016-1026 
  types.ts         |    42.5 |      100 |   33.33 |    42.5 | ...24-625,628-629 
 ...active/control |   76.11 |    89.09 |      80 |   76.11 |                   
  ...rolContext.ts |    6.45 |        0 |       0 |    6.45 | 56-95             
  ...Dispatcher.ts |   91.79 |    92.45 |   88.88 |   91.79 | ...49-367,387,390 
  ...rolService.ts |     7.4 |        0 |       0 |     7.4 | 46-185            
 ...ol/controllers |   39.78 |    63.24 |   47.22 |   39.78 |                   
  ...Controller.ts |   39.49 |      100 |      80 |   39.49 | 88-92,127-210     
  ...Controller.ts |       0 |        0 |       0 |       0 | 1-56              
  ...Controller.ts |   49.11 |    62.96 |   54.54 |   49.11 | ...63-568,570-575 
  ...Controller.ts |   14.06 |      100 |       0 |   14.06 | ...82-117,130-133 
  ...Controller.ts |   37.92 |    60.71 |   46.66 |   37.92 | ...41-653,662-691 
 .../control/types |       0 |        0 |       0 |       0 |                   
  serviceAPIs.ts   |       0 |        0 |       0 |       0 | 1                 
 ...Interactive/io |   98.07 |    94.05 |   95.23 |   98.07 |                   
  ...putAdapter.ts |   97.98 |     93.2 |   98.07 |   97.98 | ...1415,1431-1432 
  ...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 | 84-85,125-126     
  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         |   87.31 |    83.57 |   91.09 |   87.31 |                   
  ...tp-enabled.ts |     100 |      100 |     100 |     100 |                   
  ...ion-bridge.ts |     100 |      100 |     100 |     100 |                   
  auth.ts          |    93.4 |    92.95 |     100 |    93.4 | ...19-320,323-325 
  ...em-adapter.ts |     100 |      100 |     100 |     100 |                   
  capabilities.ts  |     100 |    97.95 |     100 |     100 | 649               
  ...cp-command.ts |     100 |      100 |     100 |     100 |                   
  ...horization.ts |   92.79 |    93.33 |    87.5 |   92.79 | 75-80,135-136     
  ...livery-ipc.ts |     100 |     90.9 |     100 |     100 | 94,106,134        
  ...l-delivery.ts |     100 |      100 |     100 |     100 |                   
  ...op-mcp-ipc.ts |   81.06 |    73.68 |   94.11 |   81.06 | ...37-242,267,289 
  ...nt-service.ts |   93.89 |    86.61 |     100 |   93.89 | ...66-468,475,477 
  ...-selection.ts |     100 |      100 |     100 |     100 |                   
  ...ings-store.ts |   85.85 |    91.78 |   95.83 |   85.85 | ...94-206,366-369 
  ...ebhook-ipc.ts |    98.5 |    86.66 |     100 |    98.5 | 47                
  ...iagnostics.ts |     100 |      100 |     100 |     100 |                   
  ...worker-env.ts |     100 |      100 |     100 |     100 |                   
  ...rker-group.ts |   87.27 |     85.2 |     100 |   87.27 | ...10,816-820,838 
  ...er-manager.ts |   89.39 |    83.88 |   93.33 |   89.39 | ...98,711,722-724 
  ...tartup-ipc.ts |   97.72 |    96.66 |     100 |   97.72 | 88-89             
  ...supervisor.ts |   92.41 |    84.44 |    97.1 |   92.41 | ...1460,1514-1518 
  ...e-grouping.ts |     100 |    94.11 |     100 |     100 | 69,132            
  core-runtime.ts  |     100 |      100 |     100 |     100 |                   
  ...ub-session.ts |   92.04 |    77.77 |     100 |   92.04 | ...36-445,470,508 
  daemon-logger.ts |    82.2 |    77.26 |   91.76 |    82.2 | ...1720,1747-1753 
  ...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.37 |    90.06 |     100 |   98.37 | ...1041,1043-1044 
  debug-mode.ts    |     100 |      100 |     100 |     100 |                   
  demo.ts          |     100 |      100 |     100 |     100 |                   
  env-snapshot.ts  |   93.37 |    85.18 |     100 |   93.37 | 114-117,195-202   
  ...-scheduler.ts |   87.34 |    83.87 |     100 |   87.34 | 33-36,48-50,79-81 
  ...-path-argv.ts |     100 |      100 |     100 |     100 |                   
  ...h-settings.ts |   94.41 |    88.75 |     100 |   94.41 | ...24,702,718,728 
  fast-path.ts     |   90.49 |     80.7 |   95.45 |   90.49 | ...92-501,567-568 
  ...ration-sse.ts |   42.55 |    33.33 |     100 |   42.55 | 23-24,30,33-56    
  health-query.ts  |     100 |      100 |     100 |     100 |                   
  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                
  ...-workspace.ts |    90.9 |    85.71 |     100 |    90.9 | ...27-128,139-140 
  ...iders-edit.ts |     100 |    82.14 |     100 |     100 | 58-60,65,81       
  ...ory-picker.ts |     100 |    86.95 |     100 |     100 | 36,66,92          
  ...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 |   82.69 |    79.33 |   74.06 |   82.69 | ...6744,6749-6750 
  ...tup-errors.ts |     100 |      100 |     100 |     100 |                   
  ...-keepalive.ts |   94.19 |    88.57 |     100 |   94.19 | ...26,530-531,571 
  ...-lifecycle.ts |     100 |      100 |     100 |     100 |                   
  server.ts        |   93.57 |    93.29 |   74.02 |   93.57 | ...2148,2169-2173 
  ...on-helpers.ts |     100 |      100 |     100 |     100 |                   
  ...t-event-id.ts |     100 |    95.23 |     100 |     100 | 12                
  ...-admission.ts |   98.71 |    89.65 |     100 |   98.71 | 68                
  types.ts         |     100 |      100 |     100 |     100 |                   
  ...erver-name.ts |     100 |      100 |     100 |     100 |                   
  ...ion-limits.ts |     100 |      100 |     100 |     100 |                   
  ...t-sessions.ts |    93.3 |    76.57 |     100 |    93.3 | ...13,816,829-831 
  ...l-resolver.ts |   90.32 |    66.66 |     100 |   90.32 | 16,45-46          
  ...ell-static.ts |   91.07 |    86.66 |     100 |   91.07 | ...79-182,216-219 
  ...ace-agents.ts |   66.13 |    70.57 |   92.68 |   66.13 | ...2246,2256-2266 
  ...generation.ts |    95.4 |    82.35 |   66.66 |    95.4 | 55-56,78,92       
  ...-git-state.ts |     100 |    91.93 |    90.9 |     100 | 161,172,202,265   
  ...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 |      83 |    74.54 |     100 |      83 | ...30-537,597-604 
  ...ers-status.ts |   98.58 |       79 |     100 |   98.58 | 106,134,174,177   
  ...tion-store.ts |   89.67 |    88.27 |   92.59 |   89.67 | ...91-400,411-414 
  ...e-registry.ts |   93.89 |     87.5 |     100 |   93.89 | ...18-519,525-526 
  ...ber-errors.ts |     100 |    95.32 |     100 |     100 | 53,93-94,172,192  
  ...e-remember.ts |   98.23 |    92.51 |     100 |   98.23 | ...36,340-345,386 
  ...te-runtime.ts |   83.98 |    90.29 |     100 |   83.98 | ...48-156,216-237 
  ...me-storage.ts |     100 |      100 |     100 |     100 |                   
  ...management.ts |   72.63 |    72.72 |      96 |   72.63 | ...88-889,896-900 
  ...ls-mapping.ts |     100 |      100 |     100 |     100 |                   
  ...lls-status.ts |     100 |    92.85 |     100 |     100 | 127               
  ...reconciler.ts |    91.6 |     83.9 |     100 |    91.6 | ...70-272,305-306 
 ...serve/acp-http |   77.04 |    78.33 |   93.26 |   77.04 |                   
  ...r-registry.ts |   96.92 |    94.87 |     100 |   96.92 | 184-187           
  client-mcp-ws.ts |   54.85 |    58.62 |   72.72 |   54.85 | ...99-300,304-305 
  ...n-registry.ts |    98.2 |    88.62 |     100 |    98.2 | 1015,1041-1052    
  dispatch.ts      |   71.44 |    73.89 |   95.34 |   71.44 | ...4733,4781-4787 
  index.ts         |   81.93 |    79.92 |    90.9 |   81.93 | ...2291,2375-2376 
  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.7 |   93.87 |   86.86 |                   
  device-flow.ts   |   96.35 |    80.57 |   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      |    86.4 |    80.69 |     100 |    86.4 |                   
  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.8 |     100 |   77.64 | ...65,594-598,611 
  policy.ts        |   90.42 |    89.18 |     100 |   90.42 | 161-169           
  text-cursor.ts   |   88.23 |       90 |     100 |   88.23 | 74-77,92-95       
  ...ile-system.ts |   86.17 |    79.47 |     100 |   86.17 | ...2506,2516-2517 
 src/serve/routes  |   85.55 |    79.54 |   95.47 |   85.55 |                   
  a2ui-action.ts   |   96.84 |     88.5 |    87.5 |   96.84 | ...70-272,309-311 
  capabilities.ts  |     100 |      100 |     100 |     100 |                   
  ...nel-notify.ts |   85.22 |       88 |     100 |   85.22 | ...,83-87,103-104 
  ...l-webhooks.ts |   93.56 |    84.09 |     100 |   93.56 | ...42,292,332,334 
  daemon-status.ts |   85.45 |    83.33 |     100 |   85.45 | 98-105            
  goals.ts         |   98.92 |     90.9 |     100 |   98.92 | 146               
  health-demo.ts   |   94.73 |     86.2 |     100 |   94.73 | 62-66,154         
  permission.ts    |     100 |     92.3 |     100 |     100 | 50,98             
  ...uled-tasks.ts |   87.12 |    82.73 |   92.59 |   87.12 | ...1263,1306-1307 
  ...on-runtime.ts |     100 |    90.47 |     100 |     100 | 58,94             
  session.ts       |   85.21 |    81.78 |   95.16 |   85.21 | ...4608,4610-4611 
  sse-events.ts    |   84.45 |     87.5 |   77.77 |   84.45 | ...36,453-456,485 
  usage-stats.ts   |     100 |    95.45 |     100 |     100 | 118               
  ...space-auth.ts |   85.55 |    75.64 |     100 |   85.55 | ...21-326,331,345 
  ...el-control.ts |   86.26 |    78.94 |     100 |   86.26 | ...17-318,339-347 
  ...management.ts |   90.19 |    77.68 |     100 |   90.19 | ...47-448,467-468 
  ...d-contacts.ts |     100 |      100 |     100 |     100 |                   
  ...controller.ts |   83.09 |       79 |      90 |   83.09 | ...1032,1038,1041 
  ...extensions.ts |   87.23 |    72.76 |   94.11 |   87.23 | ...1826,1871-1872 
  ...-file-read.ts |      91 |    80.91 |     100 |      91 | ...20-621,624-625 
  ...file-write.ts |   84.44 |    64.51 |     100 |   84.44 | ...73-275,355-357 
  ...t-branches.ts |   75.43 |    66.66 |     100 |   75.43 | ...13-618,627-634 
  ...e-git-diff.ts |   97.32 |    90.56 |     100 |   97.32 | 161-162,189-191   
  ...ce-git-log.ts |     100 |    93.18 |     100 |     100 | 52,77,188         
  workspace-git.ts |   77.08 |    89.65 |     100 |   77.08 | 97-118            
  ...github-prs.ts |   88.26 |    63.46 |     100 |   88.26 | ...38-239,264-265 
  ...-lifecycle.ts |   95.23 |    75.75 |     100 |   95.23 | ...50-151,186-187 
  ...management.ts |   88.22 |    85.29 |     100 |   88.22 | ...1546,1566-1571 
  ...cp-control.ts |    73.2 |    67.54 |   85.71 |    73.2 | ...27-633,644-645 
  ...ace-models.ts |   95.53 |    89.74 |     100 |   95.53 | ...52-157,296-297 
  ...ermissions.ts |    77.9 |    72.41 |     100 |    77.9 | ...69-277,298-316 
  ...e-settings.ts |   74.81 |    70.31 |     100 |   74.81 | ...47-658,664-665 
  ...tup-github.ts |   77.97 |    70.58 |   84.21 |   77.97 | ...46-352,397-398 
  ...ace-skills.ts |   69.87 |    78.12 |     100 |   69.87 | ...59-284,290-324 
  ...ace-status.ts |   82.94 |     74.5 |     100 |   82.94 | ...84-486,490-491 
  ...pace-tools.ts |   75.94 |    69.69 |   66.66 |   75.94 | ...59-164,193-194 
  ...pace-trust.ts |   78.42 |    64.78 |      80 |   78.42 | ...31-336,344-345 
  ...pace-voice.ts |   91.33 |    80.92 |     100 |   91.33 | ...70-673,676-678 
 src/serve/server  |   90.69 |    89.18 |   96.55 |   90.69 |                   
  access-log.ts    |   98.68 |     97.1 |     100 |   98.68 | 115,186           
  ...er-helpers.ts |   63.82 |    77.96 |   81.81 |   63.82 | ...16,330,332-347 
  ...w-registry.ts |    98.8 |    81.81 |     100 |    98.8 | 107               
  ...r-handlers.ts |   97.29 |       75 |     100 |   97.29 | 17                
  ...r-response.ts |   85.66 |    76.83 |     100 |   85.66 | ...02,719,782-791 
  fs-factory.ts    |     100 |    92.59 |     100 |     100 | 34,42,103,159     
  ...branch-ops.ts |     100 |      100 |     100 |     100 |                   
  ...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 |   95.11 |    95.19 |     100 |   95.11 | ...65-167,422-427 
  self-origin.ts   |   76.19 |       80 |     100 |   76.19 | 45-54             
  ...e-features.ts |   94.81 |    90.32 |     100 |   94.81 | 175-181           
  ...on-archive.ts |   89.55 |    87.78 |   97.14 |   89.55 | ...32-836,888-889 
  ...ion-export.ts |     100 |    94.44 |     100 |     100 | 64                
  session-list.ts  |   93.55 |    91.01 |     100 |   93.55 | ...79,681-687,827 
  telemetry.ts     |   99.01 |    97.45 |     100 |   99.01 | ...19,633,775-777 
 src/serve/voice   |   83.35 |    92.22 |   90.47 |   83.35 |                   
  ...ice-config.ts |   84.61 |       30 |     100 |   84.61 | 90-99,103-104     
  voice-ws.ts      |   77.16 |    94.73 |   83.33 |   77.16 | ...68,483,521-523 
  ...oordinator.ts |     100 |    98.21 |     100 |     100 | 176               
 ...kspace-service |   89.11 |    86.15 |   90.69 |   89.11 |                   
  index.ts         |   88.66 |    85.77 |   89.47 |   88.66 | ...1286-1290,1293 
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/services      |   92.23 |    88.48 |   97.82 |   92.23 |                   
  ...mandLoader.ts |     100 |    88.88 |     100 |     100 | 104-117           
  ...killLoader.ts |   97.14 |    87.87 |     100 |   97.14 | 140,151-152       
  ...andService.ts |   98.73 |      100 |     100 |   98.73 | 107               
  ...mandLoader.ts |   86.83 |    83.87 |     100 |   86.83 | ...30-335,340-345 
  ...omptLoader.ts |   79.55 |    88.29 |   83.33 |   79.55 | ...48,178,245-246 
  ...mandLoader.ts |   97.36 |    92.68 |     100 |   97.36 | 153,160-161       
  ...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 |                   
  prompt-stash.ts  |   96.66 |    92.85 |     100 |   96.66 | 34-35             
  ...tree-lease.ts |   88.29 |    86.48 |     100 |   88.29 | ...91-196,229-230 
  ...low-loader.ts |     100 |    96.15 |     100 |     100 | 88                
  setup-github.ts  |    90.8 |    80.95 |     100 |    90.8 | ...49-450,457-458 
  ...-args-file.ts |   93.54 |    90.47 |    87.5 |   93.54 | 201-203,217-223   
  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 |   90.37 |    87.87 |     100 |   90.37 | ...80,287,352-357 
  ...e-settings.ts |     100 |    95.23 |     100 |     100 | 19                
  ...ranscriber.ts |   90.46 |    82.19 |      96 |   90.46 | ...66-668,671-673 
 ...rvices/insight |     100 |      100 |     100 |     100 |                   
  dates.ts         |     100 |      100 |     100 |     100 |                   
 ...ght/generators |   88.91 |    86.29 |   96.15 |   88.91 |                   
  DataProcessor.ts |   88.28 |    86.24 |   94.73 |   88.28 | ...1352,1356-1363 
  ...tGenerator.ts |   98.24 |    85.71 |     100 |   98.24 | 47                
  ...teRenderer.ts |     100 |      100 |     100 |     100 |                   
 .../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.99 |    83.47 |    90.9 |   88.99 |                   
  ...p-prefetch.ts |   98.09 |    94.23 |    87.5 |   98.09 | 50,209,225-226    
  ...reeStartup.ts |   80.53 |     74.6 |     100 |   80.53 | ...94,403,409-412 
 src/test-utils    |   93.26 |       75 |   83.33 |   93.26 |                   
  ci-env.ts        |      88 |     62.5 |     100 |      88 | 22-23,28          
  ...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            |   72.22 |    75.68 |   64.63 |   72.22 |                   
  App.tsx          |   33.33 |       75 |   33.33 |   33.33 | 32-86             
  AppContainer.tsx |   73.35 |    72.71 |   67.85 |   73.35 | ...4133,4175-4185 
  ...tionNudge.tsx |    9.58 |      100 |       0 |    9.58 | 24-94             
  ...ackDialog.tsx |    30.3 |      100 |       0 |    30.3 | 26-76             
  ...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 |   68.12 |    64.86 |   33.33 |   68.12 | ...98,321,341-346 
  ...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.53 |    66.18 |   51.06 |   58.53 |                   
  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.21 |    70.73 |   57.69 |   60.21 | ...90,794,803,806 
  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   |   81.41 |    82.99 |    89.4 |   81.41 |                   
  aboutCommand.ts  |     100 |      100 |     100 |     100 |                   
  agentsCommand.ts |   83.78 |      100 |      60 |   83.78 | 30-32,42-44       
  ...odeCommand.ts |    93.1 |    95.23 |     100 |    93.1 | 77-82             
  arenaCommand.ts  |   63.89 |    65.71 |   65.21 |   63.89 | ...01-606,691-699 
  authCommand.ts   |     100 |      100 |     100 |     100 |                   
  branchCommand.ts |     100 |      100 |     100 |     100 |                   
  btwCommand.ts    |   94.32 |    81.25 |     100 |   94.32 | 35-36,114-119     
  bugCommand.ts    |     100 |    77.77 |     100 |     100 | 27,61             
  cdCommand.ts     |    92.3 |    82.75 |     100 |    92.3 | ...,94-99,178,187 
  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 |   84.17 |       75 |     100 |   84.17 | ...,91-97,125-130 
  ...ig-command.ts |   93.12 |    88.42 |     100 |   93.12 | ...07-315,321-323 
  ...extCommand.ts |   68.28 |    70.14 |   84.61 |   68.28 | ...66-599,610-611 
  copyCommand.ts   |    98.7 |    96.29 |     100 |    98.7 | 66-67,172,272,323 
  deleteCommand.ts |     100 |      100 |     100 |     100 |                   
  diffCommand.ts   |     100 |    87.87 |     100 |     100 | ...63,231-232,245 
  ...ryCommand.tsx |   81.64 |    87.67 |    90.9 |   81.64 | ...73-278,325-332 
  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 |   52.31 |    56.25 |   69.23 |   52.31 | ...09,277-329,390 
  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 | ...81-184,196-199 
  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   |   91.86 |       80 |     100 |   91.86 | 48,83-88          
  ...ghtCommand.ts |   77.87 |    71.42 |     100 |   77.87 | ...44-245,250-272 
  ...ageCommand.ts |   93.45 |    89.06 |     100 |   93.45 | ...68-169,196-206 
  learn-command.ts |     100 |      100 |     100 |     100 |                   
  lspCommand.ts    |     100 |    86.95 |     100 |     100 | 31,101-102        
  mcpCommand.ts    |     100 |      100 |     100 |     100 |                   
  memoryCommand.ts |     100 |      100 |     100 |     100 |                   
  modelCommand.ts  |   86.27 |    83.01 |     100 |   86.27 | ...22-935,969-974 
  ...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 |   89.06 |    88.37 |     100 |   89.06 | ...72-176,202-209 
  ...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.65 |    76.73 |     100 |   90.65 | ...30-733,825-832 
  ...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 |    94.11 |     100 |     100 | 74,148            
  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 |   71.13 |    78.52 |   78.67 |   71.13 |                   
  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 |   88.65 |    90.41 |     100 |   88.65 | ...84-286,300-302 
  Composer.tsx     |   94.49 |    66.66 |     100 |   94.49 | ...-72,84,139,153 
  ...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 | 19                
  ...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-597             
  DiffDialog.tsx   |    53.5 |     37.5 |   69.23 |    53.5 | ...32-737,747-760 
  ...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       |   75.11 |     61.4 |      50 |   75.11 | ...48-253,271-275 
  ...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.33 |       90 |     100 |   98.33 | ...25,382,448-449 
  ...emDisplay.tsx |   78.51 |     65.3 |     100 |   78.51 | ...99,502,505-511 
  ...ngeDialog.tsx |     100 |      100 |     100 |     100 |                   
  InputPrompt.tsx  |   83.08 |    81.73 |      80 |   83.08 | ...2197,2223,2297 
  ...Shortcuts.tsx |     100 |       88 |     100 |     100 | 98,119            
  ...Indicator.tsx |   98.18 |    97.82 |     100 |   98.18 | 161-162           
  ...firmation.tsx |   91.42 |      100 |      50 |   91.42 | 26-31             
  MainContent.tsx  |   95.82 |    92.53 |      50 |   95.82 | ...97,440-444,447 
  MemoryDialog.tsx |   86.59 |    80.15 |     100 |   86.59 | ...34-435,485,553 
  ...geDisplay.tsx |       0 |        0 |       0 |       0 | 1-41              
  ModelDialog.tsx  |   83.41 |    71.65 |     100 |   83.41 | ...69,971,976-992 
  ...tsDisplay.tsx |     100 |    97.22 |     100 |     100 | 270               
  ...fications.tsx |       0 |        0 |       0 |       0 | 1-56              
  ...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 |    83.78 |     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.49 |    73.89 |   69.23 |   71.49 | ...1244,1250-1251 
  ...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.77 |    87.67 |     100 |   97.77 | ...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 |      80 |    66.66 |     100 |      80 | ...70-277,283-300 
  ...ineDialog.tsx |    93.5 |    85.18 |     100 |    93.5 | ...05,267,287-289 
  ...yTodoList.tsx |   96.36 |    88.23 |     100 |   96.36 | 138-141           
  ...nsDisplay.tsx |   92.97 |    83.87 |     100 |   92.97 | ...45,248,275-277 
  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 |    83.33 |     100 |     100 | 72-87             
  ...ification.tsx |   36.36 |      100 |       0 |   36.36 | 15-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 |   55.05 |    69.09 |      50 |   55.05 |                   
  ...atContent.tsx |    9.09 |      100 |       0 |    9.09 | 54-275,281-283    
  ...tChatView.tsx |   21.05 |      100 |       0 |   21.05 | 21-39             
  ...tComposer.tsx |   69.48 |    33.33 |   66.66 |   69.48 | ...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.3 |    68.69 |   73.68 |    42.3 |                   
  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-166             
  ...tusDialog.tsx |       0 |        0 |       0 |       0 | 1-288             
  ...topDialog.tsx |       0 |        0 |       0 |       0 | 1-213             
 ...ackground-view |    82.2 |    81.36 |    90.9 |    82.2 |                   
  ...sksDialog.tsx |   77.53 |     76.9 |   80.76 |   77.53 | ...1781,1803-1809 
  ...TasksPill.tsx |   67.03 |     86.2 |     100 |   67.03 | ...02-122,130-138 
  ...gentPanel.tsx |   97.08 |    86.31 |     100 |   97.08 | 132,442-446,520   
  agent-forest.ts  |    99.2 |    93.93 |     100 |    99.2 | 258               
  ...Visibility.ts |     100 |      100 |     100 |     100 |                   
  ...e-overlay.tsx |    88.2 |    76.47 |     100 |    88.2 | ...36-138,140-142 
 ...nts/extensions |   84.32 |    76.78 |   83.33 |   84.32 |                   
  ...gerDialog.tsx |   82.15 |    76.08 |     100 |   82.15 | ...91-198,258,260 
  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.26 |       85 |   58.82 |   46.26 |                   
  ...ctionStep.tsx |   95.12 |    92.85 |   85.71 |   95.12 | 84-86,89          
  ...etailStep.tsx |       0 |        0 |       0 |       0 | 1-145             
  ...nListStep.tsx |   75.26 |    88.37 |   66.66 |   75.26 | ...53,174,203-209 
  ...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 |   71.92 |    68.21 |   70.83 |   71.92 |                   
  DiscoverTab.tsx  |   68.22 |    67.66 |   55.55 |   68.22 | ...93,656-660,664 
  InstalledTab.tsx |   75.49 |    67.44 |   83.33 |   75.49 | ...77,782-783,820 
  SourcesTab.tsx   |   71.67 |    70.47 |   77.77 |   71.67 | ...28,547,621-633 
 ...tensions/views |   50.97 |    52.38 |   20.83 |   50.97 |                   
  ...tionsView.tsx |   73.75 |    56.36 |   66.66 |   73.75 | ...30,353,369-374 
  ...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 |   87.11 |    81.37 |   91.89 |   87.11 |                   
  ...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.04 |    61.53 |   70.58 |   40.04 |                   
  ...ealthPill.tsx |   68.42 |    85.71 |     100 |   68.42 | 40-46             
  ...entDialog.tsx |   32.09 |    26.19 |      40 |   32.09 | ...12,914,927-933 
  ...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 |   53.94 |    73.51 |   57.14 |   53.94 |                   
  ...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 |   62.83 |       60 |   33.33 |   62.83 | ...87-296,307-332 
  ...rListStep.tsx |   88.53 |    81.25 |     100 |   88.53 | ...64,170,175-180 
  ...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 |   89.82 |    86.16 |   85.29 |   89.82 |                   
  ...ionDialog.tsx |   89.23 |    84.27 |   81.81 |   89.23 | ...75,593,611-613 
  BtwMessage.tsx   |     100 |      100 |     100 |     100 |                   
  ...upDisplay.tsx |     100 |    94.73 |     100 |     100 | ...43,289,402,432 
  ...onMessage.tsx |   92.06 |    82.35 |     100 |   92.06 | 58-60,62,64       
  ...nMessages.tsx |   94.44 |    97.77 |   78.57 |   94.44 | ...53-355,358-361 
  DiffRenderer.tsx |   93.17 |    86.02 |     100 |   93.17 | ...07,235-236,302 
  ...tsDisplay.tsx |   97.08 |    77.77 |     100 |   97.08 | 95,97,106         
  ...usMessage.tsx |   76.52 |     42.1 |   66.66 |   76.52 | ...00,102,125,156 
  ...tsDisplay.tsx |   95.52 |    88.31 |     100 |   95.52 | ...40,142,175-180 
  ...ssMessage.tsx |    12.5 |      100 |       0 |    12.5 | 18-59             
  ...edMessage.tsx |   21.05 |      100 |       0 |   21.05 | 23-39             
  ...sMessages.tsx |   59.04 |       50 |    37.5 |   59.04 | ...21-126,147-159 
  ...ryMessage.tsx |   13.63 |      100 |       0 |   13.63 | 23-64             
  ...onMessage.tsx |   89.75 |     79.1 |     100 |   89.75 | ...33-635,642-644 
  ...upMessage.tsx |   98.32 |    95.16 |     100 |   98.32 | 184-187,414       
  ToolMessage.tsx  |   92.49 |    84.92 |   93.33 |   92.49 | ...61-966,993-995 
 ...ponents/shared |   85.79 |    82.11 |   94.11 |   85.79 |                   
  ...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  |   84.71 |    86.86 |      90 |   84.71 | ...67-568,685-686 
  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 |   81.48 |    84.84 |     100 |   81.48 | 46-66,73-76       
  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.51 |    85.11 |   81.81 |   88.51 | ...51-779,792,887 
  text-buffer.ts   |   85.98 |    81.81 |   97.91 |   85.98 | ...2664,2762-2763 
  ...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-681             
 ...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.14 |    53.19 |    37.5 |   14.14 |                   
  ...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.61 |    59.52 |     100 |   35.61 | ...21-433,438-440 
  ...iewerStep.tsx |       0 |        0 |       0 |       0 | 1-73              
  ...gerDialog.tsx |       0 |        0 |       0 |       0 | 1-341             
 ...mponents/views |   69.81 |    72.64 |   61.11 |   69.81 |                   
  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 |   88.05 |       75 |     100 |   88.05 | 70-77             
  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   |   84.14 |    81.87 |    86.3 |   84.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 |   85.98 |    85.26 |     100 |   85.98 | ...1612-1614,1620 
  ...owContext.tsx |   91.07 |    81.81 |     100 |   91.07 | 47-48,60-62       
  ...deContext.tsx |     100 |      100 |      50 |     100 |                   
  ...onContext.tsx |   80.77 |       80 |    92.3 |   80.77 | ...31-434,443-446 
  ...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 | 155-156           
  ...teContext.tsx |   86.66 |       50 |     100 |   86.66 | 234-235           
  ...deContext.tsx |      80 |     87.5 |      75 |      80 | ...11-112,118-120 
  ...rtContext.tsx |     100 |      100 |     100 |     100 |                   
 src/ui/daemon     |   88.35 |    73.51 |   95.45 |   88.35 |                   
  ...ui-adapter.ts |   88.35 |    73.51 |   95.45 |   88.35 | ...74,792-793,879 
 src/ui/editors    |       0 |        0 |       0 |       0 |                   
  ...ngsManager.ts |       0 |        0 |       0 |       0 | 1-67              
 src/ui/hooks      |   85.19 |    82.61 |   89.66 |   85.19 |                   
  ...dProcessor.ts |   85.47 |    85.13 |     100 |   85.47 | ...-967,1014-1015 
  ...ention-ref.ts |   97.72 |       84 |     100 |   97.72 | 65                
  keyToAnsi.ts     |    3.92 |      100 |       0 |    3.92 | 19-77             
  ...esourceRef.ts |     100 |      100 |     100 |     100 |                   
  ...completion.ts |     100 |    95.45 |     100 |     100 | 95                
  ...ention-ref.ts |     100 |      100 |     100 |     100 |                   
  ...dProcessor.ts |   94.62 |    73.58 |     100 |   94.62 | ...86-287,292-293 
  ...dProcessor.ts |   85.21 |     66.4 |   81.81 |   85.21 | ...1407,1428-1432 
  ...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 
  ...ke-repaint.ts |     100 |      100 |     100 |     100 |                   
  ...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 |   86.44 |    88.48 |     100 |   86.44 | ...14-515,525-541 
  ...ifications.ts |   87.82 |    96.77 |     100 |   87.82 | 138-152           
  ...tIndicator.ts |   88.28 |    81.57 |     100 |   88.28 | ...66,175,179-187 
  ...waySummary.ts |   96.26 |       75 |     100 |   96.26 | 126-128,170       
  ...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 |   94.85 |    80.76 |     100 |   94.85 | ...54,229,292-295 
  ...ompletion.tsx |   97.09 |    87.09 |     100 |   97.09 | ...23-324,334-335 
  ...dMigration.ts |    92.1 |    88.88 |     100 |    92.1 | 42-44             
  useCompletion.ts |   96.29 |    90.56 |     100 |   96.29 | ...17-218,222-223 
  ...nitMessage.ts |     100 |      100 |     100 |     100 |                   
  ...extualTips.ts |   78.26 |       50 |     100 |   78.26 | ...2,75-79,96-104 
  ...eteCommand.ts |   89.52 |    90.69 |     100 |   89.52 | ...98-106,114-115 
  ...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.67 |     100 |   99.12 | 182-183           
  ...ionUpdates.ts |   93.72 |    92.98 |     100 |   93.72 | ...87-291,314-320 
  ...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 |    93.33 |     100 |     100 | 62                
  ...ggestions.tsx |   96.47 |    78.94 |     100 |   96.47 | 121,155-156       
  ...miniStream.ts |   85.66 |    81.38 |   96.15 |   85.66 | ...3943,4111-4119 
  ...BranchName.ts |     100 |    94.44 |     100 |     100 | 54                
  ...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 |    9.67 |      100 |       0 |    9.67 | 11-32,39-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 |     97.5 |     100 |     100 | 99                
  ...delCommand.ts |     100 |       95 |     100 |     100 | 53                
  ...ouseEvents.ts |   94.56 |    94.87 |   83.33 |   94.56 | 77-81             
  ...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 |    87.4 |    78.78 |     100 |    87.4 | ...71,321-333,381 
  useQwenAuth.ts   |     100 |      100 |     100 |     100 |                   
  ...lScheduler.ts |   88.95 |    86.95 |     100 |   88.95 | ...37-439,471-481 
  ...oryCommand.ts |       0 |        0 |       0 |       0 | 1-7               
  ...umeCommand.ts |   94.67 |    74.28 |     100 |   94.67 | ...19,174,233-238 
  ...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 |   85.48 |    58.33 |     100 |   85.48 | 22-28,40,71       
  ...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 |   67.34 |    58.82 |   66.66 |   67.34 | 52-53,61-68,79-85 
  ...rminalSize.ts |     100 |      100 |     100 |     100 |                   
  ...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 |    90.47 |     100 |     100 | 112,134           
  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 |    72.72 |     100 |   93.75 | 47-48,72          
  vim.ts           |      74 |    67.56 |   69.23 |      74 | ...1854-1861,1869 
 src/ui/layouts    |    91.2 |    89.47 |     100 |    91.2 |                   
  ...AppLayout.tsx |    90.9 |     87.5 |     100 |    90.9 | 60-62,110-115,151 
  ...AppLayout.tsx |   91.66 |    92.85 |     100 |   91.66 | 75-80             
 src/ui/models     |   80.72 |       80 |   71.42 |   80.72 |                   
  ...ableModels.ts |   80.72 |       80 |   71.42 |   80.72 | ...,61-71,125-127 
 ...noninteractive |     100 |      100 |    6.66 |     100 |                   
  ...eractiveUi.ts |     100 |      100 |    6.66 |     100 |                   
 src/ui/selection  |   86.47 |    79.88 |   96.66 |   86.47 |                   
  screen-buffer.ts |   94.73 |    64.28 |     100 |   94.73 | 51-52             
  ...ion-coords.ts |     100 |      100 |     100 |     100 |                   
  ...ction-span.ts |   92.72 |       90 |     100 |   92.72 | 37-38,67-68       
  ...tion-state.ts |   85.71 |      100 |   88.88 |   85.71 | 51-58             
  ...ction-text.ts |   92.85 |    92.45 |     100 |   92.85 | 30-34,114-115     
  ...selection.tsx |   80.31 |    59.64 |     100 |   80.31 | ...13-314,330-331 
 src/ui/state      |      95 |    81.81 |     100 |      95 |                   
  extensions.ts    |      95 |    81.81 |     100 |      95 | 69-70,89          
 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      |   86.58 |    84.96 |   95.29 |   86.58 |                   
  ...Colorizer.tsx |   80.31 |    85.41 |     100 |   80.31 | ...00-201,313-339 
  ...nRenderer.tsx |   79.84 |     75.6 |     100 |   79.84 | ...66,270,328-329 
  ...wnDisplay.tsx |   92.87 |    93.46 |     100 |   92.87 | ...,955,1002-1020 
  ...idDiagram.tsx |   87.79 |    95.34 |     100 |   87.79 | 156-179           
  ...eRenderer.tsx |   92.38 |    81.91 |   95.23 |   92.38 | ...43-746,799-804 
  ...odeDisplay.ts |   94.28 |    85.71 |     100 |   94.28 | 23,40             
  asciiCharts.ts   |    96.7 |     87.5 |     100 |    96.7 | 170-177,278       
  ...dWorkUtils.ts |     100 |      100 |     100 |     100 |                   
  ...boardUtils.ts |   52.52 |    73.25 |   91.66 |   52.52 | ...23,626-635,638 
  commandUtils.ts  |   96.17 |    88.88 |     100 |   96.17 | ...77,179-180,323 
  computeStats.ts  |     100 |      100 |     100 |     100 |                   
  customBanner.ts  |   90.68 |    91.22 |     100 |   90.68 | ...13,324-327,334 
  displayUtils.ts  |   73.84 |    73.91 |     100 |   73.84 | ...34,36-40,42-46 
  formatters.ts    |   94.87 |    98.21 |     100 |   94.87 | 116-119           
  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  |      96 |    97.05 |     100 |      96 | 102-105           
  inline-math.ts   |   98.48 |    95.23 |     100 |   98.48 | 129-130           
  input-mouse.ts   |     100 |    85.71 |     100 |     100 | 48,93             
  isNarrowWidth.ts |     100 |      100 |     100 |     100 |                   
  ...olDetector.ts |   68.81 |       75 |   66.66 |   68.81 | ...27-132,160-161 
  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 |   98.72 |    94.36 |     100 |   98.72 | 145-146           
  ...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 |    74.19 |     100 |   92.85 | ...38,145,149-152 
  osc8.ts          |   90.43 |    78.33 |     100 |   90.43 | ...59,244,248-249 
  ...red-height.ts |   98.38 |     97.1 |     100 |   98.38 | 195-197           
  ...mConstants.ts |     100 |      100 |     100 |     100 |                   
  restoreGoal.ts   |     100 |      100 |     100 |     100 |                   
  ...storyUtils.ts |   79.32 |    77.37 |     100 |   79.32 | ...32-554,685-686 
  ...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 
  suggestions.ts   |     100 |      100 |     100 |     100 |                   
  ...izedOutput.ts |   94.94 |      100 |   88.88 |   94.94 | 112-117           
  ...nal-buffer.ts |     100 |      100 |     100 |     100 |                   
  ...wOptimizer.ts |     100 |    96.77 |     100 |     100 | 69                
  terminalSetup.ts |    4.37 |      100 |       0 |    4.37 | 44-393            
  textUtils.ts     |   95.97 |    94.06 |   94.44 |   95.97 | ...29-330,490-491 
  ...background.ts |     100 |      100 |     100 |     100 |                   
  todoSnapshot.ts  |   90.42 |    92.85 |     100 |   90.42 | ...06-207,240-241 
  ...isplay-map.ts |     100 |      100 |     100 |     100 |                   
  updateCheck.ts   |     100 |    92.75 |     100 |     100 | 227-239,331       
  ...ow-keyword.ts |     100 |      100 |     100 |     100 |                   
 ...i/utils/export |   75.03 |    59.89 |   94.59 |   75.03 |                   
  collect.ts       |   71.27 |    65.81 |      96 |   71.27 | ...90-633,655-656 
  index.ts         |     100 |      100 |     100 |     100 |                   
  normalize.ts     |   80.42 |    50.68 |     100 |   80.42 | ...59-364,376-378 
  types.ts         |       0 |        0 |       0 |       0 | 1                 
  utils.ts         |     100 |      100 |     100 |     100 |                   
 ...ort/formatters |   52.92 |    47.22 |   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 |     37.5 |     100 |   82.45 | ...48,50-51,65-66 
  markdown.ts      |   36.32 |    47.05 |      50 |   36.32 | ...16-219,233-295 
 src/ui/voice      |   80.94 |    72.69 |   80.55 |   80.94 |                   
  ...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 |   89.72 |    65.33 |   93.75 |   89.72 | ...99,305,316-319 
  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 |   86.79 |    68.42 |     100 |   86.79 | 16-18,48-49,59-60 
  ...am-session.ts |   88.02 |    66.66 |   84.61 |   88.02 | ...26,343-345,363 
  ...ranscriber.ts |     100 |      100 |     100 |     100 |                   
 src/utils         |   81.24 |    86.96 |   92.54 |   81.24 |                   
  ...p-profiler.ts |   98.39 |    90.56 |     100 |   98.39 | 141,185,235       
  acpModelUtils.ts |   97.36 |    95.19 |     100 |   97.36 | ...09-210,214-215 
  apiPreconnect.ts |   96.74 |    94.59 |     100 |   96.74 | 167-170           
  ...ol-call-id.ts |   84.61 |       60 |     100 |   84.61 | 26-27,37-38       
  ...ng-failure.ts |     100 |       95 |     100 |     100 | 72                
  checks.ts        |   33.33 |      100 |       0 |   33.33 | 23-28             
  ...-api-error.ts |     100 |    96.42 |     100 |     100 | 14                
  cleanup.ts       |   84.05 |    94.11 |      80 |   84.05 | 80,111-121        
  commands.ts      |   97.45 |    96.66 |     100 |   97.45 | 153-155           
  ...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          
  ...re-runtime.ts |     100 |      100 |     100 |     100 |                   
  ...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        |   97.56 |    94.64 |     100 |   97.56 | 69-70,304-305     
  events.ts        |     100 |      100 |     100 |     100 |                   
  ...on-mention.ts |   88.48 |     82.6 |     100 |   88.48 | ...56-160,164-168 
  gitUtils.ts      |   92.85 |    86.66 |     100 |   92.85 | ...13-116,164-167 
  ...AutoUpdate.ts |    93.1 |       94 |      90 |    93.1 | 103,108,179-190   
  ...tyWarnings.ts |     100 |      100 |     100 |     100 |                   
  ...lationInfo.ts |   97.68 |    94.28 |     100 |   97.68 | ...59,376-377,422 
  jsonc-editor.ts  |   93.18 |    92.66 |     100 |   93.18 | ...80-381,384-385 
  languageUtils.ts |   98.88 |    97.05 |     100 |   98.88 | 184-185           
  load-undici.ts   |     100 |      100 |     100 |     100 |                   
  ...npm-update.ts |   86.32 |    76.05 |     100 |   86.32 | ...02-303,331-341 
  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.25 |    91.17 |     100 |   94.25 | ...30,436,439-443 
  ...iveHelpers.ts |   95.13 |    91.79 |     100 |   95.13 | ...53-454,552,565 
  osc.ts           |   97.18 |      100 |    87.5 |   97.18 | 182-183           
  package.ts       |   88.88 |    85.71 |     100 |   88.88 | 31-32             
  ...uggestions.ts |   74.38 |    69.56 |     100 |   74.38 | ...92-103,105-116 
  processUtils.ts  |    92.3 |       80 |     100 |    92.3 | 45-46             
  readStdin.ts     |   93.67 |    94.11 |   85.71 |   93.67 | 79-83             
  relaunch.ts      |   95.87 |    89.28 |     100 |   95.87 | 103-105,131       
  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       |   45.67 |    56.93 |   76.92 |   45.67 | ...1034,1046-1069 
  ...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.35 |    89.57 |      90 |   82.35 | ...25-743,750-758 
  spawnWrapper.ts  |     100 |      100 |     100 |     100 |                   
  ...ate-verify.ts |     100 |      100 |     100 |     100 |                   
  ...one-update.ts |   39.81 |    77.44 |   62.16 |   39.81 | ...1193,1196-1215 
  ...upProfiler.ts |   98.47 |    94.66 |     100 |   98.47 | 132-133,308       
  ...upWarnings.ts |     100 |      100 |     100 |     100 |                   
  stdioHelpers.ts  |     100 |     87.5 |     100 |     100 | 23                
  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 |   76.47 |       25 |     100 |   76.47 | 13,17,23-24       
  ...on-handler.ts |    73.8 |       75 |     100 |    73.8 | 17-18,25-26,67-73 
  ...e-relaunch.ts |   89.61 |    86.66 |      50 |   89.61 | 56-61,83-84       
  ...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          |   87.52 |    86.16 |   89.11 |   87.52 |                   
 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.28 |    84.25 |   95.23 |   90.28 |                   
  ...transcript.ts |   87.63 |    83.52 |     100 |   87.63 | ...80,588,594-598 
  ...ent-resume.ts |   85.53 |    77.44 |   83.33 |   85.53 | ...1781-1785,1788 
  ...ound-tasks.ts |   96.15 |    90.13 |   98.76 |   96.15 | ...1732,1752-1755 
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...ent-result.ts |    96.8 |    92.68 |     100 |    96.8 | 106,129-131       
  ...n-registry.ts |    95.9 |    90.42 |     100 |    95.9 | ...28-429,502-506 
  ...w-snapshot.ts |   91.86 |       75 |     100 |   91.86 | ...54,178,185-187 
 src/agents/arena  |   76.32 |    67.71 |   78.94 |   76.32 |                   
  ...gentClient.ts |   79.47 |    88.88 |   81.81 |   79.47 | ...68-183,189-204 
  ArenaManager.ts  |   75.11 |    64.51 |   78.57 |   75.11 | ...1887,1893-1894 
  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 |   78.09 |    85.23 |   76.28 |   78.09 |                   
  ITermBackend.ts  |   97.97 |    93.93 |     100 |   97.97 | ...78-180,255,307 
  ...essBackend.ts |    90.9 |    85.36 |   93.33 |    90.9 | ...70,672,674-675 
  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 |   90.42 |    85.66 |   87.64 |   90.42 |                   
  agent-context.ts |     100 |      100 |     100 |     100 |                   
  agent-core.ts    |   85.05 |    76.67 |   77.77 |   85.05 | ...2287,2333-2335 
  agent-events.ts  |     100 |      100 |     100 |     100 |                   
  ...t-headless.ts |   93.49 |    89.41 |   83.33 |   93.49 | ...96-497,500-501 
  ...nteractive.ts |   81.01 |    82.35 |   76.66 |   81.01 | ...33,535-538,541 
  ...statistics.ts |   98.29 |    82.55 |     100 |   98.29 | 141,165,206,239   
  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 | ...1775,1824-1827 
  ...ow-prompts.ts |     100 |      100 |     100 |     100 |                   
  ...low-runner.ts |   91.76 |    81.03 |   91.66 |   91.76 | ...51,195,215-218 
  ...ow-sandbox.ts |   96.87 |    94.64 |     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.81 |    83.99 |    87.5 |   81.81 |                   
  TeamManager.ts   |   72.02 |    79.41 |   79.24 |   72.02 | ...1632,1655-1656 
  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 | ...40-144,151-155 
  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        |   84.91 |       87 |   75.16 |   84.91 |                   
  approval-mode.ts |     100 |      100 |     100 |     100 |                   
  ...xtDefaults.ts |     100 |      100 |     100 |     100 |                   
  config.ts        |    84.2 |    86.71 |   73.52 |    84.2 | ...8178,8182-8183 
  constants.ts     |     100 |      100 |     100 |     100 |                   
  models.ts        |     100 |      100 |     100 |     100 |                   
  storage.ts       |   94.39 |    91.57 |   88.23 |   94.39 | ...45-446,449-450 
 ...nfirmation-bus |   98.27 |    97.14 |     100 |   98.27 |                   
  message-bus.ts   |   98.14 |    97.05 |     100 |   98.14 | 42-43             
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/core          |   91.95 |    88.25 |   93.21 |   91.95 |                   
  baseLlmClient.ts |   88.28 |    82.48 |   81.81 |   88.28 | ...47,660,666-668 
  client.ts        |   91.92 |    87.39 |   91.56 |   91.92 | ...3915,4011-4012 
  ...tGenerator.ts |   86.34 |    87.34 |   84.61 |   86.34 | ...81-482,527-533 
  ...lScheduler.ts |    90.1 |    85.95 |      96 |    90.1 | ...5644,5672-5683 
  geminiChat.ts    |   92.57 |    89.36 |      96 |   92.57 | ...4508,4556-4557 
  geminiRequest.ts |     100 |      100 |     100 |     100 |                   
  genai-compat.ts  |     100 |      100 |     100 |     100 |                   
  ...MediaLimit.ts |     100 |       96 |     100 |     100 | 96                
  ...htProtocol.ts |    9.09 |      100 |       0 |    9.09 | ...9,62-66,69-110 
  ...ream-error.ts |     100 |      100 |     100 |     100 |                   
  logger.ts        |   87.41 |    87.02 |     100 |   87.41 | ...64-568,614-628 
  ...lay-buffer.ts |     100 |      100 |     100 |     100 |                   
  ...dispatcher.ts |     100 |      100 |     100 |     100 |                   
  ...tyDefaults.ts |     100 |      100 |     100 |     100 |                   
  ...olExecutor.ts |   93.54 |    83.33 |      50 |   93.54 | 49-50             
  ...on-helpers.ts |   93.49 |    78.57 |     100 |   93.49 | ...10-211,228-229 
  ...issionFlow.ts |   98.97 |    96.96 |     100 |   98.97 | 107               
  ...try-policy.ts |     100 |      100 |     100 |     100 |                   
  ...ell-policy.ts |   95.19 |    89.47 |     100 |   95.19 | ...44-245,290-291 
  prompts.ts       |   93.57 |    91.42 |   83.33 |   93.57 | ...1187,1390-1391 
  ...ing-effort.ts |     100 |      100 |     100 |     100 |                   
  ...n-recovery.ts |   95.13 |       80 |     100 |   95.13 | ...06-107,142-144 
  ...t-profiler.ts |   96.89 |    80.88 |   88.23 |   96.89 | ...10,117-118,123 
  ...port-retry.ts |     100 |      100 |     100 |     100 |                   
  tokenLimits.ts   |     100 |     92.3 |     100 |     100 | 87,122-139        
  ...reparation.ts |     100 |      100 |     100 |     100 |                   
  ...tion-guard.ts |     100 |      100 |     100 |     100 |                   
  ...allIdUtils.ts |   98.41 |    93.47 |     100 |   98.41 | 36,45             
  ...okTriggers.ts |   99.45 |    92.43 |     100 |   99.45 | 182,193           
  ...terruption.ts |     100 |     92.3 |     100 |     100 | 86,104            
  turn.ts          |   98.52 |    91.66 |     100 |   98.52 | ...14,642-643,690 
  ...l-fallback.ts |     100 |      100 |     100 |     100 |                   
 ...ntentGenerator |    96.2 |    87.41 |      96 |    96.2 |                   
  ...tGenerator.ts |   97.23 |    86.48 |   94.73 |   97.23 | ...1423,1452,1463 
  converter.ts     |   95.92 |    88.16 |     100 |   95.92 | ...1305,1484-1486 
  index.ts         |       0 |        0 |       0 |       0 | 1-21              
  usage.ts         |     100 |      100 |     100 |     100 |                   
 ...ntentGenerator |   88.78 |    72.36 |   89.47 |   88.78 |                   
  ...tGenerator.ts |   87.18 |    71.83 |   88.88 |   87.18 | ...58-364,382-383 
  index.ts         |     100 |       80 |     100 |     100 | 50                
 ...ntentGenerator |    95.6 |    88.74 |    92.3 |    95.6 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...tGenerator.ts |   95.52 |    87.88 |   91.89 |   95.52 | ...1195-1196,1224 
  ...tDetection.ts |     100 |      100 |     100 |     100 |                   
 ...ntentGenerator |   91.65 |    90.23 |   95.23 |   91.65 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  converter.ts     |   91.15 |    89.32 |   96.87 |   91.15 | ...1914,2083-2098 
  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.63 |    90.94 |     100 |   96.63 | ...1100,1108,1203 
  ...ureContext.ts |     100 |      100 |     100 |     100 |                   
  ...ingOptions.ts |       0 |        0 |       0 |       0 | 1                 
  ...CallParser.ts |   92.24 |     92.4 |     100 |   92.24 | ...28-529,549-552 
  ...kingParser.ts |     100 |    96.87 |     100 |     100 | 42                
  types.ts         |       0 |        0 |       0 |       0 | 1                 
 ...rator/provider |   96.73 |    89.76 |   98.27 |   96.73 |                   
  dashscope.ts     |   97.48 |    91.91 |      95 |   97.48 | ...85-386,528-529 
  deepseek.ts      |   94.91 |    89.36 |     100 |   94.91 | ...31-132,145-146 
  default.ts       |   99.16 |    96.96 |     100 |   99.16 | 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     |    86.2 |    83.25 |   92.33 |    86.2 |                   
  ...ive-safety.ts |     100 |      100 |     100 |     100 |                   
  ...-converter.ts |   78.32 |    71.83 |     100 |   78.32 | ...1122,1168-1169 
  corruptFile.ts   |     100 |       50 |     100 |     100 | 40-45             
  ...-converter.ts |   80.39 |     87.5 |     100 |   80.39 | 50-59             
  ...me-refresh.ts |     100 |      100 |     100 |     100 |                   
  ...sion-store.ts |   90.82 |    86.38 |   97.82 |   90.82 | ...1215-1221,1265 
  ...ionManager.ts |   81.06 |    78.78 |   81.52 |   81.06 | ...2705,2727-2728 
  ...references.ts |     100 |     90.9 |     100 |     100 | ...05,129,197,200 
  ...onSettings.ts |    92.3 |     94.4 |     100 |    92.3 | ...98-501,570-571 
  ...-converter.ts |    75.9 |    84.61 |   85.71 |    75.9 | ...98,202,214-248 
  github.ts        |   88.58 |    82.13 |     100 |   88.58 | ...62,952-953,963 
  http-client.ts   |   84.61 |       80 |     100 |   84.61 | 20-21             
  i18n.ts          |   78.26 |       96 |      50 |   78.26 | 104-110,116-123   
  index.ts         |     100 |      100 |     100 |     100 |                   
  marketplace.ts   |   88.39 |    83.11 |     100 |   88.39 | ...08,494,507-508 
  ...ork-policy.ts |   89.72 |       90 |     100 |   89.72 | ...36,148-154,156 
  npm.ts           |   89.02 |    81.81 |     100 |   89.02 | ...86-688,695-700 
  override.ts      |   94.11 |    93.33 |     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 |   94.01 |    83.14 |     100 |   94.01 | ...38-344,365-366 
  storage.ts       |     100 |      100 |     100 |     100 |                   
  ...ableSchema.ts |     100 |      100 |     100 |     100 |                   
  variables.ts     |   88.95 |    83.78 |     100 |   88.95 | ...32-235,238-241 
  ...extraction.ts |   85.77 |    80.61 |   89.47 |   85.77 | ...02-205,260-261 
 src/followup      |   79.86 |    80.36 |    90.9 |   79.86 |                   
  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   |   71.45 |    66.01 |   71.42 |   71.45 | ...49-650,657-658 
  ...onToolGate.ts |     100 |    96.55 |     100 |     100 | 97                
  ...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         |   94.17 |    88.82 |   95.93 |   94.17 |                   
  ...eGoalStore.ts |   87.61 |    88.88 |   86.66 |   87.61 | ...85-188,196-204 
  goal-evidence.ts |   87.59 |     85.1 |   95.65 |   87.59 | ...12-613,636-639 
  ...projection.ts |   89.41 |    72.22 |   66.66 |   89.41 | ...28,131,135-137 
  ...ersistence.ts |   87.73 |    84.84 |      80 |   87.73 | ...-94,97,101-106 
  goal-protocol.ts |    91.3 |       90 |     100 |    91.3 | 107-108           
  goal-reducer.ts  |   92.21 |    85.48 |     100 |   92.21 | ...67-368,381,436 
  goal-runtime.ts  |   99.01 |    93.44 |     100 |   99.01 | ...83-684,707-708 
  goal-tools.ts    |   98.32 |    93.18 |   95.23 |   98.32 | ...48-149,256-257 
  ...rn-context.ts |     100 |      100 |     100 |     100 |                   
  goal-verifier.ts |   92.46 |    92.85 |     100 |   92.46 | ...67-170,183-185 
  goal-wire.ts     |       0 |        0 |       0 |       0 | 1-27              
  goalHook.ts      |   96.91 |    92.42 |     100 |   96.91 | 115-120,221-222   
  goalJudge.ts     |   95.84 |    87.09 |     100 |   95.84 | ...55-356,448-449 
  index.ts         |     100 |      100 |     100 |     100 |                   
 src/hooks         |   88.11 |    86.38 |   88.62 |   88.11 |                   
  ...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.57 |    84.76 |   94.73 |   95.57 | ...1040-1041,1051 
  hookPlanner.ts   |   87.55 |    85.54 |   86.66 |   87.55 | ...22-226,233-244 
  hookRegistry.ts  |   92.53 |    85.43 |     100 |   92.53 | ...39,458,462,466 
  hookRunner.ts    |   62.65 |    72.34 |   66.66 |   62.65 | ...70-771,780-781 
  hookSystem.ts    |   87.64 |     98.5 |   70.83 |   87.64 | ...58-759,765-766 
  ...HookRunner.ts |   79.06 |    66.66 |      80 |   79.06 | ...33-434,452-456 
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...edCallback.ts |     100 |      100 |     100 |     100 |                   
  ...HookRunner.ts |   94.19 |    84.37 |   81.81 |   94.19 | ...76-384,458-459 
  ...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     |   86.45 |    89.13 |     100 |   86.45 | ...85,289-295,301 
  stopHookCap.ts   |     100 |      100 |     100 |     100 |                   
  trustedHooks.ts  |      90 |    52.63 |     100 |      90 | ...53,66-67,97-98 
  types.ts         |   94.25 |    96.12 |   88.88 |   94.25 | ...46-547,632-636 
  urlValidator.ts  |     100 |      100 |     100 |     100 |                   
  ...it-context.ts |     100 |      100 |     100 |     100 |                   
 src/ide           |   76.98 |    85.03 |   79.03 |   76.98 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  detect-ide.ts    |     100 |      100 |     100 |     100 |                   
  ide-client.ts    |   69.16 |    84.65 |   68.29 |   69.16 | ...1068,1097-1105 
  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.3 |    77.81 |   78.33 |    82.3 |                   
  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.31 |    58.06 |     100 |   79.31 | ...26-933,940-942 
  ...en-storage.ts |   98.78 |    97.95 |     100 |   98.78 | 106-107           
  oauth-utils.ts   |   73.61 |    85.48 |    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.03 |   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        |   87.23 |    83.05 |   90.32 |   87.23 |                   
  ...y-document.ts |   89.52 |    84.61 |     100 |   89.52 | ...24-325,329-330 
  ...nel-memory.ts |   97.11 |    95.72 |   96.29 |   97.11 | ...85-287,361-362 
  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 
  ...kill-agent.ts |   97.94 |    89.36 |     100 |   97.94 | 82-83,179-180     
  manager.ts       |    78.4 |    82.29 |   77.77 |    78.4 | ...1482,1495-1497 
  ...ent-config.ts |   82.27 |    77.92 |   83.33 |   82.27 | ...66,285,292-298 
  memoryAge.ts     |   90.47 |       80 |     100 |   90.47 | 50-51             
  paths.ts         |   95.27 |    96.59 |     100 |   95.27 | ...79-380,401-402 
  ...ing-skills.ts |     100 |       72 |     100 |     100 | 31-35,73-78,97    
  prompt.ts        |   97.26 |    87.03 |     100 |   97.26 | ...10-218,222,225 
  recall.ts        |   82.06 |       75 |    90.9 |   82.06 | ...59-364,395-406 
  refresh.ts       |   89.85 |    82.92 |     100 |   89.85 | ...54-155,162-163 
  ...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 
  scopes.ts        |     100 |      100 |     100 |     100 |                   
  ...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         |   92.92 |    81.81 |     100 |   92.92 | ...16-117,147-148 
  ...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 |   81.21 |    81.53 |   81.81 |   81.21 | ...63-277,291-296 
 src/mocks         |       0 |        0 |       0 |       0 |                   
  msw.ts           |       0 |        0 |       0 |       0 | 1-9               
 src/models        |   92.54 |       89 |   91.13 |   92.54 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  ...tor-config.ts |   97.77 |    91.83 |     100 |   97.77 | 155,161,171       
  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.13 |     100 |     100 | 177,260           
  modelsConfig.ts  |   89.36 |    86.93 |   88.09 |   89.36 | ...1404,1433-1434 
  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.76 |    91.27 |   71.07 |   83.76 |                   
  autoMode.ts      |   97.65 |    93.13 |     100 |   97.65 | ...79-586,632,709 
  ...transcript.ts |      98 |    84.61 |     100 |      98 | 200-201           
  classifier.ts    |      94 |    94.54 |     100 |      94 | 158-165,389-393   
  ...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 |   86.54 |    89.63 |      80 |   86.54 | ...1096,1202-1206 
  rule-parser.ts   |   94.49 |    92.72 |     100 |   94.49 | ...1447,1481-1483 
  ...-semantics.ts |   70.44 |    91.07 |   46.66 |   70.44 | ...2237,2311-2314 
  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/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     |   83.71 |     78.5 |   81.25 |   83.71 |                   
  all-providers.ts |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  install.ts       |   93.11 |     84.5 |     100 |   93.11 | ...56-257,330-331 
  ...der-config.ts |   75.85 |    73.84 |   78.26 |   75.85 | ...73-474,502-503 
  types.ts         |       0 |        0 |       0 |       0 | 1                 
 ...viders/presets |   97.82 |    91.66 |   63.63 |   97.82 |                   
  ...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 |                   
  grok.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.41 |    78.52 |   95.89 |   85.41 |                   
  ...tGenerator.ts |   98.64 |    98.18 |     100 |   98.64 | 105-106           
  qwenOAuth2.ts    |   82.79 |    73.29 |   90.62 |   82.79 | ...1205-1221,1251 
  ...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      |   89.55 |    84.31 |   96.93 |   89.55 |                   
  ...ionTrailer.ts |     100 |      100 |     100 |     100 |                   
  ...llRegistry.ts |   97.68 |    85.71 |     100 |   97.68 | ...96,119,490-491 
  ...ionService.ts |   96.71 |    95.79 |     100 |   96.71 | ...83,699,832-840 
  ...ingService.ts |   90.91 |    84.17 |   95.45 |   90.91 | ...2058,2085-2086 
  ...ttribution.ts |   91.73 |    87.71 |      90 |   91.73 | ...80-685,826-827 
  ...utSlimming.ts |    97.2 |    94.05 |     100 |    97.2 | ...39-340,378-381 
  cronScheduler.ts |   94.17 |    90.45 |      98 |   94.17 | ...1333,1736-1737 
  cronTasksFile.ts |   95.49 |    90.82 |     100 |   95.49 | ...37,346-347,483 
  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 |   93.15 |    85.71 |   94.11 |   93.15 | ...37-441,467-474 
  ...ratedFiles.ts |      96 |    88.23 |     100 |      96 | 119-120,146-147   
  gitInit.ts       |     100 |      100 |     100 |     100 |                   
  ...reeService.ts |    73.7 |    68.49 |   95.83 |    73.7 | ...2196,2225-2226 
  ...on-service.ts |   87.38 |       72 |     100 |   87.38 | ...01-305,343-344 
  ...references.ts |   98.39 |    88.76 |     100 |   98.39 | 154-155,215-216   
  ...ionService.ts |   98.22 |    97.34 |     100 |   98.22 | ...75-676,723-724 
  ...ticsDumper.ts |   98.37 |    95.23 |     100 |   98.37 | 185-186           
  ...ureMonitor.ts |   95.82 |    90.52 |   97.05 |   95.82 | ...60,861,875-877 
  ...orRegistry.ts |    97.3 |    91.22 |     100 |    97.3 | ...53-454,611-612 
  ...ttachments.ts |   97.74 |     90.8 |     100 |   97.74 | 298-308,646       
  ...ersistence.ts |   90.95 |    78.75 |     100 |   90.95 | ...78,963-964,992 
  ...on-service.ts |   94.49 |    92.26 |   97.14 |   94.49 | ...98-600,656-664 
  ...ce-service.ts |   98.38 |    93.75 |   88.88 |   98.38 | 63-64             
  ...ipt-reader.ts |   94.51 |    89.14 |      98 |   94.51 | ...1102-1103,1167 
  ...est-helper.ts |       0 |        0 |       0 |       0 | 1-65              
  ...iter-lease.ts |   82.81 |    74.08 |    97.5 |   82.81 | ...2364,2376-2379 
  sessionRecap.ts  |   67.56 |    43.47 |     100 |   67.56 | ...60,178,180-183 
  ...ionService.ts |   88.94 |    83.69 |   97.14 |   88.94 | ...2450,2520-2540 
  sessionTitle.ts  |   94.19 |    73.21 |     100 |   94.19 | ...43-246,277-278 
  ...ionService.ts |   84.35 |    78.37 |   97.14 |   84.35 | ...2472,2478-2483 
  ...pInhibitor.ts |   97.42 |    92.77 |     100 |   97.42 | ...30,169,369-370 
  ...Estimation.ts |     100 |    88.23 |     100 |     100 | 118-119           
  ...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 |   90.72 |    84.07 |     100 |   90.72 | ...06-509,561-562 
  ...reeCleanup.ts |   14.42 |      100 |   33.33 |   14.42 | 58-186            
  ...ionService.ts |   87.98 |    86.95 |     100 |   87.98 | ...38-439,455-456 
 ...icrocompaction |   99.41 |    96.55 |     100 |   99.41 |                   
  microcompact.ts  |   99.41 |    96.55 |     100 |   99.41 | 244-245,677       
 ...s/visionBridge |   98.81 |    92.12 |     100 |   98.81 |                   
  ...capability.ts |     100 |      100 |     100 |     100 |                   
  ...part-utils.ts |     100 |      100 |     100 |     100 |                   
  ...ion-bridge.ts |   98.72 |    82.35 |     100 |   98.72 | 65,71             
  ...-constants.ts |     100 |      100 |     100 |     100 |                   
  ...ge-service.ts |   98.61 |     94.7 |     100 |   98.61 | ...06,666,679-680 
 src/skills        |   88.52 |     87.7 |   90.47 |   88.52 |                   
  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 |   84.07 |    83.67 |   83.33 |   84.07 | ...1233,1240-1244 
  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     |   87.72 |    89.01 |   96.55 |   87.72 |                   
  ...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 |   84.48 |    85.91 |   94.87 |   84.48 | ...1582,1659-1660 
  types.ts         |     100 |      100 |     100 |     100 |                   
  validation.ts    |   92.46 |    95.18 |     100 |   92.46 | 47-52,63-68,71-76 
 src/telemetry     |   81.07 |    83.99 |   84.47 |   81.07 |                   
  ...ty-tracker.ts |     100 |      100 |     100 |     100 |                   
  config.ts        |     100 |      100 |     100 |     100 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  ...on-metrics.ts |   99.07 |    80.95 |     100 |   99.07 | 183,197           
  ...on-tracing.ts |   76.31 |    74.62 |   73.68 |   76.31 | ...80,387-389,405 
  ...attributes.ts |   95.15 |    87.27 |     100 |   95.15 | ...97-198,216-217 
  ...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 
  ...ai-content.ts |    74.5 |    66.41 |   91.66 |    74.5 | ...1480,1493-1502 
  ...i-provider.ts |     100 |       99 |     100 |     100 | 99                
  ...ai-request.ts |   87.52 |    92.79 |   83.78 |   87.52 | ...55-561,564-570 
  gen-ai-usage.ts  |     100 |      100 |     100 |     100 |                   
  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       |   56.85 |    74.35 |   64.81 |   56.85 | ...1397,1414-1434 
  metrics.ts       |   79.63 |    81.98 |   79.66 |   79.63 | ...1082,1085-1096 
  otlp-urls.ts     |     100 |      100 |     100 |     100 |                   
  ...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       
  ...rters-grpc.ts |     100 |      100 |     100 |     100 |                   
  ...rters-http.ts |     100 |      100 |     100 |     100 |                   
  sdk-impl.ts      |   91.06 |    87.15 |   68.75 |   91.06 | ...32,478-479,495 
  sdk.ts           |   79.22 |    89.18 |   63.63 |   79.22 | ...57-161,199-221 
  ...on-context.ts |     100 |      100 |     100 |     100 |                   
  ...on-tracing.ts |   90.83 |    90.05 |   96.77 |   90.83 | ...1667,1698-1701 
  ...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         |   82.35 |    94.61 |   86.04 |   82.35 | ...1361,1365-1372 
  uiTelemetry.ts   |   97.18 |    93.93 |      88 |   97.18 | ...70,314,461-462 
 ...ry/qwen-logger |   74.17 |    80.35 |      70 |   74.17 |                   
  event-types.ts   |       0 |        0 |       0 |       0 |                   
  qwen-logger.ts   |   74.17 |    80.18 |   69.49 |   74.17 | ...1120,1158-1159 
 src/test-utils    |      94 |    98.24 |   78.94 |      94 |                   
  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.57 |      100 |   75.75 |   92.57 | ...63,227-228,241 
  ...aceContext.ts |     100 |      100 |     100 |     100 |                   
 src/tools         |   85.94 |    84.71 |   88.32 |   85.94 |                   
  ...erQuestion.ts |   89.71 |    80.76 |   91.66 |   89.71 | ...66-367,374-375 
  ...-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 |      85 |     82.6 |    87.5 |      85 | ...28-133,161-175 
  exit-worktree.ts |   83.29 |    83.65 |   94.44 |   83.29 | ...14-515,537-538 
  exitPlanMode.ts  |      95 |    85.29 |     100 |      95 | ...21-325,344,378 
  ...permission.ts |     100 |      100 |     100 |     100 |                   
  glob.ts          |   96.33 |     88.5 |     100 |   96.33 | ...24-225,373,376 
  grep.ts          |   90.73 |    86.61 |   85.71 |   90.73 | ...76-677,727-728 
  ...adTracking.ts |     100 |      100 |     100 |     100 |                   
  image-gen.ts     |   91.66 |    77.41 |    90.9 |   91.66 | ...13-214,221-222 
  list-agents.ts   |   94.02 |    82.35 |   83.33 |   94.02 | 31-32,47-48       
  loop-wakeup.ts   |   99.27 |    92.85 |     100 |   99.27 | 45                
  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.49 |     80.1 |   85.71 |   81.49 | ...3217,3219-3220 
  mcp-client.ts    |   79.87 |    85.58 |   89.47 |   79.87 | ...2259,2263-2266 
  ...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      |    97.2 |    93.47 |     100 |    97.2 | ...00-801,856-857 
  ...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.74 |    84.28 |   88.46 |   91.74 | ...93,606,804-809 
  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 |    90.24 |     100 |   82.57 | 174-185,234-247   
  read-file.ts     |   95.49 |    88.52 |   86.66 |   95.49 | ...49,464,536-537 
  ...p-resource.ts |   96.85 |      100 |   91.66 |   96.85 | 92-96             
  ...d-artifact.ts |   91.18 |    86.71 |    87.5 |   91.18 | ...26-427,441-453 
  ripGrep.ts       |    94.6 |    87.26 |   95.23 |    94.6 | ...33-734,740-741 
  ...-transport.ts |   71.42 |    55.55 |   71.42 |   71.42 | ...36-137,143-144 
  send-message.ts  |   81.13 |    89.74 |    62.5 |   81.13 | ...80-286,363-371 
  ...n-mcp-view.ts |   93.57 |     92.3 |      90 |   93.57 | 122-130           
  shell.ts         |   78.78 |    84.06 |   91.91 |   78.78 | ...5019,5082-5083 
  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     |   94.36 |    84.61 |   92.85 |   94.36 | ...10-415,437-438 
  tool-error.ts    |     100 |      100 |     100 |     100 |                   
  tool-names.ts    |     100 |      100 |     100 |     100 |                   
  tool-registry.ts |   78.57 |    79.59 |    82.6 |   78.57 | ...89-990,998-999 
  tool-search.ts   |   96.19 |    89.72 |   93.33 |   96.19 | ...09,259-264,426 
  tools.ts         |   92.74 |    91.52 |    91.3 |   92.74 | ...63-564,580-586 
  ...reapproved.ts |   99.27 |    94.11 |     100 |   99.27 | 170               
  web-fetch.ts     |   96.05 |    90.54 |   96.77 |   96.05 | ...85-786,800-801 
  web-search.ts    |   90.53 |    83.57 |      80 |   90.53 | ...1007,1065-1068 
  write-file.ts    |    86.7 |    84.92 |   88.88 |    86.7 | ...24-827,864-899 
  zoom-image.ts    |   95.76 |    93.75 |      90 |   95.76 | 54-59,203-204     
 src/tools/agent   |   86.03 |    86.11 |   87.85 |   86.03 |                   
  agent.ts         |   85.28 |     85.8 |   86.31 |   85.28 | ...4246,4268-4278 
  fork-subagent.ts |   99.36 |    90.69 |     100 |   99.36 | 91                
 ...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 |   83.95 |    83.05 |   73.33 |   83.95 |                   
  workflow.ts      |   83.95 |    83.05 |   73.33 |   83.95 | ...11,456,458-459 
 src/utils         |   92.83 |    89.58 |   96.84 |   92.83 |                   
  LruCache.ts      |     100 |      100 |     100 |     100 |                   
  ...Controller.ts |     100 |      100 |     100 |     100 |                   
  ...ssageQueue.ts |     100 |      100 |     100 |     100 |                   
  ...cFileWrite.ts |   94.94 |    92.47 |     100 |   94.94 | ...43-544,651-655 
  bareMode.ts      |   81.81 |      100 |      50 |   81.81 | 18-19             
  ...ry-content.ts |   98.45 |    95.45 |     100 |   98.45 | 132-133,159-160   
  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.06 |    89.47 |     100 |   91.06 | ...46-147,154-155 
  ...n-branches.ts |   95.81 |    93.95 |      95 |   95.81 | ...91-492,504-517 
  ...tion-chain.ts |     100 |      100 |     100 |     100 |                   
  cronDisplay.ts   |     100 |    97.61 |     100 |     100 | 46                
  cronParser.ts    |   95.34 |    93.33 |     100 |   95.34 | 41-42,47-48,70-71 
  debugLogger.ts   |   96.66 |    96.61 |   88.88 |   96.66 | 192-196           
  editHelper.ts    |   93.63 |     83.9 |     100 |   93.63 | ...27-428,462-463 
  editor.ts        |   97.65 |    95.45 |     100 |   97.65 | ...35-336,338-339 
  encoding.ts      |     100 |      100 |     100 |     100 |                   
  env.ts           |     100 |      100 |     100 |     100 |                   
  ...arResolver.ts |   94.28 |    88.88 |     100 |   94.28 | 28-29,125-126     
  ...entContext.ts |   96.63 |    90.13 |   96.66 |   96.63 | ...42,444-445,512 
  errorParsing.ts  |     100 |      100 |     100 |     100 |                   
  ...rReporting.ts |   95.65 |    93.33 |     100 |   95.65 | 37-38             
  errors.ts        |   82.62 |    94.32 |    61.9 |   82.62 | ...62-378,382-388 
  fetch.ts         |   90.68 |    82.51 |     100 |   90.68 | ...72,483-484,503 
  fileUtils.ts     |   94.86 |    92.95 |   96.15 |   94.86 | ...1908,1916-1917 
  forkedAgent.ts   |   92.45 |    82.35 |   93.75 |   92.45 | ...34,642,647-654 
  formatters.ts    |     100 |      100 |     100 |     100 |                   
  ...eUtilities.ts |    92.4 |    86.95 |     100 |    92.4 | ...52-158,168-169 
  ...rStructure.ts |   94.39 |    94.28 |     100 |   94.39 | ...29-132,343-348 
  getPty.ts        |   31.57 |       50 |     100 |   31.57 | 26-38             
  git-branches.ts  |    91.6 |    84.21 |    92.3 |    91.6 | ...90,405-410,570 
  gitDiff.ts       |   95.19 |    81.36 |     100 |   95.19 | ...1073,1419-1420 
  gitDirect.ts     |   98.84 |    94.28 |     100 |   98.84 | 234,318           
  ...noreParser.ts |   94.48 |    93.22 |     100 |   94.48 | ...23-124,158-159 
  gitUtils.ts      |   78.02 |    81.25 |   85.71 |   78.02 | ...22-123,147-198 
  github-prs.ts    |   95.74 |    82.27 |     100 |   95.74 | 216,314-322       
  iconvHelper.ts   |     100 |      100 |     100 |     100 |                   
  ...rePatterns.ts |     100 |      100 |     100 |     100 |                   
  image-view.ts    |   95.12 |    93.33 |     100 |   95.12 | ...68-172,240-244 
  ...ionManager.ts |     100 |     90.9 |     100 |     100 | 27                
  ...lPromptIds.ts |     100 |      100 |     100 |     100 |                   
  ...on-context.ts |     100 |      100 |     100 |     100 |                   
  jsonl-utils.ts   |   95.27 |     93.1 |     100 |   95.27 | ...16-317,359-362 
  ...-detection.ts |     100 |      100 |     100 |     100 |                   
  ...iconv-lite.ts |     100 |      100 |     100 |     100 |                   
  ...simple-git.ts |   96.77 |    91.66 |     100 |   96.77 | 38                
  ...m-headless.ts |      96 |    88.88 |     100 |      96 | 34                
  ...iagnostics.ts |    96.4 |     94.2 |     100 |    96.4 | ...66,293-294,376 
  ...yDiscovery.ts |    92.4 |    89.13 |     100 |    92.4 | ...28,331,522-525 
  ...tProcessor.ts |   94.01 |       90 |     100 |   94.01 | ...47-353,445-446 
  ...Inspectors.ts |     100 |      100 |     100 |     100 |                   
  modelId.ts       |   98.96 |    98.21 |     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 
  osc8.ts          |   54.26 |    64.86 |   83.33 |   54.26 | ...72-195,197-257 
  partUtils.ts     |     100 |    98.64 |     100 |     100 | 211               
  pathReader.ts    |     100 |      100 |     100 |     100 |                   
  paths.ts         |   93.95 |    92.79 |     100 |   93.95 | ...78-479,481-483 
  pdf.ts           |   92.17 |    85.81 |     100 |   92.17 | ...64-565,606-611 
  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 |   71.15 |       86 |     100 |   71.15 | ...-90,96-101,147 
  ...noreParser.ts |   92.63 |    91.66 |     100 |   92.63 | ...77-178,197-198 
  rateLimit.ts     |   93.75 |    89.62 |     100 |   93.75 | ...13,218-219,262 
  ...text-range.ts |    96.9 |     86.2 |     100 |    96.9 | ...59-660,735-736 
  readManyFiles.ts |   95.75 |    80.86 |     100 |   95.75 | ...05,558,568-572 
  retry.ts         |   96.09 |    92.52 |     100 |   96.09 | ...67,558-559,577 
  retryContext.ts  |     100 |      100 |     100 |     100 |                   
  ...sification.ts |   97.63 |    97.02 |     100 |   97.63 | ...17,251-252,278 
  retryPolicy.ts   |   97.72 |    90.56 |     100 |   97.72 | 130-131           
  ripgrepUtils.ts  |   90.04 |    93.43 |   95.45 |   90.04 | ...55-565,598-599 
  ...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 |   84.87 |    86.61 |   96.29 |   84.87 | ...71,696,725-734 
  ...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 |     100 |      100 |     100 |     100 |                   
  ...nStringify.ts |     100 |      100 |     100 |     100 |                   
  ...-child-env.ts |     100 |      100 |     100 |     100 |                   
  ...aConverter.ts |   98.03 |    97.75 |     100 |   98.03 | 100,102-103       
  ...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.78 |    92.18 |     100 |   91.78 | ...66-569,645-646 
  ...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 |                   
  ...fety-rules.ts |     100 |     89.7 |     100 |     100 | ...01,304,309-311 
  shell-utils.ts   |   86.07 |    88.34 |     100 |   86.07 | ...2269,2276-2280 
  ...lAstParser.ts |   98.16 |    91.91 |     100 |   98.16 | ...1244-1246,1256 
  ...ContextEnv.ts |     100 |       92 |     100 |     100 | 50-52             
  ...nlyChecker.ts |   96.33 |    96.57 |     100 |   96.33 | ...83-284,292-293 
  sideQuery.ts     |   86.82 |    86.66 |     100 |   86.82 | ...79-185,187-193 
  ...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          
  ...e-encoding.ts |   85.96 |    76.47 |     100 |   85.96 | 58-61,64-65,78-79 
  ...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             
  ...name-utils.ts |     100 |      100 |     100 |     100 |                   
  ...-finalizer.ts |   97.66 |     90.9 |     100 |   97.66 | 165-166,168-172   
  tool-utils.ts    |    95.2 |    93.61 |     100 |    95.2 | ...58-159,162-163 
  ...ultCleanup.ts |   54.62 |    30.76 |      75 |   54.62 | ...03-105,108-134 
  ...Compaction.ts |   96.13 |    96.42 |     100 |   96.13 | ...34-339,341-346 
  ...pt-records.ts |   85.85 |    83.63 |     100 |   85.85 | ...90-394,424-439 
  truncation.ts    |   90.56 |    90.43 |     100 |   90.56 | ...35-443,480-486 
  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.76 |    75.47 |   85.29 |   69.76 |                   
  ...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.

Copy link
Copy Markdown
Collaborator Author

tmux UI verification

Tested the built CLI (Qwen Code v0.19.12) from this PR's worktree.

Case Result
Standard absolute image reference (@/absolute/path/icon-128.png) PASS — TUI rendered the Read file icon-128.png card
Vision-capable route PASS — an isolated local OpenAI-compatible vision endpoint received exactly one image in the main request (images=1)
Existing text-only model configuration PASS — the same absolute path was recognized as an image/read turn; no usable external vision credential was available, so the model-side fallback was cancelled after path/routing verification
User configuration isolation PASS — the deterministic visual endpoint used a temporary QWEN_HOME; the user's normal settings were not modified

The local provider was used to inspect the exact outbound request shape without relying on external credentials.

Copy link
Copy Markdown
Collaborator Author

CI follow-up

The first repository-wide run exposed an incomplete Config mock in Session.worktree.test.ts (getFileFilteringOptions was missing). This was a test-fixture failure, not a production assertion failure.

  • Fixed in follow-up commit fc1e902
  • Focused worktree suite: 5/5 passed
  • Session.test.ts + Session.worktree.test.ts: 375/375 passed
  • ESLint and Prettier: passed
  • Two independent local review passes: clean

A fresh Qwen Code CI run was started from the updated head and remains running; it was not cancelled.

@yiliang114
yiliang114 marked this pull request as ready for review July 19, 2026 07:52

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

Thanks for the PR, @yiliang114!

The PR body doesn't follow the pull request template. Several required sections are missing:

  • What this PR does and Why it's needed — the body uses "Summary" and "Validation" instead
  • Reviewer Test Plan (How to verify, Evidence before/after, Tested on OS table)
  • Risk & Scope
  • Linked Issues (with proper References #N or Fixes #N keyword — currently only mentioned as a note)
  • 中文说明 <details> section

Could you update the PR body to match the template? It helps reviewers understand the motivation, verify the change, and assess risk.

中文说明

感谢 PR,@yiliang114

PR 描述没有按照 PR 模板 填写,缺少以下必填部分:

  • What this PR doesWhy it's needed — 目前用的是 "Summary" 和 "Validation"
  • Reviewer Test Plan(验证方法、Before/After 证据、测试平台表格)
  • Risk & Scope
  • Linked Issues(用 References #NFixes #N 关联 issue)
  • 中文说明 <details> 部分

请按模板更新 PR 描述,方便 reviewer 理解动机、验证变更和评估风险。

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.

Reviewed — no blockers. Suggestions are inline.

— qwen3.7-max via Qwen Code /review

Comment thread packages/cli/src/acp-integration/session/Session.ts Outdated
Comment thread packages/cli/src/ui/hooks/atCommandProcessor.ts
Comment thread packages/core/src/utils/readManyFiles.ts
Comment thread packages/cli/src/ui/hooks/atCommandProcessor.ts
@yiliang114

Copy link
Copy Markdown
Collaborator Author

本轮按 review feedback 做了最小修复:ACP resource_link file URI 现在和文本 @ 图片路径共用 workspace/ignore/identity revalidation;at-command canonical revalidation 补齐 configured temp dir 判断并为 fail-closed drop 输出 debug;validated snapshot 读取时错误/unsupported 文案继续使用原始 display path。验证:focused Session / atCommandProcessor / readManyFiles tests 通过,core typecheck 通过,Prettier check 和 git diff --check 通过。CLI typecheck 在临时 worktree 仍被未构建 sibling packages/既有类型问题阻塞,未作为本轮验证证据。

@yiliang114
yiliang114 marked this pull request as draft July 19, 2026 11:15
Comment thread packages/cli/src/acp-integration/session/Session.ts
Comment thread packages/cli/src/acp-integration/session/Session.ts
Comment thread packages/cli/src/acp-integration/session/Session.ts Outdated
Comment thread packages/cli/src/ui/hooks/atCommandProcessor.ts
Comment thread packages/cli/src/ui/hooks/atCommandProcessor.ts
Comment thread packages/core/src/utils/fileUtils.ts Outdated
Comment thread packages/core/src/utils/readManyFiles.ts
Comment thread packages/cli/src/nonInteractiveCli.ts
Comment thread packages/cli/src/nonInteractiveCli.ts
@wenshao

wenshao commented Jul 26, 2026

Copy link
Copy Markdown
Collaborator

@qwen-code /resolve

@qwen-code-dev-bot

Copy link
Copy Markdown
Collaborator

Qwen Code did not run conflict resolution for this request.

PR #7206 is draft.

yiliang114 and others added 3 commits July 29, 2026 15:36
resolve local image @ references consistently in TUI, ACP, and non-interactive entry points
validate aliases and canonical targets against workspace, ignore, MIME, and file-identity boundaries
route image turns through the full-turn agent or vision bridge while failing closed on unsupported/fallback paths
integrate with tool-result vision bridge from #7484: @ image routing and tool-result image routing coexist with \0 suffix priority convention

Refs #6988
@yiliang114
yiliang114 force-pushed the cx/6988-routing-completion branch from 4df535b to 070fc38 Compare July 29, 2026 07:38
@yiliang114
yiliang114 marked this pull request as ready for review July 29, 2026 07:38
@qwen-code-ci-bot

qwen-code-ci-bot commented Jul 29, 2026

Copy link
Copy Markdown
Collaborator

Qwen Triage finishedview run. See the stage comments in this thread for the result.

Qwen Triage 已完成 —— 查看运行。结果见本线程中的各阶段评论。

@github-actions

Copy link
Copy Markdown
Contributor

Please do not rebase or force-push to an active PR as it invalidates existing review comments. Note for future reference, the bots always squash all changes into a single commit automatically as part of the integration.

中文

请勿对活跃的 PR 执行 rebase 或 force-push,因为这会使已有的评审评论失效。另外,供日后参考:作为集成流程的一部分,机器人始终会自动将所有改动压缩(squash)为单个提交。

@qwen-code-ci-bot

qwen-code-ci-bot commented Jul 29, 2026

Copy link
Copy Markdown
Collaborator

Thanks for the PR — re-running on the current head cae7925 (the branch was rebased onto a much newer main and the diff grew since the last pass, so this is a fresh review, not a rubber stamp).

Template looks good ✓

Problem: real and evidenced. The design doc (docs/design/full-turn-multimodal-routing.md) explicitly deferred non-interactive routing in Phase 1, and #6988 tracks the full-turn multimodal handoff. This PR completes that entry point and retrofits symlink/TOCTOU/MIME validation across all three paths. Not theoretical hardening — an @ image reference reads an arbitrary file, so symlink escape and TOCTOU are a genuine attack surface here.

Direction: aligned. Completing routing the design doc already planned and tightening file-read validation is squarely in scope. (Minor: the title says fix(cli): but this is feature completion plus cross-path security hardening — feat would describe it better. Doesn't change the review path.)

Size: touches core (readManyFiles.ts, fileUtils.ts, nonInteractiveToolExecutor.ts, fileSystemService.ts) and CLI — 855 production-logic lines (up from ~672 at the last review) against 1712 test lines. The author has admin/write access, so the core-module two-tier gate (which applies to non-maintainer PRs only) does not escalate here; reporting the breakdown for transparency. Above the 500-line mark, so it's worth a maintainer's eye, but not blocked on size.

Approach: the scope holds together — the new non-interactive and ACP paths need the same validation the TUI already has, and the displayPath threading is a natural consequence of canonicalizing paths. One non-blocking observation carried over from last time: this bundles (a) completing non-interactive/ACP routing with (b) retrofitting symlink/TOCTOU hardening onto the already-working TUI path. Those could have been two PRs and would be easier to revert independently; worth keeping in mind if a regression surfaces.

Risk: ⚠️ packages/cli/src/acp-integration/session/Session.ts matches this repo's revert-history high-risk paths. Not a gate stopper, but it raises the review bar — full CI evidence required, and a sandboxed lane named before merge (see Stage 2).

Code reads clean and the test coverage is substantial. Moving on to code review. 🔍

中文说明

感谢贡献 —— 本次在当前 head cae7925 上重新运行(分支已 rebase 到更新的 main,diff 较上次审查增大,因此这是全新审查而非走过场)。

模板完整 ✓

问题:真实且有据。设计文档明确在 Phase 1 推迟了非交互式路由,#6988 跟踪 full-turn 多模态交接。本 PR 补全该入口,并在三条路径上回溯加固 symlink/TOCTOU/MIME 校验。不是理论加固——@ 图片引用会读取任意文件,symlink 逃逸与 TOCTOU 在此是真实攻击面。

方向:对齐。补全设计文档已规划的路由、收紧文件读取校验,完全在职责范围内。(小问题:标题是 fix(cli):,但实质是功能补全加跨路径安全加固,用 feat 更贴切,不影响审查路径。)

规模:触及 core(readManyFiles.tsfileUtils.tsnonInteractiveToolExecutor.tsfileSystemService.ts)与 CLI——855 行生产逻辑(较上次约 672 行增加),另有 1712 行测试。作者拥有 admin/write 权限,因此(仅适用于非维护者 PR 的)core 两级门禁不在此升级;仅透明地报告拆分。超过 500 行,值得维护者过目,但不因规模阻断。

方案:范围自洽——新的非交互与 ACP 路径需要与 TUI 相同的校验,displayPath 透传是路径规范化的自然结果。沿用上次的非阻断观察:本 PR 把 (a) 补全非交互/ACP 路由 与 (b) 给已可用的 TUI 路径回溯加固 symlink/TOCTOU 捆在一起。本可拆成两个 PR,独立回滚更容易;若出现回归值得留意。

风险:⚠️ packages/cli/src/acp-integration/session/Session.ts 命中仓库回滚历史中的高风险路径。不是门禁终点,但提高了审查标准——需要完整 CI 证据,且合并前需指定沙箱验证通道(见 Stage 2)。

代码读起来干净、测试充分。进入代码审查。🔍

Qwen Code · qwen3.8-max-preview

Reviewed at cae7925efb4faa174cc02216dfbabe6437b4ffb1 · re-run with @qwen-code /triage

@qwen-code-ci-bot

qwen-code-ci-bot commented Jul 29, 2026

Copy link
Copy Markdown
Collaborator

Code review

Independent proposal first (before reading the diff): given "non-interactive CLI and ACP don't route image turns like the TUI, and validation is missing," I would extract the TUI's existing vision-routing and file-validation into shared core helpers, call them from all three entry points, and close TOCTOU by canonicalizing with realpath, re-checking workspace/ignore on the canonical target, pinning {dev, ino}, and reading through an O_NOFOLLOW handle so a swapped symlink can't enter model context.

The PR matches that and goes a bit further. The non-interactive path reuses the same core helpers the TUI uses (shouldRunVisionBridge, runVisionBridge, getFullTurnVisionModelSelector, clampInlineMediaPart, splitImageParts, hasImageParts) rather than forking a parallel implementation — exactly the reuse I'd want. Validation lives in core (readManyFiles) with caller-side canonicalization in atCommandProcessor.ts (TUI) and Session.ts (ACP).

I walked the security path line by line and found it sound, with fail-closed behaviour at every branch:

  • matchesValidatedPathIdentity rejects when realpath(path) !== path (any symlink anywhere in the chain) and on dev/ino mismatch.
  • readManyFiles skips any path absent from the identity map when a map is supplied — an unvalidated path never reaches the reader.
  • Reads open with O_NOFOLLOW and verify dev/ino on the open fd, then read positionally from that pinned fd (or snapshot-copy it), so a path swap after open can't affect the bytes. A growth probe after the copy detects concurrent append and drops the file.
  • readTextFileFromHandle does not close the handle, so the caller's single finally { source.close() } is correct (I checked for a double-close — there isn't one). The getRangeReadByteLimit change from Infinity to MAX_SAFE_INTEGER is required, not churn: the handle path rejects non-finite bounds.
  • ACP adds a partsToSend filter that drops a rejected image from the outgoing parts entirely, so a file that fails revalidation can't leak through as a raw fileData attachment — a bypass specific to that entry point, correctly closed.

No critical blockers and no convention violations. Two non-blocking nits:

  • O_NOFOLLOW ?? 0 falls back to 0 on Windows, and the symlink tests are skipIf(win32) — so the protection is effectively POSIX-only. The PR flags Windows/Linux as untested; acceptable, but worth a follow-up.
  • fix(cli): understates a feature-completion + security-hardening change.
sequenceDiagram
    participant P1 as User prompt
    participant P2 as Resolver (atCommandProcessor or Session)
    participant P3 as readManyFiles
    participant P4 as File handle (O_NOFOLLOW)
    P1->>P2: at reference to image
    P2->>P2: realpath then workspace and ignore check on canonical target
    P2->>P2: revalidate and capture dev and ino identity
    P2->>P3: canonical path plus identity plus display alias
    P3->>P4: open with O_NOFOLLOW and verify dev and ino
    P4-->>P3: positional read or snapshot copy then growth probe
    P3-->>P2: accept or drop fail-closed on any mismatch
Loading

Test evidence (the PR's own CI at cae7925)

All check-runs on the head SHA completed with no failures — 17 success, 51 skipped (matrix + bot orchestration). The gating Linux unit suite is green; Windows/macOS/integration are matrix-skipped, which is normal for PRs here. I did not run the PR's code myself — this is the PR's own CI read via the API.

Check Conclusion
Test (ubuntu-latest, Node 22.x) ✅ success
web-shell E2E Smoke (ubuntu-latest, Node 22.x) ✅ success
Post Coverage Comment (ubuntu-latest, 22.x) ✅ success
Qwen Code CI (workflow) ✅ success
Test (windows-latest, Node 22.x) ⏭️ skipped (matrix)
Test (macos-latest, Node 22.x) ⏭️ skipped (matrix)
Integration Tests (CLI, No Sandbox) ⏭️ skipped

Sandboxed verification would still pin the behavioural claim: @qwen-code /verify — that a non-interactive @/abs/image.png reference actually yields one outbound image payload and that a workspace-escaping symlink is dropped is not observable from the diff, and the suite would still pass with the routing removed. @qwen-code /tmux would cover the TUI/ACP surface the same way. The author has write access so both lanes are available; given the high-risk acp-integration path and the POSIX-only O_NOFOLLOW fallback, I'd like at least one run before merge — but for a maintainer-authored PR with this coverage I'm not treating it as a hard block.

中文说明

代码审查

先独立给出方案(读 diff 之前):鉴于"非交互 CLI 与 ACP 不像 TUI 那样路由图片轮次、且缺少校验",我会把 TUI 现有的视觉路由与文件校验抽成共享 core 辅助函数,在三个入口调用,并通过 realpath 规范化、对规范目标复查 workspace/ignore、固定 {dev, ino}、再经 O_NOFOLLOW 句柄读取来关闭 TOCTOU,使被替换的 symlink 无法进入模型上下文。

本 PR 与此一致并更进一步。非交互路径复用 TUI 使用的同一批 core 辅助函数(shouldRunVisionBridgerunVisionBridgegetFullTurnVisionModelSelectorclampInlineMediaPartsplitImagePartshasImageParts),而非另起平行实现——正是我想要的复用。校验落在 core(readManyFiles),调用侧规范化分别在 atCommandProcessor.ts(TUI)与 Session.ts(ACP)。

我逐行走了安全路径,认为其健全,且每个分支都 fail-closed:

  • matchesValidatedPathIdentityrealpath(path) !== path(链路上任意 symlink)或 dev/ino 不符时拒绝。
  • readManyFiles 在提供身份映射时跳过映射中不存在的任何路径——未校验路径永远到不了读取器。
  • 读取以 O_NOFOLLOW 打开,在已打开的 fd 上校验 dev/ino,再从该固定 fd 按位置读取(或快照拷贝),因此打开后的路径替换无法影响读到的字节。拷贝后的增长探针检测并发追加并丢弃该文件。
  • readTextFileFromHandle 关闭句柄,因此调用方唯一的 finally { source.close() } 正确(我查过双重关闭——不存在)。getRangeReadByteLimitInfinity 改为 MAX_SAFE_INTEGER 是必需而非顺手改动:句柄路径拒绝非有限边界。
  • ACP 增加 partsToSend 过滤,把被拒绝的图片从出站 parts 中彻底移除,因此校验失败的文件无法作为原始 fileData 附件泄漏——这是该入口特有的旁路,已正确关闭。

无关键阻断,无规范违规。两个非阻断提示:

  • O_NOFOLLOW ?? 0 在 Windows 回退为 0,symlink 测试 skipIf(win32)——保护实际仅限 POSIX。PR 已标注 Windows/Linux 未测;可接受,但值得后续跟进。
  • fix(cli): 低估了这项功能补全加安全加固的改动。

时序图展示校验主路径:别名经 realpath 规范化,对规范目标做 workspace 与 ignore 检查,复查并捕获 dev/ino 身份,读取时以 O_NOFOLLOW 打开并校验身份,按位置读取或快照拷贝后做增长探针,最终要么接受要么 fail-closed 丢弃。

测试证据(PR 自身在 cae7925 的 CI)

head SHA 上所有 check-run 完成且无失败——17 成功、51 跳过(矩阵与 bot 编排)。门禁项 Linux 单元套件绿;Windows/macOS/集成为矩阵跳过,属本仓库 PR 常态。我未自行运行 PR 代码——以上为通过 API 读取的 PR 自身 CI。

沙箱验证仍可固定行为性声明:@qwen-code /verify——非交互 @/abs/image.png 引用是否真产生一个出站图片 payload、逃逸工作区的 symlink 是否被丢弃,从 diff 看不出来,且即便移除路由该套件仍会通过。@qwen-code /tmux 可同样覆盖 TUI 与 ACP 面。作者有写权限,两条通道都可用;鉴于高风险 acp-integration 路径与仅 POSIX 的 O_NOFOLLOW 回退,我希望合并前至少跑一条——但对一个有如此覆盖度的维护者 PR,我不将其视为硬阻断。

Qwen Code · qwen3.8-max-preview

Reviewed at cae7925efb4faa174cc02216dfbabe6437b4ffb1 · re-run with @qwen-code /triage

@qwen-code-ci-bot

qwen-code-ci-bot commented Jul 29, 2026

Copy link
Copy Markdown
Collaborator

Confidence: 4/5 — clean review across every stage and green CI; the only reservations are non-blocking (POSIX-only symlink protection, and a behavioural claim best pinned by a sandboxed run).

Stepping back: this is good work and I'd merge it. The motivation is real (the design doc explicitly deferred non-interactive routing; #6988 tracks it), the implementation matches my independent proposal and exceeds it, and the security handling — canonical-path validation on both alias and target, dev/ino identity rechecks, O_NOFOLLOW snapshot reads, a growth probe, fail-closed on every mismatch — is exactly what this kind of file-read hardening should look like. CI is green on the head SHA, and 1712 test lines cover the new paths. In six months I'd thank the author, not curse them.

One correction to my previous pass: I had capped this at 3/5 and deferred, treating the ~855 core lines as a Stage 0 maintainer-awareness escalation. That gate applies to non-maintainer PRs only, and @yiliang114 has admin/write access on this repo — so the escalation (and the cap it drove) doesn't apply here. The high-risk acp-integration path still earns a named sandboxed lane, but it isn't a gate stopper for a maintainer-authored change, and on a re-run non-blocking hygiene isn't a reason to defer.

So: approving. The two nits to carry forward — O_NOFOLLOW ?? 0 makes the symlink/TOCTOU protection POSIX-only (Windows/Linux untested), and fix(cli): undersells a feature-completion + hardening change. Neither blocks merge; I'd still encourage a @qwen-code /verify or @qwen-code /tmux run to pin the routing behaviour on a real surface before this lands.

中文说明

置信度:4/5 —— 各阶段审查干净、CI 绿;唯一保留是非阻断性的(symlink 保护仅限 POSIX,以及一个最好用沙箱运行来固定的行为性声明)。

退一步看:这是好工作,我会合并。动机真实(设计文档明确推迟非交互路由,#6988 跟踪),实现与我的独立方案一致并更优,安全处理——对别名与目标都做规范路径校验、dev/ino 身份复查、O_NOFOLLOW 快照读取、增长探针、全程 fail-closed——正是这类文件读取加固应有的样子。head SHA 上 CI 绿,1712 行测试覆盖新路径。半年后维护它我会感谢作者,而非埋怨。

对上一次审查的一处更正:我之前把它限制在 3/5 并转交维护者,是把约 855 行 core 改动当作 Stage 0 维护者关注升级。该门禁仅适用于非维护者 PR,而 @yiliang114 在本仓库拥有 admin/write 权限——因此该升级(及其导致的上限)在此不适用。高风险 acp-integration 路径仍值得指定沙箱通道,但对维护者改动不是门禁终点;且 re-run 时非阻断的卫生问题不构成转交理由。

因此:批准。需带往前的两个提示——O_NOFOLLOW ?? 0 使 symlink/TOCTOU 保护仅限 POSIX(Windows/Linux 未测),以及 fix(cli): 低估了这项功能补全加加固的改动。两者都不阻断合并;我仍鼓励合并前跑一次 @qwen-code /verify@qwen-code /tmux,在真实界面上固定路由行为。

Qwen Code · qwen3.8-max-preview

Reviewed at cae7925efb4faa174cc02216dfbabe6437b4ffb1 · re-run with @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.

Not reviewed: build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and the local build failed (TS2352) before any test suite could run.

— qwen3.8-max-preview via Qwen Code /review

Comment thread packages/core/src/utils/readManyFiles.test.ts Outdated
@yiliang114

Copy link
Copy Markdown
Collaborator Author

@qwen-code /takeover

@qwen-code-dev-bot qwen-code-dev-bot added the autofix/takeover Summon the autofix loop to manage this PR (remove to release; needs triage+) label Jul 29, 2026
@yiliang114 yiliang114 added the autofix/takeover Summon the autofix loop to manage this PR (remove to release; needs triage+) label Jul 31, 2026
@yiliang114

Copy link
Copy Markdown
Collaborator Author

Resolved the current review round.

  • Fixed validated text reads when truncation is disabled by translating the unbounded character setting to a finite safe-integer byte budget. This keeps reads bound to the approved file handle and avoids the 100 MB snapshot rejection without weakening the TOCTOU boundary.
  • Verified the full readManyFiles suite (42 tests), 63 focused fileUtils tests, Prettier, ESLint, and git diff checks.
  • Did not add ACP positive-symlink coverage: it is useful future regression coverage, but no current defect was found and this PR is already beyond the repository's review-round limit for non-Critical additions.
中文说明
  • 修复关闭截断时 validated text 错走 snapshot 并在 100 MB 以上被跳过的问题;改为使用有限的安全整数 byte budget,继续绑定已验证 file handle,不放宽 TOCTOU 边界。
  • 已通过 readManyFiles 全量 42 个测试、fileUtils 聚焦 63 个测试、Prettier、ESLint 和 git diff 检查。
  • 未新增 ACP symlink 正向覆盖:它对未来回归有价值,但当前没有实际缺陷,且本 PR 已超过仓库对多轮 review 的非 Critical 改动限制。

@qwen-code-dev-bot

Copy link
Copy Markdown
Collaborator

🤝 Takeover engaged: the autofix loop now manages this PR — it will address new review feedback and resolve base conflicts until the label is removed or the round cap is reached. Remove the autofix/takeover label (or comment @qwen-code /takeover stop) to release.

中文说明

🤝 已接管:autofix 循环现在管理此 PR —— 将持续处理新的评审反馈与 base 冲突,直到移除标签或达到轮次上限。移除 autofix/takeover 标签(或评论 @qwen-code /takeover stop)即可释放。

@qwen-code-dev-bot

Copy link
Copy Markdown
Collaborator

🤖 Reviewed the latest feedback — no changes needed. Why, point by point: · 已审阅最新反馈——无需改动。逐点说明原因如下:

Review round summary — no new changes

All actionable feedback from this round was already addressed by existing commits on the branch. No new code changes were made.

Resolved in code (re-verified this round)

Finding Resolution Commit
[rc:3689610645] Test for different model selector rejection when fullTurnModelOverrideActive is true Test added: calls onToolResultFullTurnModel with 'different-model\0…' and asserts false 3f75d8723
[rc:3690997848] Validated text routed to snapshot path (silently dropped >100 MB) when truncation disabled getRangeReadByteLimit now returns Number.MAX_SAFE_INTEGER instead of Infinity, keeping reads on the handle path 6d9c07401

Informational (maintainer tracking notes, no action required)

Deferred (maintainer decision)

  • [rc:3690997851] Positive ACP symlink test — deferred per @yiliang114: no current defect found, PR is beyond the review-round limit for non-Critical additions. Existing negative ACP cases and the TUI positive case all pass.

Verification

  • vitest run src/nonInteractiveCli.test.ts (packages/cli) — 99 passed, 1 skipped
  • vitest run src/utils/readManyFiles.test.ts (packages/core) — 42 passed
  • vitest run src/acp-integration/session/Session.test.ts (packages/cli) — 470 passed
中文说明

Review 轮次总结 — 无新改动

本轮所有可操作的反馈已由分支上的现有提交解决。未做新的代码改动。

已在代码中解决(本轮重新验证)

发现 解决方式 提交
[rc:3689610645] 当 fullTurnModelOverrideActive 为 true 时,缺少对不同 model selector 被拒绝的测试 已添加测试:用 'different-model\0…' 调用 onToolResultFullTurnModel 并断言返回 false 3f75d8723
[rc:3690997848] 关闭截断时,已校验文本被路由到快照路径(>100 MB 被静默丢弃) getRangeReadByteLimit 现在返回 Number.MAX_SAFE_INTEGER 而非 Infinity,使读取保持在句柄路径 6d9c07401

信息性(维护者跟踪备注,无需操作)

推迟(维护者决定)

  • [rc:3690997851] ACP 符号链接正向测试 — 根据 @yiliang114 的决定推迟:当前未发现实际缺陷,且本 PR 已超过仓库对多轮 review 的非 Critical 改动限制。现有 ACP 负向用例和 TUI 正向用例均通过。

验证

  • vitest run src/nonInteractiveCli.test.ts(packages/cli)— 99 通过,1 跳过
  • vitest run src/utils/readManyFiles.test.ts(packages/core)— 42 通过
  • vitest run src/acp-integration/session/Session.test.ts(packages/cli)— 470 通过

Base-conflict check · 基分支冲突检查: no conflict with main. · 与 main 无冲突。


🧠 Handled by Qwen Code · model/模型 qwen3.8-max-preview

@wenshao

wenshao commented Jul 31, 2026

Copy link
Copy Markdown
Collaborator

Review — 6d9c074 (routing completion)

Reviewed the full diff against base 9a4e924. The three-entry-point routing work itself looks solid, and the 45 resolved threads have clearly moved a lot of real defects. What follows is new: two behaviour regressions in the shared readManyFiles read path that no existing thread covers, both reproduced with a base-vs-head A/B under production default config. Requesting changes on those two.


C1 — Critical: one unreadable @ file silently discards every attached file in the turn

readValidatedTextFileContent opens the descriptor outside any per-file error boundary:

// packages/core/src/utils/readManyFiles.ts:278
const source = await fs.promises.open(
  filePath,
  (fs.constants.O_RDONLY ?? 0) | (fs.constants.O_NOFOLLOW ?? 0),
);

Any failure here — EACCES on a mode-000 / other-user file, ENOENT from a delete race, ELOOP, EMFILE — propagates out of the per-pattern loop into the function-level catch at readManyFiles.ts:249, which throws away every contentPart already collected and returns { contentParts: ['Error during file search: …'], files: [], error }.

atCommandProcessor then loses the error entirely:

  • result.files is []fileDisplays = []no tool card at all, not even an error card;
  • parts.length > 0 && !result.error is false → the else at atCommandProcessor.ts:932 only calls onDebugMessage(...), which is off by default;
  • the function still falls through to the success return: shouldProceed: true, recording: { status: 'success' }, filesRead: allLabels.

So the model receives zero file content, the UI shows nothing, and the session recording claims both files were read successfully.

A/B repro (chmod 000 honoured as root via capsh --drop=cap_dac_override,cap_dac_read_search), query compare @good.txt and @noperm.txt:

base 9a4e924 head 6d9c074
toolDisplays [{Read File, Success}, {Read File, Error, "…EACCES: permission denied…"}] []
GOOD-CONTENT-VISIBLE in prompt yes no
Error during file search in prompt no no
filesRead.length 2 2

The batch-level catch is pre-existing, but before this PR nothing ordinary reached it: processSingleFileContent catches its own I/O errors and returns a per-file error result, so one bad file never affected its siblings. The new unguarded open() is what routes a routine permission error into a whole-turn content wipe.

ACP has the same root cause with a different surface: Session.ts:8846 never inspects readResult.error, so the Error during file search: … string is pushed to the model as a text part and the sibling files' content is silently gone.

Suggested fix — three independent parts, any one of which stops the silent-loss:

  1. wrap readValidatedTextFileContent (or just its open) in a per-file try/catch that degrades to the same per-file error result readFileContent produces;
  2. in readManyFiles, keep already-collected contentParts/files when the loop aborts instead of replacing them;
  3. in atCommandProcessor, surface result.error on a real channel (an error toolDisplay + recording.status = 'error') rather than onDebugMessage.

C2 — Critical: @-referencing a text file > 100 KB with lines longer than ~100 B now errors instead of attaching truncated content

Validated standard-FS text reads now go through readTextFileFromHandle, which requires a finite maxScanBytes, and readManyFiles passes the same value for both budgets:

// fileUtils.ts:1351
maxScanBytes: options.textFileMaxScanBytes ?? maxOutputBytes,   // both = getRangeReadByteLimit(config)

Default config → max(25_000, 25_000 * 4) = 100 000 bytes. readTextRangeFromHandle always streams (no buffered fast path), and readLargeUtf8Range throws TextScanBudgetExceededError when sourceSize > maxScanBytes && scannedBytes >= maxScanBytes and neither endLine nor the byte-truncation flag fired first. The old path-bound readTextFile never passed maxScanBytes at all (so it was Infinity) and took the ≤ 10 MB buffered fast path — it always returned truncated content.

Trigger: size > 100 000 and the first truncateToolOutputLines (1000) lines don't fit in 100 000 bytes, i.e. average line length > ~100 bytes. Minified bundles, single-line JSON, CSV, wide logs, base64 blobs.

A/B with production defaults (truncateToolOutputThreshold: 25000, truncateToolOutputLines: 1000), one @<file> per case:

case file base 9a4e924 head 6d9c074
A 300 KB, single line Success — Showing lines 1-1, ... [truncated] ErrorLocating the requested line window would read more than 100000 bytes
B 300 KB, 300-byte lines Success — Showing lines 1-84 of 1025 Error
D 150 KB minified JS, single line Success Error
E 300 KB, 110-byte lines Success Error
F 300 KB, 90-byte lines Success Success
G 90 KB, single line Success Success

Two things make this worth blocking on:

  1. The regression is encoded into the suite. atCommandProcessor.test.ts's should attach a truncated text file larger than 10MB was renamed to should surface a byte-cap read error for a text file larger than 10MB, and its assertions flipped from ToolCallStatus.Success + ... [truncated] to ToolCallStatus.Error + Locating the requested line window would read more than 25000 bytes. The suite is green (70/70 locally) precisely because the only test that covered this now certifies the new behaviour. Neither the PR body nor any of the 45 threads mentions it.
  2. It also hits ACP resource_links, which now get validatedPathIdentities for any file type — so the JetBrains "attach active editor" flow errors out on a large minified/JSON file that previously attached truncated.

Fix options, in order of preference:

  • decouple the budgets: maxOutputBytes is the truncation control; maxScanBytes should be the file size (or a much larger ceiling) when the requested window starts at line 0, since locating line 0 is trivially free;
  • or catch TextScanBudgetExceededError in readValidatedTextFileContent and fall back to the byte-offset cursor reader / a bounded truncated result;
  • either way, restore the original test assertion as the regression guard.

Notes (non-blocking)

  • N1 — wasted per-file I/O on the ordinary tool path. readManyFiles.ts:190-193 computes getFileSystemService() instanceof …, await detectFileType(fullPath) and getRangeReadByteLimit(config) unconditionally, but all three are consumed only when validatedIdentity is set. On the read_many_files glob path this is a second detectFileType per file (processSingleFileContent calls it again), including a 4 KB content sniff for extensions the mime registry doesn't know. Guarding the block with if (validatedIdentity) removes it.
  • N2 — dead guard. Number.isFinite(textHandleReadByteLimit) (readManyFiles.ts:198) can no longer be false now that getRangeReadByteLimit returns MAX_SAFE_INTEGER. Harmless today, but if the Infinity return ever comes back the silent fallback is the snapshot path plus the > 100 MB drop that thread 3690997848 just closed. Drop the check or assert the invariant.
  • N3 — global helper changed for one caller. getRangeReadByteLimit's Infinity → MAX_SAFE_INTEGER switch also affects the read_file tool. Verified benign (normalizeMaxBytes / truncateUtf8 only compare, never allocate), but the translation belongs at the handle call site rather than in a shared helper.
  • N4 — readFileContent now takes 9 positional parameters with four optional trailing ones, and the single call site has to pass undefined as the 8th. An options object would make this reviewable.
  • N5 — doc claim is broader than the code. docs/design/full-turn-multimodal-routing.md now states "a symlink cannot disguise an ignored file or a non-image target". realpath doesn't resolve hardlinks, so a hardlink to a git-ignored file still passes both the alias and the canonical ignore check. Either scope the sentence to symlinks or note the hardlink gap. (Raised in conversation on 07-29, never opened as a thread.)
  • N6 — sync I/O in the async ACP handler. Session.ts revalidation uses realpathSync / statSync while atCommandProcessor uses fs.promises.*. One workspace's slow mount stalls the shared ACP child's event loop for all of its sessions.
  • N7 — matchesValidatedPathIdentity races itself. Promise.all([realpath(p), stat(p)]) lets the two syscalls observe different states. Sequential realpath then stat on the resolved path (or reusing the open descriptor) closes the window.

What's good

The base-vs-head routing evidence is convincing, and several of the hardening changes are the right shape: the fail-closed validatedPathIdentities key-miss gate, replacing snapshot copies with handle-bound reads for text, partsToSend filtering rejected fileData parts on the early-return paths, the multi-root break → continue fix, and pruneSkippedPath keeping filesRead honest on revalidation failure.

Verdict: request changes — C1 and C2 both change behaviour users depend on today, and C2's only regression guard was rewritten to match the new behaviour.

中文摘要

对照 base 9a4e924 复核了完整 diff。三入口路由本身没问题,已解决的 45 条线程也确实修掉了不少真问题。下面两条是新发现,都在共享的 readManyFiles 读取路径上,现有线程均未覆盖,且都用生产默认配置做了 base/head A/B 实证。

C1(Critical):@ 引用中只要有一个文件读不了,整轮的全部附件内容被静默丢弃。
readValidatedTextFileContent(readManyFiles.ts:278)的 fs.promises.open 不在任何单文件错误边界内,EACCES / 删除竞态的 ENOENT / ELOOP / EMFILE 都会冒泡到 readManyFiles.ts:249 的函数级 catch,该 catch 丢弃已收集的全部 contentParts,返回 files: []atCommandProcessor 随后:fileDisplays 为空(连错误卡片都没有)、atCommandProcessor.ts:932 只发默认关闭的 onDebugMessage、最后仍走成功返回(status: 'success'filesRead 照报 2 个文件)。结果:模型收到零内容,界面无任何提示,会话记录声称读取成功。A/B 实证(capsh --drop=cap_dac_override,cap_dac_read_search 使 chmod 000 对 root 生效):base 给出 Success + Error 两张卡片且好文件内容正常送达;head 卡片为空、内容全无。批级 catch 是既有代码,但此前没有常规错误能到达它——processSingleFileContent 自己兜住 I/O 错误并返回单文件错误结果。ACP 侧同源:Session.ts:8846 从不检查 readResult.error

C2(Critical):@ 引用 >100 KB 且平均行长 >~100 B 的文本文件,从"截断附加"变成"读取报错"。
校验过的标准 FS 文本读取改走 readTextFileFromHandle,它强制要求有限的 maxScanBytes,而 readManyFiles 把两个预算都设成 getRangeReadByteLimit(config)(默认 100 000 字节)。handle 路径永远走流式,readLargeUtf8RangesourceSize > maxScanBytes && scannedBytes >= maxScanBytes 且未先命中 endLine/字节截断时抛 TextScanBudgetExceededError。而旧的 path 路径从不传 maxScanBytes(即 Infinity)并走 ≤10 MB 缓冲快路,总是返回截断内容。触发条件:文件 >100 KB 且前 1000 行装不进 100 000 字节。A/B:300 KB 单行、300 B 行、150 KB 压缩 JS、110 B 行全部由 Success 变 Error;90 B 行与 90 KB 单行不受影响。
两点使其应当阻塞合并:一是回归被写进了测试——should attach a truncated text file larger than 10MB 被改名为 should surface a byte-cap read error…,断言从 Success + ... [truncated] 翻成 Error,所以套件全绿(本地 70/70)恰恰是因为唯一覆盖它的测试改成了认可新行为;PR 描述与 45 条线程均未提及。二是ACP resource_link 同样受影响(现在任何类型的文件都会带上 validatedPathIdentities),JetBrains"附加当前编辑器"遇到大压缩文件会直接报错。
建议:解耦两个预算(窗口从第 0 行开始时定位成本为零,maxScanBytes 应取文件大小或大得多的上限);或在 readValidatedTextFileContent 捕获 TextScanBudgetExceededError 回退到字节游标读取;并恢复原测试断言作为回归护栏。

其余 N1–N7 为非阻塞项:ordinary read_many_files 路径上多余的 detectFileType/instanceof/getRangeReadByteLimit 计算;Number.isFinite 已成死分支;为单一调用方修改共享 helper 的 Infinity → MAX_SAFE_INTEGER;readFileContent 已达 9 个位置参数;设计文档"符号链接无法伪装被忽略文件"的说法未覆盖硬链接;Session.ts 在异步 ACP handler 里用同步 I/O;matchesValidatedPathIdentityPromise.all 自竞态。

结论:request changes — C1、C2 都改变了用户当前依赖的行为,且 C2 唯一的回归护栏被改写成了认可新行为。

@wenshao

wenshao commented Jul 31, 2026

Copy link
Copy Markdown
Collaborator

Review round 2 — 6d9c074 (head unchanged since the last round)

Head is byte-identical to the commit I reviewed previously, so I spent this round on the parts of the diff the last one covered less — the non-interactive entry point, the atCommandProcessor revalidation loop, and the snapshot path. One new Critical came out of it, verified with the same base-vs-head A/B harness. C1 and C2 from the previous round were re-run at this head and both still reproduce.


C3 — Critical (new): @-attaching a file ≥ 100 MB makes it vanish silently, and the session still reports it as read

snapshotValidatedFile returns undefined for any file over the snapshot cap:

// packages/core/src/utils/readManyFiles.ts:361
if (stats.size > SNAPSHOT_MAX_SIZE_BYTES) {   // 100 MB
  return undefined;
}

and the caller treats that indistinguishably from a fail-closed identity mismatch:

// packages/core/src/utils/readManyFiles.ts:206
if (shouldSnapshot && !snapshot) continue;

continue pushes nothing into files, so atCommandProcessor produces no toolDisplay at all for that path — not even an error card — while contentLabelsForDisplay still holds the label, so filesRead and recording.status: 'success' both claim the file was read. The @big.png token also stays in the prompt text, so the model is told about a file it never received.

The constant's comment says these files "are always rejected by the downstream processSingleFileContent inline-data caps … so copying them to a temp file is wasted I/O" — but that rejection was the user-visible error message. Skipping the copy also skipped the diagnostic.

A/B, production defaults, sparse files, query compare @good.txt and @<big>:

case base 9a4e924 head 6d9c074
@big.png, 101 MB Read File @big.pngError: Image file exceeds the 100 MB source limit no card, no error, nothing in prompt
@big.zip, 200 MB Read File @big.zipError: File size exceeds the 10MB limit (200.00MB) no card, no error, nothing in prompt
@mid.zip, 50 MB Error: File size exceeds the 10MB limit Error: File size exceeds the 10MB limit (unchanged)
filesRead / recording.status (all rows) honest ["good.txt","big.png"] / success

Note the 50 MB row: it is under the snapshot cap, so head copies the whole 50 MB to a temp file and then rejects it at the 10 MB binary limit. That is precisely the wasted I/O the constant claims to prevent — the cap is set to the image limit (100 MB) but applied to every non-text type, whose real limit is 10 MB.

Suggested fix: don't collapse "too large to snapshot" into the fail-closed continue. Either return a typed reason from snapshotValidatedFile and synthesise the same FileReadInfo error entry readFileContent would have produced, or check the per-type size cap before deciding to snapshot so processSingleFileContent still gets to emit its own error. More generally, every continue in that loop drops a path with no entry in filesatCommandProcessor has no way to tell "rejected" from "never asked for".


C1 and C2 — still open, re-verified at 6d9c074

Both re-run against base 9a4e924 on this head; details and suggested fixes are in the previous round — not repeating them here.

C1 — one unreadable @ file discards every attachment in the turn. readValidatedTextFileContent's unguarded fs.promises.open lets EACCES reach readManyFiles' function-level catch, which replaces all already-collected contentParts.

compare @good.txt and @noperm.txt (chmod 000, DAC caps dropped) base head
toolDisplays [{@good.txt, Success}, {@noperm.txt, Error, "EACCES: permission denied"}] []
good file's content reached the model yes no
shouldProceed / filesRead true / 2 files true / 2 files

C2@-referencing text > 100 KB with lines longer than ~100 B now errors instead of attaching truncated content, because readValidatedTextFileContent passes maxScanBytes === maxOutputBytes === getRangeReadByteLimit(config).

summarize @wide.txt (300 KB, 300-byte lines) base head
status Success, ... [truncated] ErrorLocating the requested line window would read more than 100000 bytes

C2's only regression guard is still the atCommandProcessor.test.ts case that this PR renamed from should attach a truncated text file larger than 10MB to should surface a byte-cap read error… with the assertions flipped, so the green suite certifies the new behaviour rather than catching it.


Also checked this round (no findings)

  • Non-interactive routing lifecycle. fullTurnModelOverride seeds the turn-scoped modelOverride, and the notification/cron drain loop starts from a fresh itemModelOverride with no runtimeView — the drains genuinely don't inherit the selector, matching the new sentence in docs/design/full-turn-multimodal-routing.md. The fullTurnModelOverrideActive guard correctly refuses skill-tool overrides (including the clear-to-undefined case) without blocking a repeat of the same selector.
  • resolveForModel(..., { failClosed: true }) rejects into the outer turn handler, so an unresolvable vision route aborts the run instead of sending raw image bytes to the primary. Fail-closed as documented.
  • runtimeView plumbing through executeToolCallCoreToolScheduler.schedule is a pass-through to existing machinery (that scheduler code is unchanged by this PR); the map entry is cleaned up on both the error and completion paths.
  • Multi-root resolution. The break → continue fix plus deferring the ignoredByReason push until after the loop behaves correctly when a path resolves from a later workspace directory.

Non-blocking, in addition to N1–N7 from the previous round

  • N8 — processSingleFileContent's catch block now reports a workspace-relative path in the error field (Error reading file ${relativePathForDisplay}), where it previously reported the absolute filePath. That field feeds logs/telemetry for every caller including the read_file tool, so absolute paths disappear from error records repo-wide for a change that only the @ path needed.
  • N9 — readTextFileFromHandle is optional on the FileSystemService interface but invoked as readTextFileFromHandle!.call(...). Safe today because shouldUseTextHandle requires StandardFileSystemService, but processSingleFileContent is exported, and any caller passing textFileHandle with a custom service gets a TypeError rather than a fallback.

Verdict: request changes — C3 is a new silent-data-loss path on a deterministic trigger (attach a large file), and C1/C2 are unchanged.

中文说明

第 2 轮评审 — 6d9c074(head 与上一轮完全一致)

head 与上轮所审提交逐字节相同,因此本轮集中在上轮覆盖较少的部分:非交互式入口、atCommandProcessor 的复校循环、以及 snapshot 路径。由此得到一条新的 Critical,并用同一套 base/head A/B 验证。上轮的 C1、C2 已在本 head 重跑,均仍可复现。

C3(Critical,新增):@ 引用 ≥100 MB 的文件会被静默丢弃,而会话仍报告该文件已读取。
snapshotValidatedFile(readManyFiles.ts:361)对超过 SNAPSHOT_MAX_SIZE_BYTES(100 MB)的文件返回 undefined,调用方(readManyFiles.ts:206)用 if (shouldSnapshot && !snapshot) continue; 处理,与"身份校验失败"的 fail-closed 情形完全无法区分。continue 不向 files 写入任何条目,于是 atCommandProcessor 连错误卡片都不会生成;而 contentLabelsForDisplay 仍保留该标签,filesReadrecording.status: 'success' 都声称文件已读取,提示词里 @big.png 记号也依然存在——模型被告知了一个它从未收到的文件。常量注释称这些文件"反正会被下游 processSingleFileContent 的上限拒绝,拷贝到临时文件是浪费 I/O",但那次拒绝正是用户可见的错误信息;省掉拷贝的同时也省掉了诊断。

A/B(生产默认配置,稀疏文件):@big.png(101 MB)base 给出 Error 卡片 Image file exceeds the 100 MB source limit,head 无任何卡片;@big.zip(200 MB)base 给出 File size exceeds the 10MB limit,head 同样无卡片;@mid.zip(50 MB)两侧一致仍报错。注意 50 MB 这行:它在 snapshot 上限之内,所以 head 会先把整整 50 MB 拷到临时文件,然后才在 10 MB 的二进制上限处被拒——这恰恰是该常量声称要避免的浪费 I/O:上限取的是图片的 100 MB,却应用到所有非文本类型,而后者的真实上限是 10 MB。
建议:不要把"过大无法 snapshot"并入 fail-closed 的 continue;或让 snapshotValidatedFile 返回带原因的结果并补出 readFileContent 本会产生的错误条目,或把按类型的大小上限前移到决定是否 snapshot 之前,让 processSingleFileContent 自己报错。更普遍地说,该循环里每一处 continue 丢弃路径时都不写 files,atCommandProcessor 无从区分"被拒绝"与"从未请求"。

C1、C2 仍未解决,已在 6d9c074 重新验证(细节与修复建议见上一轮评论,此处不再重复):

  • C1:单个不可读的 @ 文件会丢弃整轮全部附件。compare @good.txt and @noperm.txt(chmod 000,已 drop DAC 能力):base 为 Success + Error 两张卡片且好文件内容正常送达;head toolDisplays 为空、内容全无,而 shouldProceed: truefilesRead 仍报两个文件。
  • C2:@ 引用 >100 KB 且行长 >~100 B 的文本文件由"截断附加"变为"报错"。summarize @wide.txt(300 KB、300 字节行):base 为 Success + ... [truncated],head 为 Error Locating the requested line window would read more than 100000 bytes。其唯一的回归护栏仍是本 PR 把 should attach a truncated text file larger than 10MB 改名为 should surface a byte-cap read error… 并翻转断言的那条用例,所以套件全绿是在认可新行为而非拦截它。

本轮另行核查、未发现问题的部分: 非交互式路由生命周期(fullTurnModelOverride 只作用于本轮,通知/cron drain 从全新的 itemModelOverride 起步且不带 runtimeView,与设计文档新增的那句一致;fullTurnModelOverrideActive 守卫正确拒绝 skill-tool 覆写包括清空为 undefined 的情形);resolveForModel(..., { failClosed: true }) 失败会抛到外层 turn 处理器,确实是 fail-closed;runtimeViewexecuteToolCallCoreToolScheduler.schedule 的透传属于既有机制(该调度器代码本 PR 未改动),map 条目在错误与完成两条路径上都会清理;多工作区根解析的 break → continue 修复与延后 push ignoredByReason 的处理正确。

非阻塞补充(在上轮 N1–N7 之外): N8 — processSingleFileContent 的 catch 分支现在在 error 字段里报相对路径而非绝对路径,该字段面向所有调用方(含 read_file 工具)的日志/遥测,为了 @ 路径的需要导致全仓错误记录都丢失绝对路径;N9 — readTextFileFromHandleFileSystemService 接口上是可选的,却以 readTextFileFromHandle!.call(...) 调用,当前因 shouldUseTextHandle 要求 StandardFileSystemService 而安全,但 processSingleFileContent 是导出函数,自定义服务下传 textFileHandle 会得到 TypeError 而非回退。

结论:request changes — C3 是触发条件确定(附加一个大文件)的新静默数据丢失路径,C1、C2 亦未变化。

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

Reviewed. Suggestions are inline. Not reviewed: build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally.

— qwen3.8-max-preview via Qwen Code /review

// without a redundant read_file (issue #6289). Key by the canonical
// (resolved) path — not the display alias — because Edit / WriteFile
// looks up the cache by canonical path.
recordAttachedFileRead(config, canonicalPath ?? filePath, fileReadResult);

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 positive test asserts that a successful validated read is cached by its canonical path. The negative case (a dropped read leaves cache.size() === 0) and the non-validated positive case are both covered, but every positive cache test calls readManyFiles without validatedPathIdentities, where filePath === fullPath === canonicalPath — so a regression dropping the canonicalPath argument here would key the cache by the ephemeral snapshot temp path and no test would fail. — Failure scenario: a validated @-read succeeds via the snapshot path, then the user runs Edit/WriteFile on the same canonical path; checkPriorRead looks up the canonical path, misses (the entry is keyed by the now-deleted qwen-validated-read-* path), and forces a redundant re-read instead of passing prior-read enforcement. Concrete cost: the Edit-after-@-attach workflow silently breaks for validated reads only. Consider adding a test that performs a successful validated read and asserts checkPriorRead(cache, canonicalPath, 'editing').ok === true.

— qwen3.8-max-preview via Qwen Code /review

Comment on lines +215 to +218
const configuredProjectTempDir = Storage.getGlobalTempDir();
const projectTempDir = await fs
.realpath(configuredProjectTempDir)
.catch(() => path.resolve(configuredProjectTempDir));

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 realpath'd-temp-dir branch added here (isSubpath(projectTempDir, …), also consulted by the in-loop and revalidation checks) has no test that distinguishes it from the literal configuredProjectTempDir branch. Both existing temp-dir tests mock Storage.getGlobalTempDir to a directory that realpaths to itself, so on Linux CI acceptance is always decided by the literal branch — deleting the realpath computation and every projectTempDir check would pass the whole suite. — Failure scenario: on macOS the configured temp dir is non-canonical (/var/folders/…) while the in-loop check compares a canonicalized path (/private/var/folders/…); without this branch, isSubpath('/var/folders/X/tmp', '/private/var/folders/X/tmp/file.txt') is false and a legitimate project-temp @-reference is wrongly skipped. Consider a test that spies Storage.getGlobalTempDir to return a non-canonical (symlinked) path and asserts a file inside it is still read after canonicalization.

— qwen3.8-max-preview via Qwen Code /review

@qwen-code-dev-bot

Copy link
Copy Markdown
Collaborator

🤖 Addressed the latest review feedback (round 1/100). What changed, and what I pushed back on: · 已处理最新评审反馈(第 1/100 轮)。改动内容与我反驳保留之处如下:

Review feedback addressed — a17cb4a

C1 — Critical: one unreadable @ file silently discards every attached file

Fixed. Wrapped the readValidatedTextFileContent call in a per-file try/catch that degrades to the same per-file error result shape readFileContent produces. One bad file (EACCES, ENOENT, ELOOP, EMFILE) now yields an error card and info.error for that file while sibling content is preserved. Abort errors still propagate.

Added regression test: keeps sibling files when one validated text file fails to open — mocks fs.open to throw EACCES for one of two validated files, asserts the good file's content is present, the bad file has error containing EACCES, and result.error is undefined.

C2 — Critical: @-referencing a text file > 100 KB with long lines now errors instead of attaching truncated content

Fixed. Decoupled the scan budget from the output budget. readValidatedTextFileContent now passes Math.max(1, stats.size) as maxScanBytes (from the descriptor's own fstat) instead of the output byte limit. Since @-mentions always read from line 0, locating line 0 is free — the scan just reads forward until the output budget (maxOutputBytes) truncates. This restores the pre-PR behavior where large files with long lines were truncated, not errored.

Restored the original regression guard: should attach a truncated text file larger than 10MB now asserts ToolCallStatus.Success + Showing lines 1- + ... [truncated] instead of the error assertion that had certified the regression.

Updated readManyFiles.test.ts assertion: maxScanBytes now expects approvedStats.size instead of Number.MAX_SAFE_INTEGER.

N1 — wasted per-file I/O on the ordinary tool path

Fixed. Guarded the detectFileType, instanceof StandardFileSystemService, and former getRangeReadByteLimit computations with if (validatedIdentity). On the read_many_files glob path (no validated identities), these are now skipped entirely.

N2 — dead guard

Fixed. Removed Number.isFinite(textHandleReadByteLimit) along with the getRangeReadByteLimit call and import — both are no longer needed after C2+N1.

N3 — global helper changed for one caller

Declined. The Infinity → MAX_SAFE_INTEGER translation in getRangeReadByteLimit is verified benign by the reviewer. Moving it to the handle call site would touch a shared helper used by read_file too, growing the diff without a correctness gain. Not worth the diff growth.

N4 — readFileContent now takes 9 positional parameters

Declined. Converting to an options object is a good refactor but out of scope for this PR — it's a pre-existing pattern and the change would grow the diff significantly. Worth a follow-up.

N5 — doc claim is broader than the code

Fixed. Scoped the sentence to symlinks and added: "Hardlinks are not resolved by realpath and are not covered by this check."

N6 — sync I/O in the async ACP handler

Declined. resolveExistingFile uses realpathSync/statSync in a synchronous loop building candidatePathsToRead. Converting to async would require restructuring the loop and the function signature across multiple call sites. The reviewer marked this non-blocking; worth a follow-up.

N7 — matchesValidatedPathIdentity races itself

Fixed. Replaced Promise.all([realpath, stat]) with sequential realpath then stat on the resolved path, with an early return when canonicalPath !== filePath. The two syscalls now observe the same filesystem state.

Verification

  • npx tsc --noEmit -p packages/core/tsconfig.json — passed
  • npx tsc --noEmit -p packages/cli/tsconfig.json — passed
  • npx eslint packages/core/src/utils/readManyFiles.ts packages/core/src/utils/readManyFiles.test.ts packages/cli/src/ui/hooks/atCommandProcessor.test.ts — passed (0 errors)
  • vitest run src/utils/readManyFiles.test.ts (packages/core) — 43 passed
  • vitest run src/ui/hooks/atCommandProcessor.test.ts (packages/cli) — 70 passed
  • vitest run src/utils/fileUtils.test.ts (packages/core) — 171 passed
  • vitest run src/acp-integration/session/Session.test.ts (packages/cli) — 470 passed
中文说明

已处理的审查反馈 — a17cb4a

C1 — Critical:一个不可读的 @ 文件会静默丢弃整轮的全部附件

已修复。readValidatedTextFileContent 调用包裹在单文件 try/catch 中,失败时降级为与 readFileContent 相同格式的单文件错误结果。一个坏文件(EACCES、ENOENT、ELOOP、EMFILE)现在会生成该文件的错误卡片和 info.error,同时保留兄弟文件的内容。中止错误仍然正常传播。

新增回归测试:keeps sibling files when one validated text file fails to open —— mock fs.open 对两个已验证文件中的一个抛出 EACCES,断言好文件的内容存在、坏文件的 error 包含 EACCES、且 result.error 为 undefined。

C2 — Critical:@ 引用 >100 KB 且行长较长的文本文件,从"截断附加"变成"读取报错"

已修复。 解耦了扫描预算和输出预算。readValidatedTextFileContent 现在传递 Math.max(1, stats.size) 作为 maxScanBytes(来自描述符自身的 fstat),而非输出字节限制。由于 @ 引用总是从第 0 行读取,定位第 0 行的成本为零——扫描只是向前读取直到输出预算(maxOutputBytes)截断。这恢复了 PR 之前的行为:大文件被截断而非报错。

恢复了原始回归护栏:should attach a truncated text file larger than 10MB 现在断言 ToolCallStatus.Success + Showing lines 1- + ... [truncated],而非之前认可回归行为的错误断言。

更新了 readManyFiles.test.ts 断言:maxScanBytes 现在期望 approvedStats.size 而非 Number.MAX_SAFE_INTEGER

N1 — ordinary tool 路径上浪费的单文件 I/O

已修复。detectFileTypeinstanceof StandardFileSystemService 和原 getRangeReadByteLimit 计算用 if (validatedIdentity) 包裹。在 read_many_files glob 路径(无验证身份)上,这些计算现在完全跳过。

N2 — 死分支守卫

已修复。 移除了 Number.isFinite(textHandleReadByteLimit) 以及 getRangeReadByteLimit 调用和导入——在 C2+N1 之后均不再需要。

N3 — 为单一调用方修改共享 helper

拒绝。 审查者已验证 getRangeReadByteLimitInfinity → MAX_SAFE_INTEGER 的转换是无害的。将其移到 handle 调用点会触及 read_file 也使用的共享 helper,增加 diff 但没有正确性收益。不值得增加 diff。

N4 — readFileContent 已达 9 个位置参数

拒绝。 转换为选项对象是好的重构,但超出本 PR 范围——这是既有模式,改动会显著增加 diff。值得后续跟进。

N5 — 文档声明比代码更宽泛

已修复。 将句子限定为符号链接,并添加:"Hardlinks are not resolved by realpath and are not covered by this check."

N6 — 异步 ACP handler 中的同步 I/O

拒绝。 resolveExistingFile 在构建 candidatePathsToRead 的同步循环中使用 realpathSync/statSync。转换为异步需要重构循环和跨多个调用点的函数签名。审查者标记为非阻塞;值得后续跟进。

N7 — matchesValidatedPathIdentity 自竞态

已修复。Promise.all([realpath, stat]) 替换为顺序执行的 realpath 然后对解析后的路径执行 stat,并在 canonicalPath !== filePath 时提前返回。两个系统调用现在观察相同的文件系统状态。

验证

  • npx tsc --noEmit -p packages/core/tsconfig.json — 通过
  • npx tsc --noEmit -p packages/cli/tsconfig.json — 通过
  • npx eslint packages/core/src/utils/readManyFiles.ts packages/core/src/utils/readManyFiles.test.ts packages/cli/src/ui/hooks/atCommandProcessor.test.ts — 通过(0 错误)
  • vitest run src/utils/readManyFiles.test.ts(packages/core)— 43 通过
  • vitest run src/ui/hooks/atCommandProcessor.test.ts(packages/cli)— 70 通过
  • vitest run src/utils/fileUtils.test.ts(packages/core)— 171 通过
  • vitest run src/acp-integration/session/Session.test.ts(packages/cli)— 470 通过

Base-conflict check · 基分支冲突检查: no conflict with main. · 与 main 无冲突。

Re-review when you have a moment. After round 100 this bot stops and leaves the PR for a human. · 有空请复审;第 100 轮后本 bot 停止并将 PR 交给人工。


🧠 Handled by Qwen Code · model/模型 qwen3.8-max-preview

@qwen-code-dev-bot

Copy link
Copy Markdown
Collaborator

🤖 Addressed the latest review feedback (round 2/100). What changed, and what I pushed back on: · 已处理最新评审反馈(第 2/100 轮)。改动内容与我反驳保留之处如下:

Review round 3 — feedback addressed

Critical findings (from @wenshao's round-2 review)

C1 — one unreadable @ file discards every attachment — already fixed by a17cb4aae (previous commit). A per-file try/catch around readValidatedTextFileContent catches EACCES and produces an error FileReadInfo entry instead of propagating to the function-level catch. Test: "keeps sibling files when one validated text file fails to open" (passing).

C2 — @-referencing text > 100 KB with long lines errors instead of truncating — already fixed by a17cb4aae. textFileMaxScanBytes changed from getRangeReadByteLimit(config) (100 KB) to Math.max(1, stats.size) (the actual file size), so the scan budget covers the whole file. Test: "reads validated text through a handle when truncation is disabled" asserts maxScanBytes: approvedStats.size (passing).

C3 — @-attaching a file ≥ 100 MB vanishes silentlyfixed in this commit. Root cause: snapshotValidatedFile returns undefined for files over SNAPSHOT_MAX_SIZE_BYTES, and the caller's if (shouldSnapshot && !snapshot) continue collapsed "too large to snapshot" into the same silent drop as "identity mismatch". Fix: added stats.size <= SNAPSHOT_MAX_SIZE_BYTES to the shouldSnapshot condition so oversized files skip the snapshot and fall through to a direct read with validateAfterRead, letting processSingleFileContent emit its own size-limit error card (e.g. "Image file exceeds the 100 MB source limit" or "File size exceeds the 10MB limit"). Test: "surfaces a size error for a validated file too large to snapshot" — creates a sparse 101 MB .png, asserts files has one entry with an error matching /exceeds/i.

Inline suggestions (automated reviewer)

rc:3692400651 — no positive test for validated-read cache by canonical path — implemented. Added "records a validated text read by canonical path for prior-read enforcement": performs a validated text read via readManyFiles with validatedPathIdentities and a live FileReadCache, then asserts checkPriorRead(cache, absolutePath, 'editing').ok === true.

rc:3692400658 — realpath'd-temp-dir branch untested — implemented. Added "accepts a temp-dir file via the realpath branch when the configured path is a symlink": creates a real directory and a symlink to it, mocks Storage.getGlobalTempDir to return the symlink, then asserts a file at the canonical path is still read. This exercises the projectTempDir branch that the literal configuredProjectTempDir check misses.

Non-blocking notes (declined)

N8 — catch block reports relative path in error field — declined. The displayPath change is deliberate and consistent throughout the PR. For non-@ reads (e.g. the read_file tool), displayPath defaults to filePath, so error records are unchanged. Only @ reads pass a different display path, which is the intended behavior.

N9 — readTextFileFromHandle invoked with ! — declined. The ! is safe because shouldUseTextHandle requires StandardFileSystemService, which always implements readTextFileFromHandle. Adding a fallback for an impossible case violates Simplicity First.

Verification

  • npm run build — passed
  • npm run typecheck — passed
  • npm run lint — passed
  • vitest packages/core src/utils/readManyFiles.test.ts — 45 passed
  • vitest packages/cli src/ui/hooks/atCommandProcessor.test.ts — 71 passed
中文说明

第 3 轮评审 — 反馈处理

Critical 发现(来自 @wenshao 的第 2 轮评审)

C1 — 单个不可读的 @ 文件丢弃整轮全部附件 — 已由 a17cb4aae(上一个提交)修复。在 readValidatedTextFileContent 外增加了逐文件 try/catch,捕获 EACCES 并生成错误 FileReadInfo 条目,而非传播到函数级 catch。测试:"keeps sibling files when one validated text file fails to open"(通过)。

C2 — @ 引用 >100 KB 且行长较长的文本文件由截断变为报错 — 已由 a17cb4aae 修复。textFileMaxScanBytesgetRangeReadByteLimit(config)(100 KB)改为 Math.max(1, stats.size)(实际文件大小),扫描预算覆盖整个文件。测试:"reads validated text through a handle when truncation is disabled" 断言 maxScanBytes: approvedStats.size(通过)。

C3 — @ 附加 ≥100 MB 的文件静默消失本次提交修复。根因:snapshotValidatedFile 对超过 SNAPSHOT_MAX_SIZE_BYTES 的文件返回 undefined,调用方的 if (shouldSnapshot && !snapshot) continue 将"过大无法快照"与"身份校验失败"混为同一种静默丢弃。修复:在 shouldSnapshot 条件中增加 stats.size <= SNAPSHOT_MAX_SIZE_BYTES,使超大文件跳过快照、走直接读取 + validateAfterRead 路径,让 processSingleFileContent 自行发出大小限制错误卡片(如 "Image file exceeds the 100 MB source limit" 或 "File size exceeds the 10MB limit")。测试:"surfaces a size error for a validated file too large to snapshot" — 创建 101 MB 稀疏 .png,断言 files 有一个错误条目匹配 /exceeds/i

内联建议(自动审查器)

rc:3692400651 — 缺少验证读取按规范路径缓存的正向测试 — 已实现。新增 "records a validated text read by canonical path for prior-read enforcement":通过 readManyFilesvalidatedPathIdentitiesFileReadCache 执行验证文本读取,然后断言 checkPriorRead(cache, absolutePath, 'editing').ok === true

rc:3692400658 — realpath 临时目录分支未被测试覆盖 — 已实现。新增 "accepts a temp-dir file via the realpath branch when the configured path is a symlink":创建真实目录和指向它的符号链接,将 Storage.getGlobalTempDir mock 为符号链接路径,然后断言规范路径下的文件仍可被读取。此测试覆盖了字面 configuredProjectTempDir 检查无法命中的 projectTempDir 分支。

非阻塞备注(已拒绝)

N8 — catch 块在 error 字段中报告相对路径 — 拒绝。displayPath 的更改是本 PR 中有意且一致的设计。对于非 @ 读取(如 read_file 工具),displayPath 默认为 filePath,错误记录不变。仅 @ 读取传递不同的显示路径,这是预期行为。

N9 — readTextFileFromHandle! 调用 — 拒绝。! 是安全的,因为 shouldUseTextHandle 要求 StandardFileSystemService,后者始终实现 readTextFileFromHandle。为不可能的情况添加回退违反 Simplicity First 原则。

验证

  • npm run build — 通过
  • npm run typecheck — 通过
  • npm run lint — 通过
  • vitest packages/core src/utils/readManyFiles.test.ts — 45 通过
  • vitest packages/cli src/ui/hooks/atCommandProcessor.test.ts — 71 通过

Base-conflict check · 基分支冲突检查: no conflict with main. · 与 main 无冲突。

Re-review when you have a moment. After round 100 this bot stops and leaves the PR for a human. · 有空请复审;第 100 轮后本 bot 停止并将 PR 交给人工。


🧠 Handled by Qwen Code · model/模型 qwen3.8-max-preview

@qwen-code-dev-bot

Copy link
Copy Markdown
Collaborator

🔀 Base updated: red check(s) [Test (ubuntu-latest, Node 22.x)] pass on current main — merged current main via update-branch; CI will re-run.

中文说明

🔀 已更新 base:红色检查 [Test (ubuntu-latest, Node 22.x)] 在当前 main 上通过 —— 已通过 update-branch 合入当前 main,CI 将重新运行。

@qwen-code-dev-bot

Copy link
Copy Markdown
Collaborator

🤖 Reviewed the latest feedback — no changes needed. Why, point by point: · 已审阅最新反馈——无需改动。逐点说明原因如下:

No action taken

The only feedback item this round is the failed check ubuntu-latest / Java 11 from the sdk-java.yml workflow.

Diagnosis

This check is unrelated to the PR's changes:

  • The PR modifies zero Java files. The packages/sdk-java/ tree is byte-identical between this branch and origin/main (git diff origin/main HEAD -- packages/sdk-java/ produces no output).
  • The workflow was triggered solely by the path filter on packages/cli/src/acp-integration/** (the PR modifies Session.ts there), not by any Java SDK change.
  • The failing job (test matrix, ubuntu-latest / Java 11) runs mvn clean test, mvn checkstyle:check, and mvn package — all purely Java operations on code this PR does not touch.
  • Java and Maven are not available on this runner, so the failure cannot be reproduced locally. However, since the Java SDK source is identical to main, any failure in that job is a pre-existing issue on main or a transient CI environment problem.

No code changes are warranted.

中文说明

未采取任何操作

本轮唯一的反馈项是 sdk-java.yml 工作流中的失败检查 ubuntu-latest / Java 11

诊断

此检查与本 PR 的更改无关:

  • 本 PR 未修改任何 Java 文件。packages/sdk-java/ 目录在本分支与 origin/main 之间完全一致(git diff origin/main HEAD -- packages/sdk-java/ 无任何输出)。
  • 该工作流仅因 packages/cli/src/acp-integration/** 的路径过滤器而被触发(本 PR 修改了其中的 Session.ts),而非因为任何 Java SDK 的更改。
  • 失败的作业(test 矩阵,ubuntu-latest / Java 11)运行的是 mvn clean testmvn checkstyle:checkmvn package —— 全部是针对本 PR 未触及的 Java 代码的操作。
  • 本运行器上没有 Java 和 Maven,因此无法在本地复现该失败。但由于 Java SDK 源代码与 main 完全相同,该作业中的任何失败都是 main 上的已有问题或临时性 CI 环境问题。

无需进行代码更改。

Base-conflict check · 基分支冲突检查: no conflict with main. · 与 main 无冲突。


🧠 Handled by Qwen Code · model/模型 qwen3.8-max-preview

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

Reviewed. Not reviewed: build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally.

中文说明

已审查。 未审查:build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally。

— qwen3.8-max-preview via Qwen Code /review

@qwen-code-dev-bot

Copy link
Copy Markdown
Collaborator

🤖 Reviewed the latest feedback — no changes needed. Why, point by point: · 已审阅最新反馈——无需改动。逐点说明原因如下:

Autofix review round — no action taken

No code change was made this round. There is no actionable feedback requiring a change.

Feedback triage

  • Automated reviewer (COMMENTED): "Reviewed. Not reviewed: build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally." This is the reviewer disclosing a gap in its own review coverage. It names no defect and requests no change, so there is nothing to fix. For reference, the Integration Tests (CLI, No Sandbox) suite was SKIPPED in this PR's CI run (a CI routing/configuration matter, not a code defect), and the Real daemon E2E / Java 11 job — which builds the modified TypeScript (npm run build + npm run bundle) and exercises the daemon code this PR changes — passed.
  • Inline comments: none.
  • Issue-level comments: none.
  • New failed checks: none.

Still-red check: ubuntu-latest / Java 11 (SDK Java workflow)

This failure persists from before the last evaluation and is independent of this PR's changes. Evidence:

  • This PR's diff (git diff origin/main...HEAD) touches no files under packages/sdk-java/**, no pom.xml, and no checkstyle configuration. The failing job (mvn clean test / checkstyle:check / package in packages/sdk-java/qwencode) compiles only that unchanged Java source, so the PR cannot have altered what it builds.
  • In the same CI run, ubuntu-latest / Java 17 and ubuntu-latest / Java 21 run the identical mvn clean test against the identical Java source and pass. Only the Java 11 entry fails (in ~41s), and only Java 11 runs the additional Checkstyle and release-artifact package steps. A failure confined to the Java 11 Maven build while Java 17/21 pass the same test step points to a Java-11-specific toolchain/environment issue, not a regression from this PR.
  • The Real daemon E2E / Java 11 job, which is the only job that builds and runs the TypeScript daemon this PR modifies, passed — confirming the PR's actual changes are sound.

No in-scope code change is warranted. The Java 11 SDK build failure should be tracked separately as a Java SDK / CI environment issue rather than against this TypeScript PR.

中文说明

Autofix 审查轮次 — 未采取任何操作

本轮未做任何代码改动。当前没有需要修改的可执行反馈。

反馈分类

  • 自动审查器(COMMENTED:"Reviewed. Not reviewed: build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally。" 这是审查器在说明其自身审查覆盖范围的缺口。它没有指出任何缺陷,也没有要求任何改动,因此没有可修复的内容。供参考:Integration Tests (CLI, No Sandbox) 套件在本 PR 的 CI 运行中为 SKIPPED(属于 CI 路由/配置问题,而非代码缺陷);而 Real daemon E2E / Java 11 任务——它会构建被修改的 TypeScript(npm run build + npm run bundle)并实际运行本 PR 所修改的 daemon 代码——已经通过
  • 行内评论:无。
  • Issue 级评论:无。
  • 新的失败检查:无。

仍然失败的检查:ubuntu-latest / Java 11(SDK Java 工作流)

该失败从上一次评估之前就已存在,并且与本 PR 的改动无关。证据如下:

  • 本 PR 的差异(git diff origin/main...HEAD没有触碰 packages/sdk-java/** 下的任何文件,没有改动任何 pom.xml,也没有改动任何 checkstyle 配置。失败的任务(在 packages/sdk-java/qwencode 中执行 mvn clean test / checkstyle:check / package)只编译那份未被改动的 Java 源码,因此本 PR 不可能改变了它所构建的内容。
  • 在同一次 CI 运行中,ubuntu-latest / Java 17ubuntu-latest / Java 21 对完全相同的 Java 源码执行了完全相同的 mvn clean test 并且通过。只有 Java 11 这一项失败(约 41 秒内),而且只有 Java 11 会额外运行 Checkstyle 和发布产物 package 步骤。失败仅局限于 Java 11 的 Maven 构建、而 Java 17/21 通过相同测试步骤,说明这是 Java 11 特定的工具链/环境问题,而非本 PR 引入的回归。
  • Real daemon E2E / Java 11 任务是唯一一个会构建并运行本 PR 所修改的 TypeScript daemon 的任务,它已经通过——证实本 PR 的实际改动是健全的。

不存在应当在本 PR 范围内做的代码改动。Java 11 SDK 构建失败应作为 Java SDK / CI 环境问题单独跟踪,而不应归到这个 TypeScript PR 上。

Base-conflict check · 基分支冲突检查: no conflict with main. · 与 main 无冲突。


🧠 Handled by Qwen Code · model/模型 qwen3.8-max-preview

@wenshao

wenshao commented Aug 1, 2026

Copy link
Copy Markdown
Collaborator

Local verification report — built and run against a real binary

I built this PR from source and exercised it against an isolated local model provider that records every outbound request, so each claim below is backed by a captured HTTP request body rather than by log inspection. I ran the identical scenarios against origin/main to separate what this PR changes from what was already true.

Verdict: the headline fix is real and reproducible, and the hardening delivers one genuine type-confusion fix that main was vulnerable to. I recommend merging. Two statements in the PR description overstate the scope and are worth correcting before merge; one pre-existing gap is now reachable from a new entry point and deserves an explicit decision. Details below.

Environment

PR head cae7925e (already contains origin/main)
Baseline origin/main 1e2932a6
Build npm ci && npm run build && npm run bundle, CLI reports 0.21.2
Host macOS (darwin 25.6.0), Node v24.18.1
Isolation temp QWEN_HOME, system settings/defaults pointed at nonexistent paths, NO_PROXY=127.0.0.1
Provider local OpenAI-compatible server on 127.0.0.1 logging every /v1/chat/completions body

Two models are registered on the same endpoint so bridge selection is deterministic:

  • local-text-primarycapabilities.agent, modalities: {} → not image-capable, so shouldRunVisionBridge() is true
  • local-vision-agentcapabilities: {vision, agent}, modalities: {image: true}getDefaultVisionBridgeModel() returns it with agentCapable, taking the full-turn path

1. The headline fix is confirmed

qwen -p "@<abs>/shot.png describe this image in one word", same command on both builds:

before and after

On origin/main the non-interactive CLI reads the file, emits the image-overview text, then substitutes the literal placeholder [image: image/jpeg] and keeps the turn on the text-only primary — the model is told an image exists but never receives one. Zero image parts left the process. With this PR the same command routes the turn to local-vision-agent and emits exactly one image_url part. This is issue #6988, and it is fixed.

2. Full outcome matrix, every cell from a recorded request body

outcome matrix

3. Correction: only the non-interactive CLI was broken

The PR description says "the non-interactive CLI and ACP paths did not route image turns through the same capability-aware logic as the TUI." I drove a real qwen --acp agent over stdio (initialize → session/new → session/prompt) and captured the traffic: origin/main's ACP path already routed @image turns correctlylocal-vision-agent, one image part, same as the TUI. The routing gap was specific to the non-interactive CLI. The ACP changes in this PR are validation changes, not routing changes. Worth fixing the wording, since it affects how a reviewer scopes the risk.

4. A real type-confusion fix the description undersells

The most valuable thing I found is not in the test plan. Fixture: alias-as-image.png, an in-workspace symlink whose real target is notes.txt (text/plain).

On origin/main's ACP path, the alias's .png extension decides the type, so the plain-text file is base64-encoded and shipped to the vision model labelled data:image/png;base64,…. Decoding what main actually sent returns the text file verbatim:

CONFIDENTIAL NOTES
line2: this file is text/plain, not an image.
line3: aliased through a .png symlink.

With this PR the canonical target is resolved first, its MIME is not image/*, and the reference is rejected — zero image parts. On the TUI / non-interactive path the same alias is correctly read as text, with the user's original alias preserved in the Content from … label. That display-alias-but-validate-canonical split is exactly the right shape, and it is well executed.

5. Workspace escape and ignore rules: already safe on main

escape.png (symlink whose target leaves the workspace) and ignored/hidden.png (gitignored) are rejected on both builds, across all three entry points. WorkspaceContext.isPathWithinWorkspace() on main already fully resolves symlinks before the containment check, so this vector was closed. The explicit canonical checks this PR adds are defense-in-depth and useful — particularly for the TOCTOU window — but the test plan's "confirm all are rejected" would have passed on main too.

TUI accepted
TUI rejected

6. One gap to decide on before merge

detectFileType() classifies by extension only — there is no magic-byte sniff for the image branch. So spoof.png, a real file (no symlink) with a .png name and plain-text bytes, is base64-encoded and sent as image/png. I confirmed this is identical on main and on this PR, so it is not a regression and not something this PR breaks.

The nuance that matters: because the non-interactive CLI now routes image turns, this pre-existing extension-trust behavior becomes reachable from qwen -p for the first time. Nothing here blocks the merge, but the description's "MIME spoofing" claim and the test plan's "non-image MIME types … confirm all are rejected" hold only for the symlink-alias variant, not the plain-extension one. I would either narrow that wording or file a follow-up for content-based sniffing.

7. TOCTOU

I did not reproduce the swap-during-read race live — the window is too tight to drive deterministically from outside the process. The mechanism reads correctly (dev/ino identity recapture, O_NOFOLLOW snapshot copy, post-copy growth probe) and is covered by the unit tests added here. Flagging it as reviewed-by-reading, not reviewed-by-execution.

8. Test suites

Suite Result
PR-touched CLI test files (nonInteractiveCli, atCommandProcessor, ACP Session) 643 passed, 1 skipped, 0 failed
packages/core (PR) 18,755 passed, 1 failed
packages/cli (PR) 16,061 passed, 15 failed across 3 files
packages/cli (origin/main, same machine) 16,039 passed, 11 failed across 2 files

No failure is attributable to this PR. The failing files — ui/auth/AuthDialog.test.tsx, commands/extensions/list.test.ts, serve/acp-http/transport.test.ts — are untouched by this diff and fail on origin/main as well. The AuthDialog failures are 5-second render timeouts whose subset varies run to run; transport.test.ts passes when run in isolation. The single core failure is shellAstParser.test.ts > classifies adversarial rule inputs in bounded time, a wall-clock budget assertion in a file byte-identical to main; it passes on both builds once the machine is idle. My host was carrying heavy concurrent load (1-minute load average peaked above 200), which is the cause.

Summary

The routing fix does what it claims and I verified it end to end on the real binary at all three entry points. The canonical-path validation closes a genuine mislabeled-egress bug on the ACP path. My only requests before merge are wording corrections in §3 and §6, plus a decision on whether extension-only MIME trust warrants a follow-up now that qwen -p can reach it.

中文版本

本地验证报告 —— 基于真实构建产物运行

我从源码构建了本 PR,并针对一个会记录所有出站请求的隔离本地模型 provider 进行验证,因此下文每条结论都有捕获到的 HTTP 请求体作为依据,而非仅凭日志推断。同一批场景我也在 origin/main 上跑了一遍,用来区分「本 PR 的改动」与「本来就如此」。

结论:核心修复真实可复现,安全加固中包含一处 main 确实存在的类型混淆漏洞的真修复。建议合入。 PR 描述中有两处表述夸大了范围,建议合入前修正;另有一处既有缺陷因为新入口打通而变得可达,值得显式决策。详见下文。

环境

PR head cae7925e(已包含 origin/main
基线 origin/main 1e2932a6
构建 npm ci && npm run build && npm run bundle,CLI 版本 0.21.2
主机 macOS (darwin 25.6.0),Node v24.18.1
隔离 临时 QWEN_HOME,system settings/defaults 指向不存在路径,NO_PROXY=127.0.0.1
Provider 本地 127.0.0.1 OpenAI 兼容服务,记录每一个 /v1/chat/completions 请求体

同一 endpoint 上注册两个模型,使 bridge 选择完全确定:

  • local-text-primary —— capabilities.agentmodalities: {},不具备图片能力,因此 shouldRunVisionBridge() 为真
  • local-vision-agent —— capabilities: {vision, agent}modalities: {image: true}getDefaultVisionBridgeModel() 返回它并带 agentCapable,走 full-turn 路径

1. 核心修复已确认

qwen -p "@<绝对路径>/shot.png describe this image in one word",两个构建执行同一条命令:

origin/main 上,非交互式 CLI 读取了文件、生成了图片概览文本,然后把图片替换成字面占位符 [image: image/jpeg],整轮留在纯文本主模型上 —— 模型被告知「有一张图」,却从未收到图。零个图片 part 离开进程。本 PR 下同一条命令把该轮路由到 local-vision-agent,并发出恰好一个 image_url part。这正是 issue #6988,已修复。

2. 完整结果矩阵,每个单元格都来自真实请求体

见上方矩阵截图。

3. 修正:只有非交互式 CLI 是坏的

PR 描述称「非交互式 CLI 和 ACP 路径没有像 TUI 一样走能力感知路由」。我用 stdio 驱动了真实的 qwen --acp(initialize → session/new → session/prompt)并抓取流量:origin/main 的 ACP 路径本来就能正确路由 @image 轮次 —— 同样是 local-vision-agent、一个图片 part,与 TUI 一致。路由缺口只存在于非交互式 CLI。本 PR 对 ACP 的改动属于校验层面,不是路由层面。建议修正措辞,因为这会影响 reviewer 对风险范围的判断。

4. 一处被描述低估了的真实类型混淆修复

我发现的最有价值的一点并不在测试计划里。Fixture:alias-as-image.png,一个位于工作区内、真实目标是 notes.txttext/plain)的符号链接

origin/main 的 ACP 路径上,类型由别名的 .png 扩展名决定,于是这个纯文本文件被 base64 编码,以 data:image/png;base64,… 的标签发给了视觉模型。把 main 实际发出的内容解码出来,就是该文本文件的原文:

CONFIDENTIAL NOTES
line2: this file is text/plain, not an image.
line3: aliased through a .png symlink.

本 PR 会先解析规范目标,其 MIME 不是 image/*,该引用被拒绝,零图片 part。在 TUI / 非交互式路径上,同一个别名被正确地按文本读取,同时 Content from … 标签里保留了用户写的原始别名。这种「展示用别名、校验用规范路径」的拆分方向完全正确,实现也很到位。

5. 工作区逃逸与 ignore 规则:main 上本就安全

escape.png(目标逃出工作区的符号链接)和 ignored/hidden.png(被 gitignore 命中)在两个构建、三个入口上都被拒绝。main 的 WorkspaceContext.isPathWithinWorkspace() 在做包含性检查前已经完整解析了符号链接,所以这条路径本就是关闭的。本 PR 新增的显式规范化检查属于纵深防御,确有价值(尤其对 TOCTOU 窗口),但测试计划里「确认全部被拒绝」这一条在 main 上同样会通过。

6. 合入前需要拍板的一处缺口

detectFileType() 仅按扩展名分类 —— 图片分支没有魔数嗅探。因此 spoof.png 这个真实文件(非符号链接、.png 文件名、纯文本字节)会被 base64 后以 image/png 发出。我确认该行为在 main 和本 PR 上完全一致,因此不是回归,也不是本 PR 弄坏的。

需要注意的细节是:由于非交互式 CLI 现在会路由图片轮次,这个既有的扩展名信任行为第一次变得可以从 qwen -p 触达。这不构成合入阻塞,但描述中的「MIME 伪造」以及测试计划里「非图片 MIME 类型……确认全部被拒绝」只对符号链接别名变体成立,对纯扩展名变体不成立。建议要么收窄措辞,要么另开 issue 跟进基于内容的嗅探。

7. TOCTOU

我没有在真实运行中复现「读取过程中被替换」的竞态 —— 该窗口太窄,无法从进程外确定性地驱动。相关机制(dev/ino 身份重取、O_NOFOLLOW 快照拷贝、拷贝后的增长探测)代码逻辑正确,且被本 PR 新增的单测覆盖。此项标注为「读代码审阅通过」,而非「运行验证通过」。

8. 测试套件

套件 结果
本 PR 涉及的 CLI 测试文件(nonInteractiveCliatCommandProcessor、ACP Session 643 通过,1 跳过,0 失败
packages/core(PR) 18,755 通过,1 失败
packages/cli(PR) 16,061 通过,15 失败,分布在 3 个文件
packages/cliorigin/main,同一台机器) 16,039 通过,11 失败,分布在 2 个文件

没有任何一个失败可归因于本 PR。 失败文件 —— ui/auth/AuthDialog.test.tsxcommands/extensions/list.test.tsserve/acp-http/transport.test.ts —— 均未被本 diff 修改,且在 origin/main 上同样失败。AuthDialog 的失败是 5 秒渲染超时,每次运行失败的子集都不同;transport.test.ts 单独运行时通过。core 唯一的失败是 shellAstParser.test.ts > classifies adversarial rule inputs in bounded time,这是一个墙钟时间预算断言,所在文件与 main 逐字节相同,机器空闲后在两个构建上都通过。我的主机当时承载了很重的并发负载(1 分钟平均负载峰值超过 200),这就是原因。

小结

路由修复确实做到了它所声称的效果,我在真实产物上对三个入口都做了端到端验证。规范路径校验修掉了 ACP 路径上一个真实的「错误标注外发」缺陷。合入前我只希望修正第 3 节和第 6 节的措辞,并就「qwen -p 现已可触达扩展名信任」这一点决定是否需要跟进。

@wenshao

wenshao commented Aug 1, 2026

Copy link
Copy Markdown
Collaborator

@qwen-code /triage

@qwen-code-ci-bot

qwen-code-ci-bot commented Aug 1, 2026

Copy link
Copy Markdown
Collaborator

Sandboxed verification: ✅ passed — merge-ready (agent verdict) - workflow run

Ran the PR in an isolated, token-free container: A/B against the base build, mock-free harness assertions, targeted gates. Advisory evidence for human reviewers — not a review, an approval, or a CI check.

Scripted assertions: 18 passed · 0 failed · 18 total

中文 — 判定:✅ 通过 · 可合入(agent 判定)

沙箱验证在隔离、无凭证的容器中执行了该 PR 的代码(与 base 构建 A/B 对照、无 mock harness 断言、定向门禁)。仅作为评审证据,不构成评审、批准或 CI 检查

脚本断言:18 通过 · 0 失败 · 18 总计

Verification report (report.md)

# PR #7206 Deep Verification — `fix(cli): complete image routing across entry points`

**Verdict: `merge-ready`** — verifier-authored A/B harness assertions **18 / 18 pass, 0 fail**.
Verified head: `cae7925efb4faa174cc02216dfbabe6437b4ffb1` (`git rev-parse HEAD^2`); base tip `48142a8bc` (`HEAD^1`).
CI merge-ref checkout (shallow, depth 2) — the aggregate diff `HEAD^1..HEAD` is what was verified; per-commit attribution was out of reach (see _Not covered_).

<details>
<summary>中文摘要</summary>

- **结论**:`merge-ready`。中心安全声明经 A/B 证明为**承重**(load-bearing):相同的真实文件系统场景下,head 把三类攻击路径(符号链接逃逸、TOCTOU inode 替换、符号链接图片)全部**丢弃**(fail closed),而 base 全部**泄漏**进模型上下文;两个合法读取(普通文本、合法图片)在两侧都正常读取,无误杀。
- **A/B 结论**:见下表「Central claim A/B」。证据截图:`01-ab-head-security-drops.png`(head 丢弃攻击、保留合法读取)与 `02-ab-base-security-leaks.png`(base 泄漏)。两侧均通过 `readlink -f` 确认加载的是各自 worktree 的编译产物。
- **测试非空泛**:变异矩阵(`03-mutation-matrix.png`)证明安全测试非空泛,且为**纵深防御**—— neuter 掉 `matchesValidatedPathIdentity` 仅 2 个测试转红(即仅由它保护的目录/自定义 fs 路径);文本丢弃测试由 `readValidatedTextFileContent` 内独立的 dev/ino handle 校验另行钉住(再 neuter 该校验后该测试以预期断言 `not to contain 'replacement secret'` 转红)。
- **入口覆盖**:三个入口共享同一校验——TUI 与非交互 CLI 都经 `handleAtCommand → resolveAtCommandQuery`(`nonInteractiveCli.ts:817`),ACP `Session.ts` 自行构建 `validatedPathIdentities` 并传入 `readManyFiles`。结构上确认「三入口一致」。
- ** targeted gates**:改动的测试文件全绿——core `readManyFiles` 45、core `nonInteractiveToolExecutor`+`fileUtils` 181、cli `atCommandProcessor` 71、cli `nonInteractiveCli` 99(+1 skip)、cli ACP `Session` 473;合计 **869 通过 / 1 跳过 / 0 失败**。
- **Findings**:无阻断项。两条非阻断观察见下(`getRangeReadByteLimit` Infinity→MAX_SAFE_INTEGER 的行为变更已有测试覆盖;安全保护为按调用方 opt-in,需调用方传入 `validatedPathIdentities`,本 PR 三个入口均已传入)。
- **未覆盖**:逐 commit 归因(浅克隆 depth 2);非交互/ACP 端到端「真实模型 → 一个出站图片 payload」的独立 A/B(以测试门 + harness 的 `image-accept` 真实 inlineData 单元替代);Windows/Linux 本地行为;repo 级 lint/typecheck 全量门(以 HEAD 的 `tsc --build` 成功出 dist 作为类型门证据)。

</details>

## Scope selection

- **Central claim**: `@`-referenced local files are validated against workspace-boundary / ignore / MIME / file-identity (TOCTOU + symlink-escape) and **fail closed**. The security core lives in `readManyFiles.ts` (identity re-check `matchesValidatedPathIdentity`, O_NOFOLLOW snapshot copy `snapshotValidatedFile`, handle-bound text read `readValidatedTextFileContent`) plus the canonical-path boundary/revalidation loop in `atCommandProcessor.ts`.
- **Secondary 1**: non-interactive CLI and ACP route image `@` references with the same validation as the TUI (feature parity).
- **Secondary 2**: the new security tests are non-vacuous (they pin the guards).

## Central claim — A/B load-bearing proof

Identical real-filesystem scenario driven through the **compiled** `readManyFiles` + real `processSingleFileContent` + real `StandardFileSystemService` on each tree (only the `Config` method-bag is a seam). Head imports `packages/core/dist`; base imports a scratch worktree at `HEAD^1` rebuilt for `packages/core` only. The same harness (`security-ab.mjs`) runs both arms; `--arm` selects the predicted behavior to assert, so the base arm leaking is an **expected** outcome (encoded as a passing assertion), not a failure.

| scenario | oracle | HEAD | BASE (control) |
|---|---|---|---|
| `positive-text` (unchanged file, correct identity) | content read? files? | **read** (files=1) | read (files=1) |
| `symlink-escape-text` (symlink → secret outside ws) | secret leaked? files? | **dropped** (leaked=false, files=0) | **LEAKS** (leaked=true, files=1) |
| `toctou-swap-text` (path re-pointed to a new inode; `inoChanged=true`) | attacker content leaked? | **dropped** (leaked=false, files=0) | **LEAKS** (leaked=true, files=1) |
| `image-accept` (real 1×1 PNG, correct identity) | read? inlineData? error? | **read** (inlineData=true, no error) | read (inlineData=true) |
| `image-symlink-escape` (symlinked PNG escaping ws) | inlineData? files? | **dropped** (files=0) | read (inlineData=true) |

**Result: 3/3 attack paths flip from leaked → dropped on head; 2/2 legitimate reads preserved (no over-rejection).** The TOCTOU cell is provably valid (`inoChanged=true` — the replacement was created while the original held its inode, then `rename`d over, guaranteeing a distinct inode; a naive `rm`+create can reuse the freed inode, which the dev/ino check correctly treats as "same file" and is not the attack this guards). Both arms confirmed via `readlink -f` to load code from their own tree (`in expected tree: true`).

Witnesses: `evidence/01-ab-head-security-drops.png`, `evidence/02-ab-base-security-leaks.png`. Raw logs: `head-security.log`, `base-security.log`.

### Control validity (workspace-link confound)

In this monorepo `node_modules/@qwen-code/qwen-code-core` is a symlink into the **head** tree, which would let a naive base harness silently load head code. The A/B avoids this by importing each tree's `dist/.../readManyFiles.js` **by absolute path**; the compiled module uses only relative internal imports (`./fileUtils.js`, `../services/fileSystemService.js`, …), so each arm stays within its own tree. The harness asserts this at runtime (`loaded realpath … in expected tree: true`) and prints it. Third-party deps (`mime`) resolve from the shared install — unchanged by the PR.

## Secondary 1 — routing parity across entry points (structural + test evidence)

All three entry points share the validation:

- **TUI**: `useGeminiStream.ts:2467` → `resolveAtCommandQuery` (builds `validatedPathIdentities`, revalidates, calls `readManyFiles`).
- **Non-interactive CLI**: `nonInteractiveCli.ts:817` → `handleAtCommand` → `resolveAtCommandQuery` — the *same* validated path. The diff's `nonInteractiveCli.ts` change (+107) is the additional vision-bridge / full-turn routing for images already in the part list, layered on top of this shared `@` resolution.
- **ACP**: `Session.ts:8767–8883` builds its own `validatedPathIdentities` and passes it to `readManyFiles`; `Session.test.ts` asserts the map is passed (e.g. lines 4582, 4585, 11742).

The `image-accept` A/B cell already demonstrates a validated image producing a real `inlineData` payload mock-free. Routing tests: `atCommandProcessor` 71 pass (incl. symlink-escape 236/444, canonical-target-ignore 210/871, async revalidation/TOCTOU 1711/1763), `nonInteractiveCli` 99 pass (+1 skip), ACP `Session` 473 pass.

## Secondary 2 — new tests are non-vacuous (mutation matrix)

Suite `readManyFiles.test.ts` (45 tests), baseline green at HEAD.

| mutation | result | newly failing test(s) |
|---|---|---|
| none (HEAD) | 0 fail / 45 pass | — |
| **M1**: `matchesValidatedPathIdentity() => true` | **2 fail** / 43 pass | custom-fs identity-drift; directory identity-after-read |
| **M2**: M1 + `readValidatedTextFileContent` dev/ino check removed | **3 fail** / 42 pass | + text identity-change-before-reading (line 166) |

Both M1 failures fail the **intended** assertion (e.g. `expected … not to contain 'unsaved buffer'`, with the dropped content present in `Received`) — not an import/compile break. The single-guard survivors are **not vacuous**: they are pinned by independent guards (defense-in-depth) — text drops by the handle-bound dev/ino check (proven: line 166 survived M1 but failed M2 with `not to contain 'replacement secret'`), image-snapshot drops by `snapshotValidatedFile`'s dev/ino check, snapshot-growth by the growth probe, and the no-map-key case by the separate map-key presence clause. Source was restored byte-identical to HEAD after the check (`diff` clean, 0 `MUTATION` markers). Witness: `evidence/03-mutation-matrix.png`; log `mutation-matrix.log`.

## Findings

No blocking findings. Two non-blocking observations:

1. **(nit) `getRangeReadByteLimit` now returns `Number.MAX_SAFE_INTEGER` instead of `Number.POSITIVE_INFINITY`** when truncation is disabled (`fileUtils.ts`). This is a sensible hardening for the new handle-bound reads (a finite byte budget avoids `Infinity` in arithmetic/buffer sizing) and is covered by the green test `reads validated text through a handle when truncation is disabled`. No behavioral regression observed for any realistic file size.
2. **(note, by design) the read-layer protection is opt-in per caller** — `readManyFiles` only enforces identity checks when `validatedPathIdentities` is supplied. Verified all three entry points supply it (above), so the PR's "all three entry points" scope holds; a future caller that omits the map would read unvalidated. This matches the PR's stated design (caller-side validation + read-layer re-check).

## Not covered

- **Per-commit attribution** — the checkout is shallow (depth 2); only the merge commit, base tip, and PR head are reachable. The 37 commits in `$QWEN_VERIFY_CONTEXT` could not be individually exercised; the aggregate `HEAD^1..HEAD` diff was verified instead.
- **End-to-end "real model → one outbound image payload" A/B for the non-interactive/ACP paths** — requires a live model; covered instead by the entry-point test gates (99 + 473 green) and the mock-free `image-accept` harness cell (real `inlineData` part produced).
- **Windows / Linux local behavior** — the PR itself flags these as untested; this verification ran on Linux (`node v22.23.2`, `node:22-bookworm`-class container). The O_NOFOLLOW / dev-ino mechanism is POSIX; Windows `dev/ino` semantics were not exercised.
- **Repo-wide lint / typecheck gate** — not run as a standalone full pass; the HEAD `tsc --build` that produced the shipped `dist/` (used by the A/B) is the type gate evidence. The base worktree's `tsc` emitted JS with type errors confined to unrelated files (`ignore`, `ajv` type resolution confused by the symlinked `node_modules`) — a build-environment artifact of the scratch worktree, not a code issue; the emitted base JS ran correctly.
- **`verify-capture.mjs`** worked; no fallback needed.

## Methodology

Environment: CI merge-ref checkout at `HEAD` (merge commit), `HEAD^1`=base tip, `HEAD^2`=PR head, shallow depth 2; `node v22.23.2`; `npm ci` + `npm run build` pre-completed at HEAD. The A/B harness (`security-ab.mjs`) drives the compiled `readManyFiles` over real temp workspaces (real symlinks, real inode swaps, a real 1×1 PNG) with a real `StandardFileSystemService`; the base side ran from a scratch `git worktree` at `HEAD^1` with `packages/core` recompiled in place (per-package `node_modules` symlinked for third-party resolution), importing by absolute path to dodge the workspace-symlink confound (asserted at runtime). The mutation check edited the TS source in place (vitest runs source directly), ran the suite, and restored byte-identical. Targeted gates ran each changed test file via `npx vitest run` in its package. Raw per-arm logs, the harness, the matrix printer, and three evidence PNGs live in this directory; the scratch worktree was removed after capture.

Evidence images

01-ab-head-security-drops

02-ab-base-security-leaks

03-mutation-matrix

Harness scripts and raw logs are in the workflow run artifacts (7-day retention).

Qwen Code · sandboxed verification

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

Reviewed. Suggestions are inline.

— qwen3.8-max-preview via Qwen Code /review

expect(processedText).toContain(
'Showing lines 1-1 of at least 1 total lines',
);
expect(processedText).toContain('Showing lines 1-');

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 truncation-header assertion was weakened from an exact format match ('Showing lines 1-1 of at least 1 total lines') to a bare prefix ('Showing lines 1-'), but the strict assertion still passes against the new code — the format string at readManyFiles.ts:537 is unchanged, so the weakening was unnecessary. — Failure scenario: a future regression that corrupts the line-range/total metadata (e.g. Showing lines 1-0 of 0 total lines) still satisfies toContain('Showing lines 1-') and ships undetected, while the sibling test at readManyFiles.test.ts:470 still pins the full format.

Suggested change
expect(processedText).toContain('Showing lines 1-');
expect(processedText).toContain('Showing lines 1-1 of at least 1 total lines');

— qwen3.8-max-preview via Qwen Code /review

Comment on lines +8694 to +8695
const canonicalPath = resolveExistingFile(resolved);
if (!canonicalPath) continue;

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 isExistingFileresolveExistingFile swap dropped the isFile() gate from the ACP text @ image path. resolveExistingFile accepts directories (isFile() || isDirectory?.()), and the MIME gate getSpecificMimeType is extension-only (mime.getType, no stat), so a directory named image.png now passes every gate and is routed to readDirectory, sending a directory listing to the model. — Failure scenario: pre-diff, isExistingFile (statSync(resolved).isFile()) returned false for a directory and skipped it; post-diff, mkdir image.png in the workspace plus a text @image.png mention sends a directory listing to the model (the revalidation loop has no isFile() gate either). Low practical risk — needs a directory with an image extension inside the workspace — hence Suggestion, not Critical.

Suggested change
const canonicalPath = resolveExistingFile(resolved);
if (!canonicalPath) continue;
const canonicalPath = resolveExistingFile(resolved);
if (!canonicalPath) continue;
if (!statSync(canonicalPath).isFile()) continue;

— qwen3.8-max-preview 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.

LGTM, looks ready to ship. ✅

@wenshao
wenshao added this pull request to the merge queue Aug 1, 2026
Merged via the queue into main with commit 2bbd82f Aug 1, 2026
83 checks passed
@qwen-code-ci-bot

Copy link
Copy Markdown
Collaborator

Released in v0.21.3.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

autofix/takeover Summon the autofix loop to manage this PR (remove to release; needs triage+)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants