feat: Wire --bare mode across headless → pi-coding-agent → resource-loa…
- "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
This commit is contained in:
parent
d355ab93fb
commit
c5b38d69e3
4 changed files with 65 additions and 3 deletions
|
|
@ -49,6 +49,8 @@ export interface Args {
|
|||
fileArgs: string[];
|
||||
/** Unknown flags (potentially extension flags) - map of flag name to value */
|
||||
unknownFlags: Map<string, boolean | string>;
|
||||
/** --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<string, { type: "
|
|||
}
|
||||
} else if (arg === "--verbose") {
|
||||
result.verbose = true;
|
||||
} else if (arg === "--bare") {
|
||||
result.bare = true;
|
||||
} else if (arg === "--offline") {
|
||||
result.offline = true;
|
||||
} else if (arg.startsWith("@")) {
|
||||
|
|
|
|||
|
|
@ -419,11 +419,13 @@ export async function main(args: string[]) {
|
|||
additionalPromptTemplatePaths: firstPass.promptTemplates,
|
||||
additionalThemePaths: firstPass.themes,
|
||||
noExtensions: firstPass.noExtensions,
|
||||
noSkills: firstPass.noSkills,
|
||||
noPromptTemplates: firstPass.noPromptTemplates,
|
||||
noThemes: firstPass.noThemes,
|
||||
noSkills: firstPass.noSkills || firstPass.bare,
|
||||
noPromptTemplates: firstPass.noPromptTemplates || firstPass.bare,
|
||||
noThemes: firstPass.noThemes || firstPass.bare,
|
||||
systemPrompt: firstPass.systemPrompt,
|
||||
appendSystemPrompt: firstPass.appendSystemPrompt,
|
||||
// --bare: suppress CLAUDE.md/AGENTS.md ancestor walk
|
||||
...(firstPass.bare ? { agentsFilesOverride: () => ({ agentsFiles: [] }) } : {}),
|
||||
});
|
||||
await resourceLoader.reload();
|
||||
time("resourceLoader.reload");
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@ export interface HeadlessOptions {
|
|||
answers?: string // path to answers JSON file
|
||||
eventFilter?: Set<string> // filter JSONL output to specific event types
|
||||
resumeSession?: string // session ID to resume (--resume <id>)
|
||||
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)
|
||||
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ interface HeadlessOptions {
|
|||
answers?: string
|
||||
eventFilter?: Set<string>
|
||||
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')
|
||||
})
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue