Skip to content

feat(cli): show loaded context files alongside the first prompt - #8855

Merged
yiliang114 merged 21 commits into
QwenLM:mainfrom
ZijianZhang989:context-file-visibility
Aug 19, 2026
Merged

feat(cli): show loaded context files alongside the first prompt#8855
yiliang114 merged 21 commits into
QwenLM:mainfrom
ZijianZhang989:context-file-visibility

Conversation

@ZijianZhang989

Copy link
Copy Markdown
Collaborator

What this PR does

When users attach custom context files via context.fileName in settings, the file contents are merged into the system prompt — a channel that is invisible in the conversation UI and never persisted to chat history. This PR makes the attachment visible: on the user's first real prompt of a session, a one-shot INFO line is shown right above that prompt listing exactly which context files were attached (e.g. Read context files: ~/.qwen/QWEN.md, QWEN.md, MY_RULES.md). The list is computed from the same discovery result that builds the system prompt, so what is displayed is exactly what was attached. The announcement only appears once per session, and only when at least one context file was actually loaded. Display paths are kept readable: files inside the project show as CWD-relative paths, while files under the user home (global memory, extensions) are shown with a ~/... shortcut instead of long ../../.. chains. The same ~/... shortcut is now applied to the per-file memory breakdown in /context detail, which previously rendered global files as truncated ../../../Users/... paths.

Why it's needed

Reported in #5267: a user configured context.fileName with a mistyped file name and had no way to tell whether the file was actually read. The only workarounds were digging into debug logs or running /context and comparing token counts. The reporter explicitly asked for a "read file" indication shown alongside the first prompt, mirroring how agent file reads appear in the console — so users can immediately distinguish "the file was never loaded" from "the model didn't follow the instructions". This PR delivers exactly that.

Reviewer Test Plan

How to verify

  1. In a scratch directory, create QWEN.md and a second file (e.g. MY_RULES.md), then add .qwen/settings.json with "context": { "fileName": ["QWEN.md", "MY_RULES.md"] }.
  2. Start the CLI and confirm the startup screen shows no new message (the announcement is intentionally not at startup).
  3. Send any prompt. Expected: one INFO line Read context files: ... appears directly above your prompt, listing exactly the configured files (plus any global/extension memory files).
  4. Send a second prompt. Expected: the line does not repeat.
  5. Typo check: change the setting to a non-existent file name (e.g. MY_RULESX.md), restart, send a prompt. Expected: the mistyped file is absent from the list.
  6. Run /context detail. Expected: the Memory files section shows the same files, with global files rendered as ~/... instead of ../../../Users/....
  7. Content check (optional): put a unique rule in a context file (e.g. "end every reply with [X]") and confirm the model follows it — the displayed list corresponds to content actually in the system prompt.

Evidence (Before & After)

Before (no indication anywhere; user must run /context and infer):

> 你好,只回复ok
◆︎ ok

After (first prompt, one-shot INFO line with readable paths):

●︎ Read context files: ~/.qwen/QWEN.md, QWEN.md, MY_RULES.md, ~/.qwen/extensions/refresh-fixture-a/QWEN.md
> 你好,只回复ok
◆︎ ok

After (typo scenario — mistyped MY_RULESX.md absent from list):

●︎ Read context files: ~/.qwen/QWEN.md, QWEN.md, ~/.qwen/extensions/refresh-fixture-a/QWEN.md
> hi

Before/After for /context detail memory breakdown:

Before:  └ ../../../Users/zhangzijian/.q…   2.2k tokens
After:   └ ~/.qwen/extensions/superpower…   2.2k tokens

Tested on

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

Environment (optional)

Built bundle (npm run build && npm run bundle), run interactively in tmux from a scratch directory.

Risk & Scope

  • Main risk or tradeoff: one extra INFO line appears once per session when context files are loaded; sessions with no context files show nothing. Safe mode reports an empty list (nothing shown).
  • Not validated / out of scope: SDK / non-interactive paths (announcement is a CLI UI concern only); webui.
  • Breaking changes / migration notes: none. The contextFilePaths field added to the memory-discovery response is additive.

Linked Issues

Fixes #5267

中文说明

本 PR 做了什么:用户通过 settings 中的 context.fileName 附加自定义 context 文件时,文件内容会合并进 system prompt——这条通道在会话界面不可见,也不会写入聊天历史。本 PR 让附加行为可见:在会话的第一条真实 prompt 上方,一次性显示一行 INFO 提示,列出实际附加了哪些 context 文件(如 Read context files: ~/.qwen/QWEN.md, QWEN.md, MY_RULES.md)。列表与构建 system prompt 用的是同一份发现结果,显示的即实际附加的。提示每个会话只出现一次,且仅在至少加载了一个文件时才出现。路径展示保持可读:项目内文件显示为 CWD 相对路径,用户主目录下的文件(全局 memory、扩展)用 ~/... 缩写代替冗长的 ../../.. 链。/context detail 的逐文件 memory 明细也应用了同样的 ~/... 缩写,此前全局文件显示为被截断的 ../../../Users/... 路径。

为什么需要#5267 报告者在 context.fileName 里拼错了一个文件名,却没有任何办法确认文件是否真的被读取,唯一的手段是翻 debug 日志或运行 /context 比对 token 数。报告者明确要求在第一条 prompt 时显示类似"读取文件"的提示,就像 agent 读源文件时在控制台显示的那样——这样用户可以立即区分"文件根本没加载"和"模型没遵守指令"。本 PR 正是实现了这一点。

验证方式:在临时目录创建 QWEN.mdMY_RULES.md 并配置 context.fileName;启动 CLI 确认启动区无新消息;发送第一条 prompt,预期上方出现 Read context files: ... 一行;发送第二条 prompt,预期不重复;把配置改成拼错的文件名后重启,预期该文件从列表消失;运行 /context detail,预期 Memory files 明细中全局文件显示为 ~/...;可选内容级验证:在 context 文件中写一条独特规则(如"每条回复以 [X] 结尾"),确认模型遵守——证明列表与 system prompt 内容一致。

风险与范围:每个会话在加载了 context 文件时多显示一行 INFO;无 context 文件时不显示任何内容;safe mode 下为空列表。SDK/非交互路径与 webui 不在范围内(提示纯属 CLI UI 层)。memory 发现响应新增的 contextFilePaths 字段是纯增量的,无破坏性变更。

When context files (QWEN.md / context.fileName) are attached to the
system prompt, surface a one-shot INFO line above the user's first
prompt listing exactly which files were loaded, so users can verify
discovery (e.g., catch typos in context.fileName) without digging
into debug logs.

Also shorten display paths for files under the user home to `~/...`
in both the announcement and the /context detail breakdown.

Fixes QwenLM#5267
@ZijianZhang989

Copy link
Copy Markdown
Collaborator Author

E2E Test Report (tmux, macOS)

Bundle built via npm run build && npm run bundle, run interactively from a scratch directory with QWEN.md + MY_RULES.md configured via context.fileName.

1. Startup — no new message (by design)

Tips: Try /insight to generate personalized insights from your chat history.
>   Type your message or @path/to/file

2. First prompt — one-shot announcement appears above the prompt

●︎ Read context files: ~/.qwen/QWEN.md, QWEN.md, MY_RULES.md, ~/.qwen/extensions/refresh-fixture-a/QWEN.md
> 你好,只回复ok
◆︎ ok

3. Second prompt — no repeat (full-screen grep count stays at 1)

> 再回一次ok
◆︎ ok

4. Typo scenario — MY_RULESX.md immediately absent from the list

●︎ Read context files: ~/.qwen/QWEN.md, QWEN.md, ~/.qwen/extensions/refresh-fixture-a/QWEN.md
> hi

5. Content really reaches the model (canary test)

A unique rule ("end every reply with [CTX-LOADED-42]") and a secret fact ("codename BLUEWHALE-2026") were placed only in the context files; the model followed the marker and answered the codename correctly. /context detail lists the same files (now with ~/... paths).

@qwen-code-ci-bot

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

Copy link
Copy Markdown
Collaborator

Qwen Triage finished — CI landed green on ea9d3d1 and the deferred approval was posted. finalize run

Qwen Triage 已完成 —— ea9d3d1 的 CI 全绿,延迟审批已提交。查看 finalize 运行

@qwen-code-ci-bot

Copy link
Copy Markdown
Collaborator

Thanks for the PR!

Template looks good ✓

Problem: real and observed. #5267 started as a "context.fileName doesn't work" report, but the thread established that the files ARE loaded (verifiable via /context) — just invisibly, merged into the system prompt. The reporter then explicitly asked for exactly what this PR builds: a "Read file"-style indication alongside the first prompt, so a mistyped context.fileName entry can be told apart from "the model ignored the instructions." Not theoretical hardening — the requested UX is quoted in the issue.

Direction: aligned. A small observability win requested by the reporter themselves, scoped to the CLI UI plus one additive response field. No direct counterpart found in the claude-code CHANGELOG, but context/memory-file handling is an active area there too (CLAUDE.md /doctor trimming suggestions, safe-mode disabling, memory frontmatter work), so the space is relevant.

Size: core paths touched. Production logic ≈168 lines (core: config.ts 51, memoryDiscovery.ts 42; CLI: AppContainer.tsx 64, contextCommand.ts 9, directoryCommand.tsx 2) vs. ≈111 test lines. Well under every threshold — no maintainer size escalation.

Approach: right shape. The displayed list is carved out of the same discovery result that builds the system prompt, so what is shown cannot drift from what was attached — that's the design decision that matters, and it's the right one. The rest is mechanical: one additive response field, a Config getter/setter, a one-shot INFO item on the first non-slash submit, and the same display helper fixing the ../../../Users/... chains in /context detail. That last bit is strictly beyond the announcement, but it's the same helper and the same display concern, so it earns its place. No unrelated churn in the diff.

Risk: no high-risk path matches against the revert-correlated path list.

Moving on to code review. 🔍

中文说明

感谢贡献!

模板完整 ✓

**问题:**真实且已观测。#5267 最初报告 "context.fileName 不生效",但讨论串确认文件确实被加载了(可通过 /context 验证)——只是不可见,内容被合并进了 system prompt。报告者随后明确要求的正是本 PR 实现的东西:在第一条 prompt 旁显示类似"读取文件"的提示,从而区分"拼错了文件名"和"模型没遵守指令"。不是理论性加固——issue 里原话记录了所请求的交互。

**方向:**对齐。这是报告者本人要求的小型可观测性改进,范围限于 CLI UI 加一个增量响应字段。claude-code CHANGELOG 没有直接对应项,但 context/memory 文件处理在那边也是活跃领域(CLAUDE.md /doctor 精简建议、safe-mode 禁用、memory frontmatter 等),方向相关。

**规模:**触及核心路径。生产逻辑约 168 行(core:config.ts 51、memoryDiscovery.ts 42;CLI:AppContainer.tsx 64、contextCommand.ts 9、directoryCommand.tsx 2),测试约 111 行。远低于所有阈值,无需维护者规模升级。

**方案:**形态正确。展示列表直接取自构建 system prompt 的同一份发现结果,因此显示内容与实际附加不可能漂移——这是最关键的设计决策,且是正确的。其余是机械工作:一个增量响应字段、Config getter/setter、首次非 slash 提交时的一次性 INFO 提示,以及同一个显示助手顺带修复 /context detail 里的 ../../../Users/... 链。后者严格来说超出了公告本身,但用的是同一个助手、同一个展示关注点,放在一起合理。diff 无无关改动。

**风险:**未命中 revert 相关高风险路径。

进入代码审查 🔍

Qwen Code · qwen3.8-max

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

@qwen-code-ci-bot

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

Copy link
Copy Markdown
Collaborator

Code review

The implementation matches the design described in the PR. I verified the wiring end-to-end against the base code:

  • Displayed = attached, by construction. contextFilePaths is carved out of the same contentsWithPaths inside loadServerHierarchicalMemory that builds memoryContent, using the identical filter that computes fileCount — so system context files (e.g. the output-language preference) are excluded exactly like the count, and fileCount semantics are unchanged (the filter just moved into a local).
  • All consumers updated. Every caller of loadServerHierarchicalMemory is covered: core Config.refreshHierarchicalMemory (including the safe-mode early return), AppContainer's performMemoryRefresh, and the /directory refresh. The CLI wrapper loadHierarchicalGeminiMemory returns the response directly, so the field passes through. The acp-bridge reference is a doc comment about fileCount only — nothing else constructs the response.
  • Timing is safe. Config.initialize() awaits the session-start memory load before the CLI's input_enabled checkpoint resolves, so the paths are populated before the first submit is possible — no race where the announcement would fire against an empty list. Safe mode clears the list in both the core and CLI paths.
  • The /context detail change is sound. Marker paths are CWD-relative (see concatenateInstructions), so resolving them against process.cwd() before formatContextFileDisplayPath reconstructs the right paths; the backreference regex is untouched, and the one existing path assertion in contextCommand's tests covers the unchanged no-marker fallback.
  • No test breakage expected. AppContainer tests use makeFakeConfig() (a real Config), so the new getter/setter exist automatically; the home-dir boundary check (userHomePath + path.sep) avoids /home/user2 matching /home/user; CWD-relative wins over ~/... when a project lives under home.

Non-blocking nits:

  1. The one-shot guard checks !isSlashCommand(userPromptText) only, while every adjacent one-shot notice (recovered-agents, worktree, workflow trigger) also excludes isBtwCommand. A ?btw side-question as the session's first input would consume the announcement. Cosmetic — but the exclusion pattern is established right next door.
  2. No unit test for the announcement itself (one-shot semantics, slash-command skip, empty-list silence). The data path is thoroughly covered in core; the AppContainer side currently rests on the author's tmux report. Suggestion, not a blocker.

Test evidence (the PR's own CI, read via API)

On the reviewed commit the main suite is still running; nothing is red so far. The Windows/macOS unit legs are skipped by design on PRs — they only run in the merge queue (event == 'merge_group'), so ubuntu is the gate here. The triage / review-pr in-flight entries are bot orchestration jobs, not PR CI.

Final CI results for ea9d3d1 (auto-updated by the triage finalize job after CI completed):

Check Conclusion
Classify PR ✅ success
Desktop Shell (ubuntu-22.04) ✅ success
Desktop Shell (windows-2022) ✅ success
Test (ubuntu-latest, Node 22.x) ✅ success
web-shell E2E Smoke (ubuntu-latest, Node 22.x) ✅ success

One row per check name (latest run); skipped checks omitted; failures sort first. / 每个检查名一行(取最新一次运行),省略 skipped,失败项排在最前。

The announcement line itself is a TUI-surface behaviour that nothing in the suite pins (no AppContainer test submits a prompt and asserts the INFO item). Sandboxed verification would settle this: @qwen-code /tmux — that the Read context files: line appears exactly once, directly above the first non-slash prompt, and that a mistyped context.fileName entry drops out of the list. The author already posted a macOS tmux report in this thread covering those scenarios (including a canary proving the listed files really reach the model); that is the author's claim and is consistent with my static read, but it is not an independent run, and Windows/Linux remain untested.

中文说明

代码审查

实现与 PR 描述的设计一致,我对照基础代码逐条验证了接线:

  • 显示即附加,构造上保证。 contextFilePaths 取自 loadServerHierarchicalMemory 内构建 memoryContent 的同一份 contentsWithPaths,且复用计算 fileCount 的同一个过滤器——系统 context 文件(如 output-language 偏好)与计数一样被排除,fileCount 语义不变。
  • 所有消费方已更新。 loadServerHierarchicalMemory 的全部调用方均已覆盖:core 的 Config.refreshHierarchicalMemory(含 safe-mode 提前返回)、AppContainer 的 performMemoryRefresh/directory 刷新。CLI 包装函数 loadHierarchicalGeminiMemory 直接返回响应对象,字段透传。acp-bridge 仅是引用 fileCount 的文档注释,没有其他地方构造该响应。
  • 时序安全。 Config.initialize() 在 CLI 的 input_enabled 检查点之前就 await 了会话启动时的 memory 加载,首次提交时路径必然已填充——不存在公告对着空列表触发的竞态。safe mode 在 core 与 CLI 两条路径都会清空列表。
  • /context detail 改动合理。 marker 路径是 CWD 相对的,先对 process.cwd() resolve 再走 formatContextFileDisplayPath 可正确还原;正则回退引用未动,现有唯一的路径断言覆盖的是未改动的无 marker 回退分支。
  • 预期不会破坏测试。 AppContainer 测试使用 makeFakeConfig()(真实 Config),新 getter/setter 自动存在;home 目录边界检查避免了 /home/user2 误匹配 /home/user;项目位于 home 之下时 CWD 相对路径优先于 ~/...

非阻塞建议:

  1. 一次性守卫只检查 !isSlashCommand,而相邻的所有一次性通知还排除了 isBtwCommand。若会话第一条输入是 ?btw 侧边提问,会消耗掉公告。属于外观问题,但排除模式就在旁边。
  2. 公告本身没有单元测试(一次性语义、slash 跳过、空列表静默)。数据路径在 core 覆盖充分;AppContainer 侧目前依赖作者的 tmux 报告。建议补充,不阻塞。

测试证据

在被审查的 commit 上,主套件仍在运行,暂无红色。Windows/macOS 单测在 PR 上按设计跳过——它们只在 merge queue(merge_group)运行,此处 ubuntu 即门禁。在途的 triage / review-pr 是 bot 编排任务,不是 PR CI。

公告行本身是 TUI 表面行为,套件没有任何测试钉住它。沙盒验证可以定论:@qwen-code /tmux —— Read context files: 行恰好出现一次、位于第一条非 slash prompt 上方,且拼错的 context.fileName 条目会从列表消失。作者已在本帖贴出覆盖这些场景的 macOS tmux 报告(含 canary 证明文件内容确实到达模型);那是作者单方声明,与我的静态审查一致,但并非独立运行,Windows/Linux 仍未测试。

Qwen Code · qwen3.8-max

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

@qwen-code-ci-bot

Copy link
Copy Markdown
Collaborator

Confidence: 4/5 — clean, focused implementation of an explicitly requested UX gap; the two nits are cosmetic, and the TUI surface itself waits on CI (and optionally /tmux).

My independent proposal for this problem was exactly the shape this PR took: derive the displayed list from the same discovery result that builds the system prompt so it cannot lie, stash it on Config, and fire a one-shot notice above the first real prompt — with a shared path-shortening helper that /context detail reuses. The PR matches that proposal and carries nothing extra; the /context detail fix is the same helper earning its keep next door.

The problem is verified, not assumed: the #5267 thread shows the runtime already loads the files correctly, and the reporter explicitly asked for this exact indication — the mistyped-filename scenario is precisely what the list makes obvious. The core footprint is two small additive pieces (a response field, a getter/setter pair) that will read trivially in six months. The reservations are minor: the ?btw guard inconsistency and the missing unit test for the announcement line itself — neither blocks.

CI is still running on the reviewed commit (one pull_request workflow run, Qwen Code CI, in flight), so approval is deferred until it lands green — this comment carries the marker that performs the commit-pinned approval automatically once every check settles, and withholds it if anything lands red. A maintainer can also trigger @qwen-code /tmux for independent TUI evidence in the meantime.

中文说明

置信度:4/5 —— 对一个被明确请求的 UX 缺口,实现干净而聚焦;两条建议均属外观层面;TUI 表面本身等待 CI(可选 /tmux)。

我对这个问题的独立方案与本 PR 的形态完全一致:从构建 system prompt 的同一份发现结果派生展示列表,使其不可能失真;存放在 Config 上;在第一条真实 prompt 上方触发一次性提示——并提供一个 /context detail 复用的路径缩写助手。PR 与该方案一致且没有多余内容;/context detail 修复是同一个助手顺带发挥作用。

问题是经过验证的,不是假设:#5267 讨论串表明运行时本来就正确加载了文件,而报告者明确要求的正是这个提示——拼错文件名的场景正是列表能立刻暴露的。核心足迹是两个小的增量部件(一个响应字段、一对 getter/setter),六个月后依然一目了然。保留意见都很轻微:?btw 守卫不一致、公告行本身缺单元测试——均不阻塞。

被审查的 commit 上 CI 仍在运行(一个 pull_request 工作流 Qwen Code CI 在途),因此批准推迟到其变绿为止——本评论携带的标记会在所有检查通过后自动执行钉住 commit 的批准,若有检查变红则拒绝执行。维护者也可以随时触发 @qwen-code /tmux 获取独立的 TUI 证据。

Qwen Code · qwen3.8-max

Reviewed at ea9d3d1e9589e6ef7252056a67b2b97b1e5804d1 · 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.

LGTM, looks ready to ship — CI landed green after the 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.

Not reviewed: build-and-test — Test (windows-latest, Node 22.x) was skipped in CI and its suite did not run locally.

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

Not explored to full depth (tool budget reached): PR #8855 adds a one-shot INFO line listing the loaded con...: could not run the test suites — no node_modules in the review worktree and vitest failed to load; conclusions are from reading the test code, not executing it….

Not reviewed: reverse audit — stopped before round 5 by the review time budget.

中文说明

未审查:build-and-test — Test (windows-latest, Node 22.x) 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。

未探索到全部深度(达到工具调用预算):PR #8855 adds a one-shot INFO line listing the loaded con...:could not run the test suites — no node_modules in the review worktree and vitest failed to load; conclusions are from reading the test code, not executing it…

未审查:反向审计——评审时间预算不足,未能开始第 5 轮。

— qwen3.8-max via Qwen Code /review (v0.21.8)

Comment thread packages/cli/src/ui/commands/contextCommand.ts
Comment thread packages/cli/src/ui/AppContainer.tsx Outdated
Comment thread packages/core/src/utils/memoryDiscovery.test.ts Outdated
Comment thread packages/core/src/utils/memoryDiscovery.ts Outdated
Comment thread packages/core/src/utils/memoryDiscovery.ts
Comment thread packages/cli/src/ui/AppContainer.tsx Outdated
Comment thread packages/cli/src/ui/commands/contextCommand.ts Outdated
Comment thread packages/core/src/utils/memoryDiscovery.ts Outdated
Comment thread packages/core/src/utils/memoryDiscovery.test.ts Outdated
Comment thread packages/cli/src/ui/AppContainer.tsx Outdated
- Resolve memory-marker paths against the session working directory
  instead of process.cwd() in /context detail (ACP/daemon sessions)
- Sanitize display paths with stripAnsiAndControl before they reach
  the terminal
- Drop empty context files from the announced list to match
  concatenateInstructions' empty-content filter
- Delegate home-dir shortening to tildeifyPath (with an optional home
  override for tests) instead of a second prefix-check implementation
- Align the one-shot announcement guard with downstream input
  classification (trim, /btw, shell mode)
- Add tests for the announcement latch, parseMemoryFiles ~ shortening,
  CWD-under-home and home-prefix-collision cases; use shared-volume
  fixtures so tests hold on Windows
@ZijianZhang989

Copy link
Copy Markdown
Collaborator Author

Review feedback addressed (f2e90c6)

Triage of the 12 findings from the automated review — 10 accepted, 2 declined with rationale below.

Accepted & fixed

Severity Finding Fix
Critical /context detail re-resolved memory markers against process.cwd() parseMemoryFiles now takes config.getWorkingDir() and uses it for both path.resolve and the display-path CWD
Critical Unsanitized filesystem paths reaching the terminal Sanitization moved into formatContextFileDisplayPath (stripAnsiAndControl on every return branch), covering both the announcement and the /context display surface at the source
Critical POSIX test literals break under path.win32 on the merge-queue Windows gate Fixtures rebuilt on a shared volume rooted at os.tmpdir() so the .. relationships hold on every platform
Suggestion Empty files announced as read contextFilePaths now applies the same predicate as concatenateInstructions (content.trim().length > 0)
Suggestion Home-shortening re-implemented Home branch delegates to tildeifyPath; it gained an optional homeOverride parameter instead of a second prefix-check implementation
Suggestion Guard out of sync with downstream input classification Guard now trims first, excludes isBtwCommand, and skips shell mode; shellModeActive added to the callback deps
Suggestion No test for the one-shot announcement New describe in AppContainer.test.tsx driving handleFinalSubmit: announces once on the first real prompt, does not repeat, is not consumed by a leading slash command or /btw, emits nothing for an empty path list
Suggestion No test for the ~ shortening in parseMemoryFiles New case with a home-dir marker fixture asserting the rendered path is path.join('~', '.qwen', 'QWEN.md'), computed from os.homedir() directly
Suggestion Two surviving mutations Added the CWD-under-home case (CWD must win over ~) and the sibling-home-prefix-collision case (must not tildeify)
Suggestion homedir mock leak in the helper tests The describe now sets the mock return value in its own beforeEach and uses shared-volume fixtures

Declined

  • Dual storage of count + paths (Config): after the empty-content filter above, geminiMdFileCount and contextFilePaths.length are legitimately no longer equal — the count reports all discovered memory files (the existing initializer-stat semantic), while the paths list only what actually reached the system prompt. Deriving one from the other would silently change the count's meaning for its existing readers, so the paired setters stay.
  • Markdown metacharacters eaten by RenderInline: InfoMessageRenderInline is the pre-existing render path shared by every INFO message in the app; introducing a plain-text INFO variant for this single display surface is disproportionate. Directory names containing **/~~/backticks are rare, and the ANSI vector (the real security concern) is covered by the sanitization above. Noted as a known limitation.

Verification: core + cli test suites for the touched files green (memoryDiscovery 45, contextCommand 14, AppContainer 146), typecheck green on both packages, prettier/eslint clean.

中文说明

对自动评审的 12 条 findings 逐条 triage:采纳 10 条,不采纳 2 条(附理由)。

已修复/context detail 改用会话工作目录(而非 process.cwd())解析 memory 标记路径;显示路径在源头统一做 stripAnsiAndControl 净化(同时覆盖提示与 /context 两个展示面);测试 fixture 改为 os.tmpdir() 共享卷以通过 Windows merge queue 门禁;空文件不再被宣告为已读取(与 concatenateInstructions 同一谓词);主目录 ~ 缩写委托给既有的 tildeifyPath(为其增加可选 home 参数);一次性提示的门禁对齐下游输入分类(trim、/btw、shell 模式);补齐核心功能测试(提示 latch 4 用例)、parseMemoryFiles~ 缩写回归测试、两处变异测试存活用例(CWD 位于 home 下、home 前缀冲突);修复 homedir mock 泄漏。

不采纳:① count 与 paths 双份存储——空文件过滤修复后两者合法地不再相等(count 报告所有发现的文件,paths 只列真正进入 system prompt 的),合并会静默改变既有 count 消费方的语义;② markdown 渲染吞掉 ** 等标记——InfoMessage → RenderInline 是所有 INFO 消息的既有渲染通道,为单一展示面新增纯文本 INFO 变体不成比例,含此类字符的目录名罕见,真正的安全向量(ANSI)已由净化覆盖。

验证:相关文件测试全绿(core memoryDiscovery 45、cli contextCommand 14、AppContainer 146),两个包 typecheck 通过,prettier/eslint 干净。

@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 — Test (windows-latest, Node 22.x) was skipped in CI and its suite did not run locally.

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

Not explored to full depth (tool budget reached): PR #8855 adds a one-shot INFO line listing the loaded con...: running memoryDiscovery.test.ts , contextCommand.test.ts , AppContainer.test.tsx , and core config.test.ts to confirm the updated mocks pass..

中文说明

未审查:build-and-test — Test (windows-latest, Node 22.x) 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。

未探索到全部深度(达到工具调用预算):PR #8855 adds a one-shot INFO line listing the loaded con...:running memoryDiscovery.test.ts , contextCommand.test.ts , AppContainer.test.tsx , and core config.test.ts to confirm the updated mocks pass.

— qwen3.8-max via Qwen Code /review (v0.21.8)

Comment thread packages/cli/src/ui/AppContainer.tsx
Comment thread packages/core/src/utils/memoryDiscovery.ts Outdated
Comment thread packages/core/src/utils/memoryDiscovery.ts
Comment thread packages/core/src/utils/memoryDiscovery.ts Outdated
Comment thread packages/core/src/utils/memoryDiscovery.ts Outdated
Comment thread packages/cli/src/ui/AppContainer.tsx Outdated
Comment thread packages/core/src/utils/memoryDiscovery.ts Outdated
Comment thread packages/cli/src/ui/commands/contextCommand.test.ts Outdated
Comment thread packages/cli/src/ui/AppContainer.test.tsx
Comment thread packages/cli/src/ui/commands/directoryCommand.tsx
@wenshao

wenshao commented Aug 10, 2026

Copy link
Copy Markdown
Collaborator

@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 Aug 10, 2026
@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. This is a fork PR, so the first round comes from the next scheduled scan (usually within minutes). Remove the autofix/takeover label (or comment @qwen-code /takeover stop) to release.

中文说明

🤝 已接管:autofix 循环现在管理此 PR —— 将持续处理新的评审反馈与 base 冲突,直到移除标签或达到轮次上限。本 PR 来自 fork,首轮处理将由下一次定时扫描执行(通常几分钟内)。移除 autofix/takeover 标签(或评论 @qwen-code /takeover stop)即可释放。

@qwen-code-dev-bot

qwen-code-dev-bot commented Aug 10, 2026

Copy link
Copy Markdown
Collaborator

⚠️ AutoFix round 3 ended without publishing a reportview run.

中文说明

⚠️ AutoFix 第 3 轮结束但未发布报告 —— 查看运行

@qwen-code-dev-bot

Copy link
Copy Markdown
Collaborator

🤖 AutoFix ran out of time before finishing (idle-timeout (no output for 1200000ms — the sandbox likely hung at startup)) (attempt 1/100) — it will retry on the next scan.

What I found before stopping:
Qwen failed during address-review: idle-timeout (no output for 1200000ms — the sandbox likely hung at startup).

See the Qwen Autofix agent step logs for model/tool output.

Run log: https://github.com/QwenLM/qwen-code/actions/runs/31412188961


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

@qwen-code-dev-bot

Copy link
Copy Markdown
Collaborator

🤖 AutoFix ran out of time before finishing (idle-timeout (no output for 1200000ms — the sandbox likely hung at startup)) (attempt 2/100) — it will retry on the next scan.

What I found before stopping:
Qwen failed during address-review: idle-timeout (no output for 1200000ms — the sandbox likely hung at startup).

See the Qwen Autofix agent step logs for model/tool output.

Run log: https://github.com/QwenLM/qwen-code/actions/runs/31412457256


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

@qwen-code-dev-bot

Copy link
Copy Markdown
Collaborator

🤖 AutoFix stopped: this counting window now contains 3 time-budget exhaustions (pushed rounds in between included; this round itself may have failed differently). That is 3 full agent runs that pushed nothing. 3 of those were silent-sandbox (idle) timeouts that no budget increase can cure — investigate the sandbox image and runner docker daemon for those. A human should investigate the sandbox image and runner docker daemon, then comment @qwen-code /retry to re-arm. Until then future scans will skip this PR.

What I found before stopping:
Qwen failed during address-review: idle-timeout (no output for 1200000ms — the sandbox likely hung at startup).

See the Qwen Autofix agent step logs for model/tool output.

Run log: https://github.com/QwenLM/qwen-code/actions/runs/31417991439


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

@qwen-code-dev-bot

Copy link
Copy Markdown
Collaborator

⏸️ Takeover paused: this PR reached its round cap (100/100). Comment @qwen-code /takeover to re-arm a fresh window and continue management, or @qwen-code /takeover stop to release.

中文说明

⏸️ 托管已暂停:本 PR 达到轮次上限(100/100)。评论 @qwen-code /takeover 可重新武装、开启新窗口继续托管;或评论 @qwen-code /takeover stop 释放。

…lity

- Skip the announcement latch for blank submissions (dropped by the
  message queue before reaching the model)
- Treat Windows cross-drive relative results (absolute paths) as
  outside the CWD tree so home-dir files still get `~` shortening
- Extract the hasAttachedContent predicate shared by
  concatenateInstructions and contextFilePaths so "displayed =
  attached" holds by construction
- Thread the loader's resolved userHomePath through
  formatContextFileDisplayPath into tildeifyPath so discovery and
  display agree on the home directory
- Pin ordering (announcement precedes submission admission), add a
  whitespace-only-file filter test, exercise workingDir != cwd in the
  /context detail test, and cover the /directory add reload wiring
@ZijianZhang989

Copy link
Copy Markdown
Collaborator Author

Second-round review feedback addressed (7b04b36)

Triage of the 10 findings — 8 accepted, 2 declined with rationale below.

Accepted & fixed

Severity Finding Fix
Critical Whitespace-only submission consumes the latch but is dropped by the message queue and never reaches the model Guard now requires trimmedPrompt.length > 0; new test asserts a blank prompt does not consume the latch
Suggestion Windows cross-drive layouts (home on C:, project on D:) never reach the ~ branch because path.relative returns an absolute path instead of a .. chain Gate extended with path.isAbsolute(relativePath) (probe-verified against path.win32). On POSIX path.relative never returns absolute, so this branch is Windows-only and has no POSIX unit-test representation
Suggestion The empty-content predicate was a hand-copy of concatenateInstructions' filter Extracted a single hasAttachedContent predicate used by both sites, so "displayed = attached" holds by construction
Suggestion tildeifyPath's homeOverride existed solely as test plumbing The loader's own userHomePath (already computed for discovery) is now threaded through formatContextFileDisplayPath into tildeifyPath — discovery and display agree on the home directory, giving the parameter a real production consumer. The alternative of switching paths.ts to a named homedir import was rejected: ~35 suites vi.mock('os') (several with bare auto-mocks whose homedir returns undefined), and paths.ts has ~10 homedir() call sites — the mock reachability would be a broad regression risk
Suggestion No test for the whitespace-only-file filter New loadServerHierarchicalMemory case: whitespace-only fixture → fileCount: 1, empty memoryContent, contextFilePaths: []
Suggestion The /context detail test mocked getWorkingDir to process.cwd(), so the round-1 Critical mutation survives Test now uses a tmpdir-based working directory that differs from process.cwd(); reverting to process.cwd() turns it red
Suggestion Ordering (announcement above the prompt) unpinned Harness now captures the message queue's addMessage (the synchronous admission point at the end of handleFinalSubmit) and asserts via invocationCallOrder that the INFO item is added before the submission is admitted
Suggestion /directory add reload wiring (setContextFilePaths) untested New test enables the reload branch with a mocked loadServerHierarchicalMemory and asserts the returned paths are set on the config

Declined

  • Delegate to formatDisplayPath: the observation of duplicated decision logic is fair, but delegation breaks this feature's purpose — formatDisplayPath applies middle-segment compression past 80 chars, so the displayed path would no longer equal the on-disk path (defeating copy-paste verification); it also resolves relative inputs against the root (ours passes them through), does not sanitize, and calls tildeifyPath without the home thread above. Wrapping all four differences leaves a wrapper with little actual reuse.
  • Shared isModelBoundSubmission predicate across the four one-shot gates: the sibling-gate drift is real but pre-existing behavior of unrelated features; changing when those notices fire is a behavior change that needs its own tests and review. The latch in this PR is complete on its own and unaffected by the siblings.

Verification: touched-file suites green (core memoryDiscovery 46, cli AppContainer 147, contextCommand 14, directoryCommand 28), typecheck green on both packages, prettier/eslint clean.

中文说明

对第二轮 10 条 findings 逐条核实(含代码验证与 path.win32 探针):采纳 8 条,不采纳 2 条。

已修复:空白提交不再消费 latch(addMessage 会丢弃空白输入、到不了模型——这是真 bug);Windows 跨盘符布局(home 在 C 盘、项目在 D 盘)下 path.relative 返回绝对路径而非 .. 链、导致 ~ 缩写失效的问题已修(gate 增加 isAbsolute 分支,该分支在 POSIX 上不可达、无单测);空内容过滤谓词提取为 hasAttachedContent 供两处共用;tildeifyPath 的 home 参数不再是纯测试管线——loader 为发现流程计算的 userHomePath 现在贯通到显示格式化,发现与显示使用同一 home(未采用"paths.ts 改具名导入"方案:全仓约 35 处 vi.mock('os')、多处裸 auto-mock 的 homedir 返回 undefined,穿透后是广域回归风险);补齐四处测试缺口——空白文件过滤、/context detail 的 workingDir≠cwd(杀死上一轮 Critical 的回归变异)、提示顺序(以消息队列 addMessage 的调用序为同步锚点)、/directory add 的 reload 接线。

不采纳:① 委托 formatDisplayPath——其 80 字符以上中段压缩会使显示路径不等于磁盘路径,摧毁本功能"复制粘贴可验证"的目的,且相对输入语义、净化、home 贯通四处差异包完后复用所剩无几;② 四个一次性门禁提取共享谓词——兄弟门禁的漂移属实但均为无关功能的既有行为,属行为变更,需独立测试与评审,本 PR 的 latch 自身完整。

验证:相关文件测试全绿(core memoryDiscovery 46、cli AppContainer 147、contextCommand 14、directoryCommand 28),两个包 typecheck 通过,prettier/eslint 干净。

@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 — Test (windows-latest, Node 22.x) was skipped in CI and its suite did not run locally.

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

Not explored to full depth (tool budget reached): PR #8855 (QwenLM/qwen-code) adds a one-shot INFO line lis...: none material — the checks I planned all completed; pre-existing-failure attribution was confirmed against the base commit rather than left assumed.; PR #8855 (QwenLM/qwen-code) adds a one-shot INFO line lis...: did not trace whether a daemon-served TUI session can reach performMemoryRefresh with process cwd ≠ session working dir today (finding 2 is reported at low co…; PR #8855 (QwenLM/qwen-code) adds a one-shot INFO line lis...: none — no check was left unfinished.; PR #8855 (QwenLM/qwen-code) adds a one-shot INFO line lis...: none — all checks I planned completed (~10 tool calls used of ~55).; PR #8855 (QwenLM/qwen-code) adds a one-shot INFO line lis...: none — all checks I started completed within budget..

中文说明

未审查:build-and-test — Test (windows-latest, Node 22.x) 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。

未探索到全部深度(达到工具调用预算):PR #8855 (QwenLM/qwen-code) adds a one-shot INFO line lis...:none material — the checks I planned all completed; pre-existing-failure attribution was confirmed against the base commit rather than left assumed.;PR #8855 (QwenLM/qwen-code) adds a one-shot INFO line lis...:did not trace whether a daemon-served TUI session can reach performMemoryRefresh with process cwd ≠ session working dir today (finding 2 is reported at low co…;PR #8855 (QwenLM/qwen-code) adds a one-shot INFO line lis...:none — no check was left unfinished.;PR #8855 (QwenLM/qwen-code) adds a one-shot INFO line lis...:none — all checks I planned completed (~10 tool calls used of ~55).;PR #8855 (QwenLM/qwen-code) adds a one-shot INFO line lis...:none — all checks I started completed within budget.

— qwen3.8-max via Qwen Code /review (v0.21.9)

Comment thread packages/cli/src/ui/AppContainer.tsx
Comment thread packages/core/src/utils/memoryDiscovery.ts Outdated
Comment thread packages/cli/src/ui/commands/directoryCommand.tsx
Comment thread packages/core/src/utils/memoryDiscovery.ts Outdated
Comment thread packages/cli/src/ui/AppContainer.tsx Outdated
- Consume the one-shot latch on model-invocable slash commands: skills and
  MCP prompts are expanded into a submit_prompt that reaches the model, so
  excluding all slash commands deferred the announcement to a later plain
  prompt (or hid it entirely in skill-only sessions).
- Build contextFilePaths from every attached file, not just memory-named
  ones, so the announcement matches what concatenateInstructions injects
  (extension context files with custom basenames were attached but
  unannounced while /context detail listed them).
- Correct the contextFilePaths JSDoc: entries are display paths (CWD-relative
  or ~/... shortcuts), not paths to resolve against the CWD.
- Tests: model-invocable skill first turn consumes the latch; shell-mode
  submissions do not; extension files with custom basenames are announced.
@ZijianZhang989

Copy link
Copy Markdown
Collaborator Author

Third-round review feedback addressed (31c3e98)

Triage of the 5 findings — 4 accepted, 1 declined with rationale below.

Accepted & fixed

Severity Finding Fix
Critical Model-invocable slash commands (skills, MCP prompts) reach the model via submit_prompt, but the latch excluded all slash commands Guard now admits them: `!isSlashCommand(p)
Suggestion contextFilePaths was built from memory-named files only, while concatenateInstructions attaches every discovered file — extension files with custom basenames were injected but unannounced (and /context detail listed them) contextFilePaths is now built from the same contentsWithPaths input as concatenateInstructions (still filtered by hasAttachedContent), so displayed = attached holds by construction. fileCount intentionally keeps its memory-named-only semantics (pre-existing behavior). New test covers an extension system-prompt.md
Suggestion JSDoc claimed paths are "relative to CWD" while the loader emits ~/... shortcuts Contract rewritten: display paths — CWD-relative inside the CWD tree, ~/... under the user home, display-only (do not resolve against the CWD)
Suggestion The !shellModeActive exclusion had zero test coverage (surviving mutation) New test toggles shell mode via the exposed setShellModeActive UI action: a shell-mode submission adds no INFO and does not consume the latch; the announcement fires exactly once on the next normal prompt after toggling off

Declined

  • Shared applyMemoryLoadResult(config, response) helper: the duplication observation is accurate, but the pattern predates this PR (this change followed the existing convention with one line per site), a helper cannot fully dedupe the three sites (each has private follow-ups: context.ui.setGeminiMdFileCount vs React state vs Config internals), and refactoring Config.refreshHierarchicalMemory internals is out of scope for a visibility PR. Happy to file it as a separate refactor follow-up.

Verification: touched-file suites green (core memoryDiscovery 47, cli AppContainer 149 + contextCommand 14 + directoryCommand 28), prettier/eslint clean, repo-wide typecheck green.

中文说明

对第三轮 5 条 findings 逐条核实:采纳 4 条,不采纳 1 条。

已修复:模型可调用斜杠命令(skill、MCP prompt)经 submit_prompt 展开后确实到达模型,latch 之前一刀切排除所有斜杠命令,导致首回合用 skill 时公告被推迟到下一条普通 prompt(纯 skill 会话永远看不到)——现用 modelInvocable 判定放行,并补"首回合 /feat-dev 消费 latch"测试;contextFilePaths 原来只含 memory 命名文件、而注入端是全量文件,扩展自定义文件名(如 system-prompt.md)注入了却不公告、/context detail 又会列出——现改从与注入端相同的 contentsWithPaths 构建(fileCount 的既有语义不动),补扩展自定义文件名公告测试;JSDoc 失实的"相对 CWD"契约改写为准确的显示路径契约;shell 模式排除条件零测试,补"开 shell 模式提交不消费 latch、关闭后公告恰好一次"用例(通过 UI actions 暴露的 setShellModeActive 切换)。

不采纳:三处"应用 memory 结果"提取共享 helper——重复属实但模式先于本 PR 存在(本 PR 仅跟随既有惯例每处加一行),helper 无法完全去重(三处各有私有追加动作),且重构 Config.refreshHierarchicalMemory 内部超出可见性 PR 范围;可另开 follow-up。

验证:相关文件测试全绿(core memoryDiscovery 47、cli AppContainer 149 + contextCommand 14 + directoryCommand 28),prettier/eslint 干净,全仓 typecheck 通过。

@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 — Test (windows-latest, Node 22.x) was skipped in CI (merge_group-only) and its suite did not run locally; the diff changes cross-platform path-display code whose win32 arm is untested everywhere (see R4-7).

Not reviewed: build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally; the diff changes CLI UI behavior (AppContainer announcement latch, /context, /directory).

Not explored to full depth (tool budget reached): PR #8855 (QwenLM/qwen-code, round 4 review at head 31c3e9...: exact mechanism of Finding 1's order dependency (which earlier-test state makes the full-file run pass) — not pinned down.; PR #8855 (QwenLM/qwen-code, round 4 review at head 31c3e9...: full packages/cli suite + npm run typecheck not run (targeted test files only).; PR #8855 (QwenLM/qwen-code, round 4 review at head 31c3e9...: root-causing *why* the full-file run makes the shell-mode test pass (bisected two candidate enablers, both negative; the enabling side effect elsewhere in the 6…; You are review agent reverse-audit — Reverse audit agen...: none — all checks above completed within budget.; PR #8855 (QwenLM/qwen-code, round 4 review at head 31c3e9...: none — all checks I started completed within budget., and 2 more.

中文说明

未审查:build-and-test — Test (windows-latest, Node 22.x) was skipped in CI (merge_group-only) and its suite did not run locally; the diff changes cross-platform path-display code whose win32 arm is untested everywhere (see R4-7)。

未审查:build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally; the diff changes CLI UI behavior (AppContainer announcement latch, /context, /directory)。

未探索到全部深度(达到工具调用预算):PR #8855 (QwenLM/qwen-code, round 4 review at head 31c3e9...:exact mechanism of Finding 1's order dependency (which earlier-test state makes the full-file run pass) — not pinned down.;PR #8855 (QwenLM/qwen-code, round 4 review at head 31c3e9...:full packages/cli suite + npm run typecheck not run (targeted test files only).;PR #8855 (QwenLM/qwen-code, round 4 review at head 31c3e9...:root-causing *why* the full-file run makes the shell-mode test pass (bisected two candidate enablers, both negative; the enabling side effect elsewhere in the 6…;You are review agent reverse-audit — Reverse audit agen...:none — all checks above completed within budget.;PR #8855 (QwenLM/qwen-code, round 4 review at head 31c3e9...:none — all checks I started completed within budget.,另有 2 条。

— qwen3.8-max via Qwen Code /review (v0.21.9)

Comment thread packages/cli/src/ui/AppContainer.test.tsx Outdated
Comment thread packages/core/src/utils/memoryDiscovery.ts Outdated
Comment thread packages/cli/src/ui/AppContainer.tsx Outdated
Comment thread packages/cli/src/ui/AppContainer.tsx Outdated
Comment thread packages/core/src/utils/memoryDiscovery.ts
Comment thread packages/core/src/utils/memoryDiscovery.ts Outdated
Comment thread packages/cli/src/ui/AppContainer.tsx Outdated
Comment thread packages/cli/src/ui/AppContainer.tsx Outdated
Comment thread packages/cli/src/ui/AppContainer.tsx
@qwen-code-dev-bot qwen-code-dev-bot added the autofix/needs-human The autofix loop stopped on this PR — a human must re-arm, split, merge, or close it label Aug 15, 2026
@qwen-code-dev-bot

Copy link
Copy Markdown
Collaborator

🔓 Takeover auto-released: the autofix loop paused on this PR 4 day(s) ago (🤖 AutoFix stopped: this counting window now contains 3 time-budget exhaustions (pushed rounds in between included; this ) and no re-arm followed, so the autofix/takeover label is removed to keep the managed pool honest. autofix/needs-human stays as the reminder that this PR needs a human decision: merge it, close it, or split/reduce it and comment @qwen-code /takeover to re-engage with a fresh round window.

中文说明

🔓 已自动释放接管:autofix 循环在 4 天前暂停于此 PR(🤖 AutoFix stopped: this counting window now contains 3 time-budget exhaustions (pushed rounds in between included; this ),此后无人重新武装,现移除 autofix/takeover 标签以保持托管池真实可用。保留 autofix/needs-human 作为待办提醒 —— 本 PR 需要人工决策:合并、关闭,或拆分/缩小后评论 @qwen-code /takeover 以全新轮次窗口重新接管。

@qwen-code-dev-bot qwen-code-dev-bot removed the autofix/takeover Summon the autofix loop to manage this PR (remove to release; needs triage+) label Aug 15, 2026
…e markers

useResumeCommand now accepts an optional loadHistory override; AppContainer
passes the latch-reconciling wrapper so interactive /resume (including
same-id) reconciles the latch instead of leaving it consumed with no
announcement in the rebuilt history. The wrapper also destructures
loadHistory so its useCallback deps hold the stable function reference
rather than the per-mutation historyManager identity, keeping history out
of commandContext's rebuild path.

concatenateInstructions sanitizes the marker displayPath with
stripAnsiAndControl: newline/control characters in directory names could
previously forge or hide entries in the /context parser, contradicting the
sanitized announcement surface.

Documented that contextFilePaths lists top-level files only (@import
content is inlined into its importer). Added tests for the sessionId
re-arm effect, the startup-resume armed latch, and the resume override.

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

Partially reviewed — gaps disclosed.

Not reviewed: build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally; the diff changes CLI UI behavior (announcement latch, /context, /directory).

Not reviewed: build-and-test — Test (windows-latest, Node 22.x) was skipped in CI and its suite did not run locally; the diff changes cross-platform path-display code whose win32 arm no local run exercised.

Not reviewed: reverse audit — did not converge within the reverse-audit round cap of 5.

Deferred under the convergence posture (round 15, not a blocker) — recorded, not requested in this round:

  • packages/cli/src/ui/AppContainer.tsx:987 — [probe] Startup --resume latch test is vacuous for the wrapper-vs-raw revert
  • packages/cli/src/ui/AppContainer.tsx:1634 — [probe] AppContainer's loadHistory prop into useResumeCommand is pinned by no test
  • packages/cli/src/ui/AppContainer.tsx:1918 — [probe] /restore's routing through the latch-reconciling wrapper is pinned by no test
  • packages/cli/src/ui/AppContainer.tsx:2061 — [probe] Safe-mode setContextFilePaths([]) clear is untested at both write sites
  • packages/core/src/utils/memoryDiscovery.ts:363 — [probe] U+2028/U+2029 in paths survive sanitization and hide entries from /context
  • packages/core/src/utils/memoryDiscovery.ts:367 — [probe] Marker-path sanitization in concatenateInstructions has no test
中文说明

仅完成部分审查,审查缺口已披露。

未审查:build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally; the diff changes CLI UI behavior (announcement latch, /context, /directory)。

未审查:build-and-test — Test (windows-latest, Node 22.x) was skipped in CI and its suite did not run locally; the diff changes cross-platform path-display code whose win32 arm no local run exercised。

未审查:反向审计——在 5 轮的反审轮数上限内未收敛。

收敛姿态下延后(第 15 轮,非阻断)——已记录,本轮不要求修改:共 6 条(原文未翻译,列表见上方英文部分)。

— qwen3.8-max via Qwen Code /review (v0.21.13)

contextCommand.test.ts: both sides added tests at the same spot — kept
ours (two marker-path rendering tests) and upstream's (disabled-skills
breakdown test).
@ZijianZhang989
ZijianZhang989 force-pushed the context-file-visibility branch from ca56505 to c88a5dd Compare August 18, 2026 02:38
@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 Aug 18, 2026

Copy link
Copy Markdown
Collaborator

🩺 serve daemon A/B

Built the PR base vs this PR head 65a6169, drove a fixed endpoint set against each, and diffed the JSON responses. Only fields that changed are shown.

No response changes against the PR base across 4 scenario(s).

Qwen Code · serve A/B

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

Partially reviewed — gaps disclosed.

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

Not reviewed: build-and-test — Test (windows-latest, Node 22.x) was skipped in CI and its win32 path arm did not run locally.

Deferred under the convergence posture (round 16, not a blocker) — recorded, not requested in this round:

  • packages/cli/src/ui/AppContainer.tsx:1918 — [probe] /restore routing through the latch-reconciling wrapper is pinned by no test
  • packages/core/src/utils/memoryDiscovery.ts:367 — [probe] Marker-path sanitization in concatenateInstructions has no test
中文说明

仅完成部分审查,审查缺口已披露。

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

未审查:build-and-test — Test (windows-latest, Node 22.x) was skipped in CI and its win32 path arm did not run locally。

收敛姿态下延后(第 16 轮,非阻断)——已记录,本轮不要求修改:共 2 条(原文未翻译,列表见上方英文部分)。

— qwen3.8-max via Qwen Code /review (v0.21.13)

Comment thread packages/cli/src/ui/AppContainer.test.tsx

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

Partially reviewed — gaps disclosed.

Not reviewed: build-and-test — Test (windows-latest, Node 22.x) was skipped in CI and its suite did not run locally; the diff changes cross-platform path-display code (formatContextFileDisplayPath, tildeifyPath) whose win32 arm no local run exercised.

Not reviewed: build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally; the diff changes CLI UI behavior (announcement latch, /context, /directory).

Not explored to full depth (tool budget reached): chunk 7: could not execute memoryDiscovery.test.ts under vitest (no installed node_modules in the review worktree); all assertions were instead traced against the impl….

Deferred under the convergence posture (round 17, not a blocker) — recorded, not requested in this round:

  • packages/core/src/utils/memoryDiscovery.ts:367 — [probe] Marker-path strip in concatenateInstructions has no test
  • packages/cli/src/ui/AppContainer.tsx:2408 — [review] Remote input (--input-file) bypasses the announcement latch
  • packages/cli/src/ui/utils/commandUtils.ts:173 — [probe] /goal turn-start bypasses the announcement latch
  • packages/core/src/utils/memoryDiscovery.ts:367 — [probe] U+2028/U+2029 survive sanitization and hide entries from /context
中文说明

仅完成部分审查,审查缺口已披露。

未审查:build-and-test — Test (windows-latest, Node 22.x) was skipped in CI and its suite did not run locally; the diff changes cross-platform path-display code (formatContextFileDisplayPath, tildeifyPath) whose win32 arm no local run exercised。

未审查:build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally; the diff changes CLI UI behavior (announcement latch, /context, /directory)。

未探索到全部深度(达到工具调用预算):chunk 7:could not execute memoryDiscovery.test.ts under vitest (no installed node_modules in the review worktree); all assertions were instead traced against the impl…

收敛姿态下延后(第 17 轮,非阻断)——已记录,本轮不要求修改:共 4 条(原文未翻译,列表见上方英文部分)。

— qwen3.8-max via Qwen Code /review (v0.21.13)

@qwen-code-ci-bot

Copy link
Copy Markdown
Collaborator

Qwen Code review did not complete successfully. The review pipeline failed before a review could be posted. A transient error is retried automatically; if you are seeing this, retry with @qwen-code /review. See workflow logs.

@ZijianZhang989

Copy link
Copy Markdown
Collaborator Author

@qwen-code /review

The round-18 review run was cancelled by a runner timeout before posting (see workflow logs); all functional CI suites passed. Requesting a retry per the fallback comment instructions.

@github-actions

Copy link
Copy Markdown
Contributor

Qwen Code review request accepted. Review is queued in workflow run.

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

Partially reviewed — gaps disclosed.

Not reviewed: build-and-test — Test (windows-latest, Node 22.x) was skipped in CI and its suite did not run locally; the diff changes cross-platform path-display code (formatContextFileDisplayPath, tildeifyPath) whose win32 arm no local run exercised.

Not reviewed: build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally; the diff changes CLI UI behavior (announcement latch, /context, /directory).

Not explored to full depth (tool budget reached): "agent reverse-audit (round 2)": did not confirm whether any qwen --resume or worktree-startup path adopts a persisted working dir without a matching process.chdir (the reachability questio…; chunk 4: none. (Test execution was unavailable — no node_modules in the review worktree — but that is an environment limitation, not an unfinished check; static verifi….

中文说明

仅完成部分审查,审查缺口已披露。

未审查:build-and-test — Test (windows-latest, Node 22.x) was skipped in CI and its suite did not run locally; the diff changes cross-platform path-display code (formatContextFileDisplayPath, tildeifyPath) whose win32 arm no local run exercised。

未审查:build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally; the diff changes CLI UI behavior (announcement latch, /context, /directory)。

未探索到全部深度(达到工具调用预算):"agent reverse-audit (round 2)"did not confirm whether any qwen --resume or worktree-startup path adopts a persisted working dir without a matching process.chdir (the reachability questio…;chunk 4:none. (Test execution was unavailable — no node_modules in the review worktree — but that is an environment limitation, not an unfinished check; static verifi…

— qwen3.8-max via Qwen Code /review (v0.21.13)

@yiliang114 yiliang114 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 — 0 unresolved threads. Note: several resolved Criticals were silently resolved (no author reply comment); the code reads as fixed and the bot re-scan did not re-flag, but please confirm those fixes are in the head. Approve.

@ZijianZhang989

ZijianZhang989 commented Aug 19, 2026

Copy link
Copy Markdown
Collaborator Author

E2E Verification Report

Date: 2026-08-19
Branch: context-file-visibility
Build: bundled (npm run build && npm run bundle)
Workspace: scratch directory with QWEN.md, MY_RULES.md, and .qwen/settings.json configured with context.fileName

Result: ✅ PASS (all 4 reviewer test plan scenarios verified)


Scenario 1: First prompt shows "Read context files" announcement ✅

One INFO line appears above the first prompt listing all loaded context files. Project files show as CWD-relative paths, global files use ~/... shortcuts. Model response confirms both configured files were actually loaded into the system prompt.

● Read context files: QWEN.md, MY_RULES.md, ~/.qwen/extensions/refresh-fixture-a/QWEN.md,
  ~/.qwen/extensions/superpowers/GEMINI.md, ~/.qwen/output-language.md

> hello, just reply ok

◆ PR8855-VERIFIED: ok [QWEN-TEST]

Scenario 2: Second prompt does NOT repeat the announcement ✅

No duplicate "Read context files:" line on subsequent prompts. The original announcement remains in scrollback but no new one is emitted. Model still follows context file instructions.

> say hi again

◆ PR8855-VERIFIED: Hi! [QWEN-TEST]

(No second Read context files: line above this prompt.)

Scenario 3: Typo in filename — mistyped file absent from list ✅

Changed settings to "fileName": ["QWEN.md", "MY_RULESX.md"] (typo). MY_RULESX.md is correctly absent from the announcement. Only QWEN.md from project files is listed. Model response does NOT follow the missing file's instructions (no PR8855-VERIFIED: prefix), confirming it was never loaded.

● Read context files: QWEN.md, ~/.qwen/extensions/refresh-fixture-a/QWEN.md,
  ~/.qwen/extensions/superpowers/GEMINI.md, ~/.qwen/output-language.md

> hi

◆ Hi! How can I help you today?

  [QWEN-TEST]

Note: MY_RULESX.md absent from list; response lacks PR8855-VERIFIED: prefix (from MY_RULES.md) but retains [QWEN-TEST] suffix (from QWEN.md).

Scenario 4: /context detail shows ~/... paths for global files ✅

Memory files section uses ~/... instead of ../../../Users/... chains. Project file QWEN.md shows as CWD-relative. All global extension/memory files display with readable tilde shortcuts.

Memory files
  └ auto memory                              4.1k tokens
  └ ~/.qwen/extensions/superpower…           2.2k tokens
  └ ~/.qwen/output-language.md                211 tokens
  └ QWEN.md                                    24 tokens
  └ ~/.qwen/extensions/refresh-fi…             16 tokens

Code Quality Notes

  • Latch mechanism is well-designed — re-arms on session change, Ctrl-L, rewind past announcement; skips /help, /btw, blank input; model-invocable skills consume the latch
  • Path sanitization via stripAnsiAndControl() prevents forged entries from attacker-influenceable directory names
  • Test coverage is excellent (438+ lines of new tests covering rewind re-arm, session change, resume restore, skill invocation, etc.)
  • Known gaps (/cd, /directory add don't re-arm latch are documented as follow-up work

Verdict: APPROVE — solves #5267 effectively with clean implementation and thorough test coverage.

@yiliang114
yiliang114 dismissed qwen-code-ci-bot’s stale review August 19, 2026 15:50

Stale bot review: all threads resolved, superseded by maintainer approval (yiliang114, 2026-08-19).

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

UI-verified on real CLI build (announcement one-shot, /context detail ~/ paths) and logic-reviewed: displayed=attached holds by construction; disclosed gaps (/cd, /directory add re-arm) tracked as follow-ups. Second approval to satisfy the 2-review requirement.

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

UI-verified on real CLI build (announcement one-shot, /context detail ~/ paths) and logic-reviewed: displayed=attached holds by construction; disclosed gaps (/cd, /directory add re-arm) tracked as follow-ups. Second approval to satisfy the 2-review requirement.

@yiliang114
yiliang114 added this pull request to the merge queue Aug 19, 2026
Merged via the queue into QwenLM:main with commit 39fc769 Aug 19, 2026
77 of 78 checks passed
@yiliang114

Copy link
Copy Markdown
Collaborator

Independent UI verification (real CLI builds, interactive tmux session)

Setup: scratch workspace with QWEN.md + MY_RULES.md and context.fileName: ["QWEN.md", "MY_RULES.md"]. Before = bundle built at the merge-base (a18b0803); After = bundle built from this PR's head. Same prompt sent in both runs.

Before — no indication anywhere, yet the reply ends with [PROJ-OK] (a rule injected via QWEN.md), proving the file was silently attached — exactly the #5267 blind spot:

before

After — one-shot INFO line above the first prompt listing exactly what was attached; verified it does not repeat on the second prompt:

after

Also verified live: /context detail now renders global files as ~/... instead of truncated ../../../Users/... paths. Behavior matches the PR's own E2E report.

@qwen-code-ci-bot

Copy link
Copy Markdown
Collaborator

Released in v0.21.15.

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

Labels

autofix/needs-human The autofix loop stopped on this PR — a human must re-arm, split, merge, or close it

Projects

None yet

Development

Successfully merging this pull request may close these issues.

context.fileName in setting file doesn't work?

5 participants