@dendelion/paper-camp 0.2.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -7
- package/dist/app/assets/main-8b5RQGnS.js +208 -0
- package/dist/app/assets/main-8b5RQGnS.js.map +1 -0
- package/dist/app/index.html +1 -1
- package/dist/chunks/serializer.DL7H4ZTd.js +5249 -0
- package/dist/chunks/serializer.DL7H4ZTd.js.map +1 -0
- package/dist/cli/index.js +1497 -714
- package/dist/cli/index.js.map +1 -1
- package/dist/core/frontmatter-schemas.d.ts +11 -0
- package/dist/core/frontmatter-schemas.d.ts.map +1 -0
- package/dist/core/frontmatter.test.d.ts +2 -0
- package/dist/core/frontmatter.test.d.ts.map +1 -0
- package/dist/core/idea-status.d.ts +7 -0
- package/dist/core/idea-status.d.ts.map +1 -0
- package/dist/core/index.js +48 -29
- package/dist/core/parser.d.ts +49 -4
- package/dist/core/parser.d.ts.map +1 -1
- package/dist/core/scaffold.d.ts +4 -2
- package/dist/core/scaffold.d.ts.map +1 -1
- package/dist/core/schemas.d.ts +75 -12
- package/dist/core/schemas.d.ts.map +1 -1
- package/dist/core/serializer.d.ts +52 -2
- package/dist/core/serializer.d.ts.map +1 -1
- package/dist/types/index.d.ts +22 -4
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +32 -10
- package/dist/types/index.js.map +1 -1
- package/package.json +2 -1
- package/dist/app/assets/main-tAEncq68.js +0 -272
- package/dist/app/assets/main-tAEncq68.js.map +0 -1
- package/dist/chunks/serializer.D1Ts_p8h.js +0 -462
- package/dist/chunks/serializer.D1Ts_p8h.js.map +0 -1
package/dist/cli/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../src/app/server/activity.ts","../../src/app/server/agents/claude-code.ts","../../src/app/server/agents/opencode.ts","../../src/app/server/agents/index.ts","../../src/app/server/agent.ts","../../src/app/server/git.ts","../../src/app/server/status.ts","../../src/app/server/api.ts","../../src/cli/dev-server.ts","../../src/cli/index.ts"],"sourcesContent":["import { watch } from 'node:fs';\nimport { readFile } from 'node:fs/promises';\nimport type { ServerResponse } from 'node:http';\nimport { join } from 'node:path';\nimport { parseDecisions, parseOpenQuestions, parsePlans, parseProgress } from '../../core/parser';\nimport type { DecisionEntry, OpenQuestionEntry, PlanEntry, ProgressEntry } from '../../types';\n\nexport interface ActivityEvent {\n message: string;\n timestamp: string;\n}\n\ninterface Snapshot {\n plans: PlanEntry[];\n decisions: DecisionEntry[];\n openQuestions: OpenQuestionEntry[];\n progress: ProgressEntry[];\n}\n\nconst campFile = (root: string, name: string) => join(root, 'papercamp', name);\n\nconst readMaybe = (path: string): Promise<string> => readFile(path, 'utf-8').catch(() => '');\n\nasync function takeSnapshot(root: string): Promise<Snapshot> {\n const [plansRaw, decisionsRaw, questionsRaw, progressRaw] = await Promise.all([\n readMaybe(campFile(root, 'plans.md')),\n readMaybe(campFile(root, 'decisions.md')),\n readMaybe(campFile(root, 'open-questions.md')),\n readMaybe(campFile(root, 'progress.md')),\n ]);\n return {\n plans: parsePlans(plansRaw).entries,\n decisions: parseDecisions(decisionsRaw).entries,\n openQuestions: parseOpenQuestions(questionsRaw).entries,\n progress: parseProgress(progressRaw),\n };\n}\n\nfunction diffAndSynthesize(before: Snapshot, after: Snapshot): ActivityEvent[] {\n const events: ActivityEvent[] = [];\n const ts = new Date().toISOString();\n\n const beforePlans = new Map(before.plans.map((p) => [p.title, p]));\n const afterPlans = new Map(after.plans.map((p) => [p.title, p]));\n\n for (const [title, afterP] of afterPlans) {\n const beforeP = beforePlans.get(title);\n if (!beforeP) {\n events.push({ message: `New plan added: ${title}`, timestamp: ts });\n } else if (beforeP.status !== afterP.status) {\n events.push({ message: `Plan \"${title}\" marked ${afterP.status}`, timestamp: ts });\n } else {\n for (let i = 0; i < afterP.phases.length; i++) {\n const beforePhase = beforeP.phases[i];\n const afterPhase = afterP.phases[i];\n if (beforePhase && beforePhase.done !== afterPhase.done) {\n events.push({\n message: afterPhase.done\n ? `Phase ${i + 1}/${afterP.phases.length} checked off in \"${title}\"`\n : `Phase ${i + 1}/${afterP.phases.length} unchecked in \"${title}\"`,\n timestamp: ts,\n });\n }\n }\n }\n }\n\n for (const [title] of beforePlans) {\n if (!afterPlans.has(title)) {\n events.push({ message: `Plan removed: ${title}`, timestamp: ts });\n }\n }\n\n const beforeDecisions = new Map(before.decisions.map((d) => [d.title, d]));\n const afterDecisions = new Map(after.decisions.map((d) => [d.title, d]));\n for (const [title] of afterDecisions) {\n if (!beforeDecisions.has(title)) {\n events.push({ message: `New decision: ${title}`, timestamp: ts });\n }\n }\n\n const beforeQuestions = new Map(before.openQuestions.map((q) => [q.title, q]));\n const afterQuestions = new Map(after.openQuestions.map((q) => [q.title, q]));\n for (const [title] of afterQuestions) {\n if (!beforeQuestions.has(title)) {\n events.push({ message: `New open question: ${title}`, timestamp: ts });\n }\n }\n\n const beforeProgress = new Map(before.progress.map((p) => [p.date, p]));\n const afterProgress = new Map(after.progress.map((p) => [p.date, p]));\n for (const [date] of afterProgress) {\n if (!beforeProgress.has(date)) {\n events.push({ message: `Progress logged: ${date}`, timestamp: ts });\n }\n }\n\n return events;\n}\n\nexport function createActivityManager(root: string) {\n const clients = new Set<ServerResponse>();\n let snapshot: Snapshot | null = null;\n let timer: ReturnType<typeof setTimeout> | null = null;\n\n const files = ['plans.md', 'decisions.md', 'open-questions.md', 'progress.md'];\n\n async function check() {\n try {\n const next = await takeSnapshot(root);\n if (snapshot) {\n const events = diffAndSynthesize(snapshot, next);\n for (const event of events) {\n const data = `data: ${JSON.stringify(event)}\\n\\n`;\n for (const client of clients) {\n try {\n client.write(data);\n } catch {\n clients.delete(client);\n }\n }\n }\n }\n snapshot = next;\n } catch {\n // re-parse failed, keep the old snapshot\n }\n }\n\n for (const file of files) {\n const filePath = campFile(root, file);\n try {\n watch(filePath, () => {\n if (timer) clearTimeout(timer);\n timer = setTimeout(check, 300);\n });\n } catch {\n // file might not exist yet\n }\n }\n\n takeSnapshot(root).then((s) => {\n snapshot = s;\n });\n\n return {\n subscribe(res: ServerResponse) {\n clients.add(res);\n const connected = JSON.stringify({\n message: 'Watching for changes…',\n timestamp: new Date().toISOString(),\n });\n res.write(`data: ${connected}\\n\\n`);\n res.on('close', () => clients.delete(res));\n },\n };\n}\n","export interface ParsedAgentLine {\n text: string;\n done?: boolean;\n error?: boolean;\n}\n\nexport function buildArgs(prompt: string): string[] {\n return ['-p', prompt, '--output-format', 'stream-json', '--verbose', '--permission-mode', 'auto'];\n}\n\n/**\n * Shape confirmed by a live `claude -p ... --output-format stream-json` smoke test\n * (see decisions.md, \"Confirm Claude Code's headless stream-json shape...\"), not guessed\n * from --help. Unknown subtypes fall through to a generic status line rather than being\n * dropped or throwing, since new bookkeeping subtypes (e.g. thinking_tokens) can appear.\n */\nexport function parseLine(line: string): ParsedAgentLine | null {\n let json: Record<string, unknown>;\n try {\n json = JSON.parse(line);\n } catch {\n return null;\n }\n\n switch (json.type) {\n case 'system': {\n if (json.subtype === 'init') {\n return { text: 'Agent session started' };\n }\n if (json.subtype === 'post_turn_summary' && typeof json.status_detail === 'string') {\n return { text: json.status_detail };\n }\n return null;\n }\n case 'rate_limit_event':\n return null;\n case 'assistant': {\n const message = json.message as { content?: unknown[] } | undefined;\n const blocks = message?.content ?? [];\n for (const block of blocks) {\n const b = block as { type?: string; name?: string; text?: string };\n if (b.type === 'tool_use') {\n return { text: `Running ${b.name ?? 'a tool'}…` };\n }\n if (b.type === 'text' && typeof b.text === 'string' && b.text.trim()) {\n return { text: b.text.trim() };\n }\n }\n return null;\n }\n case 'user': {\n const message = json.message as { content?: unknown[] } | undefined;\n const content = message?.content;\n const block = Array.isArray(content) ? (content[0] as Record<string, unknown>) : undefined;\n if (block?.is_error) {\n const text = typeof block.content === 'string' ? block.content : 'Tool call failed';\n return { text: `Error: ${text}`, error: true };\n }\n return { text: 'Tool finished' };\n }\n case 'result': {\n const error = Boolean(json.is_error);\n const result = typeof json.result === 'string' ? json.result.trim() : '';\n const text = result || (error ? 'Agent run failed' : 'Agent run finished');\n return { text, done: true, error };\n }\n default:\n return { text: 'Agent is working…' };\n }\n}\n","import type { ParsedAgentLine } from './claude-code';\n\nexport function buildArgs(prompt: string): string[] {\n return ['run', prompt, '--format', 'json'];\n}\n\nconst TOOL_LABELS: Record<string, string> = {\n bash: 'Running command',\n read: 'Reading file',\n edit: 'Editing file',\n write: 'Writing file',\n glob: 'Searching files',\n grep: 'Searching code',\n websearch: 'Searching web',\n webfetch: 'Fetching URL',\n question: 'Asking for input',\n};\n\nexport function parseLine(line: string): ParsedAgentLine | null {\n let json: Record<string, unknown>;\n try {\n json = JSON.parse(line);\n } catch {\n return null;\n }\n\n const type = json.type as string | undefined;\n const part = json.part as Record<string, unknown> | undefined;\n\n if (!type || !part) return null;\n\n switch (type) {\n case 'step_start':\n return null;\n case 'text': {\n const text = part.text as string | undefined;\n if (text?.trim()) return { text: text.trim() };\n return null;\n }\n case 'tool_use': {\n const tool = part.tool as string | undefined;\n const input = part.state ? (part.state as Record<string, unknown>).input : undefined;\n const desc = input ? (input as Record<string, unknown>).description : undefined;\n const label = tool ? TOOL_LABELS[tool] : 'Running tool';\n const detail = typeof desc === 'string' && desc.trim() ? `: ${desc.trim()}` : '';\n return tool ? { text: `${label}${detail}…` } : null;\n }\n case 'step_finish': {\n const reason = part.reason as string | undefined;\n const text = reason === 'tool-calls' ? null : reason === 'stop' ? 'Done' : 'Step finished';\n if (!text) return null;\n return { text };\n }\n default:\n return null;\n }\n}\n","import type { AgentId, DefaultAgentsMap, TaskKind } from '../../../types/index';\nimport * as claudeCode from './claude-code';\nimport type { ParsedAgentLine } from './claude-code';\nimport * as opencode from './opencode';\n\nexport interface AgentAdapter {\n command: string;\n buildArgs: (prompt: string) => string[];\n parseLine: (line: string) => ParsedAgentLine | null;\n}\n\nexport const DEFAULT_AGENT_ID: AgentId = 'claude-code';\n\nexport const AGENTS: Record<AgentId, AgentAdapter> = {\n 'claude-code': {\n command: 'claude',\n buildArgs: claudeCode.buildArgs,\n parseLine: claudeCode.parseLine,\n },\n opencode: {\n command: 'opencode',\n buildArgs: opencode.buildArgs,\n parseLine: opencode.parseLine,\n },\n};\n\nconst TASK_KIND_TO_DEFAULT_KEY: Record<TaskKind, keyof DefaultAgentsMap> = {\n phase: 'phase',\n audit: 'phase',\n draft: 'planDraft',\n extend: 'ideaExtend',\n};\n\nexport function resolveAgent(opts: {\n agentId: AgentId | undefined;\n defaultAgents?: DefaultAgentsMap;\n taskKind?: TaskKind;\n}): { id: AgentId; adapter: AgentAdapter } {\n const { agentId, defaultAgents, taskKind } = opts;\n if (agentId && agentId in AGENTS) return { id: agentId, adapter: AGENTS[agentId] };\n if (taskKind && defaultAgents) {\n const key = TASK_KIND_TO_DEFAULT_KEY[taskKind];\n const fallback = defaultAgents[key];\n if (fallback && fallback in AGENTS) return { id: fallback, adapter: AGENTS[fallback] };\n }\n return { id: DEFAULT_AGENT_ID, adapter: AGENTS[DEFAULT_AGENT_ID] };\n}\n","import { type ChildProcess, spawn } from 'node:child_process';\nimport { readFileSync } from 'node:fs';\nimport { readFile } from 'node:fs/promises';\nimport type { ServerResponse } from 'node:http';\nimport { join } from 'node:path';\nimport { createInterface } from 'node:readline';\nimport { parseIdeas, parsePlans } from '../../core/parser';\nimport {\n type AgentId,\n type AgentTaskState,\n type AgentTaskStatus,\n DEFAULT_AGENTS,\n type DefaultAgentsMap,\n type IdeaEntry,\n type PaperCampConfig,\n type PhaseItem,\n type PlanEntry,\n type TaskKind,\n} from '../../types/index';\nimport { type AgentAdapter, resolveAgent } from './agents';\n\nconst MAX_LINES = 50;\n\ninterface AgentTask {\n taskKind: TaskKind;\n planTitle: string;\n planId?: string;\n // Absent for a plan-scoped task (e.g. a convergence audit spanning every phase),\n // present for a single-phase task.\n phaseIndex?: number;\n // Only set for plan-scoped tasks, to check success against: did Phases or Log grow?\n planBaseline?: { phases: number; log: number };\n // Only set for an idea-drafting task, which has neither planId nor phaseIndex since\n // the plan doesn't exist yet — success is checked by idea id instead.\n ideaId?: string;\n // For idea-extend tasks: snapshot the idea's body before launch so we can detect changes.\n ideaBodyBaseline?: string;\n status: AgentTaskStatus;\n agentId: AgentId;\n adapter: AgentAdapter;\n proc: ChildProcess;\n lines: string[];\n}\n\nfunction readDefaultAgentIds(root: string): DefaultAgentsMap {\n try {\n const raw = readFileSync(join(root, '.paper-camp', 'config.json'), 'utf-8');\n const config = JSON.parse(raw) as PaperCampConfig & { defaultAgent?: AgentId };\n if (config.defaultAgents) return config.defaultAgents;\n if (config.defaultAgent) {\n return {\n phase: config.defaultAgent,\n planDraft: config.defaultAgent,\n ideaExtend: config.defaultAgent,\n };\n }\n return DEFAULT_AGENTS;\n } catch {\n return DEFAULT_AGENTS;\n }\n}\n\ntype Result = { ok: true } | { ok: false; error: string };\n\nfunction buildAgentPrompt(plan: PlanEntry, phase: PhaseItem, phaseIndex: number): string {\n return `You're working on phase ${phaseIndex + 1} (\"${phase.text}\") of the plan \"${plan.title}\" (${plan.id ?? 'no id'}) in papercamp/plans.md.\n\n${phase.description ?? ''}\n\nPlan context: ${plan.body}\n\nDo only this phase. When done, check it off in plans.md (- [ ] -> - [x]) and append what you did to progress.md. If this was the last unchecked phase, set the plan's Status to \\`review\\`, not \\`done\\`, per this repo's AGENTS.md.`;\n}\n\nexport function createAgentManager(\n root: string,\n ensureBranch: (plan: PlanEntry) => void = () => {},\n) {\n const clients = new Set<ServerResponse>();\n let current: AgentTask | null = null;\n\n function broadcast(message: string) {\n const data = `data: ${JSON.stringify({ message, timestamp: new Date().toISOString(), type: 'agent' })}\\n\\n`;\n for (const client of clients) {\n try {\n client.write(data);\n } catch {\n clients.delete(client);\n }\n }\n }\n\n function pushLine(task: AgentTask, text: string) {\n task.lines.push(text);\n if (task.lines.length > MAX_LINES) task.lines.shift();\n broadcast(text);\n }\n\n function setStatus(task: AgentTask, status: AgentTaskStatus) {\n task.status = status;\n broadcast(`agent: ${status}`);\n }\n\n async function didTaskProgress(task: AgentTask): Promise<boolean | null> {\n try {\n if (task.taskKind === 'extend') {\n const raw = await readFile(join(root, 'papercamp', 'ideas.md'), 'utf-8');\n const entries = parseIdeas(raw);\n const idea = entries.find((e) => e.id === task.ideaId);\n if (!idea) return null;\n if (task.ideaBodyBaseline === undefined) return null;\n return idea.body !== task.ideaBodyBaseline;\n }\n const raw = await readFile(join(root, 'papercamp', 'plans.md'), 'utf-8');\n const { entries } = parsePlans(raw);\n if (task.ideaId !== undefined) {\n return entries.some((p) => p.idea === task.ideaId);\n }\n const plan =\n entries.find((p) => p.id === task.planId) ??\n entries.find((p) => p.title === task.planTitle);\n if (!plan) return null;\n if (task.phaseIndex !== undefined) {\n return plan.phases[task.phaseIndex]?.done ?? null;\n }\n if (!task.planBaseline) return null;\n return (\n plan.phases.length > task.planBaseline.phases ||\n (plan.log?.length ?? 0) > task.planBaseline.log\n );\n } catch {\n return null;\n }\n }\n\n function finishTask(task: AgentTask, error: boolean) {\n setStatus(task, error ? 'error' : 'done');\n if (error) return;\n didTaskProgress(task).then((progressed) => {\n if (current === task && progressed === false) {\n const warning =\n task.taskKind === 'extend'\n ? `Warning: agent finished but the idea body for ${task.ideaId} did not change — verify manually`\n : task.ideaId !== undefined\n ? `Warning: agent finished but no plan linking idea: ${task.ideaId} appeared in plans.md — verify manually`\n : task.phaseIndex !== undefined\n ? 'Warning: agent finished but did not check off this phase in plans.md — verify manually'\n : 'Warning: agent finished but appended nothing to Phases or Log — verify manually';\n pushLine(task, warning);\n }\n });\n }\n\n function attachReader(task: AgentTask) {\n if (!task.proc.stdout) return;\n const rl = createInterface({ input: task.proc.stdout });\n rl.on('line', (line) => {\n if (current !== task || !line.trim()) return;\n const parsed = task.adapter.parseLine(line);\n if (!parsed) return;\n pushLine(task, parsed.text);\n if (parsed.done) {\n finishTask(task, Boolean(parsed.error));\n }\n });\n\n task.proc.on('close', (code) => {\n if (current !== task) return;\n if (task.status === 'starting' || task.status === 'running') {\n finishTask(task, code !== 0);\n } else if (task.status === 'stopping') {\n setStatus(task, 'done');\n }\n });\n\n task.proc.on('error', (err) => {\n if (current !== task) return;\n pushLine(task, `Failed to spawn agent: ${err.message}`);\n setStatus(task, 'error');\n });\n }\n\n function spawnAgent(adapter: AgentAdapter, args: string[]): ChildProcess {\n return spawn(adapter.command, args, {\n cwd: root,\n stdio: ['ignore', 'pipe', 'pipe'],\n });\n }\n\n function isBusy(): boolean {\n return current !== null && current.status !== 'done' && current.status !== 'error';\n }\n\n // Shared by start()/startForPlan()/startForIdea(): synchronous on purpose, same\n // race-avoidance reasoning as the busy-guard above — no `await` between the guard\n // check and reserving `current`.\n function launch(\n identity: { planTitle: string; planId?: string; agentOverride?: AgentId },\n prompt: string,\n scope: Pick<\n AgentTask,\n 'taskKind' | 'phaseIndex' | 'planBaseline' | 'ideaId' | 'ideaBodyBaseline'\n >,\n ): Result {\n if (isBusy()) {\n return { ok: false, error: 'An agent task is already running' };\n }\n const defaultAgents = readDefaultAgentIds(root);\n const { id: agentId, adapter } = resolveAgent({\n agentId: identity.agentOverride,\n defaultAgents,\n taskKind: scope.taskKind,\n });\n const proc = spawnAgent(adapter, adapter.buildArgs(prompt));\n const task: AgentTask = {\n planTitle: identity.planTitle,\n planId: identity.planId,\n status: 'starting',\n agentId,\n adapter,\n proc,\n lines: [],\n ...scope,\n };\n current = task;\n attachReader(task);\n setStatus(task, 'running');\n return { ok: true };\n }\n\n function start(plan: PlanEntry, phaseIndex: number): Result {\n if (isBusy()) {\n return { ok: false, error: 'An agent task is already running' };\n }\n const phase = plan.phases[phaseIndex];\n if (!phase) {\n return { ok: false, error: 'Phase not found' };\n }\n ensureBranch(plan);\n const prompt = buildAgentPrompt(plan, phase, phaseIndex);\n return launch({ planTitle: plan.title, planId: plan.id, agentOverride: plan.agent }, prompt, {\n taskKind: 'phase',\n phaseIndex,\n });\n }\n\n // Plan-scoped launch mode: no single phase, so success is judged by whether the\n // agent appended anything to Phases or Log rather than whether one checkbox flipped.\n function startForPlan(plan: PlanEntry, prompt: string): Result {\n return launch({ planTitle: plan.title, planId: plan.id, agentOverride: plan.agent }, prompt, {\n taskKind: 'audit',\n planBaseline: { phases: plan.phases.length, log: plan.log?.length ?? 0 },\n });\n }\n\n // Idea-drafting launch mode: there's no plan yet (and so no per-plan agent override\n // either) — the plan only exists once the agent writes it, so success is judged by\n // whether a new plan entry linking this idea's id shows up in plans.md.\n function startForIdea(idea: IdeaEntry, prompt: string): Result {\n if (!idea.id) {\n return { ok: false, error: 'Idea has no id to link a drafted plan back to' };\n }\n return launch({ planTitle: `Draft plan for ${idea.id}` }, prompt, {\n taskKind: 'draft',\n ideaId: idea.id,\n });\n }\n\n // Idea-extend launch mode: given an idea, explores the codebase and rewrites its\n // body in place in ideas.md. Success is judged by whether that idea's body text\n // actually changed.\n function startForIdeaExtend(idea: IdeaEntry, prompt: string): Result {\n if (!idea.id) {\n return { ok: false, error: 'Idea has no id to extend' };\n }\n return launch({ planTitle: `Extend ${idea.id}` }, prompt, {\n taskKind: 'extend',\n ideaId: idea.id,\n ideaBodyBaseline: idea.body,\n });\n }\n\n function stop(): Result {\n if (!current) {\n return { ok: false, error: 'No agent task running' };\n }\n const task = current;\n setStatus(task, 'stopping');\n if (!task.proc.killed) task.proc.kill('SIGTERM');\n // SIGTERM can be ignored or delayed indefinitely; without this escalation a hung\n // process leaves `current` stuck in 'stopping' forever, permanently blocking start().\n setTimeout(() => {\n if (current === task && task.status === 'stopping') {\n task.proc.kill('SIGKILL');\n }\n }, 5000);\n return { ok: true };\n }\n\n function getStatus(): AgentTaskState | null {\n if (!current) return null;\n return {\n status: current.status,\n taskKind: current.taskKind,\n planTitle: current.planTitle,\n planId: current.planId,\n phaseIndex: current.phaseIndex,\n ideaId: current.ideaId,\n agentId: current.agentId,\n lines: [...current.lines],\n };\n }\n\n return {\n start,\n startForPlan,\n startForIdea,\n startForIdeaExtend,\n stop,\n getStatus,\n subscribe(res: ServerResponse) {\n clients.add(res);\n res.on('close', () => clients.delete(res));\n },\n killCurrent() {\n if (current?.proc && !current.proc.killed) {\n current.proc.kill();\n }\n },\n };\n}\n\nexport interface AgentManager {\n start: (plan: PlanEntry, phaseIndex: number) => Result;\n startForPlan: (plan: PlanEntry, prompt: string) => Result;\n startForIdea: (idea: IdeaEntry, prompt: string) => Result;\n startForIdeaExtend: (idea: IdeaEntry, prompt: string) => Result;\n stop: () => Result;\n getStatus: () => AgentTaskState | null;\n subscribe: (res: ServerResponse) => void;\n killCurrent: () => void;\n}\n","import { spawn, spawnSync } from 'node:child_process';\nimport { watch } from 'node:fs';\nimport type { ServerResponse } from 'node:http';\nimport { join } from 'node:path';\nimport type { GitStatusEntry, PlanEntry } from '../../types';\n\nexport function createGitManager(root: string) {\n const clients = new Set<ServerResponse>();\n\n function broadcast(event: { message: string; timestamp: string }) {\n const data = `data: ${JSON.stringify(event)}\\n\\n`;\n for (const client of clients) {\n try {\n client.write(data);\n } catch {\n clients.delete(client);\n }\n }\n }\n\n function parsePorcelain(output: string): GitStatusEntry[] {\n const entries: GitStatusEntry[] = [];\n for (const line of output.split('\\n')) {\n if (!line.trim()) continue;\n const x = line[0] ?? ' ';\n const y = line[1] ?? ' ';\n const rest = line.slice(3);\n const path = rest.split(' -> ').pop() ?? rest;\n entries.push({\n path,\n status: `${x}${y}`,\n staged: x !== ' ' && x !== '?',\n });\n }\n return entries;\n }\n\n function runGit(args: string[]): Promise<string> {\n return new Promise((resolve, reject) => {\n const proc = spawn('git', args, {\n cwd: root,\n stdio: ['ignore', 'pipe', 'pipe'],\n });\n let stdout = '';\n let stderr = '';\n proc.stdout?.on('data', (d: Buffer) => {\n stdout += d.toString();\n });\n proc.stderr?.on('data', (d: Buffer) => {\n stderr += d.toString();\n });\n proc.on('close', (code) => {\n if (code === 0) {\n resolve(stdout);\n } else {\n reject(new Error(stderr || `git ${args[0]} exited with code ${code}`));\n }\n });\n proc.on('error', reject);\n });\n }\n\n function runGitStatus(): Promise<GitStatusEntry[]> {\n return runGit(['status', '--porcelain=v1']).then(parsePorcelain);\n }\n\n async function commit(files: string[], title: string, message?: string): Promise<void> {\n if (files.length > 0) {\n await runGit(['add', '--', ...files]);\n }\n const args = ['commit', '-m', title];\n if (message) args.push('-m', message);\n await runGit(args);\n }\n\n function ensureBranch(plan: PlanEntry): void {\n if (!plan.kind || !plan.id) return;\n\n const kind = plan.kind.toLowerCase();\n const id = plan.id.toLowerCase();\n const title = plan.title\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '');\n\n const branch = `${kind}/${id}-${title}`;\n\n const currentResult = spawnSync('git', ['rev-parse', '--abbrev-ref', 'HEAD'], { cwd: root });\n if (currentResult.status !== 0) {\n throw new Error(\n currentResult.stderr.toString().trim() || 'Unable to read current git branch',\n );\n }\n const currentBranch = currentResult.stdout.toString().trim();\n if (currentBranch === branch) return;\n\n const result = spawnSync('git', ['checkout', '-b', branch, 'main'], { cwd: root });\n if (result.status !== 0) {\n // Branch already exists — just check it out\n const checkoutResult = spawnSync('git', ['checkout', branch], { cwd: root });\n if (checkoutResult.status !== 0) {\n throw new Error(\n checkoutResult.stderr.toString().trim() ||\n result.stderr.toString().trim() ||\n `Unable to check out ${branch}`,\n );\n }\n }\n }\n\n async function refresh() {\n try {\n await runGitStatus();\n broadcast({\n message: 'Working tree status updated',\n timestamp: new Date().toISOString(),\n });\n } catch {\n // git not available or not a repo\n }\n }\n\n const gitDir = join(root, '.git');\n let timer: ReturnType<typeof setTimeout> | null = null;\n try {\n watch(gitDir, { recursive: true }, (eventType, filename) => {\n if (filename === 'index') {\n if (timer) clearTimeout(timer);\n timer = setTimeout(refresh, 500);\n }\n });\n } catch {\n // watcher not available\n }\n\n const srcDir = join(root, 'src');\n let srcTimer: ReturnType<typeof setTimeout> | null = null;\n try {\n watch(srcDir, { recursive: true }, () => {\n if (srcTimer) clearTimeout(srcTimer);\n srcTimer = setTimeout(refresh, 500);\n });\n } catch {\n // src/ doesn't exist or watcher not available\n }\n\n function getCurrentBranch(): string {\n const result = spawnSync('git', ['rev-parse', '--abbrev-ref', 'HEAD'], { cwd: root });\n return result.stdout.toString().trim();\n }\n\n function getFeatureBranchPlanId(): string | null {\n const branch = getCurrentBranch();\n const match = branch.match(/^[a-z]+\\/([a-z]+-\\d+)-/);\n return match ? match[1].toUpperCase() : null;\n }\n\n return {\n async getStatus(): Promise<GitStatusEntry[]> {\n return runGitStatus();\n },\n getCurrentBranch,\n commit,\n ensureBranch,\n getFeatureBranchPlanId,\n subscribe(res: ServerResponse) {\n clients.add(res);\n res.on('close', () => clients.delete(res));\n },\n };\n}\n","import { spawn } from 'node:child_process';\nimport { watch } from 'node:fs';\nimport type { ServerResponse } from 'node:http';\nimport { join } from 'node:path';\nimport type { CheckName, CheckResult, CheckStatus } from '../../types';\n\ninterface StatusSnapshot {\n lint: CheckResult;\n format: CheckResult;\n test: CheckResult;\n}\n\nconst CHECK_COMMANDS: Record<CheckName, string> = {\n lint: 'npx biome lint .',\n format: 'npx biome format .',\n test: 'npx vitest run',\n};\n\nexport function createStatusManager(root: string) {\n const clients = new Set<ServerResponse>();\n const snapshot: StatusSnapshot = {\n lint: { status: 'stale', lastRun: null, output: '' },\n format: { status: 'stale', lastRun: null, output: '' },\n test: { status: 'stale', lastRun: null, output: '' },\n };\n const running = new Set<CheckName>();\n const queued = new Set<CheckName>();\n\n function broadcast(event: { message: string; timestamp: string }) {\n const data = `data: ${JSON.stringify(event)}\\n\\n`;\n for (const client of clients) {\n try {\n client.write(data);\n } catch {\n clients.delete(client);\n }\n }\n }\n\n function setResult(name: CheckName, status: CheckStatus, output: string) {\n snapshot[name] = { status, lastRun: new Date().toISOString(), output };\n broadcast({\n message: `${name}: ${status}`,\n timestamp: snapshot[name].lastRun!,\n });\n if (status !== 'running' && queued.has(name)) {\n queued.delete(name);\n runCheck(name);\n }\n }\n\n function runCheck(name: CheckName) {\n if (running.has(name)) {\n queued.add(name);\n return;\n }\n running.add(name);\n setResult(name, 'running', '');\n\n const cmd = CHECK_COMMANDS[name];\n const proc = spawn(cmd, {\n cwd: root,\n stdio: ['ignore', 'pipe', 'pipe'],\n shell: true,\n });\n\n let stdout = '';\n let stderr = '';\n proc.stdout?.on('data', (d: Buffer) => {\n stdout += d.toString();\n });\n proc.stderr?.on('data', (d: Buffer) => {\n stderr += d.toString();\n });\n\n proc.on('close', (code) => {\n running.delete(name);\n const output = stdout + stderr;\n if (code === 0) {\n setResult(name, 'pass', output);\n } else {\n setResult(name, 'fail', output);\n }\n });\n\n proc.on('error', (err) => {\n running.delete(name);\n setResult(name, 'fail', `Failed to spawn process: ${err.message}`);\n });\n }\n\n function runQualityFix() {\n if (running.has('lint') || running.has('format')) return;\n setResult('lint', 'running', 'Applying automatic fixes…');\n setResult('format', 'running', 'Applying automatic fixes…');\n\n const proc = spawn('npx biome check . --write', {\n cwd: root,\n stdio: ['ignore', 'pipe', 'pipe'],\n shell: true,\n });\n\n proc.on('close', () => {\n runCheck('lint');\n runCheck('format');\n });\n\n proc.on('error', (err) => {\n const message = `Failed to spawn fix process: ${err.message}`;\n setResult('lint', 'fail', message);\n setResult('format', 'fail', message);\n });\n }\n\n const srcDir = join(root, 'src');\n let srcTimer: ReturnType<typeof setTimeout> | null = null;\n try {\n watch(srcDir, { recursive: true }, () => {\n if (srcTimer) clearTimeout(srcTimer);\n srcTimer = setTimeout(() => {\n runCheck('lint');\n runCheck('format');\n }, 1000);\n });\n } catch {\n // watcher not available (src/ doesn't exist or platform doesn't support recursive)\n }\n\n return {\n getStatus(): StatusSnapshot {\n return {\n lint: { ...snapshot.lint },\n format: { ...snapshot.format },\n test: { ...snapshot.test },\n };\n },\n runCheck,\n runQualityFix,\n subscribe(res: ServerResponse) {\n clients.add(res);\n for (const name of ['lint', 'format', 'test'] as CheckName[]) {\n const result = snapshot[name];\n if (result.status !== 'stale') {\n res.write(\n `data: ${JSON.stringify({ message: `${name}: ${result.status}`, timestamp: result.lastRun })}\\n\\n`,\n );\n }\n }\n res.on('close', () => clients.delete(res));\n },\n };\n}\n","import { mkdir, readFile, readdir, stat, writeFile } from 'node:fs/promises';\nimport type { IncomingMessage, ServerResponse } from 'node:http';\nimport { extname, join } from 'node:path';\nimport { applyEnvEntries, parseEnv } from '../../core/env';\nimport {\n findConsistencyIssues,\n parseDecisions,\n parseIdeas,\n parseOpenQuestions,\n parsePlans,\n parseProgress,\n} from '../../core/parser';\nimport {\n appendBlock,\n assignPlanId,\n formatPlanEntry,\n formatPlans,\n todayDateString,\n} from '../../core/serializer';\nimport {\n AGENT_IDS,\n type AgentId,\n DEFAULT_AGENTS,\n type DefaultAgentsMap,\n type EnvEntry,\n type LogEntry,\n PLAN_KINDS,\n type PaperCampConfig,\n type PhaseItem,\n type PlanEntry,\n type PlanStatus,\n} from '../../types/index';\nimport { createActivityManager } from './activity';\nimport { type AgentManager, createAgentManager } from './agent';\nimport { createGitManager } from './git';\nimport { createStatusManager } from './status';\n\nasync function readMaybe(path: string): Promise<string> {\n try {\n return await readFile(path, 'utf-8');\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') return '';\n throw error;\n }\n}\n\nasync function fileExists(path: string): Promise<boolean> {\n try {\n await stat(path);\n return true;\n } catch {\n return false;\n }\n}\n\nasync function readBody(req: IncomingMessage): Promise<string> {\n return new Promise((resolve, reject) => {\n let body = '';\n req.on('data', (chunk) => {\n body += chunk;\n });\n req.on('end', () => resolve(body));\n req.on('error', reject);\n });\n}\n\ninterface ApiRoute {\n path: string;\n handler: (root: string) => Promise<unknown>;\n}\n\nconst campFile = (root: string, name: string) => join(root, 'papercamp', name);\n\nconst CONFIG_ALLOWLIST = [\n 'biome.json',\n 'tsconfig.json',\n 'tailwind.config.ts',\n 'vite.config.ts',\n 'vite.app.config.ts',\n 'postcss.config.js',\n 'package.json',\n];\n\nasync function checkBranchConflictForPlan(\n root: string,\n git: { getFeatureBranchPlanId: () => string | null },\n targetPlanId?: string,\n): Promise<string | null> {\n const activePlanId = git.getFeatureBranchPlanId();\n if (!activePlanId) return null;\n if (targetPlanId && activePlanId === targetPlanId) return null;\n const plansRaw = await readMaybe(campFile(root, 'plans.md'));\n if (!plansRaw) return null;\n const { entries } = parsePlans(plansRaw);\n const activePlan = entries.find((p) => p.id === activePlanId);\n if (!activePlan || activePlan.status === 'done' || activePlan.status === 'dropped') return null;\n return `Finish \\`${activePlanId}\\` — ${activePlan.title} — before starting another plan`;\n}\n\nconst apiRoutes: ApiRoute[] = [\n {\n path: '/api/package-name',\n handler: async (root) => {\n const raw = await readMaybe(join(root, 'package.json'));\n if (!raw) return null;\n try {\n const pkg = JSON.parse(raw);\n return pkg.name ?? null;\n } catch {\n return null;\n }\n },\n },\n {\n path: '/api/plans',\n handler: async (root) => parsePlans(await readMaybe(campFile(root, 'plans.md'))),\n },\n {\n path: '/api/progress',\n handler: async (root) => ({\n entries: parseProgress(await readMaybe(campFile(root, 'progress.md'))),\n }),\n },\n {\n path: '/api/decisions',\n handler: async (root) => parseDecisions(await readMaybe(campFile(root, 'decisions.md'))),\n },\n {\n path: '/api/open-questions',\n handler: async (root) =>\n parseOpenQuestions(await readMaybe(campFile(root, 'open-questions.md'))),\n },\n {\n path: '/api/ideas',\n handler: async (root) => ({\n content: await readMaybe(campFile(root, 'ideas.md')),\n }),\n },\n {\n path: '/api/consistency',\n handler: async (root) => {\n const [decisionsRaw, openQuestionsRaw, plansRaw] = await Promise.all([\n readMaybe(campFile(root, 'decisions.md')),\n readMaybe(campFile(root, 'open-questions.md')),\n readMaybe(campFile(root, 'plans.md')),\n ]);\n const decisions = parseDecisions(decisionsRaw);\n const openQuestions = parseOpenQuestions(openQuestionsRaw);\n const plans = parsePlans(plansRaw);\n return findConsistencyIssues(decisions.entries, openQuestions.entries, plans.entries);\n },\n },\n {\n path: '/api/config',\n handler: async (root) => {\n const raw = await readMaybe(join(root, '.paper-camp', 'config.json'));\n return raw ? JSON.parse(raw) : null;\n },\n },\n {\n path: '/api/docs',\n handler: async (root) => {\n const docNames = ['MAIN.md', 'README.md', 'CHANGELOG.md', 'LICENSE'];\n const files: { name: string; content: string }[] = [];\n for (const name of docNames) {\n const content = await readMaybe(join(root, name));\n if (content) files.push({ name, content });\n }\n return { files };\n },\n },\n {\n path: '/api/configs',\n handler: async (root) => {\n const configNames = [\n 'biome.json',\n 'tsconfig.json',\n 'tailwind.config.ts',\n 'vite.config.ts',\n 'vite.app.config.ts',\n 'postcss.config.js',\n 'package.json',\n ];\n const files: string[] = [];\n for (const name of configNames) {\n const content = await readMaybe(join(root, name));\n if (content) files.push(name);\n }\n return { files };\n },\n },\n];\n\nexport interface ApiMiddleware {\n (req: IncomingMessage, res: ServerResponse, next: () => void): Promise<void>;\n agent: AgentManager;\n}\n\nexport function createApiMiddleware(root: string): ApiMiddleware {\n const activity = createActivityManager(root);\n const git = createGitManager(root);\n const status = createStatusManager(root);\n const agent = createAgentManager(root, (plan) => git.ensureBranch(plan));\n const handler = async (req: IncomingMessage, res: ServerResponse, next: () => void) => {\n const pathname = (req.url ?? '').split('?')[0];\n\n // DELETE /api/plans?title=... — remove a plan entry\n if (req.method === 'DELETE' && pathname === '/api/plans') {\n try {\n const url = new URL(req.url ?? '', `http://${req.headers.host ?? 'localhost'}`);\n const title = url.searchParams.get('title');\n if (!title?.trim()) {\n res.statusCode = 400;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: 'title is required' }));\n return;\n }\n const filePath = campFile(root, 'plans.md');\n const parsed = parsePlans(await readMaybe(filePath));\n const trimmed = title.trim();\n const remaining = parsed.entries.filter((entry) => entry.title !== trimmed);\n if (remaining.length === parsed.entries.length) {\n res.statusCode = 404;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: 'plan not found' }));\n return;\n }\n await writeFile(filePath, formatPlans(remaining));\n res.statusCode = 200;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ ok: true }));\n } catch (error) {\n res.statusCode = 500;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: (error as Error).message }));\n }\n return;\n }\n\n // POST /api/plans — append a new idea entry\n if (req.method === 'POST' && pathname === '/api/plans') {\n try {\n const body = await readBody(req);\n const { title, content, kind } = JSON.parse(body) as {\n title: string;\n content?: string;\n kind?: string;\n };\n if (!title?.trim()) {\n res.statusCode = 400;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: 'title is required' }));\n return;\n }\n const planKind =\n kind && PLAN_KINDS.includes(kind as (typeof PLAN_KINDS)[number]) ? kind : 'feat';\n\n const configPath = join(root, '.paper-camp', 'config.json');\n const id = await assignPlanId(configPath, planKind);\n\n const entry = formatPlanEntry({\n title: title.trim(),\n status: 'idea',\n kind: planKind,\n id,\n created: todayDateString(),\n body: content?.trim(),\n });\n await appendBlock(campFile(root, 'plans.md'), entry);\n res.statusCode = 201;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ ok: true, id }));\n } catch (error) {\n res.statusCode = 500;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: (error as Error).message }));\n }\n return;\n }\n\n // PATCH /api/plans?title=... — update an existing plan entry\n if (req.method === 'PATCH' && pathname === '/api/plans') {\n try {\n const url = new URL(req.url ?? '', `http://${req.headers.host ?? 'localhost'}`);\n const title = url.searchParams.get('title');\n if (!title?.trim()) {\n res.statusCode = 400;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: 'title is required' }));\n return;\n }\n const body = await readBody(req);\n const updates = JSON.parse(body) as {\n phases?: PhaseItem[];\n status?: PlanStatus;\n log?: LogEntry[];\n agent?: AgentId | null;\n };\n if (updates.agent && !AGENT_IDS.includes(updates.agent)) {\n res.statusCode = 400;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: 'agent must be a known agent id' }));\n return;\n }\n const filePath = campFile(root, 'plans.md');\n const parsed = parsePlans(await readMaybe(filePath));\n const trimmed = title.trim();\n let found = false;\n const updated = parsed.entries.map((entry: PlanEntry) => {\n if (entry.title === trimmed) {\n found = true;\n return {\n ...entry,\n ...(updates.status !== undefined && { status: updates.status }),\n ...(updates.phases !== undefined && { phases: updates.phases }),\n ...(updates.log !== undefined && { log: updates.log }),\n ...(updates.agent !== undefined && { agent: updates.agent ?? undefined }),\n updated: todayDateString(),\n };\n }\n // Starting a plan puts it in focus — only one other plan is ever \"in focus\"\n // (in-progress) at a time. A `review` plan isn't in focus, it's done and\n // awaiting approval, so starting a different plan must never touch it.\n if (updates.status === 'in-progress' && entry.status === 'in-progress') {\n return { ...entry, status: 'planned' as const, updated: todayDateString() };\n }\n return entry;\n });\n if (!found) {\n res.statusCode = 404;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: 'plan not found' }));\n return;\n }\n if (updates.status === 'done') {\n const targetEntry = parsed.entries.find((e: PlanEntry) => e.title === trimmed);\n const conflict = await checkBranchConflictForPlan(root, git, targetEntry?.id);\n if (conflict) {\n res.statusCode = 409;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: conflict }));\n return;\n }\n }\n await writeFile(filePath, formatPlans(updated));\n\n if (updates.status === 'done') {\n const finalEntry = updated.find((e: PlanEntry) => e.title === trimmed);\n if (finalEntry) {\n try {\n git.ensureBranch(finalEntry);\n } catch {\n // Non-fatal: git operations may fail (not a repo, etc.)\n }\n }\n }\n\n res.statusCode = 200;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ ok: true }));\n } catch (error) {\n res.statusCode = 500;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: (error as Error).message }));\n }\n return;\n }\n\n // POST /api/ideas — append a new idea entry to ideas.md\n if (req.method === 'POST' && pathname === '/api/ideas') {\n try {\n const body = await readBody(req);\n const { title, content } = JSON.parse(body) as { title?: string; content?: string };\n if (!title?.trim()) {\n res.statusCode = 400;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: 'title is required' }));\n return;\n }\n const filePath = campFile(root, 'ideas.md');\n const existing = await readMaybe(filePath);\n const parsed = parseIdeas(existing);\n const maxNum = parsed.reduce((max, idea) => {\n if (idea.id) {\n const num = Number.parseInt(idea.id.replace('IDEA-', ''), 10);\n return Number.isNaN(num) ? max : Math.max(max, num);\n }\n return max;\n }, 0);\n const newId = `IDEA-${maxNum + 1}`;\n const section = `### ${newId}: ${title.trim()}\\n\\n${content?.trim() ?? ''}`;\n const trimmed = existing.trimEnd();\n const separator = trimmed.length === 0 ? '' : '\\n\\n---\\n\\n';\n await writeFile(filePath, `${trimmed}${separator}${section}\\n`);\n res.statusCode = 201;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ ok: true, id: newId }));\n } catch (error) {\n res.statusCode = 500;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: (error as Error).message }));\n }\n return;\n }\n\n // GET /api/icon — serve project icon\n if (req.method === 'GET' && pathname === '/api/icon') {\n const assetsDir = join(root, '.paper-camp', 'assets');\n const mimeMap: Record<string, string> = {\n svg: 'image/svg+xml',\n png: 'image/png',\n jpg: 'image/jpeg',\n jpeg: 'image/jpeg',\n gif: 'image/gif',\n webp: 'image/webp',\n };\n for (const [ext, mime] of Object.entries(mimeMap)) {\n try {\n const data = await readFile(join(assetsDir, `icon.${ext}`));\n res.statusCode = 200;\n res.setHeader('Content-Type', mime);\n res.setHeader('Cache-Control', 'no-cache');\n res.end(data);\n return;\n } catch {\n /* try next */\n }\n }\n res.statusCode = 404;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: 'no icon uploaded' }));\n return;\n }\n\n // POST /api/icon — upload project icon\n if (req.method === 'POST' && pathname === '/api/icon') {\n try {\n const body = await readBody(req);\n const { dataUri } = JSON.parse(body) as { dataUri?: string };\n if (!dataUri) {\n res.statusCode = 400;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: 'dataUri is required' }));\n return;\n }\n const match = dataUri.match(/^data:(image\\/[a-z0-9+.-]+);base64,(.+)$/);\n if (!match) {\n res.statusCode = 400;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: 'invalid data URI' }));\n return;\n }\n const mime = match[1];\n const ext = mime === 'image/svg+xml' ? 'svg' : mime.split('/')[1];\n const buffer = Buffer.from(match[2], 'base64');\n const assetsDir = join(root, '.paper-camp', 'assets');\n await mkdir(assetsDir, { recursive: true });\n await writeFile(join(assetsDir, `icon.${ext}`), buffer);\n res.statusCode = 200;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ ok: true }));\n } catch (error) {\n res.statusCode = 500;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: (error as Error).message }));\n }\n return;\n }\n\n // GET /api/git/status — return working tree status\n if (req.method === 'GET' && pathname === '/api/git/status') {\n try {\n const entries = await git.getStatus();\n const branch = git.getCurrentBranch();\n res.statusCode = 200;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ branch, entries }));\n } catch (error) {\n res.statusCode = 500;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: (error as Error).message }));\n }\n return;\n }\n\n // POST /api/git/commit — stage files and create a commit\n if (req.method === 'POST' && pathname === '/api/git/commit') {\n try {\n const body = await readBody(req);\n const { files, title, message } = JSON.parse(body) as {\n files: string[];\n title: string;\n message?: string;\n };\n if (!title?.trim()) {\n res.statusCode = 400;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: 'title is required' }));\n return;\n }\n await git.commit(files ?? [], title.trim(), message?.trim());\n res.statusCode = 200;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ ok: true }));\n } catch (error) {\n res.statusCode = 400;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: (error as Error).message }));\n }\n return;\n }\n\n // GET /api/status — return current lint/format/test check results\n if (req.method === 'GET' && pathname === '/api/status') {\n res.statusCode = 200;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify(status.getStatus()));\n return;\n }\n\n // POST /api/status/check?name=lint|format|test — trigger a one-off check run\n if (req.method === 'POST' && pathname === '/api/status/check') {\n const url = new URL(req.url ?? '', `http://${req.headers.host ?? 'localhost'}`);\n const name = url.searchParams.get('name');\n if (name !== 'lint' && name !== 'format' && name !== 'test') {\n res.statusCode = 400;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: 'name must be lint, format, or test' }));\n return;\n }\n status.runCheck(name);\n res.statusCode = 202;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ ok: true }));\n return;\n }\n\n // POST /api/status/fix — run `biome check . --write` to auto-fix lint/format issues\n if (req.method === 'POST' && pathname === '/api/status/fix') {\n status.runQualityFix();\n res.statusCode = 202;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ ok: true }));\n return;\n }\n\n // GET /api/activity/stream — SSE endpoint for live activity events\n if (req.method === 'GET' && pathname === '/api/activity/stream') {\n res.statusCode = 200;\n res.setHeader('Content-Type', 'text/event-stream');\n res.setHeader('Cache-Control', 'no-cache');\n res.setHeader('Connection', 'keep-alive');\n res.flushHeaders();\n activity.subscribe(res);\n git.subscribe(res);\n status.subscribe(res);\n agent.subscribe(res);\n return;\n }\n\n // GET /api/agent/status — current agent task state, if any\n if (req.method === 'GET' && pathname === '/api/agent/status') {\n res.statusCode = 200;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify(agent.getStatus()));\n return;\n }\n\n // POST /api/agent/launch — start a headless agent on one plan phase\n if (req.method === 'POST' && pathname === '/api/agent/launch') {\n try {\n const body = await readBody(req);\n const { planId, phaseIndex } = JSON.parse(body) as { planId?: string; phaseIndex?: number };\n if (!planId || typeof phaseIndex !== 'number') {\n res.statusCode = 400;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: 'planId and phaseIndex are required' }));\n return;\n }\n const parsed = parsePlans(await readMaybe(campFile(root, 'plans.md')));\n const plan = parsed.entries.find((p) => p.id === planId);\n if (!plan) {\n res.statusCode = 404;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: 'plan not found' }));\n return;\n }\n const conflict = await checkBranchConflictForPlan(root, git, plan.id);\n if (conflict) {\n res.statusCode = 409;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: conflict }));\n return;\n }\n const result = await agent.start(plan, phaseIndex);\n if (!result.ok) {\n res.statusCode = 409;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: result.error }));\n return;\n }\n res.statusCode = 202;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ ok: true }));\n } catch (error) {\n res.statusCode = 500;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: (error as Error).message }));\n }\n return;\n }\n\n // POST /api/agent/launch-audit — start a headless agent on a plan-scoped convergence audit\n if (req.method === 'POST' && pathname === '/api/agent/launch-audit') {\n try {\n const body = await readBody(req);\n const { planId, prompt } = JSON.parse(body) as { planId?: string; prompt?: string };\n if (!planId || !prompt) {\n res.statusCode = 400;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: 'planId and prompt are required' }));\n return;\n }\n const parsed = parsePlans(await readMaybe(campFile(root, 'plans.md')));\n const plan = parsed.entries.find((p) => p.id === planId);\n if (!plan) {\n res.statusCode = 404;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: 'plan not found' }));\n return;\n }\n const conflict = await checkBranchConflictForPlan(root, git, plan.id);\n if (conflict) {\n res.statusCode = 409;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: conflict }));\n return;\n }\n const result = agent.startForPlan(plan, prompt);\n if (!result.ok) {\n res.statusCode = 409;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: result.error }));\n return;\n }\n res.statusCode = 202;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ ok: true }));\n } catch (error) {\n res.statusCode = 500;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: (error as Error).message }));\n }\n return;\n }\n\n // POST /api/agent/launch-draft — start a headless agent that drafts a new plan from an idea\n if (req.method === 'POST' && pathname === '/api/agent/launch-draft') {\n try {\n const body = await readBody(req);\n const { ideaId, prompt } = JSON.parse(body) as { ideaId?: string; prompt?: string };\n if (!ideaId || !prompt) {\n res.statusCode = 400;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: 'ideaId and prompt are required' }));\n return;\n }\n const ideas = parseIdeas(await readMaybe(campFile(root, 'ideas.md')));\n const idea = ideas.find((i) => i.id === ideaId);\n if (!idea) {\n res.statusCode = 404;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: 'idea not found' }));\n return;\n }\n const conflict = await checkBranchConflictForPlan(root, git);\n if (conflict) {\n res.statusCode = 409;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: conflict }));\n return;\n }\n const result = agent.startForIdea(idea, prompt);\n if (!result.ok) {\n res.statusCode = 409;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: result.error }));\n return;\n }\n res.statusCode = 202;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ ok: true }));\n } catch (error) {\n res.statusCode = 500;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: (error as Error).message }));\n }\n return;\n }\n\n // POST /api/agent/launch-extend — start a headless agent to extend an idea's body\n if (req.method === 'POST' && pathname === '/api/agent/launch-extend') {\n try {\n const body = await readBody(req);\n const { ideaId, prompt } = JSON.parse(body) as { ideaId?: string; prompt?: string };\n if (!ideaId || !prompt) {\n res.statusCode = 400;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: 'ideaId and prompt are required' }));\n return;\n }\n const ideas = parseIdeas(await readMaybe(campFile(root, 'ideas.md')));\n const idea = ideas.find((i) => i.id === ideaId);\n if (!idea) {\n res.statusCode = 404;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: 'idea not found' }));\n return;\n }\n const conflict = await checkBranchConflictForPlan(root, git);\n if (conflict) {\n res.statusCode = 409;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: conflict }));\n return;\n }\n const result = agent.startForIdeaExtend(idea, prompt);\n if (!result.ok) {\n res.statusCode = 409;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: result.error }));\n return;\n }\n res.statusCode = 202;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ ok: true }));\n } catch (error) {\n res.statusCode = 500;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: (error as Error).message }));\n }\n return;\n }\n\n // POST /api/agent/stop — kill the running agent task\n if (req.method === 'POST' && pathname === '/api/agent/stop') {\n const result = agent.stop();\n if (!result.ok) {\n res.statusCode = 409;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: result.error }));\n return;\n }\n res.statusCode = 202;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ ok: true }));\n return;\n }\n\n // POST /api/config — update editable fields in .paper-camp/config.json (port, projectName)\n if (req.method === 'POST' && pathname === '/api/config') {\n try {\n const configPath = join(root, '.paper-camp', 'config.json');\n const raw = await readMaybe(configPath);\n if (!raw) {\n res.statusCode = 404;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: 'config not found' }));\n return;\n }\n const body = await readBody(req);\n const { port, projectName, defaultAgent, defaultAgents } = JSON.parse(body) as {\n port?: number;\n projectName?: string;\n defaultAgent?: AgentId;\n defaultAgents?: DefaultAgentsMap;\n };\n if (port !== undefined && (!Number.isInteger(port) || port <= 0)) {\n res.statusCode = 400;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: 'port must be a positive integer' }));\n return;\n }\n if (projectName !== undefined && projectName.trim().length === 0) {\n res.statusCode = 400;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: 'projectName must not be empty' }));\n return;\n }\n if (defaultAgent !== undefined && !AGENT_IDS.includes(defaultAgent)) {\n res.statusCode = 400;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: 'defaultAgent must be a known agent id' }));\n return;\n }\n if (defaultAgents !== undefined) {\n for (const key of ['phase', 'planDraft', 'ideaExtend'] as const) {\n if (!AGENT_IDS.includes(defaultAgents[key])) {\n res.statusCode = 400;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: `defaultAgents.${key} must be a known agent id` }));\n return;\n }\n }\n }\n const config = JSON.parse(raw) as PaperCampConfig;\n const resolvedDefaultAgents =\n defaultAgents ??\n (defaultAgent !== undefined\n ? { phase: defaultAgent, planDraft: defaultAgent, ideaExtend: defaultAgent }\n : undefined);\n const configWithOld = config as PaperCampConfig & { defaultAgent?: AgentId };\n const { defaultAgent: _oldAgent, ...configRest } = configWithOld;\n const updated: PaperCampConfig = {\n ...configRest,\n ...(port !== undefined && { port }),\n ...(projectName !== undefined && { projectName: projectName.trim() }),\n ...(resolvedDefaultAgents && { defaultAgents: resolvedDefaultAgents }),\n };\n await writeFile(configPath, JSON.stringify(updated, null, 2));\n res.statusCode = 200;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ ok: true }));\n } catch (error) {\n res.statusCode = 500;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: (error as Error).message }));\n }\n return;\n }\n\n // GET /api/env — read the project root's .env, masked client-side only\n if (req.method === 'GET' && pathname === '/api/env') {\n try {\n const envPath = join(root, '.env');\n const examplePath = join(root, '.env.example');\n const [exists, exampleExists] = await Promise.all([\n fileExists(envPath),\n fileExists(examplePath),\n ]);\n const entries = exists ? parseEnv(await readMaybe(envPath)) : [];\n const exampleKeys = exampleExists\n ? parseEnv(await readMaybe(examplePath)).map((e) => e.key)\n : [];\n const envKeys = new Set(entries.map((e) => e.key));\n const missingKeys = exampleKeys.filter((key) => !envKeys.has(key));\n res.statusCode = 200;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ exists, exampleExists, entries, missingKeys }));\n } catch (error) {\n res.statusCode = 500;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: (error as Error).message }));\n }\n return;\n }\n\n // POST /api/env — write the full desired entry set back to .env\n if (req.method === 'POST' && pathname === '/api/env') {\n try {\n const body = await readBody(req);\n const { entries } = JSON.parse(body) as { entries?: EnvEntry[] };\n if (!Array.isArray(entries)) {\n res.statusCode = 400;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: 'entries is required' }));\n return;\n }\n const keys = new Set<string>();\n for (const entry of entries) {\n if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(entry.key)) {\n res.statusCode = 400;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: `invalid key: ${entry.key}` }));\n return;\n }\n if (keys.has(entry.key)) {\n res.statusCode = 400;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: `duplicate key: ${entry.key}` }));\n return;\n }\n keys.add(entry.key);\n }\n const envPath = join(root, '.env');\n const current = await readMaybe(envPath);\n await writeFile(envPath, applyEnvEntries(current, entries));\n res.statusCode = 200;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ ok: true }));\n } catch (error) {\n res.statusCode = 500;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: (error as Error).message }));\n }\n return;\n }\n\n // GET /api/configs?name=... — read a specific config file's content\n if (req.method === 'GET' && pathname === '/api/configs') {\n const url = new URL(req.url ?? '', `http://${req.headers.host ?? 'localhost'}`);\n const name = url.searchParams.get('name');\n if (name) {\n try {\n if (!CONFIG_ALLOWLIST.includes(name)) {\n res.statusCode = 400;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: 'invalid config file name' }));\n return;\n }\n const content = await readMaybe(join(root, name));\n if (!content) {\n res.statusCode = 404;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: 'config file not found' }));\n return;\n }\n res.statusCode = 200;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ name, content }));\n return;\n } catch (error) {\n res.statusCode = 500;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: (error as Error).message }));\n return;\n }\n }\n // No name param: fall through to the generic route handler for listing\n }\n\n const route = apiRoutes.find((r) => r.path === pathname);\n if (!route) {\n next();\n return;\n }\n\n try {\n const data = await route.handler(root);\n res.statusCode = 200;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify(data));\n } catch (error) {\n res.statusCode = 500;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: (error as Error).message }));\n }\n };\n\n (handler as ApiMiddleware).agent = agent;\n return handler as ApiMiddleware;\n}\n","import { readFile, stat } from 'node:fs/promises';\nimport { type IncomingMessage, type ServerResponse, createServer } from 'node:http';\nimport { dirname, extname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { createApiMiddleware } from '../app/server/api';\n\nconst MIME: Record<string, string> = {\n '.html': 'text/html; charset=utf-8',\n '.js': 'text/javascript; charset=utf-8',\n '.mjs': 'text/javascript; charset=utf-8',\n '.css': 'text/css; charset=utf-8',\n '.json': 'application/json; charset=utf-8',\n '.svg': 'image/svg+xml',\n '.png': 'image/png',\n '.jpg': 'image/jpeg',\n '.ico': 'image/x-icon',\n '.woff': 'font/woff',\n '.woff2': 'font/woff2',\n};\n\nfunction appDir(): string {\n return join(dirname(fileURLToPath(import.meta.url)), '..', 'app');\n}\n\nexport interface DevServerOptions {\n root: string;\n port: number;\n}\n\n/**\n * Serves the pre-built dashboard SPA (dist/app) plus the papercamp/ API, for an\n * installed package where there's no Vite runtime available (it's a devDependency).\n */\nexport async function startDevServer({ root, port }: DevServerOptions): Promise<void> {\n const staticDir = appDir();\n const indexPath = join(staticDir, 'index.html');\n const indexHtml = await readFile(indexPath, 'utf-8').catch(() => null);\n if (indexHtml === null) {\n throw new Error(\n `Dashboard assets not found at ${staticDir}. Run \\`pnpm build\\` (or reinstall the package) so dist/app exists.`,\n );\n }\n\n const apiMiddleware = createApiMiddleware(root);\n\n async function serveStatic(req: IncomingMessage, res: ServerResponse) {\n const pathname = decodeURIComponent((req.url ?? '/').split('?')[0]);\n const filePath = join(staticDir, pathname === '/' ? 'index.html' : pathname);\n\n try {\n const fileStat = await stat(filePath);\n if (fileStat.isFile()) {\n res.statusCode = 200;\n res.setHeader('Content-Type', MIME[extname(filePath)] ?? 'application/octet-stream');\n res.end(await readFile(filePath));\n return;\n }\n } catch {\n // not a file on disk — fall through to the SPA fallback below\n }\n\n res.statusCode = 200;\n res.setHeader('Content-Type', 'text/html; charset=utf-8');\n res.end(indexHtml);\n }\n\n const server = createServer((req, res) => {\n apiMiddleware(req, res, () => {\n serveStatic(req, res).catch((error) => {\n res.statusCode = 500;\n res.end(String(error));\n });\n });\n });\n\n const shutdown = () => {\n apiMiddleware.agent.killCurrent();\n process.exit(0);\n };\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n\n await new Promise<void>((resolve) => server.listen(port, resolve));\n}\n","#!/usr/bin/env node\nimport { basename, resolve } from 'node:path';\nimport { Command } from 'commander';\nimport { AlreadyInitializedError, PAPER_CAMP_VERSION, initProject } from '../core/scaffold';\nimport { appendBlock, assignPlanId, formatPlanEntry, todayDateString } from '../core/serializer';\nimport { PLAN_KINDS } from '../types/index';\nimport { startDevServer } from './dev-server';\n\nconst program = new Command();\n\nprogram\n .name('paper-camp')\n .description('Local-first, AI-native project companion.')\n .version(PAPER_CAMP_VERSION);\n\nprogram\n .command('init [project-name]')\n .description('Initialize Paper Camp in the current directory')\n .option('-i, --intent <text>', 'one-line description of what you are building')\n .action(async (projectName: string | undefined, opts: { intent?: string }) => {\n const targetDir = process.cwd();\n const name = projectName ?? basename(targetDir);\n try {\n await initProject(targetDir, { projectName: name, intent: opts.intent });\n console.log(`Initialized Paper Camp in ${targetDir}`);\n console.log(' .paper-camp/config.json');\n console.log(' papercamp/ideas.md, plans.md, progress.md, decisions.md, open-questions.md');\n } catch (error) {\n if (error instanceof AlreadyInitializedError) {\n console.error(error.message);\n process.exitCode = 1;\n return;\n }\n throw error;\n }\n });\n\nprogram\n .command('dev')\n .description('Start the local dashboard')\n .option('-p, --port <number>', 'port to listen on', '3333')\n .action(async (opts: { port: string }) => {\n const port = Number(opts.port);\n const root = process.cwd();\n try {\n await startDevServer({ root, port });\n console.log(`Paper Camp dashboard running at http://localhost:${port}`);\n } catch (error) {\n console.error((error as Error).message);\n process.exitCode = 1;\n }\n });\n\nprogram\n .command('add <type> [name]')\n .description('Add a new entry (currently supports: plan)')\n .option('-k, --kind <kind>', `plan kind (${PLAN_KINDS.join('|')})`, 'feat')\n .action(async (type: string, name: string | undefined, opts: { kind: string }) => {\n if (type !== 'plan') {\n console.error(`Unknown type \"${type}\". Supported types: plan`);\n process.exitCode = 1;\n return;\n }\n if (!name) {\n console.error('Usage: paper-camp add plan <name> [--kind feat|fix|chore|docs|refactor]');\n process.exitCode = 1;\n return;\n }\n if (!PLAN_KINDS.includes(opts.kind as (typeof PLAN_KINDS)[number])) {\n console.error(`Unknown kind \"${opts.kind}\". Supported kinds: ${PLAN_KINDS.join(', ')}`);\n process.exitCode = 1;\n return;\n }\n\n const kind = opts.kind;\n const configPath = resolve(process.cwd(), '.paper-camp', 'config.json');\n const id = await assignPlanId(configPath, kind);\n\n const filePath = resolve(process.cwd(), 'papercamp', 'plans.md');\n const block = formatPlanEntry({\n title: name,\n status: 'idea',\n kind,\n id,\n created: todayDateString(),\n });\n await appendBlock(filePath, block);\n console.log(`Added plan \"${name}\"${id ? ` (${id})` : ''} to papercamp/plans.md`);\n });\n\nprogram.parseAsync(process.argv);\n"],"names":["campFile","root","name","join","readMaybe","path","readFile","takeSnapshot","plansRaw","decisionsRaw","questionsRaw","progressRaw","parsePlans","parseDecisions","parseOpenQuestions","parseProgress","diffAndSynthesize","before","after","events","ts","beforePlans","p","afterPlans","title","afterP","beforeP","i","beforePhase","afterPhase","beforeDecisions","d","afterDecisions","beforeQuestions","q","afterQuestions","beforeProgress","afterProgress","date","createActivityManager","clients","snapshot","timer","files","check","next","event","data","client","file","filePath","watch","s","res","connected","buildArgs","prompt","parseLine","line","json","message","blocks","block","b","content","error","TOOL_LABELS","type","part","text","tool","input","desc","label","detail","reason","DEFAULT_AGENT_ID","AGENTS","claudeCode.buildArgs","claudeCode.parseLine","opencode.buildArgs","opencode.parseLine","TASK_KIND_TO_DEFAULT_KEY","resolveAgent","opts","agentId","defaultAgents","taskKind","key","fallback","MAX_LINES","readDefaultAgentIds","raw","readFileSync","config","DEFAULT_AGENTS","buildAgentPrompt","plan","phase","phaseIndex","createAgentManager","ensureBranch","current","broadcast","pushLine","task","setStatus","status","didTaskProgress","idea","parseIdeas","e","entries","_a","_b","finishTask","progressed","warning","attachReader","createInterface","parsed","code","err","spawnAgent","adapter","args","spawn","isBusy","launch","identity","scope","proc","start","startForPlan","startForIdea","startForIdeaExtend","stop","getStatus","createGitManager","parsePorcelain","output","x","y","rest","runGit","resolve","reject","stdout","stderr","runGitStatus","commit","kind","id","branch","currentResult","spawnSync","result","checkoutResult","refresh","gitDir","eventType","filename","srcDir","srcTimer","getCurrentBranch","getFeatureBranchPlanId","match","CHECK_COMMANDS","createStatusManager","running","queued","setResult","runCheck","cmd","runQualityFix","fileExists","stat","readBody","req","body","chunk","CONFIG_ALLOWLIST","checkBranchConflictForPlan","git","targetPlanId","activePlanId","activePlan","apiRoutes","openQuestionsRaw","decisions","openQuestions","plans","findConsistencyIssues","docNames","configNames","createApiMiddleware","activity","agent","handler","pathname","trimmed","remaining","entry","writeFile","formatPlans","planKind","PLAN_KINDS","configPath","assignPlanId","formatPlanEntry","todayDateString","appendBlock","updates","AGENT_IDS","found","updated","targetEntry","conflict","finalEntry","existing","newId","max","num","section","separator","assetsDir","mimeMap","ext","mime","dataUri","buffer","mkdir","planId","ideaId","port","projectName","defaultAgent","resolvedDefaultAgents","configWithOld","_oldAgent","configRest","envPath","examplePath","exists","exampleExists","parseEnv","exampleKeys","envKeys","missingKeys","keys","applyEnvEntries","route","r","MIME","appDir","dirname","fileURLToPath","startDevServer","staticDir","indexPath","indexHtml","apiMiddleware","serveStatic","extname","server","createServer","shutdown","program","Command","PAPER_CAMP_VERSION","targetDir","basename","initProject","AlreadyInitializedError"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../src/app/features/plans/prompts.ts","../../src/app/server/agents/claude-code.ts","../../src/app/server/agents/opencode.ts","../../src/app/server/agents/index.ts","../../src/core/idea-status.ts","../../src/app/features/plans/helpers.ts","../../src/app/server/activity.ts","../../src/app/server/agent.ts","../../src/app/server/commit-suggest.ts","../../src/app/server/git.ts","../../src/app/server/status.ts","../../src/app/server/api.ts","../../src/cli/dev-server.ts","../../src/cli/index.ts"],"sourcesContent":["import type { IdeaEntry, PlanEntry } from '@/types/index';\n\nexport function buildConvergenceAuditPrompt(plan: PlanEntry): string {\n const phaseList = plan.phases\n .map((phase, i) => `${i + 1}. [${phase.done ? 'x' : ' '}] ${phase.text}`)\n .join('\\n');\n\n const logList =\n plan.log && plan.log.length > 0\n ? plan.log.map((entry) => `- ${entry.date}: ${entry.text}`).join('\\n')\n : '(none)';\n\n const clarificationsList =\n plan.clarifications && plan.clarifications.length > 0\n ? plan.clarifications.map((entry) => `- ${entry.date}: ${entry.text}`).join('\\n')\n : '(none)';\n\n return `You're auditing the plan \"${plan.title}\" (${plan.id ?? 'no id'}), stored as a single file at papercamp/plans/${plan.id ?? '<ID>'}.md (or papercamp/plans/archive/${plan.id ?? '<ID>'}.md if it's already done/dropped — check both). Edit only that file.\n\nPlan body: ${plan.body}\n\nCurrent phases:\n${phaseList}\n\nLog entries (issues, bugs, and review notes documented so far):\n${logList}\n\nClarifications (answered questions about scope and design):\n${clarificationsList}\n\nRead this plan's phases, body, Log entries, and Clarifications, then inspect the current repo state. The Log entries often document bugs, UX issues, or missing functionality that should be turned into new phases. Append any phase that's clearly required but missing as a normal \\`- [ ]\\` line at the end of the \\`### Phases\\` list — optionally with the existing indented description format. Explicitly never touch existing lines: never reorder, check, uncheck, or rewrite anything already there, no matter how stale or redundant it looks.\n\nIf you append anything, finish with exactly one new \\`### Log\\` line (date: summary) describing what was found and appended.\n\nIf nothing is missing, write nothing at all — not even an empty heading or a Log line. The audit must be safe to re-run anytime without producing log spam.`;\n}\n\nexport function buildIdeaExtendPrompt(idea: IdeaEntry): string {\n return `You're extending an idea stored as a single file at papercamp/ideas/${idea.id ?? '<ID>'}.md: ${idea.id ?? 'no id'} (\"${idea.title}\").\n\nIdea body, in full:\n${idea.body}\n\nYour job: explore the current codebase and rewrite this idea's body in place in that file with more specific detail — concrete approaches, file references, and any relevant architectural context you find in the code. Leave the YAML frontmatter (id, title) and the idea's \\`### ${idea.id ?? 'IDEA-N'}: ${idea.title}\\` heading unchanged; only update the prose body below the heading.\n\nWrite the full updated body — everything below the heading. Make the description more specific and actionable while keeping the same general intent. Do not change the \\`## IDEA-N:\\` heading line.`;\n}\n\nexport function buildClarifyPrompt(plan: PlanEntry): string {\n return `You're clarifying the plan \"${plan.title}\" (${plan.id ?? 'no id'}), stored as a single file at papercamp/plans/${plan.id ?? '<ID>'}.md (or papercamp/plans/archive/${plan.id ?? '<ID>'}.md if done/dropped). Edit only that file.\n\nPlan body: ${plan.body}\n\nCurrent phases:\n${plan.phases.length > 0 ? plan.phases.map((p, i) => `${i + 1}. [${p.done ? 'x' : ' '}] ${p.text}`).join('\\n') : '(none yet)'}\n\nScan this plan against: functional scope, data model, UX flow, non-functional attributes, edge cases, terminology, completion signals.\n\nSurface at most 5 highest-impact gaps, one question at a time, each with a **Recommended:** answer. Write accepted answers to \\`### Clarifications\\` as:\n\n\\`\\`\\`\n- YYYY-MM-DD: Q: <question> → A: <answer>\n\\`\\`\\`\n\nOnly append answered lines. Keep existing clarifications intact. Use today's date.`;\n}\n\nexport function buildPlanDraftPrompt(idea: IdeaEntry, otherPlans: PlanEntry[]): string {\n const openPlans = otherPlans.filter((p) => p.status !== 'done');\n const plansContext = openPlans.length\n ? openPlans\n .map((p) => {\n const phaseList = p.phases\n .map((ph) => ` - [${ph.done ? 'x' : ' '}] ${ph.text}`)\n .join('\\n');\n return `### ${p.id ?? 'no id'}: ${p.title} (status: ${p.status}${p.idea ? `, idea: ${p.idea}` : ''})\n${p.body}\n${phaseList || ' (no phases yet)'}`;\n })\n .join('\\n\\n')\n : '(no other open plans exist yet)';\n\n return `You're drafting a new plan from an idea: ${idea.id ?? 'no id'} (\"${idea.title}\"), stored at papercamp/ideas/${idea.id ?? '<ID>'}.md.\n\nIdea body, in full:\n${idea.body}\n\n## Plan file shape (see papercamp/about.md)\n\nEach plan is its own file at \\`papercamp/plans/<KIND>-<N>.md\\` (the file name is the plan's id). It has YAML frontmatter, a free-prose body paragraph, then an optional \\`### Phases\\` checklist:\n\n\\`\\`\\`\n---\nid: <KIND>-<N>\ntitle: <Short headline>\nkind: feat | fix | chore | docs | refactor\nstatus: idea\ncreated: <today, YYYY-MM-DD>\nidea: ${idea.id ?? 'IDEA-N'}\ntags:\n - comma\n - separated\n---\n\nOne or two paragraphs of free prose giving context — what this is and why,\nin the same voice as the existing plan files.\n\n### Phases\n- [ ] Short phase title\n Optional indented long-form description of the phase.\n\\`\\`\\`\n\n- \\`title\\` is a short verb-led headline, 2-6 words.\n- \\`kind\\` picks the ID prefix — choose whichever Conventional Commits type\n best fits this idea (most are \\`feat\\`).\n- \\`id\\` must come from the persistent per-kind counter in\n \\`papercamp/config.json\\`'s \\`nextId\\` field — read the current value for\n your chosen \\`kind\\` (e.g. \\`nextId.feat\\`), use it as \\`<KIND>-<N>\\`, and\n increment that counter in the same write. Never derive the number by\n scanning existing plan files for the highest one — a deleted plan's number\n must never be reused.\n- \\`idea\\` must be exactly \\`${idea.id ?? \"this idea's id\"}\\` — that backlink is\n what the rest of the dashboard (and this task's own success check) uses to\n find the plan you wrote.\n- Write \\`status: idea\\`, never anything further along. Per\n papercamp/decisions.md (\"Plan-drafting agent writes directly, same as\n phase execution\"), this entry lands straight in the Backlog with no\n separate approval step — a human reviews and promotes it from there, the\n same as any other backlog entry.\n- Phases should be genuinely actionable steps a future agent or human could\n pick up one at a time — match the granularity of the existing phases shown\n below, not a single giant phase.\n\n## Every other open (non-done) plan, for scope context\n\n${plansContext}\n\n## What to write\n\nCreate exactly one new file, \\`papercamp/plans/<KIND>-<N>.md\\`, using the id\nyou allocated above. Use the list of existing plans only to avoid\nduplicating an in-flight plan's scope and to match phase granularity —\nnever create, edit, move, or rename any other plan file, and never write to\nthe legacy \\`papercamp/plans.md\\` (it is unused under per-file storage).`;\n}\n","import type { AgentRunOptions } from '../../../types/index';\n\nexport interface ParsedAgentLine {\n text: string;\n done?: boolean;\n error?: boolean;\n}\n\nexport function buildArgs(prompt: string, opts?: AgentRunOptions): string[] {\n const args = [\n '-p',\n prompt,\n '--output-format',\n 'stream-json',\n '--verbose',\n '--permission-mode',\n 'auto',\n ];\n if (opts?.model) args.push('--model', opts.model);\n if (opts?.effort) args.push('--effort', opts.effort);\n return args;\n}\n\n/**\n * Shape confirmed by a live `claude -p ... --output-format stream-json` smoke test\n * (see decisions.md, \"Confirm Claude Code's headless stream-json shape...\"), not guessed\n * from --help. Unknown subtypes fall through to a generic status line rather than being\n * dropped or throwing, since new bookkeeping subtypes (e.g. thinking_tokens) can appear.\n */\nexport function parseLine(line: string): ParsedAgentLine | null {\n let json: Record<string, unknown>;\n try {\n json = JSON.parse(line);\n } catch {\n return null;\n }\n\n switch (json.type) {\n case 'system': {\n if (json.subtype === 'init') {\n return { text: 'Agent session started' };\n }\n if (json.subtype === 'post_turn_summary' && typeof json.status_detail === 'string') {\n return { text: json.status_detail };\n }\n return null;\n }\n case 'rate_limit_event':\n return null;\n case 'assistant': {\n const message = json.message as { content?: unknown[] } | undefined;\n const blocks = message?.content ?? [];\n for (const block of blocks) {\n const b = block as { type?: string; name?: string; text?: string };\n if (b.type === 'tool_use') {\n return { text: `Running ${b.name ?? 'a tool'}…` };\n }\n if (b.type === 'text' && typeof b.text === 'string' && b.text.trim()) {\n return { text: b.text.trim() };\n }\n }\n return null;\n }\n case 'user': {\n const message = json.message as { content?: unknown[] } | undefined;\n const content = message?.content;\n const block = Array.isArray(content) ? (content[0] as Record<string, unknown>) : undefined;\n if (block?.is_error) {\n const text = typeof block.content === 'string' ? block.content : 'Tool call failed';\n return { text: `Error: ${text}`, error: true };\n }\n return { text: 'Tool finished' };\n }\n case 'result': {\n const error = Boolean(json.is_error);\n const result = typeof json.result === 'string' ? json.result.trim() : '';\n const text = result || (error ? 'Agent run failed' : 'Agent run finished');\n return { text, done: true, error };\n }\n default:\n return { text: 'Agent is working…' };\n }\n}\n","import type { AgentRunOptions } from '../../../types/index';\nimport type { ParsedAgentLine } from './claude-code';\n\nexport function buildArgs(prompt: string, opts?: AgentRunOptions): string[] {\n const args = ['run', prompt, '--format', 'json'];\n if (opts?.model) args.push('-m', opts.model);\n if (opts?.effort) args.push('--variant', opts.effort);\n return args;\n}\n\nconst TOOL_LABELS: Record<string, string> = {\n bash: 'Running command',\n read: 'Reading file',\n edit: 'Editing file',\n write: 'Writing file',\n glob: 'Searching files',\n grep: 'Searching code',\n websearch: 'Searching web',\n webfetch: 'Fetching URL',\n question: 'Asking for input',\n};\n\nexport function parseLine(line: string): ParsedAgentLine | null {\n let json: Record<string, unknown>;\n try {\n json = JSON.parse(line);\n } catch {\n return null;\n }\n\n const type = json.type as string | undefined;\n const part = json.part as Record<string, unknown> | undefined;\n\n if (!type || !part) return null;\n\n switch (type) {\n case 'step_start':\n return null;\n case 'text': {\n const text = part.text as string | undefined;\n if (text?.trim()) return { text: text.trim() };\n return null;\n }\n case 'tool_use': {\n const tool = part.tool as string | undefined;\n const input = part.state ? (part.state as Record<string, unknown>).input : undefined;\n const desc = input ? (input as Record<string, unknown>).description : undefined;\n const label = tool ? TOOL_LABELS[tool] : 'Running tool';\n const detail = typeof desc === 'string' && desc.trim() ? `: ${desc.trim()}` : '';\n return tool ? { text: `${label}${detail}…` } : null;\n }\n case 'step_finish': {\n const reason = part.reason as string | undefined;\n const text = reason === 'tool-calls' ? null : reason === 'stop' ? 'Done' : 'Step finished';\n if (!text) return null;\n return { text };\n }\n default:\n return null;\n }\n}\n","import { AGENT_OPTIONS } from '../../../types/index';\nimport type {\n AgentId,\n AgentOptionsDescriptor,\n AgentRunOptions,\n DefaultAgentsMap,\n TaskKind,\n} from '../../../types/index';\nimport * as claudeCode from './claude-code';\nimport type { ParsedAgentLine } from './claude-code';\nimport * as opencode from './opencode';\n\nexport interface AgentAdapter {\n command: string;\n buildArgs: (prompt: string, opts?: AgentRunOptions) => string[];\n parseLine: (line: string) => ParsedAgentLine | null;\n options: AgentOptionsDescriptor;\n}\n\nexport const DEFAULT_AGENT_ID: AgentId = 'claude-code';\n\nexport const AGENTS: Record<AgentId, AgentAdapter> = {\n 'claude-code': {\n command: 'claude',\n buildArgs: claudeCode.buildArgs,\n parseLine: claudeCode.parseLine,\n options: AGENT_OPTIONS['claude-code'],\n },\n opencode: {\n command: 'opencode',\n buildArgs: opencode.buildArgs,\n parseLine: opencode.parseLine,\n options: AGENT_OPTIONS.opencode,\n },\n};\n\nconst TASK_KIND_TO_DEFAULT_KEY: Record<TaskKind, keyof DefaultAgentsMap> = {\n phase: 'phase',\n audit: 'phase',\n 'batch-audit': 'phase',\n draft: 'planDraft',\n extend: 'ideaExtend',\n 'commit-suggest': 'commitSuggest',\n};\n\nexport function resolveAgent(opts: {\n agentId?: AgentId;\n defaultAgents?: DefaultAgentsMap;\n taskKind?: TaskKind;\n}): { id: AgentId; adapter: AgentAdapter } & AgentRunOptions {\n const { agentId, defaultAgents, taskKind } = opts;\n if (agentId && agentId in AGENTS) return { id: agentId, adapter: AGENTS[agentId] };\n if (taskKind && defaultAgents) {\n const key = TASK_KIND_TO_DEFAULT_KEY[taskKind];\n const fallback = defaultAgents[key];\n if (fallback) {\n const id = fallback.agent;\n if (id in AGENTS) {\n return { id, adapter: AGENTS[id], model: fallback.model, effort: fallback.effort };\n }\n }\n }\n return { id: DEFAULT_AGENT_ID, adapter: AGENTS[DEFAULT_AGENT_ID] };\n}\n","import type { IdeaEntry, PlanEntry } from '../types/index';\n\n/**\n * Pure, no I/O — kept out of parser.ts so client-bundled importers (e.g.\n * app-store.ts) don't pull in parser.ts's Node-only file-reading code.\n */\nexport function deriveIdeaStatuses(ideas: IdeaEntry[], plans: PlanEntry[]): IdeaEntry[] {\n return ideas.map((idea) => {\n if (!idea.id) {\n return { ...idea, status: 'planned' };\n }\n const linkedPlans = plans.filter((p) => p.idea === idea.id);\n if (linkedPlans.length === 0) {\n return { ...idea, status: 'planned' };\n }\n const allDone = linkedPlans.every((p) => p.status === 'done' || p.status === 'dropped');\n return { ...idea, status: allDone ? 'done' : 'planned' };\n });\n}\n","import type { PlanEntry } from '@/types/index';\n\nexport const relativeDate = (dateStr: string): string => {\n const date = new Date(dateStr);\n if (Number.isNaN(date.getTime())) return dateStr;\n const days = Math.floor((Date.now() - date.getTime()) / 86400000);\n if (days === 0) return 'today';\n if (days === 1) return 'yesterday';\n if (days < 7) return `${days}d ago`;\n if (days < 30) return `${Math.floor(days / 7)}w ago`;\n if (days < 365) return `${Math.floor(days / 30)}mo ago`;\n return `${Math.floor(days / 365)}y ago`;\n};\n\nexport const phaseProgress = (plan: PlanEntry) => {\n if (plan.phases.length === 0) return null;\n const done = plan.phases.filter((p) => p.done).length;\n return { done, total: plan.phases.length, pct: Math.round((done / plan.phases.length) * 100) };\n};\n\nexport const phasePercentage = (plan: PlanEntry): number | null => {\n if (plan.phases.length === 0) return null;\n return Math.round((plan.phases.filter((p) => p.done).length / plan.phases.length) * 100);\n};\n\nexport const findFocusPlan = (\n plans: PlanEntry[] | undefined,\n activePlanTitle?: string | null,\n): PlanEntry | undefined => {\n if (!plans) return undefined;\n if (activePlanTitle) {\n const selected = plans.find((p) => p.title === activePlanTitle);\n if (selected) return selected;\n }\n return plans.find((p) => p.status === 'in-progress' || p.status === 'review');\n};\n","import { watch } from 'node:fs';\nimport type { ServerResponse } from 'node:http';\nimport { join } from 'node:path';\n\n/**\n * Live-refresh notifier over SSE. Watches the whole papercamp/ directory and\n * pushes a tick whenever anything under it changes, so connected dashboards\n * refetch.\n *\n * It deliberately does NOT synthesize a human-readable activity feed: the only\n * consumer (stack-panel.tsx) ignores the event payload and treats every tick as\n * a generic \"something changed, reload everything\" signal. Watching the\n * directory recursively covers the per-file `plans/` and `ideas/` trees (incl.\n * `plans/archive/`) as well as the monolithic `decisions.md`,\n * `open-questions.md`, and `progress.md` — replacing the old hardcoded list that\n * still pointed at the removed legacy `plans.md`.\n */\nexport function createActivityManager(root: string) {\n const clients = new Set<ServerResponse>();\n let timer: ReturnType<typeof setTimeout> | null = null;\n\n function broadcast() {\n const data = `data: ${JSON.stringify({\n message: 'changed',\n timestamp: new Date().toISOString(),\n })}\\n\\n`;\n for (const client of clients) {\n try {\n client.write(data);\n } catch {\n clients.delete(client);\n }\n }\n }\n\n try {\n // Debounced so a burst of writes (e.g. a plan file plus its regenerated\n // index.md) collapses into a single refresh tick.\n watch(join(root, 'papercamp'), { recursive: true }, () => {\n if (timer) clearTimeout(timer);\n timer = setTimeout(broadcast, 300);\n });\n } catch {\n // papercamp/ doesn't exist yet (uninitialized project) — nothing to watch.\n }\n\n return {\n subscribe(res: ServerResponse) {\n clients.add(res);\n const connected = JSON.stringify({\n message: 'Watching for changes…',\n timestamp: new Date().toISOString(),\n });\n res.write(`data: ${connected}\\n\\n`);\n res.on('close', () => clients.delete(res));\n },\n };\n}\n","import { type ChildProcess, spawn } from 'node:child_process';\nimport { readFileSync } from 'node:fs';\nimport { readFile, stat } from 'node:fs/promises';\nimport type { ServerResponse } from 'node:http';\nimport { join } from 'node:path';\nimport { createInterface } from 'node:readline';\nimport {\n parsePlanFile,\n readAllPlanFiles,\n readIdeasMerged,\n readPlansMerged,\n} from '../../core/parser';\nimport {\n type AgentId,\n type AgentTaskState,\n type AgentTaskStatus,\n DEFAULT_AGENTS,\n type DefaultAgentsMap,\n type IdeaEntry,\n type PaperCampConfig,\n type PhaseItem,\n type PlanEntry,\n type TaskKind,\n coerceAgentConfig,\n} from '../../types/index';\nimport { buildConvergenceAuditPrompt } from '../features/plans/prompts';\nimport { AGENTS, type AgentAdapter, resolveAgent } from './agents';\n\nconst MAX_LINES = 50;\n\ninterface AgentTask {\n taskKind: TaskKind;\n planTitle: string;\n planId?: string;\n // Absent for a plan-scoped task (e.g. a convergence audit spanning every phase),\n // present for a single-phase task.\n phaseIndex?: number;\n // Only set for plan-scoped tasks, to check success against: did Phases or Log grow?\n planBaseline?: { phases: number; log: number };\n // Only set for an idea-drafting task, which has neither planId nor phaseIndex since\n // the plan doesn't exist yet — success is checked by idea id instead.\n ideaId?: string;\n // For idea-extend tasks: snapshot the idea's body before launch so we can detect changes.\n ideaBodyBaseline?: string;\n status: AgentTaskStatus;\n agentId: AgentId;\n adapter: AgentAdapter;\n proc: ChildProcess;\n lines: string[];\n}\n\nfunction readDefaultAgentIds(root: string): DefaultAgentsMap {\n try {\n const raw = readFileSync(join(root, 'papercamp', 'config.json'), 'utf-8');\n const config = JSON.parse(raw) as Record<string, unknown> & { defaultAgent?: AgentId };\n const rawAgents = config.defaultAgents as Record<string, unknown> | undefined;\n if (rawAgents) {\n return {\n phase: coerceAgentConfig(rawAgents.phase),\n planDraft: coerceAgentConfig(rawAgents.planDraft),\n ideaExtend: coerceAgentConfig(rawAgents.ideaExtend),\n commitSuggest: coerceAgentConfig(rawAgents.commitSuggest),\n };\n }\n if (config.defaultAgent) {\n const id = config.defaultAgent;\n return {\n phase: { agent: id },\n planDraft: { agent: id },\n ideaExtend: { agent: id },\n commitSuggest: { agent: id },\n };\n }\n return DEFAULT_AGENTS;\n } catch {\n return DEFAULT_AGENTS;\n }\n}\n\ntype Result = { ok: true } | { ok: false; error: string };\n\nexport function buildAgentPrompt(plan: PlanEntry, phase: PhaseItem, phaseIndex: number): string {\n return `You're working on phase ${phaseIndex + 1} (\"${phase.text}\") of the plan \"${plan.title}\" (${plan.id ?? 'no id'}), stored as a single file at papercamp/plans/${plan.id ?? '<ID>'}.md.\n\n${phase.description ?? ''}\n\nPlan context: ${plan.body}\n\nDo only this phase. When done, check it off in that file's \\`### Phases\\` list (- [ ] -> - [x]) and append what you did to progress.md. If this was the last unchecked phase, set the plan's \\`status:\\` frontmatter field to \\`review\\`, not \\`done\\`, per this repo's AGENTS.md.`;\n}\n\nexport function createAgentManager(\n root: string,\n ensureBranch: (plan: PlanEntry) => void = () => {},\n onAuditComplete?: (planId: string, gapPhases: number) => Promise<void>,\n) {\n const clients = new Set<ServerResponse>();\n let current: AgentTask | null = null;\n\n function broadcast(message: string) {\n const data = `data: ${JSON.stringify({ message, timestamp: new Date().toISOString(), type: 'agent' })}\\n\\n`;\n for (const client of clients) {\n try {\n client.write(data);\n } catch {\n clients.delete(client);\n }\n }\n }\n\n function pushLine(task: AgentTask, text: string) {\n task.lines.push(text);\n if (task.lines.length > MAX_LINES) task.lines.shift();\n broadcast(text);\n }\n\n function setStatus(task: AgentTask, status: AgentTaskStatus) {\n task.status = status;\n broadcast(`agent: ${status}`);\n }\n\n async function didTaskProgress(task: AgentTask): Promise<boolean | null> {\n try {\n if (task.taskKind === 'extend') {\n const ideasDir = join(root, 'papercamp', 'ideas');\n const { entries } = await readIdeasMerged(ideasDir, join(root, 'papercamp', 'ideas.md'));\n const idea = entries.find((e) => e.id === task.ideaId);\n if (!idea) return null;\n if (task.ideaBodyBaseline === undefined) return null;\n return idea.body !== task.ideaBodyBaseline;\n }\n const plansDir = join(root, 'papercamp', 'plans');\n const { entries } = await readPlansMerged(plansDir, join(root, 'papercamp', 'plans.md'));\n if (task.ideaId !== undefined) {\n return entries.some((p: { idea?: string }) => p.idea === task.ideaId);\n }\n const plan =\n entries.find((p: { id?: string }) => p.id === task.planId) ??\n entries.find((p: { title: string }) => p.title === task.planTitle);\n if (!plan) return null;\n if (task.phaseIndex !== undefined) {\n return plan.phases[task.phaseIndex]?.done ?? null;\n }\n if (!task.planBaseline) return null;\n return (\n plan.phases.length > task.planBaseline.phases ||\n (plan.log?.length ?? 0) > task.planBaseline.log\n );\n } catch {\n return null;\n }\n }\n\n function finishTask(task: AgentTask, error: boolean) {\n setStatus(task, error ? 'error' : 'done');\n if (error) return;\n didTaskProgress(task).then((progressed) => {\n if (current === task && progressed === false) {\n const warning =\n task.taskKind === 'extend'\n ? `Warning: agent finished but the idea body for ${task.ideaId} did not change — verify manually`\n : task.ideaId !== undefined\n ? `Warning: agent finished but no plan linking idea: ${task.ideaId} appeared in papercamp/plans/ — verify manually`\n : task.phaseIndex !== undefined\n ? 'Warning: agent finished but did not check off this phase in the plan file — verify manually'\n : 'Warning: agent finished but appended nothing to Phases or Log — verify manually';\n pushLine(task, warning);\n }\n if (current === task && task.taskKind === 'audit' && task.planId && progressed === true) {\n onAuditComplete?.(task.planId, 0).catch(() => {});\n }\n });\n }\n\n function attachReader(task: AgentTask) {\n if (!task.proc.stdout) return;\n const rl = createInterface({ input: task.proc.stdout });\n rl.on('line', (line) => {\n if (current !== task || !line.trim()) return;\n const parsed = task.adapter.parseLine(line);\n if (!parsed) return;\n pushLine(task, parsed.text);\n if (parsed.done) {\n finishTask(task, Boolean(parsed.error));\n }\n });\n\n task.proc.on('close', (code) => {\n if (current !== task) return;\n if (task.status === 'starting' || task.status === 'running') {\n finishTask(task, code !== 0);\n } else if (task.status === 'stopping') {\n setStatus(task, 'done');\n }\n });\n\n task.proc.on('error', (err) => {\n if (current !== task) return;\n pushLine(task, `Failed to spawn agent: ${err.message}`);\n setStatus(task, 'error');\n });\n }\n\n function spawnAgent(adapter: AgentAdapter, args: string[]): ChildProcess {\n return spawn(adapter.command, args, {\n cwd: root,\n stdio: ['ignore', 'pipe', 'pipe'],\n });\n }\n\n function isBusy(): boolean {\n return current !== null && current.status !== 'done' && current.status !== 'error';\n }\n\n // Shared by start()/startForPlan()/startForIdea(): synchronous on purpose, same\n // race-avoidance reasoning as the busy-guard above — no `await` between the guard\n // check and reserving `current`.\n function launch(\n identity: { planTitle: string; planId?: string; agentOverride?: AgentId },\n prompt: string,\n scope: Pick<\n AgentTask,\n 'taskKind' | 'phaseIndex' | 'planBaseline' | 'ideaId' | 'ideaBodyBaseline'\n >,\n ): Result {\n if (isBusy()) {\n return { ok: false, error: 'An agent task is already running' };\n }\n const defaultAgents = readDefaultAgentIds(root);\n const {\n id: agentId,\n adapter,\n model,\n effort,\n } = resolveAgent({\n agentId: identity.agentOverride,\n defaultAgents,\n taskKind: scope.taskKind,\n });\n const proc = spawnAgent(adapter, adapter.buildArgs(prompt, { model, effort }));\n const task: AgentTask = {\n planTitle: identity.planTitle,\n planId: identity.planId,\n status: 'starting',\n agentId,\n adapter,\n proc,\n lines: [],\n ...scope,\n };\n current = task;\n attachReader(task);\n setStatus(task, 'running');\n return { ok: true };\n }\n\n function start(plan: PlanEntry, phaseIndex: number): Result {\n if (isBusy()) {\n return { ok: false, error: 'An agent task is already running' };\n }\n const phase = plan.phases[phaseIndex];\n if (!phase) {\n return { ok: false, error: 'Phase not found' };\n }\n ensureBranch(plan);\n const prompt = buildAgentPrompt(plan, phase, phaseIndex);\n return launch({ planTitle: plan.title, planId: plan.id, agentOverride: plan.agent }, prompt, {\n taskKind: 'phase',\n phaseIndex,\n });\n }\n\n // Plan-scoped launch mode: no single phase, so success is judged by whether the\n // agent appended anything to Phases or Log rather than whether one checkbox flipped.\n function startForPlan(plan: PlanEntry, prompt: string): Result {\n return launch({ planTitle: plan.title, planId: plan.id, agentOverride: plan.agent }, prompt, {\n taskKind: 'audit',\n planBaseline: { phases: plan.phases.length, log: plan.log?.length ?? 0 },\n });\n }\n\n // Idea-drafting launch mode: there's no plan yet (and so no per-plan agent override\n // either) — the plan only exists once the agent writes it, so success is judged by\n // whether a new plan file linking this idea's id shows up in papercamp/plans/.\n function startForIdea(idea: IdeaEntry, prompt: string): Result {\n if (!idea.id) {\n return { ok: false, error: 'Idea has no id to link a drafted plan back to' };\n }\n return launch({ planTitle: `Draft plan for ${idea.id}` }, prompt, {\n taskKind: 'draft',\n ideaId: idea.id,\n });\n }\n\n // Idea-extend launch mode: given an idea, explores the codebase and rewrites its\n // body in place in its papercamp/ideas/ file. Success is judged by whether that idea's body text\n // actually changed.\n function startForIdeaExtend(idea: IdeaEntry, prompt: string): Result {\n if (!idea.id) {\n return { ok: false, error: 'Idea has no id to extend' };\n }\n return launch({ planTitle: `Extend ${idea.id}` }, prompt, {\n taskKind: 'extend',\n ideaId: idea.id,\n ideaBodyBaseline: idea.body,\n });\n }\n\n async function findBatchPlanFile(plansDir: string, id: string): Promise<string | null> {\n const direct = join(plansDir, `${id}.md`);\n try {\n await stat(direct);\n return direct;\n } catch {}\n const archived = join(plansDir, 'archive', `${id}.md`);\n try {\n await stat(archived);\n return archived;\n } catch {}\n return null;\n }\n\n // Batch audit: iterate every review/done plan and run a convergence audit on each,\n // skipping plans whose \"audited\" marker is newer than the file's last modification.\n // Runs plans sequentially; updates task.proc before each spawn so stop() kills the\n // right subprocess.\n function startBatchAudit(): Result {\n if (isBusy()) {\n return { ok: false, error: 'An agent task is already running' };\n }\n const defaultAgents = readDefaultAgentIds(root);\n const {\n id: agentId,\n adapter,\n model,\n effort,\n } = resolveAgent({ defaultAgents, taskKind: 'audit' });\n\n // Stub proc — replaced per plan in the loop. Already-exited is fine: stop() sets\n // task.status = 'stopping' first; kill() on a dead process is a no-op.\n const stubProc = spawn('sh', ['-c', 'exit 0'], {\n cwd: root,\n stdio: 'ignore',\n });\n const task: AgentTask = {\n taskKind: 'batch-audit',\n planTitle: 'Batch audit',\n status: 'starting',\n agentId,\n adapter,\n proc: stubProc,\n lines: [],\n };\n current = task;\n setStatus(task, 'running');\n\n (async () => {\n try {\n const plansDir = join(root, 'papercamp', 'plans');\n const { entries } = await readAllPlanFiles(plansDir);\n const candidates = entries.filter((p) => p.status === 'review' || p.status === 'done');\n\n if (candidates.length === 0) {\n if (current === task) {\n pushLine(task, 'No plans with status \"review\" or \"done\" to audit.');\n setStatus(task, 'done');\n }\n return;\n }\n\n pushLine(task, `Auditing ${candidates.length} plan(s)…`);\n let audited = 0;\n let skipped = 0;\n let failed = 0;\n\n for (const plan of candidates) {\n if (current !== task || task.status === 'stopping') break;\n if (!plan.id) {\n skipped++;\n continue;\n }\n\n const planFile = await findBatchPlanFile(plansDir, plan.id);\n if (!planFile) {\n skipped++;\n continue;\n }\n\n if (plan.audited) {\n const fileStat = await stat(planFile).catch(() => null);\n const mtimeDate = fileStat ? fileStat.mtime.toISOString().slice(0, 10) : null;\n if (mtimeDate && plan.audited >= mtimeDate) {\n pushLine(task, `[skip] ${plan.id} — up to date`);\n skipped++;\n continue;\n }\n }\n\n pushLine(task, `[audit] ${plan.id} ${plan.title}`);\n const prompt = buildConvergenceAuditPrompt(plan);\n const proc = spawn(adapter.command, adapter.buildArgs(prompt, { model, effort }), {\n cwd: root,\n stdio: ['ignore', 'pipe', 'pipe'],\n });\n task.proc = proc;\n\n if (proc.stdout) {\n const rl = createInterface({ input: proc.stdout });\n rl.on('line', (line) => {\n if (current !== task) return;\n const parsed = adapter.parseLine(line);\n if (parsed?.text && parsed.text !== 'Agent is working…') {\n pushLine(task, ` ${parsed.text}`);\n }\n });\n }\n // Drain stderr — an unread pipe can fill and hang the subprocess.\n proc.stderr?.on('data', () => {});\n\n const success = await new Promise<boolean>((resolve) => {\n proc.on('close', (code) => resolve(code === 0));\n proc.on('error', () => resolve(false));\n });\n\n if (current !== task) return;\n\n if (success) {\n let gapPhases = 0;\n try {\n const rawAfter = await readFile(planFile, 'utf-8');\n const parsedAfter = parsePlanFile(rawAfter);\n const afterCount = parsedAfter.entries[0]?.phases.length ?? plan.phases.length;\n gapPhases = Math.max(0, afterCount - plan.phases.length);\n } catch {\n /* gapPhases stays 0 */\n }\n await onAuditComplete?.(plan.id, gapPhases);\n audited++;\n pushLine(\n task,\n gapPhases > 0\n ? `[done] ${plan.id} — ${gapPhases} gap phase${gapPhases === 1 ? '' : 's'} added`\n : `[done] ${plan.id}`,\n );\n } else {\n failed++;\n pushLine(task, `[fail] ${plan.id} — agent error`);\n }\n }\n\n if (current !== task) return;\n\n if (task.status === 'stopping') {\n setStatus(task, 'done');\n return;\n }\n\n pushLine(task, `Audit complete — ${audited} audited, ${skipped} skipped, ${failed} failed`);\n setStatus(task, failed > 0 ? 'error' : 'done');\n } catch (err) {\n if (current === task) {\n pushLine(task, `Batch audit failed: ${(err as Error).message}`);\n setStatus(task, 'error');\n }\n }\n })();\n\n return { ok: true };\n }\n\n // Read-only, one-shot task: ask the configured agent to turn a diff into a commit\n // message. Uses the configured agent's binary but constructs its own arguments so it\n // never picks up the shared adapter's `--permission-mode auto` flag — this call must\n // stay deny-by-default since the model is only ever supposed to read the diff text.\n const COMMIT_SUGGEST_TIMEOUT_MS = 60_000;\n const STDIN_MAX_BYTES = 10 * 1024 * 1024;\n\n function runCommitSuggest(prompt: string): Promise<string> {\n if (isBusy()) {\n return Promise.reject(new Error('An agent task is already running'));\n }\n if (Buffer.byteLength(prompt, 'utf-8') > STDIN_MAX_BYTES) {\n return Promise.reject(new Error('Commit suggestion prompt exceeds the 10MB stdin limit'));\n }\n const defaultAgents = readDefaultAgentIds(root);\n const {\n id: agentId,\n adapter,\n model,\n effort,\n } = resolveAgent({\n defaultAgents,\n taskKind: 'commit-suggest',\n });\n\n const isClaude = agentId === 'claude-code';\n const args = isClaude ? ['-p', '--output-format', 'json'] : ['run', '--format', 'json'];\n if (model) args.push(isClaude ? '--model' : '-m', model);\n if (effort) args.push(isClaude ? '--effort' : '--variant', effort);\n\n return new Promise((resolve, reject) => {\n const proc = spawn(adapter.command, args, {\n cwd: root,\n stdio: ['pipe', 'pipe', 'pipe'],\n });\n const task: AgentTask = {\n taskKind: 'commit-suggest',\n planTitle: 'Suggest commit message',\n status: 'starting',\n agentId,\n adapter,\n proc,\n lines: [],\n };\n current = task;\n setStatus(task, 'running');\n\n let settled = false;\n const settle = (fn: () => void) => {\n if (settled) return;\n settled = true;\n clearTimeout(timeout);\n fn();\n };\n const timeout = setTimeout(() => {\n settle(() => {\n if (current === task) {\n pushLine(task, 'Commit suggestion timed out');\n setStatus(task, 'error');\n if (!proc.killed) proc.kill('SIGTERM');\n }\n reject(new Error('Commit suggestion timed out'));\n });\n }, COMMIT_SUGGEST_TIMEOUT_MS);\n\n proc.stdin?.on('error', () => {});\n proc.stdin?.write(prompt);\n proc.stdin?.end();\n\n let stdout = '';\n let stderr = '';\n proc.stdout?.on('data', (d: Buffer) => {\n stdout += d.toString();\n });\n proc.stderr?.on('data', (d: Buffer) => {\n stderr += d.toString();\n });\n proc.on('close', (code) => {\n if (current !== task) return;\n settle(() => {\n if (task.status === 'stopping') {\n setStatus(task, 'done');\n reject(new Error('Stopped'));\n return;\n }\n if (code === 0) {\n setStatus(task, 'done');\n // opencode outputs JSON events — extract text content to find the response.\n const result = isClaude\n ? stdout\n : stdout\n .split('\\n')\n .map((line) => {\n try {\n const evt = JSON.parse(line);\n if (evt?.type === 'text' && evt?.part?.text) return evt.part.text;\n } catch {}\n return null;\n })\n .filter(Boolean)\n .join('\\n');\n resolve(result);\n } else {\n const errText = stderr || `${adapter.command} exited with code ${code}`;\n pushLine(task, errText);\n setStatus(task, 'error');\n reject(new Error(errText));\n }\n });\n });\n proc.on('error', (err) => {\n if (current !== task) return;\n settle(() => {\n pushLine(task, `Failed to spawn agent: ${err.message}`);\n setStatus(task, 'error');\n reject(err);\n });\n });\n });\n }\n\n function stop(): Result {\n if (!current) {\n return { ok: false, error: 'No agent task running' };\n }\n const task = current;\n setStatus(task, 'stopping');\n if (!task.proc.killed) task.proc.kill('SIGTERM');\n // SIGTERM can be ignored or delayed indefinitely; without this escalation a hung\n // process leaves `current` stuck in 'stopping' forever, permanently blocking start().\n setTimeout(() => {\n if (current === task && task.status === 'stopping') {\n task.proc.kill('SIGKILL');\n }\n }, 5000);\n return { ok: true };\n }\n\n function getStatus(): AgentTaskState | null {\n if (!current) return null;\n return {\n status: current.status,\n taskKind: current.taskKind,\n planTitle: current.planTitle,\n planId: current.planId,\n phaseIndex: current.phaseIndex,\n ideaId: current.ideaId,\n agentId: current.agentId,\n lines: [...current.lines],\n };\n }\n\n return {\n start,\n startForPlan,\n startForIdea,\n startForIdeaExtend,\n startBatchAudit,\n runCommitSuggest,\n stop,\n getStatus,\n subscribe(res: ServerResponse) {\n clients.add(res);\n res.on('close', () => clients.delete(res));\n },\n killCurrent() {\n if (current?.proc && !current.proc.killed) {\n current.proc.kill();\n }\n },\n };\n}\n\nexport interface AgentManager {\n start: (plan: PlanEntry, phaseIndex: number) => Result;\n startForPlan: (plan: PlanEntry, prompt: string) => Result;\n startForIdea: (idea: IdeaEntry, prompt: string) => Result;\n startForIdeaExtend: (idea: IdeaEntry, prompt: string) => Result;\n startBatchAudit: () => Result;\n runCommitSuggest: (prompt: string) => Promise<string>;\n stop: () => Result;\n getStatus: () => AgentTaskState | null;\n subscribe: (res: ServerResponse) => void;\n killCurrent: () => void;\n}\n","function buildPrompt(diffText: string, planContext?: string): string {\n return `You are writing a single git commit message for the diff below. Do not use any tools, do not read or edit any files — base your answer only on the diff text given.\n\nFollow this repo's commit convention: \\`type(scope): Description\\`, where type is one of feat|fix|chore|docs|refactor and scope is a subsystem area from this fixed list: core, cli, app, server, agent, plans, ideas, docs, settings, stack, ui, ci, config, deps, repo. Pick the area the diff most affects. Keep the whole title under 100 characters and do not end it with a period.${\n planContext\n ? `\\nThis work belongs to plan ${planContext}. Do NOT put the plan id in the scope — instead end the message body with a \\`Refs: ${planContext}\\` line as its final line.`\n : ''\n }\n\nRespond with ONLY a single JSON object, no prose, no code fences, no markdown — exactly this shape:\n{\"title\": \"type(scope): Description\", \"message\": \"${\n planContext\n ? `longer body describing what changed and why, ending with a \\`Refs: ${planContext}\\` line`\n : 'optional longer body describing what changed and why, or an empty string if the title alone is clear enough'\n }\"}\n\nDiff:\n${diffText}`;\n}\n\n/**\n * One-shot, read-only agent call — not the long-running phase/task system in agent.ts.\n * The actual process spawn lives in agent.ts's runCommitSuggest, which tracks it on the\n * shared `current` task so the UI's Agent card shows it running; this module only builds\n * the prompt and parses the result.\n */\nexport async function suggestCommitMessage(\n diffText: string,\n planContext: string | undefined,\n runPrompt: (prompt: string) => Promise<string>,\n): Promise<{ title: string; message: string }> {\n if (!diffText.trim()) {\n throw new Error('No changes to summarize — select at least one file first');\n }\n\n const prompt = buildPrompt(diffText, planContext);\n const output = await runPrompt(prompt);\n\n let resultText = output;\n try {\n const parsed = JSON.parse(output) as { result?: string };\n if (typeof parsed.result === 'string') resultText = parsed.result;\n } catch {\n // fall through with raw output\n }\n\n const match = resultText.match(/\\{[\\s\\S]*\\}/);\n if (!match) throw new Error('Agent did not return a parseable commit message');\n\n const data = JSON.parse(match[0]) as { title?: string; message?: string };\n if (!data.title) throw new Error('Agent response missing a title');\n let message = data.message ?? '';\n // The prompt asks for a `Refs: <plan>` footer when a plan is active; backfill it\n // if the model dropped it, so plan traceability stays consistent.\n if (planContext && !/Refs:\\s*\\S/.test(message)) {\n message = message ? `${message}\\n\\nRefs: ${planContext}` : `Refs: ${planContext}`;\n }\n return { title: data.title, message };\n}\n","import { spawn, spawnSync } from 'node:child_process';\nimport { watch } from 'node:fs';\nimport { lstat, readFile } from 'node:fs/promises';\nimport type { ServerResponse } from 'node:http';\nimport { join } from 'node:path';\nimport type { GitStatusEntry, PlanEntry } from '../../types';\n\nconst AI_DIFF_BLOCKLIST = [/(^|\\/)\\.env(\\.|$)/i, /\\.(pem|key|p12|crt)$/i];\n\n// Git expands pathspec magic (e.g. `:/`) even after `--`, which can broaden a\n// command beyond the caller-selected files. Force every API-supplied path to be\n// treated literally so selections can't widen to unrelated files.\nconst toLiteralPathspec = (file: string) => `:(literal)${file}`;\n\nexport function createGitManager(root: string) {\n const clients = new Set<ServerResponse>();\n\n function broadcast(event: { message: string; timestamp: string }) {\n const data = `data: ${JSON.stringify(event)}\\n\\n`;\n for (const client of clients) {\n try {\n client.write(data);\n } catch {\n clients.delete(client);\n }\n }\n }\n\n function parsePorcelain(output: string): GitStatusEntry[] {\n const entries: GitStatusEntry[] = [];\n for (const line of output.split('\\n')) {\n if (!line.trim()) continue;\n const x = line[0] ?? ' ';\n const y = line[1] ?? ' ';\n const rest = line.slice(3);\n const parts = rest.split(' -> ');\n const path = parts.pop() ?? rest;\n entries.push({\n path,\n status: `${x}${y}`,\n staged: x !== ' ' && x !== '?',\n renameSource: (x === 'R' || x === 'C') && parts.length > 0 ? parts[0] : undefined,\n });\n }\n return entries;\n }\n\n function runGit(args: string[]): Promise<string> {\n return new Promise((resolve, reject) => {\n const proc = spawn('git', args, {\n cwd: root,\n stdio: ['ignore', 'pipe', 'pipe'],\n });\n let stdout = '';\n let stderr = '';\n proc.stdout?.on('data', (d: Buffer) => {\n stdout += d.toString();\n });\n proc.stderr?.on('data', (d: Buffer) => {\n stderr += d.toString();\n });\n proc.on('close', (code) => {\n if (code === 0) {\n resolve(stdout);\n } else {\n reject(new Error(stderr || `git ${args[0]} exited with code ${code}`));\n }\n });\n proc.on('error', reject);\n });\n }\n\n function runGitStatus(): Promise<GitStatusEntry[]> {\n return runGit(['status', '--porcelain=v1']).then(parsePorcelain);\n }\n\n async function commit(files: string[], title: string, message?: string): Promise<void> {\n if (files.length > 0) {\n const statusEntries = await runGitStatus();\n const statusByPath = new Map(statusEntries.map((e) => [e.path, e.status]));\n // Files already fully staged (no pending worktree change) have nothing left for\n // `git add` to match — passing them anyway makes git fail with \"did not match any files\".\n const toAdd = files.filter((f) => {\n const status = statusByPath.get(f);\n return status === undefined || status[1] !== ' ';\n });\n if (toAdd.length > 0) {\n await runGit(['add', '--', ...toAdd.map(toLiteralPathspec)]);\n }\n }\n const args = ['commit', '-m', title];\n if (message) args.push('-m', message);\n // Restrict the commit to the selected files so unrelated already-staged\n // paths aren't swept in; an empty selection falls through to \"commit\n // whatever's staged\", which is the intended behavior for that case.\n if (files.length > 0) {\n args.push('--', ...files.map(toLiteralPathspec));\n }\n await runGit(args);\n }\n\n function ensureBranch(plan: PlanEntry): void {\n if (!plan.kind || !plan.id) return;\n\n const kind = plan.kind.toLowerCase();\n const id = plan.id.toLowerCase();\n const title = plan.title\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '');\n\n const branch = `${kind}/${id}-${title}`;\n\n const currentResult = spawnSync('git', ['rev-parse', '--abbrev-ref', 'HEAD'], { cwd: root });\n if (currentResult.status !== 0) {\n throw new Error(\n currentResult.stderr.toString().trim() || 'Unable to read current git branch',\n );\n }\n const currentBranch = currentResult.stdout.toString().trim();\n if (currentBranch === branch) return;\n\n const result = spawnSync('git', ['checkout', '-b', branch, 'main'], { cwd: root });\n if (result.status !== 0) {\n // Branch already exists — just check it out\n const checkoutResult = spawnSync('git', ['checkout', branch], { cwd: root });\n if (checkoutResult.status !== 0) {\n throw new Error(\n checkoutResult.stderr.toString().trim() ||\n result.stderr.toString().trim() ||\n `Unable to check out ${branch}`,\n );\n }\n }\n }\n\n async function refresh() {\n try {\n await runGitStatus();\n broadcast({\n message: 'Working tree status updated',\n timestamp: new Date().toISOString(),\n });\n } catch {\n // git not available or not a repo\n }\n }\n\n const gitDir = join(root, '.git');\n let timer: ReturnType<typeof setTimeout> | null = null;\n try {\n watch(gitDir, { recursive: true }, (eventType, filename) => {\n if (filename === 'index') {\n if (timer) clearTimeout(timer);\n timer = setTimeout(refresh, 500);\n }\n });\n } catch {\n // watcher not available\n }\n\n const srcDir = join(root, 'src');\n let srcTimer: ReturnType<typeof setTimeout> | null = null;\n try {\n watch(srcDir, { recursive: true }, () => {\n if (srcTimer) clearTimeout(srcTimer);\n srcTimer = setTimeout(refresh, 500);\n });\n } catch {\n // src/ doesn't exist or watcher not available\n }\n\n async function hasUpstream(): Promise<boolean> {\n try {\n await runGit(['rev-parse', '--abbrev-ref', '--symbolic-full-name', '@{u}']);\n return true;\n } catch {\n return false;\n }\n }\n\n // Counts commits on HEAD not yet on the upstream branch. When no upstream is\n // configured (e.g. a fresh branch that's never been pushed), every local commit\n // not reachable from any remote-tracking branch counts as ahead.\n async function getAheadCount(): Promise<number> {\n try {\n const args = (await hasUpstream())\n ? ['rev-list', '--count', '@{u}..HEAD']\n : ['rev-list', '--count', 'HEAD', '--not', '--remotes'];\n const output = await runGit(args);\n return Number.parseInt(output.trim(), 10) || 0;\n } catch {\n return 0;\n }\n }\n\n async function push(): Promise<void> {\n if (await hasUpstream()) {\n await runGit(['push']);\n } else {\n await runGit(['push', '--set-upstream', 'origin', getCurrentBranch()]);\n }\n }\n\n function getCurrentBranch(): string {\n const result = spawnSync('git', ['rev-parse', '--abbrev-ref', 'HEAD'], { cwd: root });\n return result.stdout.toString().trim();\n }\n\n function getFeatureBranchPlanId(): string | null {\n const branch = getCurrentBranch();\n const match = branch.match(/^[a-z]+\\/([a-z]+-\\d+)-/);\n return match ? match[1].toUpperCase() : null;\n }\n\n /**\n * Diff text for the given paths, capped to a sane size for feeding into a prompt.\n * Plain `git diff` skips untracked files entirely, so those are read directly and\n * presented as new-file content instead.\n */\n async function diff(files: string[], maxChars = 12000): Promise<string> {\n if (files.length === 0) return '';\n const blocked = files.find((file) => AI_DIFF_BLOCKLIST.some((pattern) => pattern.test(file)));\n if (blocked) {\n throw new Error(`Refusing to send sensitive file \"${blocked}\" to commit suggestion`);\n }\n const statusEntries = await runGitStatus();\n const untracked = new Set(statusEntries.filter((e) => e.status === '??').map((e) => e.path));\n\n const renameSources = new Map(\n statusEntries\n .filter((e): e is GitStatusEntry & { renameSource: string } => !!e.renameSource)\n .map((e) => [e.path, e.renameSource]),\n );\n\n const tracked = files.filter((f) => {\n if (untracked.has(f)) return false;\n const source = renameSources.get(f);\n if (source && AI_DIFF_BLOCKLIST.some((pattern) => pattern.test(source))) return false;\n return true;\n });\n const parts: string[] = [];\n\n if (tracked.length > 0) {\n const trackedDiff = await runGit([\n 'diff',\n 'HEAD',\n '--',\n ...tracked.map(toLiteralPathspec),\n ]).catch(() => '');\n if (trackedDiff) parts.push(trackedDiff);\n }\n\n for (const file of files.filter((f) => untracked.has(f))) {\n const filePath = join(root, file);\n // lstat (not stat) so a symlink is identified as such instead of followed —\n // otherwise its target's content, possibly outside the repo, leaks into the AI prompt.\n const stats = await lstat(filePath).catch(() => null);\n if (!stats) continue;\n if (stats.isSymbolicLink()) {\n parts.push(`--- /dev/null\\n+++ b/${file}\\n(new file omitted: symlink)`);\n continue;\n }\n if (stats.size > maxChars) {\n parts.push(`--- /dev/null\\n+++ b/${file}\\n(new file omitted: exceeds diff size cap)`);\n continue;\n }\n const content = await readFile(filePath, 'utf-8').catch(() => '');\n if (content) {\n parts.push(`--- /dev/null\\n+++ b/${file}\\n(new file)\\n${content}`);\n }\n }\n\n const combined = parts.join('\\n\\n');\n return combined.length > maxChars\n ? `${combined.slice(0, maxChars)}\\n... (truncated)`\n : combined;\n }\n\n return {\n async getStatus(): Promise<GitStatusEntry[]> {\n return runGitStatus();\n },\n getCurrentBranch,\n commit,\n diff,\n ensureBranch,\n getFeatureBranchPlanId,\n getAheadCount,\n push,\n subscribe(res: ServerResponse) {\n clients.add(res);\n res.on('close', () => clients.delete(res));\n },\n };\n}\n","import { spawn } from 'node:child_process';\nimport { watch } from 'node:fs';\nimport type { ServerResponse } from 'node:http';\nimport { join } from 'node:path';\nimport type { CheckName, CheckResult, CheckStatus } from '../../types';\n\ninterface StatusSnapshot {\n lint: CheckResult;\n format: CheckResult;\n test: CheckResult;\n}\n\nconst CHECK_COMMANDS: Record<CheckName, string> = {\n lint: 'npx biome lint .',\n format: 'npx biome format .',\n test: 'npx vitest run',\n};\n\nexport function createStatusManager(root: string) {\n const clients = new Set<ServerResponse>();\n const snapshot: StatusSnapshot = {\n lint: { status: 'stale', lastRun: null, output: '' },\n format: { status: 'stale', lastRun: null, output: '' },\n test: { status: 'stale', lastRun: null, output: '' },\n };\n const running = new Set<CheckName>();\n const queued = new Set<CheckName>();\n\n function broadcast(event: { message: string; timestamp: string }) {\n const data = `data: ${JSON.stringify(event)}\\n\\n`;\n for (const client of clients) {\n try {\n client.write(data);\n } catch {\n clients.delete(client);\n }\n }\n }\n\n function setResult(name: CheckName, status: CheckStatus, output: string) {\n snapshot[name] = { status, lastRun: new Date().toISOString(), output };\n broadcast({\n message: `${name}: ${status}`,\n timestamp: snapshot[name].lastRun!,\n });\n if (status !== 'running' && queued.has(name)) {\n queued.delete(name);\n runCheck(name);\n }\n }\n\n function runCheck(name: CheckName) {\n if (running.has(name)) {\n queued.add(name);\n return;\n }\n running.add(name);\n setResult(name, 'running', '');\n\n const cmd = CHECK_COMMANDS[name];\n const proc = spawn(cmd, {\n cwd: root,\n stdio: ['ignore', 'pipe', 'pipe'],\n shell: true,\n });\n\n let stdout = '';\n let stderr = '';\n proc.stdout?.on('data', (d: Buffer) => {\n stdout += d.toString();\n });\n proc.stderr?.on('data', (d: Buffer) => {\n stderr += d.toString();\n });\n\n proc.on('close', (code) => {\n running.delete(name);\n const output = stdout + stderr;\n if (code === 0) {\n setResult(name, 'pass', output);\n } else {\n setResult(name, 'fail', output);\n }\n });\n\n proc.on('error', (err) => {\n running.delete(name);\n setResult(name, 'fail', `Failed to spawn process: ${err.message}`);\n });\n }\n\n function runQualityFix() {\n if (running.has('lint') || running.has('format')) return;\n setResult('lint', 'running', 'Applying automatic fixes…');\n setResult('format', 'running', 'Applying automatic fixes…');\n\n const proc = spawn('npx biome check . --write', {\n cwd: root,\n stdio: ['ignore', 'pipe', 'pipe'],\n shell: true,\n });\n\n proc.on('close', () => {\n runCheck('lint');\n runCheck('format');\n });\n\n proc.on('error', (err) => {\n const message = `Failed to spawn fix process: ${err.message}`;\n setResult('lint', 'fail', message);\n setResult('format', 'fail', message);\n });\n }\n\n const srcDir = join(root, 'src');\n let srcTimer: ReturnType<typeof setTimeout> | null = null;\n try {\n watch(srcDir, { recursive: true }, () => {\n if (srcTimer) clearTimeout(srcTimer);\n srcTimer = setTimeout(() => {\n runCheck('lint');\n runCheck('format');\n }, 1000);\n });\n } catch {\n // watcher not available (src/ doesn't exist or platform doesn't support recursive)\n }\n\n return {\n getStatus(): StatusSnapshot {\n return {\n lint: { ...snapshot.lint },\n format: { ...snapshot.format },\n test: { ...snapshot.test },\n };\n },\n runCheck,\n runQualityFix,\n subscribe(res: ServerResponse) {\n clients.add(res);\n for (const name of ['lint', 'format', 'test'] as CheckName[]) {\n const result = snapshot[name];\n if (result.status !== 'stale') {\n res.write(\n `data: ${JSON.stringify({ message: `${name}: ${result.status}`, timestamp: result.lastRun })}\\n\\n`,\n );\n }\n }\n res.on('close', () => clients.delete(res));\n },\n };\n}\n","import { mkdir, readFile, readdir, stat, unlink, writeFile } from 'node:fs/promises';\nimport type { IncomingMessage, ServerResponse } from 'node:http';\nimport { extname, join } from 'node:path';\nimport { applyEnvEntries, parseEnv } from '../../core/env';\nimport { deriveIdeaStatuses } from '../../core/idea-status';\nimport {\n findConsistencyIssues,\n parseDecisions,\n parseIdeas,\n parseOpenQuestions,\n parsePlanFile,\n parsePlans,\n parseProgress,\n readAllIdeaFiles,\n readAllPlanFiles,\n readIdeasMerged,\n readPlansMerged,\n} from '../../core/parser';\nimport {\n appendBlock,\n archivePlanFile,\n assignPlanId,\n formatDecisionEntry,\n formatIdeaFile,\n formatIdeasIndex,\n formatOpenQuestions,\n formatPlanEntry,\n formatPlanFile,\n formatPlansIndex,\n todayDateString,\n} from '../../core/serializer';\nimport {\n AGENT_IDS,\n type AgentId,\n DEFAULT_AGENTS,\n type DefaultAgentsMap,\n type EnvEntry,\n type IdeaEntry,\n type LogEntry,\n PLAN_KINDS,\n type PaperCampConfig,\n type PhaseItem,\n type PlanEntry,\n type PlanStatus,\n coerceAgentConfig,\n} from '../../types/index';\nimport { findFocusPlan } from '../features/plans/helpers';\nimport { createActivityManager } from './activity';\nimport { type AgentManager, createAgentManager } from './agent';\nimport { suggestCommitMessage } from './commit-suggest';\nimport { createGitManager } from './git';\nimport { createStatusManager } from './status';\n\nasync function readMaybe(path: string): Promise<string> {\n try {\n return await readFile(path, 'utf-8');\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') return '';\n throw error;\n }\n}\n\nasync function fileExists(path: string): Promise<boolean> {\n try {\n await stat(path);\n return true;\n } catch {\n return false;\n }\n}\n\nasync function readBody(req: IncomingMessage): Promise<string> {\n return new Promise((resolve, reject) => {\n let body = '';\n req.on('data', (chunk) => {\n body += chunk;\n });\n req.on('end', () => resolve(body));\n req.on('error', reject);\n });\n}\n\ninterface ApiRoute {\n path: string;\n handler: (root: string) => Promise<unknown>;\n}\n\nconst campFile = (root: string, name: string) => join(root, 'papercamp', name);\n\nconst CONFIG_ALLOWLIST = [\n 'biome.json',\n 'tsconfig.json',\n 'tailwind.config.ts',\n 'vite.config.ts',\n 'vite.app.config.ts',\n 'postcss.config.js',\n 'package.json',\n];\n\nasync function checkBranchConflictForPlan(\n root: string,\n git: { getFeatureBranchPlanId: () => string | null },\n targetPlanId?: string,\n): Promise<string | null> {\n const activePlanId = git.getFeatureBranchPlanId();\n if (!activePlanId) return null;\n if (targetPlanId && activePlanId === targetPlanId) return null;\n const plansDir = campFile(root, 'plans');\n const { entries } = await readPlansMerged(plansDir, campFile(root, 'plans.md'));\n const activePlan = entries.find((p) => p.id === activePlanId);\n if (!activePlan || activePlan.status === 'done' || activePlan.status === 'dropped') return null;\n return `Finish \\`${activePlanId}\\` — ${activePlan.title} — before starting another plan`;\n}\n\nasync function regenerateIndexes(root: string): Promise<void> {\n const plansDir = campFile(root, 'plans');\n const ideasDir = campFile(root, 'ideas');\n\n const [plansResult, ideasResult] = await Promise.all([\n readPlansMerged(plansDir, campFile(root, 'plans.md')),\n readIdeasMerged(ideasDir, campFile(root, 'ideas.md')),\n ]);\n\n const ideasWithStatus = deriveIdeaStatuses(ideasResult.entries, plansResult.entries);\n\n await mkdir(plansDir, { recursive: true });\n await mkdir(ideasDir, { recursive: true });\n\n await Promise.all([\n writeFile(join(plansDir, 'index.md'), formatPlansIndex(plansResult.entries)),\n writeFile(join(ideasDir, 'index.md'), formatIdeasIndex(ideasWithStatus)),\n ]);\n}\n\nconst apiRoutes: ApiRoute[] = [\n {\n path: '/api/package-name',\n handler: async (root) => {\n const raw = await readMaybe(join(root, 'package.json'));\n if (!raw) return null;\n try {\n const pkg = JSON.parse(raw);\n return pkg.name ?? null;\n } catch {\n return null;\n }\n },\n },\n {\n path: '/api/plans',\n handler: async (root) => readPlansMerged(campFile(root, 'plans'), campFile(root, 'plans.md')),\n },\n {\n path: '/api/progress',\n handler: async (root) => ({\n entries: parseProgress(await readMaybe(campFile(root, 'progress.md'))),\n }),\n },\n {\n path: '/api/decisions',\n handler: async (root) => parseDecisions(await readMaybe(campFile(root, 'decisions.md'))),\n },\n {\n path: '/api/open-questions',\n handler: async (root) =>\n parseOpenQuestions(await readMaybe(campFile(root, 'open-questions.md'))),\n },\n {\n path: '/api/ideas',\n handler: async (root) => readIdeasMerged(campFile(root, 'ideas'), campFile(root, 'ideas.md')),\n },\n {\n path: '/api/consistency',\n handler: async (root) => {\n const [decisionsRaw, openQuestionsRaw, plansResult] = await Promise.all([\n readMaybe(campFile(root, 'decisions.md')),\n readMaybe(campFile(root, 'open-questions.md')),\n readPlansMerged(campFile(root, 'plans'), campFile(root, 'plans.md')),\n ]);\n const decisions = parseDecisions(decisionsRaw);\n const openQuestions = parseOpenQuestions(openQuestionsRaw);\n return findConsistencyIssues(decisions.entries, openQuestions.entries, plansResult.entries);\n },\n },\n {\n path: '/api/config',\n handler: async (root) => {\n const raw = await readMaybe(join(root, 'papercamp', 'config.json'));\n if (!raw) return null;\n const config = JSON.parse(raw);\n // Coerce legacy bare-string defaultAgents (e.g. \"phase\": \"opencode\") into\n // the { agent, model?, effort? } shape the settings UI expects — old\n // config.json files predate FEAT-26 and would otherwise crash the page.\n if (config?.defaultAgents) {\n config.defaultAgents = {\n phase: coerceAgentConfig(config.defaultAgents.phase),\n planDraft: coerceAgentConfig(config.defaultAgents.planDraft),\n ideaExtend: coerceAgentConfig(config.defaultAgents.ideaExtend),\n commitSuggest: coerceAgentConfig(config.defaultAgents.commitSuggest),\n };\n }\n return config;\n },\n },\n {\n path: '/api/docs',\n handler: async (root) => {\n const docNames = ['MAIN.md', 'README.md', 'CHANGELOG.md', 'LICENSE'];\n const files: { name: string; content: string }[] = [];\n for (const name of docNames) {\n const content = await readMaybe(join(root, name));\n if (content) files.push({ name, content });\n }\n return { files };\n },\n },\n {\n path: '/api/configs',\n handler: async (root) => {\n const configNames = [\n 'biome.json',\n 'tsconfig.json',\n 'tailwind.config.ts',\n 'vite.config.ts',\n 'vite.app.config.ts',\n 'postcss.config.js',\n 'package.json',\n ];\n const files: string[] = [];\n for (const name of configNames) {\n const content = await readMaybe(join(root, name));\n if (content) files.push(name);\n }\n return { files };\n },\n },\n];\n\nexport interface ApiMiddleware {\n (req: IncomingMessage, res: ServerResponse, next: () => void): Promise<void>;\n agent: AgentManager;\n}\n\nexport function createApiMiddleware(root: string): ApiMiddleware {\n const activity = createActivityManager(root);\n const git = createGitManager(root);\n const status = createStatusManager(root);\n\n async function prependProgressItem(item: string): Promise<void> {\n const progressPath = campFile(root, 'progress.md');\n const today = todayDateString();\n const heading = `## ${today}`;\n const raw = await readMaybe(progressPath);\n if (raw.startsWith(`${heading}\\n`)) {\n await writeFile(\n progressPath,\n `${heading}\\n- ${item}\\n${raw.slice(heading.length + 1)}`,\n 'utf-8',\n );\n } else {\n const trimmed = raw.trimEnd();\n const next = trimmed ? `${heading}\\n- ${item}\\n\\n${trimmed}\\n` : `${heading}\\n- ${item}\\n`;\n await writeFile(progressPath, next, 'utf-8');\n }\n }\n\n async function stampAuditDate(planId: string, gapPhases: number): Promise<void> {\n const plansDir = campFile(root, 'plans');\n // Batch audit can touch archived (done/dropped) plans too — resolve the\n // actual file so those get stamped instead of re-audited every run.\n const directPlanFile = join(plansDir, `${planId}.md`);\n const archivedPlanFile = join(plansDir, 'archive', `${planId}.md`);\n const planFile = (await fileExists(directPlanFile))\n ? directPlanFile\n : (await fileExists(archivedPlanFile))\n ? archivedPlanFile\n : null;\n if (!planFile) return;\n const raw = await readMaybe(planFile);\n if (!raw) return;\n const parsed = parsePlanFile(raw);\n if (parsed.entries.length === 0) return;\n const entry = parsed.entries[0];\n const writeInput: Parameters<typeof formatPlanFile>[0] = {\n id: planId,\n title: entry.title,\n kind: entry.kind ?? 'feat',\n status: entry.status,\n idea: entry.idea,\n agent: entry.agent,\n created: entry.created,\n updated: entry.updated,\n audited: todayDateString(),\n tags: entry.tags,\n body: entry.body,\n phases: entry.phases,\n log: entry.log,\n clarifications: entry.clarifications,\n };\n await writeFile(planFile, `${formatPlanFile(writeInput)}\\n`, 'utf-8');\n if (gapPhases > 0) {\n const label = `gap phase${gapPhases === 1 ? '' : 's'}`;\n await prependProgressItem(\n `Batch audit of ${planId} (${entry.title}) — ${gapPhases} ${label} appended`,\n );\n }\n }\n\n const agent = createAgentManager(root, (plan) => git.ensureBranch(plan), stampAuditDate);\n const handler = async (req: IncomingMessage, res: ServerResponse, next: () => void) => {\n const pathname = (req.url ?? '').split('?')[0];\n\n // DELETE /api/plans?title=... — remove a plan entry from per-file storage\n if (req.method === 'DELETE' && pathname === '/api/plans') {\n try {\n const url = new URL(req.url ?? '', `http://${req.headers.host ?? 'localhost'}`);\n const title = url.searchParams.get('title');\n if (!title?.trim()) {\n res.statusCode = 400;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: 'title is required' }));\n return;\n }\n const plansDir = campFile(root, 'plans');\n const trimmed = title.trim();\n const { entries } = await readAllPlanFiles(plansDir);\n const target = entries.find((e) => e.title === trimmed || e.id === trimmed);\n if (!target?.id) {\n res.statusCode = 404;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: 'plan not found in per-file storage' }));\n return;\n }\n const filePath = join(plansDir, `${target.id}.md`);\n if (!(await fileExists(filePath))) {\n res.statusCode = 404;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: 'plan file not found' }));\n return;\n }\n await unlink(filePath);\n await regenerateIndexes(root);\n res.statusCode = 200;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ ok: true }));\n } catch (error) {\n res.statusCode = 500;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: (error as Error).message }));\n }\n return;\n }\n\n // POST /api/plans — create a new per-file plan entry\n if (req.method === 'POST' && pathname === '/api/plans') {\n try {\n const body = await readBody(req);\n const { title, content, kind } = JSON.parse(body) as {\n title: string;\n content?: string;\n kind?: string;\n };\n if (!title?.trim()) {\n res.statusCode = 400;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: 'title is required' }));\n return;\n }\n const planKind =\n kind && PLAN_KINDS.includes(kind as (typeof PLAN_KINDS)[number]) ? kind : 'feat';\n\n const configPath = join(root, 'papercamp', 'config.json');\n const id = await assignPlanId(configPath, planKind);\n\n if (!id) {\n res.statusCode = 500;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: 'could not assign plan ID' }));\n return;\n }\n\n const plansDir = campFile(root, 'plans');\n await mkdir(plansDir, { recursive: true });\n\n const planContent = formatPlanFile({\n id,\n title: title.trim(),\n kind: planKind,\n status: 'idea',\n created: todayDateString(),\n body: content?.trim(),\n });\n await writeFile(join(plansDir, `${id}.md`), `${planContent}\\n`, 'utf-8');\n await regenerateIndexes(root);\n res.statusCode = 201;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ ok: true, id }));\n } catch (error) {\n res.statusCode = 500;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: (error as Error).message }));\n }\n return;\n }\n\n // PATCH /api/plans?title=... — update an existing plan entry\n if (req.method === 'PATCH' && pathname === '/api/plans') {\n try {\n const url = new URL(req.url ?? '', `http://${req.headers.host ?? 'localhost'}`);\n const title = url.searchParams.get('title');\n if (!title?.trim()) {\n res.statusCode = 400;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: 'title is required' }));\n return;\n }\n const reqBody = await readBody(req);\n const updates = JSON.parse(reqBody) as {\n phases?: PhaseItem[];\n status?: PlanStatus;\n log?: LogEntry[];\n agent?: AgentId | null;\n };\n if (updates.agent && !AGENT_IDS.includes(updates.agent)) {\n res.statusCode = 400;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: 'agent must be a known agent id' }));\n return;\n }\n\n const plansDir = campFile(root, 'plans');\n const { entries } = await readAllPlanFiles(plansDir);\n const trimmed = title.trim();\n const target = entries.find((e) => e.title === trimmed || e.id === trimmed);\n\n if (!target?.id) {\n res.statusCode = 404;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: 'plan not found' }));\n return;\n }\n\n const targetFile = join(plansDir, `${target.id}.md`);\n const raw = await readMaybe(targetFile);\n if (!raw) {\n res.statusCode = 404;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: 'plan file not found' }));\n return;\n }\n\n const parsed = parsePlanFile(raw);\n if (parsed.entries.length === 0) {\n res.statusCode = 500;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: 'failed to parse plan file' }));\n return;\n }\n\n const updatedEntry: PlanEntry = {\n ...parsed.entries[0],\n ...(updates.status !== undefined && { status: updates.status }),\n ...(updates.phases !== undefined && { phases: updates.phases }),\n ...(updates.log !== undefined && { log: updates.log }),\n ...(updates.agent !== undefined && { agent: updates.agent ?? undefined }),\n updated: todayDateString(),\n };\n\n if (updates.status === 'done' || updates.status === 'dropped') {\n const conflict = await checkBranchConflictForPlan(root, git, target.id);\n if (conflict) {\n res.statusCode = 409;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: conflict }));\n return;\n }\n }\n\n // Demote other in-progress plans when starting a new one\n if (updates.status === 'in-progress') {\n const allPlans = await readAllPlanFiles(plansDir);\n for (const other of allPlans.entries) {\n if (other.id !== target.id && other.status === 'in-progress') {\n const otherFile = join(plansDir, `${other.id}.md`);\n const otherRaw = await readMaybe(otherFile);\n if (otherRaw) {\n const otherParsed = parsePlanFile(otherRaw);\n if (otherParsed.entries.length > 0) {\n const demotedInput: Parameters<typeof formatPlanFile>[0] = {\n id: otherParsed.entries[0].id ?? other.id!,\n title: otherParsed.entries[0].title,\n kind: otherParsed.entries[0].kind ?? 'feat',\n status: 'planned',\n created: otherParsed.entries[0].created,\n updated: todayDateString(),\n audited: otherParsed.entries[0].audited,\n body: otherParsed.entries[0].body,\n phases: otherParsed.entries[0].phases,\n log: otherParsed.entries[0].log,\n clarifications: otherParsed.entries[0].clarifications,\n };\n await writeFile(otherFile, `${formatPlanFile(demotedInput)}\\n`, 'utf-8');\n }\n }\n }\n }\n }\n\n // Write updated plan\n const writeInput: Parameters<typeof formatPlanFile>[0] = {\n id: updatedEntry.id ?? target.id,\n title: updatedEntry.title,\n kind: updatedEntry.kind ?? 'feat',\n status: updatedEntry.status,\n idea: updatedEntry.idea,\n agent: updatedEntry.agent,\n created: updatedEntry.created,\n updated: updatedEntry.updated,\n audited: updatedEntry.audited,\n tags: updatedEntry.tags,\n body: updatedEntry.body,\n phases: updatedEntry.phases,\n log: updatedEntry.log,\n clarifications: updatedEntry.clarifications,\n };\n await writeFile(targetFile, `${formatPlanFile(writeInput)}\\n`, 'utf-8');\n await regenerateIndexes(root);\n\n if (updates.status === 'done' || updates.status === 'dropped') {\n await archivePlanFile(root, target.id);\n try {\n git.ensureBranch(updatedEntry);\n } catch {\n // Non-fatal\n }\n }\n\n res.statusCode = 200;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ ok: true }));\n } catch (error) {\n res.statusCode = 500;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: (error as Error).message }));\n }\n return;\n }\n\n // POST /api/ideas — create a new per-file idea entry\n if (req.method === 'POST' && pathname === '/api/ideas') {\n try {\n const reqBody = await readBody(req);\n const { title, content } = JSON.parse(reqBody) as { title?: string; content?: string };\n if (!title?.trim()) {\n res.statusCode = 400;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: 'title is required' }));\n return;\n }\n const ideasDir = campFile(root, 'ideas');\n const existing = await readIdeasMerged(ideasDir, campFile(root, 'ideas.md'));\n const maxNum = existing.entries.reduce((max, idea) => {\n if (idea.id) {\n const num = Number.parseInt(idea.id.replace('IDEA-', ''), 10);\n return Number.isNaN(num) ? max : Math.max(max, num);\n }\n return max;\n }, 0);\n const newId = `IDEA-${maxNum + 1}`;\n await mkdir(ideasDir, { recursive: true });\n const ideaContent = formatIdeaFile({\n id: newId,\n title: title.trim(),\n body: content?.trim(),\n });\n await writeFile(join(ideasDir, `${newId}.md`), `${ideaContent}\\n`, 'utf-8');\n await regenerateIndexes(root);\n res.statusCode = 201;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ ok: true, id: newId }));\n } catch (error) {\n res.statusCode = 500;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: (error as Error).message }));\n }\n return;\n }\n\n // GET /api/icon — serve project icon\n if (req.method === 'GET' && pathname === '/api/icon') {\n const assetsDir = join(root, 'papercamp', 'assets');\n const mimeMap: Record<string, string> = {\n svg: 'image/svg+xml',\n png: 'image/png',\n jpg: 'image/jpeg',\n jpeg: 'image/jpeg',\n gif: 'image/gif',\n webp: 'image/webp',\n };\n for (const [ext, mime] of Object.entries(mimeMap)) {\n try {\n const data = await readFile(join(assetsDir, `icon.${ext}`));\n res.statusCode = 200;\n res.setHeader('Content-Type', mime);\n res.setHeader('Cache-Control', 'no-cache');\n res.end(data);\n return;\n } catch {\n /* try next */\n }\n }\n res.statusCode = 404;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: 'no icon uploaded' }));\n return;\n }\n\n // POST /api/icon — upload project icon\n if (req.method === 'POST' && pathname === '/api/icon') {\n try {\n const body = await readBody(req);\n const { dataUri } = JSON.parse(body) as { dataUri?: string };\n if (!dataUri) {\n res.statusCode = 400;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: 'dataUri is required' }));\n return;\n }\n const match = dataUri.match(/^data:(image\\/[a-z0-9+.-]+);base64,(.+)$/);\n if (!match) {\n res.statusCode = 400;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: 'invalid data URI' }));\n return;\n }\n const mime = match[1];\n const ext = mime === 'image/svg+xml' ? 'svg' : mime.split('/')[1];\n const buffer = Buffer.from(match[2], 'base64');\n const assetsDir = join(root, 'papercamp', 'assets');\n await mkdir(assetsDir, { recursive: true });\n await writeFile(join(assetsDir, `icon.${ext}`), buffer);\n res.statusCode = 200;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ ok: true }));\n } catch (error) {\n res.statusCode = 500;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: (error as Error).message }));\n }\n return;\n }\n\n // GET /api/git/status — return working tree status\n if (req.method === 'GET' && pathname === '/api/git/status') {\n try {\n const entries = await git.getStatus();\n const branch = git.getCurrentBranch();\n const ahead = await git.getAheadCount();\n res.statusCode = 200;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ branch, entries, ahead }));\n } catch (error) {\n res.statusCode = 500;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: (error as Error).message }));\n }\n return;\n }\n\n // POST /api/git/push — push the current branch to its upstream\n if (req.method === 'POST' && pathname === '/api/git/push') {\n try {\n await git.push();\n res.statusCode = 200;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ ok: true }));\n } catch (error) {\n res.statusCode = 400;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: (error as Error).message }));\n }\n return;\n }\n\n // POST /api/git/commit — stage files and create a commit\n if (req.method === 'POST' && pathname === '/api/git/commit') {\n try {\n const body = await readBody(req);\n const { files, title, message } = JSON.parse(body) as {\n files: string[];\n title: string;\n message?: string;\n };\n if (!title?.trim()) {\n res.statusCode = 400;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: 'title is required' }));\n return;\n }\n await git.commit(files ?? [], title.trim(), message?.trim());\n res.statusCode = 200;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ ok: true }));\n } catch (error) {\n res.statusCode = 400;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: (error as Error).message }));\n }\n return;\n }\n\n // POST /api/git/suggest-commit-message — agent-written title/body from the actual diff\n if (req.method === 'POST' && pathname === '/api/git/suggest-commit-message') {\n try {\n const body = await readBody(req);\n const { files } = JSON.parse(body) as { files?: string[] };\n if (!files?.length) {\n res.statusCode = 400;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: 'files is required' }));\n return;\n }\n const diffText = await git.diff(files);\n const { entries } = await readPlansMerged(\n campFile(root, 'plans'),\n campFile(root, 'plans.md'),\n );\n const activePlan = findFocusPlan(entries);\n const suggestion = await suggestCommitMessage(\n diffText,\n activePlan?.id,\n agent.runCommitSuggest,\n );\n res.statusCode = 200;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify(suggestion));\n } catch (error) {\n res.statusCode = 400;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: (error as Error).message }));\n }\n return;\n }\n\n // GET /api/status — return current lint/format/test check results\n if (req.method === 'GET' && pathname === '/api/status') {\n res.statusCode = 200;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify(status.getStatus()));\n return;\n }\n\n // POST /api/status/check?name=lint|format|test — trigger a one-off check run\n if (req.method === 'POST' && pathname === '/api/status/check') {\n const url = new URL(req.url ?? '', `http://${req.headers.host ?? 'localhost'}`);\n const name = url.searchParams.get('name');\n if (name !== 'lint' && name !== 'format' && name !== 'test') {\n res.statusCode = 400;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: 'name must be lint, format, or test' }));\n return;\n }\n status.runCheck(name);\n res.statusCode = 202;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ ok: true }));\n return;\n }\n\n // POST /api/status/fix — run `biome check . --write` to auto-fix lint/format issues\n if (req.method === 'POST' && pathname === '/api/status/fix') {\n status.runQualityFix();\n res.statusCode = 202;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ ok: true }));\n return;\n }\n\n // GET /api/activity/stream — SSE endpoint for live activity events\n if (req.method === 'GET' && pathname === '/api/activity/stream') {\n res.statusCode = 200;\n res.setHeader('Content-Type', 'text/event-stream');\n res.setHeader('Cache-Control', 'no-cache');\n res.setHeader('Connection', 'keep-alive');\n res.flushHeaders();\n activity.subscribe(res);\n git.subscribe(res);\n status.subscribe(res);\n agent.subscribe(res);\n return;\n }\n\n // GET /api/agent/status — current agent task state, if any\n if (req.method === 'GET' && pathname === '/api/agent/status') {\n res.statusCode = 200;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify(agent.getStatus()));\n return;\n }\n\n // POST /api/agent/launch — start a headless agent on one plan phase\n if (req.method === 'POST' && pathname === '/api/agent/launch') {\n try {\n const reqBody = await readBody(req);\n const { planId, phaseIndex } = JSON.parse(reqBody) as {\n planId?: string;\n phaseIndex?: number;\n };\n if (!planId || typeof phaseIndex !== 'number') {\n res.statusCode = 400;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: 'planId and phaseIndex are required' }));\n return;\n }\n const plansDir = campFile(root, 'plans');\n const parsed = await readAllPlanFiles(plansDir);\n const plan = parsed.entries.find((p) => p.id === planId);\n if (!plan) {\n // Fallback to monolithic\n const mono = parsePlans(await readMaybe(campFile(root, 'plans.md')));\n const monoPlan = mono.entries.find((p) => p.id === planId);\n if (!monoPlan) {\n res.statusCode = 404;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: 'plan not found' }));\n return;\n }\n const conflict = await checkBranchConflictForPlan(root, git, monoPlan.id);\n if (conflict) {\n res.statusCode = 409;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: conflict }));\n return;\n }\n const result = await agent.start(monoPlan, phaseIndex);\n if (!result.ok) {\n res.statusCode = 409;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: result.error }));\n return;\n }\n res.statusCode = 202;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ ok: true }));\n return;\n }\n const conflict = await checkBranchConflictForPlan(root, git, plan.id);\n if (conflict) {\n res.statusCode = 409;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: conflict }));\n return;\n }\n const result = await agent.start(plan, phaseIndex);\n if (!result.ok) {\n res.statusCode = 409;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: result.error }));\n return;\n }\n res.statusCode = 202;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ ok: true }));\n } catch (error) {\n res.statusCode = 500;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: (error as Error).message }));\n }\n return;\n }\n\n // POST /api/agent/launch-audit — start a headless agent on a plan-scoped convergence audit\n if (req.method === 'POST' && pathname === '/api/agent/launch-audit') {\n try {\n const reqBody = await readBody(req);\n const { planId, prompt } = JSON.parse(reqBody) as { planId?: string; prompt?: string };\n if (!planId || !prompt) {\n res.statusCode = 400;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: 'planId and prompt are required' }));\n return;\n }\n const plansDir = campFile(root, 'plans');\n const parsed = await readAllPlanFiles(plansDir);\n let plan = parsed.entries.find((p) => p.id === planId);\n if (!plan) {\n const mono = parsePlans(await readMaybe(campFile(root, 'plans.md')));\n plan = mono.entries.find((p) => p.id === planId);\n }\n if (!plan) {\n res.statusCode = 404;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: 'plan not found' }));\n return;\n }\n const conflict = await checkBranchConflictForPlan(root, git, plan.id);\n if (conflict) {\n res.statusCode = 409;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: conflict }));\n return;\n }\n const result = agent.startForPlan(plan, prompt);\n if (!result.ok) {\n res.statusCode = 409;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: result.error }));\n return;\n }\n res.statusCode = 202;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ ok: true }));\n } catch (error) {\n res.statusCode = 500;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: (error as Error).message }));\n }\n return;\n }\n\n // POST /api/agent/launch-draft — start a headless agent that drafts a new plan from an idea\n if (req.method === 'POST' && pathname === '/api/agent/launch-draft') {\n try {\n const reqBody = await readBody(req);\n const { ideaId, prompt } = JSON.parse(reqBody) as { ideaId?: string; prompt?: string };\n if (!ideaId || !prompt) {\n res.statusCode = 400;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: 'ideaId and prompt are required' }));\n return;\n }\n const ideasDir = campFile(root, 'ideas');\n const ideas = await readAllIdeaFiles(ideasDir);\n let idea = ideas.entries.find((i) => i.id === ideaId);\n if (!idea) {\n const mono = parseIdeas(await readMaybe(campFile(root, 'ideas.md')));\n idea = mono.find((i) => i.id === ideaId);\n }\n if (!idea) {\n res.statusCode = 404;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: 'idea not found' }));\n return;\n }\n const conflict = await checkBranchConflictForPlan(root, git);\n if (conflict) {\n res.statusCode = 409;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: conflict }));\n return;\n }\n const result = agent.startForIdea(idea, prompt);\n if (!result.ok) {\n res.statusCode = 409;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: result.error }));\n return;\n }\n res.statusCode = 202;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ ok: true }));\n } catch (error) {\n res.statusCode = 500;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: (error as Error).message }));\n }\n return;\n }\n\n // POST /api/agent/launch-extend — start a headless agent to extend an idea's body\n if (req.method === 'POST' && pathname === '/api/agent/launch-extend') {\n try {\n const reqBody = await readBody(req);\n const { ideaId, prompt } = JSON.parse(reqBody) as { ideaId?: string; prompt?: string };\n if (!ideaId || !prompt) {\n res.statusCode = 400;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: 'ideaId and prompt are required' }));\n return;\n }\n const ideasDir = campFile(root, 'ideas');\n const ideas = await readAllIdeaFiles(ideasDir);\n let idea = ideas.entries.find((i) => i.id === ideaId);\n if (!idea) {\n const mono = parseIdeas(await readMaybe(campFile(root, 'ideas.md')));\n idea = mono.find((i) => i.id === ideaId);\n }\n if (!idea) {\n res.statusCode = 404;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: 'idea not found' }));\n return;\n }\n const conflict = await checkBranchConflictForPlan(root, git);\n if (conflict) {\n res.statusCode = 409;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: conflict }));\n return;\n }\n const result = agent.startForIdeaExtend(idea, prompt);\n if (!result.ok) {\n res.statusCode = 409;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: result.error }));\n return;\n }\n res.statusCode = 202;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ ok: true }));\n } catch (error) {\n res.statusCode = 500;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: (error as Error).message }));\n }\n return;\n }\n\n // POST /api/agent/launch-audit-all — start a batch convergence audit across all review/done plans\n if (req.method === 'POST' && pathname === '/api/agent/launch-audit-all') {\n // Batch audit can modify many plan files — gate it behind the same\n // active-plan guard the other write-capable agent routes use.\n const conflict = await checkBranchConflictForPlan(root, git);\n if (conflict) {\n res.statusCode = 409;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: conflict }));\n return;\n }\n const result = agent.startBatchAudit();\n if (!result.ok) {\n res.statusCode = 409;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: result.error }));\n return;\n }\n res.statusCode = 202;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ ok: true }));\n return;\n }\n\n // POST /api/agent/stop — kill the running agent task\n if (req.method === 'POST' && pathname === '/api/agent/stop') {\n const result = agent.stop();\n if (!result.ok) {\n res.statusCode = 409;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: result.error }));\n return;\n }\n res.statusCode = 202;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ ok: true }));\n return;\n }\n\n // POST /api/config — update editable fields in papercamp/config.json (port, projectName)\n if (req.method === 'POST' && pathname === '/api/config') {\n try {\n const configPath = join(root, 'papercamp', 'config.json');\n const raw = await readMaybe(configPath);\n if (!raw) {\n res.statusCode = 404;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: 'config not found' }));\n return;\n }\n const body = await readBody(req);\n const bodyParsed = JSON.parse(body) as {\n port?: number;\n projectName?: string;\n defaultAgent?: AgentId;\n defaultAgents?: Record<string, unknown>;\n };\n const { port, projectName, defaultAgent } = bodyParsed;\n const rawDefaultAgents = bodyParsed.defaultAgents;\n if (port !== undefined && (!Number.isInteger(port) || port <= 0)) {\n res.statusCode = 400;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: 'port must be a positive integer' }));\n return;\n }\n if (projectName !== undefined && projectName.trim().length === 0) {\n res.statusCode = 400;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: 'projectName must not be empty' }));\n return;\n }\n if (defaultAgent !== undefined && !AGENT_IDS.includes(defaultAgent)) {\n res.statusCode = 400;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: 'defaultAgent must be a known agent id' }));\n return;\n }\n if (rawDefaultAgents !== undefined) {\n for (const key of ['phase', 'planDraft', 'ideaExtend', 'commitSuggest'] as const) {\n const val = rawDefaultAgents[key];\n const agentId =\n typeof val === 'string' ? val : (val as Record<string, unknown> | undefined)?.agent;\n if (!agentId || !AGENT_IDS.includes(agentId as AgentId)) {\n res.statusCode = 400;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: `defaultAgents.${key} must be a known agent id` }));\n return;\n }\n }\n }\n const config = JSON.parse(raw) as PaperCampConfig;\n const defaultAgents: DefaultAgentsMap | undefined = rawDefaultAgents\n ? {\n phase: coerceAgentConfig(rawDefaultAgents.phase),\n planDraft: coerceAgentConfig(rawDefaultAgents.planDraft),\n ideaExtend: coerceAgentConfig(rawDefaultAgents.ideaExtend),\n commitSuggest: coerceAgentConfig(rawDefaultAgents.commitSuggest),\n }\n : undefined;\n const resolvedDefaultAgents: DefaultAgentsMap | undefined =\n defaultAgents ??\n (defaultAgent !== undefined\n ? {\n phase: { agent: defaultAgent },\n planDraft: { agent: defaultAgent },\n ideaExtend: { agent: defaultAgent },\n commitSuggest: { agent: defaultAgent },\n }\n : undefined);\n const configWithOld = config as PaperCampConfig & { defaultAgent?: AgentId };\n const { defaultAgent: _oldAgent, ...configRest } = configWithOld;\n const updated: PaperCampConfig = {\n ...configRest,\n ...(port !== undefined && { port }),\n ...(projectName !== undefined && { projectName: projectName.trim() }),\n ...(resolvedDefaultAgents && { defaultAgents: resolvedDefaultAgents }),\n };\n await writeFile(configPath, JSON.stringify(updated, null, 2));\n res.statusCode = 200;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ ok: true }));\n } catch (error) {\n res.statusCode = 500;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: (error as Error).message }));\n }\n return;\n }\n\n // GET /api/env — read the project root's .env, masked client-side only\n if (req.method === 'GET' && pathname === '/api/env') {\n try {\n const envPath = join(root, '.env');\n const examplePath = join(root, '.env.example');\n const [exists, exampleExists] = await Promise.all([\n fileExists(envPath),\n fileExists(examplePath),\n ]);\n const entries = exists ? parseEnv(await readMaybe(envPath)) : [];\n const exampleKeys = exampleExists\n ? parseEnv(await readMaybe(examplePath)).map((e) => e.key)\n : [];\n const envKeys = new Set(entries.map((e) => e.key));\n const missingKeys = exampleKeys.filter((key) => !envKeys.has(key));\n res.statusCode = 200;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ exists, exampleExists, entries, missingKeys }));\n } catch (error) {\n res.statusCode = 500;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: (error as Error).message }));\n }\n return;\n }\n\n // POST /api/env — write the full desired entry set back to .env\n if (req.method === 'POST' && pathname === '/api/env') {\n try {\n const body = await readBody(req);\n const { entries } = JSON.parse(body) as { entries?: EnvEntry[] };\n if (!Array.isArray(entries)) {\n res.statusCode = 400;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: 'entries is required' }));\n return;\n }\n const keys = new Set<string>();\n for (const entry of entries) {\n if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(entry.key)) {\n res.statusCode = 400;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: `invalid key: ${entry.key}` }));\n return;\n }\n if (keys.has(entry.key)) {\n res.statusCode = 400;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: `duplicate key: ${entry.key}` }));\n return;\n }\n keys.add(entry.key);\n }\n const envPath = join(root, '.env');\n const current = await readMaybe(envPath);\n await writeFile(envPath, applyEnvEntries(current, entries));\n res.statusCode = 200;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ ok: true }));\n } catch (error) {\n res.statusCode = 500;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: (error as Error).message }));\n }\n return;\n }\n\n // POST /api/open-questions/resolve?title=... — resolve an open question with a new decision\n if (req.method === 'POST' && pathname === '/api/open-questions/resolve') {\n try {\n const url = new URL(req.url ?? '', `http://${req.headers.host ?? 'localhost'}`);\n const title = url.searchParams.get('title');\n if (!title?.trim()) {\n res.statusCode = 400;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: 'title is required' }));\n return;\n }\n const body = await readBody(req);\n const { decision, rationale } = JSON.parse(body) as {\n decision?: string;\n rationale?: string;\n };\n if (!decision?.trim()) {\n res.statusCode = 400;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: 'decision is required' }));\n return;\n }\n\n // Validate everything before any writes — avoids partial state on failure.\n const questionsPath = campFile(root, 'open-questions.md');\n const raw = await readMaybe(questionsPath);\n if (!raw) {\n res.statusCode = 404;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: 'open-questions.md not found' }));\n return;\n }\n const parsed = parseOpenQuestions(raw);\n if (parsed.warnings.length > 0) {\n res.statusCode = 409;\n res.setHeader('Content-Type', 'application/json');\n res.end(\n JSON.stringify({\n error:\n 'open-questions.md has parse warnings — resolve them before updating to avoid data loss',\n warnings: parsed.warnings.map((w) => `${w.title}: ${w.message}`),\n }),\n );\n return;\n }\n const trimmed = title.trim();\n const target = parsed.entries.find((q) => q.title === trimmed);\n if (!target) {\n res.statusCode = 404;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: `open question \"${trimmed}\" not found` }));\n return;\n }\n if (target.status !== 'open') {\n res.statusCode = 409;\n res.setHeader('Content-Type', 'application/json');\n res.end(\n JSON.stringify({ error: `open question \"${trimmed}\" is already ${target.status}` }),\n );\n return;\n }\n\n // Both targets validated — now write the two files.\n const decisionBlock = formatDecisionEntry({\n title: decision.trim(),\n date: todayDateString(),\n status: 'decided',\n body: rationale?.trim(),\n });\n await appendBlock(campFile(root, 'decisions.md'), decisionBlock);\n\n target.status = 'resolved';\n target.resolvedBy = decision.trim();\n const updated = formatOpenQuestions(parsed.entries);\n await writeFile(questionsPath, `${updated}\\n`, 'utf-8');\n\n res.statusCode = 200;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ ok: true }));\n } catch (error) {\n res.statusCode = 500;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: (error as Error).message }));\n }\n return;\n }\n\n // GET /api/configs?name=... — read a specific config file's content\n if (req.method === 'GET' && pathname === '/api/configs') {\n const url = new URL(req.url ?? '', `http://${req.headers.host ?? 'localhost'}`);\n const name = url.searchParams.get('name');\n if (name) {\n try {\n if (!CONFIG_ALLOWLIST.includes(name)) {\n res.statusCode = 400;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: 'invalid config file name' }));\n return;\n }\n const content = await readMaybe(join(root, name));\n if (!content) {\n res.statusCode = 404;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: 'config file not found' }));\n return;\n }\n res.statusCode = 200;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ name, content }));\n return;\n } catch (error) {\n res.statusCode = 500;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: (error as Error).message }));\n return;\n }\n }\n // No name param: fall through to the generic route handler for listing\n }\n\n const route = apiRoutes.find((r) => r.path === pathname);\n if (!route) {\n next();\n return;\n }\n\n try {\n const data = await route.handler(root);\n res.statusCode = 200;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify(data));\n } catch (error) {\n res.statusCode = 500;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ error: (error as Error).message }));\n }\n };\n\n (handler as ApiMiddleware).agent = agent;\n return handler as ApiMiddleware;\n}\n","import { readFile, stat } from 'node:fs/promises';\nimport { type IncomingMessage, type ServerResponse, createServer } from 'node:http';\nimport { dirname, extname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { createApiMiddleware } from '../app/server/api';\n\nconst MIME: Record<string, string> = {\n '.html': 'text/html; charset=utf-8',\n '.js': 'text/javascript; charset=utf-8',\n '.mjs': 'text/javascript; charset=utf-8',\n '.css': 'text/css; charset=utf-8',\n '.json': 'application/json; charset=utf-8',\n '.svg': 'image/svg+xml',\n '.png': 'image/png',\n '.jpg': 'image/jpeg',\n '.ico': 'image/x-icon',\n '.woff': 'font/woff',\n '.woff2': 'font/woff2',\n};\n\nfunction appDir(): string {\n return join(dirname(fileURLToPath(import.meta.url)), '..', 'app');\n}\n\nexport interface DevServerOptions {\n root: string;\n port: number;\n}\n\n/**\n * Serves the pre-built dashboard SPA (dist/app) plus the papercamp/ API, for an\n * installed package where there's no Vite runtime available (it's a devDependency).\n */\nexport async function startDevServer({ root, port }: DevServerOptions): Promise<void> {\n const staticDir = appDir();\n const indexPath = join(staticDir, 'index.html');\n const indexHtml = await readFile(indexPath, 'utf-8').catch(() => null);\n if (indexHtml === null) {\n throw new Error(\n `Dashboard assets not found at ${staticDir}. Run \\`pnpm build\\` (or reinstall the package) so dist/app exists.`,\n );\n }\n\n const apiMiddleware = createApiMiddleware(root);\n\n async function serveStatic(req: IncomingMessage, res: ServerResponse) {\n const pathname = decodeURIComponent((req.url ?? '/').split('?')[0]);\n const filePath = join(staticDir, pathname === '/' ? 'index.html' : pathname);\n\n try {\n const fileStat = await stat(filePath);\n if (fileStat.isFile()) {\n res.statusCode = 200;\n res.setHeader('Content-Type', MIME[extname(filePath)] ?? 'application/octet-stream');\n res.end(await readFile(filePath));\n return;\n }\n } catch {\n // not a file on disk — fall through to the SPA fallback below\n }\n\n res.statusCode = 200;\n res.setHeader('Content-Type', 'text/html; charset=utf-8');\n res.end(indexHtml);\n }\n\n const server = createServer((req, res) => {\n apiMiddleware(req, res, () => {\n serveStatic(req, res).catch((error) => {\n res.statusCode = 500;\n res.end(String(error));\n });\n });\n });\n\n const shutdown = () => {\n apiMiddleware.agent.killCurrent();\n process.exit(0);\n };\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n\n await new Promise<void>((resolve) => server.listen(port, resolve));\n}\n","#!/usr/bin/env node\nimport { spawn } from 'node:child_process';\nimport { mkdir, readFile, stat, writeFile } from 'node:fs/promises';\nimport { basename, join, resolve } from 'node:path';\nimport { createInterface } from 'node:readline';\nimport { Command } from 'commander';\nimport { buildConvergenceAuditPrompt } from '../app/features/plans/prompts';\nimport { type AgentAdapter, resolveAgent } from '../app/server/agents/index';\nimport { deriveIdeaStatuses } from '../core/idea-status';\nimport {\n parseIdeas,\n parsePlanFile,\n parsePlans,\n readAllIdeaFiles,\n readAllPlanFiles,\n} from '../core/parser';\nimport { AlreadyInitializedError, PAPER_CAMP_VERSION, initProject } from '../core/scaffold';\nimport {\n assignPlanId,\n formatIdeaFile,\n formatIdeasIndex,\n formatPlanFile,\n formatPlansIndex,\n todayDateString,\n} from '../core/serializer';\nimport {\n type AgentRunOptions,\n DEFAULT_AGENTS,\n PLAN_KINDS,\n type PlanEntry,\n coerceAgentConfig,\n} from '../types/index';\nimport { startDevServer } from './dev-server';\n\nasync function exists(path: string): Promise<boolean> {\n try {\n await stat(path);\n return true;\n } catch {\n return false;\n }\n}\n\nasync function findPlanFile(plansDir: string, id: string): Promise<string | null> {\n const direct = join(plansDir, `${id}.md`);\n if (await exists(direct)) return direct;\n const archived = join(plansDir, 'archive', `${id}.md`);\n if (await exists(archived)) return archived;\n return null;\n}\n\nasync function getFileMtimeDateString(filePath: string): Promise<string | null> {\n try {\n const s = await stat(filePath);\n return s.mtime.toISOString().slice(0, 10);\n } catch {\n return null;\n }\n}\n\nasync function stampCliAuditDate(planFile: string, planId: string): Promise<void> {\n // Throw on failure so the caller can mark the audit failed rather than\n // logging [done] while the audited stamp was silently never written.\n const raw = await readFile(planFile, 'utf-8');\n const parsed = parsePlanFile(raw);\n const entry = parsed.entries[0];\n if (!entry) {\n throw new Error(`Could not parse plan file after audit: ${planFile}`);\n }\n const writeInput: Parameters<typeof formatPlanFile>[0] = {\n id: planId,\n title: entry.title,\n kind: entry.kind ?? 'feat',\n status: entry.status,\n idea: entry.idea,\n agent: entry.agent,\n created: entry.created,\n updated: entry.updated,\n audited: todayDateString(),\n tags: entry.tags,\n body: entry.body,\n phases: entry.phases,\n log: entry.log,\n clarifications: entry.clarifications,\n };\n await writeFile(planFile, `${formatPlanFile(writeInput)}\\n`, 'utf-8');\n}\n\nasync function runPlanAudit(\n root: string,\n plan: PlanEntry,\n adapter: AgentAdapter,\n opts?: AgentRunOptions,\n): Promise<boolean> {\n const prompt = buildConvergenceAuditPrompt(plan);\n const proc = spawn(adapter.command, adapter.buildArgs(prompt, opts), {\n cwd: root,\n stdio: ['ignore', 'pipe', 'pipe'],\n });\n\n if (proc.stdout) {\n const rl = createInterface({ input: proc.stdout });\n rl.on('line', (line) => {\n const parsed = adapter.parseLine(line);\n if (parsed?.text && parsed.text !== 'Agent is working…') {\n process.stdout.write(` ${parsed.text}\\n`);\n }\n });\n }\n proc.stderr?.on('data', (d: Buffer) => process.stderr.write(d));\n\n return new Promise((resolve) => {\n proc.on('close', (code) => resolve(code === 0));\n proc.on('error', () => resolve(false));\n });\n}\n\nconst program = new Command();\n\nprogram\n .name('paper-camp')\n .description('Local-first, AI-native project companion.')\n .version(PAPER_CAMP_VERSION);\n\nprogram\n .command('init [project-name]')\n .description('Initialize Paper Camp in the current directory')\n .option('-i, --intent <text>', 'one-line description of what you are building')\n .action(async (projectName: string | undefined, opts: { intent?: string }) => {\n const targetDir = process.cwd();\n const name = projectName ?? basename(targetDir);\n try {\n await initProject(targetDir, { projectName: name, intent: opts.intent });\n console.log(`Initialized Paper Camp in ${targetDir}`);\n console.log(' papercamp/config.json');\n console.log(' papercamp/plans/ (per-file plan entries)');\n console.log(' papercamp/plans/index.md');\n console.log(' papercamp/plans/archive/');\n console.log(' papercamp/ideas/ (per-file idea entries)');\n console.log(' papercamp/ideas/index.md');\n console.log(' papercamp/progress.md, decisions.md, open-questions.md');\n } catch (error) {\n if (error instanceof AlreadyInitializedError) {\n console.error(error.message);\n process.exitCode = 1;\n return;\n }\n throw error;\n }\n });\n\nprogram\n .command('dev')\n .description('Start the local dashboard')\n .option('-p, --port <number>', 'port to listen on', '3333')\n .action(async (opts: { port: string }) => {\n const port = Number(opts.port);\n const root = process.cwd();\n try {\n await startDevServer({ root, port });\n console.log(`Paper Camp dashboard running at http://localhost:${port}`);\n } catch (error) {\n console.error((error as Error).message);\n process.exitCode = 1;\n }\n });\n\nprogram\n .command('add <type> [name]')\n .description('Add a new entry (currently supports: plan)')\n .option('-k, --kind <kind>', `plan kind (${PLAN_KINDS.join('|')})`, 'feat')\n .action(async (type: string, name: string | undefined, opts: { kind: string }) => {\n if (type !== 'plan') {\n console.error(`Unknown type \"${type}\". Supported types: plan`);\n process.exitCode = 1;\n return;\n }\n if (!name) {\n console.error('Usage: paper-camp add plan <name> [--kind feat|fix|chore|docs|refactor]');\n process.exitCode = 1;\n return;\n }\n if (!PLAN_KINDS.includes(opts.kind as (typeof PLAN_KINDS)[number])) {\n console.error(`Unknown kind \"${opts.kind}\". Supported kinds: ${PLAN_KINDS.join(', ')}`);\n process.exitCode = 1;\n return;\n }\n\n const kind = opts.kind;\n const root = process.cwd();\n const configPath = resolve(root, 'papercamp', 'config.json');\n const id = await assignPlanId(configPath, kind);\n\n if (!id) {\n console.error('Could not assign plan ID — is the project initialized?');\n process.exitCode = 1;\n return;\n }\n\n const plansDir = resolve(root, 'papercamp', 'plans');\n await mkdir(plansDir, { recursive: true });\n\n const planContent = formatPlanFile({\n id,\n title: name,\n kind,\n status: 'idea',\n created: todayDateString(),\n });\n await writeFile(join(plansDir, `${id}.md`), `${planContent}\\n`, 'utf-8');\n\n // Regenerate index\n const { entries } = await readAllPlanFiles(plansDir);\n await writeFile(join(plansDir, 'index.md'), formatPlansIndex(entries), 'utf-8');\n\n console.log(`Added plan \"${name}\" (${id}) to papercamp/plans/${id}.md`);\n });\n\nprogram\n .command('migrate')\n .description(\n 'One-time migration: split monolithic plans.md/ideas.md into per-file YAML frontmatter entries',\n )\n .action(async () => {\n const root = process.cwd();\n const plansDir = resolve(root, 'papercamp', 'plans');\n const archiveDir = join(plansDir, 'archive');\n const ideasDir = resolve(root, 'papercamp', 'ideas');\n await mkdir(archiveDir, { recursive: true });\n await mkdir(ideasDir, { recursive: true });\n\n const plansPath = resolve(root, 'papercamp', 'plans.md');\n const ideasPath = resolve(root, 'papercamp', 'ideas.md');\n\n let migratedPlans = 0;\n let skippedPlans = 0;\n let planWarnings = 0;\n const plansRaw = await readFile(plansPath, 'utf-8').catch(() => '');\n if (plansRaw.trim()) {\n const { entries, warnings } = parsePlans(plansRaw);\n planWarnings = warnings.length;\n for (const warning of warnings) {\n console.warn(` warning: ${warning.title}: ${warning.message}`);\n }\n for (const entry of entries) {\n if (!entry.id) {\n console.warn(` skipping plan \"${entry.title}\" — no Id assigned, cannot migrate`);\n skippedPlans++;\n continue;\n }\n const targetDir =\n entry.status === 'done' || entry.status === 'dropped' ? archiveDir : plansDir;\n const targetFile = join(targetDir, `${entry.id}.md`);\n if (await exists(targetFile)) {\n skippedPlans++;\n continue;\n }\n const content = formatPlanFile({\n id: entry.id,\n title: entry.title,\n kind: entry.kind ?? 'feat',\n status: entry.status,\n idea: entry.idea,\n agent: entry.agent,\n created: entry.created,\n updated: entry.updated,\n tags: entry.tags,\n body: entry.body,\n phases: entry.phases,\n log: entry.log,\n clarifications: entry.clarifications,\n });\n await writeFile(targetFile, `${content}\\n`, 'utf-8');\n migratedPlans++;\n }\n }\n\n let migratedIdeas = 0;\n let skippedIdeas = 0;\n const ideasRaw = await readFile(ideasPath, 'utf-8').catch(() => '');\n if (ideasRaw.trim()) {\n const entries = parseIdeas(ideasRaw);\n for (const idea of entries) {\n if (!idea.id) {\n console.warn(` skipping idea \"${idea.title}\" — no Id assigned, cannot migrate`);\n skippedIdeas++;\n continue;\n }\n const targetFile = join(ideasDir, `${idea.id}.md`);\n if (await exists(targetFile)) {\n skippedIdeas++;\n continue;\n }\n const body = idea.body.replace(/^#{1,3}\\s+.+(?:\\r?\\n)?/, '').trim();\n const content = formatIdeaFile({ id: idea.id, title: idea.title, body });\n await writeFile(targetFile, `${content}\\n`, 'utf-8');\n migratedIdeas++;\n }\n }\n\n const { entries: allPlans } = await readAllPlanFiles(plansDir);\n await writeFile(join(plansDir, 'index.md'), formatPlansIndex(allPlans), 'utf-8');\n const { entries: allIdeas } = await readAllIdeaFiles(ideasDir);\n const ideasWithStatus = deriveIdeaStatuses(allIdeas, allPlans);\n await writeFile(join(ideasDir, 'index.md'), formatIdeasIndex(ideasWithStatus), 'utf-8');\n\n // Empty, not a pointer comment: readPlansMerged/readIdeasMerged fast-path on falsy\n // monolithic content, and parseIdeas() in particular has no heading match for plain\n // prose, producing a phantom null-id entry that the merge step's dedup logic always\n // keeps. A truly empty file avoids both parsers entirely.\n if (migratedPlans > 0 && skippedPlans === 0 && planWarnings === 0) {\n await writeFile(plansPath, '', 'utf-8');\n }\n if (migratedIdeas > 0 && skippedIdeas === 0) {\n await writeFile(ideasPath, '', 'utf-8');\n }\n\n console.log(\n `Migrated ${migratedPlans} plans (${skippedPlans} skipped), ${migratedIdeas} ideas (${skippedIdeas} skipped).`,\n );\n });\n\nprogram\n .command('audit')\n .description('Audit all review/done plans for missing phases')\n .action(async () => {\n const root = process.cwd();\n const plansDir = resolve(root, 'papercamp', 'plans');\n\n const { entries, warnings } = await readAllPlanFiles(plansDir);\n\n for (const warning of warnings) {\n console.warn(` warning: ${warning.title}: ${warning.message}`);\n }\n\n const candidates = entries.filter((p) => p.status === 'review' || p.status === 'done');\n\n if (candidates.length === 0) {\n console.log('No plans with status \"review\" or \"done\" found.');\n return;\n }\n\n const configRaw = await readFile(join(root, 'papercamp', 'config.json'), 'utf-8').catch(\n () => '{}',\n );\n let config: {\n defaultAgents?: Record<string, unknown>;\n defaultAgent?: string;\n };\n try {\n config = JSON.parse(configRaw) as typeof config;\n } catch {\n console.error('Invalid papercamp/config.json');\n process.exitCode = 1;\n return;\n }\n const rawAgents = config.defaultAgents;\n const defaultAgents = rawAgents\n ? {\n phase: coerceAgentConfig(rawAgents.phase),\n planDraft: coerceAgentConfig(rawAgents.planDraft),\n ideaExtend: coerceAgentConfig(rawAgents.ideaExtend),\n commitSuggest: coerceAgentConfig(rawAgents.commitSuggest),\n }\n : DEFAULT_AGENTS;\n const { adapter, model, effort } = resolveAgent({ defaultAgents, taskKind: 'audit' });\n\n console.log(`Auditing ${candidates.length} plan(s):\\n`);\n\n interface AuditResult {\n id: string;\n title: string;\n status: 'audited' | 'skipped' | 'failed';\n gapPhases?: number;\n skipReason?: string;\n }\n\n const results: AuditResult[] = [];\n\n for (const plan of candidates) {\n const id = plan.id ?? '(no id)';\n const label = id.padEnd(14);\n\n if (!plan.id) {\n console.log(` [skip] ${label} ${plan.title} — no id`);\n results.push({ id, title: plan.title, status: 'skipped', skipReason: 'no id' });\n continue;\n }\n\n const planFile = await findPlanFile(plansDir, plan.id);\n if (!planFile) {\n console.log(` [skip] ${label} ${plan.title} — file not found`);\n results.push({ id, title: plan.title, status: 'skipped', skipReason: 'file not found' });\n continue;\n }\n\n if (plan.audited) {\n const mtimeDate = await getFileMtimeDateString(planFile);\n if (mtimeDate && plan.audited >= mtimeDate) {\n console.log(\n ` [skip] ${label} ${plan.title} — audited ${plan.audited}, unchanged since`,\n );\n results.push({\n id,\n title: plan.title,\n status: 'skipped',\n skipReason: `audited ${plan.audited}, unchanged`,\n });\n continue;\n }\n }\n\n const phasesBefore = plan.phases.length;\n\n console.log(` [audit] ${label} ${plan.title}`);\n const success = await runPlanAudit(root, plan, adapter, { model, effort });\n\n if (success) {\n try {\n await stampCliAuditDate(planFile, plan.id);\n } catch (err) {\n console.log(` [fail] ${label} ${plan.title} — ${(err as Error).message}`);\n process.exitCode = 1;\n results.push({ id, title: plan.title, status: 'failed' });\n continue;\n }\n\n const afterRaw = await readFile(planFile, 'utf-8').catch(() => '');\n const afterParsed = parsePlanFile(afterRaw);\n const phasesAfter = afterParsed.entries[0]?.phases.length ?? phasesBefore;\n const gapPhases = Math.max(0, phasesAfter - phasesBefore);\n\n console.log(` [done] ${label} ${plan.title}`);\n results.push({ id, title: plan.title, status: 'audited', gapPhases });\n } else {\n console.log(` [fail] ${label} ${plan.title} — agent exited with error`);\n process.exitCode = 1;\n results.push({ id, title: plan.title, status: 'failed' });\n }\n }\n\n const audited = results.filter((r) => r.status === 'audited');\n const skipped = results.filter((r) => r.status === 'skipped');\n const failed = results.filter((r) => r.status === 'failed');\n const totalGaps = audited.reduce((sum, r) => sum + (r.gapPhases ?? 0), 0);\n const bar = '─'.repeat(43);\n\n console.log(`\\n${bar}`);\n console.log('Audit summary');\n console.log(\n ` Audited : ${audited.length} Skipped : ${skipped.length} Failed : ${failed.length}`,\n );\n if (audited.length > 0) {\n if (totalGaps > 0) {\n console.log(` Gap phases appended: ${totalGaps} total`);\n for (const r of audited.filter((r) => (r.gapPhases ?? 0) > 0)) {\n console.log(` ${r.id.padEnd(14)} +${r.gapPhases} phase(s)`);\n }\n } else {\n console.log(' No gap phases appended — all audited plans are complete.');\n }\n }\n if (skipped.length > 0) {\n console.log(' Skipped:');\n for (const r of skipped) {\n console.log(` ${r.id.padEnd(14)} ${r.skipReason}`);\n }\n }\n console.log(bar);\n });\n\nprogram.parseAsync(process.argv);\n"],"names":["buildConvergenceAuditPrompt","plan","phaseList","phase","i","logList","entry","clarificationsList","buildArgs","prompt","opts","args","parseLine","line","json","message","blocks","block","b","content","error","TOOL_LABELS","type","part","text","tool","input","desc","label","detail","reason","DEFAULT_AGENT_ID","AGENTS","claudeCode.buildArgs","claudeCode.parseLine","AGENT_OPTIONS","opencode.buildArgs","opencode.parseLine","TASK_KIND_TO_DEFAULT_KEY","resolveAgent","agentId","defaultAgents","taskKind","key","fallback","id","deriveIdeaStatuses","ideas","plans","idea","linkedPlans","p","allDone","findFocusPlan","activePlanTitle","createActivityManager","root","clients","timer","broadcast","data","client","watch","join","res","connected","MAX_LINES","readDefaultAgentIds","raw","readFileSync","config","rawAgents","coerceAgentConfig","DEFAULT_AGENTS","buildAgentPrompt","phaseIndex","createAgentManager","ensureBranch","onAuditComplete","current","pushLine","task","setStatus","status","didTaskProgress","ideasDir","entries","readIdeasMerged","e","plansDir","readPlansMerged","_a","_b","finishTask","progressed","warning","attachReader","createInterface","parsed","code","err","spawnAgent","adapter","spawn","isBusy","launch","identity","scope","model","effort","proc","start","startForPlan","startForIdea","startForIdeaExtend","findBatchPlanFile","direct","stat","archived","startBatchAudit","stubProc","readAllPlanFiles","candidates","audited","skipped","failed","planFile","fileStat","mtimeDate","success","resolve","gapPhases","rawAfter","readFile","afterCount","parsePlanFile","COMMIT_SUGGEST_TIMEOUT_MS","STDIN_MAX_BYTES","runCommitSuggest","isClaude","reject","settled","settle","fn","timeout","_c","stdout","stderr","_d","d","_e","result","evt","errText","stop","getStatus","buildPrompt","diffText","planContext","suggestCommitMessage","runPrompt","output","resultText","match","AI_DIFF_BLOCKLIST","toLiteralPathspec","file","createGitManager","event","parsePorcelain","x","y","rest","parts","path","runGit","runGitStatus","commit","files","title","statusEntries","statusByPath","toAdd","f","kind","branch","currentResult","spawnSync","checkoutResult","refresh","gitDir","eventType","filename","srcDir","srcTimer","hasUpstream","getAheadCount","push","getCurrentBranch","getFeatureBranchPlanId","diff","maxChars","blocked","pattern","untracked","renameSources","tracked","source","trackedDiff","filePath","stats","lstat","combined","CHECK_COMMANDS","createStatusManager","snapshot","running","queued","setResult","name","runCheck","cmd","runQualityFix","readMaybe","fileExists","readBody","req","body","chunk","campFile","CONFIG_ALLOWLIST","checkBranchConflictForPlan","git","targetPlanId","activePlanId","activePlan","regenerateIndexes","plansResult","ideasResult","ideasWithStatus","mkdir","writeFile","formatPlansIndex","formatIdeasIndex","apiRoutes","parseProgress","parseDecisions","parseOpenQuestions","decisionsRaw","openQuestionsRaw","decisions","openQuestions","findConsistencyIssues","docNames","configNames","createApiMiddleware","activity","prependProgressItem","item","progressPath","heading","todayDateString","trimmed","next","stampAuditDate","planId","directPlanFile","archivedPlanFile","writeInput","formatPlanFile","agent","handler","pathname","target","unlink","planKind","PLAN_KINDS","configPath","assignPlanId","planContent","reqBody","updates","AGENT_IDS","targetFile","updatedEntry","conflict","allPlans","other","otherFile","otherRaw","otherParsed","demotedInput","archivePlanFile","newId","max","num","ideaContent","formatIdeaFile","assetsDir","mimeMap","ext","mime","dataUri","buffer","ahead","suggestion","monoPlan","parsePlans","ideaId","readAllIdeaFiles","parseIdeas","bodyParsed","port","projectName","defaultAgent","rawDefaultAgents","val","resolvedDefaultAgents","configWithOld","_oldAgent","configRest","updated","envPath","examplePath","exists","exampleExists","parseEnv","exampleKeys","envKeys","missingKeys","keys","applyEnvEntries","decision","rationale","questionsPath","w","q","decisionBlock","formatDecisionEntry","appendBlock","formatOpenQuestions","route","MIME","appDir","dirname","fileURLToPath","startDevServer","staticDir","indexPath","indexHtml","apiMiddleware","serveStatic","extname","server","createServer","shutdown","findPlanFile","getFileMtimeDateString","stampCliAuditDate","runPlanAudit","program","Command","PAPER_CAMP_VERSION","targetDir","basename","initProject","AlreadyInitializedError","archiveDir","plansPath","ideasPath","migratedPlans","skippedPlans","planWarnings","plansRaw","warnings","migratedIdeas","skippedIdeas","ideasRaw","allIdeas","configRaw","results","phasesBefore","afterRaw","phasesAfter","r","totalGaps","sum","bar"],"mappings":"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"}
|