feat: auto --init flag, headless prompts, and prompt sanitizer (#1417)
* fix: Created 10 headless prompt files (5 workflows + 5 agents) in sdk/p… - "sdk/prompts/workflows/execute-plan.md" - "sdk/prompts/workflows/research-phase.md" - "sdk/prompts/workflows/plan-phase.md" - "sdk/prompts/workflows/verify-phase.md" - "sdk/prompts/workflows/discuss-phase.md" - "sdk/prompts/agents/gsd-executor.md" - "sdk/prompts/agents/gsd-phase-researcher.md" - "sdk/prompts/agents/gsd-planner.md" GSD-Task: S01/T02 * feat: Created prompt-sanitizer.ts, wired headless prompt loading into P… - "sdk/src/prompt-sanitizer.ts" - "sdk/src/phase-prompt.ts" - "sdk/src/gsd-tools.ts" - "sdk/src/gsd-tools.test.ts" - "sdk/src/phase-runner-types.test.ts" GSD-Task: S01/T01 * test: Added 111 unit tests covering sanitizePrompt(), headless prompt l… - "sdk/src/prompt-sanitizer.test.ts" - "sdk/src/headless-prompts.test.ts" - "sdk/src/phase-prompt.test.ts" GSD-Task: S01/T03 * feat: Wired sdkPromptsDir preference and sanitizePrompt into InitRunner… - "sdk/src/init-runner.ts" - "sdk/package.json" GSD-Task: S02/T01 * feat: add --init flag to auto command for single-command PRD-to-execution gsd-sdk auto --init @path/to/prd.md now bootstraps the project (init) then immediately runs the autonomous phase execution loop. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * chore: add remaining headless prompt files and templates Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * test: Extended init-runner.test.ts with 7 sdkPromptsDir preference and… - "sdk/src/init-runner.test.ts" GSD-Task: S02/T03 --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -23,6 +23,8 @@ export interface ParsedCliArgs {
|
||||
prompt: string | undefined;
|
||||
/** For 'init' command: the raw input source (@file, text, or undefined for stdin). */
|
||||
initInput: string | undefined;
|
||||
/** For 'auto --init': bootstrap from a PRD before running the autonomous loop. */
|
||||
init: string | undefined;
|
||||
projectDir: string;
|
||||
wsPort: number | undefined;
|
||||
model: string | undefined;
|
||||
@@ -43,6 +45,7 @@ export function parseCliArgs(argv: string[]): ParsedCliArgs {
|
||||
'ws-port': { type: 'string' },
|
||||
model: { type: 'string' },
|
||||
'max-budget': { type: 'string' },
|
||||
init: { type: 'string' },
|
||||
help: { type: 'boolean', short: 'h', default: false },
|
||||
version: { type: 'boolean', short: 'v', default: false },
|
||||
},
|
||||
@@ -61,6 +64,7 @@ export function parseCliArgs(argv: string[]): ParsedCliArgs {
|
||||
command,
|
||||
prompt,
|
||||
initInput,
|
||||
init: values.init as string | undefined,
|
||||
projectDir: values['project-dir'] as string,
|
||||
wsPort: values['ws-port'] ? Number(values['ws-port']) : undefined,
|
||||
model: values.model as string | undefined,
|
||||
@@ -85,6 +89,8 @@ Commands:
|
||||
(empty) Read from stdin
|
||||
|
||||
Options:
|
||||
--init <input> Bootstrap from a PRD before running (auto only)
|
||||
Accepts @path/to/prd.md or "description text"
|
||||
--project-dir <dir> Project directory (default: cwd)
|
||||
--ws-port <port> Enable WebSocket transport on <port>
|
||||
--model <model> Override LLM model
|
||||
@@ -306,6 +312,47 @@ export async function main(argv: string[] = process.argv.slice(2)): Promise<void
|
||||
}
|
||||
|
||||
try {
|
||||
// If --init provided, bootstrap project first
|
||||
if (args.init) {
|
||||
const initInput = await resolveInitInput({
|
||||
...args,
|
||||
command: 'init',
|
||||
initInput: args.init,
|
||||
});
|
||||
|
||||
console.log(`[auto] Bootstrapping project from --init (${initInput.length} chars)`);
|
||||
|
||||
const tools = gsd.createTools();
|
||||
const runner = new InitRunner({
|
||||
projectDir: args.projectDir,
|
||||
tools,
|
||||
eventStream: gsd.eventStream,
|
||||
config: {
|
||||
maxBudgetPerSession: args.maxBudget,
|
||||
orchestratorModel: args.model,
|
||||
},
|
||||
});
|
||||
|
||||
const initResult = await runner.run(initInput);
|
||||
|
||||
const initStatus = initResult.success ? 'SUCCESS' : 'FAILED';
|
||||
const stepCount = initResult.steps.length;
|
||||
const passedSteps = initResult.steps.filter(s => s.success).length;
|
||||
const initCost = initResult.totalCostUsd.toFixed(2);
|
||||
const initDuration = (initResult.totalDurationMs / 1000).toFixed(1);
|
||||
console.log(`[init ${initStatus}] ${passedSteps}/${stepCount} steps, $${initCost}, ${initDuration}s`);
|
||||
|
||||
if (!initResult.success) {
|
||||
for (const step of initResult.steps) {
|
||||
if (!step.success && step.error) {
|
||||
console.error(` ✗ ${step.step}: ${step.error}`);
|
||||
}
|
||||
}
|
||||
process.exitCode = 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const result = await gsd.run('');
|
||||
|
||||
// Final summary
|
||||
|
||||
Reference in New Issue
Block a user