@neotx/cli 0.1.0-alpha.2 → 0.1.0-alpha.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +383 -0
- package/dist/activity-LWUVGQVN.js +86 -0
- package/dist/activity-LWUVGQVN.js.map +1 -0
- package/dist/{agents-Y6LREFXP.js → agents-PH3P7G7E.js} +2 -2
- package/dist/{chunk-CP54H7WA.js → chunk-3ZP3BQXB.js} +6 -11
- package/dist/chunk-3ZP3BQXB.js.map +1 -0
- package/dist/{chunk-TNJOG54I.js → chunk-F622JUDY.js} +6 -2
- package/dist/{chunk-TNJOG54I.js.map → chunk-F622JUDY.js.map} +1 -1
- package/dist/config-NYF6AJXU.js +282 -0
- package/dist/config-NYF6AJXU.js.map +1 -0
- package/dist/{cost-DNGKT4UC.js → cost-OQGFNBBG.js} +3 -8
- package/dist/cost-OQGFNBBG.js.map +1 -0
- package/dist/daemon/supervisor-worker.js +7 -1
- package/dist/daemon/supervisor-worker.js.map +1 -1
- package/dist/daemon/worker.js +31 -12
- package/dist/daemon/worker.js.map +1 -1
- package/dist/decision-PNZ2S2TU.js +362 -0
- package/dist/decision-PNZ2S2TU.js.map +1 -0
- package/dist/doctor-ZBO73UID.js +337 -0
- package/dist/doctor-ZBO73UID.js.map +1 -0
- package/dist/guide-UQRNA3FC.js +23 -0
- package/dist/guide-UQRNA3FC.js.map +1 -0
- package/dist/index.js +17 -9
- package/dist/index.js.map +1 -1
- package/dist/{init-YNSPTCA3.js → init-UYS6KS5U.js} +4 -20
- package/dist/init-UYS6KS5U.js.map +1 -0
- package/dist/log-PTHLI7ZN.js +141 -0
- package/dist/log-PTHLI7ZN.js.map +1 -0
- package/dist/{mcp-GH6CCW7A.js → mcp-XHZND5A4.js} +6 -1
- package/dist/mcp-XHZND5A4.js.map +1 -0
- package/dist/memory-6R22DFS7.js +292 -0
- package/dist/memory-6R22DFS7.js.map +1 -0
- package/dist/{run-KIU2ZE72.js → run-OF53USMD.js} +46 -20
- package/dist/run-OF53USMD.js.map +1 -0
- package/dist/{runs-CHA2JM5K.js → runs-TAASM3YF.js} +16 -12
- package/dist/runs-TAASM3YF.js.map +1 -0
- package/dist/status-LQOFOJJI.js +90 -0
- package/dist/status-LQOFOJJI.js.map +1 -0
- package/dist/{supervise-KIB2EYY4.js → supervise-J3GYBSOC.js} +33 -28
- package/dist/supervise-J3GYBSOC.js.map +1 -0
- package/dist/supervisor-3RUX5SPH.js +16 -0
- package/dist/supervisor-3RUX5SPH.js.map +1 -0
- package/dist/{tui-QS3RPHKH.js → tui-RYLR4OLF.js} +378 -43
- package/dist/tui-RYLR4OLF.js.map +1 -0
- package/dist/version-XVOAMGDD.js +26 -0
- package/dist/version-XVOAMGDD.js.map +1 -0
- package/dist/webhooks-PUKAHFHE.js +151 -0
- package/dist/webhooks-PUKAHFHE.js.map +1 -0
- package/package.json +22 -4
- package/dist/chunk-CP54H7WA.js.map +0 -1
- package/dist/cost-DNGKT4UC.js.map +0 -1
- package/dist/doctor-GC4NH7H6.js +0 -173
- package/dist/doctor-GC4NH7H6.js.map +0 -1
- package/dist/init-YNSPTCA3.js.map +0 -1
- package/dist/mcp-GH6CCW7A.js.map +0 -1
- package/dist/run-KIU2ZE72.js.map +0 -1
- package/dist/runs-CHA2JM5K.js.map +0 -1
- package/dist/supervise-KIB2EYY4.js.map +0 -1
- package/dist/tui-QS3RPHKH.js.map +0 -1
- /package/dist/{agents-Y6LREFXP.js.map → agents-PH3P7G7E.js.map} +0 -0
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
import {
|
|
2
|
+
printError,
|
|
3
|
+
printJson,
|
|
4
|
+
printSuccess,
|
|
5
|
+
printTable
|
|
6
|
+
} from "./chunk-YQIWMDXL.js";
|
|
7
|
+
|
|
8
|
+
// src/commands/decision.ts
|
|
9
|
+
import { randomUUID } from "crypto";
|
|
10
|
+
import { appendFile, mkdir } from "fs/promises";
|
|
11
|
+
import path from "path";
|
|
12
|
+
import { DecisionStore, getSupervisorDecisionsPath, getSupervisorDir } from "@neotx/core";
|
|
13
|
+
import { defineCommand } from "citty";
|
|
14
|
+
var DEFAULT_EXPIRES_MS = 24 * 60 * 60 * 1e3;
|
|
15
|
+
function truncate(text, max) {
|
|
16
|
+
return text.length > max ? `${text.slice(0, max - 1)}\u2026` : text;
|
|
17
|
+
}
|
|
18
|
+
function formatStatus(decision) {
|
|
19
|
+
if (decision.answer !== void 0) {
|
|
20
|
+
return "answered";
|
|
21
|
+
}
|
|
22
|
+
if (decision.expiredAt !== void 0) {
|
|
23
|
+
return "expired";
|
|
24
|
+
}
|
|
25
|
+
if (decision.expiresAt && decision.expiresAt < (/* @__PURE__ */ new Date()).toISOString()) {
|
|
26
|
+
return "expired";
|
|
27
|
+
}
|
|
28
|
+
return "pending";
|
|
29
|
+
}
|
|
30
|
+
function formatTimeAgo(timestamp) {
|
|
31
|
+
const ms = Date.now() - new Date(timestamp).getTime();
|
|
32
|
+
const seconds = Math.floor(ms / 1e3);
|
|
33
|
+
if (seconds < 60) return `${seconds}s ago`;
|
|
34
|
+
const minutes = Math.floor(seconds / 60);
|
|
35
|
+
if (minutes < 60) return `${minutes}m ago`;
|
|
36
|
+
const hours = Math.floor(minutes / 60);
|
|
37
|
+
return `${hours}h ago`;
|
|
38
|
+
}
|
|
39
|
+
function parseDurationMs(input) {
|
|
40
|
+
const match = input.match(/^(\d+)(h|m|d)$/);
|
|
41
|
+
if (!match) return void 0;
|
|
42
|
+
const value = Number(match[1]);
|
|
43
|
+
const unit = match[2];
|
|
44
|
+
switch (unit) {
|
|
45
|
+
case "d":
|
|
46
|
+
return value * 24 * 60 * 60 * 1e3;
|
|
47
|
+
case "h":
|
|
48
|
+
return value * 60 * 60 * 1e3;
|
|
49
|
+
case "m":
|
|
50
|
+
return value * 60 * 1e3;
|
|
51
|
+
default:
|
|
52
|
+
return void 0;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
function parseOptions(optionsArg) {
|
|
56
|
+
if (!optionsArg.trim()) return void 0;
|
|
57
|
+
const options = [];
|
|
58
|
+
const parts = optionsArg.split(",");
|
|
59
|
+
for (const part of parts) {
|
|
60
|
+
const segments = part.trim().split(":");
|
|
61
|
+
const key = segments[0];
|
|
62
|
+
const label = segments[1];
|
|
63
|
+
if (!key || !label) {
|
|
64
|
+
throw new Error(
|
|
65
|
+
`Invalid option format: "${part}". Expected "key:label" or "key:label:description"`
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
const descParts = segments.slice(2);
|
|
69
|
+
options.push({
|
|
70
|
+
key: key.trim(),
|
|
71
|
+
label: label.trim(),
|
|
72
|
+
description: descParts.length > 0 ? descParts.join(":").trim() : void 0
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
return options.length > 0 ? options : void 0;
|
|
76
|
+
}
|
|
77
|
+
function openStore(name) {
|
|
78
|
+
const filePath = getSupervisorDecisionsPath(name);
|
|
79
|
+
return new DecisionStore(filePath);
|
|
80
|
+
}
|
|
81
|
+
async function handleCreate(args) {
|
|
82
|
+
if (!args.question) {
|
|
83
|
+
printError(
|
|
84
|
+
"Usage: neo decision create <question> --options 'key1:label1,key2:label2' [--default <key>] [--expires-in 24h]"
|
|
85
|
+
);
|
|
86
|
+
process.exitCode = 1;
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
let options;
|
|
90
|
+
if (args.options) {
|
|
91
|
+
try {
|
|
92
|
+
options = parseOptions(args.options);
|
|
93
|
+
} catch (error) {
|
|
94
|
+
printError(error instanceof Error ? error.message : String(error));
|
|
95
|
+
process.exitCode = 1;
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
let expiresAt;
|
|
100
|
+
if (args.expiresIn) {
|
|
101
|
+
const ms = parseDurationMs(args.expiresIn);
|
|
102
|
+
if (!ms) {
|
|
103
|
+
printError('Invalid --expires-in format. Use e.g. "24h", "30m", or "7d".');
|
|
104
|
+
process.exitCode = 1;
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
expiresAt = new Date(Date.now() + ms).toISOString();
|
|
108
|
+
} else {
|
|
109
|
+
expiresAt = new Date(Date.now() + DEFAULT_EXPIRES_MS).toISOString();
|
|
110
|
+
}
|
|
111
|
+
const store = openStore(args.name);
|
|
112
|
+
try {
|
|
113
|
+
const id = await store.create({
|
|
114
|
+
question: args.question,
|
|
115
|
+
options,
|
|
116
|
+
defaultAnswer: args.defaultAnswer,
|
|
117
|
+
expiresAt,
|
|
118
|
+
type: args.type ?? "generic",
|
|
119
|
+
source: "supervisor",
|
|
120
|
+
context: args.context
|
|
121
|
+
});
|
|
122
|
+
printSuccess(`Decision created: ${id}`);
|
|
123
|
+
console.log(id);
|
|
124
|
+
} catch (error) {
|
|
125
|
+
printError(
|
|
126
|
+
`Failed to create decision: ${error instanceof Error ? error.message : String(error)}`
|
|
127
|
+
);
|
|
128
|
+
process.exitCode = 1;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
async function handleList(args) {
|
|
132
|
+
const store = openStore(args.name);
|
|
133
|
+
const pending = await store.pending();
|
|
134
|
+
if (args.json) {
|
|
135
|
+
printJson(pending);
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
if (pending.length === 0) {
|
|
139
|
+
console.log("No pending decisions.");
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
printTable(
|
|
143
|
+
["ID", "TYPE", "QUESTION", "SOURCE", "CREATED"],
|
|
144
|
+
pending.map((d) => [
|
|
145
|
+
d.id.slice(0, 12),
|
|
146
|
+
d.type,
|
|
147
|
+
truncate(d.question, 50),
|
|
148
|
+
d.source,
|
|
149
|
+
formatTimeAgo(d.createdAt)
|
|
150
|
+
])
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
async function handleGet(args) {
|
|
154
|
+
if (!args.value) {
|
|
155
|
+
printError("Usage: neo decision get <id>");
|
|
156
|
+
process.exitCode = 1;
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
const store = openStore(args.name);
|
|
160
|
+
const decision = await store.get(args.value);
|
|
161
|
+
if (!decision) {
|
|
162
|
+
printError(`Decision not found: ${args.value}`);
|
|
163
|
+
process.exitCode = 1;
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
if (args.json) {
|
|
167
|
+
printJson(decision);
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
const status = formatStatus(decision);
|
|
171
|
+
console.log(`ID: ${decision.id}`);
|
|
172
|
+
console.log(`Status: ${status}`);
|
|
173
|
+
console.log(`Type: ${decision.type}`);
|
|
174
|
+
console.log(`Source: ${decision.source}`);
|
|
175
|
+
console.log(`Created: ${decision.createdAt}`);
|
|
176
|
+
console.log();
|
|
177
|
+
console.log(`Question: ${decision.question}`);
|
|
178
|
+
if (decision.context) {
|
|
179
|
+
console.log();
|
|
180
|
+
console.log(`Context:
|
|
181
|
+
${decision.context}`);
|
|
182
|
+
}
|
|
183
|
+
if (decision.options && decision.options.length > 0) {
|
|
184
|
+
console.log();
|
|
185
|
+
console.log("Options:");
|
|
186
|
+
for (const opt of decision.options) {
|
|
187
|
+
console.log(` [${opt.key}] ${opt.label}${opt.description ? ` - ${opt.description}` : ""}`);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
if (decision.answer !== void 0) {
|
|
191
|
+
console.log();
|
|
192
|
+
console.log(`Answer: ${decision.answer}`);
|
|
193
|
+
if (decision.answeredAt) {
|
|
194
|
+
console.log(`Answered: ${decision.answeredAt}`);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
if (decision.defaultAnswer !== void 0) {
|
|
198
|
+
console.log(`Default: ${decision.defaultAnswer}`);
|
|
199
|
+
}
|
|
200
|
+
if (decision.expiresAt) {
|
|
201
|
+
console.log(`Expires: ${decision.expiresAt}`);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
async function handleAnswer(args) {
|
|
205
|
+
const argv = process.argv;
|
|
206
|
+
const answerIdx = argv.indexOf("answer");
|
|
207
|
+
const idArg = argv[answerIdx + 1];
|
|
208
|
+
const answerArg = argv[answerIdx + 2];
|
|
209
|
+
if (!idArg || !answerArg) {
|
|
210
|
+
printError("Usage: neo decision answer <id> <answer>");
|
|
211
|
+
process.exitCode = 1;
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
const store = openStore(args.name);
|
|
215
|
+
try {
|
|
216
|
+
await store.answer(idArg, answerArg);
|
|
217
|
+
const dir = getSupervisorDir(args.name);
|
|
218
|
+
const inboxMessage = {
|
|
219
|
+
id: randomUUID(),
|
|
220
|
+
from: "external",
|
|
221
|
+
text: `decision:answer ${idArg} ${answerArg}`,
|
|
222
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
223
|
+
};
|
|
224
|
+
const inboxPath = path.join(dir, "inbox.jsonl");
|
|
225
|
+
try {
|
|
226
|
+
await mkdir(dir, { recursive: true });
|
|
227
|
+
await appendFile(inboxPath, `${JSON.stringify(inboxMessage)}
|
|
228
|
+
`, "utf-8");
|
|
229
|
+
} catch (error) {
|
|
230
|
+
console.error(
|
|
231
|
+
`Warning: Failed to write to inbox: ${error instanceof Error ? error.message : String(error)}`
|
|
232
|
+
);
|
|
233
|
+
}
|
|
234
|
+
printSuccess(`Decision answered: ${idArg} \u2192 "${answerArg}"`);
|
|
235
|
+
} catch (error) {
|
|
236
|
+
printError(error instanceof Error ? error.message : "Unknown error");
|
|
237
|
+
process.exitCode = 1;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
async function handlePending(args) {
|
|
241
|
+
const store = openStore(args.name);
|
|
242
|
+
const pending = await store.pending();
|
|
243
|
+
if (args.json) {
|
|
244
|
+
printJson(pending);
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
if (pending.length === 0) {
|
|
248
|
+
console.log("No pending decisions.");
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
for (const d of pending) {
|
|
252
|
+
console.log(`\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500`);
|
|
253
|
+
console.log(`ID: ${d.id} (${formatTimeAgo(d.createdAt)})`);
|
|
254
|
+
console.log(`Question: ${d.question}`);
|
|
255
|
+
if (d.options && d.options.length > 0) {
|
|
256
|
+
console.log("Options:");
|
|
257
|
+
for (const opt of d.options) {
|
|
258
|
+
console.log(` [${opt.key}] ${opt.label}`);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
if (d.defaultAnswer) {
|
|
262
|
+
console.log(`Default: ${d.defaultAnswer}`);
|
|
263
|
+
}
|
|
264
|
+
console.log();
|
|
265
|
+
}
|
|
266
|
+
console.log(`\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500`);
|
|
267
|
+
console.log(`
|
|
268
|
+
Answer with: neo decision answer <id> <answer>`);
|
|
269
|
+
}
|
|
270
|
+
var decision_default = defineCommand({
|
|
271
|
+
meta: {
|
|
272
|
+
name: "decision",
|
|
273
|
+
description: "Manage supervisor decision gates"
|
|
274
|
+
},
|
|
275
|
+
args: {
|
|
276
|
+
action: {
|
|
277
|
+
type: "positional",
|
|
278
|
+
description: "Action: create, list, get, answer, pending",
|
|
279
|
+
required: true
|
|
280
|
+
},
|
|
281
|
+
value: {
|
|
282
|
+
type: "positional",
|
|
283
|
+
description: "Decision ID (for get/answer) or question text (for create)",
|
|
284
|
+
required: false
|
|
285
|
+
},
|
|
286
|
+
options: {
|
|
287
|
+
type: "string",
|
|
288
|
+
alias: "o",
|
|
289
|
+
description: 'Options in format "key1:label1,key2:label2" or "key1:label1:desc1,key2:label2:desc2"'
|
|
290
|
+
},
|
|
291
|
+
"default-answer": {
|
|
292
|
+
type: "string",
|
|
293
|
+
alias: "d",
|
|
294
|
+
description: "Default answer key (used if decision expires)"
|
|
295
|
+
},
|
|
296
|
+
"expires-in": {
|
|
297
|
+
type: "string",
|
|
298
|
+
alias: "e",
|
|
299
|
+
description: "Expiration duration (e.g. 24h, 30m, 7d). Default: 24h"
|
|
300
|
+
},
|
|
301
|
+
type: {
|
|
302
|
+
type: "string",
|
|
303
|
+
alias: "t",
|
|
304
|
+
description: "Decision type (default: generic)"
|
|
305
|
+
},
|
|
306
|
+
context: {
|
|
307
|
+
type: "string",
|
|
308
|
+
alias: "c",
|
|
309
|
+
description: "Additional context for the decision"
|
|
310
|
+
},
|
|
311
|
+
name: {
|
|
312
|
+
type: "string",
|
|
313
|
+
description: "Supervisor name",
|
|
314
|
+
default: "supervisor"
|
|
315
|
+
},
|
|
316
|
+
json: {
|
|
317
|
+
type: "boolean",
|
|
318
|
+
description: "Output as JSON",
|
|
319
|
+
default: false
|
|
320
|
+
}
|
|
321
|
+
},
|
|
322
|
+
async run({ args }) {
|
|
323
|
+
const action = args.action;
|
|
324
|
+
const parsed = {
|
|
325
|
+
action,
|
|
326
|
+
value: args.value,
|
|
327
|
+
question: args.value,
|
|
328
|
+
// For create action
|
|
329
|
+
options: args.options,
|
|
330
|
+
defaultAnswer: args["default-answer"],
|
|
331
|
+
expiresIn: args["expires-in"],
|
|
332
|
+
type: args.type,
|
|
333
|
+
context: args.context,
|
|
334
|
+
name: args.name,
|
|
335
|
+
id: args.value,
|
|
336
|
+
// For get/answer actions
|
|
337
|
+
answer: void 0,
|
|
338
|
+
json: args.json
|
|
339
|
+
};
|
|
340
|
+
switch (action) {
|
|
341
|
+
case "create":
|
|
342
|
+
return handleCreate(parsed);
|
|
343
|
+
case "list":
|
|
344
|
+
return handleList(parsed);
|
|
345
|
+
case "get":
|
|
346
|
+
return handleGet(parsed);
|
|
347
|
+
case "answer":
|
|
348
|
+
return handleAnswer(parsed);
|
|
349
|
+
case "pending":
|
|
350
|
+
return handlePending(parsed);
|
|
351
|
+
default:
|
|
352
|
+
printError(
|
|
353
|
+
`Unknown action "${action}". Must be one of: create, list, get, answer, pending`
|
|
354
|
+
);
|
|
355
|
+
process.exitCode = 1;
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
});
|
|
359
|
+
export {
|
|
360
|
+
decision_default as default
|
|
361
|
+
};
|
|
362
|
+
//# sourceMappingURL=decision-PNZ2S2TU.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}\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":[]}
|