@neotx/cli 0.1.0-alpha.20 → 0.1.0-alpha.21

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.
@@ -47,7 +47,8 @@ ${err.stack}`);
47
47
  try {
48
48
  const raw = await readFile(dispatchPath, "utf-8");
49
49
  const request = JSON.parse(raw);
50
- await unlink(dispatchPath).catch(() => {
50
+ await unlink(dispatchPath).catch((err) => {
51
+ console.debug("[worker] Failed to clean up dispatch file:", err);
51
52
  });
52
53
  writeLog(`[worker] Dispatch loaded: agent=${request.agentName} repo=${request.repo}`);
53
54
  const config = await loadGlobalConfig();
@@ -92,7 +93,8 @@ ${err.stack}`);
92
93
  await updatePersistedRun(runPath, {
93
94
  status: "failed",
94
95
  updatedAt: (/* @__PURE__ */ new Date()).toISOString()
95
- }).catch(() => {
96
+ }).catch((err) => {
97
+ console.debug("[worker] Failed to update persisted run on error:", err);
96
98
  });
97
99
  } finally {
98
100
  logStream.end();
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/daemon/worker.ts"],"sourcesContent":["/**\n * Detached worker process for `neo run -d`.\n *\n * Launched via child_process.fork() from the run command.\n * Reads dispatch parameters from a .dispatch.json file, runs the orchestrator,\n * and persists results. Stdout/stderr are redirected to a log file.\n *\n * Usage: node worker.js <runId> <repoSlug>\n */\n\nimport { createWriteStream, existsSync } from \"node:fs\";\nimport { mkdir, readFile, unlink, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type { PersistedRun } from \"@neotx/core\";\nimport {\n AgentRegistry,\n getRepoRunsDir,\n getRunDispatchPath,\n getRunLogPath,\n loadGlobalConfig,\n Orchestrator,\n} from \"@neotx/core\";\n\ninterface DispatchRequest {\n agentName: string;\n repo: string;\n prompt: string;\n branch?: string;\n priority?: \"critical\" | \"high\" | \"medium\" | \"low\";\n metadata?: Record<string, unknown>;\n bundledAgentsDir: string;\n customAgentsDir?: string;\n}\n\nasync function main(): Promise<void> {\n const [runId, repoSlug] = process.argv.slice(2);\n if (!runId || !repoSlug) {\n process.stderr.write(\"Usage: worker.js <runId> <repoSlug>\\n\");\n process.exit(1);\n }\n\n // Redirect stdout/stderr to log file\n const logPath = getRunLogPath(repoSlug, runId);\n await mkdir(path.dirname(logPath), { recursive: true });\n const logStream = createWriteStream(logPath, { flags: \"a\" });\n\n function writeLog(msg: string): void {\n logStream.write(`${new Date().toISOString()} ${msg}\\n`);\n }\n\n process.stdout.write = logStream.write.bind(logStream);\n process.stderr.write = logStream.write.bind(logStream);\n\n // Catch crashes and signals so we always leave a trace\n process.on(\"uncaughtException\", (err) => {\n writeLog(`[worker] UNCAUGHT EXCEPTION: ${err.message}\\n${err.stack}`);\n logStream.end();\n process.exit(1);\n });\n process.on(\"unhandledRejection\", (reason) => {\n writeLog(`[worker] UNHANDLED REJECTION: ${String(reason)}`);\n });\n for (const sig of [\"SIGTERM\", \"SIGINT\", \"SIGHUP\"] as const) {\n process.on(sig, () => {\n writeLog(`[worker] Received ${sig}, exiting`);\n logStream.end();\n process.exit(1);\n });\n }\n\n writeLog(`[worker] Starting run ${runId} (PID ${process.pid})`);\n\n const dispatchPath = getRunDispatchPath(repoSlug, runId);\n const runPath = path.join(getRepoRunsDir(repoSlug), `${runId}.json`);\n\n try {\n // Read dispatch request\n const raw = await readFile(dispatchPath, \"utf-8\");\n const request = JSON.parse(raw) as DispatchRequest;\n\n // Clean up dispatch file\n await unlink(dispatchPath).catch(() => {});\n writeLog(`[worker] Dispatch loaded: agent=${request.agentName} repo=${request.repo}`);\n\n // Load config and agents\n const config = await loadGlobalConfig();\n const agentRegistry = new AgentRegistry(\n request.bundledAgentsDir,\n request.customAgentsDir && existsSync(request.customAgentsDir)\n ? request.customAgentsDir\n : undefined,\n );\n await agentRegistry.load();\n\n const agent = agentRegistry.get(request.agentName);\n if (!agent) {\n throw new Error(`Agent \"${request.agentName}\" not found`);\n }\n\n // Create orchestrator — skip orphan recovery to prevent false positives on concurrent launches\n const orchestrator = new Orchestrator(config, { skipOrphanRecovery: true });\n orchestrator.registerAgent(agent);\n\n // Update persisted run with PID\n await updatePersistedRun(runPath, { pid: process.pid });\n\n // Safety timeout — ensure the process eventually exits\n const safetyTimeout = setTimeout(() => {\n console.error(\"[worker] Safety timeout reached, forcing exit\");\n process.exit(1);\n }, config.sessions.maxDurationMs + 60_000);\n safetyTimeout.unref();\n\n writeLog(\"[worker] Starting orchestrator...\");\n await orchestrator.start();\n\n writeLog(\"[worker] Dispatching...\");\n const result = await orchestrator.dispatch({\n runId,\n agent: request.agentName,\n repo: request.repo,\n prompt: request.prompt,\n ...(request.branch ? { branch: request.branch } : {}),\n priority: request.priority ?? \"medium\",\n metadata: request.metadata,\n });\n\n await orchestrator.shutdown();\n\n console.log(`[worker] Run ${runId} completed: ${result.status}`);\n console.log(`[worker] Cost: $${result.costUsd.toFixed(4)}`);\n if (result.branch) {\n console.log(`[worker] Branch: ${result.branch}`);\n }\n } catch (error) {\n const errorMsg = error instanceof Error ? error.message : String(error);\n console.error(`[worker] Run ${runId} failed: ${errorMsg}`);\n\n // Update persisted run to failed status\n await updatePersistedRun(runPath, {\n status: \"failed\",\n updatedAt: new Date().toISOString(),\n }).catch(() => {});\n } finally {\n logStream.end();\n process.exit(0);\n }\n}\n\nasync function updatePersistedRun(runPath: string, updates: Partial<PersistedRun>): Promise<void> {\n try {\n const raw = await readFile(runPath, \"utf-8\");\n const run = JSON.parse(raw) as PersistedRun;\n Object.assign(run, updates);\n await writeFile(runPath, JSON.stringify(run, null, 2), \"utf-8\");\n } catch {\n // Non-critical\n }\n}\n\nmain();\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/daemon/worker.ts"],"sourcesContent":["/**\n * Detached worker process for `neo run -d`.\n *\n * Launched via child_process.fork() from the run command.\n * Reads dispatch parameters from a .dispatch.json file, runs the orchestrator,\n * and persists results. Stdout/stderr are redirected to a log file.\n *\n * Usage: node worker.js <runId> <repoSlug>\n */\n\nimport { createWriteStream, existsSync } from \"node:fs\";\nimport { mkdir, readFile, unlink, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type { PersistedRun } from \"@neotx/core\";\nimport {\n AgentRegistry,\n getRepoRunsDir,\n getRunDispatchPath,\n getRunLogPath,\n loadGlobalConfig,\n Orchestrator,\n} from \"@neotx/core\";\n\ninterface DispatchRequest {\n agentName: string;\n repo: string;\n prompt: string;\n branch?: string;\n priority?: \"critical\" | \"high\" | \"medium\" | \"low\";\n metadata?: Record<string, unknown>;\n bundledAgentsDir: string;\n customAgentsDir?: string;\n}\n\nasync function main(): Promise<void> {\n const [runId, repoSlug] = process.argv.slice(2);\n if (!runId || !repoSlug) {\n process.stderr.write(\"Usage: worker.js <runId> <repoSlug>\\n\");\n process.exit(1);\n }\n\n // Redirect stdout/stderr to log file\n const logPath = getRunLogPath(repoSlug, runId);\n await mkdir(path.dirname(logPath), { recursive: true });\n const logStream = createWriteStream(logPath, { flags: \"a\" });\n\n function writeLog(msg: string): void {\n logStream.write(`${new Date().toISOString()} ${msg}\\n`);\n }\n\n process.stdout.write = logStream.write.bind(logStream);\n process.stderr.write = logStream.write.bind(logStream);\n\n // Catch crashes and signals so we always leave a trace\n process.on(\"uncaughtException\", (err) => {\n writeLog(`[worker] UNCAUGHT EXCEPTION: ${err.message}\\n${err.stack}`);\n logStream.end();\n process.exit(1);\n });\n process.on(\"unhandledRejection\", (reason) => {\n writeLog(`[worker] UNHANDLED REJECTION: ${String(reason)}`);\n });\n for (const sig of [\"SIGTERM\", \"SIGINT\", \"SIGHUP\"] as const) {\n process.on(sig, () => {\n writeLog(`[worker] Received ${sig}, exiting`);\n logStream.end();\n process.exit(1);\n });\n }\n\n writeLog(`[worker] Starting run ${runId} (PID ${process.pid})`);\n\n const dispatchPath = getRunDispatchPath(repoSlug, runId);\n const runPath = path.join(getRepoRunsDir(repoSlug), `${runId}.json`);\n\n try {\n // Read dispatch request\n const raw = await readFile(dispatchPath, \"utf-8\");\n const request = JSON.parse(raw) as DispatchRequest;\n\n // Clean up dispatch file\n await unlink(dispatchPath).catch((err) => {\n console.debug(\"[worker] Failed to clean up dispatch file:\", err);\n });\n writeLog(`[worker] Dispatch loaded: agent=${request.agentName} repo=${request.repo}`);\n\n // Load config and agents\n const config = await loadGlobalConfig();\n const agentRegistry = new AgentRegistry(\n request.bundledAgentsDir,\n request.customAgentsDir && existsSync(request.customAgentsDir)\n ? request.customAgentsDir\n : undefined,\n );\n await agentRegistry.load();\n\n const agent = agentRegistry.get(request.agentName);\n if (!agent) {\n throw new Error(`Agent \"${request.agentName}\" not found`);\n }\n\n // Create orchestrator — skip orphan recovery to prevent false positives on concurrent launches\n const orchestrator = new Orchestrator(config, { skipOrphanRecovery: true });\n orchestrator.registerAgent(agent);\n\n // Update persisted run with PID\n await updatePersistedRun(runPath, { pid: process.pid });\n\n // Safety timeout — ensure the process eventually exits\n const safetyTimeout = setTimeout(() => {\n console.error(\"[worker] Safety timeout reached, forcing exit\");\n process.exit(1);\n }, config.sessions.maxDurationMs + 60_000);\n safetyTimeout.unref();\n\n writeLog(\"[worker] Starting orchestrator...\");\n await orchestrator.start();\n\n writeLog(\"[worker] Dispatching...\");\n const result = await orchestrator.dispatch({\n runId,\n agent: request.agentName,\n repo: request.repo,\n prompt: request.prompt,\n ...(request.branch ? { branch: request.branch } : {}),\n priority: request.priority ?? \"medium\",\n metadata: request.metadata,\n });\n\n await orchestrator.shutdown();\n\n console.log(`[worker] Run ${runId} completed: ${result.status}`);\n console.log(`[worker] Cost: $${result.costUsd.toFixed(4)}`);\n if (result.branch) {\n console.log(`[worker] Branch: ${result.branch}`);\n }\n } catch (error) {\n const errorMsg = error instanceof Error ? error.message : String(error);\n console.error(`[worker] Run ${runId} failed: ${errorMsg}`);\n\n // Update persisted run to failed status\n await updatePersistedRun(runPath, {\n status: \"failed\",\n updatedAt: new Date().toISOString(),\n }).catch((err) => {\n console.debug(\"[worker] Failed to update persisted run on error:\", err);\n });\n } finally {\n logStream.end();\n process.exit(0);\n }\n}\n\nasync function updatePersistedRun(runPath: string, updates: Partial<PersistedRun>): Promise<void> {\n try {\n const raw = await readFile(runPath, \"utf-8\");\n const run = JSON.parse(raw) as PersistedRun;\n Object.assign(run, updates);\n await writeFile(runPath, JSON.stringify(run, null, 2), \"utf-8\");\n } catch {\n // Non-critical\n }\n}\n\nmain();\n"],"mappings":"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","names":[]}
package/dist/index.js CHANGED
@@ -18,7 +18,7 @@ var main = defineCommand({
18
18
  config: () => import("./config-NYF6AJXU.js").then((m) => m.default),
19
19
  repos: () => import("./repos-GI6F72NO.js").then((m) => m.default),
20
20
  agents: () => import("./agents-PH3P7G7E.js").then((m) => m.default),
21
- supervise: () => import("./supervise-FI6MYULH.js").then((m) => m.default),
21
+ supervise: () => import("./supervise-J3GYBSOC.js").then((m) => m.default),
22
22
  supervisor: () => import("./supervisor-3RUX5SPH.js").then((m) => m.default),
23
23
  memory: () => import("./memory-6R22DFS7.js").then((m) => m.default),
24
24
  mcp: () => import("./mcp-XHZND5A4.js").then((m) => m.default),
@@ -144,7 +144,7 @@ async function handleAttach(name) {
144
144
  process.exitCode = 1;
145
145
  return;
146
146
  }
147
- const { renderSupervisorTui } = await import("./tui-JJ6CD2YW.js");
147
+ const { renderSupervisorTui } = await import("./tui-RYLR4OLF.js");
148
148
  await renderSupervisorTui(name);
149
149
  }
150
150
  async function handleMessage(name, text) {
@@ -239,4 +239,4 @@ var supervise_default = defineCommand({
239
239
  export {
240
240
  supervise_default as default
241
241
  };
242
- //# sourceMappingURL=supervise-FI6MYULH.js.map
242
+ //# sourceMappingURL=supervise-J3GYBSOC.js.map
@@ -659,7 +659,8 @@ function SupervisorTui({ name }) {
659
659
  };
660
660
  }, [stdout]);
661
661
  useEffect(() => {
662
- loadGlobalConfig().then((cfg) => setDailyCap(cfg.supervisor.dailyCapUsd)).catch(() => {
662
+ loadGlobalConfig().then((cfg) => setDailyCap(cfg.supervisor.dailyCapUsd)).catch((err) => {
663
+ console.debug("[tui] Failed to load global config:", err);
663
664
  });
664
665
  }, []);
665
666
  useEffect(() => {
@@ -820,4 +821,4 @@ async function renderSupervisorTui(name) {
820
821
  export {
821
822
  renderSupervisorTui
822
823
  };
823
- //# sourceMappingURL=tui-JJ6CD2YW.js.map
824
+ //# sourceMappingURL=tui-RYLR4OLF.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/tui/index.ts","../src/tui/supervisor-tui.tsx"],"sourcesContent":["import { render } from \"ink\";\nimport React from \"react\";\nimport { SupervisorTui } from \"./supervisor-tui.js\";\n\n/**\n * Render the supervisor TUI. Returns a promise that resolves when the user exits.\n */\nexport async function renderSupervisorTui(name: string): Promise<void> {\n const { waitUntilExit } = render(React.createElement(SupervisorTui, { name }));\n await waitUntilExit();\n}\n","import { randomUUID } from \"node:crypto\";\nimport { appendFile, mkdir, readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type {\n ActivityEntry,\n Decision,\n InboxMessage,\n MemoryEntry,\n SupervisorDaemonState,\n} from \"@neotx/core\";\nimport {\n DecisionStore,\n getSupervisorActivityPath,\n getSupervisorDecisionsPath,\n getSupervisorDir,\n getSupervisorInboxPath,\n getSupervisorStatePath,\n loadGlobalConfig,\n MemoryStore,\n} from \"@neotx/core\";\nimport { Box, Text, useApp, useInput, useStdout } from \"ink\";\nimport TextInput from \"ink-text-input\";\nimport { useCallback, useEffect, useState } from \"react\";\n\n// ─── Constants ───────────────────────────────────────────\n\nconst MAX_VISIBLE_ENTRIES = 24;\nconst POLL_INTERVAL_MS = 1_500;\nconst ANIMATION_TICK_MS = 400;\n\n// ─── Unicode Visual Elements ─────────────────────────────\n\nconst SPARK_CHARS = [\"▁\", \"▂\", \"▃\", \"▄\", \"▅\", \"▆\", \"▇\", \"█\"];\nconst BLOCK_FULL = \"█\";\nconst BLOCK_EMPTY = \"░\";\nconst PULSE_FRAMES = [\"◉\", \"◎\", \"○\", \"◎\"];\nconst IDLE_FRAMES = [\"◌\", \"◌\", \"◌\", \"◌\"];\n\nconst TYPE_ICONS: Record<string, string> = {\n heartbeat: \"♥\",\n decision: \"★\",\n action: \"⚡\",\n error: \"✖\",\n event: \"◆\",\n message: \"✉\",\n thinking: \"◇\",\n plan: \"▸\",\n dispatch: \"↗\",\n tool_use: \"⊘\",\n};\n\nconst TYPE_COLORS: Record<string, string> = {\n heartbeat: \"#6ee7b7\",\n decision: \"#fbbf24\",\n action: \"#60a5fa\",\n error: \"#f87171\",\n event: \"#c084fc\",\n message: \"#67e8f9\",\n thinking: \"#a78bfa\",\n plan: \"#34d399\",\n dispatch: \"#f472b6\",\n tool_use: \"#38bdf8\",\n};\n\nconst TYPE_LABELS: Record<string, string> = {\n heartbeat: \"BEAT\",\n decision: \"DECIDE\",\n action: \"ACTION\",\n error: \"ERROR\",\n event: \"EVENT\",\n message: \"MSG\",\n thinking: \"THINK\",\n plan: \"PLAN\",\n dispatch: \"SEND\",\n tool_use: \"TOOL\",\n};\n\n// ─── Helpers ─────────────────────────────────────────────\n\nfunction formatTime(timestamp: string): string {\n return timestamp.slice(11, 19);\n}\n\nfunction formatUptime(startedAt: string): string {\n const ms = Date.now() - new Date(startedAt).getTime();\n const seconds = Math.floor(ms / 1000);\n const minutes = Math.floor(seconds / 60);\n const hours = Math.floor(minutes / 60);\n const days = Math.floor(hours / 24);\n if (days > 0) return `${days}d ${hours % 24}h`;\n if (hours > 0) return `${hours}h ${minutes % 60}m`;\n if (minutes > 0) return `${minutes}m ${seconds % 60}s`;\n return `${seconds}s`;\n}\n\nfunction formatTimeAgo(timestamp: string): string {\n const ms = Date.now() - new Date(timestamp).getTime();\n const seconds = Math.floor(ms / 1000);\n if (seconds < 60) return `${seconds}s ago`;\n const minutes = Math.floor(seconds / 60);\n if (minutes < 60) return `${minutes}m ago`;\n const hours = Math.floor(minutes / 60);\n return `${hours}h ago`;\n}\n\nfunction buildProgressBar(ratio: number, width: number): { filled: string; empty: string } {\n const clamped = Math.max(0, Math.min(1, ratio));\n const filledCount = Math.round(clamped * width);\n return {\n filled: BLOCK_FULL.repeat(filledCount),\n empty: BLOCK_EMPTY.repeat(width - filledCount),\n };\n}\n\nfunction buildSparkline(values: number[], width: number): string {\n if (values.length === 0) return \"▁\".repeat(width);\n const recent = values.slice(-width);\n const max = Math.max(...recent, 0.001);\n return recent\n .map((v) => {\n const idx = Math.min(\n Math.floor((v / max) * (SPARK_CHARS.length - 1)),\n SPARK_CHARS.length - 1,\n );\n return SPARK_CHARS[idx];\n })\n .join(\"\");\n}\n\nfunction extractCostHistory(entries: ActivityEntry[]): number[] {\n return entries\n .filter((e) => e.type === \"heartbeat\" && e.summary.includes(\"complete\"))\n .map((e) => {\n const detail = e.detail as Record<string, unknown> | undefined;\n return typeof detail?.costUsd === \"number\" ? detail.costUsd : 0;\n });\n}\n\n// ─── Animated Hooks ──────────────────────────────────────\n\nfunction useAnimationFrame(): number {\n const [frame, setFrame] = useState(0);\n useEffect(() => {\n const interval = setInterval(() => setFrame((f) => f + 1), ANIMATION_TICK_MS);\n return () => clearInterval(interval);\n }, []);\n return frame;\n}\n\nfunction useClock(): string {\n const [time, setTime] = useState(() => new Date().toLocaleTimeString());\n useEffect(() => {\n const interval = setInterval(() => setTime(new Date().toLocaleTimeString()), 1000);\n return () => clearInterval(interval);\n }, []);\n return time;\n}\n\n// ─── Components ──────────────────────────────────────────\n\nfunction Logo() {\n return (\n <Box paddingX={1} gap={1}>\n <Text color=\"#c084fc\" bold>\n ◆\n </Text>\n <Text bold>\n <Text color=\"#c084fc\">N</Text>\n <Text color=\"#a78bfa\">E</Text>\n <Text color=\"#818cf8\">O</Text>\n </Text>\n <Text dimColor>SUPERVISOR</Text>\n </Box>\n );\n}\n\nfunction LiveIndicator({ frame, isRunning }: { frame: number; isRunning: boolean }) {\n const frames = isRunning ? PULSE_FRAMES : IDLE_FRAMES;\n const dot = frames[frame % frames.length];\n return (\n <Box paddingX={1}>\n <Text color={isRunning ? \"#4ade80\" : \"#6b7280\"} bold>\n {dot}\n </Text>\n <Text color={isRunning ? \"#4ade80\" : \"#6b7280\"} bold>\n {\" \"}\n {isRunning ? \"LIVE\" : \"IDLE\"}\n </Text>\n </Box>\n );\n}\n\nfunction HeaderBar({\n state,\n name,\n frame,\n clock,\n}: {\n state: SupervisorDaemonState | null;\n name: string;\n frame: number;\n clock: string;\n}) {\n if (!state) {\n return (\n <Box borderStyle=\"round\" borderColor=\"#6b7280\" paddingX={1} flexDirection=\"column\">\n <Box justifyContent=\"space-between\">\n <Logo />\n <Box paddingX={1}>\n <Text dimColor>{clock}</Text>\n </Box>\n </Box>\n <Box paddingX={1}>\n <Text color=\"#fbbf24\">⟳ Connecting to \"{name}\"...</Text>\n </Box>\n </Box>\n );\n }\n\n const isRunning = state.status === \"running\";\n\n return (\n <Box\n borderStyle=\"round\"\n borderColor={isRunning ? \"#6ee7b7\" : \"#f87171\"}\n paddingX={0}\n flexDirection=\"column\"\n >\n <Box justifyContent=\"space-between\">\n <Logo />\n <Box gap={2}>\n <LiveIndicator frame={frame} isRunning={isRunning} />\n <Box paddingX={1}>\n <Text dimColor>{clock}</Text>\n </Box>\n </Box>\n </Box>\n\n <Box paddingX={1} gap={1}>\n <Text dimColor>│</Text>\n <Text>\n <Text dimColor>pid</Text> <Text bold>{state.pid}</Text>\n </Text>\n <Text dimColor>·</Text>\n <Text>\n <Text dimColor>port</Text> <Text bold>:{state.port}</Text>\n </Text>\n <Text dimColor>·</Text>\n <Text>\n <Text dimColor>beats</Text>{\" \"}\n <Text bold color=\"#6ee7b7\">\n ▲{state.heartbeatCount}\n </Text>\n </Text>\n {state.lastHeartbeat && (\n <>\n <Text dimColor>·</Text>\n <Text>\n <Text dimColor>last</Text> <Text>{formatTimeAgo(state.lastHeartbeat)}</Text>\n </Text>\n </>\n )}\n <Text dimColor>·</Text>\n <Text>\n <Text dimColor>up</Text> <Text>{formatUptime(state.startedAt)}</Text>\n </Text>\n </Box>\n </Box>\n );\n}\n\nfunction BudgetPanel({\n state,\n dailyCap,\n costHistory,\n}: {\n state: SupervisorDaemonState | null;\n dailyCap: number;\n costHistory: number[];\n}) {\n if (!state) return null;\n\n const todayCost = state.todayCostUsd ?? 0;\n const totalCost = state.totalCostUsd ?? 0;\n const ratio = dailyCap > 0 ? todayCost / dailyCap : 0;\n const barWidth = 20;\n const bar = buildProgressBar(ratio, barWidth);\n const pct = Math.round(ratio * 100);\n\n const barColor = pct < 50 ? \"#4ade80\" : pct < 80 ? \"#fbbf24\" : \"#f87171\";\n\n const sparkline = buildSparkline(costHistory, 12);\n\n return (\n <Box paddingX={2} gap={2}>\n <Box gap={1}>\n <Text dimColor>budget</Text>\n <Text color={barColor}>{bar.filled}</Text>\n <Text dimColor>{bar.empty}</Text>\n <Text bold color={barColor}>\n {pct}%\n </Text>\n <Text dimColor>\n (${todayCost.toFixed(2)}/${dailyCap})\n </Text>\n </Box>\n <Text dimColor>│</Text>\n <Box gap={1}>\n <Text dimColor>total</Text>\n <Text bold>${totalCost.toFixed(2)}</Text>\n </Box>\n <Text dimColor>│</Text>\n <Box gap={1}>\n <Text dimColor>cost/beat</Text>\n <Text color=\"#818cf8\">{sparkline}</Text>\n </Box>\n </Box>\n );\n}\n\nfunction ActivityRow({\n entry,\n isLatest,\n isOld,\n}: {\n entry: ActivityEntry;\n isLatest: boolean;\n isOld: boolean;\n}) {\n const icon = TYPE_ICONS[entry.type] ?? \"·\";\n const color = TYPE_COLORS[entry.type] ?? \"#9ca3af\";\n const label = (TYPE_LABELS[entry.type] ?? (entry.type as string).toUpperCase()).padEnd(7);\n\n return (\n <Box gap={1} paddingX={2}>\n <Text dimColor={isOld}>{isLatest ? \"│\" : \"│\"}</Text>\n <Text dimColor={isOld}>{formatTime(entry.timestamp)}</Text>\n <Text color={color} dimColor={isOld} bold={isLatest}>\n {icon}\n </Text>\n <Text color={color} dimColor={isOld} bold>\n {label}\n </Text>\n <Text dimColor={isOld} bold={isLatest}>\n {entry.summary}\n </Text>\n </Box>\n );\n}\n\nconst TASK_STATUS_COLORS: Record<string, string> = {\n in_progress: \"#60a5fa\",\n blocked: \"#f87171\",\n pending: \"#6b7280\",\n done: \"#4ade80\",\n};\n\nconst TASK_STATUS_LABELS: Record<string, string> = {\n in_progress: \"ACTIVE\",\n blocked: \"BLOCK\",\n pending: \"·\",\n};\n\nfunction TaskPanel({ tasks }: { tasks: MemoryEntry[] }) {\n const active = tasks.filter((t) => t.outcome !== \"done\" && t.outcome !== \"abandoned\");\n const doneCount = tasks.filter((t) => t.outcome === \"done\").length;\n\n if (tasks.length === 0) return null;\n\n const MAX_VISIBLE = 6;\n const visible = active.slice(0, MAX_VISIBLE);\n const overflow = active.length - visible.length;\n\n return (\n <Box flexDirection=\"column\">\n <Box paddingX={2} gap={1}>\n <Text dimColor>├</Text>\n <Text dimColor bold>\n TASKS\n </Text>\n <Text dimColor>\n ({active.length} active, {doneCount} done)\n </Text>\n <Text dimColor>{\"─\".repeat(30)}</Text>\n </Box>\n {visible.map((t) => {\n const status = t.outcome ?? \"pending\";\n const color = TASK_STATUS_COLORS[status] ?? \"#6b7280\";\n const label = (TASK_STATUS_LABELS[status] ?? \"·\").padEnd(6);\n const prio = t.severity ? `[${t.severity.slice(0, 3)}] ` : \"\";\n const repo = t.scope !== \"global\" ? path.basename(t.scope) : \"\";\n const run = t.runId ? `run:${t.runId.slice(0, 4)}` : \"\";\n const meta = [repo, run].filter(Boolean).join(\" \");\n\n return (\n <Box key={t.id} gap={1} paddingX={2}>\n <Text dimColor>│</Text>\n <Text color={color} bold>\n {label}\n </Text>\n {prio && <Text dimColor>{prio.padEnd(5)}</Text>}\n <Text wrap=\"truncate\">{t.content}</Text>\n {meta && <Text dimColor>({meta})</Text>}\n </Box>\n );\n })}\n {overflow > 0 && (\n <Box paddingX={2}>\n <Text dimColor>│ ... +{overflow} more pending</Text>\n </Box>\n )}\n </Box>\n );\n}\n\n/** Compact banner shown above activity when decisions exist but input is focused on chat */\nfunction DecisionBanner({ decisions, frame }: { decisions: Decision[]; frame: number }) {\n if (decisions.length === 0) return null;\n\n const pulseChars = [\"★\", \"☆\"];\n const pulse = pulseChars[frame % pulseChars.length];\n\n return (\n <Box paddingX={2} gap={1}>\n <Text dimColor>├</Text>\n <Text color=\"#fbbf24\" bold>\n {pulse} {decisions.length} decision{decisions.length > 1 ? \"s\" : \"\"} pending\n </Text>\n <Text dimColor>\n — press <Text bold>tab</Text> to review\n </Text>\n </Box>\n );\n}\n\n/** Full decision input panel — replaces the chat input when focused */\nfunction DecisionInputPanel({\n decision,\n optionIndex,\n isTextMode,\n textInput,\n onTextChange,\n onSubmit,\n decisionCount,\n decisionIdx,\n frame,\n}: {\n decision: Decision;\n optionIndex: number;\n isTextMode: boolean;\n textInput: string;\n onTextChange: (v: string) => void;\n onSubmit: (v: string) => void;\n decisionCount: number;\n decisionIdx: number;\n frame: number;\n}) {\n const hasOptions = decision.options && decision.options.length > 0;\n const pulseChars = [\"★\", \"☆\"];\n const pulse = pulseChars[frame % pulseChars.length];\n\n return (\n <Box flexDirection=\"column\">\n {/* Header */}\n <Box paddingX={2} gap={1}>\n <Text dimColor>├</Text>\n <Text color=\"#fbbf24\" bold>\n {pulse} DECISION\n </Text>\n {decisionCount > 1 && (\n <Text color=\"#fbbf24\">\n ({decisionIdx + 1}/{decisionCount})\n </Text>\n )}\n <Text dimColor>{\"─\".repeat(30)}</Text>\n </Box>\n\n {/* Question */}\n <Box paddingX={2} gap={1}>\n <Text dimColor>│</Text>\n <Text bold wrap=\"truncate-end\">\n {decision.question}\n </Text>\n </Box>\n\n {/* Context if available */}\n {decision.context && (\n <Box paddingX={2} gap={1}>\n <Text dimColor>│</Text>\n <Text dimColor wrap=\"truncate-end\">\n {decision.context}\n </Text>\n </Box>\n )}\n\n {/* Option selector or free text */}\n {hasOptions ? (\n <Box flexDirection=\"column\">\n {(decision.options ?? []).map((opt, idx) => {\n const isSelected = idx === optionIndex;\n return (\n <Box key={opt.key} paddingX={2} gap={1}>\n <Text dimColor>│</Text>\n {isSelected ? (\n <Text color=\"#fbbf24\" bold>\n ▸ {opt.label}\n </Text>\n ) : (\n <Text dimColor>\n {\" \"}\n {opt.label}\n </Text>\n )}\n {opt.description && isSelected && <Text dimColor>— {opt.description}</Text>}\n </Box>\n );\n })}\n </Box>\n ) : (\n <Box paddingX={2} gap={1}>\n <Text dimColor>│</Text>\n <Text color=\"#fbbf24\" bold>\n ❯\n </Text>\n <TextInput\n value={textInput}\n onChange={onTextChange}\n onSubmit={onSubmit}\n focus={isTextMode}\n placeholder=\"type your answer...\"\n />\n </Box>\n )}\n\n {/* Footer hints */}\n <Box paddingX={2} gap={1}>\n <Text dimColor>└</Text>\n <Text dimColor>\n {hasOptions ? (\n <>\n <Text bold>↑↓</Text> choose · <Text bold>enter</Text> confirm\n </>\n ) : (\n <>\n <Text bold>enter</Text> send\n </>\n )}\n {decisionCount > 1 && (\n <>\n {\" · \"}\n <Text bold>←→</Text> prev/next\n </>\n )}\n {\" · \"}\n <Text bold>tab</Text> chat · <Text bold>esc</Text> back\n </Text>\n </Box>\n </Box>\n );\n}\n\n/** Types shown in the activity feed — plan/thinking are internal, not shown */\nconst ACTIVITY_TYPES = new Set([\n \"heartbeat\",\n \"decision\",\n \"action\",\n \"dispatch\",\n \"error\",\n \"event\",\n \"message\",\n]);\n\nfunction ActivityPanel({ entries, termHeight }: { entries: ActivityEntry[]; termHeight: number }) {\n // Reserve lines for header (5), budget (1), separator (1), input (2), footer (1) = 10\n const maxVisible = Math.max(5, Math.min(MAX_VISIBLE_ENTRIES, termHeight - 10));\n const filtered = entries.filter((e) => ACTIVITY_TYPES.has(e.type));\n const visible = filtered.slice(-maxVisible);\n\n return (\n <Box flexDirection=\"column\">\n <Box paddingX={2} gap={1}>\n <Text dimColor>├</Text>\n <Text dimColor bold>\n ACTIVITY\n </Text>\n <Text dimColor>{\"─\".repeat(40)}</Text>\n </Box>\n\n {visible.length === 0 ? (\n <Box paddingX={2}>\n <Text dimColor>│ Waiting for heartbeats...</Text>\n </Box>\n ) : (\n visible.map((entry, idx) => (\n <ActivityRow\n key={entry.id}\n entry={entry}\n isLatest={idx === visible.length - 1}\n isOld={idx < visible.length - 5}\n />\n ))\n )}\n\n <Box paddingX={2}>\n <Text dimColor>│</Text>\n </Box>\n </Box>\n );\n}\n\nfunction InputPanel({\n value,\n onChange,\n onSubmit,\n lastSent,\n focus,\n}: {\n value: string;\n onChange: (v: string) => void;\n onSubmit: (v: string) => void;\n lastSent: string;\n focus: boolean;\n}) {\n return (\n <Box flexDirection=\"column\">\n <Box paddingX={2} gap={1}>\n <Text dimColor>└</Text>\n <Text bold color=\"#60a5fa\">\n ❯\n </Text>\n <TextInput\n value={value}\n onChange={onChange}\n onSubmit={onSubmit}\n focus={focus}\n placeholder=\"message the supervisor...\"\n />\n </Box>\n <Box paddingX={2} gap={1}>\n <Text dimColor> </Text>\n {lastSent ? <Text color=\"#6b7280\">✓ \"{lastSent}\"</Text> : null}\n </Box>\n </Box>\n );\n}\n\nfunction Footer({ hasDecisions }: { hasDecisions: boolean }) {\n return (\n <Box paddingX={2} gap={1} justifyContent=\"center\">\n <Text dimColor>\n <Text bold>esc</Text> quit\n </Text>\n <Text dimColor>·</Text>\n <Text dimColor>\n <Text bold>enter</Text> send\n </Text>\n {hasDecisions && (\n <>\n <Text dimColor>·</Text>\n <Text dimColor>\n <Text bold>tab</Text> decisions\n </Text>\n </>\n )}\n <Text dimColor>·</Text>\n <Text dimColor>daemon keeps running</Text>\n </Box>\n );\n}\n\n// ─── Data Fetching ───────────────────────────────────────\n\nasync function readState(name: string): Promise<SupervisorDaemonState | null> {\n try {\n const raw = await readFile(getSupervisorStatePath(name), \"utf-8\");\n return JSON.parse(raw) as SupervisorDaemonState;\n } catch {\n return null;\n }\n}\n\nasync function readActivity(name: string, maxEntries: number): Promise<ActivityEntry[]> {\n try {\n const content = await readFile(getSupervisorActivityPath(name), \"utf-8\");\n const lines = content.trim().split(\"\\n\").filter(Boolean);\n const lastLines = lines.slice(-maxEntries);\n const entries: ActivityEntry[] = [];\n for (const line of lastLines) {\n try {\n entries.push(JSON.parse(line) as ActivityEntry);\n } catch {\n // Skip malformed\n }\n }\n return entries;\n } catch {\n return [];\n }\n}\n\nfunction readTasks(name: string): MemoryEntry[] {\n try {\n const dir = getSupervisorDir(name);\n const store = new MemoryStore(path.join(dir, \"memory.sqlite\"));\n const tasks = store.query({ types: [\"task\"], limit: 20, sortBy: \"createdAt\" });\n store.close();\n return tasks;\n } catch {\n return [];\n }\n}\n\nasync function readDecisions(name: string): Promise<Decision[]> {\n try {\n const store = new DecisionStore(getSupervisorDecisionsPath(name));\n return await store.pending();\n } catch {\n return [];\n }\n}\n\n/**\n * Appends a JSON entry to a JSONL file.\n * Creates the parent directory if needed. Returns false on error.\n */\nasync function appendToJsonl(filePath: string, data: unknown): Promise<boolean> {\n const dir = path.dirname(filePath);\n try {\n await mkdir(dir, { recursive: true });\n await appendFile(filePath, `${JSON.stringify(data)}\\n`, \"utf-8\");\n return true;\n } catch (error) {\n console.error(\n `Warning: Failed to write to ${path.basename(filePath)}: ${error instanceof Error ? error.message : String(error)}`,\n );\n return false;\n }\n}\n\n/**\n * Writes a message to the supervisor's inbox.jsonl file.\n * Creates the directory if it doesn't exist and handles write errors gracefully.\n */\nasync function writeToInbox(name: string, message: InboxMessage): Promise<boolean> {\n const inboxPath = getSupervisorInboxPath(name);\n return appendToJsonl(inboxPath, message);\n}\n\nasync function answerDecision(name: string, id: string, answer: string): Promise<void> {\n const store = new DecisionStore(getSupervisorDecisionsPath(name));\n await store.answer(id, answer);\n\n // Wake up the supervisor heartbeat by appending to inbox.jsonl\n const inboxMessage: InboxMessage = {\n id: randomUUID(),\n from: \"tui\",\n text: `decision:answer ${id} ${answer}`,\n timestamp: new Date().toISOString(),\n };\n await writeToInbox(name, inboxMessage);\n}\n\nasync function sendMessage(name: string, text: string): Promise<void> {\n const id = randomUUID();\n const timestamp = new Date().toISOString();\n\n const message: InboxMessage = { id, from: \"tui\", text, timestamp };\n await writeToInbox(name, message);\n\n // Write to activity.jsonl so the message appears in the TUI conversation\n const activityEntry: ActivityEntry = { id, type: \"message\", summary: text, timestamp };\n const activityPath = getSupervisorActivityPath(name);\n await appendToJsonl(activityPath, activityEntry);\n}\n\n// ─── Main Component ──────────────────────────────────────\n\nexport function SupervisorTui({ name }: { name: string }) {\n const { exit } = useApp();\n const { stdout } = useStdout();\n const frame = useAnimationFrame();\n const clock = useClock();\n\n const [state, setState] = useState<SupervisorDaemonState | null>(null);\n const [entries, setEntries] = useState<ActivityEntry[]>([]);\n const [tasks, setTasks] = useState<MemoryEntry[]>([]);\n const [decisions, setDecisions] = useState<Decision[]>([]);\n const [dailyCap, setDailyCap] = useState(50);\n const [input, setInput] = useState(\"\");\n const [lastSent, setLastSent] = useState(\"\");\n const [termHeight, setTermHeight] = useState(stdout?.rows ?? 30);\n\n // Decision interaction state\n const [decisionIndex, setDecisionIndex] = useState(0);\n const [optionIndex, setOptionIndex] = useState(0);\n const [decisionAnswer, setDecisionAnswer] = useState(\"\");\n const [focusMode, setFocusMode] = useState<\"input\" | \"decisions\">(\"input\");\n\n // Track terminal resize\n useEffect(() => {\n function onResize() {\n if (stdout) setTermHeight(stdout.rows);\n }\n stdout?.on(\"resize\", onResize);\n return () => {\n stdout?.off(\"resize\", onResize);\n };\n }, [stdout]);\n\n // Load daily cap from config\n useEffect(() => {\n loadGlobalConfig()\n .then((cfg) => setDailyCap(cfg.supervisor.dailyCapUsd))\n .catch(() => {});\n }, []);\n\n // Poll state, activity, and decisions\n useEffect(() => {\n let active = true;\n\n async function poll() {\n if (!active) return;\n const [newState, newEntries, newDecisions] = await Promise.all([\n readState(name),\n readActivity(name, MAX_VISIBLE_ENTRIES),\n readDecisions(name),\n ]);\n if (!active) return;\n setState(newState);\n setEntries(newEntries);\n setDecisions(newDecisions);\n setTasks(readTasks(name));\n // Reset decision index if out of bounds\n if (newDecisions.length > 0 && decisionIndex >= newDecisions.length) {\n setDecisionIndex(0);\n }\n // Auto-switch to decisions mode when new decisions appear\n if (newDecisions.length > 0 && decisions.length === 0) {\n setFocusMode(\"decisions\");\n }\n // Return to input mode when all decisions are resolved\n if (newDecisions.length === 0 && decisions.length > 0) {\n setFocusMode(\"input\");\n }\n }\n\n poll();\n const interval = setInterval(poll, POLL_INTERVAL_MS);\n return () => {\n active = false;\n clearInterval(interval);\n };\n }, [name, decisionIndex, decisions.length]);\n\n // Current decision being interacted with\n const currentDecision = decisions[decisionIndex] as Decision | undefined;\n const currentHasOptions = (currentDecision?.options?.length ?? 0) > 0;\n\n // Submit the selected option or free-text answer\n const submitDecisionAnswer = useCallback(\n async (answer: string) => {\n if (!answer.trim() || !currentDecision) return;\n try {\n await answerDecision(name, currentDecision.id, answer.trim());\n setLastSent(`Decision ${currentDecision.id.slice(4, 12)}: \"${answer.trim()}\"`);\n setDecisionAnswer(\"\");\n setOptionIndex(0);\n } catch {\n // Decision may have been answered already\n }\n },\n [name, currentDecision],\n );\n\n const handleOptionNav = useCallback(\n (key: { upArrow: boolean; downArrow: boolean; return: boolean }): boolean => {\n const options = currentDecision?.options;\n if (!options || options.length === 0) return false;\n\n if (key.upArrow) {\n setOptionIndex((i) => Math.max(0, i - 1));\n return true;\n }\n if (key.downArrow) {\n setOptionIndex((i) => Math.min(options.length - 1, i + 1));\n return true;\n }\n if (key.return) {\n const opt = options[optionIndex];\n if (opt) submitDecisionAnswer(opt.key);\n return true;\n }\n return false;\n },\n [currentDecision, optionIndex, submitDecisionAnswer],\n );\n\n useInput((_char, key) => {\n if (key.tab && decisions.length > 0) {\n setFocusMode((m) => (m === \"input\" ? \"decisions\" : \"input\"));\n setOptionIndex(0);\n return;\n }\n\n if (key.escape) {\n if (focusMode === \"decisions\") {\n setFocusMode(\"input\");\n } else {\n exit();\n }\n return;\n }\n\n if (focusMode !== \"decisions\" || decisions.length === 0) return;\n\n if (currentHasOptions && handleOptionNav(key)) return;\n\n // ←→ to switch between decisions when multiple\n if (decisions.length > 1) {\n if (key.leftArrow) {\n setDecisionIndex((i) => Math.max(0, i - 1));\n setOptionIndex(0);\n } else if (key.rightArrow) {\n setDecisionIndex((i) => Math.min(decisions.length - 1, i + 1));\n setOptionIndex(0);\n }\n }\n });\n\n const handleSubmit = useCallback(\n (text: string) => {\n if (!text.trim()) return;\n sendMessage(name, text.trim());\n setLastSent(text.trim());\n setInput(\"\");\n },\n [name],\n );\n\n const costHistory = extractCostHistory(entries);\n\n // Calculate height adjustments for panels\n const activeTaskCount = tasks.filter(\n (t) => t.outcome !== \"done\" && t.outcome !== \"abandoned\",\n ).length;\n const taskPanelLines = tasks.length > 0 ? Math.min(activeTaskCount, 6) + 2 : 0;\n const decisionPanelLines =\n focusMode === \"decisions\" && currentDecision\n ? (currentHasOptions ? (currentDecision.options?.length ?? 0) : 1) + 4\n : decisions.length > 0\n ? 1\n : 0;\n\n // Bottom panel: either decision input or chat input\n const bottomPanel =\n focusMode === \"decisions\" && currentDecision ? (\n <DecisionInputPanel\n decision={currentDecision}\n optionIndex={optionIndex}\n isTextMode={!currentHasOptions}\n textInput={decisionAnswer}\n onTextChange={setDecisionAnswer}\n onSubmit={submitDecisionAnswer}\n decisionCount={decisions.length}\n decisionIdx={decisionIndex}\n frame={frame}\n />\n ) : (\n <>\n <InputPanel\n value={input}\n onChange={setInput}\n onSubmit={handleSubmit}\n lastSent={lastSent}\n focus={focusMode === \"input\"}\n />\n <Footer hasDecisions={decisions.length > 0} />\n </>\n );\n\n return (\n <Box flexDirection=\"column\">\n <HeaderBar state={state} name={name} frame={frame} clock={clock} />\n <BudgetPanel state={state} dailyCap={dailyCap} costHistory={costHistory} />\n {focusMode !== \"decisions\" && <DecisionBanner decisions={decisions} frame={frame} />}\n <TaskPanel tasks={tasks} />\n <ActivityPanel\n entries={entries}\n termHeight={termHeight - taskPanelLines - decisionPanelLines}\n />\n {bottomPanel}\n </Box>\n );\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/tui/index.ts","../src/tui/supervisor-tui.tsx"],"sourcesContent":["import { render } from \"ink\";\nimport React from \"react\";\nimport { SupervisorTui } from \"./supervisor-tui.js\";\n\n/**\n * Render the supervisor TUI. Returns a promise that resolves when the user exits.\n */\nexport async function renderSupervisorTui(name: string): Promise<void> {\n const { waitUntilExit } = render(React.createElement(SupervisorTui, { name }));\n await waitUntilExit();\n}\n","import { randomUUID } from \"node:crypto\";\nimport { appendFile, mkdir, readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type {\n ActivityEntry,\n Decision,\n InboxMessage,\n MemoryEntry,\n SupervisorDaemonState,\n} from \"@neotx/core\";\nimport {\n DecisionStore,\n getSupervisorActivityPath,\n getSupervisorDecisionsPath,\n getSupervisorDir,\n getSupervisorInboxPath,\n getSupervisorStatePath,\n loadGlobalConfig,\n MemoryStore,\n} from \"@neotx/core\";\nimport { Box, Text, useApp, useInput, useStdout } from \"ink\";\nimport TextInput from \"ink-text-input\";\nimport { useCallback, useEffect, useState } from \"react\";\n\n// ─── Constants ───────────────────────────────────────────\n\nconst MAX_VISIBLE_ENTRIES = 24;\nconst POLL_INTERVAL_MS = 1_500;\nconst ANIMATION_TICK_MS = 400;\n\n// ─── Unicode Visual Elements ─────────────────────────────\n\nconst SPARK_CHARS = [\"▁\", \"▂\", \"▃\", \"▄\", \"▅\", \"▆\", \"▇\", \"█\"];\nconst BLOCK_FULL = \"█\";\nconst BLOCK_EMPTY = \"░\";\nconst PULSE_FRAMES = [\"◉\", \"◎\", \"○\", \"◎\"];\nconst IDLE_FRAMES = [\"◌\", \"◌\", \"◌\", \"◌\"];\n\nconst TYPE_ICONS: Record<string, string> = {\n heartbeat: \"♥\",\n decision: \"★\",\n action: \"⚡\",\n error: \"✖\",\n event: \"◆\",\n message: \"✉\",\n thinking: \"◇\",\n plan: \"▸\",\n dispatch: \"↗\",\n tool_use: \"⊘\",\n};\n\nconst TYPE_COLORS: Record<string, string> = {\n heartbeat: \"#6ee7b7\",\n decision: \"#fbbf24\",\n action: \"#60a5fa\",\n error: \"#f87171\",\n event: \"#c084fc\",\n message: \"#67e8f9\",\n thinking: \"#a78bfa\",\n plan: \"#34d399\",\n dispatch: \"#f472b6\",\n tool_use: \"#38bdf8\",\n};\n\nconst TYPE_LABELS: Record<string, string> = {\n heartbeat: \"BEAT\",\n decision: \"DECIDE\",\n action: \"ACTION\",\n error: \"ERROR\",\n event: \"EVENT\",\n message: \"MSG\",\n thinking: \"THINK\",\n plan: \"PLAN\",\n dispatch: \"SEND\",\n tool_use: \"TOOL\",\n};\n\n// ─── Helpers ─────────────────────────────────────────────\n\nfunction formatTime(timestamp: string): string {\n return timestamp.slice(11, 19);\n}\n\nfunction formatUptime(startedAt: string): string {\n const ms = Date.now() - new Date(startedAt).getTime();\n const seconds = Math.floor(ms / 1000);\n const minutes = Math.floor(seconds / 60);\n const hours = Math.floor(minutes / 60);\n const days = Math.floor(hours / 24);\n if (days > 0) return `${days}d ${hours % 24}h`;\n if (hours > 0) return `${hours}h ${minutes % 60}m`;\n if (minutes > 0) return `${minutes}m ${seconds % 60}s`;\n return `${seconds}s`;\n}\n\nfunction formatTimeAgo(timestamp: string): string {\n const ms = Date.now() - new Date(timestamp).getTime();\n const seconds = Math.floor(ms / 1000);\n if (seconds < 60) return `${seconds}s ago`;\n const minutes = Math.floor(seconds / 60);\n if (minutes < 60) return `${minutes}m ago`;\n const hours = Math.floor(minutes / 60);\n return `${hours}h ago`;\n}\n\nfunction buildProgressBar(ratio: number, width: number): { filled: string; empty: string } {\n const clamped = Math.max(0, Math.min(1, ratio));\n const filledCount = Math.round(clamped * width);\n return {\n filled: BLOCK_FULL.repeat(filledCount),\n empty: BLOCK_EMPTY.repeat(width - filledCount),\n };\n}\n\nfunction buildSparkline(values: number[], width: number): string {\n if (values.length === 0) return \"▁\".repeat(width);\n const recent = values.slice(-width);\n const max = Math.max(...recent, 0.001);\n return recent\n .map((v) => {\n const idx = Math.min(\n Math.floor((v / max) * (SPARK_CHARS.length - 1)),\n SPARK_CHARS.length - 1,\n );\n return SPARK_CHARS[idx];\n })\n .join(\"\");\n}\n\nfunction extractCostHistory(entries: ActivityEntry[]): number[] {\n return entries\n .filter((e) => e.type === \"heartbeat\" && e.summary.includes(\"complete\"))\n .map((e) => {\n const detail = e.detail as Record<string, unknown> | undefined;\n return typeof detail?.costUsd === \"number\" ? detail.costUsd : 0;\n });\n}\n\n// ─── Animated Hooks ──────────────────────────────────────\n\nfunction useAnimationFrame(): number {\n const [frame, setFrame] = useState(0);\n useEffect(() => {\n const interval = setInterval(() => setFrame((f) => f + 1), ANIMATION_TICK_MS);\n return () => clearInterval(interval);\n }, []);\n return frame;\n}\n\nfunction useClock(): string {\n const [time, setTime] = useState(() => new Date().toLocaleTimeString());\n useEffect(() => {\n const interval = setInterval(() => setTime(new Date().toLocaleTimeString()), 1000);\n return () => clearInterval(interval);\n }, []);\n return time;\n}\n\n// ─── Components ──────────────────────────────────────────\n\nfunction Logo() {\n return (\n <Box paddingX={1} gap={1}>\n <Text color=\"#c084fc\" bold>\n ◆\n </Text>\n <Text bold>\n <Text color=\"#c084fc\">N</Text>\n <Text color=\"#a78bfa\">E</Text>\n <Text color=\"#818cf8\">O</Text>\n </Text>\n <Text dimColor>SUPERVISOR</Text>\n </Box>\n );\n}\n\nfunction LiveIndicator({ frame, isRunning }: { frame: number; isRunning: boolean }) {\n const frames = isRunning ? PULSE_FRAMES : IDLE_FRAMES;\n const dot = frames[frame % frames.length];\n return (\n <Box paddingX={1}>\n <Text color={isRunning ? \"#4ade80\" : \"#6b7280\"} bold>\n {dot}\n </Text>\n <Text color={isRunning ? \"#4ade80\" : \"#6b7280\"} bold>\n {\" \"}\n {isRunning ? \"LIVE\" : \"IDLE\"}\n </Text>\n </Box>\n );\n}\n\nfunction HeaderBar({\n state,\n name,\n frame,\n clock,\n}: {\n state: SupervisorDaemonState | null;\n name: string;\n frame: number;\n clock: string;\n}) {\n if (!state) {\n return (\n <Box borderStyle=\"round\" borderColor=\"#6b7280\" paddingX={1} flexDirection=\"column\">\n <Box justifyContent=\"space-between\">\n <Logo />\n <Box paddingX={1}>\n <Text dimColor>{clock}</Text>\n </Box>\n </Box>\n <Box paddingX={1}>\n <Text color=\"#fbbf24\">⟳ Connecting to \"{name}\"...</Text>\n </Box>\n </Box>\n );\n }\n\n const isRunning = state.status === \"running\";\n\n return (\n <Box\n borderStyle=\"round\"\n borderColor={isRunning ? \"#6ee7b7\" : \"#f87171\"}\n paddingX={0}\n flexDirection=\"column\"\n >\n <Box justifyContent=\"space-between\">\n <Logo />\n <Box gap={2}>\n <LiveIndicator frame={frame} isRunning={isRunning} />\n <Box paddingX={1}>\n <Text dimColor>{clock}</Text>\n </Box>\n </Box>\n </Box>\n\n <Box paddingX={1} gap={1}>\n <Text dimColor>│</Text>\n <Text>\n <Text dimColor>pid</Text> <Text bold>{state.pid}</Text>\n </Text>\n <Text dimColor>·</Text>\n <Text>\n <Text dimColor>port</Text> <Text bold>:{state.port}</Text>\n </Text>\n <Text dimColor>·</Text>\n <Text>\n <Text dimColor>beats</Text>{\" \"}\n <Text bold color=\"#6ee7b7\">\n ▲{state.heartbeatCount}\n </Text>\n </Text>\n {state.lastHeartbeat && (\n <>\n <Text dimColor>·</Text>\n <Text>\n <Text dimColor>last</Text> <Text>{formatTimeAgo(state.lastHeartbeat)}</Text>\n </Text>\n </>\n )}\n <Text dimColor>·</Text>\n <Text>\n <Text dimColor>up</Text> <Text>{formatUptime(state.startedAt)}</Text>\n </Text>\n </Box>\n </Box>\n );\n}\n\nfunction BudgetPanel({\n state,\n dailyCap,\n costHistory,\n}: {\n state: SupervisorDaemonState | null;\n dailyCap: number;\n costHistory: number[];\n}) {\n if (!state) return null;\n\n const todayCost = state.todayCostUsd ?? 0;\n const totalCost = state.totalCostUsd ?? 0;\n const ratio = dailyCap > 0 ? todayCost / dailyCap : 0;\n const barWidth = 20;\n const bar = buildProgressBar(ratio, barWidth);\n const pct = Math.round(ratio * 100);\n\n const barColor = pct < 50 ? \"#4ade80\" : pct < 80 ? \"#fbbf24\" : \"#f87171\";\n\n const sparkline = buildSparkline(costHistory, 12);\n\n return (\n <Box paddingX={2} gap={2}>\n <Box gap={1}>\n <Text dimColor>budget</Text>\n <Text color={barColor}>{bar.filled}</Text>\n <Text dimColor>{bar.empty}</Text>\n <Text bold color={barColor}>\n {pct}%\n </Text>\n <Text dimColor>\n (${todayCost.toFixed(2)}/${dailyCap})\n </Text>\n </Box>\n <Text dimColor>│</Text>\n <Box gap={1}>\n <Text dimColor>total</Text>\n <Text bold>${totalCost.toFixed(2)}</Text>\n </Box>\n <Text dimColor>│</Text>\n <Box gap={1}>\n <Text dimColor>cost/beat</Text>\n <Text color=\"#818cf8\">{sparkline}</Text>\n </Box>\n </Box>\n );\n}\n\nfunction ActivityRow({\n entry,\n isLatest,\n isOld,\n}: {\n entry: ActivityEntry;\n isLatest: boolean;\n isOld: boolean;\n}) {\n const icon = TYPE_ICONS[entry.type] ?? \"·\";\n const color = TYPE_COLORS[entry.type] ?? \"#9ca3af\";\n const label = (TYPE_LABELS[entry.type] ?? (entry.type as string).toUpperCase()).padEnd(7);\n\n return (\n <Box gap={1} paddingX={2}>\n <Text dimColor={isOld}>{isLatest ? \"│\" : \"│\"}</Text>\n <Text dimColor={isOld}>{formatTime(entry.timestamp)}</Text>\n <Text color={color} dimColor={isOld} bold={isLatest}>\n {icon}\n </Text>\n <Text color={color} dimColor={isOld} bold>\n {label}\n </Text>\n <Text dimColor={isOld} bold={isLatest}>\n {entry.summary}\n </Text>\n </Box>\n );\n}\n\nconst TASK_STATUS_COLORS: Record<string, string> = {\n in_progress: \"#60a5fa\",\n blocked: \"#f87171\",\n pending: \"#6b7280\",\n done: \"#4ade80\",\n};\n\nconst TASK_STATUS_LABELS: Record<string, string> = {\n in_progress: \"ACTIVE\",\n blocked: \"BLOCK\",\n pending: \"·\",\n};\n\nfunction TaskPanel({ tasks }: { tasks: MemoryEntry[] }) {\n const active = tasks.filter((t) => t.outcome !== \"done\" && t.outcome !== \"abandoned\");\n const doneCount = tasks.filter((t) => t.outcome === \"done\").length;\n\n if (tasks.length === 0) return null;\n\n const MAX_VISIBLE = 6;\n const visible = active.slice(0, MAX_VISIBLE);\n const overflow = active.length - visible.length;\n\n return (\n <Box flexDirection=\"column\">\n <Box paddingX={2} gap={1}>\n <Text dimColor>├</Text>\n <Text dimColor bold>\n TASKS\n </Text>\n <Text dimColor>\n ({active.length} active, {doneCount} done)\n </Text>\n <Text dimColor>{\"─\".repeat(30)}</Text>\n </Box>\n {visible.map((t) => {\n const status = t.outcome ?? \"pending\";\n const color = TASK_STATUS_COLORS[status] ?? \"#6b7280\";\n const label = (TASK_STATUS_LABELS[status] ?? \"·\").padEnd(6);\n const prio = t.severity ? `[${t.severity.slice(0, 3)}] ` : \"\";\n const repo = t.scope !== \"global\" ? path.basename(t.scope) : \"\";\n const run = t.runId ? `run:${t.runId.slice(0, 4)}` : \"\";\n const meta = [repo, run].filter(Boolean).join(\" \");\n\n return (\n <Box key={t.id} gap={1} paddingX={2}>\n <Text dimColor>│</Text>\n <Text color={color} bold>\n {label}\n </Text>\n {prio && <Text dimColor>{prio.padEnd(5)}</Text>}\n <Text wrap=\"truncate\">{t.content}</Text>\n {meta && <Text dimColor>({meta})</Text>}\n </Box>\n );\n })}\n {overflow > 0 && (\n <Box paddingX={2}>\n <Text dimColor>│ ... +{overflow} more pending</Text>\n </Box>\n )}\n </Box>\n );\n}\n\n/** Compact banner shown above activity when decisions exist but input is focused on chat */\nfunction DecisionBanner({ decisions, frame }: { decisions: Decision[]; frame: number }) {\n if (decisions.length === 0) return null;\n\n const pulseChars = [\"★\", \"☆\"];\n const pulse = pulseChars[frame % pulseChars.length];\n\n return (\n <Box paddingX={2} gap={1}>\n <Text dimColor>├</Text>\n <Text color=\"#fbbf24\" bold>\n {pulse} {decisions.length} decision{decisions.length > 1 ? \"s\" : \"\"} pending\n </Text>\n <Text dimColor>\n — press <Text bold>tab</Text> to review\n </Text>\n </Box>\n );\n}\n\n/** Full decision input panel — replaces the chat input when focused */\nfunction DecisionInputPanel({\n decision,\n optionIndex,\n isTextMode,\n textInput,\n onTextChange,\n onSubmit,\n decisionCount,\n decisionIdx,\n frame,\n}: {\n decision: Decision;\n optionIndex: number;\n isTextMode: boolean;\n textInput: string;\n onTextChange: (v: string) => void;\n onSubmit: (v: string) => void;\n decisionCount: number;\n decisionIdx: number;\n frame: number;\n}) {\n const hasOptions = decision.options && decision.options.length > 0;\n const pulseChars = [\"★\", \"☆\"];\n const pulse = pulseChars[frame % pulseChars.length];\n\n return (\n <Box flexDirection=\"column\">\n {/* Header */}\n <Box paddingX={2} gap={1}>\n <Text dimColor>├</Text>\n <Text color=\"#fbbf24\" bold>\n {pulse} DECISION\n </Text>\n {decisionCount > 1 && (\n <Text color=\"#fbbf24\">\n ({decisionIdx + 1}/{decisionCount})\n </Text>\n )}\n <Text dimColor>{\"─\".repeat(30)}</Text>\n </Box>\n\n {/* Question */}\n <Box paddingX={2} gap={1}>\n <Text dimColor>│</Text>\n <Text bold wrap=\"truncate-end\">\n {decision.question}\n </Text>\n </Box>\n\n {/* Context if available */}\n {decision.context && (\n <Box paddingX={2} gap={1}>\n <Text dimColor>│</Text>\n <Text dimColor wrap=\"truncate-end\">\n {decision.context}\n </Text>\n </Box>\n )}\n\n {/* Option selector or free text */}\n {hasOptions ? (\n <Box flexDirection=\"column\">\n {(decision.options ?? []).map((opt, idx) => {\n const isSelected = idx === optionIndex;\n return (\n <Box key={opt.key} paddingX={2} gap={1}>\n <Text dimColor>│</Text>\n {isSelected ? (\n <Text color=\"#fbbf24\" bold>\n ▸ {opt.label}\n </Text>\n ) : (\n <Text dimColor>\n {\" \"}\n {opt.label}\n </Text>\n )}\n {opt.description && isSelected && <Text dimColor>— {opt.description}</Text>}\n </Box>\n );\n })}\n </Box>\n ) : (\n <Box paddingX={2} gap={1}>\n <Text dimColor>│</Text>\n <Text color=\"#fbbf24\" bold>\n ❯\n </Text>\n <TextInput\n value={textInput}\n onChange={onTextChange}\n onSubmit={onSubmit}\n focus={isTextMode}\n placeholder=\"type your answer...\"\n />\n </Box>\n )}\n\n {/* Footer hints */}\n <Box paddingX={2} gap={1}>\n <Text dimColor>└</Text>\n <Text dimColor>\n {hasOptions ? (\n <>\n <Text bold>↑↓</Text> choose · <Text bold>enter</Text> confirm\n </>\n ) : (\n <>\n <Text bold>enter</Text> send\n </>\n )}\n {decisionCount > 1 && (\n <>\n {\" · \"}\n <Text bold>←→</Text> prev/next\n </>\n )}\n {\" · \"}\n <Text bold>tab</Text> chat · <Text bold>esc</Text> back\n </Text>\n </Box>\n </Box>\n );\n}\n\n/** Types shown in the activity feed — plan/thinking are internal, not shown */\nconst ACTIVITY_TYPES = new Set([\n \"heartbeat\",\n \"decision\",\n \"action\",\n \"dispatch\",\n \"error\",\n \"event\",\n \"message\",\n]);\n\nfunction ActivityPanel({ entries, termHeight }: { entries: ActivityEntry[]; termHeight: number }) {\n // Reserve lines for header (5), budget (1), separator (1), input (2), footer (1) = 10\n const maxVisible = Math.max(5, Math.min(MAX_VISIBLE_ENTRIES, termHeight - 10));\n const filtered = entries.filter((e) => ACTIVITY_TYPES.has(e.type));\n const visible = filtered.slice(-maxVisible);\n\n return (\n <Box flexDirection=\"column\">\n <Box paddingX={2} gap={1}>\n <Text dimColor>├</Text>\n <Text dimColor bold>\n ACTIVITY\n </Text>\n <Text dimColor>{\"─\".repeat(40)}</Text>\n </Box>\n\n {visible.length === 0 ? (\n <Box paddingX={2}>\n <Text dimColor>│ Waiting for heartbeats...</Text>\n </Box>\n ) : (\n visible.map((entry, idx) => (\n <ActivityRow\n key={entry.id}\n entry={entry}\n isLatest={idx === visible.length - 1}\n isOld={idx < visible.length - 5}\n />\n ))\n )}\n\n <Box paddingX={2}>\n <Text dimColor>│</Text>\n </Box>\n </Box>\n );\n}\n\nfunction InputPanel({\n value,\n onChange,\n onSubmit,\n lastSent,\n focus,\n}: {\n value: string;\n onChange: (v: string) => void;\n onSubmit: (v: string) => void;\n lastSent: string;\n focus: boolean;\n}) {\n return (\n <Box flexDirection=\"column\">\n <Box paddingX={2} gap={1}>\n <Text dimColor>└</Text>\n <Text bold color=\"#60a5fa\">\n ❯\n </Text>\n <TextInput\n value={value}\n onChange={onChange}\n onSubmit={onSubmit}\n focus={focus}\n placeholder=\"message the supervisor...\"\n />\n </Box>\n <Box paddingX={2} gap={1}>\n <Text dimColor> </Text>\n {lastSent ? <Text color=\"#6b7280\">✓ \"{lastSent}\"</Text> : null}\n </Box>\n </Box>\n );\n}\n\nfunction Footer({ hasDecisions }: { hasDecisions: boolean }) {\n return (\n <Box paddingX={2} gap={1} justifyContent=\"center\">\n <Text dimColor>\n <Text bold>esc</Text> quit\n </Text>\n <Text dimColor>·</Text>\n <Text dimColor>\n <Text bold>enter</Text> send\n </Text>\n {hasDecisions && (\n <>\n <Text dimColor>·</Text>\n <Text dimColor>\n <Text bold>tab</Text> decisions\n </Text>\n </>\n )}\n <Text dimColor>·</Text>\n <Text dimColor>daemon keeps running</Text>\n </Box>\n );\n}\n\n// ─── Data Fetching ───────────────────────────────────────\n\nasync function readState(name: string): Promise<SupervisorDaemonState | null> {\n try {\n const raw = await readFile(getSupervisorStatePath(name), \"utf-8\");\n return JSON.parse(raw) as SupervisorDaemonState;\n } catch {\n return null;\n }\n}\n\nasync function readActivity(name: string, maxEntries: number): Promise<ActivityEntry[]> {\n try {\n const content = await readFile(getSupervisorActivityPath(name), \"utf-8\");\n const lines = content.trim().split(\"\\n\").filter(Boolean);\n const lastLines = lines.slice(-maxEntries);\n const entries: ActivityEntry[] = [];\n for (const line of lastLines) {\n try {\n entries.push(JSON.parse(line) as ActivityEntry);\n } catch {\n // Skip malformed\n }\n }\n return entries;\n } catch {\n return [];\n }\n}\n\nfunction readTasks(name: string): MemoryEntry[] {\n try {\n const dir = getSupervisorDir(name);\n const store = new MemoryStore(path.join(dir, \"memory.sqlite\"));\n const tasks = store.query({ types: [\"task\"], limit: 20, sortBy: \"createdAt\" });\n store.close();\n return tasks;\n } catch {\n return [];\n }\n}\n\nasync function readDecisions(name: string): Promise<Decision[]> {\n try {\n const store = new DecisionStore(getSupervisorDecisionsPath(name));\n return await store.pending();\n } catch {\n return [];\n }\n}\n\n/**\n * Appends a JSON entry to a JSONL file.\n * Creates the parent directory if needed. Returns false on error.\n */\nasync function appendToJsonl(filePath: string, data: unknown): Promise<boolean> {\n const dir = path.dirname(filePath);\n try {\n await mkdir(dir, { recursive: true });\n await appendFile(filePath, `${JSON.stringify(data)}\\n`, \"utf-8\");\n return true;\n } catch (error) {\n console.error(\n `Warning: Failed to write to ${path.basename(filePath)}: ${error instanceof Error ? error.message : String(error)}`,\n );\n return false;\n }\n}\n\n/**\n * Writes a message to the supervisor's inbox.jsonl file.\n * Creates the directory if it doesn't exist and handles write errors gracefully.\n */\nasync function writeToInbox(name: string, message: InboxMessage): Promise<boolean> {\n const inboxPath = getSupervisorInboxPath(name);\n return appendToJsonl(inboxPath, message);\n}\n\nasync function answerDecision(name: string, id: string, answer: string): Promise<void> {\n const store = new DecisionStore(getSupervisorDecisionsPath(name));\n await store.answer(id, answer);\n\n // Wake up the supervisor heartbeat by appending to inbox.jsonl\n const inboxMessage: InboxMessage = {\n id: randomUUID(),\n from: \"tui\",\n text: `decision:answer ${id} ${answer}`,\n timestamp: new Date().toISOString(),\n };\n await writeToInbox(name, inboxMessage);\n}\n\nasync function sendMessage(name: string, text: string): Promise<void> {\n const id = randomUUID();\n const timestamp = new Date().toISOString();\n\n const message: InboxMessage = { id, from: \"tui\", text, timestamp };\n await writeToInbox(name, message);\n\n // Write to activity.jsonl so the message appears in the TUI conversation\n const activityEntry: ActivityEntry = { id, type: \"message\", summary: text, timestamp };\n const activityPath = getSupervisorActivityPath(name);\n await appendToJsonl(activityPath, activityEntry);\n}\n\n// ─── Main Component ──────────────────────────────────────\n\nexport function SupervisorTui({ name }: { name: string }) {\n const { exit } = useApp();\n const { stdout } = useStdout();\n const frame = useAnimationFrame();\n const clock = useClock();\n\n const [state, setState] = useState<SupervisorDaemonState | null>(null);\n const [entries, setEntries] = useState<ActivityEntry[]>([]);\n const [tasks, setTasks] = useState<MemoryEntry[]>([]);\n const [decisions, setDecisions] = useState<Decision[]>([]);\n const [dailyCap, setDailyCap] = useState(50);\n const [input, setInput] = useState(\"\");\n const [lastSent, setLastSent] = useState(\"\");\n const [termHeight, setTermHeight] = useState(stdout?.rows ?? 30);\n\n // Decision interaction state\n const [decisionIndex, setDecisionIndex] = useState(0);\n const [optionIndex, setOptionIndex] = useState(0);\n const [decisionAnswer, setDecisionAnswer] = useState(\"\");\n const [focusMode, setFocusMode] = useState<\"input\" | \"decisions\">(\"input\");\n\n // Track terminal resize\n useEffect(() => {\n function onResize() {\n if (stdout) setTermHeight(stdout.rows);\n }\n stdout?.on(\"resize\", onResize);\n return () => {\n stdout?.off(\"resize\", onResize);\n };\n }, [stdout]);\n\n // Load daily cap from config\n useEffect(() => {\n loadGlobalConfig()\n .then((cfg) => setDailyCap(cfg.supervisor.dailyCapUsd))\n .catch((err) => {\n console.debug(\"[tui] Failed to load global config:\", err);\n });\n }, []);\n\n // Poll state, activity, and decisions\n useEffect(() => {\n let active = true;\n\n async function poll() {\n if (!active) return;\n const [newState, newEntries, newDecisions] = await Promise.all([\n readState(name),\n readActivity(name, MAX_VISIBLE_ENTRIES),\n readDecisions(name),\n ]);\n if (!active) return;\n setState(newState);\n setEntries(newEntries);\n setDecisions(newDecisions);\n setTasks(readTasks(name));\n // Reset decision index if out of bounds\n if (newDecisions.length > 0 && decisionIndex >= newDecisions.length) {\n setDecisionIndex(0);\n }\n // Auto-switch to decisions mode when new decisions appear\n if (newDecisions.length > 0 && decisions.length === 0) {\n setFocusMode(\"decisions\");\n }\n // Return to input mode when all decisions are resolved\n if (newDecisions.length === 0 && decisions.length > 0) {\n setFocusMode(\"input\");\n }\n }\n\n poll();\n const interval = setInterval(poll, POLL_INTERVAL_MS);\n return () => {\n active = false;\n clearInterval(interval);\n };\n }, [name, decisionIndex, decisions.length]);\n\n // Current decision being interacted with\n const currentDecision = decisions[decisionIndex] as Decision | undefined;\n const currentHasOptions = (currentDecision?.options?.length ?? 0) > 0;\n\n // Submit the selected option or free-text answer\n const submitDecisionAnswer = useCallback(\n async (answer: string) => {\n if (!answer.trim() || !currentDecision) return;\n try {\n await answerDecision(name, currentDecision.id, answer.trim());\n setLastSent(`Decision ${currentDecision.id.slice(4, 12)}: \"${answer.trim()}\"`);\n setDecisionAnswer(\"\");\n setOptionIndex(0);\n } catch {\n // Decision may have been answered already\n }\n },\n [name, currentDecision],\n );\n\n const handleOptionNav = useCallback(\n (key: { upArrow: boolean; downArrow: boolean; return: boolean }): boolean => {\n const options = currentDecision?.options;\n if (!options || options.length === 0) return false;\n\n if (key.upArrow) {\n setOptionIndex((i) => Math.max(0, i - 1));\n return true;\n }\n if (key.downArrow) {\n setOptionIndex((i) => Math.min(options.length - 1, i + 1));\n return true;\n }\n if (key.return) {\n const opt = options[optionIndex];\n if (opt) submitDecisionAnswer(opt.key);\n return true;\n }\n return false;\n },\n [currentDecision, optionIndex, submitDecisionAnswer],\n );\n\n useInput((_char, key) => {\n if (key.tab && decisions.length > 0) {\n setFocusMode((m) => (m === \"input\" ? \"decisions\" : \"input\"));\n setOptionIndex(0);\n return;\n }\n\n if (key.escape) {\n if (focusMode === \"decisions\") {\n setFocusMode(\"input\");\n } else {\n exit();\n }\n return;\n }\n\n if (focusMode !== \"decisions\" || decisions.length === 0) return;\n\n if (currentHasOptions && handleOptionNav(key)) return;\n\n // ←→ to switch between decisions when multiple\n if (decisions.length > 1) {\n if (key.leftArrow) {\n setDecisionIndex((i) => Math.max(0, i - 1));\n setOptionIndex(0);\n } else if (key.rightArrow) {\n setDecisionIndex((i) => Math.min(decisions.length - 1, i + 1));\n setOptionIndex(0);\n }\n }\n });\n\n const handleSubmit = useCallback(\n (text: string) => {\n if (!text.trim()) return;\n sendMessage(name, text.trim());\n setLastSent(text.trim());\n setInput(\"\");\n },\n [name],\n );\n\n const costHistory = extractCostHistory(entries);\n\n // Calculate height adjustments for panels\n const activeTaskCount = tasks.filter(\n (t) => t.outcome !== \"done\" && t.outcome !== \"abandoned\",\n ).length;\n const taskPanelLines = tasks.length > 0 ? Math.min(activeTaskCount, 6) + 2 : 0;\n const decisionPanelLines =\n focusMode === \"decisions\" && currentDecision\n ? (currentHasOptions ? (currentDecision.options?.length ?? 0) : 1) + 4\n : decisions.length > 0\n ? 1\n : 0;\n\n // Bottom panel: either decision input or chat input\n const bottomPanel =\n focusMode === \"decisions\" && currentDecision ? (\n <DecisionInputPanel\n decision={currentDecision}\n optionIndex={optionIndex}\n isTextMode={!currentHasOptions}\n textInput={decisionAnswer}\n onTextChange={setDecisionAnswer}\n onSubmit={submitDecisionAnswer}\n decisionCount={decisions.length}\n decisionIdx={decisionIndex}\n frame={frame}\n />\n ) : (\n <>\n <InputPanel\n value={input}\n onChange={setInput}\n onSubmit={handleSubmit}\n lastSent={lastSent}\n focus={focusMode === \"input\"}\n />\n <Footer hasDecisions={decisions.length > 0} />\n </>\n );\n\n return (\n <Box flexDirection=\"column\">\n <HeaderBar state={state} name={name} frame={frame} clock={clock} />\n <BudgetPanel state={state} dailyCap={dailyCap} costHistory={costHistory} />\n {focusMode !== \"decisions\" && <DecisionBanner decisions={decisions} frame={frame} />}\n <TaskPanel tasks={tasks} />\n <ActivityPanel\n entries={entries}\n termHeight={termHeight - taskPanelLines - decisionPanelLines}\n />\n {bottomPanel}\n </Box>\n );\n}\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neotx/cli",
3
- "version": "0.1.0-alpha.20",
3
+ "version": "0.1.0-alpha.21",
4
4
  "description": "CLI for the Neo orchestration framework",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -51,8 +51,8 @@
51
51
  "ink-text-input": "^6.0.0",
52
52
  "react": "^19.2.4",
53
53
  "yaml": "^2.8.2",
54
- "@neotx/agents": "0.1.0-alpha.20",
55
- "@neotx/core": "0.1.0-alpha.20"
54
+ "@neotx/agents": "0.1.0-alpha.21",
55
+ "@neotx/core": "0.1.0-alpha.21"
56
56
  },
57
57
  "devDependencies": {
58
58
  "@anthropic-ai/claude-agent-sdk": "^0.1.0",