singularity-forge/src/headless-context.ts
TÂCHES 87cd612542 refactor(headless): split 772-line god file into events, UI, and context modules (#1047)
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 18:36:20 -06:00

59 lines
2.1 KiB
TypeScript

/**
* Headless Context Loading — stdin reading, file context, and project bootstrapping
*
* Handles loading context from files or stdin for headless new-milestone,
* and bootstraps the .gsd/ directory structure when needed.
*/
import { readFileSync, mkdirSync } from 'node:fs'
import { join, resolve } from 'node:path'
// ---------------------------------------------------------------------------
// Types
// ---------------------------------------------------------------------------
interface ContextOptions {
context?: string // file path or '-' for stdin
contextText?: string // inline text
}
// ---------------------------------------------------------------------------
// Stdin Reader
// ---------------------------------------------------------------------------
export async function readStdin(): Promise<string> {
const chunks: Buffer[] = []
for await (const chunk of process.stdin) {
chunks.push(chunk as Buffer)
}
return Buffer.concat(chunks).toString('utf-8')
}
// ---------------------------------------------------------------------------
// Context Loading
// ---------------------------------------------------------------------------
export async function loadContext(options: ContextOptions): Promise<string> {
if (options.contextText) return options.contextText
if (options.context === '-') {
return readStdin()
}
if (options.context) {
return readFileSync(resolve(options.context), 'utf-8')
}
throw new Error('No context provided. Use --context <file> or --context-text <text>')
}
// ---------------------------------------------------------------------------
// Project Bootstrap
// ---------------------------------------------------------------------------
/**
* Bootstrap .gsd/ directory structure for headless new-milestone.
* Mirrors the bootstrap logic from guided-flow.ts showSmartEntry().
*/
export function bootstrapGsdProject(basePath: string): void {
const gsdDir = join(basePath, '.gsd')
mkdirSync(join(gsdDir, 'milestones'), { recursive: true })
mkdirSync(join(gsdDir, 'runtime'), { recursive: true })
}