feat(coding-agent): add --no-context-files flag

closes #3253
This commit is contained in:
Mario Zechner
2026-04-16 10:59:11 +02:00
parent f2c0489197
commit e189b23964
7 changed files with 41 additions and 1 deletions

View File

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

View File

@@ -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 <path>` | 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`).

View File

@@ -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 <path> 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 <file> Export session file to HTML and exit
--list-models [search] List available models (with optional fuzzy search)
--verbose Force verbose startup (overrides quietStartup setting)

View File

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

View File

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

View File

@@ -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"]);

View File

@@ -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 });