fix(cli): stop re-prompting on wmill refresh prompts (#9357)

referencesIncludeLine required the include token to be the entire
trimmed line. The wmill-default CLAUDE.md template is
`Instructions are in @AGENTS.md` — include mid-sentence — so the
migration prompt fired every run on files wmill itself wrote.

Accept the include as a whitespace-separated token on any non-comment
line.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
hugocasa
2026-05-28 12:31:25 +02:00
committed by GitHub
parent 4efc37212a
commit c2b5ba8871
2 changed files with 19 additions and 7 deletions
+12 -6
View File
@@ -207,13 +207,19 @@ async function reconcileIncludingFile(options: {
}
function referencesIncludeLine(content: string, includeLine: string): boolean {
// Match only when the include sits on a line by itself (allowing leading
// and trailing whitespace). Earlier we split on `\s+`, but that
// false-positives on commented-out includes like `<!-- @AGENTS.cli.md -->`
// where the middle token equals the include. CRLF is handled by the
// `\r?\n` split.
// Match when the include appears as a whitespace-separated token on any
// line that isn't an HTML comment. We can't require the include to be on a
// line by itself: our own CLAUDE.md default is `Instructions are in
// @AGENTS.md` (one sentence), and a strict equality check made `wmill
// refresh prompts` re-prompt every run on files wmill itself wrote.
// Skipping comment-bearing lines keeps `<!-- @AGENTS.cli.md -->` from
// false-positiving.
for (const line of content.split(/\r?\n/)) {
if (line.trim() === includeLine) {
const trimmed = line.trim();
if (trimmed.startsWith("<!--") || trimmed.endsWith("-->")) {
continue;
}
if (trimmed.split(/\s+/).includes(includeLine)) {
return true;
}
}
+7 -1
View File
@@ -391,6 +391,13 @@ describe("writeAiGuidanceFiles — referencesAgentsCli (via reconciliation)", ()
["between blank lines", "before\n\n@AGENTS.cli.md\n\nafter"],
["leading whitespace then include", " @AGENTS.cli.md\n"],
["CRLF line endings", "line one\r\n@AGENTS.cli.md\r\nline three"],
// Mid-sentence include: this is how our own CLAUDE.md default looks
// ("Instructions are in @AGENTS.md"). A strict line-equality check made
// `wmill refresh prompts` re-prompt every run on files wmill wrote.
["mid-sentence include", "Instructions are in @AGENTS.cli.md\n"],
// `>` blockquote prefix doesn't disable Claude's `@`-import expansion,
// so we treat it as a reference too.
["blockquoted include", "> @AGENTS.cli.md"],
])("treats %s as a reference (no append)", async (_label, content) => {
await withTempDir(async (tempDir) => {
await writeFile(join(tempDir, "AGENTS.md"), content, "utf8");
@@ -406,7 +413,6 @@ describe("writeAiGuidanceFiles — referencesAgentsCli (via reconciliation)", ()
["@AGENTS-cli-md (lookalike)", "@AGENTS-cli-md"],
["@AGENTS.cli.md without surrounding whitespace", "foo@AGENTS.cli.md"],
["commented-out include", "<!-- @AGENTS.cli.md -->"],
["blockquoted include", "> @AGENTS.cli.md"],
])("does not treat %s as a reference (append happens)", async (_label, content) => {
await withTempDir(async (tempDir) => {
await writeFile(join(tempDir, "AGENTS.md"), content, "utf8");