@neotx/cli 0.1.0-alpha.22 → 0.1.0-alpha.24

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.
@@ -78,6 +78,23 @@ function openStore(name) {
78
78
  const filePath = getSupervisorDecisionsPath(name);
79
79
  return new DecisionStore(filePath);
80
80
  }
81
+ async function pollForAnswer(store, id, timeout) {
82
+ const timeoutMs = parseDurationMs(timeout) ?? 30 * 60 * 1e3;
83
+ const startTime = Date.now();
84
+ const pollIntervalMs = 1e4;
85
+ process.stdout.write(`Waiting for answer (timeout: ${timeout})...
86
+ `);
87
+ while (Date.now() - startTime < timeoutMs) {
88
+ const decision = await store.get(id);
89
+ if (decision?.answer !== void 0) {
90
+ console.log(`Answer: ${decision.answer}`);
91
+ return;
92
+ }
93
+ await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));
94
+ }
95
+ printError(`Decision ${id} timed out after ${timeout}`);
96
+ process.exitCode = 1;
97
+ }
81
98
  async function handleCreate(args) {
82
99
  if (!args.question) {
83
100
  printError(
@@ -121,6 +138,9 @@ async function handleCreate(args) {
121
138
  });
122
139
  printSuccess(`Decision created: ${id}`);
123
140
  console.log(id);
141
+ if (args.wait) {
142
+ await pollForAnswer(store, id, args.timeout);
143
+ }
124
144
  } catch (error) {
125
145
  printError(
126
146
  `Failed to create decision: ${error instanceof Error ? error.message : String(error)}`
@@ -317,6 +337,17 @@ var decision_default = defineCommand({
317
337
  type: "boolean",
318
338
  description: "Output as JSON",
319
339
  default: false
340
+ },
341
+ wait: {
342
+ type: "boolean",
343
+ alias: "w",
344
+ description: "Block until the decision is answered (poll every 10s)",
345
+ default: false
346
+ },
347
+ timeout: {
348
+ type: "string",
349
+ description: "Max wait time when using --wait (e.g. 30m, 1h). Default: 30m",
350
+ default: "30m"
320
351
  }
321
352
  },
322
353
  async run({ args }) {
@@ -335,7 +366,9 @@ var decision_default = defineCommand({
335
366
  id: args.value,
336
367
  // For get/answer actions
337
368
  answer: void 0,
338
- json: args.json
369
+ json: args.json,
370
+ wait: args.wait,
371
+ timeout: args.timeout
339
372
  };
340
373
  switch (action) {
341
374
  case "create":
@@ -359,4 +392,4 @@ var decision_default = defineCommand({
359
392
  export {
360
393
  decision_default as default
361
394
  };
362
- //# sourceMappingURL=decision-PNZ2S2TU.js.map
395
+ //# sourceMappingURL=decision-T2526ITK.js.map
@@ -0,0 +1 @@
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 wait: boolean;\n timeout: string;\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 pollForAnswer(store: DecisionStore, id: string, timeout: string): Promise<void> {\n const timeoutMs = parseDurationMs(timeout) ?? 30 * 60 * 1000;\n const startTime = Date.now();\n const pollIntervalMs = 10_000;\n\n process.stdout.write(`Waiting for answer (timeout: ${timeout})...\\n`);\n\n while (Date.now() - startTime < timeoutMs) {\n const decision = await store.get(id);\n if (decision?.answer !== undefined) {\n console.log(`Answer: ${decision.answer}`);\n return;\n }\n await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));\n }\n\n printError(`Decision ${id} timed out after ${timeout}`);\n process.exitCode = 1;\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\n if (args.wait) {\n await pollForAnswer(store, id, args.timeout);\n }\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 wait: {\n type: \"boolean\",\n alias: \"w\",\n description: \"Block until the decision is answered (poll every 10s)\",\n default: false,\n },\n timeout: {\n type: \"string\",\n description: \"Max wait time when using --wait (e.g. 30m, 1h). Default: 30m\",\n default: \"30m\",\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 wait: args.wait as boolean,\n timeout: args.timeout as string,\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":[]}
@@ -0,0 +1,72 @@
1
+ // src/commands/health.ts
2
+ import { execFile } from "child_process";
3
+ import { promisify } from "util";
4
+ import { loadGlobalConfig } from "@neotx/core";
5
+ import { defineCommand } from "citty";
6
+ var execFileAsync = promisify(execFile);
7
+ var CLAUDE_TIMEOUT_MS = 5e3;
8
+ async function checkConfig() {
9
+ try {
10
+ await loadGlobalConfig();
11
+ return { ok: true };
12
+ } catch (err) {
13
+ return {
14
+ ok: false,
15
+ error: err instanceof Error ? err.message : String(err)
16
+ };
17
+ }
18
+ }
19
+ async function checkGit() {
20
+ try {
21
+ const { stdout } = await execFileAsync("git", ["--version"]);
22
+ const match = stdout.match(/git version (\d+\.\d+(?:\.\d+)?)/);
23
+ return { ok: true, version: match?.[1] ?? "unknown" };
24
+ } catch (err) {
25
+ return {
26
+ ok: false,
27
+ error: err instanceof Error ? err.message : String(err)
28
+ };
29
+ }
30
+ }
31
+ async function checkClaude() {
32
+ const controller = new AbortController();
33
+ const timeout = setTimeout(() => controller.abort(), CLAUDE_TIMEOUT_MS);
34
+ try {
35
+ const { stdout } = await execFileAsync("claude", ["--version"], {
36
+ signal: controller.signal
37
+ });
38
+ const version = stdout.trim();
39
+ return { ok: true, version };
40
+ } catch (err) {
41
+ if (err instanceof Error && err.name === "AbortError") {
42
+ return { ok: false, error: `timeout after ${CLAUDE_TIMEOUT_MS}ms` };
43
+ }
44
+ return {
45
+ ok: false,
46
+ error: err instanceof Error ? err.message : String(err)
47
+ };
48
+ } finally {
49
+ clearTimeout(timeout);
50
+ }
51
+ }
52
+ var health_default = defineCommand({
53
+ meta: {
54
+ name: "health",
55
+ description: "Quick health check: config, git, Claude SDK (JSON output)"
56
+ },
57
+ async run() {
58
+ const [config, git, claude] = await Promise.all([checkConfig(), checkGit(), checkClaude()]);
59
+ const summary = {
60
+ ok: config.ok && git.ok && claude.ok,
61
+ checks: { config, git, claude }
62
+ };
63
+ console.log(JSON.stringify(summary, null, 2));
64
+ if (!summary.ok) {
65
+ process.exitCode = 1;
66
+ }
67
+ }
68
+ });
69
+ export {
70
+ health_default as default
71
+ };
72
+ //# sourceMappingURL=health-SWQ6V4H5.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/health.ts"],"sourcesContent":["import { execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport { loadGlobalConfig } from \"@neotx/core\";\nimport { defineCommand } from \"citty\";\n\nconst execFileAsync = promisify(execFile);\n\nconst CLAUDE_TIMEOUT_MS = 5000;\n\ninterface CheckResult {\n ok: boolean;\n version?: string;\n error?: string;\n}\n\ninterface HealthSummary {\n ok: boolean;\n checks: {\n config: CheckResult;\n git: CheckResult;\n claude: CheckResult;\n };\n}\n\nasync function checkConfig(): Promise<CheckResult> {\n try {\n await loadGlobalConfig();\n return { ok: true };\n } catch (err) {\n return {\n ok: false,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n}\n\nasync function checkGit(): Promise<CheckResult> {\n try {\n const { stdout } = await execFileAsync(\"git\", [\"--version\"]);\n // Handle both \"2.25.1\" and \"2.25\" version formats\n const match = stdout.match(/git version (\\d+\\.\\d+(?:\\.\\d+)?)/);\n return { ok: true, version: match?.[1] ?? \"unknown\" };\n } catch (err) {\n return {\n ok: false,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n}\n\nasync function checkClaude(): Promise<CheckResult> {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), CLAUDE_TIMEOUT_MS);\n\n try {\n const { stdout } = await execFileAsync(\"claude\", [\"--version\"], {\n signal: controller.signal,\n });\n\n const version = stdout.trim();\n return { ok: true, version };\n } catch (err) {\n if (err instanceof Error && err.name === \"AbortError\") {\n return { ok: false, error: `timeout after ${CLAUDE_TIMEOUT_MS}ms` };\n }\n return {\n ok: false,\n error: err instanceof Error ? err.message : String(err),\n };\n } finally {\n clearTimeout(timeout);\n }\n}\n\nexport default defineCommand({\n meta: {\n name: \"health\",\n description: \"Quick health check: config, git, Claude SDK (JSON output)\",\n },\n async run() {\n const [config, git, claude] = await Promise.all([checkConfig(), checkGit(), checkClaude()]);\n\n const summary: HealthSummary = {\n ok: config.ok && git.ok && claude.ok,\n checks: { config, git, claude },\n };\n\n console.log(JSON.stringify(summary, null, 2));\n\n // Use process.exitCode (not process.exit) to allow proper cleanup\n if (!summary.ok) {\n process.exitCode = 1;\n }\n },\n});\n"],"mappings":";AAAA,SAAS,gBAAgB;AACzB,SAAS,iBAAiB;AAC1B,SAAS,wBAAwB;AACjC,SAAS,qBAAqB;AAE9B,IAAM,gBAAgB,UAAU,QAAQ;AAExC,IAAM,oBAAoB;AAiB1B,eAAe,cAAoC;AACjD,MAAI;AACF,UAAM,iBAAiB;AACvB,WAAO,EAAE,IAAI,KAAK;AAAA,EACpB,SAAS,KAAK;AACZ,WAAO;AAAA,MACL,IAAI;AAAA,MACJ,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,IACxD;AAAA,EACF;AACF;AAEA,eAAe,WAAiC;AAC9C,MAAI;AACF,UAAM,EAAE,OAAO,IAAI,MAAM,cAAc,OAAO,CAAC,WAAW,CAAC;AAE3D,UAAM,QAAQ,OAAO,MAAM,kCAAkC;AAC7D,WAAO,EAAE,IAAI,MAAM,SAAS,QAAQ,CAAC,KAAK,UAAU;AAAA,EACtD,SAAS,KAAK;AACZ,WAAO;AAAA,MACL,IAAI;AAAA,MACJ,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,IACxD;AAAA,EACF;AACF;AAEA,eAAe,cAAoC;AACjD,QAAM,aAAa,IAAI,gBAAgB;AACvC,QAAM,UAAU,WAAW,MAAM,WAAW,MAAM,GAAG,iBAAiB;AAEtE,MAAI;AACF,UAAM,EAAE,OAAO,IAAI,MAAM,cAAc,UAAU,CAAC,WAAW,GAAG;AAAA,MAC9D,QAAQ,WAAW;AAAA,IACrB,CAAC;AAED,UAAM,UAAU,OAAO,KAAK;AAC5B,WAAO,EAAE,IAAI,MAAM,QAAQ;AAAA,EAC7B,SAAS,KAAK;AACZ,QAAI,eAAe,SAAS,IAAI,SAAS,cAAc;AACrD,aAAO,EAAE,IAAI,OAAO,OAAO,iBAAiB,iBAAiB,KAAK;AAAA,IACpE;AACA,WAAO;AAAA,MACL,IAAI;AAAA,MACJ,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,IACxD;AAAA,EACF,UAAE;AACA,iBAAa,OAAO;AAAA,EACtB;AACF;AAEA,IAAO,iBAAQ,cAAc;AAAA,EAC3B,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA,EACf;AAAA,EACA,MAAM,MAAM;AACV,UAAM,CAAC,QAAQ,KAAK,MAAM,IAAI,MAAM,QAAQ,IAAI,CAAC,YAAY,GAAG,SAAS,GAAG,YAAY,CAAC,CAAC;AAE1F,UAAM,UAAyB;AAAA,MAC7B,IAAI,OAAO,MAAM,IAAI,MAAM,OAAO;AAAA,MAClC,QAAQ,EAAE,QAAQ,KAAK,OAAO;AAAA,IAChC;AAEA,YAAQ,IAAI,KAAK,UAAU,SAAS,MAAM,CAAC,CAAC;AAG5C,QAAI,CAAC,QAAQ,IAAI;AACf,cAAQ,WAAW;AAAA,IACrB;AAAA,EACF;AACF,CAAC;","names":[]}
package/dist/index.js CHANGED
@@ -10,7 +10,7 @@ var main = defineCommand({
10
10
  subCommands: {
11
11
  init: () => import("./init-OE4LAB6S.js").then((m) => m.default),
12
12
  run: () => import("./run-MWHIQUSY.js").then((m) => m.default),
13
- decision: () => import("./decision-PNZ2S2TU.js").then((m) => m.default),
13
+ decision: () => import("./decision-T2526ITK.js").then((m) => m.default),
14
14
  runs: () => import("./runs-CMLDYH7M.js").then((m) => m.default),
15
15
  log: () => import("./log-PTHLI7ZN.js").then((m) => m.default),
16
16
  logs: () => import("./logs-AWNAMMJC.js").then((m) => m.default),
@@ -23,6 +23,7 @@ var main = defineCommand({
23
23
  memory: () => import("./memory-SDZ57W2S.js").then((m) => m.default),
24
24
  mcp: () => import("./mcp-XHZND5A4.js").then((m) => m.default),
25
25
  guide: () => import("./guide-UQRNA3FC.js").then((m) => m.default),
26
+ health: () => import("./health-SWQ6V4H5.js").then((m) => m.default),
26
27
  doctor: () => import("./doctor-ZBO73UID.js").then((m) => m.default),
27
28
  version: () => import("./version-XVOAMGDD.js").then((m) => m.default),
28
29
  webhooks: () => import("./webhooks-PUKAHFHE.js").then((m) => m.default)
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { defineCommand, runMain } from \"citty\";\n\nconst main = defineCommand({\n meta: {\n name: \"neo\",\n version: \"0.1.0\",\n description:\n \"Orchestrate autonomous developer agents with clone isolation, budget guards, and 3-level recovery. Run 'neo init' to get started.\",\n },\n subCommands: {\n init: () => import(\"./commands/init.js\").then((m) => m.default),\n run: () => import(\"./commands/run.js\").then((m) => m.default),\n decision: () => import(\"./commands/decision.js\").then((m) => m.default),\n runs: () => import(\"./commands/runs.js\").then((m) => m.default),\n log: () => import(\"./commands/log.js\").then((m) => m.default),\n logs: () => import(\"./commands/logs.js\").then((m) => m.default),\n cost: () => import(\"./commands/cost.js\").then((m) => m.default),\n config: () => import(\"./commands/config.js\").then((m) => m.default),\n repos: () => import(\"./commands/repos.js\").then((m) => m.default),\n agents: () => import(\"./commands/agents.js\").then((m) => m.default),\n supervise: () => import(\"./commands/supervise.js\").then((m) => m.default),\n supervisor: () => import(\"./commands/supervisor/index.js\").then((m) => m.default),\n memory: () => import(\"./commands/memory.js\").then((m) => m.default),\n mcp: () => import(\"./commands/mcp.js\").then((m) => m.default),\n guide: () => import(\"./commands/guide.js\").then((m) => m.default),\n doctor: () => import(\"./commands/doctor.js\").then((m) => m.default),\n version: () => import(\"./commands/version.js\").then((m) => m.default),\n webhooks: () => import(\"./commands/webhooks.js\").then((m) => m.default),\n },\n});\n\nrunMain(main);\n"],"mappings":";AAAA,SAAS,eAAe,eAAe;AAEvC,IAAM,OAAO,cAAc;AAAA,EACzB,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,SAAS;AAAA,IACT,aACE;AAAA,EACJ;AAAA,EACA,aAAa;AAAA,IACX,MAAM,MAAM,OAAO,oBAAoB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,IAC9D,KAAK,MAAM,OAAO,mBAAmB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,IAC5D,UAAU,MAAM,OAAO,wBAAwB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,IACtE,MAAM,MAAM,OAAO,oBAAoB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,IAC9D,KAAK,MAAM,OAAO,mBAAmB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,IAC5D,MAAM,MAAM,OAAO,oBAAoB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,IAC9D,MAAM,MAAM,OAAO,oBAAoB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,IAC9D,QAAQ,MAAM,OAAO,sBAAsB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,IAClE,OAAO,MAAM,OAAO,qBAAqB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,IAChE,QAAQ,MAAM,OAAO,sBAAsB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,IAClE,WAAW,MAAM,OAAO,yBAAyB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,IACxE,YAAY,MAAM,OAAO,0BAAgC,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,IAChF,QAAQ,MAAM,OAAO,sBAAsB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,IAClE,KAAK,MAAM,OAAO,mBAAmB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,IAC5D,OAAO,MAAM,OAAO,qBAAqB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,IAChE,QAAQ,MAAM,OAAO,sBAAsB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,IAClE,SAAS,MAAM,OAAO,uBAAuB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,IACpE,UAAU,MAAM,OAAO,wBAAwB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,EACxE;AACF,CAAC;AAED,QAAQ,IAAI;","names":[]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { defineCommand, runMain } from \"citty\";\n\nconst main = defineCommand({\n meta: {\n name: \"neo\",\n version: \"0.1.0\",\n description:\n \"Orchestrate autonomous developer agents with clone isolation, budget guards, and 3-level recovery. Run 'neo init' to get started.\",\n },\n subCommands: {\n init: () => import(\"./commands/init.js\").then((m) => m.default),\n run: () => import(\"./commands/run.js\").then((m) => m.default),\n decision: () => import(\"./commands/decision.js\").then((m) => m.default),\n runs: () => import(\"./commands/runs.js\").then((m) => m.default),\n log: () => import(\"./commands/log.js\").then((m) => m.default),\n logs: () => import(\"./commands/logs.js\").then((m) => m.default),\n cost: () => import(\"./commands/cost.js\").then((m) => m.default),\n config: () => import(\"./commands/config.js\").then((m) => m.default),\n repos: () => import(\"./commands/repos.js\").then((m) => m.default),\n agents: () => import(\"./commands/agents.js\").then((m) => m.default),\n supervise: () => import(\"./commands/supervise.js\").then((m) => m.default),\n supervisor: () => import(\"./commands/supervisor/index.js\").then((m) => m.default),\n memory: () => import(\"./commands/memory.js\").then((m) => m.default),\n mcp: () => import(\"./commands/mcp.js\").then((m) => m.default),\n guide: () => import(\"./commands/guide.js\").then((m) => m.default),\n health: () => import(\"./commands/health.js\").then((m) => m.default),\n doctor: () => import(\"./commands/doctor.js\").then((m) => m.default),\n version: () => import(\"./commands/version.js\").then((m) => m.default),\n webhooks: () => import(\"./commands/webhooks.js\").then((m) => m.default),\n },\n});\n\nrunMain(main);\n"],"mappings":";AAAA,SAAS,eAAe,eAAe;AAEvC,IAAM,OAAO,cAAc;AAAA,EACzB,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,SAAS;AAAA,IACT,aACE;AAAA,EACJ;AAAA,EACA,aAAa;AAAA,IACX,MAAM,MAAM,OAAO,oBAAoB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,IAC9D,KAAK,MAAM,OAAO,mBAAmB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,IAC5D,UAAU,MAAM,OAAO,wBAAwB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,IACtE,MAAM,MAAM,OAAO,oBAAoB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,IAC9D,KAAK,MAAM,OAAO,mBAAmB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,IAC5D,MAAM,MAAM,OAAO,oBAAoB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,IAC9D,MAAM,MAAM,OAAO,oBAAoB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,IAC9D,QAAQ,MAAM,OAAO,sBAAsB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,IAClE,OAAO,MAAM,OAAO,qBAAqB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,IAChE,QAAQ,MAAM,OAAO,sBAAsB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,IAClE,WAAW,MAAM,OAAO,yBAAyB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,IACxE,YAAY,MAAM,OAAO,0BAAgC,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,IAChF,QAAQ,MAAM,OAAO,sBAAsB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,IAClE,KAAK,MAAM,OAAO,mBAAmB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,IAC5D,OAAO,MAAM,OAAO,qBAAqB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,IAChE,QAAQ,MAAM,OAAO,sBAAsB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,IAClE,QAAQ,MAAM,OAAO,sBAAsB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,IAClE,SAAS,MAAM,OAAO,uBAAuB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,IACpE,UAAU,MAAM,OAAO,wBAAwB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,EACxE;AACF,CAAC;AAED,QAAQ,IAAI;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neotx/cli",
3
- "version": "0.1.0-alpha.22",
3
+ "version": "0.1.0-alpha.24",
4
4
  "description": "CLI for the Neo orchestration framework",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -51,8 +51,8 @@
51
51
  "ink-text-input": "^6.0.0",
52
52
  "react": "^19.2.4",
53
53
  "yaml": "^2.8.2",
54
- "@neotx/agents": "0.1.0-alpha.22",
55
- "@neotx/core": "0.1.0-alpha.22"
54
+ "@neotx/agents": "0.1.0-alpha.24",
55
+ "@neotx/core": "0.1.0-alpha.24"
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":[]}