nightralph 0.0.7 → 0.0.9
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 +2 -1
- package/dist/demo-display.js +298 -0
- package/dist/display.js +280 -0
- package/dist/display.js.map +7 -0
- package/dist/index.js +6 -2
- package/dist/index.js.map +2 -2
- package/dist/meta.json +49 -8
- package/dist/orchestrator.js +158 -60
- package/dist/orchestrator.js.map +2 -2
- package/dist/src/display.d.ts +69 -0
- package/dist/src/display.d.ts.map +1 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/orchestrator.d.ts +12 -3
- package/dist/src/orchestrator.d.ts.map +1 -1
- package/package.json +3 -3
package/dist/orchestrator.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/orchestrator.ts"],
|
|
4
|
-
"sourcesContent": ["import { spawn } from 'node:child_process'\nimport {\n createWriteStream,\n mkdirSync,\n readFileSync,\n writeFileSync,\n unlinkSync,\n readdirSync,\n} from 'node:fs'\nimport { tmpdir } from 'node:os'\nimport { join, dirname, basename } from 'node:path'\nimport { createInterface } from 'node:readline'\nimport {\n getRepoRoot,\n getRepoName,\n getCurrentBranch,\n createWorktree,\n removeWorktree,\n hasNewCommits,\n isDirty,\n commitDirty,\n} from './worktree.js'\nimport {\n generateProgress,\n readProgress,\n mergeProgress,\n writeProgress,\n commitProgress,\n checkTicket,\n type ProgressData,\n} from './progress.js'\nimport {\n mergeBranch,\n mergeWave,\n updateWorktreeFromBase,\n type MergeConflictStrategy,\n} from './merge.js'\n\nexport type Ticket = {\n num:number\n slug:string\n filename:string\n filepath:string\n body:string\n status:string\n blockers:number[]\n}\n\nexport function formatErrorMessage (error:unknown):string {\n return error instanceof Error ?\n error.message :\n String(error)\n}\n\nexport const TICKET_RE = /^(\\d+)-(.+)\\.md$/\n\nexport function parseTicketFilename (\n filename:string\n):{ num:number; slug:string }|null {\n const m = filename.match(TICKET_RE)\n if (!m) return null\n return { num:Number(m[1]), slug:m[2] }\n}\n\nexport function parseStatus (body:string):string {\n const m = body.match(/\\*\\*Status:\\*\\*\\s*(.+)/i)\n return m ? m[1].trim().toLowerCase() : ''\n}\n\nexport function parseBlockers (body:string):number[] {\n const m = body.match(/\\*\\*Blocked by:\\*\\*\\s*(.+)/i)\n if (!m) return []\n const text = m[1]\n if (/none/i.test(text)) return []\n const nums:number[] = []\n const re = /(\\d+)/g\n let match\n while ((match = re.exec(text))) {\n nums.push(Number(match[1]))\n }\n return nums\n}\n\nexport function scanTickets (dir:string):Ticket[] {\n const files = readdirSync(dir)\n .filter(f => TICKET_RE.test(f))\n .sort((a, b) => a.localeCompare(\n b,\n undefined,\n { numeric:true, sensitivity:'base' }\n ))\n\n return files.map(filename => {\n const parsed = parseTicketFilename(filename)!\n const filepath = join(dir, filename)\n const body = readFileSync(filepath, 'utf8')\n return {\n num:parsed.num,\n slug:parsed.slug,\n filename,\n filepath,\n body,\n status:parseStatus(body),\n blockers:parseBlockers(body),\n }\n })\n}\n\nexport function findReadyTickets (\n tickets:ReadonlyArray<Ticket>\n):Ticket[] {\n const doneNums = new Set(\n tickets\n .filter(t => t.status === 'done')\n .map(t => t.num)\n )\n return tickets.filter(t => {\n if (t.status !== 'ready-for-agent') return false\n return t.blockers.every(b => doneNums.has(b))\n })\n}\n\nexport function markDone (ticket:Ticket):void {\n const updated = ticket.body.replace(\n /\\*\\*Status:\\*\\*\\s*.+/i,\n '**Status:** done'\n )\n writeFileSync(ticket.filepath, updated)\n ticket.status = 'done'\n ticket.body = updated\n}\n\nexport function renderPrompt (\n specBody:string,\n ticket:Ticket\n):string {\n return [\n '---- SPEC CONTEXT ----',\n specBody,\n '',\n '---- TICKET ----',\n ticket.filename,\n ticket.body,\n '',\n '---- AGENT INSTRUCTIONS ----',\n 'You are an autonomous coding agent. ' +\n 'Implement the ticket.',\n '',\n 'Time is limited. Follow these rules:',\n '- Spend at most 2 minutes reading existing ' +\n 'code. Read only the files directly relevant ' +\n 'to the ticket.',\n '- Do NOT research external APIs or services ' +\n 'via web search. Use the spec and ticket ' +\n 'body as your sole reference for API shapes.',\n '- Start writing code as soon as you understand ' +\n 'the immediate context. You can read more ' +\n 'files as needed while implementing.',\n '- Commit your work when finished.',\n '',\n ].join('\\n')\n}\n\nfunction listTickets (tickets:ReadonlyArray<Ticket>):void {\n console.log('\\nTickets:')\n for (const t of tickets) {\n const blockerStr = t.blockers.length > 0 ?\n `blocked by [${t.blockers.join(', ')}]` :\n 'no blockers'\n console.log(\n ` ${t.filename} ` +\n `(${t.status}) ${blockerStr}`\n )\n }\n}\n\nfunction * simulateWaves (\n tickets:ReadonlyArray<Ticket>\n):Generator<{ wave:number; ready:Array<Ticket> }> {\n const sim = new Map(\n tickets.map(t => [t.num, t.status])\n )\n let wave = 1\n while (true) {\n const doneNums = new Set(\n [...sim.entries()]\n .filter(([, s]) => s === 'done')\n .map(([n]) => n)\n )\n const ready = [...tickets].filter(t => {\n if (sim.get(t.num) !== 'ready-for-agent') {\n return false\n }\n return t.blockers.every(\n b => doneNums.has(b)\n )\n })\n if (ready.length === 0) break\n yield { wave, ready }\n for (const t of ready) {\n sim.set(t.num, 'done')\n }\n wave++\n }\n}\n\nfunction detectDeadlocks (\n tickets:ReadonlyArray<Ticket>\n):Array<Ticket> {\n const doneNums = new Set<number>()\n const ready = new Set<number>()\n\n for (const t of tickets) {\n if (t.status === 'ready-for-agent') {\n ready.add(t.num)\n } else if (t.status === 'done') {\n doneNums.add(t.num)\n }\n }\n\n let changed = true\n while (changed) {\n changed = false\n for (const num of ready) {\n const ticket = tickets.find(t =>\n t.num === num\n )!\n if (ticket.blockers.every(\n b => doneNums.has(b)\n )) {\n doneNums.add(num)\n ready.delete(num)\n changed = true\n }\n }\n }\n\n return [...ready].map(num =>\n tickets.find(t => t.num === num)!\n )\n}\n\nconst PROVIDER_ARGS:Record<string, string[]> = {\n claude:[\n '--print', '--verbose',\n '--output-format', 'stream-json',\n '--dangerously-skip-permissions',\n ],\n codex:['exec', '--full-auto'],\n pi:[\n '-p', '--verbose',\n '--approve', '--no-session',\n '--mode', 'json',\n ],\n}\n\nexport function getProviderArgs (cmd:string):string[] {\n const name = basename(cmd)\n return PROVIDER_ARGS[name] ?? []\n}\n\nexport function formatStreamLine (\n line:string\n):string|null {\n let obj:Record<string, unknown>\n try {\n obj = JSON.parse(line) as Record<string, unknown>\n } catch {\n return line\n }\n\n if (obj.type === 'assistant') {\n const msg = obj.message as\n Record<string, unknown>|undefined\n const content = msg?.content as\n Array<Record<string, unknown>>|undefined\n if (!content) return null\n for (const block of content) {\n if (block.type === 'text') {\n return String(block.text)\n }\n }\n return null\n }\n\n if (obj.type === 'result') {\n const sub = obj.subtype as string|undefined ?? 'done'\n const cost = obj.total_cost_usd as number|undefined\n const costStr = cost != null ?\n ` ($${cost.toFixed(2)})` :\n ''\n return `${sub}${costStr}`\n }\n\n if (obj.type === 'system') {\n const sub = obj.subtype as string|undefined\n if (sub === 'api_retry') {\n const error = obj.error as string|undefined\n return `retry: ${error ?? 'unknown'}`\n }\n }\n\n return null\n}\n\nexport function createPiStreamFormatter (\n):(line:string) => string|null {\n const calls = new Map<\n number,\n { name:string; buf:string }\n >()\n let toolNum = 0\n\n return (line:string):string|null => {\n let obj:Record<string, unknown>\n try {\n obj = JSON.parse(line) as\n Record<string, unknown>\n } catch {\n return line\n }\n\n const evt = obj.assistantMessageEvent as\n Record<string, unknown>|undefined\n if (!evt) return null\n\n const type = evt.type as string|undefined\n const ci = evt.contentIndex as\n number|undefined ?? -1\n\n if (type === 'text_delta') {\n return (evt.delta as string|undefined) ??\n null\n }\n\n if (type === 'toolcall_start') {\n toolNum++\n calls.set(ci, {\n name:(evt.toolName as\n string|undefined) ?? '?',\n buf:'',\n })\n return null\n }\n\n if (\n type === 'toolcall_delta' &&\n calls.has(ci)\n ) {\n calls.get(ci)!.buf +=\n (evt.delta as string|undefined) ?? ''\n return null\n }\n\n if (\n type === 'toolcall_end' &&\n calls.has(ci)\n ) {\n const call = calls.get(ci)!\n calls.delete(ci)\n let label = ''\n try {\n const args = JSON.parse(call.buf) as\n Record<string, unknown>\n label = String(\n args.command ??\n args.file_path ??\n args.query ?? ''\n ).split('\\n')[0].slice(0, 72)\n } catch {\n // unparseable tool args\n }\n return `[${call.name}] ${label}`\n }\n\n return null\n }\n}\n\nfunction writePromptFile (prompt:string):string {\n const name = `nightralph-${Date.now()}-` +\n `${Math.random().toString(36).slice(2)}.md`\n const filePath = join(tmpdir(), name)\n writeFileSync(filePath, prompt)\n return filePath\n}\n\nfunction cleanupPromptFile (filePath:string):void {\n try {\n unlinkSync(filePath)\n } catch {\n // already removed\n }\n}\n\nexport function spawnAgent (opts:{\n prompt:string\n agentCmd:string\n model:string|null\n timeout:number\n logPath:string\n cwd?:string\n label?:string\n}):Promise<number> {\n const args:string[] = [\n ...getProviderArgs(opts.agentCmd),\n ]\n if (opts.model) {\n args.push('--model', opts.model)\n }\n\n const providerName = basename(opts.agentCmd)\n const isClaude = providerName === 'claude'\n const isPi = providerName === 'pi'\n const prefix = opts.label ?\n ` [${opts.label}] ` :\n ' '\n\n let promptFile:string|null = null\n if (isPi) {\n promptFile = writePromptFile(opts.prompt)\n args.push(`@${promptFile}`)\n }\n\n const logStream = createWriteStream(\n opts.logPath,\n { flags:'w' }\n )\n const proc = spawn(opts.agentCmd, args, {\n stdio:['pipe', 'pipe', 'pipe'],\n cwd:opts.cwd,\n })\n\n proc.stdout.pipe(logStream)\n\n const piFormatter = isPi ?\n createPiStreamFormatter() :\n null\n\n const rl = createInterface({ input:proc.stdout })\n rl.on('line', line => {\n if (isClaude) {\n const formatted = formatStreamLine(line)\n if (formatted !== null) {\n console.log(`${prefix}${formatted}`)\n }\n } else if (piFormatter) {\n const formatted = piFormatter(line)\n if (formatted !== null) {\n console.log(`${prefix}${formatted}`)\n }\n } else {\n console.log(`${prefix}${line}`)\n }\n })\n\n proc.stderr.pipe(logStream)\n const rlErr = createInterface({ input:proc.stderr })\n rlErr.on('line', line => {\n console.error(`${prefix}${line}`)\n })\n\n const timeout = setTimeout(() => {\n if (!proc.killed) {\n console.warn(\n 'Agent did not exit in ' +\n `${opts.timeout}s; killing.`\n )\n proc.kill('SIGKILL')\n }\n }, opts.timeout * 1000)\n\n if (!promptFile) {\n proc.stdin.write(opts.prompt)\n }\n proc.stdin.end()\n\n return new Promise<number>(resolve => {\n proc.on('close', code => {\n clearTimeout(timeout)\n rl.close()\n rlErr.close()\n logStream.end()\n if (promptFile) cleanupPromptFile(promptFile)\n resolve(code ?? 1)\n })\n proc.on('error', err => {\n clearTimeout(timeout)\n rl.close()\n rlErr.close()\n logStream.end()\n if (promptFile) cleanupPromptFile(promptFile)\n console.error(\n 'Agent process error:',\n formatErrorMessage(err)\n )\n resolve(1)\n })\n })\n}\n\nexport function dryRun (\n tickets:Array<Ticket>,\n specBody:string\n):void {\n listTickets(tickets)\n\n console.log('\\nSimulated wave order:')\n for (const { wave, ready } of simulateWaves(tickets)) {\n console.log(\n ` Wave ${wave}: ` +\n ready.map(t => t.filename).join(', ')\n )\n }\n\n const stuck = detectDeadlocks(tickets)\n if (stuck.length > 0) {\n console.log(\n '\\nDeadlocked tickets: ' +\n stuck.map(t => t.filename).join(', ')\n )\n }\n\n const firstReady = findReadyTickets(tickets)\n if (firstReady.length > 0) {\n console.log(\n '\\nPrompt for first ready ticket ' +\n `(${firstReady[0].filename}):\\n`\n )\n console.log(\n renderPrompt(specBody, firstReady[0])\n )\n }\n}\n\nexport function dryRunIsolated (opts:{\n tickets:Array<Ticket>\n specBody:string\n repoName:string\n conflictStrategy:MergeConflictStrategy\n progressPath:string\n}):void {\n listTickets(opts.tickets)\n\n console.log('\\nSimulated wave order:')\n for (const { wave, ready } of simulateWaves(\n opts.tickets\n )) {\n console.log(\n ` Wave ${wave}: ` +\n ready.map(t => t.filename).join(', ')\n )\n for (const t of ready) {\n const num = String(t.num).padStart(2, '0')\n const branchName =\n `${opts.repoName}/${num}-${t.slug}`\n const worktreePath =\n `../${opts.repoName}.${num}-${t.slug}`\n console.log(` worktree: ${worktreePath}`)\n console.log(` branch: ${branchName}`)\n }\n }\n\n const stuck = detectDeadlocks(opts.tickets)\n if (stuck.length > 0) {\n console.log(\n '\\nDeadlocked tickets: ' +\n stuck.map(t => t.filename).join(', ')\n )\n }\n\n const firstReady = findReadyTickets(opts.tickets)\n if (firstReady.length > 0) {\n console.log(\n '\\nPrompt for first ready ticket ' +\n `(${firstReady[0].filename}):\\n`\n )\n console.log(\n renderPrompt(opts.specBody, firstReady[0])\n )\n }\n\n const strategyDesc =\n opts.conflictStrategy === 'respawn' ?\n 'respawn (re-run agent on conflict)' :\n 'stop (stop merging on conflict)'\n console.log(\n `\\nMerge strategy: ${strategyDesc}`\n )\n console.log(`Progress file: ${opts.progressPath}`)\n}\n\n// Re-runs the agent in a ticket's existing worktree\n// after a merge conflict, then retries the merge once.\n// Called at most once per ticket per wave.\nasync function respawnAndRetryMerge (opts:{\n repoRoot:string\n baseBranch:string\n branch:string\n ticket:Ticket\n worktreePath:string\n specBody:string\n agentCmd:string\n model:string|null\n timeout:number\n logsDir:string\n}):Promise<boolean> {\n await updateWorktreeFromBase(\n opts.worktreePath, opts.baseBranch\n )\n\n console.log(\n ` ${opts.ticket.filename}: respawning agent ` +\n 'to resolve merge conflict'\n )\n const prompt = renderPrompt(opts.specBody, opts.ticket)\n const logPath = join(\n opts.logsDir,\n opts.ticket.filename.replace(/\\.md$/, '.respawn.log')\n )\n const label = opts.ticket.filename.replace(\n /\\.md$/, ''\n )\n const exitCode = await spawnAgent({\n prompt,\n agentCmd:opts.agentCmd,\n model:opts.model,\n timeout:opts.timeout,\n logPath,\n cwd:opts.worktreePath,\n label,\n })\n\n if (exitCode !== 0) {\n console.log(\n ` ${opts.ticket.filename}: respawned agent ` +\n `exited ${exitCode}`\n )\n return false\n }\n\n const merged = await mergeBranch(\n opts.repoRoot, opts.branch\n )\n if (!merged) {\n console.log(\n ` ${opts.ticket.filename}: merge still ` +\n 'conflicted after respawn'\n )\n }\n return merged\n}\n\nexport async function runWaves (\n tickets:Ticket[],\n specBody:string,\n agentCmd:string,\n model:string|null,\n timeout:number,\n logsDir:string,\n):Promise<{ allDone:boolean }> {\n mkdirSync(logsDir, { recursive:true })\n\n let totalCompleted = 0\n let waveNum = 0\n\n while (true) {\n const ready = findReadyTickets(tickets)\n if (ready.length === 0) break\n\n waveNum++\n console.log(\n `\\nWave ${waveNum}: ` +\n ready.map(t => t.filename).join(', ')\n )\n\n const results = await Promise.allSettled(\n ready.map(async t => {\n const prompt = renderPrompt(specBody, t)\n const logPath = join(\n logsDir,\n t.filename.replace(/\\.md$/, '.log')\n )\n const label = t.filename.replace(\n /\\.md$/, ''\n )\n console.log(` Starting ${t.filename}`)\n const code = await spawnAgent({\n prompt,\n agentCmd,\n model,\n timeout,\n logPath,\n label,\n })\n return { ticket:t, exitCode:code }\n })\n )\n\n let waveCompleted = 0\n for (const r of results) {\n if (r.status === 'rejected') continue\n const { ticket, exitCode } = r.value\n if (exitCode !== 0) {\n console.log(\n ` ${ticket.filename}: ` +\n `agent exited ${exitCode}`\n )\n continue\n }\n\n markDone(ticket)\n waveCompleted++\n totalCompleted++\n console.log(\n ` ${ticket.filename}: done`\n )\n }\n\n if (waveCompleted === 0) {\n console.log(\n '\\nNo tickets completed this wave. ' +\n 'Stopping.'\n )\n break\n }\n }\n\n const remaining = tickets.filter(\n t => t.status === 'ready-for-agent'\n )\n console.log(\n `\\nFinished: ${totalCompleted} completed` +\n (remaining.length > 0 ?\n `, ${remaining.length} remaining` :\n '')\n )\n\n return { allDone:remaining.length === 0 }\n}\n\nexport async function runWavesIsolated (opts:{\n tickets:Array<Ticket>\n specBody:string\n agentCmd:string\n model:string|null\n timeout:number\n logsDir:string\n featureName:string\n conflictStrategy:MergeConflictStrategy\n}):Promise<{ allDone:boolean }> {\n mkdirSync(opts.logsDir, { recursive:true })\n\n const repoRoot = getRepoRoot()\n const repoName = getRepoName()\n const baseBranch = getCurrentBranch()\n\n const progressPath = join(\n dirname(opts.logsDir), 'progress.md'\n )\n const progress:ProgressData = mergeProgress(\n generateProgress(opts.featureName, opts.tickets),\n readProgress(progressPath)\n )\n writeProgress(progressPath, progress)\n await commitProgress(\n repoRoot,\n progressPath,\n `nightralph: start ${opts.featureName}`\n )\n\n let totalCompleted = 0\n let waveNum = 0\n\n while (true) {\n const ready = findReadyTickets(opts.tickets)\n if (ready.length === 0) break\n\n waveNum++\n console.log(\n `\\nWave ${waveNum}: ` +\n ready.map(t => t.filename).join(', ')\n )\n\n const worktreeSettled = await Promise.allSettled(\n ready.map(t => createWorktree({\n repoRoot,\n repoName,\n baseBranch,\n ticket:t,\n }))\n )\n\n const activeTickets:Array<Ticket> = []\n const worktrees:Array<{\n worktreePath:string\n branchName:string\n }> = []\n\n for (let i = 0; i < worktreeSettled.length; i++) {\n const settled = worktreeSettled[i]\n const ticket = ready[i]\n if (settled.status === 'rejected') {\n console.log(\n ` ${ticket.filename}: failed to create ` +\n `worktree: ${formatErrorMessage(settled.reason)}`\n )\n continue\n }\n activeTickets.push(ticket)\n worktrees.push(settled.value)\n }\n\n const results = await Promise.allSettled(\n activeTickets.map((t, i) => {\n const prompt = renderPrompt(opts.specBody, t)\n const logPath = join(\n opts.logsDir,\n t.filename.replace(/\\.md$/, '.log')\n )\n const label = t.filename.replace(\n /\\.md$/, ''\n )\n console.log(` Starting ${t.filename}`)\n return spawnAgent({\n prompt,\n agentCmd:opts.agentCmd,\n model:opts.model,\n timeout:opts.timeout,\n logPath,\n cwd:worktrees[i].worktreePath,\n label,\n })\n })\n )\n\n let waveCompleted = 0\n const successfulBranches:Array<{\n branch:string\n ticketNum:number\n worktreePath:string\n }> = []\n const ticketsByNum = new Map<number, Ticket>()\n const worktreePathsByNum = new Map<number, string>()\n\n for (let i = 0; i < results.length; i++) {\n const r = results[i]\n if (r.status === 'rejected') continue\n const exitCode = r.value\n const ticket = activeTickets[i]\n const worktree = worktrees[i]\n\n if (exitCode !== 0) {\n console.log(\n ` ${ticket.filename}: ` +\n `agent exited ${exitCode}`\n )\n checkTicket(progress, ticket.num, {\n branch:worktree.branchName,\n exitCode,\n done:false,\n })\n writeProgress(progressPath, progress)\n await commitProgress(\n repoRoot,\n progressPath,\n `nightralph: ${ticket.filename} failed`\n )\n\n try {\n await removeWorktree(worktree.worktreePath)\n } catch (err) {\n console.error(\n ' Failed to remove worktree ' +\n `${worktree.worktreePath}: ` +\n formatErrorMessage(err)\n )\n }\n continue\n }\n\n if (isDirty(worktree.worktreePath)) {\n const committed = await commitDirty(\n worktree.worktreePath,\n 'nightralph: auto-commit ' +\n `${ticket.filename} remaining changes`\n )\n if (committed) {\n console.log(\n ` ${ticket.filename}: ` +\n 'auto-committed remaining changes'\n )\n }\n }\n\n if (!hasNewCommits(\n repoRoot, baseBranch, worktree.branchName\n )) {\n console.log(\n ` ${ticket.filename}: agent exited 0 ` +\n 'but made no changes; leaving ticket ' +\n 'ready-for-agent'\n )\n continue\n }\n\n console.log(\n ` ${ticket.filename}: agent finished, ` +\n 'awaiting merge'\n )\n ticketsByNum.set(ticket.num, ticket)\n worktreePathsByNum.set(\n ticket.num, worktree.worktreePath\n )\n successfulBranches.push({\n branch:worktree.branchName,\n ticketNum:ticket.num,\n worktreePath:worktree.worktreePath,\n })\n }\n\n if (successfulBranches.length > 0) {\n const mergeResult = await mergeWave({\n repoRoot,\n baseBranch,\n branches:successfulBranches,\n strategy:opts.conflictStrategy,\n })\n\n for (const branchResult of mergeResult.merged) {\n const ticket = ticketsByNum.get(\n branchResult.ticketNum\n )\n if (!ticket) continue\n\n if (branchResult.merged) {\n markDone(ticket)\n waveCompleted++\n totalCompleted++\n console.log(\n ` ${ticket.filename}: done`\n )\n checkTicket(progress, ticket.num, {\n branch:branchResult.branch,\n exitCode:0,\n })\n writeProgress(progressPath, progress)\n await commitProgress(\n repoRoot,\n progressPath,\n `nightralph: ${ticket.filename} done`\n )\n\n const worktreePath = worktreePathsByNum.get(\n ticket.num\n )\n if (worktreePath) {\n try {\n await removeWorktree(worktreePath)\n } catch (err) {\n console.error(\n ' Failed to remove worktree ' +\n `${worktreePath}: ` +\n formatErrorMessage(err)\n )\n }\n }\n } else {\n const worktreePath = worktreePathsByNum.get(\n ticket.num\n )\n const recovered =\n opts.conflictStrategy === 'respawn' &&\n worktreePath ?\n await respawnAndRetryMerge({\n repoRoot,\n baseBranch,\n branch:branchResult.branch,\n ticket,\n worktreePath,\n specBody:opts.specBody,\n agentCmd:opts.agentCmd,\n model:opts.model,\n timeout:opts.timeout,\n logsDir:opts.logsDir,\n }) :\n false\n\n if (recovered) {\n markDone(ticket)\n waveCompleted++\n totalCompleted++\n console.log(\n ` ${ticket.filename}: done ` +\n '(resolved via respawn)'\n )\n checkTicket(progress, ticket.num, {\n branch:branchResult.branch,\n exitCode:0,\n })\n writeProgress(progressPath, progress)\n await commitProgress(\n repoRoot,\n progressPath,\n `nightralph: ${ticket.filename} ` +\n 'done (respawn)'\n )\n\n if (worktreePath) {\n try {\n await removeWorktree(worktreePath)\n } catch (err) {\n console.error(\n ' Failed to remove worktree ' +\n `${worktreePath}: ` +\n formatErrorMessage(err)\n )\n }\n }\n } else {\n console.log(\n ` ${ticket.filename}: merge failed, ` +\n 'staying ready-for-agent'\n )\n }\n }\n }\n\n if (mergeResult.stoppedAt) {\n console.log(\n '\\nMerge stopped at ' +\n `${mergeResult.stoppedAt.branch}`\n )\n\n for (const sb of successfulBranches) {\n const ticket = ticketsByNum.get(sb.ticketNum)\n if (ticket && ticket.status === 'done') continue\n try {\n await removeWorktree(sb.worktreePath)\n } catch (err) {\n console.error(\n ' Failed to remove worktree ' +\n `${sb.worktreePath}: ` +\n formatErrorMessage(err)\n )\n }\n }\n\n break\n }\n }\n\n if (waveCompleted === 0) {\n console.log(\n '\\nNo tickets completed this wave. ' +\n 'Stopping.'\n )\n break\n }\n }\n\n const remaining = opts.tickets.filter(\n t => t.status === 'ready-for-agent'\n )\n console.log(\n `\\nFinished: ${totalCompleted} completed` +\n (remaining.length > 0 ?\n `, ${remaining.length} remaining` :\n '')\n )\n\n return { allDone:remaining.length === 0 }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import { spawn } from 'node:child_process'\nimport {\n createWriteStream,\n mkdirSync,\n readFileSync,\n writeFileSync,\n unlinkSync,\n readdirSync,\n} from 'node:fs'\nimport { tmpdir } from 'node:os'\nimport { join, dirname, basename } from 'node:path'\nimport { createInterface } from 'node:readline'\nimport {\n getRepoRoot,\n getRepoName,\n getCurrentBranch,\n createWorktree,\n removeWorktree,\n hasNewCommits,\n isDirty,\n commitDirty,\n} from './worktree.js'\nimport {\n generateProgress,\n readProgress,\n mergeProgress,\n writeProgress,\n commitProgress,\n checkTicket,\n type ProgressData,\n} from './progress.js'\nimport {\n mergeBranch,\n mergeWave,\n updateWorktreeFromBase,\n type MergeConflictStrategy,\n} from './merge.js'\nimport {\n createDisplay,\n type Display,\n} from './display.js'\n\nexport type Ticket = {\n num:number\n slug:string\n filename:string\n filepath:string\n body:string\n status:string\n blockers:number[]\n}\n\nexport function formatErrorMessage (error:unknown):string {\n return error instanceof Error ?\n error.message :\n String(error)\n}\n\nexport const TICKET_RE = /^(\\d+)-(.+)\\.md$/\n\nexport function parseTicketFilename (\n filename:string\n):{ num:number; slug:string }|null {\n const m = filename.match(TICKET_RE)\n if (!m) return null\n return { num:Number(m[1]), slug:m[2] }\n}\n\nexport function parseStatus (body:string):string {\n const m = body.match(/\\*\\*Status:\\*\\*\\s*(.+)/i)\n return m ? m[1].trim().toLowerCase() : ''\n}\n\nexport function parseBlockers (body:string):number[] {\n const m = body.match(/\\*\\*Blocked by:\\*\\*\\s*(.+)/i)\n if (!m) return []\n const text = m[1]\n if (/none/i.test(text)) return []\n const nums:number[] = []\n const re = /(\\d+)/g\n let match\n while ((match = re.exec(text))) {\n nums.push(Number(match[1]))\n }\n return nums\n}\n\nexport function scanTickets (dir:string):Ticket[] {\n const files = readdirSync(dir)\n .filter(f => TICKET_RE.test(f))\n .sort((a, b) => a.localeCompare(\n b,\n undefined,\n { numeric:true, sensitivity:'base' }\n ))\n\n return files.map(filename => {\n const parsed = parseTicketFilename(filename)!\n const filepath = join(dir, filename)\n const body = readFileSync(filepath, 'utf8')\n return {\n num:parsed.num,\n slug:parsed.slug,\n filename,\n filepath,\n body,\n status:parseStatus(body),\n blockers:parseBlockers(body),\n }\n })\n}\n\nexport function findReadyTickets (\n tickets:ReadonlyArray<Ticket>\n):Ticket[] {\n const doneNums = new Set(\n tickets\n .filter(t => t.status === 'done')\n .map(t => t.num)\n )\n return tickets.filter(t => {\n if (t.status !== 'ready-for-agent') return false\n return t.blockers.every(b => doneNums.has(b))\n })\n}\n\nexport const COMPLETED_RE = /^\\[x\\]\\s+(.+)$/i\n\nexport function checkItems (\n ticket:Ticket,\n completedItems:string[]\n):void {\n if (completedItems.length === 0) return\n let body = ticket.body\n for (const item of completedItems) {\n const escaped = item.replace(\n /[.*+?^${}()|[\\]\\\\]/g, '\\\\$&'\n )\n body = body.replace(\n new RegExp(\n `- \\\\[ \\\\] ${escaped}`,\n 'i'\n ),\n `- [x] ${item}`\n )\n }\n writeFileSync(ticket.filepath, body)\n ticket.body = body\n}\n\nexport function markDone (ticket:Ticket):void {\n const updated = ticket.body.replace(\n /\\*\\*Status:\\*\\*\\s*.+/i,\n '**Status:** done'\n )\n writeFileSync(ticket.filepath, updated)\n ticket.status = 'done'\n ticket.body = updated\n}\n\nexport function renderPrompt (\n specBody:string,\n ticket:Ticket\n):string {\n return [\n '---- SPEC CONTEXT ----',\n specBody,\n '',\n '---- TICKET ----',\n ticket.filename,\n ticket.body,\n '',\n '---- AGENT INSTRUCTIONS ----',\n 'You are an autonomous coding agent. ' +\n 'Implement the ticket.',\n '',\n 'Time is limited. Follow these rules:',\n '- Spend at most 2 minutes reading existing ' +\n 'code. Read only the files directly relevant ' +\n 'to the ticket.',\n '- Do NOT research external APIs or services ' +\n 'via web search. Use the spec and ticket ' +\n 'body as your sole reference for API shapes.',\n '- Start writing code as soon as you understand ' +\n 'the immediate context. You can read more ' +\n 'files as needed while implementing.',\n '- Commit your work when finished.',\n '- After completing each checklist item in the ' +\n 'ticket, print a line: [x] <item text> ' +\n '(matching the checklist text exactly).',\n '',\n ].join('\\n')\n}\n\nfunction listTickets (tickets:ReadonlyArray<Ticket>):void {\n console.log('\\nTickets:')\n for (const t of tickets) {\n const blockerStr = t.blockers.length > 0 ?\n `blocked by [${t.blockers.join(', ')}]` :\n 'no blockers'\n console.log(\n ` ${t.filename} ` +\n `(${t.status}) ${blockerStr}`\n )\n }\n}\n\nfunction * simulateWaves (\n tickets:ReadonlyArray<Ticket>\n):Generator<{ wave:number; ready:Array<Ticket> }> {\n const sim = new Map(\n tickets.map(t => [t.num, t.status])\n )\n let wave = 1\n while (true) {\n const doneNums = new Set(\n [...sim.entries()]\n .filter(([, s]) => s === 'done')\n .map(([n]) => n)\n )\n const ready = [...tickets].filter(t => {\n if (sim.get(t.num) !== 'ready-for-agent') {\n return false\n }\n return t.blockers.every(\n b => doneNums.has(b)\n )\n })\n if (ready.length === 0) break\n yield { wave, ready }\n for (const t of ready) {\n sim.set(t.num, 'done')\n }\n wave++\n }\n}\n\nfunction detectDeadlocks (\n tickets:ReadonlyArray<Ticket>\n):Array<Ticket> {\n const doneNums = new Set<number>()\n const ready = new Set<number>()\n\n for (const t of tickets) {\n if (t.status === 'ready-for-agent') {\n ready.add(t.num)\n } else if (t.status === 'done') {\n doneNums.add(t.num)\n }\n }\n\n let changed = true\n while (changed) {\n changed = false\n for (const num of ready) {\n const ticket = tickets.find(t =>\n t.num === num\n )!\n if (ticket.blockers.every(\n b => doneNums.has(b)\n )) {\n doneNums.add(num)\n ready.delete(num)\n changed = true\n }\n }\n }\n\n return [...ready].map(num =>\n tickets.find(t => t.num === num)!\n )\n}\n\nconst PROVIDER_ARGS:Record<string, string[]> = {\n claude:[\n '--print', '--verbose',\n '--output-format', 'stream-json',\n '--dangerously-skip-permissions',\n ],\n codex:['exec', '--full-auto'],\n pi:[\n '-p', '--verbose',\n '--approve', '--no-session',\n '--mode', 'json',\n ],\n}\n\nexport function getProviderArgs (cmd:string):string[] {\n const name = basename(cmd)\n return PROVIDER_ARGS[name] ?? []\n}\n\nexport function formatStreamLine (\n line:string\n):string|null {\n let obj:Record<string, unknown>\n try {\n obj = JSON.parse(line) as Record<string, unknown>\n } catch {\n return line\n }\n\n if (obj.type === 'assistant') {\n const msg = obj.message as\n Record<string, unknown>|undefined\n const content = msg?.content as\n Array<Record<string, unknown>>|undefined\n if (!content) return null\n for (const block of content) {\n if (block.type === 'text') {\n return String(block.text)\n }\n }\n return null\n }\n\n if (obj.type === 'result') {\n const sub = obj.subtype as string|undefined ?? 'done'\n const cost = obj.total_cost_usd as number|undefined\n const costStr = cost != null ?\n ` ($${cost.toFixed(2)})` :\n ''\n return `${sub}${costStr}`\n }\n\n if (obj.type === 'system') {\n const sub = obj.subtype as string|undefined\n if (sub === 'api_retry') {\n const error = obj.error as string|undefined\n return `retry: ${error ?? 'unknown'}`\n }\n }\n\n return null\n}\n\nexport function createPiStreamFormatter ():((line:string) => string|null) {\n const calls = new Map<number, { name:string; buf:string }>()\n\n return (line:string):string|null => {\n let obj:Record<string, unknown>\n try {\n obj = JSON.parse(line) as\n Record<string, unknown>\n } catch {\n return line\n }\n\n const evt = obj.assistantMessageEvent as\n Record<string, unknown>|undefined\n if (!evt) return null\n\n const type = evt.type as string|undefined\n const ci = evt.contentIndex as\n number|undefined ?? -1\n\n if (type === 'text_delta') {\n return (evt.delta as string|undefined) ??\n null\n }\n\n if (type === 'toolcall_start') {\n calls.set(ci, {\n name:(evt.toolName as\n string|undefined) ?? '?',\n buf:'',\n })\n return null\n }\n\n if (\n type === 'toolcall_delta' &&\n calls.has(ci)\n ) {\n calls.get(ci)!.buf +=\n (evt.delta as string|undefined) ?? ''\n return null\n }\n\n if (\n type === 'toolcall_end' &&\n calls.has(ci)\n ) {\n const call = calls.get(ci)!\n calls.delete(ci)\n let label = ''\n try {\n const args = JSON.parse(call.buf) as\n Record<string, unknown>\n label = String(\n args.command ??\n args.file_path ??\n args.query ?? ''\n ).split('\\n')[0].slice(0, 72)\n } catch {\n // unparseable tool args\n }\n return `[${call.name}] ${label}`\n }\n\n return null\n }\n}\n\nfunction writePromptFile (prompt:string):string {\n const name = `nightralph-${Date.now()}-` +\n `${Math.random().toString(36).slice(2)}.md`\n const filePath = join(tmpdir(), name)\n writeFileSync(filePath, prompt)\n return filePath\n}\n\nfunction cleanupPromptFile (filePath:string):void {\n try {\n unlinkSync(filePath)\n } catch {\n // already removed\n }\n}\n\nexport type AgentResult = {\n exitCode:number\n completedItems:string[]\n}\n\nexport function spawnAgent (opts:{\n prompt:string\n agentCmd:string\n model:string|null\n timeout:number\n logPath:string\n cwd?:string\n label?:string\n onLine?:(line:string) => void\n}):Promise<AgentResult> {\n const args:string[] = [\n ...getProviderArgs(opts.agentCmd),\n ]\n if (opts.model) {\n args.push('--model', opts.model)\n }\n\n const providerName = basename(opts.agentCmd)\n const isClaude = providerName === 'claude'\n const isPi = providerName === 'pi'\n const prefix = opts.label ?\n ` [${opts.label}] ` :\n ' '\n\n let promptFile:string|null = null\n if (isPi) {\n promptFile = writePromptFile(opts.prompt)\n args.push(`@${promptFile}`)\n }\n\n const logStream = createWriteStream(\n opts.logPath,\n { flags:'w' }\n )\n const proc = spawn(opts.agentCmd, args, {\n stdio:['pipe', 'pipe', 'pipe'],\n cwd:opts.cwd,\n })\n\n proc.stdout.pipe(logStream)\n\n const piFormatter = isPi ?\n createPiStreamFormatter() :\n null\n\n const completedItems:string[] = []\n\n function collectCompleted (text:string):void {\n const match = text.match(COMPLETED_RE)\n if (match) completedItems.push(match[1])\n }\n\n const rl = createInterface({ input:proc.stdout })\n rl.on('line', line => {\n if (isClaude) {\n const formatted = formatStreamLine(line)\n if (formatted !== null) {\n collectCompleted(formatted)\n const output = `${prefix}${formatted}`\n if (opts.onLine) {\n opts.onLine(output)\n } else {\n console.log(output)\n }\n }\n } else if (piFormatter) {\n const formatted = piFormatter(line)\n if (formatted !== null) {\n collectCompleted(formatted)\n const output = `${prefix}${formatted}`\n if (opts.onLine) {\n opts.onLine(output)\n } else {\n console.log(output)\n }\n }\n } else {\n collectCompleted(line)\n const output = `${prefix}${line}`\n if (opts.onLine) {\n opts.onLine(output)\n } else {\n console.log(output)\n }\n }\n })\n\n proc.stderr.pipe(logStream)\n const rlErr = createInterface({ input:proc.stderr })\n rlErr.on('line', line => {\n const output = `${prefix}${line}`\n if (opts.onLine) {\n opts.onLine(output)\n } else {\n console.error(output)\n }\n })\n\n const timeout = setTimeout(() => {\n if (!proc.killed) {\n console.warn(\n 'Agent did not exit in ' +\n `${opts.timeout}s; killing.`\n )\n proc.kill('SIGKILL')\n }\n }, opts.timeout * 1000)\n\n if (!promptFile) {\n proc.stdin.write(opts.prompt)\n }\n proc.stdin.end()\n\n return new Promise<AgentResult>(resolve => {\n proc.on('close', code => {\n clearTimeout(timeout)\n rl.close()\n rlErr.close()\n logStream.end()\n if (promptFile) cleanupPromptFile(promptFile)\n resolve({\n exitCode:code ?? 1,\n completedItems,\n })\n })\n proc.on('error', err => {\n clearTimeout(timeout)\n rl.close()\n rlErr.close()\n logStream.end()\n if (promptFile) cleanupPromptFile(promptFile)\n console.error(\n 'Agent process error:',\n formatErrorMessage(err)\n )\n resolve({ exitCode:1, completedItems })\n })\n })\n}\n\nexport function dryRun (\n tickets:Array<Ticket>,\n specBody:string\n):void {\n listTickets(tickets)\n\n console.log('\\nSimulated wave order:')\n for (const { wave, ready } of simulateWaves(tickets)) {\n console.log(\n ` Wave ${wave}: ` +\n ready.map(t => t.filename).join(', ')\n )\n }\n\n const stuck = detectDeadlocks(tickets)\n if (stuck.length > 0) {\n console.log(\n '\\nDeadlocked tickets: ' +\n stuck.map(t => t.filename).join(', ')\n )\n }\n\n const firstReady = findReadyTickets(tickets)\n if (firstReady.length > 0) {\n console.log(\n '\\nPrompt for first ready ticket ' +\n `(${firstReady[0].filename}):\\n`\n )\n console.log(\n renderPrompt(specBody, firstReady[0])\n )\n }\n}\n\nexport function dryRunIsolated (opts:{\n tickets:Array<Ticket>\n specBody:string\n repoName:string\n conflictStrategy:MergeConflictStrategy\n progressPath:string\n}):void {\n listTickets(opts.tickets)\n\n console.log('\\nSimulated wave order:')\n for (const { wave, ready } of simulateWaves(\n opts.tickets\n )) {\n console.log(\n ` Wave ${wave}: ` +\n ready.map(t => t.filename).join(', ')\n )\n for (const t of ready) {\n const num = String(t.num).padStart(2, '0')\n const branchName =\n `${opts.repoName}/${num}-${t.slug}`\n const worktreePath =\n `../${opts.repoName}.${num}-${t.slug}`\n console.log(` worktree: ${worktreePath}`)\n console.log(` branch: ${branchName}`)\n }\n }\n\n const stuck = detectDeadlocks(opts.tickets)\n if (stuck.length > 0) {\n console.log(\n '\\nDeadlocked tickets: ' +\n stuck.map(t => t.filename).join(', ')\n )\n }\n\n const firstReady = findReadyTickets(opts.tickets)\n if (firstReady.length > 0) {\n console.log(\n '\\nPrompt for first ready ticket ' +\n `(${firstReady[0].filename}):\\n`\n )\n console.log(\n renderPrompt(opts.specBody, firstReady[0])\n )\n }\n\n const strategyDesc =\n opts.conflictStrategy === 'respawn' ?\n 'respawn (re-run agent on conflict)' :\n 'stop (stop merging on conflict)'\n console.log(\n `\\nMerge strategy: ${strategyDesc}`\n )\n console.log(`Progress file: ${opts.progressPath}`)\n}\n\n// Re-runs the agent in a ticket's existing worktree\n// after a merge conflict, then retries the merge once.\n// Called at most once per ticket per wave.\nasync function respawnAndRetryMerge (opts:{\n repoRoot:string\n baseBranch:string\n branch:string\n ticket:Ticket\n worktreePath:string\n specBody:string\n agentCmd:string\n model:string|null\n timeout:number\n logsDir:string\n onLine?:(msg:string) => void\n}):Promise<boolean> {\n await updateWorktreeFromBase(\n opts.worktreePath, opts.baseBranch\n )\n\n const msg1 = ` ${opts.ticket.filename}: respawning agent ` +\n 'to resolve merge conflict'\n if (opts.onLine) {\n opts.onLine(msg1)\n } else {\n console.log(msg1)\n }\n\n const prompt = renderPrompt(opts.specBody, opts.ticket)\n const logPath = join(\n opts.logsDir,\n opts.ticket.filename.replace(/\\.md$/, '.respawn.log')\n )\n const label = opts.ticket.filename.replace(\n /\\.md$/, ''\n )\n const result = await spawnAgent({\n prompt,\n agentCmd:opts.agentCmd,\n model:opts.model,\n timeout:opts.timeout,\n logPath,\n cwd:opts.worktreePath,\n label,\n onLine:opts.onLine,\n })\n\n if (result.exitCode !== 0) {\n const msg2 = ` ${opts.ticket.filename}: respawned agent ` +\n `exited ${result.exitCode}`\n if (opts.onLine) {\n opts.onLine(msg2)\n } else {\n console.log(msg2)\n }\n return false\n }\n\n const merged = await mergeBranch(\n opts.repoRoot, opts.branch\n )\n if (!merged) {\n const msg3 = ` ${opts.ticket.filename}: merge still ` +\n 'conflicted after respawn'\n if (opts.onLine) {\n opts.onLine(msg3)\n } else {\n console.log(msg3)\n }\n }\n return merged\n}\n\nexport async function runWaves (\n tickets:Ticket[],\n specBody:string,\n agentCmd:string,\n model:string|null,\n timeout:number,\n logsDir:string,\n display?:Display,\n):Promise<{ allDone:boolean }> {\n mkdirSync(logsDir, { recursive:true })\n\n const d = display ?? createDisplay()\n let totalWaves = 0\n for (const _ of simulateWaves(tickets)) totalWaves++\n\n let totalCompleted = 0\n let waveNum = 0\n\n while (true) {\n const ready = findReadyTickets(tickets)\n if (ready.length === 0) break\n\n waveNum++\n d.startWave(\n waveNum,\n totalWaves,\n ready.map(t => ({\n num:t.num,\n filename:t.filename,\n }))\n )\n\n const results = await Promise.allSettled(\n ready.map(async t => {\n const prompt = renderPrompt(specBody, t)\n const logPath = join(\n logsDir,\n t.filename.replace(/\\.md$/, '.log')\n )\n const label = t.filename.replace(\n /\\.md$/, ''\n )\n d.setTicketStatus(t.num, 'in-progress')\n d.log(` Starting ${t.filename}`)\n const result = await spawnAgent({\n prompt,\n agentCmd,\n model,\n timeout,\n logPath,\n label,\n onLine:(line) => d.log(line),\n })\n return { ticket:t, result }\n })\n )\n\n let waveCompleted = 0\n for (const r of results) {\n if (r.status === 'rejected') continue\n const { ticket, result } = r.value\n if (result.exitCode !== 0) {\n d.setTicketStatus(ticket.num, 'failed')\n d.log(\n ` ${ticket.filename}: ` +\n `agent exited ${result.exitCode}`\n )\n continue\n }\n\n checkItems(ticket, result.completedItems)\n markDone(ticket)\n waveCompleted++\n totalCompleted++\n d.setTicketStatus(ticket.num, 'done')\n d.log(\n ` ${ticket.filename}: done`\n )\n }\n\n if (waveCompleted === 0) {\n d.log(\n '\\nNo tickets completed this wave. ' +\n 'Stopping.'\n )\n break\n }\n }\n\n const remaining = tickets.filter(\n t => t.status === 'ready-for-agent'\n )\n d.log(\n `\\nFinished: ${totalCompleted} completed` +\n (remaining.length > 0 ?\n `, ${remaining.length} remaining` :\n '')\n )\n d.cleanup()\n\n return { allDone:remaining.length === 0 }\n}\n\nexport async function runWavesIsolated (opts:{\n tickets:Array<Ticket>\n specBody:string\n agentCmd:string\n model:string|null\n timeout:number\n logsDir:string\n featureName:string\n conflictStrategy:MergeConflictStrategy\n display?:Display\n}):Promise<{ allDone:boolean }> {\n mkdirSync(opts.logsDir, { recursive:true })\n\n const d = opts.display ?? createDisplay()\n let totalWaves = 0\n for (const _ of simulateWaves(opts.tickets)) totalWaves++\n\n const repoRoot = getRepoRoot()\n const repoName = getRepoName()\n const baseBranch = getCurrentBranch()\n\n const progressPath = join(\n dirname(opts.logsDir), 'progress.md'\n )\n const progress:ProgressData = mergeProgress(\n generateProgress(opts.featureName, opts.tickets),\n readProgress(progressPath)\n )\n writeProgress(progressPath, progress)\n await commitProgress(\n repoRoot,\n progressPath,\n `nightralph: start ${opts.featureName}`\n )\n\n let totalCompleted = 0\n let waveNum = 0\n\n while (true) {\n const ready = findReadyTickets(opts.tickets)\n if (ready.length === 0) break\n\n waveNum++\n d.startWave(\n waveNum,\n totalWaves,\n ready.map(t => ({\n num:t.num,\n filename:t.filename,\n }))\n )\n\n const worktreeSettled = await Promise.allSettled(\n ready.map(t => createWorktree({\n repoRoot,\n repoName,\n baseBranch,\n ticket:t,\n }))\n )\n\n const activeTickets:Array<Ticket> = []\n const worktrees:Array<{\n worktreePath:string\n branchName:string\n }> = []\n\n for (let i = 0; i < worktreeSettled.length; i++) {\n const settled = worktreeSettled[i]\n const ticket = ready[i]\n if (settled.status === 'rejected') {\n d.setTicketStatus(ticket.num, 'failed')\n d.log(\n ` ${ticket.filename}: failed to create ` +\n `worktree: ${formatErrorMessage(settled.reason)}`\n )\n continue\n }\n activeTickets.push(ticket)\n worktrees.push(settled.value)\n }\n\n const results = await Promise.allSettled(\n activeTickets.map((t, i) => {\n const prompt = renderPrompt(opts.specBody, t)\n const logPath = join(\n opts.logsDir,\n t.filename.replace(/\\.md$/, '.log')\n )\n const label = t.filename.replace(\n /\\.md$/, ''\n )\n d.setTicketStatus(t.num, 'in-progress')\n d.log(` Starting ${t.filename}`)\n return spawnAgent({\n prompt,\n agentCmd:opts.agentCmd,\n model:opts.model,\n timeout:opts.timeout,\n logPath,\n cwd:worktrees[i].worktreePath,\n label,\n onLine:(line) => d.log(line),\n })\n })\n )\n\n let waveCompleted = 0\n const successfulBranches:Array<{\n branch:string\n ticketNum:number\n worktreePath:string\n }> = []\n const ticketsByNum = new Map<number, Ticket>()\n const worktreePathsByNum = new Map<number, string>()\n\n for (let i = 0; i < results.length; i++) {\n const r = results[i]\n if (r.status === 'rejected') continue\n const agentResult = r.value\n const ticket = activeTickets[i]\n const worktree = worktrees[i]\n\n if (agentResult.exitCode !== 0) {\n d.setTicketStatus(ticket.num, 'failed')\n d.log(\n ` ${ticket.filename}: ` +\n `agent exited ${agentResult.exitCode}`\n )\n checkItems(ticket, agentResult.completedItems)\n checkTicket(progress, ticket.num, {\n branch:worktree.branchName,\n exitCode:agentResult.exitCode,\n done:false,\n })\n writeProgress(progressPath, progress)\n await commitProgress(\n repoRoot,\n progressPath,\n `nightralph: ${ticket.filename} failed`\n )\n\n try {\n await removeWorktree(worktree.worktreePath)\n } catch (err) {\n d.log(\n ' Failed to remove worktree ' +\n `${worktree.worktreePath}: ` +\n formatErrorMessage(err)\n )\n }\n continue\n }\n\n if (isDirty(worktree.worktreePath)) {\n const committed = await commitDirty(\n worktree.worktreePath,\n 'nightralph: auto-commit ' +\n `${ticket.filename} remaining changes`\n )\n if (committed) {\n d.log(\n ` ${ticket.filename}: ` +\n 'auto-committed remaining changes'\n )\n }\n }\n\n if (!hasNewCommits(\n repoRoot, baseBranch, worktree.branchName\n )) {\n d.setTicketStatus(ticket.num, 'failed')\n d.log(\n ` ${ticket.filename}: agent exited 0 ` +\n 'but made no changes; leaving ticket ' +\n 'ready-for-agent'\n )\n continue\n }\n\n checkItems(ticket, agentResult.completedItems)\n d.log(\n ` ${ticket.filename}: agent finished, ` +\n 'awaiting merge'\n )\n ticketsByNum.set(ticket.num, ticket)\n worktreePathsByNum.set(\n ticket.num, worktree.worktreePath\n )\n successfulBranches.push({\n branch:worktree.branchName,\n ticketNum:ticket.num,\n worktreePath:worktree.worktreePath,\n })\n }\n\n if (successfulBranches.length > 0) {\n const mergeResult = await mergeWave({\n repoRoot,\n baseBranch,\n branches:successfulBranches,\n strategy:opts.conflictStrategy,\n })\n\n for (const branchResult of mergeResult.merged) {\n const ticket = ticketsByNum.get(\n branchResult.ticketNum\n )\n if (!ticket) continue\n\n if (branchResult.merged) {\n markDone(ticket)\n waveCompleted++\n totalCompleted++\n d.setTicketStatus(ticket.num, 'done')\n d.log(\n ` ${ticket.filename}: done`\n )\n checkTicket(progress, ticket.num, {\n branch:branchResult.branch,\n exitCode:0,\n })\n writeProgress(progressPath, progress)\n await commitProgress(\n repoRoot,\n progressPath,\n `nightralph: ${ticket.filename} done`\n )\n\n const worktreePath = worktreePathsByNum.get(\n ticket.num\n )\n if (worktreePath) {\n try {\n await removeWorktree(worktreePath)\n } catch (err) {\n d.log(\n ' Failed to remove worktree ' +\n `${worktreePath}: ` +\n formatErrorMessage(err)\n )\n }\n }\n } else {\n const worktreePath = worktreePathsByNum.get(\n ticket.num\n )\n const recovered =\n opts.conflictStrategy === 'respawn' &&\n worktreePath ?\n await respawnAndRetryMerge({\n repoRoot,\n baseBranch,\n branch:branchResult.branch,\n ticket,\n worktreePath,\n specBody:opts.specBody,\n agentCmd:opts.agentCmd,\n model:opts.model,\n timeout:opts.timeout,\n logsDir:opts.logsDir,\n onLine:(msg) => d.log(msg),\n }) :\n false\n\n if (recovered) {\n markDone(ticket)\n waveCompleted++\n totalCompleted++\n d.setTicketStatus(ticket.num, 'done')\n d.log(\n ` ${ticket.filename}: done ` +\n '(resolved via respawn)'\n )\n checkTicket(progress, ticket.num, {\n branch:branchResult.branch,\n exitCode:0,\n })\n writeProgress(progressPath, progress)\n await commitProgress(\n repoRoot,\n progressPath,\n `nightralph: ${ticket.filename} ` +\n 'done (respawn)'\n )\n\n if (worktreePath) {\n try {\n await removeWorktree(worktreePath)\n } catch (err) {\n d.log(\n ' Failed to remove worktree ' +\n `${worktreePath}: ` +\n formatErrorMessage(err)\n )\n }\n }\n } else {\n d.log(\n ` ${ticket.filename}: merge failed, ` +\n 'staying ready-for-agent'\n )\n }\n }\n }\n\n if (mergeResult.stoppedAt) {\n d.log(\n '\\nMerge stopped at ' +\n `${mergeResult.stoppedAt.branch}`\n )\n\n for (const sb of successfulBranches) {\n const ticket = ticketsByNum.get(sb.ticketNum)\n if (ticket && ticket.status === 'done') continue\n try {\n await removeWorktree(sb.worktreePath)\n } catch (err) {\n d.log(\n ' Failed to remove worktree ' +\n `${sb.worktreePath}: ` +\n formatErrorMessage(err)\n )\n }\n }\n\n break\n }\n }\n\n if (waveCompleted === 0) {\n d.log(\n '\\nNo tickets completed this wave. ' +\n 'Stopping.'\n )\n break\n }\n }\n\n const remaining = opts.tickets.filter(\n t => t.status === 'ready-for-agent'\n )\n d.log(\n `\\nFinished: ${totalCompleted} completed` +\n (remaining.length > 0 ?\n `, ${remaining.length} remaining` :\n '')\n )\n d.cleanup()\n\n return { allDone:remaining.length === 0 }\n}\n"],
|
|
5
|
+
"mappings": ";;AAAA,SAAS,aAAa;AACtB;AAAA,EACI;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACG;AACP,SAAS,cAAc;AACvB,SAAS,MAAM,SAAS,gBAAgB;AACxC,SAAS,uBAAuB;AAChC;AAAA,EACI;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACG;AACP;AAAA,EACI;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAEG;AACP;AAAA,EACI;AAAA,EACA;AAAA,EACA;AAAA,OAEG;AACP;AAAA,EACI;AAAA,OAEG;AAYA,SAAS,mBAAoB,OAAsB;AACtD,SAAO,iBAAiB,QACpB,MAAM,UACN,OAAO,KAAK;AACpB;AAJgB;AAMT,MAAM,YAAY;AAElB,SAAS,oBACZ,UAC+B;AAC/B,QAAM,IAAI,SAAS,MAAM,SAAS;AAClC,MAAI,CAAC,EAAG,QAAO;AACf,SAAO,EAAE,KAAI,OAAO,EAAE,CAAC,CAAC,GAAG,MAAK,EAAE,CAAC,EAAE;AACzC;AANgB;AAQT,SAAS,YAAa,MAAoB;AAC7C,QAAM,IAAI,KAAK,MAAM,yBAAyB;AAC9C,SAAO,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,YAAY,IAAI;AAC3C;AAHgB;AAKT,SAAS,cAAe,MAAsB;AACjD,QAAM,IAAI,KAAK,MAAM,6BAA6B;AAClD,MAAI,CAAC,EAAG,QAAO,CAAC;AAChB,QAAM,OAAO,EAAE,CAAC;AAChB,MAAI,QAAQ,KAAK,IAAI,EAAG,QAAO,CAAC;AAChC,QAAM,OAAgB,CAAC;AACvB,QAAM,KAAK;AACX,MAAI;AACJ,SAAQ,QAAQ,GAAG,KAAK,IAAI,GAAI;AAC5B,SAAK,KAAK,OAAO,MAAM,CAAC,CAAC,CAAC;AAAA,EAC9B;AACA,SAAO;AACX;AAZgB;AAcT,SAAS,YAAa,KAAqB;AAC9C,QAAM,QAAQ,YAAY,GAAG,EACxB,OAAO,OAAK,UAAU,KAAK,CAAC,CAAC,EAC7B,KAAK,CAAC,GAAG,MAAM,EAAE;AAAA,IACd;AAAA,IACA;AAAA,IACA,EAAE,SAAQ,MAAM,aAAY,OAAO;AAAA,EACvC,CAAC;AAEL,SAAO,MAAM,IAAI,cAAY;AACzB,UAAM,SAAS,oBAAoB,QAAQ;AAC3C,UAAM,WAAW,KAAK,KAAK,QAAQ;AACnC,UAAM,OAAO,aAAa,UAAU,MAAM;AAC1C,WAAO;AAAA,MACH,KAAI,OAAO;AAAA,MACX,MAAK,OAAO;AAAA,MACZ;AAAA,MACA;AAAA,MACA;AAAA,MACA,QAAO,YAAY,IAAI;AAAA,MACvB,UAAS,cAAc,IAAI;AAAA,IAC/B;AAAA,EACJ,CAAC;AACL;AAvBgB;AAyBT,SAAS,iBACZ,SACO;AACP,QAAM,WAAW,IAAI;AAAA,IACjB,QACK,OAAO,OAAK,EAAE,WAAW,MAAM,EAC/B,IAAI,OAAK,EAAE,GAAG;AAAA,EACvB;AACA,SAAO,QAAQ,OAAO,OAAK;AACvB,QAAI,EAAE,WAAW,kBAAmB,QAAO;AAC3C,WAAO,EAAE,SAAS,MAAM,OAAK,SAAS,IAAI,CAAC,CAAC;AAAA,EAChD,CAAC;AACL;AAZgB;AAcT,MAAM,eAAe;AAErB,SAAS,WACZ,QACA,gBACG;AACH,MAAI,eAAe,WAAW,EAAG;AACjC,MAAI,OAAO,OAAO;AAClB,aAAW,QAAQ,gBAAgB;AAC/B,UAAM,UAAU,KAAK;AAAA,MACjB;AAAA,MAAuB;AAAA,IAC3B;AACA,WAAO,KAAK;AAAA,MACR,IAAI;AAAA,QACA,aAAa,OAAO;AAAA,QACpB;AAAA,MACJ;AAAA,MACA,SAAS,IAAI;AAAA,IACjB;AAAA,EACJ;AACA,gBAAc,OAAO,UAAU,IAAI;AACnC,SAAO,OAAO;AAClB;AApBgB;AAsBT,SAAS,SAAU,QAAoB;AAC1C,QAAM,UAAU,OAAO,KAAK;AAAA,IACxB;AAAA,IACA;AAAA,EACJ;AACA,gBAAc,OAAO,UAAU,OAAO;AACtC,SAAO,SAAS;AAChB,SAAO,OAAO;AAClB;AARgB;AAUT,SAAS,aACZ,UACA,QACK;AACL,SAAO;AAAA,IACH;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,OAAO;AAAA,IACP,OAAO;AAAA,IACP;AAAA,IACA;AAAA,IACA;AAAA,IAEA;AAAA,IACA;AAAA,IACA;AAAA,IAGA;AAAA,IAGA;AAAA,IAGA;AAAA,IACA;AAAA,IAGA;AAAA,EACJ,EAAE,KAAK,IAAI;AACf;AAhCgB;AAkChB,SAAS,YAAa,SAAoC;AACtD,UAAQ,IAAI,YAAY;AACxB,aAAW,KAAK,SAAS;AACrB,UAAM,aAAa,EAAE,SAAS,SAAS,IACnC,eAAe,EAAE,SAAS,KAAK,IAAI,CAAC,MACpC;AACJ,YAAQ;AAAA,MACJ,KAAK,EAAE,QAAQ,KACX,EAAE,MAAM,KAAK,UAAU;AAAA,IAC/B;AAAA,EACJ;AACJ;AAXS;AAaT,UAAW,cACP,SAC8C;AAC9C,QAAM,MAAM,IAAI;AAAA,IACZ,QAAQ,IAAI,OAAK,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC;AAAA,EACtC;AACA,MAAI,OAAO;AACX,SAAO,MAAM;AACT,UAAM,WAAW,IAAI;AAAA,MACjB,CAAC,GAAG,IAAI,QAAQ,CAAC,EACZ,OAAO,CAAC,CAAC,EAAE,CAAC,MAAM,MAAM,MAAM,EAC9B,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC;AAAA,IACvB;AACA,UAAM,QAAQ,CAAC,GAAG,OAAO,EAAE,OAAO,OAAK;AACnC,UAAI,IAAI,IAAI,EAAE,GAAG,MAAM,mBAAmB;AACtC,eAAO;AAAA,MACX;AACA,aAAO,EAAE,SAAS;AAAA,QACd,OAAK,SAAS,IAAI,CAAC;AAAA,MACvB;AAAA,IACJ,CAAC;AACD,QAAI,MAAM,WAAW,EAAG;AACxB,UAAM,EAAE,MAAM,MAAM;AACpB,eAAW,KAAK,OAAO;AACnB,UAAI,IAAI,EAAE,KAAK,MAAM;AAAA,IACzB;AACA;AAAA,EACJ;AACJ;AA5BW;AA8BX,SAAS,gBACL,SACY;AACZ,QAAM,WAAW,oBAAI,IAAY;AACjC,QAAM,QAAQ,oBAAI,IAAY;AAE9B,aAAW,KAAK,SAAS;AACrB,QAAI,EAAE,WAAW,mBAAmB;AAChC,YAAM,IAAI,EAAE,GAAG;AAAA,IACnB,WAAW,EAAE,WAAW,QAAQ;AAC5B,eAAS,IAAI,EAAE,GAAG;AAAA,IACtB;AAAA,EACJ;AAEA,MAAI,UAAU;AACd,SAAO,SAAS;AACZ,cAAU;AACV,eAAW,OAAO,OAAO;AACrB,YAAM,SAAS,QAAQ;AAAA,QAAK,OACxB,EAAE,QAAQ;AAAA,MACd;AACA,UAAI,OAAO,SAAS;AAAA,QAChB,OAAK,SAAS,IAAI,CAAC;AAAA,MACvB,GAAG;AACC,iBAAS,IAAI,GAAG;AAChB,cAAM,OAAO,GAAG;AAChB,kBAAU;AAAA,MACd;AAAA,IACJ;AAAA,EACJ;AAEA,SAAO,CAAC,GAAG,KAAK,EAAE;AAAA,IAAI,SAClB,QAAQ,KAAK,OAAK,EAAE,QAAQ,GAAG;AAAA,EACnC;AACJ;AAlCS;AAoCT,MAAM,gBAAyC;AAAA,EAC3C,QAAO;AAAA,IACH;AAAA,IAAW;AAAA,IACX;AAAA,IAAmB;AAAA,IACnB;AAAA,EACJ;AAAA,EACA,OAAM,CAAC,QAAQ,aAAa;AAAA,EAC5B,IAAG;AAAA,IACC;AAAA,IAAM;AAAA,IACN;AAAA,IAAa;AAAA,IACb;AAAA,IAAU;AAAA,EACd;AACJ;AAEO,SAAS,gBAAiB,KAAqB;AAClD,QAAM,OAAO,SAAS,GAAG;AACzB,SAAO,cAAc,IAAI,KAAK,CAAC;AACnC;AAHgB;AAKT,SAAS,iBACZ,MACU;AACV,MAAI;AACJ,MAAI;AACA,UAAM,KAAK,MAAM,IAAI;AAAA,EACzB,QAAQ;AACJ,WAAO;AAAA,EACX;AAEA,MAAI,IAAI,SAAS,aAAa;AAC1B,UAAM,MAAM,IAAI;AAEhB,UAAM,UAAU,KAAK;AAErB,QAAI,CAAC,QAAS,QAAO;AACrB,eAAW,SAAS,SAAS;AACzB,UAAI,MAAM,SAAS,QAAQ;AACvB,eAAO,OAAO,MAAM,IAAI;AAAA,MAC5B;AAAA,IACJ;AACA,WAAO;AAAA,EACX;AAEA,MAAI,IAAI,SAAS,UAAU;AACvB,UAAM,MAAM,IAAI,WAA+B;AAC/C,UAAM,OAAO,IAAI;AACjB,UAAM,UAAU,QAAQ,OACpB,MAAM,KAAK,QAAQ,CAAC,CAAC,MACrB;AACJ,WAAO,GAAG,GAAG,GAAG,OAAO;AAAA,EAC3B;AAEA,MAAI,IAAI,SAAS,UAAU;AACvB,UAAM,MAAM,IAAI;AAChB,QAAI,QAAQ,aAAa;AACrB,YAAM,QAAQ,IAAI;AAClB,aAAO,UAAU,SAAS,SAAS;AAAA,IACvC;AAAA,EACJ;AAEA,SAAO;AACX;AA1CgB;AA4CT,SAAS,0BAA0D;AACtE,QAAM,QAAQ,oBAAI,IAAyC;AAE3D,SAAO,CAAC,SAA4B;AAChC,QAAI;AACJ,QAAI;AACA,YAAM,KAAK,MAAM,IAAI;AAAA,IAEzB,QAAQ;AACJ,aAAO;AAAA,IACX;AAEA,UAAM,MAAM,IAAI;AAEhB,QAAI,CAAC,IAAK,QAAO;AAEjB,UAAM,OAAO,IAAI;AACjB,UAAM,KAAK,IAAI,gBACS;AAExB,QAAI,SAAS,cAAc;AACvB,aAAQ,IAAI,SACR;AAAA,IACR;AAEA,QAAI,SAAS,kBAAkB;AAC3B,YAAM,IAAI,IAAI;AAAA,QACV,MAAM,IAAI,YACe;AAAA,QACzB,KAAI;AAAA,MACR,CAAC;AACD,aAAO;AAAA,IACX;AAEA,QACI,SAAS,oBACT,MAAM,IAAI,EAAE,GACd;AACE,YAAM,IAAI,EAAE,EAAG,OACV,IAAI,SAA8B;AACvC,aAAO;AAAA,IACX;AAEA,QACI,SAAS,kBACT,MAAM,IAAI,EAAE,GACd;AACE,YAAM,OAAO,MAAM,IAAI,EAAE;AACzB,YAAM,OAAO,EAAE;AACf,UAAI,QAAQ;AACZ,UAAI;AACA,cAAM,OAAO,KAAK,MAAM,KAAK,GAAG;AAEhC,gBAAQ;AAAA,UACJ,KAAK,WACL,KAAK,aACL,KAAK,SAAS;AAAA,QAClB,EAAE,MAAM,IAAI,EAAE,CAAC,EAAE,MAAM,GAAG,EAAE;AAAA,MAChC,QAAQ;AAAA,MAER;AACA,aAAO,IAAI,KAAK,IAAI,KAAK,KAAK;AAAA,IAClC;AAEA,WAAO;AAAA,EACX;AACJ;AAlEgB;AAoEhB,SAAS,gBAAiB,QAAsB;AAC5C,QAAM,OAAO,cAAc,KAAK,IAAI,CAAC,IAC9B,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,CAAC,CAAC;AAC1C,QAAM,WAAW,KAAK,OAAO,GAAG,IAAI;AACpC,gBAAc,UAAU,MAAM;AAC9B,SAAO;AACX;AANS;AAQT,SAAS,kBAAmB,UAAsB;AAC9C,MAAI;AACA,eAAW,QAAQ;AAAA,EACvB,QAAQ;AAAA,EAER;AACJ;AANS;AAaF,SAAS,WAAY,MASJ;AACpB,QAAM,OAAgB;AAAA,IAClB,GAAG,gBAAgB,KAAK,QAAQ;AAAA,EACpC;AACA,MAAI,KAAK,OAAO;AACZ,SAAK,KAAK,WAAW,KAAK,KAAK;AAAA,EACnC;AAEA,QAAM,eAAe,SAAS,KAAK,QAAQ;AAC3C,QAAM,WAAW,iBAAiB;AAClC,QAAM,OAAO,iBAAiB;AAC9B,QAAM,SAAS,KAAK,QAChB,MAAM,KAAK,KAAK,OAChB;AAEJ,MAAI,aAAyB;AAC7B,MAAI,MAAM;AACN,iBAAa,gBAAgB,KAAK,MAAM;AACxC,SAAK,KAAK,IAAI,UAAU,EAAE;AAAA,EAC9B;AAEA,QAAM,YAAY;AAAA,IACd,KAAK;AAAA,IACL,EAAE,OAAM,IAAI;AAAA,EAChB;AACA,QAAM,OAAO,MAAM,KAAK,UAAU,MAAM;AAAA,IACpC,OAAM,CAAC,QAAQ,QAAQ,MAAM;AAAA,IAC7B,KAAI,KAAK;AAAA,EACb,CAAC;AAED,OAAK,OAAO,KAAK,SAAS;AAE1B,QAAM,cAAc,OAChB,wBAAwB,IACxB;AAEJ,QAAM,iBAA0B,CAAC;AAEjC,WAAS,iBAAkB,MAAkB;AACzC,UAAM,QAAQ,KAAK,MAAM,YAAY;AACrC,QAAI,MAAO,gBAAe,KAAK,MAAM,CAAC,CAAC;AAAA,EAC3C;AAHS;AAKT,QAAM,KAAK,gBAAgB,EAAE,OAAM,KAAK,OAAO,CAAC;AAChD,KAAG,GAAG,QAAQ,UAAQ;AAClB,QAAI,UAAU;AACV,YAAM,YAAY,iBAAiB,IAAI;AACvC,UAAI,cAAc,MAAM;AACpB,yBAAiB,SAAS;AAC1B,cAAM,SAAS,GAAG,MAAM,GAAG,SAAS;AACpC,YAAI,KAAK,QAAQ;AACb,eAAK,OAAO,MAAM;AAAA,QACtB,OAAO;AACH,kBAAQ,IAAI,MAAM;AAAA,QACtB;AAAA,MACJ;AAAA,IACJ,WAAW,aAAa;AACpB,YAAM,YAAY,YAAY,IAAI;AAClC,UAAI,cAAc,MAAM;AACpB,yBAAiB,SAAS;AAC1B,cAAM,SAAS,GAAG,MAAM,GAAG,SAAS;AACpC,YAAI,KAAK,QAAQ;AACb,eAAK,OAAO,MAAM;AAAA,QACtB,OAAO;AACH,kBAAQ,IAAI,MAAM;AAAA,QACtB;AAAA,MACJ;AAAA,IACJ,OAAO;AACH,uBAAiB,IAAI;AACrB,YAAM,SAAS,GAAG,MAAM,GAAG,IAAI;AAC/B,UAAI,KAAK,QAAQ;AACb,aAAK,OAAO,MAAM;AAAA,MACtB,OAAO;AACH,gBAAQ,IAAI,MAAM;AAAA,MACtB;AAAA,IACJ;AAAA,EACJ,CAAC;AAED,OAAK,OAAO,KAAK,SAAS;AAC1B,QAAM,QAAQ,gBAAgB,EAAE,OAAM,KAAK,OAAO,CAAC;AACnD,QAAM,GAAG,QAAQ,UAAQ;AACrB,UAAM,SAAS,GAAG,MAAM,GAAG,IAAI;AAC/B,QAAI,KAAK,QAAQ;AACb,WAAK,OAAO,MAAM;AAAA,IACtB,OAAO;AACH,cAAQ,MAAM,MAAM;AAAA,IACxB;AAAA,EACJ,CAAC;AAED,QAAM,UAAU,WAAW,MAAM;AAC7B,QAAI,CAAC,KAAK,QAAQ;AACd,cAAQ;AAAA,QACJ,yBACG,KAAK,OAAO;AAAA,MACnB;AACA,WAAK,KAAK,SAAS;AAAA,IACvB;AAAA,EACJ,GAAG,KAAK,UAAU,GAAI;AAEtB,MAAI,CAAC,YAAY;AACb,SAAK,MAAM,MAAM,KAAK,MAAM;AAAA,EAChC;AACA,OAAK,MAAM,IAAI;AAEf,SAAO,IAAI,QAAqB,aAAW;AACvC,SAAK,GAAG,SAAS,UAAQ;AACrB,mBAAa,OAAO;AACpB,SAAG,MAAM;AACT,YAAM,MAAM;AACZ,gBAAU,IAAI;AACd,UAAI,WAAY,mBAAkB,UAAU;AAC5C,cAAQ;AAAA,QACJ,UAAS,QAAQ;AAAA,QACjB;AAAA,MACJ,CAAC;AAAA,IACL,CAAC;AACD,SAAK,GAAG,SAAS,SAAO;AACpB,mBAAa,OAAO;AACpB,SAAG,MAAM;AACT,YAAM,MAAM;AACZ,gBAAU,IAAI;AACd,UAAI,WAAY,mBAAkB,UAAU;AAC5C,cAAQ;AAAA,QACJ;AAAA,QACA,mBAAmB,GAAG;AAAA,MAC1B;AACA,cAAQ,EAAE,UAAS,GAAG,eAAe,CAAC;AAAA,IAC1C,CAAC;AAAA,EACL,CAAC;AACL;AA1IgB;AA4IT,SAAS,OACZ,SACA,UACG;AACH,cAAY,OAAO;AAEnB,UAAQ,IAAI,yBAAyB;AACrC,aAAW,EAAE,MAAM,MAAM,KAAK,cAAc,OAAO,GAAG;AAClD,YAAQ;AAAA,MACJ,UAAU,IAAI,OACd,MAAM,IAAI,OAAK,EAAE,QAAQ,EAAE,KAAK,IAAI;AAAA,IACxC;AAAA,EACJ;AAEA,QAAM,QAAQ,gBAAgB,OAAO;AACrC,MAAI,MAAM,SAAS,GAAG;AAClB,YAAQ;AAAA,MACJ,2BACA,MAAM,IAAI,OAAK,EAAE,QAAQ,EAAE,KAAK,IAAI;AAAA,IACxC;AAAA,EACJ;AAEA,QAAM,aAAa,iBAAiB,OAAO;AAC3C,MAAI,WAAW,SAAS,GAAG;AACvB,YAAQ;AAAA,MACJ;AAAA,iCACI,WAAW,CAAC,EAAE,QAAQ;AAAA;AAAA,IAC9B;AACA,YAAQ;AAAA,MACJ,aAAa,UAAU,WAAW,CAAC,CAAC;AAAA,IACxC;AAAA,EACJ;AACJ;AAhCgB;AAkCT,SAAS,eAAgB,MAMxB;AACJ,cAAY,KAAK,OAAO;AAExB,UAAQ,IAAI,yBAAyB;AACrC,aAAW,EAAE,MAAM,MAAM,KAAK;AAAA,IAC1B,KAAK;AAAA,EACT,GAAG;AACC,YAAQ;AAAA,MACJ,UAAU,IAAI,OACd,MAAM,IAAI,OAAK,EAAE,QAAQ,EAAE,KAAK,IAAI;AAAA,IACxC;AACA,eAAW,KAAK,OAAO;AACnB,YAAM,MAAM,OAAO,EAAE,GAAG,EAAE,SAAS,GAAG,GAAG;AACzC,YAAM,aACF,GAAG,KAAK,QAAQ,IAAI,GAAG,IAAI,EAAE,IAAI;AACrC,YAAM,eACF,MAAM,KAAK,QAAQ,IAAI,GAAG,IAAI,EAAE,IAAI;AACxC,cAAQ,IAAI,iBAAiB,YAAY,EAAE;AAC3C,cAAQ,IAAI,iBAAiB,UAAU,EAAE;AAAA,IAC7C;AAAA,EACJ;AAEA,QAAM,QAAQ,gBAAgB,KAAK,OAAO;AAC1C,MAAI,MAAM,SAAS,GAAG;AAClB,YAAQ;AAAA,MACJ,2BACA,MAAM,IAAI,OAAK,EAAE,QAAQ,EAAE,KAAK,IAAI;AAAA,IACxC;AAAA,EACJ;AAEA,QAAM,aAAa,iBAAiB,KAAK,OAAO;AAChD,MAAI,WAAW,SAAS,GAAG;AACvB,YAAQ;AAAA,MACJ;AAAA,iCACI,WAAW,CAAC,EAAE,QAAQ;AAAA;AAAA,IAC9B;AACA,YAAQ;AAAA,MACJ,aAAa,KAAK,UAAU,WAAW,CAAC,CAAC;AAAA,IAC7C;AAAA,EACJ;AAEA,QAAM,eACF,KAAK,qBAAqB,YACtB,uCACA;AACR,UAAQ;AAAA,IACJ;AAAA,kBAAqB,YAAY;AAAA,EACrC;AACA,UAAQ,IAAI,kBAAkB,KAAK,YAAY,EAAE;AACrD;AAvDgB;AA4DhB,eAAe,qBAAsB,MAYjB;AAChB,QAAM;AAAA,IACF,KAAK;AAAA,IAAc,KAAK;AAAA,EAC5B;AAEA,QAAM,OAAO,KAAK,KAAK,OAAO,QAAQ;AAEtC,MAAI,KAAK,QAAQ;AACb,SAAK,OAAO,IAAI;AAAA,EACpB,OAAO;AACH,YAAQ,IAAI,IAAI;AAAA,EACpB;AAEA,QAAM,SAAS,aAAa,KAAK,UAAU,KAAK,MAAM;AACtD,QAAM,UAAU;AAAA,IACZ,KAAK;AAAA,IACL,KAAK,OAAO,SAAS,QAAQ,SAAS,cAAc;AAAA,EACxD;AACA,QAAM,QAAQ,KAAK,OAAO,SAAS;AAAA,IAC/B;AAAA,IAAS;AAAA,EACb;AACA,QAAM,SAAS,MAAM,WAAW;AAAA,IAC5B;AAAA,IACA,UAAS,KAAK;AAAA,IACd,OAAM,KAAK;AAAA,IACX,SAAQ,KAAK;AAAA,IACb;AAAA,IACA,KAAI,KAAK;AAAA,IACT;AAAA,IACA,QAAO,KAAK;AAAA,EAChB,CAAC;AAED,MAAI,OAAO,aAAa,GAAG;AACvB,UAAM,OAAO,KAAK,KAAK,OAAO,QAAQ,4BACxB,OAAO,QAAQ;AAC7B,QAAI,KAAK,QAAQ;AACb,WAAK,OAAO,IAAI;AAAA,IACpB,OAAO;AACH,cAAQ,IAAI,IAAI;AAAA,IACpB;AACA,WAAO;AAAA,EACX;AAEA,QAAM,SAAS,MAAM;AAAA,IACjB,KAAK;AAAA,IAAU,KAAK;AAAA,EACxB;AACA,MAAI,CAAC,QAAQ;AACT,UAAM,OAAO,KAAK,KAAK,OAAO,QAAQ;AAEtC,QAAI,KAAK,QAAQ;AACb,WAAK,OAAO,IAAI;AAAA,IACpB,OAAO;AACH,cAAQ,IAAI,IAAI;AAAA,IACpB;AAAA,EACJ;AACA,SAAO;AACX;AApEe;AAsEf,eAAsB,SAClB,SACA,UACA,UACA,OACA,SACA,SACA,SAC2B;AAC3B,YAAU,SAAS,EAAE,WAAU,KAAK,CAAC;AAErC,QAAM,IAAI,WAAW,cAAc;AACnC,MAAI,aAAa;AACjB,aAAW,KAAK,cAAc,OAAO,EAAG;AAExC,MAAI,iBAAiB;AACrB,MAAI,UAAU;AAEd,SAAO,MAAM;AACT,UAAM,QAAQ,iBAAiB,OAAO;AACtC,QAAI,MAAM,WAAW,EAAG;AAExB;AACA,MAAE;AAAA,MACE;AAAA,MACA;AAAA,MACA,MAAM,IAAI,QAAM;AAAA,QACZ,KAAI,EAAE;AAAA,QACN,UAAS,EAAE;AAAA,MACf,EAAE;AAAA,IACN;AAEA,UAAM,UAAU,MAAM,QAAQ;AAAA,MAC1B,MAAM,IAAI,OAAM,MAAK;AACjB,cAAM,SAAS,aAAa,UAAU,CAAC;AACvC,cAAM,UAAU;AAAA,UACZ;AAAA,UACA,EAAE,SAAS,QAAQ,SAAS,MAAM;AAAA,QACtC;AACA,cAAM,QAAQ,EAAE,SAAS;AAAA,UACrB;AAAA,UAAS;AAAA,QACb;AACA,UAAE,gBAAgB,EAAE,KAAK,aAAa;AACtC,UAAE,IAAI,cAAc,EAAE,QAAQ,EAAE;AAChC,cAAM,SAAS,MAAM,WAAW;AAAA,UAC5B;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA,QAAO,wBAAC,SAAS,EAAE,IAAI,IAAI,GAApB;AAAA,QACX,CAAC;AACD,eAAO,EAAE,QAAO,GAAG,OAAO;AAAA,MAC9B,CAAC;AAAA,IACL;AAEA,QAAI,gBAAgB;AACpB,eAAW,KAAK,SAAS;AACrB,UAAI,EAAE,WAAW,WAAY;AAC7B,YAAM,EAAE,QAAQ,OAAO,IAAI,EAAE;AAC7B,UAAI,OAAO,aAAa,GAAG;AACvB,UAAE,gBAAgB,OAAO,KAAK,QAAQ;AACtC,UAAE;AAAA,UACE,KAAK,OAAO,QAAQ,kBACJ,OAAO,QAAQ;AAAA,QACnC;AACA;AAAA,MACJ;AAEA,iBAAW,QAAQ,OAAO,cAAc;AACxC,eAAS,MAAM;AACf;AACA;AACA,QAAE,gBAAgB,OAAO,KAAK,MAAM;AACpC,QAAE;AAAA,QACE,KAAK,OAAO,QAAQ;AAAA,MACxB;AAAA,IACJ;AAEA,QAAI,kBAAkB,GAAG;AACrB,QAAE;AAAA,QACE;AAAA,MAEJ;AACA;AAAA,IACJ;AAAA,EACJ;AAEA,QAAM,YAAY,QAAQ;AAAA,IACtB,OAAK,EAAE,WAAW;AAAA,EACtB;AACA,IAAE;AAAA,IACE;AAAA,YAAe,cAAc,gBAC5B,UAAU,SAAS,IAChB,KAAK,UAAU,MAAM,eACrB;AAAA,EACR;AACA,IAAE,QAAQ;AAEV,SAAO,EAAE,SAAQ,UAAU,WAAW,EAAE;AAC5C;AArGsB;AAuGtB,eAAsB,iBAAkB,MAUR;AAC5B,YAAU,KAAK,SAAS,EAAE,WAAU,KAAK,CAAC;AAE1C,QAAM,IAAI,KAAK,WAAW,cAAc;AACxC,MAAI,aAAa;AACjB,aAAW,KAAK,cAAc,KAAK,OAAO,EAAG;AAE7C,QAAM,WAAW,YAAY;AAC7B,QAAM,WAAW,YAAY;AAC7B,QAAM,aAAa,iBAAiB;AAEpC,QAAM,eAAe;AAAA,IACjB,QAAQ,KAAK,OAAO;AAAA,IAAG;AAAA,EAC3B;AACA,QAAM,WAAwB;AAAA,IAC1B,iBAAiB,KAAK,aAAa,KAAK,OAAO;AAAA,IAC/C,aAAa,YAAY;AAAA,EAC7B;AACA,gBAAc,cAAc,QAAQ;AACpC,QAAM;AAAA,IACF;AAAA,IACA;AAAA,IACA,qBAAqB,KAAK,WAAW;AAAA,EACzC;AAEA,MAAI,iBAAiB;AACrB,MAAI,UAAU;AAEd,SAAO,MAAM;AACT,UAAM,QAAQ,iBAAiB,KAAK,OAAO;AAC3C,QAAI,MAAM,WAAW,EAAG;AAExB;AACA,MAAE;AAAA,MACE;AAAA,MACA;AAAA,MACA,MAAM,IAAI,QAAM;AAAA,QACZ,KAAI,EAAE;AAAA,QACN,UAAS,EAAE;AAAA,MACf,EAAE;AAAA,IACN;AAEA,UAAM,kBAAkB,MAAM,QAAQ;AAAA,MAClC,MAAM,IAAI,OAAK,eAAe;AAAA,QAC1B;AAAA,QACA;AAAA,QACA;AAAA,QACA,QAAO;AAAA,MACX,CAAC,CAAC;AAAA,IACN;AAEA,UAAM,gBAA8B,CAAC;AACrC,UAAM,YAGD,CAAC;AAEN,aAAS,IAAI,GAAG,IAAI,gBAAgB,QAAQ,KAAK;AAC7C,YAAM,UAAU,gBAAgB,CAAC;AACjC,YAAM,SAAS,MAAM,CAAC;AACtB,UAAI,QAAQ,WAAW,YAAY;AAC/B,UAAE,gBAAgB,OAAO,KAAK,QAAQ;AACtC,UAAE;AAAA,UACE,KAAK,OAAO,QAAQ,gCACP,mBAAmB,QAAQ,MAAM,CAAC;AAAA,QACnD;AACA;AAAA,MACJ;AACA,oBAAc,KAAK,MAAM;AACzB,gBAAU,KAAK,QAAQ,KAAK;AAAA,IAChC;AAEA,UAAM,UAAU,MAAM,QAAQ;AAAA,MAC1B,cAAc,IAAI,CAAC,GAAG,MAAM;AACxB,cAAM,SAAS,aAAa,KAAK,UAAU,CAAC;AAC5C,cAAM,UAAU;AAAA,UACZ,KAAK;AAAA,UACL,EAAE,SAAS,QAAQ,SAAS,MAAM;AAAA,QACtC;AACA,cAAM,QAAQ,EAAE,SAAS;AAAA,UACrB;AAAA,UAAS;AAAA,QACb;AACA,UAAE,gBAAgB,EAAE,KAAK,aAAa;AACtC,UAAE,IAAI,cAAc,EAAE,QAAQ,EAAE;AAChC,eAAO,WAAW;AAAA,UACd;AAAA,UACA,UAAS,KAAK;AAAA,UACd,OAAM,KAAK;AAAA,UACX,SAAQ,KAAK;AAAA,UACb;AAAA,UACA,KAAI,UAAU,CAAC,EAAE;AAAA,UACjB;AAAA,UACA,QAAO,wBAAC,SAAS,EAAE,IAAI,IAAI,GAApB;AAAA,QACX,CAAC;AAAA,MACL,CAAC;AAAA,IACL;AAEA,QAAI,gBAAgB;AACpB,UAAM,qBAID,CAAC;AACN,UAAM,eAAe,oBAAI,IAAoB;AAC7C,UAAM,qBAAqB,oBAAI,IAAoB;AAEnD,aAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACrC,YAAM,IAAI,QAAQ,CAAC;AACnB,UAAI,EAAE,WAAW,WAAY;AAC7B,YAAM,cAAc,EAAE;AACtB,YAAM,SAAS,cAAc,CAAC;AAC9B,YAAM,WAAW,UAAU,CAAC;AAE5B,UAAI,YAAY,aAAa,GAAG;AAC5B,UAAE,gBAAgB,OAAO,KAAK,QAAQ;AACtC,UAAE;AAAA,UACE,KAAK,OAAO,QAAQ,kBACJ,YAAY,QAAQ;AAAA,QACxC;AACA,mBAAW,QAAQ,YAAY,cAAc;AAC7C,oBAAY,UAAU,OAAO,KAAK;AAAA,UAC9B,QAAO,SAAS;AAAA,UAChB,UAAS,YAAY;AAAA,UACrB,MAAK;AAAA,QACT,CAAC;AACD,sBAAc,cAAc,QAAQ;AACpC,cAAM;AAAA,UACF;AAAA,UACA;AAAA,UACA,eAAe,OAAO,QAAQ;AAAA,QAClC;AAEA,YAAI;AACA,gBAAM,eAAe,SAAS,YAAY;AAAA,QAC9C,SAAS,KAAK;AACV,YAAE;AAAA,YACE,+BACG,SAAS,YAAY,OACxB,mBAAmB,GAAG;AAAA,UAC1B;AAAA,QACJ;AACA;AAAA,MACJ;AAEA,UAAI,QAAQ,SAAS,YAAY,GAAG;AAChC,cAAM,YAAY,MAAM;AAAA,UACpB,SAAS;AAAA,UACT,2BACG,OAAO,QAAQ;AAAA,QACtB;AACA,YAAI,WAAW;AACX,YAAE;AAAA,YACE,KAAK,OAAO,QAAQ;AAAA,UAExB;AAAA,QACJ;AAAA,MACJ;AAEA,UAAI,CAAC;AAAA,QACD;AAAA,QAAU;AAAA,QAAY,SAAS;AAAA,MACnC,GAAG;AACC,UAAE,gBAAgB,OAAO,KAAK,QAAQ;AACtC,UAAE;AAAA,UACE,KAAK,OAAO,QAAQ;AAAA,QAGxB;AACA;AAAA,MACJ;AAEA,iBAAW,QAAQ,YAAY,cAAc;AAC7C,QAAE;AAAA,QACE,KAAK,OAAO,QAAQ;AAAA,MAExB;AACA,mBAAa,IAAI,OAAO,KAAK,MAAM;AACnC,yBAAmB;AAAA,QACf,OAAO;AAAA,QAAK,SAAS;AAAA,MACzB;AACA,yBAAmB,KAAK;AAAA,QACpB,QAAO,SAAS;AAAA,QAChB,WAAU,OAAO;AAAA,QACjB,cAAa,SAAS;AAAA,MAC1B,CAAC;AAAA,IACL;AAEA,QAAI,mBAAmB,SAAS,GAAG;AAC/B,YAAM,cAAc,MAAM,UAAU;AAAA,QAChC;AAAA,QACA;AAAA,QACA,UAAS;AAAA,QACT,UAAS,KAAK;AAAA,MAClB,CAAC;AAED,iBAAW,gBAAgB,YAAY,QAAQ;AAC3C,cAAM,SAAS,aAAa;AAAA,UACxB,aAAa;AAAA,QACjB;AACA,YAAI,CAAC,OAAQ;AAEb,YAAI,aAAa,QAAQ;AACrB,mBAAS,MAAM;AACf;AACA;AACA,YAAE,gBAAgB,OAAO,KAAK,MAAM;AACpC,YAAE;AAAA,YACE,KAAK,OAAO,QAAQ;AAAA,UACxB;AACA,sBAAY,UAAU,OAAO,KAAK;AAAA,YAC9B,QAAO,aAAa;AAAA,YACpB,UAAS;AAAA,UACb,CAAC;AACD,wBAAc,cAAc,QAAQ;AACpC,gBAAM;AAAA,YACF;AAAA,YACA;AAAA,YACA,eAAe,OAAO,QAAQ;AAAA,UAClC;AAEA,gBAAM,eAAe,mBAAmB;AAAA,YACpC,OAAO;AAAA,UACX;AACA,cAAI,cAAc;AACd,gBAAI;AACA,oBAAM,eAAe,YAAY;AAAA,YACrC,SAAS,KAAK;AACV,gBAAE;AAAA,gBACE,+BACG,YAAY,OACf,mBAAmB,GAAG;AAAA,cAC1B;AAAA,YACJ;AAAA,UACJ;AAAA,QACJ,OAAO;AACH,gBAAM,eAAe,mBAAmB;AAAA,YACpC,OAAO;AAAA,UACX;AACA,gBAAM,YACF,KAAK,qBAAqB,aAC1B,eACI,MAAM,qBAAqB;AAAA,YACvB;AAAA,YACA;AAAA,YACA,QAAO,aAAa;AAAA,YACpB;AAAA,YACA;AAAA,YACA,UAAS,KAAK;AAAA,YACd,UAAS,KAAK;AAAA,YACd,OAAM,KAAK;AAAA,YACX,SAAQ,KAAK;AAAA,YACb,SAAQ,KAAK;AAAA,YACb,QAAO,wBAAC,QAAQ,EAAE,IAAI,GAAG,GAAlB;AAAA,UACX,CAAC,IACD;AAER,cAAI,WAAW;AACX,qBAAS,MAAM;AACf;AACA;AACA,cAAE,gBAAgB,OAAO,KAAK,MAAM;AACpC,cAAE;AAAA,cACE,KAAK,OAAO,QAAQ;AAAA,YAExB;AACA,wBAAY,UAAU,OAAO,KAAK;AAAA,cAC9B,QAAO,aAAa;AAAA,cACpB,UAAS;AAAA,YACb,CAAC;AACD,0BAAc,cAAc,QAAQ;AACpC,kBAAM;AAAA,cACF;AAAA,cACA;AAAA,cACA,eAAe,OAAO,QAAQ;AAAA,YAElC;AAEA,gBAAI,cAAc;AACd,kBAAI;AACA,sBAAM,eAAe,YAAY;AAAA,cACrC,SAAS,KAAK;AACV,kBAAE;AAAA,kBACE,+BACG,YAAY,OACf,mBAAmB,GAAG;AAAA,gBAC1B;AAAA,cACJ;AAAA,YACJ;AAAA,UACJ,OAAO;AACH,cAAE;AAAA,cACE,KAAK,OAAO,QAAQ;AAAA,YAExB;AAAA,UACJ;AAAA,QACJ;AAAA,MACJ;AAEA,UAAI,YAAY,WAAW;AACvB,UAAE;AAAA,UACE;AAAA,mBACG,YAAY,UAAU,MAAM;AAAA,QACnC;AAEA,mBAAW,MAAM,oBAAoB;AACjC,gBAAM,SAAS,aAAa,IAAI,GAAG,SAAS;AAC5C,cAAI,UAAU,OAAO,WAAW,OAAQ;AACxC,cAAI;AACA,kBAAM,eAAe,GAAG,YAAY;AAAA,UACxC,SAAS,KAAK;AACV,cAAE;AAAA,cACE,+BACG,GAAG,YAAY,OAClB,mBAAmB,GAAG;AAAA,YAC1B;AAAA,UACJ;AAAA,QACJ;AAEA;AAAA,MACJ;AAAA,IACJ;AAEA,QAAI,kBAAkB,GAAG;AACrB,QAAE;AAAA,QACE;AAAA,MAEJ;AACA;AAAA,IACJ;AAAA,EACJ;AAEA,QAAM,YAAY,KAAK,QAAQ;AAAA,IAC3B,OAAK,EAAE,WAAW;AAAA,EACtB;AACA,IAAE;AAAA,IACE;AAAA,YAAe,cAAc,gBAC5B,UAAU,SAAS,IAChB,KAAK,UAAU,MAAM,eACrB;AAAA,EACR;AACA,IAAE,QAAQ;AAEV,SAAO,EAAE,SAAQ,UAAU,WAAW,EAAE;AAC5C;AA/VsB;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
export type TicketStatus = 'pending' | 'in-progress' | 'done' | 'failed';
|
|
2
|
+
export type DisplayTicket = {
|
|
3
|
+
readonly num: number;
|
|
4
|
+
readonly filename: string;
|
|
5
|
+
status: TicketStatus;
|
|
6
|
+
};
|
|
7
|
+
export type WaveState = {
|
|
8
|
+
readonly waveNum: number;
|
|
9
|
+
readonly totalWaves: number;
|
|
10
|
+
readonly tickets: Array<DisplayTicket>;
|
|
11
|
+
};
|
|
12
|
+
export type DisplayConfig = {
|
|
13
|
+
readonly messageLines: number;
|
|
14
|
+
readonly stream: NodeJS.WriteStream;
|
|
15
|
+
};
|
|
16
|
+
export type Display = {
|
|
17
|
+
startWave(waveNum: number, totalWaves: number, tickets: ReadonlyArray<{
|
|
18
|
+
num: number;
|
|
19
|
+
filename: string;
|
|
20
|
+
}>): void;
|
|
21
|
+
setTicketStatus(num: number, status: TicketStatus): void;
|
|
22
|
+
log(message: string): void;
|
|
23
|
+
cleanup(): void;
|
|
24
|
+
};
|
|
25
|
+
export declare const ansi: {
|
|
26
|
+
readonly cursorUp: (n: number) => string;
|
|
27
|
+
readonly cursorTo: (col: number) => string;
|
|
28
|
+
readonly eraseLine: () => string;
|
|
29
|
+
readonly eraseLines: (n: number) => string;
|
|
30
|
+
readonly cursorHide: () => string;
|
|
31
|
+
readonly cursorShow: () => string;
|
|
32
|
+
};
|
|
33
|
+
export declare const color: {
|
|
34
|
+
readonly green: (text: string) => string;
|
|
35
|
+
readonly yellow: (text: string) => string;
|
|
36
|
+
readonly red: (text: string) => string;
|
|
37
|
+
readonly dim: (text: string) => string;
|
|
38
|
+
};
|
|
39
|
+
export declare function renderDot(status: TicketStatus): string;
|
|
40
|
+
export declare class StatusDisplay implements Display {
|
|
41
|
+
private wave;
|
|
42
|
+
private messages;
|
|
43
|
+
private renderedLines;
|
|
44
|
+
private config;
|
|
45
|
+
private viewportStart;
|
|
46
|
+
private resizeListener;
|
|
47
|
+
private signalHandler;
|
|
48
|
+
constructor(config?: Readonly<Partial<DisplayConfig>>);
|
|
49
|
+
private getAvailableRows;
|
|
50
|
+
startWave(waveNum: number, totalWaves: number, tickets: Array<Readonly<{
|
|
51
|
+
num: number;
|
|
52
|
+
filename: string;
|
|
53
|
+
}>>): void;
|
|
54
|
+
setTicketStatus(num: number, status: TicketStatus): void;
|
|
55
|
+
log(message: string): void;
|
|
56
|
+
cleanup(): void;
|
|
57
|
+
private render;
|
|
58
|
+
}
|
|
59
|
+
export declare class PlainDisplay implements Display {
|
|
60
|
+
startWave(waveNum: number, _totalWaves: number, tickets: ReadonlyArray<{
|
|
61
|
+
num: number;
|
|
62
|
+
filename: string;
|
|
63
|
+
}>): void;
|
|
64
|
+
setTicketStatus(_num: number, _status: TicketStatus): void;
|
|
65
|
+
log(message: string): void;
|
|
66
|
+
cleanup(): void;
|
|
67
|
+
}
|
|
68
|
+
export declare function createDisplay(stream?: NodeJS.WriteStream): Display;
|
|
69
|
+
//# sourceMappingURL=display.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"display.d.ts","sourceRoot":"","sources":["../../src/display.ts"],"names":[],"mappings":"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"}
|
package/dist/src/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AAgBA,OAAO,EACH,eAAe,EACf,gBAAgB,EAEnB,MAAM,cAAc,CAAA;AAGrB,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,CAAA"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type MergeConflictStrategy } from './merge.js';
|
|
2
|
+
import { type Display } from './display.js';
|
|
2
3
|
export type Ticket = {
|
|
3
4
|
num: number;
|
|
4
5
|
slug: string;
|
|
@@ -18,11 +19,17 @@ export declare function parseStatus(body: string): string;
|
|
|
18
19
|
export declare function parseBlockers(body: string): number[];
|
|
19
20
|
export declare function scanTickets(dir: string): Ticket[];
|
|
20
21
|
export declare function findReadyTickets(tickets: ReadonlyArray<Ticket>): Ticket[];
|
|
22
|
+
export declare const COMPLETED_RE: RegExp;
|
|
23
|
+
export declare function checkItems(ticket: Ticket, completedItems: string[]): void;
|
|
21
24
|
export declare function markDone(ticket: Ticket): void;
|
|
22
25
|
export declare function renderPrompt(specBody: string, ticket: Ticket): string;
|
|
23
26
|
export declare function getProviderArgs(cmd: string): string[];
|
|
24
27
|
export declare function formatStreamLine(line: string): string | null;
|
|
25
|
-
export declare function createPiStreamFormatter(): (line: string) => string | null;
|
|
28
|
+
export declare function createPiStreamFormatter(): ((line: string) => string | null);
|
|
29
|
+
export type AgentResult = {
|
|
30
|
+
exitCode: number;
|
|
31
|
+
completedItems: string[];
|
|
32
|
+
};
|
|
26
33
|
export declare function spawnAgent(opts: {
|
|
27
34
|
prompt: string;
|
|
28
35
|
agentCmd: string;
|
|
@@ -31,7 +38,8 @@ export declare function spawnAgent(opts: {
|
|
|
31
38
|
logPath: string;
|
|
32
39
|
cwd?: string;
|
|
33
40
|
label?: string;
|
|
34
|
-
|
|
41
|
+
onLine?: (line: string) => void;
|
|
42
|
+
}): Promise<AgentResult>;
|
|
35
43
|
export declare function dryRun(tickets: Array<Ticket>, specBody: string): void;
|
|
36
44
|
export declare function dryRunIsolated(opts: {
|
|
37
45
|
tickets: Array<Ticket>;
|
|
@@ -40,7 +48,7 @@ export declare function dryRunIsolated(opts: {
|
|
|
40
48
|
conflictStrategy: MergeConflictStrategy;
|
|
41
49
|
progressPath: string;
|
|
42
50
|
}): void;
|
|
43
|
-
export declare function runWaves(tickets: Ticket[], specBody: string, agentCmd: string, model: string | null, timeout: number, logsDir: string): Promise<{
|
|
51
|
+
export declare function runWaves(tickets: Ticket[], specBody: string, agentCmd: string, model: string | null, timeout: number, logsDir: string, display?: Display): Promise<{
|
|
44
52
|
allDone: boolean;
|
|
45
53
|
}>;
|
|
46
54
|
export declare function runWavesIsolated(opts: {
|
|
@@ -52,6 +60,7 @@ export declare function runWavesIsolated(opts: {
|
|
|
52
60
|
logsDir: string;
|
|
53
61
|
featureName: string;
|
|
54
62
|
conflictStrategy: MergeConflictStrategy;
|
|
63
|
+
display?: Display;
|
|
55
64
|
}): Promise<{
|
|
56
65
|
allDone: boolean;
|
|
57
66
|
}>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"orchestrator.d.ts","sourceRoot":"","sources":["../../src/orchestrator.ts"],"names":[],"mappings":"AA+BA,OAAO,EAIH,KAAK,qBAAqB,EAC7B,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"orchestrator.d.ts","sourceRoot":"","sources":["../../src/orchestrator.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nightralph",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.9",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Orchestrator that runs a single-agent session per issue.",
|
|
6
6
|
"bin": {
|
|
@@ -17,14 +17,14 @@
|
|
|
17
17
|
"lint": "eslint \"./**/*.{ts,js}\"",
|
|
18
18
|
"start": "npm run build && node dist/index.js",
|
|
19
19
|
"build": "mkdir -p ./dist && rm -rf ./dist/* && npm run build-esm && npm run copy",
|
|
20
|
-
"build-esm": "esbuild src/index.ts src/orchestrator.ts src/setup.ts src/resolve.ts src/worktree.ts src/progress.ts src/merge.ts --format=esm --metafile=dist/meta.json --keep-names --tsconfig=tsconfig.build.json --outdir=./dist --sourcemap && tsc --emitDeclarationOnly --project tsconfig.build.json",
|
|
20
|
+
"build-esm": "esbuild src/index.ts src/orchestrator.ts src/setup.ts src/resolve.ts src/worktree.ts src/progress.ts src/merge.ts src/display.ts --format=esm --metafile=dist/meta.json --keep-names --tsconfig=tsconfig.build.json --outdir=./dist --sourcemap && tsc --emitDeclarationOnly --project tsconfig.build.json",
|
|
21
21
|
"copy": "mkdir -p ./dist/skills ./dist/docs-templates && cp -r ./src/skills/* ./dist/skills && cp -r ./src/docs-templates/* ./dist/docs-templates",
|
|
22
22
|
"clone-skills": "bash scripts/clone-skills.sh",
|
|
23
23
|
"toc": "markdown-toc --maxdepth 3 -i README.md",
|
|
24
24
|
"preversion": "npm run lint",
|
|
25
25
|
"version": "npm run toc",
|
|
26
26
|
"postversion": "git push --follow-tags && npm publish",
|
|
27
|
-
"test": "esbuild test/setup.test.ts test/orchestrator.test.ts test/worktree.test.ts test/progress.test.ts test/merge.test.ts test/integration.test.ts --format=esm --bundle --packages=external --outdir=dist/test --sourcemap && node dist/test/setup.test.js && node dist/test/orchestrator.test.js && node dist/test/worktree.test.js && node dist/test/progress.test.js && node dist/test/merge.test.js && node dist/test/integration.test.js"
|
|
27
|
+
"test": "esbuild test/setup.test.ts test/orchestrator.test.ts test/worktree.test.ts test/progress.test.ts test/merge.test.ts test/display.test.ts test/integration.test.ts --format=esm --bundle --packages=external --outdir=dist/test --sourcemap && node dist/test/setup.test.js && node dist/test/orchestrator.test.js && node dist/test/worktree.test.js && node dist/test/progress.test.js && node dist/test/merge.test.js && node dist/test/display.test.js && node dist/test/integration.test.js"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"@inquirer/prompts": "^8.7.0",
|