From f7941360969004553feed82f64ded2e0ccbbcd3e Mon Sep 17 00:00:00 2001 From: Christophe Dervieux Date: Thu, 12 Mar 2026 17:00:14 +0100 Subject: [PATCH] Ignore CLAUDE.local.md and AGENTS.local.md during project render and template use The .local.md variants of AI assistant config files were not excluded from project file discovery or extension templates. Extends the ignore patterns added in #13907 to also cover these files. Fixes #14198 --- news/changelog-1.9.md | 1 + src/extension/template.ts | 2 ++ src/project/project-context.ts | 4 ++-- tests/smoke/project/project-ai-config.test.ts | 18 +++++++++++++++++- tests/smoke/use/template-ai-config.test.ts | 10 ++++++++++ 5 files changed, 32 insertions(+), 3 deletions(-) diff --git a/news/changelog-1.9.md b/news/changelog-1.9.md index 51f9f904b87..c6f919abb12 100644 --- a/news/changelog-1.9.md +++ b/news/changelog-1.9.md @@ -217,6 +217,7 @@ All changes included in 1.9: - ([#13856](https://github.com/quarto-dev/quarto-cli/issues/13856)): Add code annotation support for Typst and Observable.js code blocks. (author: @mcanouil) - ([#13890](https://github.com/quarto-dev/quarto-cli/issues/13890)): Fix render failure when using `embed-resources: true` with input path through a symlinked directory. The cleanup now resolves symlinks before comparing paths. - ([#13907](https://github.com/quarto-dev/quarto-cli/issues/13907)): Ignore AI assistant configuration files (`CLAUDE.md`, `AGENTS.md`) when scanning for project input files and in extension templates, similar to how `README.md` is handled. +- ([#14198](https://github.com/quarto-dev/quarto-cli/issues/14198)): Ignore `.local.md` variants of AI assistant configuration files (`CLAUDE.local.md`, `AGENTS.local.md`) during project render and `quarto use template`. - ([#13935](https://github.com/quarto-dev/quarto-cli/issues/13935)): Fix `quarto install`, `quarto update`, and `quarto uninstall` interactive tool selection. - ([#13992](https://github.com/quarto-dev/quarto-cli/issues/13992)): Fix crash when rendering div with both cross-reference ID and conditional visibility to PDF. - ([#13997](https://github.com/quarto-dev/quarto-cli/issues/13997)): Fix Windows dart-sass theme compilation failing when Quarto is installed in a path with spaces (e.g., `C:\Program Files\`) and the project path also contains spaces. diff --git a/src/extension/template.ts b/src/extension/template.ts index 87e43029000..84c12431397 100644 --- a/src/extension/template.ts +++ b/src/extension/template.ts @@ -58,5 +58,7 @@ const kBuiltInExcludes = [ "LICENSE", "_extensions", "CLAUDE.md", + "CLAUDE.local.md", "AGENTS.md", + "AGENTS.local.md", ]; diff --git a/src/project/project-context.ts b/src/project/project-context.ts index df308c0d4f9..f68be8bb46c 100644 --- a/src/project/project-context.ts +++ b/src/project/project-context.ts @@ -880,8 +880,8 @@ function projectHiddenIgnoreGlob(dir: string) { .concat(["**/_*", "**/_*/**"]) // underscore prefix .concat(["**/.*", "**/.*/**"]) // hidden (dot prefix) .concat(["**/README.?([Rrq])md"]) // README - .concat(["**/CLAUDE.md"]) // Anthropic claude code file - .concat(["**/AGENTS.md"]) // https://agents.md/ + .concat(["**/CLAUDE.md", "**/CLAUDE.local.md"]) // Anthropic claude code file + .concat(["**/AGENTS.md", "**/AGENTS.local.md"]) // https://agents.md/ .concat(["**/*.llms.md"]); // llms.txt companion markdown files } diff --git a/tests/smoke/project/project-ai-config.test.ts b/tests/smoke/project/project-ai-config.test.ts index b5a2752bc86..fab64c00df6 100644 --- a/tests/smoke/project/project-ai-config.test.ts +++ b/tests/smoke/project/project-ai-config.test.ts @@ -10,12 +10,16 @@ import { docs } from "../../utils.ts"; import { join } from "../../../src/deno_ral/path.ts"; import { existsSync } from "../../../src/deno_ral/fs.ts"; +import { removeIfExists } from "../../../src/core/path.ts"; import { testQuartoCmd } from "../../test.ts"; import { fileExists, pathDoNotExists, noErrors } from "../../verify.ts"; const projectDir = docs("project/ai-config-files"); const outputDir = join(projectDir, "_site"); +// .local.md fixture files are created at runtime to avoid .gitignore conflicts +const localFiles = ["CLAUDE.local.md", "AGENTS.local.md"]; + // Test that AI assistant config files are properly excluded testQuartoCmd( "render", @@ -25,10 +29,22 @@ testQuartoCmd( fileExists(join(outputDir, "index.html")), // Control: regular file should be rendered pathDoNotExists(join(outputDir, "CLAUDE.html")), // CLAUDE.md should be ignored pathDoNotExists(join(outputDir, "AGENTS.html")), // AGENTS.md should be ignored + pathDoNotExists(join(outputDir, "CLAUDE.local.html")), // CLAUDE.local.md should be ignored + pathDoNotExists(join(outputDir, "AGENTS.local.html")), // AGENTS.local.md should be ignored ], { + setup: async () => { + for (const file of localFiles) { + await Deno.writeTextFile( + join(projectDir, file), + "This is a local AI config file that should be ignored during project scanning.\n", + ); + } + }, teardown: async () => { - // Clean up _site directory + for (const file of localFiles) { + removeIfExists(join(projectDir, file)); + } if (existsSync(outputDir)) { await Deno.remove(outputDir, { recursive: true }); } diff --git a/tests/smoke/use/template-ai-config.test.ts b/tests/smoke/use/template-ai-config.test.ts index 12e81b7854a..904cad28042 100644 --- a/tests/smoke/use/template-ai-config.test.ts +++ b/tests/smoke/use/template-ai-config.test.ts @@ -29,6 +29,14 @@ Deno.writeTextFileSync( join(templateSourceDir, "AGENTS.md"), "# Agents Configuration\n\nThis should be excluded." ); +Deno.writeTextFileSync( + join(templateSourceDir, "CLAUDE.local.md"), + "# Claude Local Configuration\n\nThis should be excluded." +); +Deno.writeTextFileSync( + join(templateSourceDir, "AGENTS.local.md"), + "# Agents Local Configuration\n\nThis should be excluded." +); Deno.writeTextFileSync( join(templateSourceDir, "README.md"), "# Template README\n\nThis should also be excluded." @@ -46,6 +54,8 @@ testQuartoCmd( fileExists(`${templateFolder}.qmd`), // Template file should be copied and renamed pathDoNotExists(join(workingDir, "CLAUDE.md")), // CLAUDE.md should be excluded pathDoNotExists(join(workingDir, "AGENTS.md")), // AGENTS.md should be excluded + pathDoNotExists(join(workingDir, "CLAUDE.local.md")), // CLAUDE.local.md should be excluded + pathDoNotExists(join(workingDir, "AGENTS.local.md")), // AGENTS.local.md should be excluded pathDoNotExists(join(workingDir, "README.md")), // README.md should also be excluded (sanity check) ], {