diff --git a/packages/coding-agent/CHANGELOG.md b/packages/coding-agent/CHANGELOG.md index 5a5d08e8..f55e8a5b 100644 --- a/packages/coding-agent/CHANGELOG.md +++ b/packages/coding-agent/CHANGELOG.md @@ -2,6 +2,10 @@ ## [Unreleased] +### Added + +- Added `--no-context-files` (`-nc`) to disable `AGENTS.md` and `CLAUDE.md` context file discovery and loading ([#3253](https://github.com/badlogic/pi-mono/issues/3253)) + ### Fixed - Fixed flaky `edit-tool-no-full-redraw` TUI tests by waiting for asynchronous preview and preflight error rendering instead of relying on fixed render ticks. diff --git a/packages/coding-agent/README.md b/packages/coding-agent/README.md index a8b95259..974dd99c 100644 --- a/packages/coding-agent/README.md +++ b/packages/coding-agent/README.md @@ -278,6 +278,8 @@ Pi loads `AGENTS.md` (or `CLAUDE.md`) at startup from: Use for project instructions, conventions, common commands. All matching files are concatenated. +Disable context file loading with `--no-context-files` (or `-nc`). + ### System Prompt Replace the default system prompt with `.pi/SYSTEM.md` (project) or `~/.pi/agent/SYSTEM.md` (global). Append without replacing via `APPEND_SYSTEM.md`. @@ -529,6 +531,7 @@ Available built-in tools: `read`, `bash`, `edit`, `write`, `grep`, `find`, `ls` | `--no-prompt-templates` | Disable prompt template discovery | | `--theme ` | Load theme (repeatable) | | `--no-themes` | Disable theme discovery | +| `--no-context-files`, `-nc` | Disable AGENTS.md and CLAUDE.md context file discovery | Combine `--no-*` with explicit flags to load exactly what you need, ignoring settings.json (e.g., `--no-extensions -e ./my-ext.ts`). diff --git a/packages/coding-agent/src/cli/args.ts b/packages/coding-agent/src/cli/args.ts index 19464594..da2b8198 100644 --- a/packages/coding-agent/src/cli/args.ts +++ b/packages/coding-agent/src/cli/args.ts @@ -39,6 +39,7 @@ export interface Args { noPromptTemplates?: boolean; themes?: string[]; noThemes?: boolean; + noContextFiles?: boolean; listModels?: string | true; offline?: boolean; verbose?: boolean; @@ -150,6 +151,8 @@ export function parseArgs(args: string[]): Args { result.noPromptTemplates = true; } else if (arg === "--no-themes") { result.noThemes = true; + } else if (arg === "--no-context-files" || arg === "-nc") { + result.noContextFiles = true; } else if (arg === "--list-models") { // Check if next arg is a search pattern (not a flag or file arg) if (i + 1 < args.length && !args[i + 1].startsWith("-") && !args[i + 1].startsWith("@")) { @@ -240,6 +243,7 @@ ${chalk.bold("Options:")} --no-prompt-templates, -np Disable prompt template discovery and loading --theme Load a theme file or directory (can be used multiple times) --no-themes Disable theme discovery and loading + --no-context-files, -nc Disable AGENTS.md and CLAUDE.md discovery and loading --export Export session file to HTML and exit --list-models [search] List available models (with optional fuzzy search) --verbose Force verbose startup (overrides quietStartup setting) diff --git a/packages/coding-agent/src/core/resource-loader.ts b/packages/coding-agent/src/core/resource-loader.ts index ce71b1ec..9f21102d 100644 --- a/packages/coding-agent/src/core/resource-loader.ts +++ b/packages/coding-agent/src/core/resource-loader.ts @@ -126,6 +126,7 @@ export interface DefaultResourceLoaderOptions { noSkills?: boolean; noPromptTemplates?: boolean; noThemes?: boolean; + noContextFiles?: boolean; systemPrompt?: string; appendSystemPrompt?: string[]; extensionsOverride?: (base: LoadExtensionsResult) => LoadExtensionsResult; @@ -163,6 +164,7 @@ export class DefaultResourceLoader implements ResourceLoader { private noSkills: boolean; private noPromptTemplates: boolean; private noThemes: boolean; + private noContextFiles: boolean; private systemPromptSource?: string; private appendSystemPromptSource?: string[]; private extensionsOverride?: (base: LoadExtensionsResult) => LoadExtensionsResult; @@ -220,6 +222,7 @@ export class DefaultResourceLoader implements ResourceLoader { this.noSkills = options.noSkills ?? false; this.noPromptTemplates = options.noPromptTemplates ?? false; this.noThemes = options.noThemes ?? false; + this.noContextFiles = options.noContextFiles ?? false; this.systemPromptSource = options.systemPrompt; this.appendSystemPromptSource = options.appendSystemPrompt; this.extensionsOverride = options.extensionsOverride; @@ -448,7 +451,9 @@ export class DefaultResourceLoader implements ResourceLoader { } } - const agentsFiles = { agentsFiles: loadProjectContextFiles({ cwd: this.cwd, agentDir: this.agentDir }) }; + const agentsFiles = { + agentsFiles: this.noContextFiles ? [] : loadProjectContextFiles({ cwd: this.cwd, agentDir: this.agentDir }), + }; const resolvedAgentsFiles = this.agentsFilesOverride ? this.agentsFilesOverride(agentsFiles) : agentsFiles; this.agentsFiles = resolvedAgentsFiles.agentsFiles; diff --git a/packages/coding-agent/src/main.ts b/packages/coding-agent/src/main.ts index 0057a13b..a8b7e8c8 100644 --- a/packages/coding-agent/src/main.ts +++ b/packages/coding-agent/src/main.ts @@ -538,6 +538,7 @@ export async function main(args: string[], options?: MainOptions) { noSkills: parsed.noSkills, noPromptTemplates: parsed.noPromptTemplates, noThemes: parsed.noThemes, + noContextFiles: parsed.noContextFiles, systemPrompt: parsed.systemPrompt, appendSystemPrompt: parsed.appendSystemPrompt, extensionFactories: options?.extensionFactories, diff --git a/packages/coding-agent/test/args.test.ts b/packages/coding-agent/test/args.test.ts index 4091295e..d1739c69 100644 --- a/packages/coding-agent/test/args.test.ts +++ b/packages/coding-agent/test/args.test.ts @@ -231,6 +231,18 @@ describe("parseArgs", () => { }); }); + describe("--no-context-files flag", () => { + test("parses --no-context-files flag", () => { + const result = parseArgs(["--no-context-files"]); + expect(result.noContextFiles).toBe(true); + }); + + test("parses -nc shorthand", () => { + const result = parseArgs(["-nc"]); + expect(result.noContextFiles).toBe(true); + }); + }); + describe("--verbose flag", () => { test("parses --verbose flag", () => { const result = parseArgs(["--verbose"]); diff --git a/packages/coding-agent/test/resource-loader.test.ts b/packages/coding-agent/test/resource-loader.test.ts index 29877ba5..054b7da6 100644 --- a/packages/coding-agent/test/resource-loader.test.ts +++ b/packages/coding-agent/test/resource-loader.test.ts @@ -276,6 +276,17 @@ Content`, expect(agentsFiles.some((f) => f.path.includes("AGENTS.md"))).toBe(true); }); + it("should skip AGENTS.md and CLAUDE.md discovery when noContextFiles is true", async () => { + writeFileSync(join(cwd, "AGENTS.md"), "# Project Guidelines\n\nBe helpful."); + writeFileSync(join(cwd, "CLAUDE.md"), "# Claude Guidelines\n\nBe helpful."); + + const loader = new DefaultResourceLoader({ cwd, agentDir, noContextFiles: true }); + await loader.reload(); + + const { agentsFiles } = loader.getAgentsFiles(); + expect(agentsFiles).toEqual([]); + }); + it("should discover SYSTEM.md from cwd/.pi", async () => { const piDir = join(cwd, ".pi"); mkdirSync(piDir, { recursive: true });