fix(cli): keep AGENTS.md enabled by default context reset#2082
Conversation
LaZzyMan
left a comment
There was a problem hiding this comment.
Great catch on the root cause! The analysis is spot-on — getCurrentGeminiMdFilename() collapses the array into a single string.
A couple of suggestions:
1. Use getAllGeminiMdFilenames() instead of hardcoding the default array
The current fix hardcodes [DEFAULT_CONTEXT_FILENAME, AGENT_CONTEXT_FILENAME], which duplicates the default value defined in memoryTool.ts. If additional context filenames are added in the future, this code won't automatically pick them up. A more robust approach:
import {
getAllGeminiMdFilenames,
// remove getCurrentGeminiMdFilename if no longer needed
} from '@qwen-code/qwen-code-core';
// in loadCliConfig:
} else {
setServerGeminiMdFilename(getAllGeminiMdFilenames());
}This keeps the single source of truth in memoryTool.ts.
2. There's a similar issue in packages/core/src/utils/ignorePatterns.ts
ignorePatterns.ts also uses getCurrentGeminiMdFilename() to build file exclusion patterns (line 163):
patterns.push(`**/${getCurrentGeminiMdFilename()}`);This means AGENTS.md is not excluded from tool scan results (e.g., read_many_files, glob search), causing its content to potentially appear twice in the model's context — once from system memory loading and once from tool output. It should iterate over getAllGeminiMdFilenames() to exclude all configured context files:
for (const filename of getAllGeminiMdFilenames()) {
patterns.push(`**/${filename}`);
}|
Thanks @LaZzyMan for the detailed review and the two concrete suggestions. Both points make sense and I will update this PR accordingly:
I’ll include test updates as well in the follow-up commit. |
|
Implemented in commit d7d2ffb. Addressed both suggestions:
Also updated tests/mocks accordingly ( Thanks again for the review. Please take another look when convenient. |
Config.startNewSession() reassigns this.sessionId in the same process, which is reached by /clear, /reset, /new and /resume. Previously the old <oldId>.runtime.json was left behind, falsely claiming the still- live PID for a session no longer being served, and no new sidecar was written for the incoming session. Centralize the swap by clearing the old sidecar and writing a fresh one for the new session id from inside startNewSession itself, so all same-PID transitions are covered. The refresh runs as a fire-and- forget best-effort; failures must not block the session switch. Mirrors the post-merge Codex P1 fix on kimi-cli PR QwenLM#2082 (the source of the runtime.json sidecar pattern this PR ports). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Mirrors kimi-cli PR QwenLM#2082 commit e237951f (Codex P1 r3158754463): a short-lived non-interactive invocation (qwen --prompt, ACP, etc.) that runs `/clear` would otherwise call `Config.startNewSession()`, delete a concurrent shell's runtime.json sidecar (same outgoing session id), and never write a replacement — leaving the shell discoverable to nobody. Add a `runtimeStatusEnabled` flag on Config, flipped on by the interactive UI bootstrap immediately after the first successful sidecar write, and gate the swap-time refresh in `startNewSession()` on it. Non-interactive entry points never reach the bootstrap, so they won't touch sibling sidecars. Kimi later reverted the equivalent `write only from shell mode` guard (commit 7083975a) in favor of writing from every long-lived mode, but qwen's wire point is already interactive-only, so the narrower guard is the right shape here. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* feat(core): write runtime.json sidecar for active sessions Port kimi-cli PR #2082 part 1 to qwen-code. On interactive session start, atomically write a small JSON sidecar at <projectDir>/chats/<sessionId>.runtime.json recording the (pid, session_id, work_dir, hostname, started_at, qwen_version) tuple. External tools (terminal multiplexers, IDE integrations, status daemons) can map a running PID to its session id and work dir without parsing argv. Write is best-effort: a read-only filesystem must not block UI startup. OS process title (was #3713) and dynamic OSC tab title (kimi #2083) remain out of scope. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix(core): refresh runtime.json on same-PID session swap Config.startNewSession() reassigns this.sessionId in the same process, which is reached by /clear, /reset, /new and /resume. Previously the old <oldId>.runtime.json was left behind, falsely claiming the still- live PID for a session no longer being served, and no new sidecar was written for the incoming session. Centralize the swap by clearing the old sidecar and writing a fresh one for the new session id from inside startNewSession itself, so all same-PID transitions are covered. The refresh runs as a fire-and- forget best-effort; failures must not block the session switch. Mirrors the post-merge Codex P1 fix on kimi-cli PR #2082 (the source of the runtime.json sidecar pattern this PR ports). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix(core): only refresh runtime.json when this process owns it Mirrors kimi-cli PR #2082 commit e237951f (Codex P1 r3158754463): a short-lived non-interactive invocation (qwen --prompt, ACP, etc.) that runs `/clear` would otherwise call `Config.startNewSession()`, delete a concurrent shell's runtime.json sidecar (same outgoing session id), and never write a replacement — leaving the shell discoverable to nobody. Add a `runtimeStatusEnabled` flag on Config, flipped on by the interactive UI bootstrap immediately after the first successful sidecar write, and gate the swap-time refresh in `startNewSession()` on it. Non-interactive entry points never reach the bootstrap, so they won't touch sibling sidecars. Kimi later reverted the equivalent `write only from shell mode` guard (commit 7083975a) in favor of writing from every long-lived mode, but qwen's wire point is already interactive-only, so the narrower guard is the right shape here. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ents-context-loading fix(cli): keep AGENTS.md enabled by default context reset
TLDR
Fix default context filename reset so
AGENTS.mdremains effective whensettings.context.fileNameis not configured.Dive Deeper
Root cause:
loadCliConfig, whensettings.context.fileNameis absent, we called:setGeminiMdFilename(getCurrentGeminiMdFilename())getCurrentGeminiMdFilename()returns only the first configured file name.[QWEN.md, AGENTS.md], but this code collapsed it into onlyQWEN.md, unintentionally disabling defaultAGENTS.mdloading.What changed:
packages/cli/src/config/config.tssetGeminiMdFilename([DEFAULT_CONTEXT_FILENAME, AGENT_CONTEXT_FILENAME])packages/cli/src/config/config.test.tsQWEN.mdandAGENTS.mdsettings.context.fileNamestill overrides as expectedReviewer Test Plan
context.fileNamein settings.setGeminiMdFilenamereceives both default names (QWEN.md,AGENTS.md).context.fileName = "CUSTOM_AGENTS.md"and verify custom filename is used.AGENTS.mdin project and ensure it is discovered in default configuration.Testing Matrix
Linked issues / bugs
Fixes #2062