nightralph 0.0.22 → 0.0.23

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/dist/meta.json CHANGED
@@ -27,7 +27,7 @@
27
27
  "format": "esm"
28
28
  },
29
29
  "src/worktree.ts": {
30
- "bytes": 4846,
30
+ "bytes": 5108,
31
31
  "imports": [
32
32
  {
33
33
  "path": "node:child_process",
@@ -116,7 +116,7 @@
116
116
  "format": "esm"
117
117
  },
118
118
  "src/testcmd.ts": {
119
- "bytes": 2195,
119
+ "bytes": 2463,
120
120
  "imports": [
121
121
  {
122
122
  "path": "node:child_process",
@@ -142,7 +142,7 @@
142
142
  "format": "esm"
143
143
  },
144
144
  "src/orchestrator.ts": {
145
- "bytes": 56085,
145
+ "bytes": 57999,
146
146
  "imports": [
147
147
  {
148
148
  "path": "node:child_process",
@@ -305,7 +305,7 @@
305
305
  "imports": [],
306
306
  "exports": [],
307
307
  "inputs": {},
308
- "bytes": 161686
308
+ "bytes": 165335
309
309
  },
310
310
  "dist/index.js": {
311
311
  "imports": [
@@ -468,10 +468,10 @@
468
468
  "bytesInOutput": 4339
469
469
  },
470
470
  "src/orchestrator.ts": {
471
- "bytesInOutput": 39685
471
+ "bytesInOutput": 40993
472
472
  },
473
473
  "src/worktree.ts": {
474
- "bytesInOutput": 3537
474
+ "bytesInOutput": 3788
475
475
  },
476
476
  "src/progress.ts": {
477
477
  "bytesInOutput": 4419
@@ -483,13 +483,13 @@
483
483
  "bytesInOutput": 7877
484
484
  },
485
485
  "src/testcmd.ts": {
486
- "bytesInOutput": 1620
486
+ "bytesInOutput": 1911
487
487
  },
488
488
  "src/resolve.ts": {
489
489
  "bytesInOutput": 1937
490
490
  }
491
491
  },
492
- "bytes": 75751
492
+ "bytes": 77601
493
493
  }
494
494
  }
495
495
  }
@@ -219,6 +219,7 @@ function renderMergePrompt(specBody, ticket) {
219
219
  "3. Commit the resolved files.",
220
220
  "",
221
221
  "Do NOT re-implement the ticket from scratch.",
222
+ "Do NOT read or modify files outside your current directory (the worktree).",
222
223
  "Do NOT run git push."
223
224
  ].join("\n");
224
225
  }
@@ -600,6 +601,7 @@ function spawnAgent(opts) {
600
601
  __name(finish, "finish");
601
602
  proc.on("exit", (code) => {
602
603
  graceTimer = setTimeout(() => {
604
+ killProcessGroup(proc.pid);
603
605
  proc.stdout.destroy();
604
606
  proc.stderr.destroy();
605
607
  finish(code ?? 1);
@@ -710,7 +712,7 @@ Test command: ${opts.testCmd ?? "(none)"}`
710
712
  `Retries: ${opts.retries ?? DEFAULT_RETRIES}`
711
713
  );
712
714
  console.log(
713
- `Retry delay: ${opts.retryDelay ?? DEFAULT_RETRY_DELAY}s`
715
+ `Retry delay: ${opts.retryDelay ?? 0}s`
714
716
  );
715
717
  console.log(
716
718
  `
@@ -723,7 +725,8 @@ async function runTestGate(opts) {
723
725
  const result = await runTestCmd({
724
726
  cmd: opts.testCmd,
725
727
  cwd: opts.worktreePath,
726
- timeout: opts.timeout
728
+ timeout: opts.timeout,
729
+ registry: opts.registry
727
730
  });
728
731
  const testLogPath = attemptLogPath(
729
732
  opts.logsDir,
@@ -799,7 +802,8 @@ async function respawnAndRetryMerge(opts) {
799
802
  worktreePath: opts.worktreePath,
800
803
  timeout: opts.timeout,
801
804
  logsDir: opts.logsDir,
802
- log
805
+ log,
806
+ registry: runningAgents
803
807
  });
804
808
  if (!passed) {
805
809
  log(
@@ -915,7 +919,12 @@ async function runTicketAttempt(opts) {
915
919
  opts.baseBranch,
916
920
  worktree.branchName
917
921
  )) {
918
- return { kind: "no-commits" };
922
+ await removeWorktreeQuietly(worktree.worktreePath, d);
923
+ return {
924
+ kind: "no-commits",
925
+ worktreePath: worktree.worktreePath,
926
+ branchName: worktree.branchName
927
+ };
919
928
  }
920
929
  if (opts.testCmd) {
921
930
  const passed = await runTestGate({
@@ -925,7 +934,8 @@ async function runTicketAttempt(opts) {
925
934
  timeout: opts.timeout,
926
935
  logsDir: opts.logsDir,
927
936
  attempt: opts.attempt,
928
- log: /* @__PURE__ */ __name((msg) => d.log(msg), "log")
937
+ log: /* @__PURE__ */ __name((msg) => d.log(msg), "log"),
938
+ registry: runningAgents
929
939
  });
930
940
  if (!passed) {
931
941
  await removeWorktreeQuietly(
@@ -954,7 +964,11 @@ async function runTicketAttempts(opts) {
954
964
  const maxAttempts = opts.retries + 1;
955
965
  const isPi = basename(opts.agentCmd) === "pi";
956
966
  let thinking = opts.thinking;
957
- let outcome = { kind: "no-commits" };
967
+ let outcome = {
968
+ kind: "no-commits",
969
+ worktreePath: "",
970
+ branchName: ""
971
+ };
958
972
  for (let attempt = 1; attempt <= maxAttempts; attempt++) {
959
973
  if (attempt === 1) {
960
974
  d.log(` Starting ${ticket.filename}`);
@@ -1215,6 +1229,18 @@ async function runWavesIsolated(opts) {
1215
1229
  d.log(
1216
1230
  ` ${ticket.filename}: failed to create worktree: ${formatErrorMessage(outcome.error)}`
1217
1231
  );
1232
+ checkTicket(progress, ticket.num, {
1233
+ branch: "",
1234
+ exitCode: -1,
1235
+ done: false
1236
+ });
1237
+ await saveProgress(
1238
+ repoRoot,
1239
+ progressPath,
1240
+ progress,
1241
+ `nightralph: ${ticket.filename} worktree error`,
1242
+ d
1243
+ );
1218
1244
  continue;
1219
1245
  }
1220
1246
  if (outcome.kind === "error") {
@@ -1223,6 +1249,18 @@ async function runWavesIsolated(opts) {
1223
1249
  d.log(
1224
1250
  ` ${ticket.filename}: attempt error: ` + formatErrorMessage(outcome.error)
1225
1251
  );
1252
+ checkTicket(progress, ticket.num, {
1253
+ branch: outcome.branchName ?? "",
1254
+ exitCode: -1,
1255
+ done: false
1256
+ });
1257
+ await saveProgress(
1258
+ repoRoot,
1259
+ progressPath,
1260
+ progress,
1261
+ `nightralph: ${ticket.filename} error`,
1262
+ d
1263
+ );
1226
1264
  continue;
1227
1265
  }
1228
1266
  if (outcome.kind === "no-commits") {
@@ -1231,6 +1269,18 @@ async function runWavesIsolated(opts) {
1231
1269
  d.log(
1232
1270
  ` ${ticket.filename}: agent exited 0 but made no changes; leaving ticket ready-for-agent`
1233
1271
  );
1272
+ checkTicket(progress, ticket.num, {
1273
+ branch: outcome.branchName,
1274
+ exitCode: 0,
1275
+ done: false
1276
+ });
1277
+ await saveProgress(
1278
+ repoRoot,
1279
+ progressPath,
1280
+ progress,
1281
+ `nightralph: ${ticket.filename} no commits`,
1282
+ d
1283
+ );
1234
1284
  continue;
1235
1285
  }
1236
1286
  if (outcome.kind === "failed") {
@@ -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'\nimport {\n createDisplay,\n type RunProgress,\n type Display,\n} from './display.js'\nimport { runTestCmd } from './testcmd.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\n// Removes a ticket's worktree, logging and swallowing any\n// failure instead of letting it interrupt the wave.\nasync function removeWorktreeQuietly (\n worktreePath:string,\n d:Display\n):Promise<void> {\n try {\n await removeWorktree(worktreePath, { force:true })\n } catch (err) {\n d.log(\n ' Failed to remove worktree ' +\n `${worktreePath}: ` +\n formatErrorMessage(err)\n )\n }\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\nexport const TOOL_USE_RE = /^\\[[\\w.]+\\]/\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\n// Drops one markdown section from a spec. Used to keep the\n// per-ticket prompt short: the User Stories list is useful\n// to humans and to to-tickets but not to an implementing agent.\nexport function stripSpecSection (\n specBody:string,\n heading:string\n):string {\n const out:string[] = []\n let skipping = false\n let skipLevel = 0\n let inFence = false\n\n for (const line of specBody.split('\\n')) {\n // Toggle fence state on lines starting with ``` (after\n // optional whitespace)\n if (/^\\s*```/.test(line)) {\n inFence = !inFence\n }\n\n // Only check for headings outside of code fences\n if (!inFence) {\n const m = /^(#{1,6})\\s+(.*?)\\s*$/.exec(line)\n if (m) {\n const level = m[1].length\n if (skipping && level <= skipLevel) {\n skipping = false\n }\n if (!skipping && m[2] === heading) {\n skipping = true\n skipLevel = level\n continue\n }\n }\n }\n if (!skipping) out.push(line)\n }\n\n return out.join('\\n')\n}\n\nexport function renderPrompt (\n specBody:string,\n ticket:Ticket,\n opts:{ testCmd?:string|null } = {}\n):string {\n const testRules = opts.testCmd ?\n [\n '- Work test-first. For each checklist ' +\n 'item, write a failing test at the ' +\n 'seams named in the spec\\'s Testing ' +\n 'Decisions section, then write only ' +\n 'enough code to make it pass.',\n `- Run \\`${opts.testCmd}\\` before ` +\n 'committing. Do not commit with failing ' +\n 'tests. The orchestrator runs the same ' +\n 'command after you exit and rejects the ' +\n 'ticket if it fails.',\n ] :\n []\n\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 'Follow these rules:',\n '- Read the files directly relevant to the ' +\n 'ticket before writing code.',\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 ...testRules,\n '- Do NOT read or modify files outside ' +\n 'your current directory (the worktree).',\n '- Do NOT run git push.',\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\nexport function renderMergePrompt (\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 resolving ' +\n 'a merge conflict.',\n '',\n 'Another agent already implemented this ticket ' +\n 'on a feature branch. The branch was then ' +\n 'merged with the base branch, but conflicts ' +\n 'arose. The working tree may contain conflict ' +\n 'markers that need resolution.',\n '',\n 'Your task:',\n '1. Find and resolve all conflict markers ' +\n '(<<<<<<< / ======= / >>>>>>>).',\n '2. Make sure the code compiles and tests pass.',\n '3. Commit the resolved files.',\n '',\n 'Do NOT re-implement the ticket from scratch.',\n 'Do NOT run git push.',\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 removed --full-auto; this is the counterpart\n // of claude's --dangerously-skip-permissions, and the\n // workspace-write sandbox would block commits because\n // a worktree's .git link points outside the tree\n codex:['exec', '--dangerously-bypass-approvals-and-sandbox'],\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\n// The thinking levels pi accepts, lowest to highest.\nexport const THINKING_LEVELS = [\n 'off', 'minimal', 'low', 'medium',\n 'high', 'xhigh', 'max',\n] as const\n\nexport type ThinkingLevel = typeof THINKING_LEVELS[number]\n\n// The level for a retry. Without a starting level the\n// first retry jumps to high; otherwise step one rung up\n// and stop at max.\nexport function escalateThinking (\n level?:ThinkingLevel\n):ThinkingLevel {\n if (!level) return 'high'\n const i = THINKING_LEVELS.indexOf(level)\n return THINKING_LEVELS[\n Math.min(i + 1, THINKING_LEVELS.length - 1)\n ]\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 type PiStreamFormatter = {\n process:(line:string) => string[]\n flush:() => string[]\n}\n\nexport function createPiStreamFormatter (\n):PiStreamFormatter {\n const calls = new Map<\n number, { name:string; buf:string }\n >()\n let textBuf = ''\n\n function drainLines ():string[] {\n const parts = textBuf.split('\\n')\n if (parts.length === 1) return []\n textBuf = parts[parts.length - 1]\n return parts.slice(0, -1)\n }\n\n function flushBuf ():string[] {\n if (textBuf.length === 0) return []\n const out = textBuf\n textBuf = ''\n return [out]\n }\n\n function process (line:string):string[] {\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 []\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 const delta =\n (evt.delta as string|undefined) ?? ''\n textBuf += delta\n return drainLines()\n }\n\n if (type === 'toolcall_start') {\n const flushed = flushBuf()\n calls.set(ci, {\n name:(evt.toolName as\n string|undefined) ?? '?',\n buf:'',\n })\n return flushed\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 []\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 []\n }\n\n return { process, flush:flushBuf }\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 // true when the orchestrator killed the agent at\n // the timeout; exitCode is non-zero in that case\n timedOut:boolean\n}\n\n// How long to wait after the process exits before giving up on a\n// graceful pipe close and forcing the streams shut. A grandchild\n// (dev server, watcher) that inherited the agent's stdout can keep\n// the pipe open after the agent itself has been killed, which would\n// otherwise leave spawnAgent's promise pending forever.\nconst CLOSE_GRACE_MS = 2000\n\n// Agents are spawned with detached:true so they become their own\n// process group leader; this lets us kill the whole tree (agent +\n// any children it spawned, like dev servers) with one signal to\n// -pid instead of leaving orphans behind. Exported for reuse by\n// signal handling (Ctrl-C / SIGTERM).\nexport function killProcessGroup (pid:number|undefined):void {\n if (pid === undefined) return\n try {\n process.kill(-pid, 'SIGKILL')\n } catch {\n // Process group is already gone.\n }\n}\n\n// Tracks every agent process spawnAgent currently has running, so\n// a Ctrl-C or SIGTERM to the orchestrator itself can kill them all\n// instead of leaving them running after the orchestrator exits.\nconst runningAgents = new Set<number>()\n\nexport function killRunningAgents ():void {\n for (const pid of runningAgents) {\n killProcessGroup(pid)\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 maxTurns?:number\n // pi only; other providers ignore it\n thinking?:ThinkingLevel\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 if (opts.maxTurns) {\n args.push('--max-turns', String(opts.maxTurns))\n }\n\n const providerName = basename(opts.agentCmd)\n const isClaude = providerName === 'claude'\n const isPi = providerName === 'pi'\n if (isPi && opts.thinking) {\n args.push('--thinking', opts.thinking)\n }\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 detached:true,\n })\n\n if (proc.pid !== undefined) runningAgents.add(proc.pid)\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 lines = piFormatter.process(line)\n for (const formatted of lines) {\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 if (isClaude && !TOOL_USE_RE.test(line)) return\n const output = `${prefix}${line}`\n if (opts.onLine) {\n opts.onLine(output)\n } else {\n console.error(output)\n }\n })\n\n let timedOut = false\n const timeout = setTimeout(() => {\n if (proc.killed) return\n timedOut = true\n const msg = 'agent timed out after ' +\n `${opts.timeout}s; killing it`\n // The status display repaints the screen, so a\n // bare console.warn would be painted over. Route\n // the reason through onLine and into the ticket\n // log so it is visible in both places.\n logStream.write(`nightralph: ${msg}\\n`)\n if (opts.onLine) {\n opts.onLine(`${prefix}${msg}`)\n } else {\n console.warn(`${prefix}${msg}`)\n }\n killProcessGroup(proc.pid)\n }, opts.timeout * 1000)\n\n // An agent that exits before draining stdin (bad flags,\n // auth failure) closes its end of the pipe; writing to it\n // then raises EPIPE on proc.stdin. Without a listener that\n // is an uncaught 'error' event that kills the orchestrator.\n proc.stdin.on('error', err => {\n logStream.write(\n 'nightralph: stdin write failed: ' +\n `${formatErrorMessage(err)}\\n`\n )\n })\n\n if (!promptFile) {\n proc.stdin.write(opts.prompt)\n }\n proc.stdin.end()\n\n return new Promise<AgentResult>(resolve => {\n let settled = false\n let graceTimer:ReturnType<typeof setTimeout>|undefined\n\n function finish (exitCode:number):void {\n if (settled) return\n settled = true\n clearTimeout(timeout)\n if (graceTimer) clearTimeout(graceTimer)\n if (proc.pid !== undefined) {\n runningAgents.delete(proc.pid)\n }\n if (piFormatter) {\n for (const line of piFormatter.flush()) {\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 rl.close()\n rlErr.close()\n logStream.end()\n if (promptFile) cleanupPromptFile(promptFile)\n resolve({ exitCode, completedItems, timedOut })\n }\n\n // The process itself has exited, but 'close' waits for its\n // stdio streams to close too -- a grandchild that inherited\n // stdout/stderr can hold those pipes open indefinitely. Give\n // it a grace period, then destroy the streams ourselves so\n // the run does not hang forever on someone else's fd.\n proc.on('exit', code => {\n graceTimer = setTimeout(() => {\n proc.stdout.destroy()\n proc.stderr.destroy()\n finish(code ?? 1)\n }, CLOSE_GRACE_MS)\n })\n\n proc.on('close', code => {\n finish(code ?? 1)\n })\n proc.on('error', err => {\n if (settled) return\n settled = true\n if (graceTimer) clearTimeout(graceTimer)\n clearTimeout(timeout)\n if (proc.pid !== undefined) {\n runningAgents.delete(proc.pid)\n }\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({\n exitCode:1,\n completedItems,\n timedOut,\n })\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 testCmd?:string|null\n thinking?:ThinkingLevel\n retries?:number\n retryDelay?:number\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(\n opts.specBody, firstReady[0],\n { testCmd:opts.testCmd }\n )\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 `\\nTest command: ${opts.testCmd ?? '(none)'}`\n )\n console.log(\n `Thinking: ${opts.thinking ?? '(provider default)'}`\n )\n console.log(\n `Retries: ${opts.retries ?? DEFAULT_RETRIES}`\n )\n console.log(\n 'Retry delay: ' +\n `${opts.retryDelay ?? DEFAULT_RETRY_DELAY}s`\n )\n console.log(\n `\\nMerge strategy: ${strategyDesc}`\n )\n console.log(`Progress file: ${opts.progressPath}`)\n}\n\n// Runs the project's test command in a ticket's worktree.\n// Writes the output to a per-ticket log either way, and\n// returns true only when the suite is green.\nasync function runTestGate (opts:{\n testCmd:string\n ticket:Ticket\n worktreePath:string\n timeout:number\n logsDir:string\n attempt?:number\n log:(msg:string) => void\n}):Promise<boolean> {\n const result = await runTestCmd({\n cmd:opts.testCmd,\n cwd:opts.worktreePath,\n timeout:opts.timeout,\n })\n const testLogPath = attemptLogPath(\n opts.logsDir, opts.ticket, opts.attempt ?? 1,\n '.test.log'\n )\n writeFileSync(testLogPath, result.output)\n\n if (result.exitCode !== 0) {\n opts.log(\n ` ${opts.ticket.filename}: tests failed ` +\n `(exit ${result.exitCode}); ` +\n `see ${testLogPath}`\n )\n return false\n }\n\n opts.log(` ${opts.ticket.filename}: tests passed`)\n return true\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 testCmd?:string|null\n maxTurns?:number\n onLine?:(msg:string) => void\n}):Promise<boolean> {\n const log = (msg:string):void => {\n if (opts.onLine) {\n opts.onLine(msg)\n } else {\n console.log(msg)\n }\n }\n\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 = renderMergePrompt(\n opts.specBody, opts.ticket\n )\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 maxTurns:opts.maxTurns,\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 if (opts.testCmd) {\n const passed = await runTestGate({\n testCmd:opts.testCmd,\n ticket:opts.ticket,\n worktreePath:opts.worktreePath,\n timeout:opts.timeout,\n logsDir:opts.logsDir,\n log,\n })\n if (!passed) {\n log(\n ` ${opts.ticket.filename}: tests failed ` +\n 'after conflict respawn; not merging'\n )\n return false\n }\n }\n\n const mergeResult = await mergeBranch(\n opts.repoRoot, opts.branch\n )\n if (!mergeResult.success) {\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 if (mergeResult.stderr) {\n const stderrMsg =\n ` git: ${mergeResult.stderr.trim()}`\n if (opts.onLine) {\n opts.onLine(stderrMsg)\n } else {\n console.log(stderrMsg)\n }\n }\n }\n return mergeResult.success\n}\n\nexport const DEFAULT_RETRIES = 2\n\n// Seconds to wait before the first retry; each later retry\n// doubles the wait so a provider outage is waited out instead\n// of burning every attempt back to back.\nexport const DEFAULT_RETRY_DELAY = 30\n\nexport function retryDelayFor (base:number, attempt:number):number {\n return base * 2 ** (attempt - 2)\n}\n\nfunction sleep (ms:number):Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms))\n}\n\n// Log file for one attempt: the first attempt keeps the\n// plain name so existing tooling still finds it, later\n// attempts get their own file instead of overwriting it.\nfunction attemptLogPath (\n logsDir:string,\n ticket:Ticket,\n attempt:number,\n ext:string\n):string {\n const stem = ticket.filename.replace(/\\.md$/, '')\n const suffix = attempt > 1 ? `.attempt${attempt}` : ''\n return join(logsDir, `${stem}${suffix}${ext}`)\n}\n\ntype TicketOutcome =\n | { kind:'worktree-error'; error:unknown }\n | { kind:'error'; error:unknown }\n | { kind:'no-commits' }\n | {\n kind:'failed'\n reason:'exit'|'tests'\n branchName:string\n exitCode:number\n completedItems:string[]\n }\n | {\n kind:'ready'\n worktreePath:string\n branchName:string\n completedItems:string[]\n }\n\ntype TicketAttemptOpts = {\n ticket:Ticket\n repoRoot:string\n repoName:string\n baseBranch:string\n specBody:string\n agentCmd:string\n model:string|null\n timeout:number\n logsDir:string\n testCmd?:string|null\n maxTurns?:number\n thinking?:ThinkingLevel\n d:Display\n}\n\n// One attempt at a ticket: a fresh worktree, one agent run,\n// and the checks that decide whether the branch can merge.\n// A failed attempt removes its worktree before returning.\nasync function runTicketAttempt (\n opts:TicketAttemptOpts&{ attempt:number }\n):Promise<TicketOutcome> {\n const { ticket, d } = opts\n\n let worktree:{ worktreePath:string; branchName:string }\n try {\n worktree = await createWorktree({\n repoRoot:opts.repoRoot,\n repoName:opts.repoName,\n baseBranch:opts.baseBranch,\n ticket,\n })\n } catch (error) {\n return { kind:'worktree-error', error }\n }\n\n d.setTicketStatus(ticket.num, 'in-progress')\n const agentResult = await spawnAgent({\n prompt:renderPrompt(\n opts.specBody, ticket,\n { testCmd:opts.testCmd }\n ),\n agentCmd:opts.agentCmd,\n model:opts.model,\n timeout:opts.timeout,\n logPath:attemptLogPath(\n opts.logsDir, ticket, opts.attempt, '.log'\n ),\n cwd:worktree.worktreePath,\n label:ticket.filename.replace(/\\.md$/, ''),\n maxTurns:opts.maxTurns,\n thinking:opts.thinking,\n onLine:(line) => d.log(line),\n })\n\n // A timeout kill is not the agent reporting failure.\n // Keep whatever it committed and let the test gate and\n // merge decide, instead of discarding the worktree.\n if (agentResult.timedOut) {\n d.log(\n ` ${ticket.filename}: timed out; ` +\n 'keeping the work it committed'\n )\n } else if (agentResult.exitCode !== 0) {\n d.log(\n ` ${ticket.filename}: ` +\n `agent exited ${agentResult.exitCode}`\n )\n await removeWorktreeQuietly(worktree.worktreePath, d)\n return {\n kind:'failed',\n reason:'exit',\n branchName:worktree.branchName,\n exitCode:agentResult.exitCode,\n completedItems:agentResult.completedItems,\n }\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 opts.repoRoot, opts.baseBranch, worktree.branchName\n )) {\n return { kind:'no-commits' }\n }\n\n if (opts.testCmd) {\n const passed = await runTestGate({\n testCmd:opts.testCmd,\n ticket,\n worktreePath:worktree.worktreePath,\n timeout:opts.timeout,\n logsDir:opts.logsDir,\n attempt:opts.attempt,\n log:(msg) => d.log(msg),\n })\n if (!passed) {\n await removeWorktreeQuietly(\n worktree.worktreePath, d\n )\n return {\n kind:'failed',\n reason:'tests',\n branchName:worktree.branchName,\n exitCode:1,\n completedItems:agentResult.completedItems,\n }\n }\n }\n\n return {\n kind:'ready',\n worktreePath:worktree.worktreePath,\n branchName:worktree.branchName,\n completedItems:agentResult.completedItems,\n }\n}\n\n// Runs a ticket until an attempt is ready to merge or the\n// retry cap is hit. Each retry starts from a fresh worktree\n// and, for pi, a higher thinking level.\nasync function runTicketAttempts (\n opts:TicketAttemptOpts&{ retries:number; retryDelay:number }\n):Promise<TicketOutcome> {\n const { ticket, d } = opts\n const maxAttempts = opts.retries + 1\n const isPi = basename(opts.agentCmd) === 'pi'\n let thinking = opts.thinking\n let outcome:TicketOutcome = { kind:'no-commits' }\n\n for (let attempt = 1; attempt <= maxAttempts; attempt++) {\n if (attempt === 1) {\n d.log(` Starting ${ticket.filename}`)\n } else {\n thinking = escalateThinking(thinking)\n const delay = retryDelayFor(opts.retryDelay, attempt)\n d.log(\n ` ${ticket.filename}: retrying ` +\n `(attempt ${attempt}/${maxAttempts}` +\n (isPi ? `, thinking ${thinking}` : '') +\n (delay > 0 ? `, waiting ${delay}s` : '') +\n ')'\n )\n if (delay > 0) await sleep(delay * 1000)\n }\n try {\n outcome = await runTicketAttempt({\n ...opts, attempt, thinking,\n })\n } catch (error) {\n d.log(\n ` ${ticket.filename}: attempt ${attempt} ` +\n `threw: ${formatErrorMessage(error)}`\n )\n return { kind:'error', error }\n }\n if (\n outcome.kind === 'ready' ||\n outcome.kind === 'worktree-error'\n ) {\n return outcome\n }\n }\n return outcome\n}\n\n// Wraps writeProgress + commitProgress so callers do not each\n// need to guard against a commit failure (e.g. a git lock held\n// by a concurrent process) crashing the run.\nasync function saveProgress (\n repoRoot:string,\n progressPath:string,\n progress:ProgressData,\n message:string,\n d:Display\n):Promise<void> {\n writeProgress(progressPath, progress)\n try {\n await commitProgress(repoRoot, progressPath, message)\n } catch (err) {\n d.log(\n ' Failed to commit progress: ' +\n formatErrorMessage(err)\n )\n }\n}\n\nfunction runProgress (tickets:ReadonlyArray<Ticket>):RunProgress {\n return {\n completed:tickets.filter(t => t.status === 'done').length,\n total:tickets.length,\n }\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 maxTurns?:number,\n thinking?:ThinkingLevel,\n retries?:number,\n retryDelay?:number,\n):Promise<{ allDone:boolean }> {\n mkdirSync(logsDir, { recursive:true })\n\n const d = display ?? createDisplay()\n const maxAttempts = (retries ?? DEFAULT_RETRIES) + 1\n const delayBase = retryDelay ?? 0\n const isPi = basename(agentCmd) === 'pi'\n let totalWaves = 0\n for (const _ of simulateWaves(tickets)) totalWaves++\n\n let totalCompleted = 0\n let waveNum = 0\n const failedNums = new Set<number>()\n\n while (true) {\n const ready = findReadyTickets(tickets).filter(\n t => !failedNums.has(t.num)\n )\n if (ready.length === 0) break\n\n waveNum++\n const readyNums = new Set(ready.map(t => t.num))\n const remaining = tickets.filter(t =>\n t.status === 'ready-for-agent' &&\n !readyNums.has(t.num)\n )\n d.startWave(\n waveNum,\n totalWaves,\n ready.map(t => ({\n num:t.num,\n filename:t.filename,\n })),\n runProgress(tickets),\n remaining.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 label = t.filename.replace(\n /\\.md$/, ''\n )\n d.setTicketStatus(t.num, 'in-progress')\n d.log(` Starting ${t.filename}`)\n let level = thinking\n let result = await spawnAgent({\n prompt,\n agentCmd,\n model,\n timeout,\n logPath:attemptLogPath(logsDir, t, 1, '.log'),\n label,\n maxTurns,\n thinking:level,\n onLine:(line) => d.log(line),\n })\n // In-place runs have no worktree or test\n // gate, so a non-zero exit is the only\n // failure that can be retried here.\n for (\n let attempt = 2;\n result.exitCode !== 0 &&\n !result.timedOut &&\n attempt <= maxAttempts;\n attempt++\n ) {\n level = escalateThinking(level)\n const delay = retryDelayFor(delayBase, attempt)\n d.log(\n ` ${t.filename}: agent exited ` +\n `${result.exitCode}; retrying ` +\n `(attempt ${attempt}/${maxAttempts}` +\n (isPi ? `, thinking ${level}` : '') +\n (delay > 0 ? `, waiting ${delay}s` : '') +\n ')'\n )\n if (delay > 0) await sleep(delay * 1000)\n result = await spawnAgent({\n prompt,\n agentCmd,\n model,\n timeout,\n logPath:attemptLogPath(\n logsDir, t, attempt, '.log'\n ),\n label,\n maxTurns,\n thinking:level,\n onLine:(line) => d.log(line),\n })\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 failedNums.add(ticket.num)\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 (failedNums.size > 0 ?\n `, ${failedNums.size} failed` :\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 testCmd?:string|null\n maxTurns?:number\n // starting thinking level for pi; unset = pi's default\n thinking?:ThinkingLevel\n // extra attempts per ticket after a failure; default 2\n retries?:number\n // seconds to wait before the first retry; default 30\n retryDelay?:number\n}):Promise<{ allDone:boolean }> {\n mkdirSync(opts.logsDir, { recursive:true })\n\n const d = opts.display ?? createDisplay()\n const retries = opts.retries ?? DEFAULT_RETRIES\n const retryDelay = opts.retryDelay ?? 0\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 if (isDirty(repoRoot)) {\n throw new Error(\n 'Working tree is dirty; commit or stash ' +\n 'changes before running'\n )\n }\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 await saveProgress(\n repoRoot,\n progressPath,\n progress,\n `nightralph: start ${opts.featureName}`,\n d,\n )\n\n if (!opts.testCmd) {\n d.log(' Test gate disabled: no test command')\n }\n\n let totalCompleted = 0\n let waveNum = 0\n const failedNums = new Set<number>()\n\n while (true) {\n const ready = findReadyTickets(opts.tickets).filter(\n t => !failedNums.has(t.num)\n )\n if (ready.length === 0) break\n\n waveNum++\n const readyNums = new Set(ready.map(t => t.num))\n const remaining = opts.tickets.filter(t =>\n t.status === 'ready-for-agent' &&\n !readyNums.has(t.num)\n )\n d.startWave(\n waveNum,\n totalWaves,\n ready.map(t => ({\n num:t.num,\n filename:t.filename,\n })),\n runProgress(opts.tickets),\n remaining.map(t => ({\n num:t.num,\n filename:t.filename,\n })),\n )\n\n // Each ticket runs its own attempt loop in parallel.\n // Progress is recorded afterwards, sequentially, so\n // commits on the base branch never race each other.\n const outcomes = await Promise.all(\n ready.map(t => runTicketAttempts({\n ticket:t,\n repoRoot,\n repoName,\n baseBranch,\n specBody:opts.specBody,\n agentCmd:opts.agentCmd,\n model:opts.model,\n timeout:opts.timeout,\n logsDir:opts.logsDir,\n testCmd:opts.testCmd,\n maxTurns:opts.maxTurns,\n thinking:opts.thinking,\n retries,\n retryDelay,\n d,\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 < outcomes.length; i++) {\n const outcome = outcomes[i]\n const ticket = ready[i]\n\n if (outcome.kind === 'worktree-error') {\n failedNums.add(ticket.num)\n d.setTicketStatus(ticket.num, 'failed')\n d.log(\n ` ${ticket.filename}: failed to create ` +\n `worktree: ${formatErrorMessage(outcome.error)}`\n )\n continue\n }\n\n if (outcome.kind === 'error') {\n failedNums.add(ticket.num)\n d.setTicketStatus(ticket.num, 'failed')\n d.log(\n ` ${ticket.filename}: attempt error: ` +\n formatErrorMessage(outcome.error)\n )\n continue\n }\n\n if (outcome.kind === 'no-commits') {\n failedNums.add(ticket.num)\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 if (outcome.kind === 'failed') {\n failedNums.add(ticket.num)\n d.setTicketStatus(ticket.num, 'failed')\n if (outcome.reason === 'exit') {\n checkItems(ticket, outcome.completedItems)\n }\n // Acceptance criteria are not met when the\n // suite is red, so checklist items the agent\n // claimed are not checked off in that case.\n checkTicket(progress, ticket.num, {\n branch:outcome.branchName,\n exitCode:outcome.exitCode,\n done:false,\n })\n await saveProgress(\n repoRoot,\n progressPath,\n progress,\n `nightralph: ${ticket.filename} ` +\n (outcome.reason === 'tests' ?\n 'tests failed' :\n 'failed'),\n d,\n )\n continue\n }\n\n checkItems(ticket, outcome.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, outcome.worktreePath\n )\n successfulBranches.push({\n branch:outcome.branchName,\n ticketNum:ticket.num,\n worktreePath:outcome.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 await saveProgress(\n repoRoot,\n progressPath,\n progress,\n `nightralph: ${ticket.filename} done`,\n d,\n )\n\n const worktreePath = worktreePathsByNum.get(\n ticket.num\n )\n if (worktreePath) {\n await removeWorktreeQuietly(\n worktreePath, d\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 testCmd:opts.testCmd,\n maxTurns:opts.maxTurns,\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 await saveProgress(\n repoRoot,\n progressPath,\n progress,\n `nightralph: ${ticket.filename} ` +\n 'done (respawn)',\n d,\n )\n\n if (worktreePath) {\n try {\n await removeWorktree(\n worktreePath,\n { force:true }\n )\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 if (branchResult.stderr) {\n d.log(\n ' git: ' +\n branchResult.stderr.trim()\n )\n }\n checkTicket(progress, ticket.num, {\n branch:branchResult.branch,\n exitCode:0,\n done:false,\n })\n await saveProgress(\n repoRoot,\n progressPath,\n progress,\n `nightralph: ${ticket.filename} ` +\n 'merge failed',\n d,\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(\n sb.worktreePath,\n { force:true }\n )\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 (failedNums.size > 0 ?\n `, ${failedNums.size} failed` :\n '')\n )\n d.cleanup()\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 RunProgress,\n type Display,\n} from './display.js'\nimport { runTestCmd } from './testcmd.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\n// Removes a ticket's worktree, logging and swallowing any\n// failure instead of letting it interrupt the wave.\nasync function removeWorktreeQuietly (\n worktreePath:string,\n d:Display\n):Promise<void> {\n try {\n await removeWorktree(worktreePath, { force:true })\n } catch (err) {\n d.log(\n ' Failed to remove worktree ' +\n `${worktreePath}: ` +\n formatErrorMessage(err)\n )\n }\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\nexport const TOOL_USE_RE = /^\\[[\\w.]+\\]/\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\n// Drops one markdown section from a spec. Used to keep the\n// per-ticket prompt short: the User Stories list is useful\n// to humans and to to-tickets but not to an implementing agent.\nexport function stripSpecSection (\n specBody:string,\n heading:string\n):string {\n const out:string[] = []\n let skipping = false\n let skipLevel = 0\n let inFence = false\n\n for (const line of specBody.split('\\n')) {\n // Toggle fence state on lines starting with ``` (after\n // optional whitespace)\n if (/^\\s*```/.test(line)) {\n inFence = !inFence\n }\n\n // Only check for headings outside of code fences\n if (!inFence) {\n const m = /^(#{1,6})\\s+(.*?)\\s*$/.exec(line)\n if (m) {\n const level = m[1].length\n if (skipping && level <= skipLevel) {\n skipping = false\n }\n if (!skipping && m[2] === heading) {\n skipping = true\n skipLevel = level\n continue\n }\n }\n }\n if (!skipping) out.push(line)\n }\n\n return out.join('\\n')\n}\n\nexport function renderPrompt (\n specBody:string,\n ticket:Ticket,\n opts:{ testCmd?:string|null } = {}\n):string {\n const testRules = opts.testCmd ?\n [\n '- Work test-first. For each checklist ' +\n 'item, write a failing test at the ' +\n 'seams named in the spec\\'s Testing ' +\n 'Decisions section, then write only ' +\n 'enough code to make it pass.',\n `- Run \\`${opts.testCmd}\\` before ` +\n 'committing. Do not commit with failing ' +\n 'tests. The orchestrator runs the same ' +\n 'command after you exit and rejects the ' +\n 'ticket if it fails.',\n ] :\n []\n\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 'Follow these rules:',\n '- Read the files directly relevant to the ' +\n 'ticket before writing code.',\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 ...testRules,\n '- Do NOT read or modify files outside ' +\n 'your current directory (the worktree).',\n '- Do NOT run git push.',\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\nexport function renderMergePrompt (\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 resolving ' +\n 'a merge conflict.',\n '',\n 'Another agent already implemented this ticket ' +\n 'on a feature branch. The branch was then ' +\n 'merged with the base branch, but conflicts ' +\n 'arose. The working tree may contain conflict ' +\n 'markers that need resolution.',\n '',\n 'Your task:',\n '1. Find and resolve all conflict markers ' +\n '(<<<<<<< / ======= / >>>>>>>).',\n '2. Make sure the code compiles and tests pass.',\n '3. Commit the resolved files.',\n '',\n 'Do NOT re-implement the ticket from scratch.',\n 'Do NOT read or modify files outside your ' +\n 'current directory (the worktree).',\n 'Do NOT run git push.',\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 removed --full-auto; this is the counterpart\n // of claude's --dangerously-skip-permissions, and the\n // workspace-write sandbox would block commits because\n // a worktree's .git link points outside the tree\n codex:['exec', '--dangerously-bypass-approvals-and-sandbox'],\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\n// The thinking levels pi accepts, lowest to highest.\nexport const THINKING_LEVELS = [\n 'off', 'minimal', 'low', 'medium',\n 'high', 'xhigh', 'max',\n] as const\n\nexport type ThinkingLevel = typeof THINKING_LEVELS[number]\n\n// The level for a retry. Without a starting level the\n// first retry jumps to high; otherwise step one rung up\n// and stop at max.\nexport function escalateThinking (\n level?:ThinkingLevel\n):ThinkingLevel {\n if (!level) return 'high'\n const i = THINKING_LEVELS.indexOf(level)\n return THINKING_LEVELS[\n Math.min(i + 1, THINKING_LEVELS.length - 1)\n ]\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 type PiStreamFormatter = {\n process:(line:string) => string[]\n flush:() => string[]\n}\n\nexport function createPiStreamFormatter (\n):PiStreamFormatter {\n const calls = new Map<\n number, { name:string; buf:string }\n >()\n let textBuf = ''\n\n function drainLines ():string[] {\n const parts = textBuf.split('\\n')\n if (parts.length === 1) return []\n textBuf = parts[parts.length - 1]\n return parts.slice(0, -1)\n }\n\n function flushBuf ():string[] {\n if (textBuf.length === 0) return []\n const out = textBuf\n textBuf = ''\n return [out]\n }\n\n function process (line:string):string[] {\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 []\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 const delta =\n (evt.delta as string|undefined) ?? ''\n textBuf += delta\n return drainLines()\n }\n\n if (type === 'toolcall_start') {\n const flushed = flushBuf()\n calls.set(ci, {\n name:(evt.toolName as\n string|undefined) ?? '?',\n buf:'',\n })\n return flushed\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 []\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 []\n }\n\n return { process, flush:flushBuf }\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 // true when the orchestrator killed the agent at\n // the timeout; exitCode is non-zero in that case\n timedOut:boolean\n}\n\n// How long to wait after the process exits before giving up on a\n// graceful pipe close and forcing the streams shut. A grandchild\n// (dev server, watcher) that inherited the agent's stdout can keep\n// the pipe open after the agent itself has been killed, which would\n// otherwise leave spawnAgent's promise pending forever.\nconst CLOSE_GRACE_MS = 2000\n\n// Agents are spawned with detached:true so they become their own\n// process group leader; this lets us kill the whole tree (agent +\n// any children it spawned, like dev servers) with one signal to\n// -pid instead of leaving orphans behind. Exported for reuse by\n// signal handling (Ctrl-C / SIGTERM).\nexport function killProcessGroup (pid:number|undefined):void {\n if (pid === undefined) return\n try {\n process.kill(-pid, 'SIGKILL')\n } catch {\n // Process group is already gone.\n }\n}\n\n// Tracks every agent process spawnAgent currently has running, so\n// a Ctrl-C or SIGTERM to the orchestrator itself can kill them all\n// instead of leaving them running after the orchestrator exits.\nconst runningAgents = new Set<number>()\n\nexport function killRunningAgents ():void {\n for (const pid of runningAgents) {\n killProcessGroup(pid)\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 maxTurns?:number\n // pi only; other providers ignore it\n thinking?:ThinkingLevel\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 if (opts.maxTurns) {\n args.push('--max-turns', String(opts.maxTurns))\n }\n\n const providerName = basename(opts.agentCmd)\n const isClaude = providerName === 'claude'\n const isPi = providerName === 'pi'\n if (isPi && opts.thinking) {\n args.push('--thinking', opts.thinking)\n }\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 detached:true,\n })\n\n if (proc.pid !== undefined) runningAgents.add(proc.pid)\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 lines = piFormatter.process(line)\n for (const formatted of lines) {\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 if (isClaude && !TOOL_USE_RE.test(line)) return\n const output = `${prefix}${line}`\n if (opts.onLine) {\n opts.onLine(output)\n } else {\n console.error(output)\n }\n })\n\n let timedOut = false\n const timeout = setTimeout(() => {\n if (proc.killed) return\n timedOut = true\n const msg = 'agent timed out after ' +\n `${opts.timeout}s; killing it`\n // The status display repaints the screen, so a\n // bare console.warn would be painted over. Route\n // the reason through onLine and into the ticket\n // log so it is visible in both places.\n logStream.write(`nightralph: ${msg}\\n`)\n if (opts.onLine) {\n opts.onLine(`${prefix}${msg}`)\n } else {\n console.warn(`${prefix}${msg}`)\n }\n killProcessGroup(proc.pid)\n }, opts.timeout * 1000)\n\n // An agent that exits before draining stdin (bad flags,\n // auth failure) closes its end of the pipe; writing to it\n // then raises EPIPE on proc.stdin. Without a listener that\n // is an uncaught 'error' event that kills the orchestrator.\n proc.stdin.on('error', err => {\n logStream.write(\n 'nightralph: stdin write failed: ' +\n `${formatErrorMessage(err)}\\n`\n )\n })\n\n if (!promptFile) {\n proc.stdin.write(opts.prompt)\n }\n proc.stdin.end()\n\n return new Promise<AgentResult>(resolve => {\n let settled = false\n let graceTimer:ReturnType<typeof setTimeout>|undefined\n\n function finish (exitCode:number):void {\n if (settled) return\n settled = true\n clearTimeout(timeout)\n if (graceTimer) clearTimeout(graceTimer)\n if (proc.pid !== undefined) {\n runningAgents.delete(proc.pid)\n }\n if (piFormatter) {\n for (const line of piFormatter.flush()) {\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 rl.close()\n rlErr.close()\n logStream.end()\n if (promptFile) cleanupPromptFile(promptFile)\n resolve({ exitCode, completedItems, timedOut })\n }\n\n // The process itself has exited, but 'close' waits for its\n // stdio streams to close too -- a grandchild that inherited\n // stdout/stderr can hold those pipes open indefinitely. Give\n // it a grace period, then destroy the streams ourselves so\n // the run does not hang forever on someone else's fd.\n proc.on('exit', code => {\n graceTimer = setTimeout(() => {\n killProcessGroup(proc.pid)\n proc.stdout.destroy()\n proc.stderr.destroy()\n finish(code ?? 1)\n }, CLOSE_GRACE_MS)\n })\n\n proc.on('close', code => {\n finish(code ?? 1)\n })\n proc.on('error', err => {\n if (settled) return\n settled = true\n if (graceTimer) clearTimeout(graceTimer)\n clearTimeout(timeout)\n if (proc.pid !== undefined) {\n runningAgents.delete(proc.pid)\n }\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({\n exitCode:1,\n completedItems,\n timedOut,\n })\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 testCmd?:string|null\n thinking?:ThinkingLevel\n retries?:number\n retryDelay?:number\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(\n opts.specBody, firstReady[0],\n { testCmd:opts.testCmd }\n )\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 `\\nTest command: ${opts.testCmd ?? '(none)'}`\n )\n console.log(\n `Thinking: ${opts.thinking ?? '(provider default)'}`\n )\n console.log(\n `Retries: ${opts.retries ?? DEFAULT_RETRIES}`\n )\n console.log(\n 'Retry delay: ' +\n `${opts.retryDelay ?? 0}s`\n )\n console.log(\n `\\nMerge strategy: ${strategyDesc}`\n )\n console.log(`Progress file: ${opts.progressPath}`)\n}\n\n// Runs the project's test command in a ticket's worktree.\n// Writes the output to a per-ticket log either way, and\n// returns true only when the suite is green.\nasync function runTestGate (opts:{\n testCmd:string\n ticket:Ticket\n worktreePath:string\n timeout:number\n logsDir:string\n attempt?:number\n log:(msg:string) => void\n registry?:Set<number>\n}):Promise<boolean> {\n const result = await runTestCmd({\n cmd:opts.testCmd,\n cwd:opts.worktreePath,\n timeout:opts.timeout,\n registry:opts.registry,\n })\n const testLogPath = attemptLogPath(\n opts.logsDir, opts.ticket, opts.attempt ?? 1,\n '.test.log'\n )\n writeFileSync(testLogPath, result.output)\n\n if (result.exitCode !== 0) {\n opts.log(\n ` ${opts.ticket.filename}: tests failed ` +\n `(exit ${result.exitCode}); ` +\n `see ${testLogPath}`\n )\n return false\n }\n\n opts.log(` ${opts.ticket.filename}: tests passed`)\n return true\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 testCmd?:string|null\n maxTurns?:number\n onLine?:(msg:string) => void\n}):Promise<boolean> {\n const log = (msg:string):void => {\n if (opts.onLine) {\n opts.onLine(msg)\n } else {\n console.log(msg)\n }\n }\n\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 = renderMergePrompt(\n opts.specBody, opts.ticket\n )\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 maxTurns:opts.maxTurns,\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 if (opts.testCmd) {\n const passed = await runTestGate({\n testCmd:opts.testCmd,\n ticket:opts.ticket,\n worktreePath:opts.worktreePath,\n timeout:opts.timeout,\n logsDir:opts.logsDir,\n log,\n registry:runningAgents,\n })\n if (!passed) {\n log(\n ` ${opts.ticket.filename}: tests failed ` +\n 'after conflict respawn; not merging'\n )\n return false\n }\n }\n\n const mergeResult = await mergeBranch(\n opts.repoRoot, opts.branch\n )\n if (!mergeResult.success) {\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 if (mergeResult.stderr) {\n const stderrMsg =\n ` git: ${mergeResult.stderr.trim()}`\n if (opts.onLine) {\n opts.onLine(stderrMsg)\n } else {\n console.log(stderrMsg)\n }\n }\n }\n return mergeResult.success\n}\n\nexport const DEFAULT_RETRIES = 2\n\n// Seconds to wait before the first retry; each later retry\n// doubles the wait so a provider outage is waited out instead\n// of burning every attempt back to back.\nexport const DEFAULT_RETRY_DELAY = 30\n\nexport function retryDelayFor (base:number, attempt:number):number {\n return base * 2 ** (attempt - 2)\n}\n\nfunction sleep (ms:number):Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms))\n}\n\n// Log file for one attempt: the first attempt keeps the\n// plain name so existing tooling still finds it, later\n// attempts get their own file instead of overwriting it.\nfunction attemptLogPath (\n logsDir:string,\n ticket:Ticket,\n attempt:number,\n ext:string\n):string {\n const stem = ticket.filename.replace(/\\.md$/, '')\n const suffix = attempt > 1 ? `.attempt${attempt}` : ''\n return join(logsDir, `${stem}${suffix}${ext}`)\n}\n\ntype TicketOutcome =\n | { kind:'worktree-error'; error:unknown }\n | {\n kind:'error'\n error:unknown\n worktreePath?:string\n branchName?:string\n }\n | {\n kind:'no-commits'\n worktreePath:string\n branchName:string\n }\n | {\n kind:'failed'\n reason:'exit'|'tests'\n branchName:string\n exitCode:number\n completedItems:string[]\n }\n | {\n kind:'ready'\n worktreePath:string\n branchName:string\n completedItems:string[]\n }\n\ntype TicketAttemptOpts = {\n ticket:Ticket\n repoRoot:string\n repoName:string\n baseBranch:string\n specBody:string\n agentCmd:string\n model:string|null\n timeout:number\n logsDir:string\n testCmd?:string|null\n maxTurns?:number\n thinking?:ThinkingLevel\n d:Display\n}\n\n// One attempt at a ticket: a fresh worktree, one agent run,\n// and the checks that decide whether the branch can merge.\n// A failed attempt removes its worktree before returning.\nasync function runTicketAttempt (\n opts:TicketAttemptOpts&{ attempt:number }\n):Promise<TicketOutcome> {\n const { ticket, d } = opts\n\n let worktree:{ worktreePath:string; branchName:string }\n try {\n worktree = await createWorktree({\n repoRoot:opts.repoRoot,\n repoName:opts.repoName,\n baseBranch:opts.baseBranch,\n ticket,\n })\n } catch (error) {\n return { kind:'worktree-error', error }\n }\n\n d.setTicketStatus(ticket.num, 'in-progress')\n const agentResult = await spawnAgent({\n prompt:renderPrompt(\n opts.specBody, ticket,\n { testCmd:opts.testCmd }\n ),\n agentCmd:opts.agentCmd,\n model:opts.model,\n timeout:opts.timeout,\n logPath:attemptLogPath(\n opts.logsDir, ticket, opts.attempt, '.log'\n ),\n cwd:worktree.worktreePath,\n label:ticket.filename.replace(/\\.md$/, ''),\n maxTurns:opts.maxTurns,\n thinking:opts.thinking,\n onLine:(line) => d.log(line),\n })\n\n // A timeout kill is not the agent reporting failure.\n // Keep whatever it committed and let the test gate and\n // merge decide, instead of discarding the worktree.\n if (agentResult.timedOut) {\n d.log(\n ` ${ticket.filename}: timed out; ` +\n 'keeping the work it committed'\n )\n } else if (agentResult.exitCode !== 0) {\n d.log(\n ` ${ticket.filename}: ` +\n `agent exited ${agentResult.exitCode}`\n )\n await removeWorktreeQuietly(worktree.worktreePath, d)\n return {\n kind:'failed',\n reason:'exit',\n branchName:worktree.branchName,\n exitCode:agentResult.exitCode,\n completedItems:agentResult.completedItems,\n }\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 opts.repoRoot, opts.baseBranch, worktree.branchName\n )) {\n await removeWorktreeQuietly(worktree.worktreePath, d)\n return {\n kind:'no-commits',\n worktreePath:worktree.worktreePath,\n branchName:worktree.branchName,\n }\n }\n\n if (opts.testCmd) {\n const passed = await runTestGate({\n testCmd:opts.testCmd,\n ticket,\n worktreePath:worktree.worktreePath,\n timeout:opts.timeout,\n logsDir:opts.logsDir,\n attempt:opts.attempt,\n log:(msg) => d.log(msg),\n registry:runningAgents,\n })\n if (!passed) {\n await removeWorktreeQuietly(\n worktree.worktreePath, d\n )\n return {\n kind:'failed',\n reason:'tests',\n branchName:worktree.branchName,\n exitCode:1,\n completedItems:agentResult.completedItems,\n }\n }\n }\n\n return {\n kind:'ready',\n worktreePath:worktree.worktreePath,\n branchName:worktree.branchName,\n completedItems:agentResult.completedItems,\n }\n}\n\n// Runs a ticket until an attempt is ready to merge or the\n// retry cap is hit. Each retry starts from a fresh worktree\n// and, for pi, a higher thinking level.\nasync function runTicketAttempts (\n opts:TicketAttemptOpts&{ retries:number; retryDelay:number }\n):Promise<TicketOutcome> {\n const { ticket, d } = opts\n const maxAttempts = opts.retries + 1\n const isPi = basename(opts.agentCmd) === 'pi'\n let thinking = opts.thinking\n let outcome:TicketOutcome = {\n kind:'no-commits', worktreePath:'', branchName:'',\n }\n\n for (let attempt = 1; attempt <= maxAttempts; attempt++) {\n if (attempt === 1) {\n d.log(` Starting ${ticket.filename}`)\n } else {\n thinking = escalateThinking(thinking)\n const delay = retryDelayFor(opts.retryDelay, attempt)\n d.log(\n ` ${ticket.filename}: retrying ` +\n `(attempt ${attempt}/${maxAttempts}` +\n (isPi ? `, thinking ${thinking}` : '') +\n (delay > 0 ? `, waiting ${delay}s` : '') +\n ')'\n )\n if (delay > 0) await sleep(delay * 1000)\n }\n try {\n outcome = await runTicketAttempt({\n ...opts, attempt, thinking,\n })\n } catch (error) {\n d.log(\n ` ${ticket.filename}: attempt ${attempt} ` +\n `threw: ${formatErrorMessage(error)}`\n )\n return { kind:'error', error }\n }\n if (\n outcome.kind === 'ready' ||\n outcome.kind === 'worktree-error'\n ) {\n return outcome\n }\n }\n return outcome\n}\n\n// Wraps writeProgress + commitProgress so callers do not each\n// need to guard against a commit failure (e.g. a git lock held\n// by a concurrent process) crashing the run.\nasync function saveProgress (\n repoRoot:string,\n progressPath:string,\n progress:ProgressData,\n message:string,\n d:Display\n):Promise<void> {\n writeProgress(progressPath, progress)\n try {\n await commitProgress(repoRoot, progressPath, message)\n } catch (err) {\n d.log(\n ' Failed to commit progress: ' +\n formatErrorMessage(err)\n )\n }\n}\n\nfunction runProgress (tickets:ReadonlyArray<Ticket>):RunProgress {\n return {\n completed:tickets.filter(t => t.status === 'done').length,\n total:tickets.length,\n }\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 maxTurns?:number,\n thinking?:ThinkingLevel,\n retries?:number,\n retryDelay?:number,\n):Promise<{ allDone:boolean }> {\n mkdirSync(logsDir, { recursive:true })\n\n const d = display ?? createDisplay()\n const maxAttempts = (retries ?? DEFAULT_RETRIES) + 1\n const delayBase = retryDelay ?? 0\n const isPi = basename(agentCmd) === 'pi'\n let totalWaves = 0\n for (const _ of simulateWaves(tickets)) totalWaves++\n\n let totalCompleted = 0\n let waveNum = 0\n const failedNums = new Set<number>()\n\n while (true) {\n const ready = findReadyTickets(tickets).filter(\n t => !failedNums.has(t.num)\n )\n if (ready.length === 0) break\n\n waveNum++\n const readyNums = new Set(ready.map(t => t.num))\n const remaining = tickets.filter(t =>\n t.status === 'ready-for-agent' &&\n !readyNums.has(t.num)\n )\n d.startWave(\n waveNum,\n totalWaves,\n ready.map(t => ({\n num:t.num,\n filename:t.filename,\n })),\n runProgress(tickets),\n remaining.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 label = t.filename.replace(\n /\\.md$/, ''\n )\n d.setTicketStatus(t.num, 'in-progress')\n d.log(` Starting ${t.filename}`)\n let level = thinking\n let result = await spawnAgent({\n prompt,\n agentCmd,\n model,\n timeout,\n logPath:attemptLogPath(logsDir, t, 1, '.log'),\n label,\n maxTurns,\n thinking:level,\n onLine:(line) => d.log(line),\n })\n // In-place runs have no worktree or test\n // gate, so a non-zero exit is the only\n // failure that can be retried here.\n for (\n let attempt = 2;\n result.exitCode !== 0 &&\n !result.timedOut &&\n attempt <= maxAttempts;\n attempt++\n ) {\n level = escalateThinking(level)\n const delay = retryDelayFor(delayBase, attempt)\n d.log(\n ` ${t.filename}: agent exited ` +\n `${result.exitCode}; retrying ` +\n `(attempt ${attempt}/${maxAttempts}` +\n (isPi ? `, thinking ${level}` : '') +\n (delay > 0 ? `, waiting ${delay}s` : '') +\n ')'\n )\n if (delay > 0) await sleep(delay * 1000)\n result = await spawnAgent({\n prompt,\n agentCmd,\n model,\n timeout,\n logPath:attemptLogPath(\n logsDir, t, attempt, '.log'\n ),\n label,\n maxTurns,\n thinking:level,\n onLine:(line) => d.log(line),\n })\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 failedNums.add(ticket.num)\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 (failedNums.size > 0 ?\n `, ${failedNums.size} failed` :\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 testCmd?:string|null\n maxTurns?:number\n // starting thinking level for pi; unset = pi's default\n thinking?:ThinkingLevel\n // extra attempts per ticket after a failure; default 2\n retries?:number\n // seconds to wait before the first retry; default 30\n retryDelay?:number\n}):Promise<{ allDone:boolean }> {\n mkdirSync(opts.logsDir, { recursive:true })\n\n const d = opts.display ?? createDisplay()\n const retries = opts.retries ?? DEFAULT_RETRIES\n const retryDelay = opts.retryDelay ?? 0\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 if (isDirty(repoRoot)) {\n throw new Error(\n 'Working tree is dirty; commit or stash ' +\n 'changes before running'\n )\n }\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 await saveProgress(\n repoRoot,\n progressPath,\n progress,\n `nightralph: start ${opts.featureName}`,\n d,\n )\n\n if (!opts.testCmd) {\n d.log(' Test gate disabled: no test command')\n }\n\n let totalCompleted = 0\n let waveNum = 0\n const failedNums = new Set<number>()\n\n while (true) {\n const ready = findReadyTickets(opts.tickets).filter(\n t => !failedNums.has(t.num)\n )\n if (ready.length === 0) break\n\n waveNum++\n const readyNums = new Set(ready.map(t => t.num))\n const remaining = opts.tickets.filter(t =>\n t.status === 'ready-for-agent' &&\n !readyNums.has(t.num)\n )\n d.startWave(\n waveNum,\n totalWaves,\n ready.map(t => ({\n num:t.num,\n filename:t.filename,\n })),\n runProgress(opts.tickets),\n remaining.map(t => ({\n num:t.num,\n filename:t.filename,\n })),\n )\n\n // Each ticket runs its own attempt loop in parallel.\n // Progress is recorded afterwards, sequentially, so\n // commits on the base branch never race each other.\n const outcomes = await Promise.all(\n ready.map(t => runTicketAttempts({\n ticket:t,\n repoRoot,\n repoName,\n baseBranch,\n specBody:opts.specBody,\n agentCmd:opts.agentCmd,\n model:opts.model,\n timeout:opts.timeout,\n logsDir:opts.logsDir,\n testCmd:opts.testCmd,\n maxTurns:opts.maxTurns,\n thinking:opts.thinking,\n retries,\n retryDelay,\n d,\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 < outcomes.length; i++) {\n const outcome = outcomes[i]\n const ticket = ready[i]\n\n if (outcome.kind === 'worktree-error') {\n failedNums.add(ticket.num)\n d.setTicketStatus(ticket.num, 'failed')\n d.log(\n ` ${ticket.filename}: failed to create ` +\n `worktree: ${formatErrorMessage(outcome.error)}`\n )\n checkTicket(progress, ticket.num, {\n branch:'',\n exitCode:-1,\n done:false,\n })\n await saveProgress(\n repoRoot,\n progressPath,\n progress,\n `nightralph: ${ticket.filename} ` +\n 'worktree error',\n d,\n )\n continue\n }\n\n if (outcome.kind === 'error') {\n failedNums.add(ticket.num)\n d.setTicketStatus(ticket.num, 'failed')\n d.log(\n ` ${ticket.filename}: attempt error: ` +\n formatErrorMessage(outcome.error)\n )\n checkTicket(progress, ticket.num, {\n branch:outcome.branchName ?? '',\n exitCode:-1,\n done:false,\n })\n await saveProgress(\n repoRoot,\n progressPath,\n progress,\n `nightralph: ${ticket.filename} error`,\n d,\n )\n continue\n }\n\n if (outcome.kind === 'no-commits') {\n failedNums.add(ticket.num)\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 checkTicket(progress, ticket.num, {\n branch:outcome.branchName,\n exitCode:0,\n done:false,\n })\n await saveProgress(\n repoRoot,\n progressPath,\n progress,\n `nightralph: ${ticket.filename} ` +\n 'no commits',\n d,\n )\n continue\n }\n\n if (outcome.kind === 'failed') {\n failedNums.add(ticket.num)\n d.setTicketStatus(ticket.num, 'failed')\n if (outcome.reason === 'exit') {\n checkItems(ticket, outcome.completedItems)\n }\n // Acceptance criteria are not met when the\n // suite is red, so checklist items the agent\n // claimed are not checked off in that case.\n checkTicket(progress, ticket.num, {\n branch:outcome.branchName,\n exitCode:outcome.exitCode,\n done:false,\n })\n await saveProgress(\n repoRoot,\n progressPath,\n progress,\n `nightralph: ${ticket.filename} ` +\n (outcome.reason === 'tests' ?\n 'tests failed' :\n 'failed'),\n d,\n )\n continue\n }\n\n checkItems(ticket, outcome.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, outcome.worktreePath\n )\n successfulBranches.push({\n branch:outcome.branchName,\n ticketNum:ticket.num,\n worktreePath:outcome.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 await saveProgress(\n repoRoot,\n progressPath,\n progress,\n `nightralph: ${ticket.filename} done`,\n d,\n )\n\n const worktreePath = worktreePathsByNum.get(\n ticket.num\n )\n if (worktreePath) {\n await removeWorktreeQuietly(\n worktreePath, d\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 testCmd:opts.testCmd,\n maxTurns:opts.maxTurns,\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 await saveProgress(\n repoRoot,\n progressPath,\n progress,\n `nightralph: ${ticket.filename} ` +\n 'done (respawn)',\n d,\n )\n\n if (worktreePath) {\n try {\n await removeWorktree(\n worktreePath,\n { force:true }\n )\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 if (branchResult.stderr) {\n d.log(\n ' git: ' +\n branchResult.stderr.trim()\n )\n }\n checkTicket(progress, ticket.num, {\n branch:branchResult.branch,\n exitCode:0,\n done:false,\n })\n await saveProgress(\n repoRoot,\n progressPath,\n progress,\n `nightralph: ${ticket.filename} ` +\n 'merge failed',\n d,\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(\n sb.worktreePath,\n { force:true }\n )\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 (failedNums.size > 0 ?\n `, ${failedNums.size} failed` :\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,OAGG;AACP,SAAS,kBAAkB;AAYpB,SAAS,mBAAoB,OAAsB;AACtD,SAAO,iBAAiB,QACpB,MAAM,UACN,OAAO,KAAK;AACpB;AAJgB;AAQhB,eAAe,sBACX,cACA,GACY;AACZ,MAAI;AACA,UAAM,eAAe,cAAc,EAAE,OAAM,KAAK,CAAC;AAAA,EACrD,SAAS,KAAK;AACV,MAAE;AAAA,MACE,+BACG,YAAY,OACf,mBAAmB,GAAG;AAAA,IAC1B;AAAA,EACJ;AACJ;AAbe;AAeR,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;AACrB,MAAM,cAAc;AAEpB,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;AAaT,SAAS,iBACZ,UACA,SACK;AACL,QAAM,MAAe,CAAC;AACtB,MAAI,WAAW;AACf,MAAI,YAAY;AAChB,MAAI,UAAU;AAEd,aAAW,QAAQ,SAAS,MAAM,IAAI,GAAG;AAGrC,QAAI,UAAU,KAAK,IAAI,GAAG;AACtB,gBAAU,CAAC;AAAA,IACf;AAGA,QAAI,CAAC,SAAS;AACV,YAAM,IAAI,wBAAwB,KAAK,IAAI;AAC3C,UAAI,GAAG;AACH,cAAM,QAAQ,EAAE,CAAC,EAAE;AACnB,YAAI,YAAY,SAAS,WAAW;AAChC,qBAAW;AAAA,QACf;AACA,YAAI,CAAC,YAAY,EAAE,CAAC,MAAM,SAAS;AAC/B,qBAAW;AACX,sBAAY;AACZ;AAAA,QACJ;AAAA,MACJ;AAAA,IACJ;AACA,QAAI,CAAC,SAAU,KAAI,KAAK,IAAI;AAAA,EAChC;AAEA,SAAO,IAAI,KAAK,IAAI;AACxB;AAnCgB;AAqCT,SAAS,aACZ,UACA,QACA,OAAgC,CAAC,GAC5B;AACL,QAAM,YAAY,KAAK,UACnB;AAAA,IACI;AAAA,IAKA,WAAW,KAAK,OAAO;AAAA,EAK3B,IACA,CAAC;AAEL,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,IAEA;AAAA,IAGA,GAAG;AAAA,IACH;AAAA,IAEA;AAAA,IACA;AAAA,IACA;AAAA,IAGA;AAAA,EACJ,EAAE,KAAK,IAAI;AACf;AAhDgB;AAkDT,SAAS,kBACZ,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,IAKA;AAAA,IACA;AAAA,IACA;AAAA,IAEA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IAEA;AAAA,EACJ,EAAE,KAAK,IAAI;AACf;AAjCgB;AAmChB,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;AAAA;AAAA;AAAA;AAAA,EAKA,OAAM,CAAC,QAAQ,4CAA4C;AAAA,EAC3D,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;AAMT,MAAM,kBAAkB;AAAA,EAC3B;AAAA,EAAO;AAAA,EAAW;AAAA,EAAO;AAAA,EACzB;AAAA,EAAQ;AAAA,EAAS;AACrB;AAOO,SAAS,iBACZ,OACY;AACZ,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,IAAI,gBAAgB,QAAQ,KAAK;AACvC,SAAO,gBACH,KAAK,IAAI,IAAI,GAAG,gBAAgB,SAAS,CAAC,CAC9C;AACJ;AARgB;AAUT,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;AAiDT,SAAS,0BACI;AAChB,QAAM,QAAQ,oBAAI,IAEhB;AACF,MAAI,UAAU;AAEd,WAAS,aAAuB;AAC5B,UAAM,QAAQ,QAAQ,MAAM,IAAI;AAChC,QAAI,MAAM,WAAW,EAAG,QAAO,CAAC;AAChC,cAAU,MAAM,MAAM,SAAS,CAAC;AAChC,WAAO,MAAM,MAAM,GAAG,EAAE;AAAA,EAC5B;AALS;AAOT,WAAS,WAAqB;AAC1B,QAAI,QAAQ,WAAW,EAAG,QAAO,CAAC;AAClC,UAAM,MAAM;AACZ,cAAU;AACV,WAAO,CAAC,GAAG;AAAA,EACf;AALS;AAOT,WAASA,SAAS,MAAsB;AACpC,QAAI;AACJ,QAAI;AACA,YAAM,KAAK,MAAM,IAAI;AAAA,IAEzB,QAAQ;AACJ,aAAO,CAAC,IAAI;AAAA,IAChB;AAEA,UAAM,MAAM,IAAI;AAEhB,QAAI,CAAC,IAAK,QAAO,CAAC;AAElB,UAAM,OAAO,IAAI;AACjB,UAAM,KAAK,IAAI,gBACS;AAExB,QAAI,SAAS,cAAc;AACvB,YAAM,QACD,IAAI,SAA8B;AACvC,iBAAW;AACX,aAAO,WAAW;AAAA,IACtB;AAEA,QAAI,SAAS,kBAAkB;AAC3B,YAAM,UAAU,SAAS;AACzB,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,CAAC;AAAA,IACZ;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,CAAC,IAAI,KAAK,IAAI,KAAK,KAAK,EAAE;AAAA,IACrC;AAEA,WAAO,CAAC;AAAA,EACZ;AAjES,SAAAA,UAAA;AAmET,SAAO,EAAE,SAAAA,UAAS,OAAM,SAAS;AACrC;AAzFgB;AA2FhB,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;AAqBT,MAAM,iBAAiB;AAOhB,SAAS,iBAAkB,KAA2B;AACzD,MAAI,QAAQ,OAAW;AACvB,MAAI;AACA,YAAQ,KAAK,CAAC,KAAK,SAAS;AAAA,EAChC,QAAQ;AAAA,EAER;AACJ;AAPgB;AAYhB,MAAM,gBAAgB,oBAAI,IAAY;AAE/B,SAAS,oBAA0B;AACtC,aAAW,OAAO,eAAe;AAC7B,qBAAiB,GAAG;AAAA,EACxB;AACJ;AAJgB;AAMT,SAAS,WAAY,MAYJ;AACpB,QAAM,OAAgB;AAAA,IAClB,GAAG,gBAAgB,KAAK,QAAQ;AAAA,EACpC;AACA,MAAI,KAAK,OAAO;AACZ,SAAK,KAAK,WAAW,KAAK,KAAK;AAAA,EACnC;AACA,MAAI,KAAK,UAAU;AACf,SAAK,KAAK,eAAe,OAAO,KAAK,QAAQ,CAAC;AAAA,EAClD;AAEA,QAAM,eAAe,SAAS,KAAK,QAAQ;AAC3C,QAAM,WAAW,iBAAiB;AAClC,QAAM,OAAO,iBAAiB;AAC9B,MAAI,QAAQ,KAAK,UAAU;AACvB,SAAK,KAAK,cAAc,KAAK,QAAQ;AAAA,EACzC;AACA,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,IACT,UAAS;AAAA,EACb,CAAC;AAED,MAAI,KAAK,QAAQ,OAAW,eAAc,IAAI,KAAK,GAAG;AAEtD,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,QAAQ,YAAY,QAAQ,IAAI;AACtC,iBAAW,aAAa,OAAO;AAC3B,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,QAAI,YAAY,CAAC,YAAY,KAAK,IAAI,EAAG;AACzC,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,MAAI,WAAW;AACf,QAAM,UAAU,WAAW,MAAM;AAC7B,QAAI,KAAK,OAAQ;AACjB,eAAW;AACX,UAAM,MAAM,yBACL,KAAK,OAAO;AAKnB,cAAU,MAAM,eAAe,GAAG;AAAA,CAAI;AACtC,QAAI,KAAK,QAAQ;AACb,WAAK,OAAO,GAAG,MAAM,GAAG,GAAG,EAAE;AAAA,IACjC,OAAO;AACH,cAAQ,KAAK,GAAG,MAAM,GAAG,GAAG,EAAE;AAAA,IAClC;AACA,qBAAiB,KAAK,GAAG;AAAA,EAC7B,GAAG,KAAK,UAAU,GAAI;AAMtB,OAAK,MAAM,GAAG,SAAS,SAAO;AAC1B,cAAU;AAAA,MACN,mCACG,mBAAmB,GAAG,CAAC;AAAA;AAAA,IAC9B;AAAA,EACJ,CAAC;AAED,MAAI,CAAC,YAAY;AACb,SAAK,MAAM,MAAM,KAAK,MAAM;AAAA,EAChC;AACA,OAAK,MAAM,IAAI;AAEf,SAAO,IAAI,QAAqB,aAAW;AACvC,QAAI,UAAU;AACd,QAAI;AAEJ,aAAS,OAAQ,UAAsB;AACnC,UAAI,QAAS;AACb,gBAAU;AACV,mBAAa,OAAO;AACpB,UAAI,WAAY,cAAa,UAAU;AACvC,UAAI,KAAK,QAAQ,QAAW;AACxB,sBAAc,OAAO,KAAK,GAAG;AAAA,MACjC;AACA,UAAI,aAAa;AACb,mBAAW,QAAQ,YAAY,MAAM,GAAG;AACpC,2BAAiB,IAAI;AACrB,gBAAM,SAAS,GAAG,MAAM,GAAG,IAAI;AAC/B,cAAI,KAAK,QAAQ;AACb,iBAAK,OAAO,MAAM;AAAA,UACtB,OAAO;AACH,oBAAQ,IAAI,MAAM;AAAA,UACtB;AAAA,QACJ;AAAA,MACJ;AACA,SAAG,MAAM;AACT,YAAM,MAAM;AACZ,gBAAU,IAAI;AACd,UAAI,WAAY,mBAAkB,UAAU;AAC5C,cAAQ,EAAE,UAAU,gBAAgB,SAAS,CAAC;AAAA,IAClD;AAxBS;AA+BT,SAAK,GAAG,QAAQ,UAAQ;AACpB,mBAAa,WAAW,MAAM;AAC1B,yBAAiB,KAAK,GAAG;AACzB,aAAK,OAAO,QAAQ;AACpB,aAAK,OAAO,QAAQ;AACpB,eAAO,QAAQ,CAAC;AAAA,MACpB,GAAG,cAAc;AAAA,IACrB,CAAC;AAED,SAAK,GAAG,SAAS,UAAQ;AACrB,aAAO,QAAQ,CAAC;AAAA,IACpB,CAAC;AACD,SAAK,GAAG,SAAS,SAAO;AACpB,UAAI,QAAS;AACb,gBAAU;AACV,UAAI,WAAY,cAAa,UAAU;AACvC,mBAAa,OAAO;AACpB,UAAI,KAAK,QAAQ,QAAW;AACxB,sBAAc,OAAO,KAAK,GAAG;AAAA,MACjC;AACA,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;AAAA,QACJ,UAAS;AAAA,QACT;AAAA,QACA;AAAA,MACJ,CAAC;AAAA,IACL,CAAC;AAAA,EACL,CAAC;AACL;AAxNgB;AA0NT,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,MAUxB;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,QACI,KAAK;AAAA,QAAU,WAAW,CAAC;AAAA,QAC3B,EAAE,SAAQ,KAAK,QAAQ;AAAA,MAC3B;AAAA,IACJ;AAAA,EACJ;AAEA,QAAM,eACF,KAAK,qBAAqB,YACtB,uCACA;AACR,UAAQ;AAAA,IACJ;AAAA,gBAAmB,KAAK,WAAW,QAAQ;AAAA,EAC/C;AACA,UAAQ;AAAA,IACJ,iBAAiB,KAAK,YAAY,oBAAoB;AAAA,EAC1D;AACA,UAAQ;AAAA,IACJ,iBAAiB,KAAK,WAAW,eAAe;AAAA,EACpD;AACA,UAAQ;AAAA,IACJ,iBACG,KAAK,cAAc,CAAC;AAAA,EAC3B;AACA,UAAQ;AAAA,IACJ;AAAA,kBAAqB,YAAY;AAAA,EACrC;AACA,UAAQ,IAAI,kBAAkB,KAAK,YAAY,EAAE;AACrD;AA3EgB;AAgFhB,eAAe,YAAa,MASR;AAChB,QAAM,SAAS,MAAM,WAAW;AAAA,IAC5B,KAAI,KAAK;AAAA,IACT,KAAI,KAAK;AAAA,IACT,SAAQ,KAAK;AAAA,IACb,UAAS,KAAK;AAAA,EAClB,CAAC;AACD,QAAM,cAAc;AAAA,IAChB,KAAK;AAAA,IAAS,KAAK;AAAA,IAAQ,KAAK,WAAW;AAAA,IAC3C;AAAA,EACJ;AACA,gBAAc,aAAa,OAAO,MAAM;AAExC,MAAI,OAAO,aAAa,GAAG;AACvB,SAAK;AAAA,MACD,KAAK,KAAK,OAAO,QAAQ,wBAChB,OAAO,QAAQ,UACjB,WAAW;AAAA,IACtB;AACA,WAAO;AAAA,EACX;AAEA,OAAK,IAAI,KAAK,KAAK,OAAO,QAAQ,gBAAgB;AAClD,SAAO;AACX;AAjCe;AAsCf,eAAe,qBAAsB,MAcjB;AAChB,QAAM,MAAM,wBAAC,QAAoB;AAC7B,QAAI,KAAK,QAAQ;AACb,WAAK,OAAO,GAAG;AAAA,IACnB,OAAO;AACH,cAAQ,IAAI,GAAG;AAAA,IACnB;AAAA,EACJ,GANY;AAQZ,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,IACX,KAAK;AAAA,IAAU,KAAK;AAAA,EACxB;AACA,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,UAAS,KAAK;AAAA,IACd,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,MAAI,KAAK,SAAS;AACd,UAAM,SAAS,MAAM,YAAY;AAAA,MAC7B,SAAQ,KAAK;AAAA,MACb,QAAO,KAAK;AAAA,MACZ,cAAa,KAAK;AAAA,MAClB,SAAQ,KAAK;AAAA,MACb,SAAQ,KAAK;AAAA,MACb;AAAA,MACA,UAAS;AAAA,IACb,CAAC;AACD,QAAI,CAAC,QAAQ;AACT;AAAA,QACI,KAAK,KAAK,OAAO,QAAQ;AAAA,MAE7B;AACA,aAAO;AAAA,IACX;AAAA,EACJ;AAEA,QAAM,cAAc,MAAM;AAAA,IACtB,KAAK;AAAA,IAAU,KAAK;AAAA,EACxB;AACA,MAAI,CAAC,YAAY,SAAS;AACtB,UAAM,OAAO,KAAK,KAAK,OAAO,QAAQ;AAEtC,QAAI,KAAK,QAAQ;AACb,WAAK,OAAO,IAAI;AAAA,IACpB,OAAO;AACH,cAAQ,IAAI,IAAI;AAAA,IACpB;AACA,QAAI,YAAY,QAAQ;AACpB,YAAM,YACF,UAAU,YAAY,OAAO,KAAK,CAAC;AACvC,UAAI,KAAK,QAAQ;AACb,aAAK,OAAO,SAAS;AAAA,MACzB,OAAO;AACH,gBAAQ,IAAI,SAAS;AAAA,MACzB;AAAA,IACJ;AAAA,EACJ;AACA,SAAO,YAAY;AACvB;AA7Ge;AA+GR,MAAM,kBAAkB;AAKxB,MAAM,sBAAsB;AAE5B,SAAS,cAAe,MAAa,SAAuB;AAC/D,SAAO,OAAO,MAAM,UAAU;AAClC;AAFgB;AAIhB,SAAS,MAAO,IAAyB;AACrC,SAAO,IAAI,QAAQ,aAAW,WAAW,SAAS,EAAE,CAAC;AACzD;AAFS;AAOT,SAAS,eACL,SACA,QACA,SACA,KACK;AACL,QAAM,OAAO,OAAO,SAAS,QAAQ,SAAS,EAAE;AAChD,QAAM,SAAS,UAAU,IAAI,WAAW,OAAO,KAAK;AACpD,SAAO,KAAK,SAAS,GAAG,IAAI,GAAG,MAAM,GAAG,GAAG,EAAE;AACjD;AATS;AAyDT,eAAe,iBACX,MACqB;AACrB,QAAM,EAAE,QAAQ,EAAE,IAAI;AAEtB,MAAI;AACJ,MAAI;AACA,eAAW,MAAM,eAAe;AAAA,MAC5B,UAAS,KAAK;AAAA,MACd,UAAS,KAAK;AAAA,MACd,YAAW,KAAK;AAAA,MAChB;AAAA,IACJ,CAAC;AAAA,EACL,SAAS,OAAO;AACZ,WAAO,EAAE,MAAK,kBAAkB,MAAM;AAAA,EAC1C;AAEA,IAAE,gBAAgB,OAAO,KAAK,aAAa;AAC3C,QAAM,cAAc,MAAM,WAAW;AAAA,IACjC,QAAO;AAAA,MACH,KAAK;AAAA,MAAU;AAAA,MACf,EAAE,SAAQ,KAAK,QAAQ;AAAA,IAC3B;AAAA,IACA,UAAS,KAAK;AAAA,IACd,OAAM,KAAK;AAAA,IACX,SAAQ,KAAK;AAAA,IACb,SAAQ;AAAA,MACJ,KAAK;AAAA,MAAS;AAAA,MAAQ,KAAK;AAAA,MAAS;AAAA,IACxC;AAAA,IACA,KAAI,SAAS;AAAA,IACb,OAAM,OAAO,SAAS,QAAQ,SAAS,EAAE;AAAA,IACzC,UAAS,KAAK;AAAA,IACd,UAAS,KAAK;AAAA,IACd,QAAO,wBAAC,SAAS,EAAE,IAAI,IAAI,GAApB;AAAA,EACX,CAAC;AAKD,MAAI,YAAY,UAAU;AACtB,MAAE;AAAA,MACE,KAAK,OAAO,QAAQ;AAAA,IAExB;AAAA,EACJ,WAAW,YAAY,aAAa,GAAG;AACnC,MAAE;AAAA,MACE,KAAK,OAAO,QAAQ,kBACJ,YAAY,QAAQ;AAAA,IACxC;AACA,UAAM,sBAAsB,SAAS,cAAc,CAAC;AACpD,WAAO;AAAA,MACH,MAAK;AAAA,MACL,QAAO;AAAA,MACP,YAAW,SAAS;AAAA,MACpB,UAAS,YAAY;AAAA,MACrB,gBAAe,YAAY;AAAA,IAC/B;AAAA,EACJ;AAEA,MAAI,QAAQ,SAAS,YAAY,GAAG;AAChC,UAAM,YAAY,MAAM;AAAA,MACpB,SAAS;AAAA,MACT,2BACG,OAAO,QAAQ;AAAA,IACtB;AACA,QAAI,WAAW;AACX,QAAE;AAAA,QACE,KAAK,OAAO,QAAQ;AAAA,MAExB;AAAA,IACJ;AAAA,EACJ;AAEA,MAAI,CAAC;AAAA,IACD,KAAK;AAAA,IAAU,KAAK;AAAA,IAAY,SAAS;AAAA,EAC7C,GAAG;AACC,UAAM,sBAAsB,SAAS,cAAc,CAAC;AACpD,WAAO;AAAA,MACH,MAAK;AAAA,MACL,cAAa,SAAS;AAAA,MACtB,YAAW,SAAS;AAAA,IACxB;AAAA,EACJ;AAEA,MAAI,KAAK,SAAS;AACd,UAAM,SAAS,MAAM,YAAY;AAAA,MAC7B,SAAQ,KAAK;AAAA,MACb;AAAA,MACA,cAAa,SAAS;AAAA,MACtB,SAAQ,KAAK;AAAA,MACb,SAAQ,KAAK;AAAA,MACb,SAAQ,KAAK;AAAA,MACb,KAAI,wBAAC,QAAQ,EAAE,IAAI,GAAG,GAAlB;AAAA,MACJ,UAAS;AAAA,IACb,CAAC;AACD,QAAI,CAAC,QAAQ;AACT,YAAM;AAAA,QACF,SAAS;AAAA,QAAc;AAAA,MAC3B;AACA,aAAO;AAAA,QACH,MAAK;AAAA,QACL,QAAO;AAAA,QACP,YAAW,SAAS;AAAA,QACpB,UAAS;AAAA,QACT,gBAAe,YAAY;AAAA,MAC/B;AAAA,IACJ;AAAA,EACJ;AAEA,SAAO;AAAA,IACH,MAAK;AAAA,IACL,cAAa,SAAS;AAAA,IACtB,YAAW,SAAS;AAAA,IACpB,gBAAe,YAAY;AAAA,EAC/B;AACJ;AAnHe;AAwHf,eAAe,kBACX,MACqB;AACrB,QAAM,EAAE,QAAQ,EAAE,IAAI;AACtB,QAAM,cAAc,KAAK,UAAU;AACnC,QAAM,OAAO,SAAS,KAAK,QAAQ,MAAM;AACzC,MAAI,WAAW,KAAK;AACpB,MAAI,UAAwB;AAAA,IACxB,MAAK;AAAA,IAAc,cAAa;AAAA,IAAI,YAAW;AAAA,EACnD;AAEA,WAAS,UAAU,GAAG,WAAW,aAAa,WAAW;AACrD,QAAI,YAAY,GAAG;AACf,QAAE,IAAI,cAAc,OAAO,QAAQ,EAAE;AAAA,IACzC,OAAO;AACH,iBAAW,iBAAiB,QAAQ;AACpC,YAAM,QAAQ,cAAc,KAAK,YAAY,OAAO;AACpD,QAAE;AAAA,QACE,KAAK,OAAO,QAAQ,uBACR,OAAO,IAAI,WAAW,MACjC,OAAO,cAAc,QAAQ,KAAK,OAClC,QAAQ,IAAI,aAAa,KAAK,MAAM,MACrC;AAAA,MACJ;AACA,UAAI,QAAQ,EAAG,OAAM,MAAM,QAAQ,GAAI;AAAA,IAC3C;AACA,QAAI;AACA,gBAAU,MAAM,iBAAiB;AAAA,QAC7B,GAAG;AAAA,QAAM;AAAA,QAAS;AAAA,MACtB,CAAC;AAAA,IACL,SAAS,OAAO;AACZ,QAAE;AAAA,QACE,KAAK,OAAO,QAAQ,aAAa,OAAO,WAC9B,mBAAmB,KAAK,CAAC;AAAA,MACvC;AACA,aAAO,EAAE,MAAK,SAAS,MAAM;AAAA,IACjC;AACA,QACI,QAAQ,SAAS,WACjB,QAAQ,SAAS,kBACnB;AACE,aAAO;AAAA,IACX;AAAA,EACJ;AACA,SAAO;AACX;AA7Ce;AAkDf,eAAe,aACX,UACA,cACA,UACA,SACA,GACY;AACZ,gBAAc,cAAc,QAAQ;AACpC,MAAI;AACA,UAAM,eAAe,UAAU,cAAc,OAAO;AAAA,EACxD,SAAS,KAAK;AACV,MAAE;AAAA,MACE,kCACA,mBAAmB,GAAG;AAAA,IAC1B;AAAA,EACJ;AACJ;AAhBe;AAkBf,SAAS,YAAa,SAA2C;AAC7D,SAAO;AAAA,IACH,WAAU,QAAQ,OAAO,OAAK,EAAE,WAAW,MAAM,EAAE;AAAA,IACnD,OAAM,QAAQ;AAAA,EAClB;AACJ;AALS;AAOT,eAAsB,SAClB,SACA,UACA,UACA,OACA,SACA,SACA,SACA,UACA,UACA,SACA,YAC2B;AAC3B,YAAU,SAAS,EAAE,WAAU,KAAK,CAAC;AAErC,QAAM,IAAI,WAAW,cAAc;AACnC,QAAM,eAAe,WAAW,mBAAmB;AACnD,QAAM,YAAY,cAAc;AAChC,QAAM,OAAO,SAAS,QAAQ,MAAM;AACpC,MAAI,aAAa;AACjB,aAAW,KAAK,cAAc,OAAO,EAAG;AAExC,MAAI,iBAAiB;AACrB,MAAI,UAAU;AACd,QAAM,aAAa,oBAAI,IAAY;AAEnC,SAAO,MAAM;AACT,UAAM,QAAQ,iBAAiB,OAAO,EAAE;AAAA,MACpC,OAAK,CAAC,WAAW,IAAI,EAAE,GAAG;AAAA,IAC9B;AACA,QAAI,MAAM,WAAW,EAAG;AAExB;AACA,UAAM,YAAY,IAAI,IAAI,MAAM,IAAI,OAAK,EAAE,GAAG,CAAC;AAC/C,UAAMC,aAAY,QAAQ;AAAA,MAAO,OAC7B,EAAE,WAAW,qBACb,CAAC,UAAU,IAAI,EAAE,GAAG;AAAA,IACxB;AACA,MAAE;AAAA,MACE;AAAA,MACA;AAAA,MACA,MAAM,IAAI,QAAM;AAAA,QACZ,KAAI,EAAE;AAAA,QACN,UAAS,EAAE;AAAA,MACf,EAAE;AAAA,MACF,YAAY,OAAO;AAAA,MACnBA,WAAU,IAAI,QAAM;AAAA,QAChB,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,QAAQ,EAAE,SAAS;AAAA,UACrB;AAAA,UAAS;AAAA,QACb;AACA,UAAE,gBAAgB,EAAE,KAAK,aAAa;AACtC,UAAE,IAAI,cAAc,EAAE,QAAQ,EAAE;AAChC,YAAI,QAAQ;AACZ,YAAI,SAAS,MAAM,WAAW;AAAA,UAC1B;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA,SAAQ,eAAe,SAAS,GAAG,GAAG,MAAM;AAAA,UAC5C;AAAA,UACA;AAAA,UACA,UAAS;AAAA,UACT,QAAO,wBAAC,SAAS,EAAE,IAAI,IAAI,GAApB;AAAA,QACX,CAAC;AAID,iBACQ,UAAU,GACd,OAAO,aAAa,KACpB,CAAC,OAAO,YACR,WAAW,aACX,WACF;AACE,kBAAQ,iBAAiB,KAAK;AAC9B,gBAAM,QAAQ,cAAc,WAAW,OAAO;AAC9C,YAAE;AAAA,YACE,KAAK,EAAE,QAAQ,kBACZ,OAAO,QAAQ,uBACN,OAAO,IAAI,WAAW,MACjC,OAAO,cAAc,KAAK,KAAK,OAC/B,QAAQ,IAAI,aAAa,KAAK,MAAM,MACrC;AAAA,UACJ;AACA,cAAI,QAAQ,EAAG,OAAM,MAAM,QAAQ,GAAI;AACvC,mBAAS,MAAM,WAAW;AAAA,YACtB;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA,SAAQ;AAAA,cACJ;AAAA,cAAS;AAAA,cAAG;AAAA,cAAS;AAAA,YACzB;AAAA,YACA;AAAA,YACA;AAAA,YACA,UAAS;AAAA,YACT,QAAO,wBAAC,SAAS,EAAE,IAAI,IAAI,GAApB;AAAA,UACX,CAAC;AAAA,QACL;AACA,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,mBAAW,IAAI,OAAO,GAAG;AACzB,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,OACH,WAAW,OAAO,IACf,KAAK,WAAW,IAAI,YACpB;AAAA,EACR;AACA,IAAE,QAAQ;AAEV,SAAO,EAAE,SAAQ,UAAU,WAAW,EAAE;AAC5C;AA/JsB;AAiKtB,eAAsB,iBAAkB,MAkBR;AAC5B,YAAU,KAAK,SAAS,EAAE,WAAU,KAAK,CAAC;AAE1C,QAAM,IAAI,KAAK,WAAW,cAAc;AACxC,QAAM,UAAU,KAAK,WAAW;AAChC,QAAM,aAAa,KAAK,cAAc;AACtC,MAAI,aAAa;AACjB,aAAW,KAAK,cAAc,KAAK,OAAO,EAAG;AAE7C,QAAM,WAAW,YAAY;AAC7B,QAAM,WAAW,YAAY;AAC7B,QAAM,aAAa,iBAAiB;AAEpC,MAAI,QAAQ,QAAQ,GAAG;AACnB,UAAM,IAAI;AAAA,MACN;AAAA,IAEJ;AAAA,EACJ;AAEA,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,QAAM;AAAA,IACF;AAAA,IACA;AAAA,IACA;AAAA,IACA,qBAAqB,KAAK,WAAW;AAAA,IACrC;AAAA,EACJ;AAEA,MAAI,CAAC,KAAK,SAAS;AACf,MAAE,IAAI,uCAAuC;AAAA,EACjD;AAEA,MAAI,iBAAiB;AACrB,MAAI,UAAU;AACd,QAAM,aAAa,oBAAI,IAAY;AAEnC,SAAO,MAAM;AACT,UAAM,QAAQ,iBAAiB,KAAK,OAAO,EAAE;AAAA,MACzC,OAAK,CAAC,WAAW,IAAI,EAAE,GAAG;AAAA,IAC9B;AACA,QAAI,MAAM,WAAW,EAAG;AAExB;AACA,UAAM,YAAY,IAAI,IAAI,MAAM,IAAI,OAAK,EAAE,GAAG,CAAC;AAC/C,UAAMA,aAAY,KAAK,QAAQ;AAAA,MAAO,OAClC,EAAE,WAAW,qBACb,CAAC,UAAU,IAAI,EAAE,GAAG;AAAA,IACxB;AACA,MAAE;AAAA,MACE;AAAA,MACA;AAAA,MACA,MAAM,IAAI,QAAM;AAAA,QACZ,KAAI,EAAE;AAAA,QACN,UAAS,EAAE;AAAA,MACf,EAAE;AAAA,MACF,YAAY,KAAK,OAAO;AAAA,MACxBA,WAAU,IAAI,QAAM;AAAA,QAChB,KAAI,EAAE;AAAA,QACN,UAAS,EAAE;AAAA,MACf,EAAE;AAAA,IACN;AAKA,UAAM,WAAW,MAAM,QAAQ;AAAA,MAC3B,MAAM,IAAI,OAAK,kBAAkB;AAAA,QAC7B,QAAO;AAAA,QACP;AAAA,QACA;AAAA,QACA;AAAA,QACA,UAAS,KAAK;AAAA,QACd,UAAS,KAAK;AAAA,QACd,OAAM,KAAK;AAAA,QACX,SAAQ,KAAK;AAAA,QACb,SAAQ,KAAK;AAAA,QACb,SAAQ,KAAK;AAAA,QACb,UAAS,KAAK;AAAA,QACd,UAAS,KAAK;AAAA,QACd;AAAA,QACA;AAAA,QACA;AAAA,MACJ,CAAC,CAAC;AAAA,IACN;AAEA,QAAI,gBAAgB;AACpB,UAAM,qBAID,CAAC;AACN,UAAM,eAAe,oBAAI,IAAoB;AAC7C,UAAM,qBAAqB,oBAAI,IAAoB;AAEnD,aAAS,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK;AACtC,YAAM,UAAU,SAAS,CAAC;AAC1B,YAAM,SAAS,MAAM,CAAC;AAEtB,UAAI,QAAQ,SAAS,kBAAkB;AACnC,mBAAW,IAAI,OAAO,GAAG;AACzB,UAAE,gBAAgB,OAAO,KAAK,QAAQ;AACtC,UAAE;AAAA,UACE,KAAK,OAAO,QAAQ,gCACP,mBAAmB,QAAQ,KAAK,CAAC;AAAA,QAClD;AACA,oBAAY,UAAU,OAAO,KAAK;AAAA,UAC9B,QAAO;AAAA,UACP,UAAS;AAAA,UACT,MAAK;AAAA,QACT,CAAC;AACD,cAAM;AAAA,UACF;AAAA,UACA;AAAA,UACA;AAAA,UACA,eAAe,OAAO,QAAQ;AAAA,UAE9B;AAAA,QACJ;AACA;AAAA,MACJ;AAEA,UAAI,QAAQ,SAAS,SAAS;AAC1B,mBAAW,IAAI,OAAO,GAAG;AACzB,UAAE,gBAAgB,OAAO,KAAK,QAAQ;AACtC,UAAE;AAAA,UACE,KAAK,OAAO,QAAQ,sBACpB,mBAAmB,QAAQ,KAAK;AAAA,QACpC;AACA,oBAAY,UAAU,OAAO,KAAK;AAAA,UAC9B,QAAO,QAAQ,cAAc;AAAA,UAC7B,UAAS;AAAA,UACT,MAAK;AAAA,QACT,CAAC;AACD,cAAM;AAAA,UACF;AAAA,UACA;AAAA,UACA;AAAA,UACA,eAAe,OAAO,QAAQ;AAAA,UAC9B;AAAA,QACJ;AACA;AAAA,MACJ;AAEA,UAAI,QAAQ,SAAS,cAAc;AAC/B,mBAAW,IAAI,OAAO,GAAG;AACzB,UAAE,gBAAgB,OAAO,KAAK,QAAQ;AACtC,UAAE;AAAA,UACE,KAAK,OAAO,QAAQ;AAAA,QAGxB;AACA,oBAAY,UAAU,OAAO,KAAK;AAAA,UAC9B,QAAO,QAAQ;AAAA,UACf,UAAS;AAAA,UACT,MAAK;AAAA,QACT,CAAC;AACD,cAAM;AAAA,UACF;AAAA,UACA;AAAA,UACA;AAAA,UACA,eAAe,OAAO,QAAQ;AAAA,UAE9B;AAAA,QACJ;AACA;AAAA,MACJ;AAEA,UAAI,QAAQ,SAAS,UAAU;AAC3B,mBAAW,IAAI,OAAO,GAAG;AACzB,UAAE,gBAAgB,OAAO,KAAK,QAAQ;AACtC,YAAI,QAAQ,WAAW,QAAQ;AAC3B,qBAAW,QAAQ,QAAQ,cAAc;AAAA,QAC7C;AAIA,oBAAY,UAAU,OAAO,KAAK;AAAA,UAC9B,QAAO,QAAQ;AAAA,UACf,UAAS,QAAQ;AAAA,UACjB,MAAK;AAAA,QACT,CAAC;AACD,cAAM;AAAA,UACF;AAAA,UACA;AAAA,UACA;AAAA,UACA,eAAe,OAAO,QAAQ,OAC7B,QAAQ,WAAW,UAChB,iBACA;AAAA,UACJ;AAAA,QACJ;AACA;AAAA,MACJ;AAEA,iBAAW,QAAQ,QAAQ,cAAc;AACzC,QAAE;AAAA,QACE,KAAK,OAAO,QAAQ;AAAA,MAExB;AACA,mBAAa,IAAI,OAAO,KAAK,MAAM;AACnC,yBAAmB;AAAA,QACf,OAAO;AAAA,QAAK,QAAQ;AAAA,MACxB;AACA,yBAAmB,KAAK;AAAA,QACpB,QAAO,QAAQ;AAAA,QACf,WAAU,OAAO;AAAA,QACjB,cAAa,QAAQ;AAAA,MACzB,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,gBAAM;AAAA,YACF;AAAA,YACA;AAAA,YACA;AAAA,YACA,eAAe,OAAO,QAAQ;AAAA,YAC9B;AAAA,UACJ;AAEA,gBAAM,eAAe,mBAAmB;AAAA,YACpC,OAAO;AAAA,UACX;AACA,cAAI,cAAc;AACd,kBAAM;AAAA,cACF;AAAA,cAAc;AAAA,YAClB;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,SAAQ,KAAK;AAAA,YACb,UAAS,KAAK;AAAA,YACd,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,kBAAM;AAAA,cACF;AAAA,cACA;AAAA,cACA;AAAA,cACA,eAAe,OAAO,QAAQ;AAAA,cAE9B;AAAA,YACJ;AAEA,gBAAI,cAAc;AACd,kBAAI;AACA,sBAAM;AAAA,kBACF;AAAA,kBACA,EAAE,OAAM,KAAK;AAAA,gBACjB;AAAA,cACJ,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;AACA,gBAAI,aAAa,QAAQ;AACrB,gBAAE;AAAA,gBACE,YACA,aAAa,OAAO,KAAK;AAAA,cAC7B;AAAA,YACJ;AACA,wBAAY,UAAU,OAAO,KAAK;AAAA,cAC9B,QAAO,aAAa;AAAA,cACpB,UAAS;AAAA,cACT,MAAK;AAAA,YACT,CAAC;AACD,kBAAM;AAAA,cACF;AAAA,cACA;AAAA,cACA;AAAA,cACA,eAAe,OAAO,QAAQ;AAAA,cAE9B;AAAA,YACJ;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;AAAA,cACF,GAAG;AAAA,cACH,EAAE,OAAM,KAAK;AAAA,YACjB;AAAA,UACJ,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,OACH,WAAW,OAAO,IACf,KAAK,WAAW,IAAI,YACpB;AAAA,EACR;AACA,IAAE,QAAQ;AAEV,SAAO,EAAE,SAAQ,UAAU,WAAW,EAAE;AAC5C;AAhasB;",
6
6
  "names": ["process", "remaining"]
7
7
  }