@neotx/cli 0.1.0-alpha.22 → 0.1.0-alpha.25
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/child-5X5IHAKS.js +92 -0
- package/dist/child-5X5IHAKS.js.map +1 -0
- package/dist/child-mode-IB3XSUHD.js +8 -0
- package/dist/child-mode-IB3XSUHD.js.map +1 -0
- package/dist/chunk-4TQ3Q6IE.js +43 -0
- package/dist/chunk-4TQ3Q6IE.js.map +1 -0
- package/dist/chunk-6PSXZ3UV.js +46 -0
- package/dist/chunk-6PSXZ3UV.js.map +1 -0
- package/dist/chunk-V5SN5F73.js +54 -0
- package/dist/chunk-V5SN5F73.js.map +1 -0
- package/dist/daemon/child-supervisor-worker.js +136 -0
- package/dist/daemon/child-supervisor-worker.js.map +1 -0
- package/dist/daemon/supervisor-worker.js +9 -1
- package/dist/daemon/supervisor-worker.js.map +1 -1
- package/dist/daemon/worker.js +16 -3
- package/dist/daemon/worker.js.map +1 -1
- package/dist/{decision-PNZ2S2TU.js → decision-T2526ITK.js} +35 -2
- package/dist/decision-T2526ITK.js.map +1 -0
- package/dist/directive-7WM2Q2UW.js +259 -0
- package/dist/directive-7WM2Q2UW.js.map +1 -0
- package/dist/do-F5XW2ELZ.js +83 -0
- package/dist/do-F5XW2ELZ.js.map +1 -0
- package/dist/health-SWQ6V4H5.js +72 -0
- package/dist/health-SWQ6V4H5.js.map +1 -0
- package/dist/index.js +10 -6
- package/dist/index.js.map +1 -1
- package/dist/{log-PTHLI7ZN.js → log-ZLIAIBZQ.js} +64 -9
- package/dist/log-ZLIAIBZQ.js.map +1 -0
- package/dist/{memory-SDZ57W2S.js → memory-CW6E65SQ.js} +112 -62
- package/dist/memory-CW6E65SQ.js.map +1 -0
- package/dist/{run-MWHIQUSY.js → run-NV762V5B.js} +56 -22
- package/dist/run-NV762V5B.js.map +1 -0
- package/dist/{supervise-XMZRNODO.js → supervise-BWIKWNHH.js} +68 -41
- package/dist/supervise-BWIKWNHH.js.map +1 -0
- package/dist/{supervisor-3RUX5SPH.js → supervisor-N4D5EWCC.js} +1 -1
- package/dist/tui-LSW7VVK6.js +1319 -0
- package/dist/tui-LSW7VVK6.js.map +1 -0
- package/package.json +4 -4
- package/dist/decision-PNZ2S2TU.js.map +0 -1
- package/dist/log-PTHLI7ZN.js.map +0 -1
- package/dist/memory-SDZ57W2S.js.map +0 -1
- package/dist/run-MWHIQUSY.js.map +0 -1
- package/dist/supervise-XMZRNODO.js.map +0 -1
- package/dist/tui-67VJ5VBA.js +0 -842
- package/dist/tui-67VJ5VBA.js.map +0 -1
- /package/dist/{supervisor-3RUX5SPH.js.map → supervisor-N4D5EWCC.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/tui/index.ts","../src/tui/supervisor-tui.tsx","../src/tui/components/child-detail.tsx","../src/tui/components/child-input.tsx","../src/tui/components/child-list.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 ChildHandle,\n Decision,\n InboxMessage,\n SupervisorDaemonState,\n TaskEntry,\n} from \"@neotx/core\";\nimport {\n DecisionStore,\n getFocusedSupervisorDir,\n getSupervisorActivityPath,\n getSupervisorChildrenPath,\n getSupervisorDecisionsPath,\n getSupervisorDir,\n getSupervisorInboxPath,\n getSupervisorStatePath,\n loadGlobalConfig,\n readChildrenFile,\n TaskStore,\n} from \"@neotx/core\";\nimport { Box, Text, useApp, useInput, useStdout } from \"ink\";\nimport TextInput from \"ink-text-input\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport { ChildDetail } from \"./components/child-detail.js\";\nimport type { ChildInputMode } from \"./components/child-input.js\";\nimport { ChildInput } from \"./components/child-input.js\";\nimport { ChildList } from \"./components/child-list.js\";\n\n// ─── Constants ───────────────────────────────────────────\n\nconst MAX_VISIBLE_ENTRIES = 24;\nconst MAX_CHILD_ACTIVITY = 12;\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 columnFocus,\n childCount,\n}: {\n state: SupervisorDaemonState | null;\n name: string;\n frame: number;\n clock: string;\n columnFocus: \"left\" | \"right\";\n childCount: number;\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 {childCount > 0 && (\n <Box paddingX={1} gap={1}>\n <Text dimColor>focus:</Text>\n <Text color=\"#c084fc\" bold>\n {columnFocus === \"left\" ? \"ROOT\" : \"CHILDREN\"}\n </Text>\n <Text dimColor>(tab to switch)</Text>\n </Box>\n )}\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: TaskEntry[] }) {\n const active = tasks.filter((t) => t.status !== \"done\" && t.status !== \"abandoned\");\n const doneCount = tasks.filter((t) => t.status === \"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.status ?? \"pending\";\n const color = TASK_STATUS_COLORS[status] ?? \"#6b7280\";\n const label = (TASK_STATUS_LABELS[status] ?? \"·\").padEnd(6);\n const prio = t.priority ? `[${t.priority.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.title}</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, maxVisible }: { entries: ActivityEntry[]; maxVisible: number }) {\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\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 (err) {\n console.debug(\n `[tui] Failed to read supervisor state for ${name}: ${err instanceof Error ? err.message : String(err)}`,\n );\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 (err) {\n console.debug(\n `[tui] Skipping malformed activity line: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n return entries;\n } catch (err) {\n console.debug(\n `[tui] Failed to read activity for ${name}: ${err instanceof Error ? err.message : String(err)}`,\n );\n return [];\n }\n}\n\nasync function readChildActivity(\n supervisorId: string,\n maxEntries: number,\n): Promise<ActivityEntry[]> {\n const activityPath = path.join(getFocusedSupervisorDir(supervisorId), \"activity.jsonl\");\n try {\n const content = await readFile(activityPath, \"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 line */\n }\n }\n return entries;\n } catch {\n return [];\n }\n}\n\nfunction readTasks(name: string): TaskEntry[] {\n try {\n const dir = getSupervisorDir(name);\n const store = new TaskStore(path.join(dir, \"tasks.sqlite\"));\n const tasks = store.getTasks();\n store.close();\n return tasks.slice(0, 20);\n } catch (err) {\n console.debug(\n `[tui] Failed to read tasks for ${name}: ${err instanceof Error ? err.message : String(err)}`,\n );\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 (err) {\n console.debug(\n `[tui] Failed to read decisions for ${name}: ${err instanceof Error ? err.message : String(err)}`,\n );\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 */\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 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 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\n// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: Main TUI component with complex keyboard/state interactions; splitting would fragment cohesive UI logic\nexport function SupervisorTui({ name }: { name: string }) {\n const { exit } = useApp();\n const { stdout } = useStdout();\n const frame = useAnimationFrame();\n const clock = useClock();\n\n // Root supervisor state\n const [state, setState] = useState<SupervisorDaemonState | null>(null);\n const [entries, setEntries] = useState<ActivityEntry[]>([]);\n const [tasks, setTasks] = useState<TaskEntry[]>([]);\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 // Child supervisor state\n const [children, setChildren] = useState<ChildHandle[]>([]);\n const [selectedChildIndex, setSelectedChildIndex] = useState(0);\n const [childActivity, setChildActivity] = useState<ActivityEntry[]>([]);\n const [columnFocus, setColumnFocus] = useState<\"left\" | \"right\">(\"left\");\n const [childInputMode, setChildInputMode] = useState<ChildInputMode>(\"idle\");\n const [childInputValue, setChildInputValue] = useState(\"\");\n\n const hasChildren = children.length > 0;\n const selectedChild = children[selectedChildIndex] as ChildHandle | undefined;\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 // Refs to avoid stale closures inside poll without restarting the timer\n const decisionIndexRef = useRef(decisionIndex);\n const decisionsLengthRef = useRef(decisions.length);\n useEffect(() => {\n decisionIndexRef.current = decisionIndex;\n }, [decisionIndex]);\n useEffect(() => {\n decisionsLengthRef.current = decisions.length;\n }, [decisions.length]);\n\n // Poll root state, activity, decisions, and children\n useEffect(() => {\n let active = true;\n\n async function poll() {\n if (!active) return;\n const [newState, newEntries, newDecisions, newChildren] = await Promise.all([\n readState(name),\n readActivity(name, MAX_VISIBLE_ENTRIES),\n readDecisions(name),\n readChildrenFile(getSupervisorChildrenPath(name)).catch((err) => {\n // File not found is expected when no children exist - only log real errors\n if ((err as NodeJS.ErrnoException).code !== \"ENOENT\") {\n console.debug(`[TUI] readChildrenFile failed: ${err}`);\n }\n return [] as ChildHandle[];\n }),\n ]);\n if (!active) return;\n setState(newState);\n setEntries(newEntries);\n setDecisions(newDecisions);\n // Clamp selectedChildIndex if children list shrinks\n setSelectedChildIndex((i) => Math.min(i, Math.max(0, newChildren.length - 1)));\n setChildren(newChildren);\n setTasks(readTasks(name));\n // Reset decision index if out of bounds (using ref to avoid dep)\n if (newDecisions.length > 0 && decisionIndexRef.current >= newDecisions.length) {\n setDecisionIndex(0);\n }\n // Auto-switch to decisions mode when new decisions appear\n if (newDecisions.length > 0 && decisionsLengthRef.current === 0) {\n setFocusMode(\"decisions\");\n }\n // Return to input mode when all decisions are resolved\n if (newDecisions.length === 0 && decisionsLengthRef.current > 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]);\n\n // Poll child activity when selected child id changes\n const selectedChildId = selectedChild?.supervisorId;\n useEffect(() => {\n if (!selectedChildId) {\n setChildActivity([]);\n return;\n }\n\n // Capture after guard - TypeScript doesn't narrow inside async closures\n const childId = selectedChildId;\n let active = true;\n\n async function poll() {\n if (!active) return;\n const activity = await readChildActivity(childId, MAX_CHILD_ACTIVITY);\n if (!active) return;\n setChildActivity(activity);\n }\n\n poll();\n const interval = setInterval(poll, POLL_INTERVAL_MS);\n return () => {\n active = false;\n clearInterval(interval);\n };\n }, [selectedChildId]);\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 (err) {\n console.debug(\n `[tui] Failed to answer decision ${currentDecision.id}: ${err instanceof Error ? err.message : String(err)}`,\n );\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 const handleChildInputSubmit = useCallback(\n async (value: string) => {\n if (!selectedChild) return;\n const id = selectedChild.supervisorId;\n let text: string | null = null;\n if (childInputMode === \"inject\" && value.trim()) {\n text = `child:inject ${id} ${value.trim()}`;\n } else if (childInputMode === \"unblock\" && value.trim()) {\n text = `child:unblock ${id} ${value.trim()}`;\n } else if (childInputMode === \"kill\" && value.trim().toLowerCase() === \"stop\") {\n text = `child:stop ${id}`;\n }\n if (text) {\n const message: InboxMessage = {\n id: randomUUID(),\n from: \"tui\",\n text,\n timestamp: new Date().toISOString(),\n };\n await writeToInbox(name, message);\n setLastSent(text.slice(0, 40));\n }\n setChildInputMode(\"idle\");\n setChildInputValue(\"\");\n },\n [name, selectedChild, childInputMode],\n );\n\n const handleRightColumnKey = useCallback(\n (char: string, key: { upArrow: boolean; downArrow: boolean }) => {\n if (key.upArrow) {\n setSelectedChildIndex((i) => Math.max(0, i - 1));\n return;\n }\n if (key.downArrow) {\n if (children.length > 0) {\n setSelectedChildIndex((i) => Math.min(children.length - 1, i + 1));\n }\n return;\n }\n if (char === \"i\") {\n setChildInputMode(\"inject\");\n return;\n }\n if (char === \"u\" && selectedChild?.status === \"blocked\") {\n setChildInputMode(\"unblock\");\n return;\n }\n if (char === \"k\") {\n setChildInputMode(\"kill\");\n }\n },\n [children.length, selectedChild],\n );\n\n const handleDecisionKey = useCallback(\n (key: {\n upArrow: boolean;\n downArrow: boolean;\n return: boolean;\n leftArrow: boolean;\n rightArrow: boolean;\n }) => {\n if (currentHasOptions && handleOptionNav(key)) return;\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 [currentHasOptions, handleOptionNav, decisions.length],\n );\n\n // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: Keyboard input handler with extensive keybinding logic; single handler maintains key priority/fallthrough clarity\n useInput((char, key) => {\n if (key.tab) {\n if (hasChildren && focusMode !== \"decisions\") {\n setColumnFocus((c) => (c === \"left\" ? \"right\" : \"left\"));\n setOptionIndex(0);\n } else if (decisions.length > 0) {\n setFocusMode((m) => (m === \"input\" ? \"decisions\" : \"input\"));\n setOptionIndex(0);\n }\n return;\n }\n\n if (key.escape) {\n if (childInputMode !== \"idle\") {\n setChildInputMode(\"idle\");\n setChildInputValue(\"\");\n } else if (columnFocus === \"right\") {\n setColumnFocus(\"left\");\n } else if (focusMode === \"decisions\") {\n setFocusMode(\"input\");\n } else {\n exit();\n }\n return;\n }\n\n if (columnFocus === \"right\" && childInputMode === \"idle\") {\n handleRightColumnKey(char, key);\n return;\n }\n\n if (focusMode === \"decisions\" && decisions.length > 0 && columnFocus === \"left\") {\n handleDecisionKey(key);\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 left column panels\n const activeTaskCount = tasks.filter(\n (t) => t.status !== \"done\" && t.status !== \"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 const leftActivityMaxVisible = Math.max(\n 5,\n Math.min(MAX_VISIBLE_ENTRIES, termHeight - 10 - taskPanelLines - decisionPanelLines),\n );\n\n // Bottom panel: either decision input or chat input\n const bottomPanel =\n focusMode === \"decisions\" && currentDecision && columnFocus === \"left\" ? (\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 <InputPanel\n value={input}\n onChange={setInput}\n onSubmit={handleSubmit}\n lastSent={lastSent}\n focus={columnFocus === \"left\" && focusMode === \"input\"}\n />\n );\n\n return (\n <Box flexDirection=\"column\">\n <HeaderBar\n state={state}\n name={name}\n frame={frame}\n clock={clock}\n columnFocus={columnFocus}\n childCount={children.length}\n />\n <BudgetPanel state={state} dailyCap={dailyCap} costHistory={costHistory} />\n <Box flexDirection=\"row\" flexGrow={1}>\n {/* Left column */}\n <Box\n flexDirection=\"column\"\n flexGrow={1}\n flexBasis={hasChildren ? \"50%\" : \"100%\"}\n borderStyle={hasChildren && columnFocus === \"left\" ? \"single\" : undefined}\n borderColor=\"#c084fc\"\n >\n {focusMode !== \"decisions\" && <DecisionBanner decisions={decisions} frame={frame} />}\n <TaskPanel tasks={tasks} />\n <ActivityPanel entries={entries} maxVisible={leftActivityMaxVisible} />\n {bottomPanel}\n </Box>\n\n {/* Right column — only when children exist */}\n {hasChildren && (\n <Box\n flexDirection=\"column\"\n flexGrow={1}\n flexBasis=\"50%\"\n borderStyle={columnFocus === \"right\" ? \"single\" : undefined}\n borderColor=\"#c084fc\"\n >\n <ChildList handles={children} selectedIndex={selectedChildIndex} />\n {selectedChild && (\n <>\n <ChildDetail\n handle={selectedChild}\n activity={childActivity}\n maxActivityLines={MAX_CHILD_ACTIVITY}\n />\n <ChildInput\n handle={selectedChild}\n mode={childInputMode}\n value={childInputValue}\n onChange={setChildInputValue}\n onSubmit={handleChildInputSubmit}\n />\n </>\n )}\n </Box>\n )}\n </Box>\n\n {/* Footer */}\n <Box paddingX={2} gap={1} justifyContent=\"center\">\n <Text dimColor>\n <Text bold>esc</Text> quit\n </Text>\n {hasChildren && (\n <>\n <Text dimColor>·</Text>\n <Text dimColor>\n <Text bold>tab</Text> switch panel\n </Text>\n </>\n )}\n <Text dimColor>·</Text>\n <Text dimColor>daemon keeps running</Text>\n </Box>\n </Box>\n );\n}\n","import type { ActivityEntry, ChildHandle } from \"@neotx/core\";\nimport { Box, Text } from \"ink\";\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\nfunction formatTime(timestamp: string): string {\n return timestamp.slice(11, 19);\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\nconst STATUS_COLORS: Record<string, string> = {\n running: \"#4ade80\",\n blocked: \"#fbbf24\",\n stalled: \"#f97316\",\n complete: \"#818cf8\",\n failed: \"#f87171\",\n};\n\nexport function ChildDetail({\n handle,\n activity,\n maxActivityLines,\n}: {\n handle: ChildHandle;\n activity: ActivityEntry[];\n maxActivityLines: number;\n}) {\n const statusColor = STATUS_COLORS[handle.status] ?? \"#9ca3af\";\n const visible = activity.slice(-maxActivityLines);\n\n return (\n <Box flexDirection=\"column\">\n {/* Header */}\n <Box paddingX={1} gap={1}>\n <Text dimColor>├</Text>\n <Text color=\"#c084fc\" bold>\n {handle.supervisorId}\n </Text>\n <Text dimColor>·</Text>\n <Text color={statusColor} bold>\n {handle.status.toUpperCase()}\n </Text>\n <Text dimColor>·</Text>\n <Text dimColor>${handle.costUsd.toFixed(2)}</Text>\n {handle.lastProgressAt && (\n <>\n <Text dimColor>·</Text>\n <Text dimColor>{formatTimeAgo(handle.lastProgressAt)}</Text>\n </>\n )}\n </Box>\n\n {/* Objective */}\n <Box paddingX={1} gap={1}>\n <Text dimColor>│</Text>\n <Text dimColor>obj:</Text>\n <Text wrap=\"truncate\">{handle.objective}</Text>\n </Box>\n\n {/* Activity divider */}\n <Box paddingX={1} gap={1}>\n <Text dimColor>├</Text>\n <Text dimColor bold>\n ACTIVITY\n </Text>\n <Text dimColor>{\"─\".repeat(15)}</Text>\n </Box>\n\n {/* Activity entries */}\n {visible.length === 0 ? (\n <Box paddingX={1}>\n <Text dimColor>│ No activity yet...</Text>\n </Box>\n ) : (\n visible.map((entry, idx) => {\n const icon = TYPE_ICONS[entry.type] ?? \"·\";\n const color = TYPE_COLORS[entry.type] ?? \"#9ca3af\";\n const isLatest = idx === visible.length - 1;\n const isOld = idx < visible.length - 4;\n return (\n <Box key={entry.id} gap={1} paddingX={1}>\n <Text dimColor={isOld}>{formatTime(entry.timestamp)}</Text>\n <Text color={color} dimColor={isOld} bold={isLatest}>\n {icon}\n </Text>\n <Text dimColor={isOld} bold={isLatest} wrap=\"truncate\">\n {entry.summary}\n </Text>\n </Box>\n );\n })\n )}\n </Box>\n );\n}\n","import type { ChildHandle } from \"@neotx/core\";\nimport { Box, Text } from \"ink\";\nimport TextInput from \"ink-text-input\";\n\nexport type ChildInputMode = \"idle\" | \"inject\" | \"unblock\" | \"kill\";\n\nexport function ChildInput({\n handle,\n mode,\n value,\n onChange,\n onSubmit,\n}: {\n handle: ChildHandle;\n mode: ChildInputMode;\n value: string;\n onChange: (v: string) => void;\n onSubmit: (v: string) => void;\n}) {\n const isBlocked = handle.status === \"blocked\";\n\n if (mode === \"idle\") {\n return (\n <Box paddingX={1} gap={2} flexDirection=\"column\">\n <Box paddingX={1} gap={1}>\n <Text dimColor>└</Text>\n <Text dimColor>\n <Text bold>i</Text> inject context\n </Text>\n <Text dimColor>·</Text>\n <Text dimColor={!isBlocked}>\n <Text bold={isBlocked}>u</Text> unblock{!isBlocked ? \" (not blocked)\" : \"\"}\n </Text>\n <Text dimColor>·</Text>\n <Text dimColor>\n <Text bold color=\"#f87171\">\n k\n </Text>{\" \"}\n kill\n </Text>\n <Text dimColor>·</Text>\n <Text dimColor>\n <Text bold>esc</Text> back\n </Text>\n </Box>\n </Box>\n );\n }\n\n if (mode === \"inject\") {\n return (\n <Box flexDirection=\"column\">\n <Box paddingX={1} gap={1}>\n <Text dimColor>└</Text>\n <Text color=\"#60a5fa\" bold>\n INJECT\n </Text>\n <Text dimColor>→ {handle.supervisorId}</Text>\n </Box>\n <Box paddingX={1} gap={1}>\n <Text dimColor> </Text>\n <Text color=\"#60a5fa\" bold>\n ❯\n </Text>\n <TextInput\n value={value}\n onChange={onChange}\n onSubmit={onSubmit}\n focus\n placeholder=\"context to inject...\"\n />\n </Box>\n <Box paddingX={1}>\n <Text dimColor> enter send · esc cancel</Text>\n </Box>\n </Box>\n );\n }\n\n if (mode === \"unblock\") {\n return (\n <Box flexDirection=\"column\">\n <Box paddingX={1} gap={1}>\n <Text dimColor>└</Text>\n <Text color=\"#fbbf24\" bold>\n UNBLOCK\n </Text>\n <Text dimColor>→ {handle.supervisorId}</Text>\n </Box>\n <Box paddingX={1} gap={1}>\n <Text dimColor> </Text>\n <Text color=\"#fbbf24\" bold>\n ❯\n </Text>\n <TextInput\n value={value}\n onChange={onChange}\n onSubmit={onSubmit}\n focus\n placeholder=\"your answer...\"\n />\n </Box>\n <Box paddingX={1}>\n <Text dimColor> enter send · esc cancel</Text>\n </Box>\n </Box>\n );\n }\n\n // kill mode — requires typing \"stop\" to confirm\n return (\n <Box flexDirection=\"column\">\n <Box paddingX={1} gap={1}>\n <Text dimColor>└</Text>\n <Text color=\"#f87171\" bold>\n KILL\n </Text>\n <Text dimColor>→ {handle.supervisorId}</Text>\n <Text dimColor>— type</Text>\n <Text bold color=\"#f87171\">\n stop\n </Text>\n <Text dimColor>to confirm</Text>\n </Box>\n <Box paddingX={1} gap={1}>\n <Text dimColor> </Text>\n <Text color=\"#f87171\" bold>\n ❯\n </Text>\n <TextInput\n value={value}\n onChange={onChange}\n onSubmit={onSubmit}\n focus\n placeholder='type \"stop\" to kill...'\n />\n </Box>\n <Box paddingX={1}>\n <Text dimColor> esc cancel</Text>\n </Box>\n </Box>\n );\n}\n","import type { ChildHandle } from \"@neotx/core\";\nimport { Box, Text } from \"ink\";\n\nconst STATUS_COLORS: Record<string, string> = {\n running: \"#4ade80\",\n blocked: \"#fbbf24\",\n stalled: \"#f97316\",\n complete: \"#818cf8\",\n failed: \"#f87171\",\n};\n\nconst STATUS_ICONS: Record<string, string> = {\n running: \"●\",\n blocked: \"◆\",\n stalled: \"◌\",\n complete: \"✓\",\n failed: \"✖\",\n};\n\nconst STATUS_LABELS: Record<string, string> = {\n running: \"RUN\",\n blocked: \"BLK\",\n stalled: \"STL\",\n complete: \"DONE\",\n failed: \"FAIL\",\n};\n\nfunction truncate(s: string, max: number): string {\n if (s.length <= max) return s;\n return `${s.slice(0, max - 1)}…`;\n}\n\nfunction ChildRow({ handle, isSelected }: { handle: ChildHandle; isSelected: boolean }) {\n const color = STATUS_COLORS[handle.status] ?? \"#9ca3af\";\n const icon = STATUS_ICONS[handle.status] ?? \"·\";\n const label = (STATUS_LABELS[handle.status] ?? handle.status).padEnd(4);\n const cost = `$${handle.costUsd.toFixed(2)}`;\n const id = truncate(handle.supervisorId, 12);\n const objective = truncate(handle.objective, 28);\n\n return (\n <Box gap={1} paddingX={1}>\n <Text color={isSelected ? \"#c084fc\" : \"#4b5563\"}>{isSelected ? \"▶\" : \" \"}</Text>\n <Text color={color} bold>\n {icon}\n </Text>\n <Text color={color} bold>\n {label}\n </Text>\n <Text bold={isSelected} dimColor={!isSelected}>\n {id}\n </Text>\n <Text dimColor>·</Text>\n <Text dimColor>{cost}</Text>\n <Text dimColor>·</Text>\n <Text dimColor={!isSelected} wrap=\"truncate\">\n {objective}\n </Text>\n </Box>\n );\n}\n\nexport function ChildList({\n handles,\n selectedIndex,\n}: {\n handles: ChildHandle[];\n selectedIndex: number;\n}) {\n if (handles.length === 0) {\n return (\n <Box paddingX={2}>\n <Text dimColor>No focused supervisors running</Text>\n </Box>\n );\n }\n\n return (\n <Box flexDirection=\"column\">\n <Box paddingX={1} gap={1}>\n <Text dimColor>├</Text>\n <Text dimColor bold>\n CHILDREN\n </Text>\n <Text dimColor>({handles.length})</Text>\n <Text dimColor>{\"─\".repeat(20)}</Text>\n </Box>\n {handles.map((handle, idx) => (\n <ChildRow key={handle.supervisorId} handle={handle} isSelected={idx === selectedIndex} />\n ))}\n </Box>\n );\n}\n"],"mappings":"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","names":["Box","Text","TextInput","Box","Text","jsx","jsxs","Box","Text","jsx","jsxs","STATUS_COLORS","Fragment","jsx","jsxs","TYPE_ICONS","TYPE_COLORS","formatTime","formatTimeAgo","Box","Text","TextInput"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@neotx/cli",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.25",
|
|
4
4
|
"description": "CLI for the Neo orchestration framework",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -50,9 +50,9 @@
|
|
|
50
50
|
"ink": "^6.8.0",
|
|
51
51
|
"ink-text-input": "^6.0.0",
|
|
52
52
|
"react": "^19.2.4",
|
|
53
|
-
"yaml": "^2.8.
|
|
54
|
-
"@neotx/agents": "0.1.0-alpha.
|
|
55
|
-
"@neotx/core": "0.1.0-alpha.
|
|
53
|
+
"yaml": "^2.8.3",
|
|
54
|
+
"@neotx/agents": "0.1.0-alpha.25",
|
|
55
|
+
"@neotx/core": "0.1.0-alpha.25"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
58
|
"@anthropic-ai/claude-agent-sdk": "^0.1.0",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/commands/decision.ts"],"sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { appendFile, mkdir } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type { Decision, DecisionOption, InboxMessage } from \"@neotx/core\";\nimport { DecisionStore, getSupervisorDecisionsPath, getSupervisorDir } from \"@neotx/core\";\nimport { defineCommand } from \"citty\";\nimport { printError, printJson, printSuccess, printTable } from \"../output.js\";\n\nconst DEFAULT_EXPIRES_MS = 24 * 60 * 60 * 1000; // 24 hours\n\ninterface ParsedArgs {\n action: string;\n value: string | undefined;\n question: string | undefined;\n options: string | undefined;\n defaultAnswer: string | undefined;\n expiresIn: string | undefined;\n type: string | undefined;\n context: string | undefined;\n name: string;\n id: string | undefined;\n answer: string | undefined;\n json: boolean;\n}\n\nfunction truncate(text: string, max: number): string {\n return text.length > max ? `${text.slice(0, max - 1)}…` : text;\n}\n\nfunction formatStatus(decision: Decision): string {\n if (decision.answer !== undefined) {\n return \"answered\";\n }\n if (decision.expiredAt !== undefined) {\n return \"expired\";\n }\n if (decision.expiresAt && decision.expiresAt < new Date().toISOString()) {\n return \"expired\";\n }\n return \"pending\";\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 parseDurationMs(input: string): number | undefined {\n const match = input.match(/^(\\d+)(h|m|d)$/);\n if (!match) return undefined;\n\n const value = Number(match[1]);\n const unit = match[2];\n switch (unit) {\n case \"d\":\n return value * 24 * 60 * 60 * 1000;\n case \"h\":\n return value * 60 * 60 * 1000;\n case \"m\":\n return value * 60 * 1000;\n default:\n return undefined;\n }\n}\n\nfunction parseOptions(optionsArg: string): DecisionOption[] | undefined {\n // Format: \"key1:label1,key2:label2\" or \"key1:label1:description1,key2:label2:description2\"\n if (!optionsArg.trim()) return undefined;\n\n const options: DecisionOption[] = [];\n const parts = optionsArg.split(\",\");\n\n for (const part of parts) {\n const segments = part.trim().split(\":\");\n const key = segments[0];\n const label = segments[1];\n if (!key || !label) {\n throw new Error(\n `Invalid option format: \"${part}\". Expected \"key:label\" or \"key:label:description\"`,\n );\n }\n const descParts = segments.slice(2);\n options.push({\n key: key.trim(),\n label: label.trim(),\n description: descParts.length > 0 ? descParts.join(\":\").trim() : undefined,\n });\n }\n\n return options.length > 0 ? options : undefined;\n}\n\nfunction openStore(name: string): DecisionStore {\n const filePath = getSupervisorDecisionsPath(name);\n return new DecisionStore(filePath);\n}\n\nasync function handleCreate(args: ParsedArgs): Promise<void> {\n if (!args.question) {\n printError(\n \"Usage: neo decision create <question> --options 'key1:label1,key2:label2' [--default <key>] [--expires-in 24h]\",\n );\n process.exitCode = 1;\n return;\n }\n\n let options: DecisionOption[] | undefined;\n if (args.options) {\n try {\n options = parseOptions(args.options);\n } catch (error) {\n printError(error instanceof Error ? error.message : String(error));\n process.exitCode = 1;\n return;\n }\n }\n\n let expiresAt: string | undefined;\n if (args.expiresIn) {\n const ms = parseDurationMs(args.expiresIn);\n if (!ms) {\n printError('Invalid --expires-in format. Use e.g. \"24h\", \"30m\", or \"7d\".');\n process.exitCode = 1;\n return;\n }\n expiresAt = new Date(Date.now() + ms).toISOString();\n } else {\n // Default to 24 hours\n expiresAt = new Date(Date.now() + DEFAULT_EXPIRES_MS).toISOString();\n }\n\n const store = openStore(args.name);\n try {\n const id = await store.create({\n question: args.question,\n options,\n defaultAnswer: args.defaultAnswer,\n expiresAt,\n type: args.type ?? \"generic\",\n source: \"supervisor\",\n context: args.context,\n });\n printSuccess(`Decision created: ${id}`);\n console.log(id); // Output just the ID for easy parsing in scripts\n } catch (error) {\n printError(\n `Failed to create decision: ${error instanceof Error ? error.message : String(error)}`,\n );\n process.exitCode = 1;\n }\n}\n\nasync function handleList(args: ParsedArgs): Promise<void> {\n const store = openStore(args.name);\n const pending = await store.pending();\n\n if (args.json) {\n printJson(pending);\n return;\n }\n\n if (pending.length === 0) {\n console.log(\"No pending decisions.\");\n return;\n }\n\n printTable(\n [\"ID\", \"TYPE\", \"QUESTION\", \"SOURCE\", \"CREATED\"],\n pending.map((d) => [\n d.id.slice(0, 12),\n d.type,\n truncate(d.question, 50),\n d.source,\n formatTimeAgo(d.createdAt),\n ]),\n );\n}\n\nasync function handleGet(args: ParsedArgs): Promise<void> {\n if (!args.value) {\n printError(\"Usage: neo decision get <id>\");\n process.exitCode = 1;\n return;\n }\n\n const store = openStore(args.name);\n const decision = await store.get(args.value);\n\n if (!decision) {\n printError(`Decision not found: ${args.value}`);\n process.exitCode = 1;\n return;\n }\n\n if (args.json) {\n printJson(decision);\n return;\n }\n\n const status = formatStatus(decision);\n console.log(`ID: ${decision.id}`);\n console.log(`Status: ${status}`);\n console.log(`Type: ${decision.type}`);\n console.log(`Source: ${decision.source}`);\n console.log(`Created: ${decision.createdAt}`);\n console.log();\n console.log(`Question: ${decision.question}`);\n if (decision.context) {\n console.log();\n console.log(`Context:\\n${decision.context}`);\n }\n if (decision.options && decision.options.length > 0) {\n console.log();\n console.log(\"Options:\");\n for (const opt of decision.options) {\n console.log(` [${opt.key}] ${opt.label}${opt.description ? ` - ${opt.description}` : \"\"}`);\n }\n }\n if (decision.answer !== undefined) {\n console.log();\n console.log(`Answer: ${decision.answer}`);\n if (decision.answeredAt) {\n console.log(`Answered: ${decision.answeredAt}`);\n }\n }\n if (decision.defaultAnswer !== undefined) {\n console.log(`Default: ${decision.defaultAnswer}`);\n }\n if (decision.expiresAt) {\n console.log(`Expires: ${decision.expiresAt}`);\n }\n}\n\nasync function handleAnswer(args: ParsedArgs): Promise<void> {\n // Parse positional args from process.argv\n const argv = process.argv;\n const answerIdx = argv.indexOf(\"answer\");\n const idArg = argv[answerIdx + 1];\n const answerArg = argv[answerIdx + 2];\n\n if (!idArg || !answerArg) {\n printError(\"Usage: neo decision answer <id> <answer>\");\n process.exitCode = 1;\n return;\n }\n\n const store = openStore(args.name);\n\n try {\n await store.answer(idArg, answerArg);\n\n // Wake up the supervisor heartbeat by appending to inbox.jsonl\n const dir = getSupervisorDir(args.name);\n const inboxMessage: InboxMessage = {\n id: randomUUID(),\n from: \"external\",\n text: `decision:answer ${idArg} ${answerArg}`,\n timestamp: new Date().toISOString(),\n };\n const inboxPath = path.join(dir, \"inbox.jsonl\");\n try {\n await mkdir(dir, { recursive: true });\n await appendFile(inboxPath, `${JSON.stringify(inboxMessage)}\\n`, \"utf-8\");\n } catch (error) {\n // Log but don't fail the answer operation - the decision was still recorded\n console.error(\n `Warning: Failed to write to inbox: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n\n printSuccess(`Decision answered: ${idArg} → \"${answerArg}\"`);\n } catch (error) {\n printError(error instanceof Error ? error.message : \"Unknown error\");\n process.exitCode = 1;\n }\n}\n\nasync function handlePending(args: ParsedArgs): Promise<void> {\n const store = openStore(args.name);\n const pending = await store.pending();\n\n if (args.json) {\n printJson(pending);\n return;\n }\n\n if (pending.length === 0) {\n console.log(\"No pending decisions.\");\n return;\n }\n\n // Show more detailed view for pending decisions\n for (const d of pending) {\n console.log(`─────────────────────────────────────────`);\n console.log(`ID: ${d.id} (${formatTimeAgo(d.createdAt)})`);\n console.log(`Question: ${d.question}`);\n if (d.options && d.options.length > 0) {\n console.log(\"Options:\");\n for (const opt of d.options) {\n console.log(` [${opt.key}] ${opt.label}`);\n }\n }\n if (d.defaultAnswer) {\n console.log(`Default: ${d.defaultAnswer}`);\n }\n console.log();\n }\n console.log(`─────────────────────────────────────────`);\n console.log(`\\nAnswer with: neo decision answer <id> <answer>`);\n}\n\nexport default defineCommand({\n meta: {\n name: \"decision\",\n description: \"Manage supervisor decision gates\",\n },\n args: {\n action: {\n type: \"positional\",\n description: \"Action: create, list, get, answer, pending\",\n required: true,\n },\n value: {\n type: \"positional\",\n description: \"Decision ID (for get/answer) or question text (for create)\",\n required: false,\n },\n options: {\n type: \"string\",\n alias: \"o\",\n description:\n 'Options in format \"key1:label1,key2:label2\" or \"key1:label1:desc1,key2:label2:desc2\"',\n },\n \"default-answer\": {\n type: \"string\",\n alias: \"d\",\n description: \"Default answer key (used if decision expires)\",\n },\n \"expires-in\": {\n type: \"string\",\n alias: \"e\",\n description: \"Expiration duration (e.g. 24h, 30m, 7d). Default: 24h\",\n },\n type: {\n type: \"string\",\n alias: \"t\",\n description: \"Decision type (default: generic)\",\n },\n context: {\n type: \"string\",\n alias: \"c\",\n description: \"Additional context for the decision\",\n },\n name: {\n type: \"string\",\n description: \"Supervisor name\",\n default: \"supervisor\",\n },\n json: {\n type: \"boolean\",\n description: \"Output as JSON\",\n default: false,\n },\n },\n async run({ args }) {\n const action = args.action as string;\n const parsed: ParsedArgs = {\n action,\n value: args.value as string | undefined,\n question: args.value as string | undefined, // For create action\n options: args.options as string | undefined,\n defaultAnswer: args[\"default-answer\"] as string | undefined,\n expiresIn: args[\"expires-in\"] as string | undefined,\n type: args.type as string | undefined,\n context: args.context as string | undefined,\n name: args.name as string,\n id: args.value as string | undefined, // For get/answer actions\n answer: undefined,\n json: args.json as boolean,\n };\n\n switch (action) {\n case \"create\":\n return handleCreate(parsed);\n case \"list\":\n return handleList(parsed);\n case \"get\":\n return handleGet(parsed);\n case \"answer\":\n return handleAnswer(parsed);\n case \"pending\":\n return handlePending(parsed);\n default:\n printError(\n `Unknown action \"${action}\". Must be one of: create, list, get, answer, pending`,\n );\n process.exitCode = 1;\n }\n },\n});\n"],"mappings":"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","names":[]}
|
package/dist/log-PTHLI7ZN.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/commands/log.ts"],"sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { appendFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { appendLogBuffer, getSupervisorDir, MemoryStore } from \"@neotx/core\";\nimport { defineCommand } from \"citty\";\nimport { printError, printSuccess } from \"../output.js\";\n\nconst VALID_TYPES = [\n \"progress\",\n \"action\",\n \"decision\",\n \"blocker\",\n \"milestone\",\n \"discovery\",\n] as const;\ntype LogType = (typeof VALID_TYPES)[number];\n\n// Map log types to activity.jsonl entry types (preserve existing behavior)\nconst TYPE_MAP: Record<string, string> = {\n decision: \"decision\",\n action: \"action\",\n blocker: \"error\",\n progress: \"event\",\n milestone: \"event\",\n discovery: \"event\",\n};\n\n// Implicit routing: which target each type gets by default\nconst TARGET_MAP: Record<string, \"memory\" | \"knowledge\" | \"digest\"> = {\n progress: \"digest\",\n action: \"digest\",\n decision: \"memory\",\n milestone: \"memory\",\n blocker: \"memory\",\n discovery: \"knowledge\",\n};\n\nexport default defineCommand({\n meta: {\n name: \"log\",\n description: \"Log a structured progress report to the supervisor activity log\",\n },\n args: {\n type: {\n type: \"positional\",\n description: \"Report type: progress, action, decision, blocker, milestone, discovery\",\n required: true,\n },\n message: {\n type: \"positional\",\n description: \"Message to log\",\n required: true,\n },\n name: {\n type: \"string\",\n description: \"Supervisor instance name\",\n default: \"supervisor\",\n },\n memory: {\n type: \"boolean\",\n description: \"Override routing: send to memory target\",\n default: false,\n },\n knowledge: {\n type: \"boolean\",\n description: \"Override routing: send to knowledge target\",\n default: false,\n },\n repo: {\n type: \"string\",\n description: \"Repository path\",\n },\n procedure: {\n type: \"boolean\",\n description: \"Also write as a procedure memory entry\",\n default: false,\n },\n },\n async run({ args }) {\n const type = args.type as string;\n if (!VALID_TYPES.includes(type as LogType)) {\n printError(`Invalid type \"${type}\". Must be one of: ${VALID_TYPES.join(\", \")}`);\n process.exitCode = 1;\n return;\n }\n\n const dir = getSupervisorDir(args.name);\n const now = new Date().toISOString();\n const id = randomUUID();\n\n // Resolve agent/run from env vars or flags\n const agent = process.env.NEO_AGENT_NAME ?? undefined;\n const runId = process.env.NEO_RUN_ID ?? undefined;\n const repo = (args.repo as string | undefined) ?? process.env.NEO_REPOSITORY ?? undefined;\n\n // Resolve target with flag overrides\n let target: \"memory\" | \"knowledge\" | \"digest\" = TARGET_MAP[type] ?? \"digest\";\n if (args.memory) target = \"memory\";\n if (args.knowledge) target = \"knowledge\";\n\n // 1. Always: append to activity.jsonl (existing behavior)\n const activityEntry = {\n id,\n type: TYPE_MAP[type] ?? \"event\",\n summary: args.message,\n timestamp: now,\n };\n await appendFile(`${dir}/activity.jsonl`, `${JSON.stringify(activityEntry)}\\n`, \"utf-8\");\n\n // 2. Always: append to log-buffer.jsonl via shared helper\n await appendLogBuffer(dir, {\n id,\n type: type as \"progress\" | \"action\" | \"decision\" | \"blocker\" | \"milestone\" | \"discovery\",\n message: args.message,\n agent,\n runId,\n repo,\n target,\n timestamp: now,\n });\n\n // 3. Write to memory store for knowledge/procedure entries\n if (target === \"knowledge\" || args.procedure) {\n try {\n const store = new MemoryStore(path.join(dir, \"memory.sqlite\"));\n await store.write({\n type: args.procedure ? \"procedure\" : \"fact\",\n scope: repo ?? \"global\",\n content: args.message,\n source: agent ?? \"user\",\n runId,\n });\n store.close();\n } catch {\n // Best-effort — don't crash CLI if store write fails\n }\n }\n\n // 4. If blocker: also append to inbox.jsonl (wake up heartbeat)\n if (type === \"blocker\") {\n const inboxMessage = {\n id: randomUUID(),\n from: \"agent\" as const,\n text: `[BLOCKER]${agent ? ` (${agent})` : \"\"} ${args.message}`,\n timestamp: now,\n };\n await appendFile(`${dir}/inbox.jsonl`, `${JSON.stringify(inboxMessage)}\\n`, \"utf-8\");\n }\n\n printSuccess(`Logged: [${type}] ${args.message.slice(0, 100)}`);\n },\n});\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/commands/memory.ts"],"sourcesContent":["import path from \"node:path\";\nimport type { Embedder, MemoryEntry, MemoryType } from \"@neotx/core\";\nimport { getSupervisorDir, LocalEmbedder, MemoryStore } from \"@neotx/core\";\nimport { defineCommand } from \"citty\";\nimport { printError, printSuccess, printTable } from \"../output.js\";\n\nconst VALID_TYPES = [\"fact\", \"procedure\", \"episode\", \"focus\", \"feedback\", \"task\"] as const;\n\ninterface ParsedArgs {\n value: string | undefined;\n type: string | undefined;\n scope: string;\n source: string;\n expires: string | undefined;\n name: string;\n outcome: string | undefined;\n severity: string | undefined;\n category: string | undefined;\n tags: string | undefined;\n}\n\nfunction parseDuration(input: string): string | undefined {\n const match = input.match(/^(\\d+)(h|m)$/);\n if (!match) return undefined;\n\n const value = Number(match[1]);\n const unit = match[2];\n const ms = unit === \"h\" ? value * 60 * 60 * 1000 : value * 60 * 1000;\n return new Date(Date.now() + ms).toISOString();\n}\n\nfunction truncate(text: string, max: number): string {\n return text.length > max ? `${text.slice(0, max - 1)}…` : text;\n}\n\nfunction createEmbedder(): Embedder | null {\n try {\n return new LocalEmbedder();\n } catch (err) {\n // Embedder initialization failed — semantic search will be unavailable\n console.debug(\n `[memory] Failed to create embedder: ${err instanceof Error ? err.message : String(err)}`,\n );\n return null;\n }\n}\n\nfunction openStore(name: string, withEmbeddings = false): MemoryStore {\n const dir = getSupervisorDir(name);\n const embedder = withEmbeddings ? createEmbedder() : null;\n return new MemoryStore(path.join(dir, \"memory.sqlite\"), embedder);\n}\n\nfunction formatResultsTable(results: MemoryEntry[]): void {\n printTable(\n [\"ID\", \"TYPE\", \"SCOPE\", \"CONTENT\", \"ACCESSES\"],\n results.map((m) => [m.id, m.type, m.scope, truncate(m.content, 60), String(m.accessCount)]),\n );\n}\n\nasync function handleWrite(args: ParsedArgs): Promise<void> {\n if (!args.value) {\n printError(\"Usage: neo memory write <content> --type <type> [--scope <scope>]\");\n process.exitCode = 1;\n return;\n }\n\n const type = args.type ?? \"fact\";\n if (!VALID_TYPES.includes(type as MemoryType)) {\n printError(`Invalid type \"${type}\". Must be one of: ${VALID_TYPES.join(\", \")}`);\n process.exitCode = 1;\n return;\n }\n\n let expiresAt: string | undefined;\n if (args.expires) {\n expiresAt = parseDuration(args.expires);\n if (!expiresAt) {\n printError('Invalid --expires format. Use e.g. \"2h\" or \"30m\".');\n process.exitCode = 1;\n return;\n }\n }\n\n const store = openStore(args.name, true);\n try {\n const tags = args.tags ? args.tags.split(\",\").map((t) => t.trim()) : [];\n const id = await store.write({\n type: type as MemoryType,\n scope: args.scope,\n content: args.value,\n source: args.source,\n tags,\n expiresAt,\n severity: args.severity,\n category: args.category,\n outcome: args.outcome,\n });\n printSuccess(`Memory written: ${id}`);\n } finally {\n store.close();\n }\n}\n\nfunction handleForget(args: ParsedArgs): void {\n if (!args.value) {\n printError(\"Usage: neo memory forget <id>\");\n process.exitCode = 1;\n return;\n }\n\n const store = openStore(args.name);\n try {\n store.forget(args.value);\n printSuccess(`Memory forgotten: ${args.value}`);\n } finally {\n store.close();\n }\n}\n\nconst VALID_OUTCOMES = [\"pending\", \"in_progress\", \"done\", \"blocked\", \"abandoned\"] as const;\n\nfunction handleUpdate(args: ParsedArgs): void {\n if (!args.value) {\n printError('Usage: neo memory update <id> [\"new content\"] [--outcome <status>]');\n process.exitCode = 1;\n return;\n }\n\n // The ID is in value, but we need content too.\n // citty only supports 2 positional args — content comes after ID.\n const argv = process.argv;\n const updateIdx = argv.indexOf(\"update\");\n const idArg = argv[updateIdx + 1];\n const contentArg = argv[updateIdx + 2];\n\n // Validate outcome if provided\n if (args.outcome && !VALID_OUTCOMES.includes(args.outcome as (typeof VALID_OUTCOMES)[number])) {\n printError(`Invalid outcome \"${args.outcome}\". Must be one of: ${VALID_OUTCOMES.join(\", \")}`);\n process.exitCode = 1;\n return;\n }\n\n // Determine if contentArg is actually content or a flag\n const isContentArgAFlag = contentArg?.startsWith(\"--\");\n const hasContent = contentArg && !isContentArgAFlag;\n\n // Need either content or --outcome\n if (!hasContent && !args.outcome) {\n printError('Usage: neo memory update <id> [\"new content\"] [--outcome <status>]');\n process.exitCode = 1;\n return;\n }\n\n // ID is required at this point — validated by args.value check above\n if (!idArg) {\n printError('Usage: neo memory update <id> [\"new content\"] [--outcome <status>]');\n process.exitCode = 1;\n return;\n }\n\n const store = openStore(args.name);\n try {\n // Use updateFields when --outcome is provided\n if (args.outcome) {\n store.updateFields(idArg, {\n ...(hasContent && { content: contentArg }),\n outcome: args.outcome,\n });\n } else {\n // contentArg is guaranteed to be defined when hasContent is true and no outcome\n store.update(idArg, contentArg as string);\n }\n printSuccess(`Memory updated: ${idArg}`);\n } finally {\n store.close();\n }\n}\n\nasync function handleSearch(args: ParsedArgs): Promise<void> {\n if (!args.value) {\n printError(\"Usage: neo memory search <query>\");\n process.exitCode = 1;\n return;\n }\n\n const store = openStore(args.name, true);\n try {\n const results = await store.search(args.value, {\n ...(args.scope !== \"global\" && { scope: args.scope }),\n ...(args.type && { types: [args.type as MemoryType] }),\n });\n\n if (results.length === 0) {\n console.log(\"No memories found.\");\n return;\n }\n\n formatResultsTable(results);\n } finally {\n store.close();\n }\n}\n\nfunction handleList(args: ParsedArgs): void {\n const store = openStore(args.name);\n try {\n const results = store.query({\n ...(args.scope !== \"global\" && { scope: args.scope }),\n ...(args.type && { types: [args.type as MemoryType] }),\n });\n\n if (results.length === 0) {\n console.log(\"No memories found.\");\n return;\n }\n\n formatResultsTable(results);\n } finally {\n store.close();\n }\n}\n\nfunction handleStats(args: ParsedArgs): void {\n const store = openStore(args.name);\n try {\n const s = store.stats();\n console.log(`Total memories: ${s.total}\\n`);\n\n if (Object.keys(s.byType).length > 0) {\n printTable(\n [\"TYPE\", \"COUNT\"],\n Object.entries(s.byType).map(([t, c]) => [t, String(c)]),\n );\n console.log();\n }\n\n if (Object.keys(s.byScope).length > 0) {\n printTable(\n [\"SCOPE\", \"COUNT\"],\n Object.entries(s.byScope).map(([sc, c]) => [sc, String(c)]),\n );\n }\n } finally {\n store.close();\n }\n}\n\nexport default defineCommand({\n meta: {\n name: \"memory\",\n description: \"Manage the supervisor memory store\",\n },\n args: {\n action: {\n type: \"positional\",\n description: \"Action: write, forget, update, search, list, stats\",\n required: true,\n },\n value: {\n type: \"positional\",\n description: \"Content or ID depending on action\",\n required: false,\n },\n type: {\n type: \"string\",\n description: \"Memory type: fact, procedure, episode, focus, feedback, task\",\n },\n scope: {\n type: \"string\",\n description: \"Scope: global or repo path\",\n default: \"global\",\n },\n source: {\n type: \"string\",\n description: \"Source: developer, reviewer, supervisor, user\",\n default: \"user\",\n },\n expires: {\n type: \"string\",\n description: \"TTL for focus entries (e.g. 2h, 30m)\",\n },\n outcome: {\n type: \"string\",\n description: \"Task outcome: pending, in_progress, done, blocked, abandoned\",\n },\n severity: {\n type: \"string\",\n description: \"Priority: critical, high, medium, low\",\n },\n category: {\n type: \"string\",\n description: \"Context reference (e.g. 'neo runs abc123' or 'cat notes/plan.md')\",\n },\n tags: {\n type: \"string\",\n description: \"Comma-separated tags (e.g. 'initiative:auth,depends:mem_abc')\",\n },\n name: {\n type: \"string\",\n description: \"Supervisor name\",\n default: \"supervisor\",\n },\n },\n async run({ args }) {\n const action = args.action as string;\n const parsed: ParsedArgs = {\n value: args.value as string | undefined,\n type: args.type as string | undefined,\n scope: args.scope as string,\n source: args.source as string,\n expires: args.expires as string | undefined,\n name: args.name as string,\n outcome: args.outcome as string | undefined,\n severity: args.severity as string | undefined,\n category: args.category as string | undefined,\n tags: args.tags as string | undefined,\n };\n\n switch (action) {\n case \"write\":\n return handleWrite(parsed);\n case \"forget\":\n return handleForget(parsed);\n case \"update\":\n return handleUpdate(parsed);\n case \"search\":\n return handleSearch(parsed);\n case \"list\":\n return handleList(parsed);\n case \"stats\":\n return handleStats(parsed);\n default:\n printError(\n `Unknown action \"${action}\". Must be one of: write, forget, update, search, list, stats`,\n );\n process.exitCode = 1;\n }\n },\n});\n"],"mappings":"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","names":[]}
|
package/dist/run-MWHIQUSY.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/commands/run.ts"],"sourcesContent":["import { spawn } from \"node:child_process\";\nimport { randomUUID } from \"node:crypto\";\nimport { existsSync } from \"node:fs\";\nimport { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type { NeoEvent, PersistedRun } from \"@neotx/core\";\nimport {\n AgentRegistry,\n getRepoRunsDir,\n getRunDispatchPath,\n loadGlobalConfig,\n Orchestrator,\n toRepoSlug,\n} from \"@neotx/core\";\nimport { defineCommand } from \"citty\";\nimport { printError, printJson, printSuccess } from \"../output.js\";\nimport { resolveAgentsDir } from \"../resolve.js\";\n\nfunction printProgress(event: NeoEvent): void {\n const ts = event.timestamp.slice(11, 19);\n switch (event.type) {\n case \"session:start\":\n console.log(`[${ts}] ${event.agent}: starting`);\n break;\n case \"session:complete\":\n console.log(`[${ts}] session complete: $${event.costUsd.toFixed(4)}`);\n break;\n case \"session:fail\":\n console.log(`[${ts}] session failed: ${event.error}`);\n break;\n case \"cost:update\":\n break;\n case \"budget:alert\":\n console.log(`[${ts}] ⚠ Budget alert: ${event.utilizationPct.toFixed(0)}% used`);\n break;\n }\n}\n\nfunction parseMetadata(meta: string | undefined): Record<string, unknown> | undefined {\n if (!meta) return undefined;\n try {\n return JSON.parse(meta) as Record<string, unknown>;\n } catch (err) {\n // Expected error: invalid JSON provided by user\n throw new Error(\n `Invalid --meta JSON: ${meta}. Error: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n}\n\nfunction printResult(result: import(\"@neotx/core\").TaskResult, agentName: string): void {\n console.log(\"\");\n console.log(`Run: ${result.runId}`);\n console.log(`Agent: ${agentName}`);\n console.log(`Status: ${result.status}`);\n console.log(`Cost: $${result.costUsd.toFixed(4)}`);\n console.log(`Duration: ${(result.durationMs / 1000).toFixed(1)}s`);\n if (result.branch) {\n console.log(`Branch: ${result.branch}`);\n }\n if (result.prUrl) {\n console.log(`PR: ${result.prUrl}`);\n }\n\n const stepResult = Object.values(result.steps)[0];\n const output = stepResult?.output ?? result.summary;\n if (output) {\n console.log(\"\");\n console.log(typeof output === \"string\" ? output : JSON.stringify(output, null, 2));\n }\n}\n\ninterface DetachParams {\n agentName: string;\n repo: string;\n prompt: string;\n branch: string | undefined;\n priority: string;\n metadata: Record<string, unknown> | undefined;\n bundledAgentsDir: string;\n customAgentsDir: string | undefined;\n jsonOutput: boolean;\n}\n\nasync function runDetached(params: DetachParams): Promise<void> {\n const runId = randomUUID();\n const repoSlug = toRepoSlug({ path: params.repo });\n const runsDir = getRepoRunsDir(repoSlug);\n await mkdir(runsDir, { recursive: true });\n\n const persistedRun: PersistedRun = {\n version: 1,\n runId,\n agent: params.agentName,\n repo: params.repo,\n prompt: params.prompt,\n status: \"running\",\n steps: {},\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n metadata: params.metadata,\n };\n await writeFile(\n path.join(runsDir, `${runId}.json`),\n JSON.stringify(persistedRun, null, 2),\n \"utf-8\",\n );\n\n const dispatchPath = getRunDispatchPath(repoSlug, runId);\n await writeFile(\n dispatchPath,\n JSON.stringify({\n agentName: params.agentName,\n repo: params.repo,\n prompt: params.prompt,\n branch: params.branch,\n priority: params.priority,\n metadata: params.metadata,\n bundledAgentsDir: params.bundledAgentsDir,\n customAgentsDir: params.customAgentsDir,\n }),\n \"utf-8\",\n );\n\n const workerPath = path.join(path.dirname(fileURLToPath(import.meta.url)), \"daemon\", \"worker.js\");\n // Use spawn (not fork) so the child gets its own process group via detached: true.\n // fork() shares the parent's process group, so when the SDK kills the Bash\n // process tree the worker dies too.\n const child = spawn(process.execPath, [workerPath, runId, repoSlug], {\n detached: true,\n stdio: \"ignore\",\n env: process.env,\n });\n child.unref();\n\n // Write PID to persisted run immediately so other workers' recoverOrphanedRuns()\n // can see this process is alive (prevents false orphan detection on concurrent launches)\n if (child.pid) {\n const runFilePath = path.join(runsDir, `${runId}.json`);\n try {\n const raw = await readFile(runFilePath, \"utf-8\");\n const run = JSON.parse(raw) as PersistedRun;\n run.pid = child.pid;\n await writeFile(runFilePath, JSON.stringify(run, null, 2), \"utf-8\");\n } catch (err) {\n // Non-critical — worker will write PID on startup anyway\n console.debug(\n `[run] Failed to update run file with PID: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n\n if (params.jsonOutput) {\n printJson({ runId, status: \"detached\", pid: child.pid });\n } else {\n printSuccess(`Detached run started: ${runId}`);\n console.log(` PID: ${String(child.pid)}`);\n console.log(` Logs: neo logs -f ${runId}`);\n }\n}\n\nexport default defineCommand({\n meta: {\n name: \"run\",\n description: \"Dispatch an agent to execute a task in an isolated clone\",\n },\n args: {\n agent: {\n type: \"positional\",\n description: \"Agent name to run (e.g. developer, architect, reviewer-quality)\",\n required: true,\n },\n repo: {\n type: \"string\",\n description: \"Target repository path\",\n default: \".\",\n },\n prompt: {\n type: \"string\",\n description: \"Task description for the agent\",\n required: true,\n },\n branch: {\n type: \"string\",\n description: \"Branch name for the session clone (required for writable agents)\",\n },\n priority: {\n type: \"string\",\n description: \"Priority level: critical, high, medium, low\",\n },\n meta: {\n type: \"string\",\n description: \"Metadata as JSON string (for traceability: ticketId, stage, etc.)\",\n },\n output: {\n type: \"string\",\n description: \"Output format: json\",\n },\n detach: {\n type: \"boolean\",\n alias: \"d\",\n description: \"Run in background and return immediately with the run ID\",\n default: true,\n },\n sync: {\n type: \"boolean\",\n alias: \"s\",\n description: \"Run in foreground (blocking) instead of detached\",\n default: false,\n },\n \"git-strategy\": {\n type: \"string\",\n description: \"Git strategy: pr (create PR), branch (push only, default)\",\n },\n },\n async run({ args }) {\n const jsonOutput = args.output === \"json\";\n\n // Zero-config: only need global config (auto-creates ~/.neo/config.yml if absent)\n const config = await loadGlobalConfig();\n const repo = path.resolve(args.repo);\n\n // Load agent registry (bundled + project-local agents)\n const bundledAgentsDir = resolveAgentsDir();\n const customAgentsDir = path.resolve(\".neo/agents\");\n const agentRegistry = new AgentRegistry(\n bundledAgentsDir,\n existsSync(customAgentsDir) ? customAgentsDir : undefined,\n );\n await agentRegistry.load();\n\n // Validate agent exists\n const agent = agentRegistry.get(args.agent);\n if (!agent) {\n const available = agentRegistry\n .list()\n .map((a) => a.name)\n .join(\", \");\n printError(`Agent \"${args.agent}\" not found. Available: ${available}`);\n process.exitCode = 1;\n return;\n }\n\n if (args.detach && !args.sync) {\n await runDetached({\n agentName: args.agent,\n repo,\n prompt: args.prompt,\n branch: args.branch,\n priority: args.priority ?? \"medium\",\n metadata: parseMetadata(args.meta),\n bundledAgentsDir,\n customAgentsDir: existsSync(customAgentsDir) ? customAgentsDir : undefined,\n jsonOutput,\n });\n return;\n }\n\n // ─── Foreground mode (default) ──────────────────────\n const orchestrator = new Orchestrator(config, { skipOrphanRecovery: true });\n orchestrator.registerAgent(agent);\n\n if (!jsonOutput) {\n orchestrator.on(\"*\", printProgress);\n }\n\n try {\n await orchestrator.start();\n\n const gitStrategy = args[\"git-strategy\"] as \"pr\" | \"branch\" | undefined;\n const result = await orchestrator.dispatch({\n agent: args.agent,\n repo,\n prompt: args.prompt,\n ...(args.branch ? { branch: args.branch } : {}),\n priority: (args.priority as \"critical\" | \"high\" | \"medium\" | \"low\") ?? \"medium\",\n metadata: parseMetadata(args.meta),\n ...(gitStrategy ? { gitStrategy } : {}),\n });\n\n if (jsonOutput) {\n printJson(result);\n } else {\n printResult(result, args.agent);\n }\n\n await orchestrator.shutdown();\n if (result.status !== \"success\") {\n process.exitCode = 1;\n }\n } catch (error) {\n await orchestrator.shutdown();\n printError(error instanceof Error ? error.message : String(error));\n process.exitCode = 1;\n }\n },\n});\n"],"mappings":";;;;;;;;;;AAAA,SAAS,aAAa;AACtB,SAAS,kBAAkB;AAC3B,SAAS,kBAAkB;AAC3B,SAAS,OAAO,UAAU,iBAAiB;AAC3C,OAAO,UAAU;AACjB,SAAS,qBAAqB;AAE9B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,qBAAqB;AAI9B,SAAS,cAAc,OAAuB;AAC5C,QAAM,KAAK,MAAM,UAAU,MAAM,IAAI,EAAE;AACvC,UAAQ,MAAM,MAAM;AAAA,IAClB,KAAK;AACH,cAAQ,IAAI,IAAI,EAAE,KAAK,MAAM,KAAK,YAAY;AAC9C;AAAA,IACF,KAAK;AACH,cAAQ,IAAI,IAAI,EAAE,wBAAwB,MAAM,QAAQ,QAAQ,CAAC,CAAC,EAAE;AACpE;AAAA,IACF,KAAK;AACH,cAAQ,IAAI,IAAI,EAAE,qBAAqB,MAAM,KAAK,EAAE;AACpD;AAAA,IACF,KAAK;AACH;AAAA,IACF,KAAK;AACH,cAAQ,IAAI,IAAI,EAAE,0BAAqB,MAAM,eAAe,QAAQ,CAAC,CAAC,QAAQ;AAC9E;AAAA,EACJ;AACF;AAEA,SAAS,cAAc,MAA+D;AACpF,MAAI,CAAC,KAAM,QAAO;AAClB,MAAI;AACF,WAAO,KAAK,MAAM,IAAI;AAAA,EACxB,SAAS,KAAK;AAEZ,UAAM,IAAI;AAAA,MACR,wBAAwB,IAAI,YAAY,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,IAC1F;AAAA,EACF;AACF;AAEA,SAAS,YAAY,QAA0C,WAAyB;AACtF,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,aAAa,OAAO,KAAK,EAAE;AACvC,UAAQ,IAAI,aAAa,SAAS,EAAE;AACpC,UAAQ,IAAI,aAAa,OAAO,MAAM,EAAE;AACxC,UAAQ,IAAI,cAAc,OAAO,QAAQ,QAAQ,CAAC,CAAC,EAAE;AACrD,UAAQ,IAAI,cAAc,OAAO,aAAa,KAAM,QAAQ,CAAC,CAAC,GAAG;AACjE,MAAI,OAAO,QAAQ;AACjB,YAAQ,IAAI,aAAa,OAAO,MAAM,EAAE;AAAA,EAC1C;AACA,MAAI,OAAO,OAAO;AAChB,YAAQ,IAAI,aAAa,OAAO,KAAK,EAAE;AAAA,EACzC;AAEA,QAAM,aAAa,OAAO,OAAO,OAAO,KAAK,EAAE,CAAC;AAChD,QAAM,SAAS,YAAY,UAAU,OAAO;AAC5C,MAAI,QAAQ;AACV,YAAQ,IAAI,EAAE;AACd,YAAQ,IAAI,OAAO,WAAW,WAAW,SAAS,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAAA,EACnF;AACF;AAcA,eAAe,YAAY,QAAqC;AAC9D,QAAM,QAAQ,WAAW;AACzB,QAAM,WAAW,WAAW,EAAE,MAAM,OAAO,KAAK,CAAC;AACjD,QAAM,UAAU,eAAe,QAAQ;AACvC,QAAM,MAAM,SAAS,EAAE,WAAW,KAAK,CAAC;AAExC,QAAM,eAA6B;AAAA,IACjC,SAAS;AAAA,IACT;AAAA,IACA,OAAO,OAAO;AAAA,IACd,MAAM,OAAO;AAAA,IACb,QAAQ,OAAO;AAAA,IACf,QAAQ;AAAA,IACR,OAAO,CAAC;AAAA,IACR,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,IAClC,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,IAClC,UAAU,OAAO;AAAA,EACnB;AACA,QAAM;AAAA,IACJ,KAAK,KAAK,SAAS,GAAG,KAAK,OAAO;AAAA,IAClC,KAAK,UAAU,cAAc,MAAM,CAAC;AAAA,IACpC;AAAA,EACF;AAEA,QAAM,eAAe,mBAAmB,UAAU,KAAK;AACvD,QAAM;AAAA,IACJ;AAAA,IACA,KAAK,UAAU;AAAA,MACb,WAAW,OAAO;AAAA,MAClB,MAAM,OAAO;AAAA,MACb,QAAQ,OAAO;AAAA,MACf,QAAQ,OAAO;AAAA,MACf,UAAU,OAAO;AAAA,MACjB,UAAU,OAAO;AAAA,MACjB,kBAAkB,OAAO;AAAA,MACzB,iBAAiB,OAAO;AAAA,IAC1B,CAAC;AAAA,IACD;AAAA,EACF;AAEA,QAAM,aAAa,KAAK,KAAK,KAAK,QAAQ,cAAc,YAAY,GAAG,CAAC,GAAG,UAAU,WAAW;AAIhG,QAAM,QAAQ,MAAM,QAAQ,UAAU,CAAC,YAAY,OAAO,QAAQ,GAAG;AAAA,IACnE,UAAU;AAAA,IACV,OAAO;AAAA,IACP,KAAK,QAAQ;AAAA,EACf,CAAC;AACD,QAAM,MAAM;AAIZ,MAAI,MAAM,KAAK;AACb,UAAM,cAAc,KAAK,KAAK,SAAS,GAAG,KAAK,OAAO;AACtD,QAAI;AACF,YAAM,MAAM,MAAM,SAAS,aAAa,OAAO;AAC/C,YAAM,MAAM,KAAK,MAAM,GAAG;AAC1B,UAAI,MAAM,MAAM;AAChB,YAAM,UAAU,aAAa,KAAK,UAAU,KAAK,MAAM,CAAC,GAAG,OAAO;AAAA,IACpE,SAAS,KAAK;AAEZ,cAAQ;AAAA,QACN,6CAA6C,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,MAC/F;AAAA,IACF;AAAA,EACF;AAEA,MAAI,OAAO,YAAY;AACrB,cAAU,EAAE,OAAO,QAAQ,YAAY,KAAK,MAAM,IAAI,CAAC;AAAA,EACzD,OAAO;AACL,iBAAa,yBAAyB,KAAK,EAAE;AAC7C,YAAQ,IAAI,WAAW,OAAO,MAAM,GAAG,CAAC,EAAE;AAC1C,YAAQ,IAAI,uBAAuB,KAAK,EAAE;AAAA,EAC5C;AACF;AAEA,IAAO,cAAQ,cAAc;AAAA,EAC3B,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA,EACf;AAAA,EACA,MAAM;AAAA,IACJ,OAAO;AAAA,MACL,MAAM;AAAA,MACN,aAAa;AAAA,MACb,UAAU;AAAA,IACZ;AAAA,IACA,MAAM;AAAA,MACJ,MAAM;AAAA,MACN,aAAa;AAAA,MACb,SAAS;AAAA,IACX;AAAA,IACA,QAAQ;AAAA,MACN,MAAM;AAAA,MACN,aAAa;AAAA,MACb,UAAU;AAAA,IACZ;AAAA,IACA,QAAQ;AAAA,MACN,MAAM;AAAA,MACN,aAAa;AAAA,IACf;AAAA,IACA,UAAU;AAAA,MACR,MAAM;AAAA,MACN,aAAa;AAAA,IACf;AAAA,IACA,MAAM;AAAA,MACJ,MAAM;AAAA,MACN,aAAa;AAAA,IACf;AAAA,IACA,QAAQ;AAAA,MACN,MAAM;AAAA,MACN,aAAa;AAAA,IACf;AAAA,IACA,QAAQ;AAAA,MACN,MAAM;AAAA,MACN,OAAO;AAAA,MACP,aAAa;AAAA,MACb,SAAS;AAAA,IACX;AAAA,IACA,MAAM;AAAA,MACJ,MAAM;AAAA,MACN,OAAO;AAAA,MACP,aAAa;AAAA,MACb,SAAS;AAAA,IACX;AAAA,IACA,gBAAgB;AAAA,MACd,MAAM;AAAA,MACN,aAAa;AAAA,IACf;AAAA,EACF;AAAA,EACA,MAAM,IAAI,EAAE,KAAK,GAAG;AAClB,UAAM,aAAa,KAAK,WAAW;AAGnC,UAAM,SAAS,MAAM,iBAAiB;AACtC,UAAM,OAAO,KAAK,QAAQ,KAAK,IAAI;AAGnC,UAAM,mBAAmB,iBAAiB;AAC1C,UAAM,kBAAkB,KAAK,QAAQ,aAAa;AAClD,UAAM,gBAAgB,IAAI;AAAA,MACxB;AAAA,MACA,WAAW,eAAe,IAAI,kBAAkB;AAAA,IAClD;AACA,UAAM,cAAc,KAAK;AAGzB,UAAM,QAAQ,cAAc,IAAI,KAAK,KAAK;AAC1C,QAAI,CAAC,OAAO;AACV,YAAM,YAAY,cACf,KAAK,EACL,IAAI,CAAC,MAAM,EAAE,IAAI,EACjB,KAAK,IAAI;AACZ,iBAAW,UAAU,KAAK,KAAK,2BAA2B,SAAS,EAAE;AACrE,cAAQ,WAAW;AACnB;AAAA,IACF;AAEA,QAAI,KAAK,UAAU,CAAC,KAAK,MAAM;AAC7B,YAAM,YAAY;AAAA,QAChB,WAAW,KAAK;AAAA,QAChB;AAAA,QACA,QAAQ,KAAK;AAAA,QACb,QAAQ,KAAK;AAAA,QACb,UAAU,KAAK,YAAY;AAAA,QAC3B,UAAU,cAAc,KAAK,IAAI;AAAA,QACjC;AAAA,QACA,iBAAiB,WAAW,eAAe,IAAI,kBAAkB;AAAA,QACjE;AAAA,MACF,CAAC;AACD;AAAA,IACF;AAGA,UAAM,eAAe,IAAI,aAAa,QAAQ,EAAE,oBAAoB,KAAK,CAAC;AAC1E,iBAAa,cAAc,KAAK;AAEhC,QAAI,CAAC,YAAY;AACf,mBAAa,GAAG,KAAK,aAAa;AAAA,IACpC;AAEA,QAAI;AACF,YAAM,aAAa,MAAM;AAEzB,YAAM,cAAc,KAAK,cAAc;AACvC,YAAM,SAAS,MAAM,aAAa,SAAS;AAAA,QACzC,OAAO,KAAK;AAAA,QACZ;AAAA,QACA,QAAQ,KAAK;AAAA,QACb,GAAI,KAAK,SAAS,EAAE,QAAQ,KAAK,OAAO,IAAI,CAAC;AAAA,QAC7C,UAAW,KAAK,YAAuD;AAAA,QACvE,UAAU,cAAc,KAAK,IAAI;AAAA,QACjC,GAAI,cAAc,EAAE,YAAY,IAAI,CAAC;AAAA,MACvC,CAAC;AAED,UAAI,YAAY;AACd,kBAAU,MAAM;AAAA,MAClB,OAAO;AACL,oBAAY,QAAQ,KAAK,KAAK;AAAA,MAChC;AAEA,YAAM,aAAa,SAAS;AAC5B,UAAI,OAAO,WAAW,WAAW;AAC/B,gBAAQ,WAAW;AAAA,MACrB;AAAA,IACF,SAAS,OAAO;AACd,YAAM,aAAa,SAAS;AAC5B,iBAAW,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AACjE,cAAQ,WAAW;AAAA,IACrB;AAAA,EACF;AACF,CAAC;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/commands/supervise.ts"],"sourcesContent":["import { spawn } from \"node:child_process\";\nimport { randomUUID } from \"node:crypto\";\nimport { closeSync, existsSync, openSync } from \"node:fs\";\nimport { appendFile, mkdir, readFile, rm } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport {\n getSupervisorActivityPath,\n getSupervisorDir,\n getSupervisorInboxPath,\n getSupervisorLockPath,\n getSupervisorStatePath,\n isProcessAlive,\n loadGlobalConfig,\n type SupervisorDaemonState,\n supervisorDaemonStateSchema,\n} from \"@neotx/core\";\nimport { defineCommand } from \"citty\";\nimport { printError, printSuccess } from \"../output.js\";\n\nconst DEFAULT_NAME = \"supervisor\";\n\nasync function readState(name: string): Promise<SupervisorDaemonState | null> {\n const statePath = getSupervisorStatePath(name);\n if (!existsSync(statePath)) return null;\n try {\n const raw = await readFile(statePath, \"utf-8\");\n return supervisorDaemonStateSchema.parse(JSON.parse(raw));\n } catch {\n return null;\n }\n}\n\nasync function isDaemonRunning(name: string): Promise<SupervisorDaemonState | null> {\n const state = await readState(name);\n if (!state || state.status === \"stopped\") return null;\n if (!isProcessAlive(state.pid)) return null;\n return state;\n}\n\nasync function handleStatus(name: string): Promise<void> {\n const state = await isDaemonRunning(name);\n if (!state) {\n console.log(`No supervisor daemon running (name: ${name}).`);\n return;\n }\n\n const config = await loadGlobalConfig();\n printSuccess(`Supervisor \"${name}\" running`);\n console.log(` PID: ${state.pid}`);\n console.log(` Port: ${state.port}`);\n console.log(` Session: ${state.sessionId}`);\n console.log(` Started: ${state.startedAt}`);\n console.log(` Timeout: ${config.supervisor.eventTimeoutMs / 1000}s`);\n console.log(` Heartbeats: ${state.heartbeatCount}`);\n if (state.lastHeartbeat) {\n console.log(` Last beat: ${state.lastHeartbeat}`);\n }\n console.log(` Cost today: $${state.todayCostUsd?.toFixed(2) ?? \"0.00\"}`);\n console.log(` Cost total: $${state.totalCostUsd?.toFixed(2) ?? \"0.00\"}`);\n console.log(` Status: ${state.status}`);\n console.log(\"\");\n console.log(` Health: curl localhost:${state.port}/health`);\n console.log(\" TUI: neo supervise\");\n console.log(\" Stop: neo supervise --kill\");\n}\n\nasync function handleKill(name: string): Promise<void> {\n const state = await isDaemonRunning(name);\n if (!state) {\n printError(`No supervisor daemon running (name: ${name}).`);\n\n // Clean up stale lock if exists\n const lockPath = getSupervisorLockPath(name);\n if (existsSync(lockPath)) {\n await rm(lockPath, { force: true });\n }\n process.exitCode = 1;\n return;\n }\n\n // Send SIGTERM for graceful shutdown, then SIGKILL after 10s\n const pid = state.pid;\n try {\n process.kill(pid, \"SIGTERM\");\n printSuccess(`Sent SIGTERM to supervisor \"${name}\" (PID ${pid})`);\n } catch {\n printError(`Failed to send signal to PID ${pid}. Cleaning up.`);\n const lockPath = getSupervisorLockPath(name);\n await rm(lockPath, { force: true });\n return;\n }\n\n // Wait up to 10s for graceful exit, then force kill\n const deadline = Date.now() + 10_000;\n while (Date.now() < deadline) {\n await new Promise((r) => setTimeout(r, 500));\n if (!isProcessAlive(pid)) {\n printSuccess(\"Daemon stopped.\");\n return;\n }\n }\n\n // Force kill\n try {\n process.kill(pid, \"SIGKILL\");\n printSuccess(`Daemon did not exit in time — sent SIGKILL (PID ${pid}).`);\n } catch {\n // Already dead\n }\n\n // Clean up lock\n const lockPath = getSupervisorLockPath(name);\n await rm(lockPath, { force: true });\n}\n\nasync function startDaemon(name: string): Promise<void> {\n const running = await isDaemonRunning(name);\n if (running) {\n printError(`Supervisor \"${name}\" is already running (PID ${running.pid}).`);\n printError(\"Use --kill first, or run neo supervise to open TUI.\");\n process.exitCode = 1;\n return;\n }\n\n // Clean up stale lock\n const lockPath = getSupervisorLockPath(name);\n if (existsSync(lockPath)) {\n await rm(lockPath, { force: true });\n }\n\n // Resolve the worker script path and package root (for module resolution)\n const __dirname = path.dirname(fileURLToPath(import.meta.url));\n const workerPath = path.join(__dirname, \"daemon\", \"supervisor-worker.js\");\n const packageRoot = path.resolve(__dirname, \"..\");\n\n // Spawn as detached child process with stdio to log file\n const logDir = getSupervisorDir(name);\n await mkdir(logDir, { recursive: true });\n const logFd = openSync(path.join(logDir, \"daemon.log\"), \"a\");\n const child = spawn(process.execPath, [workerPath, name], {\n detached: true,\n stdio: [\"ignore\", logFd, logFd],\n cwd: packageRoot,\n env: process.env,\n });\n child.unref();\n closeSync(logFd);\n\n const config = await loadGlobalConfig();\n printSuccess(`Supervisor \"${name}\" started (PID ${child.pid})`);\n console.log(` Port: ${config.supervisor.port}`);\n console.log(` Health: curl localhost:${config.supervisor.port}/health`);\n console.log(` Webhook: curl -X POST localhost:${config.supervisor.port}/webhook -d '{}'`);\n console.log(` Logs: ${getSupervisorDir(name)}/daemon.log`);\n console.log(` TUI: neo supervise`);\n console.log(` Status: neo supervise --status`);\n console.log(` Stop: neo supervise --kill`);\n}\n\nasync function handleAttach(name: string): Promise<void> {\n const running = await isDaemonRunning(name);\n if (!running) {\n printError(`No supervisor daemon running (name: ${name}).`);\n printError(\"Start with: neo supervise\");\n process.exitCode = 1;\n return;\n }\n\n const { renderSupervisorTui } = await import(\"../tui/index.js\");\n await renderSupervisorTui(name);\n}\n\nasync function handleMessage(name: string, text: string): Promise<void> {\n const running = await isDaemonRunning(name);\n if (!running) {\n printError(`No supervisor daemon running (name: ${name}).`);\n process.exitCode = 1;\n return;\n }\n\n const id = randomUUID();\n const timestamp = new Date().toISOString();\n\n const message = { id, from: \"api\" as const, text, timestamp };\n await appendFile(getSupervisorInboxPath(name), `${JSON.stringify(message)}\\n`, \"utf-8\");\n\n // Write to activity.jsonl so the message appears in the TUI conversation\n const activityEntry = { id, type: \"message\", summary: text, timestamp };\n await appendFile(getSupervisorActivityPath(name), `${JSON.stringify(activityEntry)}\\n`, \"utf-8\");\n\n printSuccess(`Message sent to supervisor \"${name}\".`);\n}\n\nexport default defineCommand({\n meta: {\n name: \"supervise\",\n description: \"Manage the autonomous supervisor daemon\",\n },\n args: {\n name: {\n type: \"string\",\n description: \"Supervisor instance name\",\n default: DEFAULT_NAME,\n },\n status: {\n type: \"boolean\",\n description: \"Show supervisor status\",\n default: false,\n },\n kill: {\n type: \"boolean\",\n description: \"Stop the running supervisor\",\n default: false,\n },\n attach: {\n type: \"boolean\",\n description: \"Open the TUI for a running supervisor (default when no flags given)\",\n default: false,\n },\n detach: {\n type: \"boolean\",\n alias: \"d\",\n description: \"Start daemon in the background without opening the TUI\",\n default: false,\n },\n message: {\n type: \"string\",\n description: \"Send a message to the supervisor inbox\",\n },\n },\n async run({ args }) {\n const name = args.name;\n\n if (args.status) {\n await handleStatus(name);\n return;\n }\n\n if (args.kill) {\n await handleKill(name);\n return;\n }\n\n if (args.attach) {\n await handleAttach(name);\n return;\n }\n\n if (args.message) {\n await handleMessage(name, args.message);\n return;\n }\n\n // --detach: start daemon headless (no TUI)\n if (args.detach) {\n const alreadyRunning = await isDaemonRunning(name);\n if (alreadyRunning) {\n printSuccess(`Supervisor \"${name}\" already running (PID ${alreadyRunning.pid}).`);\n return;\n }\n await startDaemon(name);\n return;\n }\n\n // Default: start daemon if needed, then open TUI\n const alreadyRunning = await isDaemonRunning(name);\n if (!alreadyRunning) {\n await startDaemon(name);\n // Wait briefly for daemon to initialize before attaching\n await new Promise((r) => setTimeout(r, 1500));\n }\n await handleAttach(name);\n },\n});\n"],"mappings":"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","names":["lockPath","alreadyRunning"]}
|