From c5b38d69e35fa95646cc3205ccf47e75dc80ad71 Mon Sep 17 00:00:00 2001 From: Lex Christopherson Date: Thu, 26 Mar 2026 11:39:25 -0600 Subject: [PATCH] =?UTF-8?q?feat:=20Wire=20--bare=20mode=20across=20headles?= =?UTF-8?q?s=20=E2=86=92=20pi-coding-agent=20=E2=86=92=20resource-loa?= =?UTF-8?q?=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - "src/headless.ts" - "packages/pi-coding-agent/src/cli/args.ts" - "packages/pi-coding-agent/src/main.ts" - "src/tests/headless-cli-surface.test.ts" GSD-Task: S02/T02 --- packages/pi-coding-agent/src/cli/args.ts | 4 ++ packages/pi-coding-agent/src/main.ts | 8 ++-- src/headless.ts | 7 ++++ src/tests/headless-cli-surface.test.ts | 49 ++++++++++++++++++++++++ 4 files changed, 65 insertions(+), 3 deletions(-) diff --git a/packages/pi-coding-agent/src/cli/args.ts b/packages/pi-coding-agent/src/cli/args.ts index 101e67da5..cd056d5d8 100644 --- a/packages/pi-coding-agent/src/cli/args.ts +++ b/packages/pi-coding-agent/src/cli/args.ts @@ -49,6 +49,8 @@ export interface Args { fileArgs: string[]; /** Unknown flags (potentially extension flags) - map of flag name to value */ unknownFlags: Map; + /** --bare: suppress CLAUDE.md/AGENTS.md, user skills, prompt templates, themes, project preferences */ + bare?: boolean; } const VALID_THINKING_LEVELS = ["off", "minimal", "low", "medium", "high", "xhigh"] as const; @@ -169,6 +171,8 @@ export function parseArgs(args: string[], extensionFlags?: Map ({ agentsFiles: [] }) } : {}), }); await resourceLoader.reload(); time("resourceLoader.reload"); diff --git a/src/headless.ts b/src/headless.ts index b91fabd92..f332dbe89 100644 --- a/src/headless.ts +++ b/src/headless.ts @@ -71,6 +71,7 @@ export interface HeadlessOptions { answers?: string // path to answers JSON file eventFilter?: Set // filter JSONL output to specific event types resumeSession?: string // session ID to resume (--resume ) + bare?: boolean // --bare: suppress CLAUDE.md/AGENTS.md, user skills, project preferences } interface TrackedEvent { @@ -158,6 +159,8 @@ export function parseHeadlessArgs(argv: string[]): HeadlessOptions { } } else if (arg === '--resume' && i + 1 < args.length) { options.resumeSession = args[++i] + } else if (arg === '--bare') { + options.bare = true } } else if (!positionalStarted) { positionalStarted = true @@ -306,6 +309,10 @@ async function runHeadlessOnce(options: HeadlessOptions, restartCount: number): if (injector) { clientOptions.env = injector.getSecretEnvVars() } + // Propagate --bare to the child process + if (options.bare) { + clientOptions.args = [...((clientOptions.args as string[]) || []), '--bare'] + } const client = new RpcClient(clientOptions) diff --git a/src/tests/headless-cli-surface.test.ts b/src/tests/headless-cli-surface.test.ts index a1b81ae29..89fab5d44 100644 --- a/src/tests/headless-cli-surface.test.ts +++ b/src/tests/headless-cli-surface.test.ts @@ -41,6 +41,7 @@ interface HeadlessOptions { answers?: string eventFilter?: Set resumeSession?: string + bare?: boolean } function parseHeadlessArgs(argv: string[]): HeadlessOptions { @@ -104,6 +105,8 @@ function parseHeadlessArgs(argv: string[]): HeadlessOptions { options.responseTimeout = parseInt(args[++i], 10) } else if (arg === '--resume' && i + 1 < args.length) { options.resumeSession = args[++i] + } else if (arg === '--bare') { + options.bare = true } } else if (!positionalStarted) { positionalStarted = true @@ -336,3 +339,49 @@ test('combined flags parse correctly', () => { assert.equal(opts.verbose, true) assert.equal(opts.command, 'auto') }) + +// ─── --bare flag ─────────────────────────────────────────────────────────── + +test('--bare sets bare to true', () => { + const opts = parseHeadlessArgs(['node', 'gsd', 'headless', '--bare', 'auto']) + assert.equal(opts.bare, true) + assert.equal(opts.command, 'auto') +}) + +test('no --bare means bare is undefined', () => { + const opts = parseHeadlessArgs(['node', 'gsd', 'headless', 'auto']) + assert.equal(opts.bare, undefined) +}) + +test('--bare is a boolean flag (no value needed)', () => { + const opts = parseHeadlessArgs(['node', 'gsd', 'headless', '--bare', '--json', 'auto']) + assert.equal(opts.bare, true) + assert.equal(opts.json, true) +}) + +test('--bare combined with --output-format json', () => { + const opts = parseHeadlessArgs([ + 'node', 'gsd', 'headless', + '--bare', + '--output-format', 'json', + 'auto', + ]) + assert.equal(opts.bare, true) + assert.equal(opts.outputFormat, 'json') + assert.equal(opts.json, true) + assert.equal(opts.command, 'auto') +}) + +test('--bare does not affect other flags', () => { + const opts = parseHeadlessArgs([ + 'node', 'gsd', 'headless', + '--bare', + '--timeout', '60000', + '--resume', 'sess-abc', + 'auto', + ]) + assert.equal(opts.bare, true) + assert.equal(opts.timeout, 60000) + assert.equal(opts.resumeSession, 'sess-abc') + assert.equal(opts.command, 'auto') +})