@neotx/cli 0.1.0-alpha.2 → 0.1.0-alpha.4

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.
Files changed (46) hide show
  1. package/README.md +381 -0
  2. package/dist/{agents-Y6LREFXP.js → agents-PH3P7G7E.js} +2 -2
  3. package/dist/{chunk-CP54H7WA.js → chunk-3ZP3BQXB.js} +6 -11
  4. package/dist/chunk-3ZP3BQXB.js.map +1 -0
  5. package/dist/{chunk-TNJOG54I.js → chunk-F622JUDY.js} +6 -2
  6. package/dist/{chunk-TNJOG54I.js.map → chunk-F622JUDY.js.map} +1 -1
  7. package/dist/{cost-DNGKT4UC.js → cost-OQGFNBBG.js} +3 -8
  8. package/dist/cost-OQGFNBBG.js.map +1 -0
  9. package/dist/daemon/supervisor-worker.js +7 -1
  10. package/dist/daemon/supervisor-worker.js.map +1 -1
  11. package/dist/daemon/worker.js +25 -0
  12. package/dist/daemon/worker.js.map +1 -1
  13. package/dist/doctor-ZBO73UID.js +337 -0
  14. package/dist/doctor-ZBO73UID.js.map +1 -0
  15. package/dist/index.js +12 -9
  16. package/dist/index.js.map +1 -1
  17. package/dist/{init-YNSPTCA3.js → init-UYS6KS5U.js} +4 -20
  18. package/dist/init-UYS6KS5U.js.map +1 -0
  19. package/dist/log-PTHLI7ZN.js +141 -0
  20. package/dist/log-PTHLI7ZN.js.map +1 -0
  21. package/dist/{mcp-GH6CCW7A.js → mcp-XHZND5A4.js} +6 -1
  22. package/dist/mcp-XHZND5A4.js.map +1 -0
  23. package/dist/memory-6R22DFS7.js +292 -0
  24. package/dist/memory-6R22DFS7.js.map +1 -0
  25. package/dist/{run-KIU2ZE72.js → run-GJLDWPUE.js} +32 -9
  26. package/dist/run-GJLDWPUE.js.map +1 -0
  27. package/dist/{runs-CHA2JM5K.js → runs-LOYOWU55.js} +9 -10
  28. package/dist/runs-LOYOWU55.js.map +1 -0
  29. package/dist/{supervise-KIB2EYY4.js → supervise-LVCGVYA4.js} +33 -28
  30. package/dist/supervise-LVCGVYA4.js.map +1 -0
  31. package/dist/{tui-QS3RPHKH.js → tui-6USVDV75.js} +100 -33
  32. package/dist/tui-6USVDV75.js.map +1 -0
  33. package/dist/version-XVOAMGDD.js +26 -0
  34. package/dist/version-XVOAMGDD.js.map +1 -0
  35. package/package.json +22 -4
  36. package/dist/chunk-CP54H7WA.js.map +0 -1
  37. package/dist/cost-DNGKT4UC.js.map +0 -1
  38. package/dist/doctor-GC4NH7H6.js +0 -173
  39. package/dist/doctor-GC4NH7H6.js.map +0 -1
  40. package/dist/init-YNSPTCA3.js.map +0 -1
  41. package/dist/mcp-GH6CCW7A.js.map +0 -1
  42. package/dist/run-KIU2ZE72.js.map +0 -1
  43. package/dist/runs-CHA2JM5K.js.map +0 -1
  44. package/dist/supervise-KIB2EYY4.js.map +0 -1
  45. package/dist/tui-QS3RPHKH.js.map +0 -1
  46. /package/dist/{agents-Y6LREFXP.js.map → agents-PH3P7G7E.js.map} +0 -0
@@ -17,6 +17,7 @@ var MCP_PRESETS = {
17
17
  type: "stdio",
18
18
  command: "npx",
19
19
  args: ["-y", "@anthropic/linear-mcp-server"],
20
+ // biome-ignore lint/suspicious/noTemplateCurlyInString: Template placeholder interpolated at runtime by Claude Code
20
21
  env: { LINEAR_API_KEY: "${LINEAR_API_KEY}" }
21
22
  },
22
23
  envVars: ["LINEAR_API_KEY"]
@@ -26,6 +27,7 @@ var MCP_PRESETS = {
26
27
  type: "stdio",
27
28
  command: "npx",
28
29
  args: ["-y", "@notionhq/notion-mcp-server"],
30
+ // biome-ignore lint/suspicious/noTemplateCurlyInString: Template placeholder interpolated at runtime by Claude Code
29
31
  env: { NOTION_TOKEN: "${NOTION_TOKEN}" }
30
32
  },
31
33
  envVars: ["NOTION_TOKEN"]
@@ -35,6 +37,7 @@ var MCP_PRESETS = {
35
37
  type: "stdio",
36
38
  command: "npx",
37
39
  args: ["-y", "@modelcontextprotocol/server-github"],
40
+ // biome-ignore lint/suspicious/noTemplateCurlyInString: Template placeholder interpolated at runtime by Claude Code
38
41
  env: { GITHUB_PERSONAL_ACCESS_TOKEN: "${GITHUB_TOKEN}" }
39
42
  },
40
43
  envVars: ["GITHUB_TOKEN"]
@@ -44,6 +47,7 @@ var MCP_PRESETS = {
44
47
  type: "stdio",
45
48
  command: "npx",
46
49
  args: ["-y", "@anthropic/jira-mcp-server"],
50
+ // biome-ignore lint/suspicious/noTemplateCurlyInString: Template placeholders interpolated at runtime by Claude Code
47
51
  env: { JIRA_API_TOKEN: "${JIRA_API_TOKEN}", JIRA_URL: "${JIRA_URL}" }
48
52
  },
49
53
  envVars: ["JIRA_API_TOKEN", "JIRA_URL"]
@@ -53,6 +57,7 @@ var MCP_PRESETS = {
53
57
  type: "stdio",
54
58
  command: "npx",
55
59
  args: ["-y", "@modelcontextprotocol/server-slack"],
60
+ // biome-ignore lint/suspicious/noTemplateCurlyInString: Template placeholder interpolated at runtime by Claude Code
56
61
  env: { SLACK_BOT_TOKEN: "${SLACK_BOT_TOKEN}" }
57
62
  },
58
63
  envVars: ["SLACK_BOT_TOKEN"]
@@ -214,4 +219,4 @@ var mcp_default = defineCommand({
214
219
  export {
215
220
  mcp_default as default
216
221
  };
217
- //# sourceMappingURL=mcp-GH6CCW7A.js.map
222
+ //# sourceMappingURL=mcp-XHZND5A4.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/mcp.ts"],"sourcesContent":["import { readFile, writeFile } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport path from \"node:path\";\nimport { loadGlobalConfig, type McpServerConfig } from \"@neotx/core\";\nimport { defineCommand } from \"citty\";\nimport { parse as parseYaml, stringify as stringifyYaml } from \"yaml\";\nimport { printError, printSuccess, printTable } from \"../output.js\";\n\n// ─── Presets for popular MCP servers ─────────────────────\n\nconst MCP_PRESETS: Record<string, { config: McpServerConfig; envVars: string[] }> = {\n linear: {\n config: {\n type: \"stdio\",\n command: \"npx\",\n args: [\"-y\", \"@anthropic/linear-mcp-server\"],\n // biome-ignore lint/suspicious/noTemplateCurlyInString: Template placeholder interpolated at runtime by Claude Code\n env: { LINEAR_API_KEY: \"${LINEAR_API_KEY}\" },\n },\n envVars: [\"LINEAR_API_KEY\"],\n },\n notion: {\n config: {\n type: \"stdio\",\n command: \"npx\",\n args: [\"-y\", \"@notionhq/notion-mcp-server\"],\n // biome-ignore lint/suspicious/noTemplateCurlyInString: Template placeholder interpolated at runtime by Claude Code\n env: { NOTION_TOKEN: \"${NOTION_TOKEN}\" },\n },\n envVars: [\"NOTION_TOKEN\"],\n },\n github: {\n config: {\n type: \"stdio\",\n command: \"npx\",\n args: [\"-y\", \"@modelcontextprotocol/server-github\"],\n // biome-ignore lint/suspicious/noTemplateCurlyInString: Template placeholder interpolated at runtime by Claude Code\n env: { GITHUB_PERSONAL_ACCESS_TOKEN: \"${GITHUB_TOKEN}\" },\n },\n envVars: [\"GITHUB_TOKEN\"],\n },\n jira: {\n config: {\n type: \"stdio\",\n command: \"npx\",\n args: [\"-y\", \"@anthropic/jira-mcp-server\"],\n // biome-ignore lint/suspicious/noTemplateCurlyInString: Template placeholders interpolated at runtime by Claude Code\n env: { JIRA_API_TOKEN: \"${JIRA_API_TOKEN}\", JIRA_URL: \"${JIRA_URL}\" },\n },\n envVars: [\"JIRA_API_TOKEN\", \"JIRA_URL\"],\n },\n slack: {\n config: {\n type: \"stdio\",\n command: \"npx\",\n args: [\"-y\", \"@modelcontextprotocol/server-slack\"],\n // biome-ignore lint/suspicious/noTemplateCurlyInString: Template placeholder interpolated at runtime by Claude Code\n env: { SLACK_BOT_TOKEN: \"${SLACK_BOT_TOKEN}\" },\n },\n envVars: [\"SLACK_BOT_TOKEN\"],\n },\n};\n\n// ─── Helpers ─────────────────────────────────────────────\n\nasync function loadAndModifyConfig(\n modify: (config: Record<string, unknown>) => void,\n): Promise<void> {\n const configPath = path.join(homedir(), \".neo\", \"config.yml\");\n let config: Record<string, unknown>;\n\n try {\n const raw = await readFile(configPath, \"utf-8\");\n config = (parseYaml(raw) as Record<string, unknown>) ?? {};\n } catch {\n config = {};\n }\n\n modify(config);\n await writeFile(configPath, stringifyYaml(config), \"utf-8\");\n}\n\n// ─── Subcommands ─────────────────────────────────────────\n\nconst listCmd = defineCommand({\n meta: { name: \"list\", description: \"List configured MCP servers\" },\n async run() {\n const config = await loadGlobalConfig();\n const servers = config.mcpServers ?? {};\n const entries = Object.entries(servers);\n\n if (entries.length === 0) {\n console.log(\"No MCP servers configured.\");\n console.log(\"Add one with: neo mcp add <name> or neo mcp add <preset>\");\n console.log(`Available presets: ${Object.keys(MCP_PRESETS).join(\", \")}`);\n return;\n }\n\n const rows = entries.map(([name, cfg]) => {\n if (cfg.type === \"stdio\") {\n return [name, \"stdio\", `${cfg.command} ${(cfg.args ?? []).join(\" \")}`];\n }\n return [name, \"http\", cfg.url];\n });\n\n printTable([\"Name\", \"Type\", \"Config\"], rows);\n },\n});\n\nconst addCmd = defineCommand({\n meta: { name: \"add\", description: \"Add an MCP server (use a preset name or custom flags)\" },\n args: {\n name: {\n type: \"positional\",\n description: \"Server name or preset (linear, notion, github, jira, slack)\",\n },\n type: { type: \"string\", description: \"Server type: stdio or http\" },\n command: { type: \"string\", description: \"Command for stdio servers\" },\n serverArgs: { type: \"string\", description: \"Comma-separated args for stdio servers\" },\n url: { type: \"string\", description: \"URL for http servers\" },\n },\n async run({ args }) {\n const name = args.name as string | undefined;\n if (!name) {\n printError(\"Server name is required. Usage: neo mcp add <name>\");\n process.exitCode = 1;\n return;\n }\n\n // Check if it's a preset\n const preset = MCP_PRESETS[name];\n if (preset) {\n // Check env vars\n const missing = preset.envVars.filter((v: string) => !process.env[v]);\n if (missing.length > 0) {\n console.log(`Preset \"${name}\" requires the following environment variables:`);\n for (const v of missing) {\n console.log(` ${v} (not set)`);\n }\n console.log(\"\\nSet them before starting the supervisor.\");\n }\n\n await loadAndModifyConfig((config) => {\n const servers = (config.mcpServers as Record<string, unknown>) ?? {};\n servers[name] = preset.config;\n config.mcpServers = servers;\n });\n\n printSuccess(`Added MCP server \"${name}\" (preset)`);\n return;\n }\n\n // Custom server\n if (!args.type) {\n printError(`Unknown preset \"${name}\". Use --type stdio or --type http for custom servers.`);\n console.log(`Available presets: ${Object.keys(MCP_PRESETS).join(\", \")}`);\n process.exitCode = 1;\n return;\n }\n\n let serverConfig: McpServerConfig;\n if (args.type === \"stdio\") {\n if (!args.command) {\n printError(\"--command is required for stdio servers\");\n process.exitCode = 1;\n return;\n }\n serverConfig = {\n type: \"stdio\",\n command: args.command,\n args: args.serverArgs ? args.serverArgs.split(\",\") : undefined,\n };\n } else if (args.type === \"http\") {\n if (!args.url) {\n printError(\"--url is required for http servers\");\n process.exitCode = 1;\n return;\n }\n serverConfig = {\n type: \"http\",\n url: args.url,\n };\n } else {\n printError(`Invalid type \"${args.type}\". Use \"stdio\" or \"http\".`);\n process.exitCode = 1;\n return;\n }\n\n await loadAndModifyConfig((config) => {\n const servers = (config.mcpServers as Record<string, unknown>) ?? {};\n servers[name] = serverConfig;\n config.mcpServers = servers;\n });\n\n printSuccess(`Added MCP server \"${name}\"`);\n },\n});\n\nconst removeCmd = defineCommand({\n meta: { name: \"remove\", description: \"Remove an MCP server\" },\n args: {\n name: { type: \"positional\", description: \"Server name to remove\" },\n },\n async run({ args }) {\n const name = args.name as string | undefined;\n if (!name) {\n printError(\"Server name is required. Usage: neo mcp remove <name>\");\n process.exitCode = 1;\n return;\n }\n\n let found = false;\n\n await loadAndModifyConfig((config) => {\n const servers = config.mcpServers as Record<string, unknown> | undefined;\n if (servers && name in servers) {\n delete servers[name];\n found = true;\n if (Object.keys(servers).length === 0) {\n delete config.mcpServers;\n }\n }\n });\n\n if (found) {\n printSuccess(`Removed MCP server \"${name}\"`);\n } else {\n printError(`MCP server \"${name}\" not found`);\n process.exitCode = 1;\n }\n },\n});\n\n// ─── Main command ────────────────────────────────────────\n\nexport default defineCommand({\n meta: {\n name: \"mcp\",\n description: \"Manage MCP server integrations (Linear, Notion, GitHub, etc.)\",\n },\n subCommands: {\n list: () => Promise.resolve(listCmd),\n add: () => Promise.resolve(addCmd),\n remove: () => Promise.resolve(removeCmd),\n },\n});\n"],"mappings":"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","names":[]}
@@ -0,0 +1,292 @@
1
+ import {
2
+ printError,
3
+ printSuccess,
4
+ printTable
5
+ } from "./chunk-YQIWMDXL.js";
6
+
7
+ // src/commands/memory.ts
8
+ import path from "path";
9
+ import { getSupervisorDir, LocalEmbedder, MemoryStore } from "@neotx/core";
10
+ import { defineCommand } from "citty";
11
+ var VALID_TYPES = ["fact", "procedure", "episode", "focus", "feedback", "task"];
12
+ function parseDuration(input) {
13
+ const match = input.match(/^(\d+)(h|m)$/);
14
+ if (!match) return void 0;
15
+ const value = Number(match[1]);
16
+ const unit = match[2];
17
+ const ms = unit === "h" ? value * 60 * 60 * 1e3 : value * 60 * 1e3;
18
+ return new Date(Date.now() + ms).toISOString();
19
+ }
20
+ function truncate(text, max) {
21
+ return text.length > max ? `${text.slice(0, max - 1)}\u2026` : text;
22
+ }
23
+ function createEmbedder() {
24
+ try {
25
+ return new LocalEmbedder();
26
+ } catch {
27
+ return null;
28
+ }
29
+ }
30
+ function openStore(name, withEmbeddings = false) {
31
+ const dir = getSupervisorDir(name);
32
+ const embedder = withEmbeddings ? createEmbedder() : null;
33
+ return new MemoryStore(path.join(dir, "memory.sqlite"), embedder);
34
+ }
35
+ function formatResultsTable(results) {
36
+ printTable(
37
+ ["ID", "TYPE", "SCOPE", "CONTENT", "ACCESSES"],
38
+ results.map((m) => [m.id, m.type, m.scope, truncate(m.content, 60), String(m.accessCount)])
39
+ );
40
+ }
41
+ async function handleWrite(args) {
42
+ if (!args.value) {
43
+ printError("Usage: neo memory write <content> --type <type> [--scope <scope>]");
44
+ process.exitCode = 1;
45
+ return;
46
+ }
47
+ const type = args.type ?? "fact";
48
+ if (!VALID_TYPES.includes(type)) {
49
+ printError(`Invalid type "${type}". Must be one of: ${VALID_TYPES.join(", ")}`);
50
+ process.exitCode = 1;
51
+ return;
52
+ }
53
+ let expiresAt;
54
+ if (args.expires) {
55
+ expiresAt = parseDuration(args.expires);
56
+ if (!expiresAt) {
57
+ printError('Invalid --expires format. Use e.g. "2h" or "30m".');
58
+ process.exitCode = 1;
59
+ return;
60
+ }
61
+ }
62
+ const store = openStore(args.name, true);
63
+ try {
64
+ const tags = args.tags ? args.tags.split(",").map((t) => t.trim()) : [];
65
+ const id = await store.write({
66
+ type,
67
+ scope: args.scope,
68
+ content: args.value,
69
+ source: args.source,
70
+ tags,
71
+ expiresAt,
72
+ severity: args.severity,
73
+ category: args.category,
74
+ outcome: args.outcome
75
+ });
76
+ printSuccess(`Memory written: ${id}`);
77
+ } finally {
78
+ store.close();
79
+ }
80
+ }
81
+ function handleForget(args) {
82
+ if (!args.value) {
83
+ printError("Usage: neo memory forget <id>");
84
+ process.exitCode = 1;
85
+ return;
86
+ }
87
+ const store = openStore(args.name);
88
+ try {
89
+ store.forget(args.value);
90
+ printSuccess(`Memory forgotten: ${args.value}`);
91
+ } finally {
92
+ store.close();
93
+ }
94
+ }
95
+ var VALID_OUTCOMES = ["pending", "in_progress", "done", "blocked", "abandoned"];
96
+ function handleUpdate(args) {
97
+ if (!args.value) {
98
+ printError('Usage: neo memory update <id> ["new content"] [--outcome <status>]');
99
+ process.exitCode = 1;
100
+ return;
101
+ }
102
+ const argv = process.argv;
103
+ const updateIdx = argv.indexOf("update");
104
+ const idArg = argv[updateIdx + 1];
105
+ const contentArg = argv[updateIdx + 2];
106
+ if (args.outcome && !VALID_OUTCOMES.includes(args.outcome)) {
107
+ printError(`Invalid outcome "${args.outcome}". Must be one of: ${VALID_OUTCOMES.join(", ")}`);
108
+ process.exitCode = 1;
109
+ return;
110
+ }
111
+ const isContentArgAFlag = contentArg?.startsWith("--");
112
+ const hasContent = contentArg && !isContentArgAFlag;
113
+ if (!hasContent && !args.outcome) {
114
+ printError('Usage: neo memory update <id> ["new content"] [--outcome <status>]');
115
+ process.exitCode = 1;
116
+ return;
117
+ }
118
+ if (!idArg) {
119
+ printError('Usage: neo memory update <id> ["new content"] [--outcome <status>]');
120
+ process.exitCode = 1;
121
+ return;
122
+ }
123
+ const store = openStore(args.name);
124
+ try {
125
+ if (args.outcome) {
126
+ store.updateFields(idArg, {
127
+ ...hasContent && { content: contentArg },
128
+ outcome: args.outcome
129
+ });
130
+ } else {
131
+ store.update(idArg, contentArg);
132
+ }
133
+ printSuccess(`Memory updated: ${idArg}`);
134
+ } finally {
135
+ store.close();
136
+ }
137
+ }
138
+ async function handleSearch(args) {
139
+ if (!args.value) {
140
+ printError("Usage: neo memory search <query>");
141
+ process.exitCode = 1;
142
+ return;
143
+ }
144
+ const store = openStore(args.name, true);
145
+ try {
146
+ const results = await store.search(args.value, {
147
+ ...args.scope !== "global" && { scope: args.scope },
148
+ ...args.type && { types: [args.type] }
149
+ });
150
+ if (results.length === 0) {
151
+ console.log("No memories found.");
152
+ return;
153
+ }
154
+ formatResultsTable(results);
155
+ } finally {
156
+ store.close();
157
+ }
158
+ }
159
+ function handleList(args) {
160
+ const store = openStore(args.name);
161
+ try {
162
+ const results = store.query({
163
+ ...args.scope !== "global" && { scope: args.scope },
164
+ ...args.type && { types: [args.type] }
165
+ });
166
+ if (results.length === 0) {
167
+ console.log("No memories found.");
168
+ return;
169
+ }
170
+ formatResultsTable(results);
171
+ } finally {
172
+ store.close();
173
+ }
174
+ }
175
+ function handleStats(args) {
176
+ const store = openStore(args.name);
177
+ try {
178
+ const s = store.stats();
179
+ console.log(`Total memories: ${s.total}
180
+ `);
181
+ if (Object.keys(s.byType).length > 0) {
182
+ printTable(
183
+ ["TYPE", "COUNT"],
184
+ Object.entries(s.byType).map(([t, c]) => [t, String(c)])
185
+ );
186
+ console.log();
187
+ }
188
+ if (Object.keys(s.byScope).length > 0) {
189
+ printTable(
190
+ ["SCOPE", "COUNT"],
191
+ Object.entries(s.byScope).map(([sc, c]) => [sc, String(c)])
192
+ );
193
+ }
194
+ } finally {
195
+ store.close();
196
+ }
197
+ }
198
+ var memory_default = defineCommand({
199
+ meta: {
200
+ name: "memory",
201
+ description: "Manage the supervisor memory store"
202
+ },
203
+ args: {
204
+ action: {
205
+ type: "positional",
206
+ description: "Action: write, forget, update, search, list, stats",
207
+ required: true
208
+ },
209
+ value: {
210
+ type: "positional",
211
+ description: "Content or ID depending on action",
212
+ required: false
213
+ },
214
+ type: {
215
+ type: "string",
216
+ description: "Memory type: fact, procedure, episode, focus, feedback, task"
217
+ },
218
+ scope: {
219
+ type: "string",
220
+ description: "Scope: global or repo path",
221
+ default: "global"
222
+ },
223
+ source: {
224
+ type: "string",
225
+ description: "Source: developer, reviewer, supervisor, user",
226
+ default: "user"
227
+ },
228
+ expires: {
229
+ type: "string",
230
+ description: "TTL for focus entries (e.g. 2h, 30m)"
231
+ },
232
+ outcome: {
233
+ type: "string",
234
+ description: "Task outcome: pending, in_progress, done, blocked, abandoned"
235
+ },
236
+ severity: {
237
+ type: "string",
238
+ description: "Priority: critical, high, medium, low"
239
+ },
240
+ category: {
241
+ type: "string",
242
+ description: "Context reference (e.g. 'neo runs abc123' or 'cat notes/plan.md')"
243
+ },
244
+ tags: {
245
+ type: "string",
246
+ description: "Comma-separated tags (e.g. 'initiative:auth,depends:mem_abc')"
247
+ },
248
+ name: {
249
+ type: "string",
250
+ description: "Supervisor name",
251
+ default: "supervisor"
252
+ }
253
+ },
254
+ async run({ args }) {
255
+ const action = args.action;
256
+ const parsed = {
257
+ value: args.value,
258
+ type: args.type,
259
+ scope: args.scope,
260
+ source: args.source,
261
+ expires: args.expires,
262
+ name: args.name,
263
+ outcome: args.outcome,
264
+ severity: args.severity,
265
+ category: args.category,
266
+ tags: args.tags
267
+ };
268
+ switch (action) {
269
+ case "write":
270
+ return handleWrite(parsed);
271
+ case "forget":
272
+ return handleForget(parsed);
273
+ case "update":
274
+ return handleUpdate(parsed);
275
+ case "search":
276
+ return handleSearch(parsed);
277
+ case "list":
278
+ return handleList(parsed);
279
+ case "stats":
280
+ return handleStats(parsed);
281
+ default:
282
+ printError(
283
+ `Unknown action "${action}". Must be one of: write, forget, update, search, list, stats`
284
+ );
285
+ process.exitCode = 1;
286
+ }
287
+ }
288
+ });
289
+ export {
290
+ memory_default as default
291
+ };
292
+ //# sourceMappingURL=memory-6R22DFS7.js.map
@@ -0,0 +1 @@
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 {\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":[]}
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  resolveAgentsDir
3
- } from "./chunk-TNJOG54I.js";
3
+ } from "./chunk-F622JUDY.js";
4
4
  import {
5
5
  printError,
6
6
  printJson,
@@ -8,7 +8,7 @@ import {
8
8
  } from "./chunk-YQIWMDXL.js";
9
9
 
10
10
  // src/commands/run.ts
11
- import { fork } from "child_process";
11
+ import { spawn } from "child_process";
12
12
  import { randomUUID } from "crypto";
13
13
  import { existsSync } from "fs";
14
14
  import { mkdir, writeFile } from "fs/promises";
@@ -60,6 +60,9 @@ function printResult(result, agentName) {
60
60
  if (result.branch) {
61
61
  console.log(`Branch: ${result.branch}`);
62
62
  }
63
+ if (result.prUrl) {
64
+ console.log(`PR: ${result.prUrl}`);
65
+ }
63
66
  const stepResult = Object.values(result.steps)[0];
64
67
  const output = stepResult?.output ?? result.summary;
65
68
  if (output) {
@@ -96,6 +99,7 @@ async function runDetached(params) {
96
99
  agentName: params.agentName,
97
100
  repo: params.repo,
98
101
  prompt: params.prompt,
102
+ branch: params.branch,
99
103
  priority: params.priority,
100
104
  metadata: params.metadata,
101
105
  bundledAgentsDir: params.bundledAgentsDir,
@@ -104,9 +108,10 @@ async function runDetached(params) {
104
108
  "utf-8"
105
109
  );
106
110
  const workerPath = path.join(path.dirname(fileURLToPath(import.meta.url)), "daemon", "worker.js");
107
- const child = fork(workerPath, [runId, repoSlug], {
111
+ const child = spawn(process.execPath, [workerPath, runId, repoSlug], {
108
112
  detached: true,
109
- stdio: "ignore"
113
+ stdio: "ignore",
114
+ env: process.env
110
115
  });
111
116
  child.unref();
112
117
  if (params.jsonOutput) {
@@ -120,7 +125,7 @@ async function runDetached(params) {
120
125
  var run_default = defineCommand({
121
126
  meta: {
122
127
  name: "run",
123
- description: "Dispatch an agent to execute a task in an isolated worktree"
128
+ description: "Dispatch an agent to execute a task in an isolated clone"
124
129
  },
125
130
  args: {
126
131
  agent: {
@@ -138,13 +143,17 @@ var run_default = defineCommand({
138
143
  description: "Task description for the agent",
139
144
  required: true
140
145
  },
146
+ branch: {
147
+ type: "string",
148
+ description: "Branch name for the session clone (required for writable agents)"
149
+ },
141
150
  priority: {
142
151
  type: "string",
143
152
  description: "Priority level: critical, high, medium, low"
144
153
  },
145
154
  meta: {
146
155
  type: "string",
147
- description: "Metadata as JSON string"
156
+ description: "Metadata as JSON string (for traceability: ticketId, stage, etc.)"
148
157
  },
149
158
  output: {
150
159
  type: "string",
@@ -154,7 +163,17 @@ var run_default = defineCommand({
154
163
  type: "boolean",
155
164
  alias: "d",
156
165
  description: "Run in background and return immediately with the run ID",
166
+ default: true
167
+ },
168
+ sync: {
169
+ type: "boolean",
170
+ alias: "s",
171
+ description: "Run in foreground (blocking) instead of detached",
157
172
  default: false
173
+ },
174
+ "git-strategy": {
175
+ type: "string",
176
+ description: "Git strategy: pr (create PR), branch (push only, default)"
158
177
  }
159
178
  },
160
179
  async run({ args }) {
@@ -175,11 +194,12 @@ var run_default = defineCommand({
175
194
  process.exitCode = 1;
176
195
  return;
177
196
  }
178
- if (args.detach) {
197
+ if (args.detach && !args.sync) {
179
198
  await runDetached({
180
199
  agentName: args.agent,
181
200
  repo,
182
201
  prompt: args.prompt,
202
+ branch: args.branch,
183
203
  priority: args.priority ?? "medium",
184
204
  metadata: parseMetadata(args.meta),
185
205
  bundledAgentsDir,
@@ -202,12 +222,15 @@ var run_default = defineCommand({
202
222
  }
203
223
  try {
204
224
  await orchestrator.start();
225
+ const gitStrategy = args["git-strategy"];
205
226
  const result = await orchestrator.dispatch({
206
227
  workflow: `_run_${args.agent}`,
207
228
  repo,
208
229
  prompt: args.prompt,
230
+ ...args.branch ? { branch: args.branch } : {},
209
231
  priority: args.priority ?? "medium",
210
- metadata: parseMetadata(args.meta)
232
+ metadata: parseMetadata(args.meta),
233
+ ...gitStrategy ? { gitStrategy } : {}
211
234
  });
212
235
  if (jsonOutput) {
213
236
  printJson(result);
@@ -228,4 +251,4 @@ var run_default = defineCommand({
228
251
  export {
229
252
  run_default as default
230
253
  };
231
- //# sourceMappingURL=run-KIU2ZE72.js.map
254
+ //# sourceMappingURL=run-GJLDWPUE.js.map
@@ -0,0 +1 @@
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, 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 {\n throw new Error(`Invalid --meta JSON: ${meta}`);\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 workflow: `_run_${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 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);\n orchestrator.registerAgent(agent);\n orchestrator.registerWorkflow({\n name: `_run_${args.agent}`,\n description: `Direct dispatch to ${args.agent}`,\n steps: {\n run: { agent: args.agent },\n },\n });\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 workflow: `_run_${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":"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","names":[]}
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  loadRunsFiltered,
3
3
  resolveRepoFilter
4
- } from "./chunk-CP54H7WA.js";
4
+ } from "./chunk-3ZP3BQXB.js";
5
5
  import {
6
6
  printError,
7
7
  printJson,
@@ -23,6 +23,9 @@ function totalDuration(run) {
23
23
  function shortId(runId) {
24
24
  return runId.slice(0, 8);
25
25
  }
26
+ function repoName(run) {
27
+ return run.repo.split("/").pop() ?? run.repo;
28
+ }
26
29
  function showRunDetail(match, short) {
27
30
  if (short) {
28
31
  console.log(`${match.runId} ${match.status} $${totalCost(match).toFixed(4)}`);
@@ -59,7 +62,7 @@ function listRuns(runs, short) {
59
62
  for (const r of runs) {
60
63
  const agent = Object.values(r.steps)[0]?.agent ?? "?";
61
64
  console.log(
62
- `${shortId(r.runId)} ${r.status.padEnd(9)} ${agent.padEnd(18)} $${totalCost(r).toFixed(4).padStart(8)} ${formatDuration(totalDuration(r)).padStart(7)}`
65
+ `${shortId(r.runId)} ${r.status.padEnd(9)} ${repoName(r).padEnd(14)} ${agent.padEnd(18)} $${totalCost(r).toFixed(4).padStart(8)} ${formatDuration(totalDuration(r)).padStart(7)}`
63
66
  );
64
67
  }
65
68
  return;
@@ -69,10 +72,11 @@ function listRuns(runs, short) {
69
72
  return;
70
73
  }
71
74
  printTable(
72
- ["RUN", "STATUS", "AGENT", "COST", "DURATION", "BRANCH"],
75
+ ["RUN", "STATUS", "REPO", "AGENT", "COST", "DURATION", "BRANCH"],
73
76
  runs.map((r) => [
74
77
  shortId(r.runId),
75
78
  r.status,
79
+ repoName(r),
76
80
  Object.values(r.steps)[0]?.agent ?? "unknown",
77
81
  `$${totalCost(r).toFixed(4)}`,
78
82
  formatDuration(totalDuration(r)),
@@ -91,11 +95,6 @@ var runs_default = defineCommand({
91
95
  description: "Run ID to show details (omit to list all runs)",
92
96
  required: false
93
97
  },
94
- all: {
95
- type: "boolean",
96
- description: "Show runs from all repos",
97
- default: false
98
- },
99
98
  repo: {
100
99
  type: "string",
101
100
  description: "Filter by repo name or path"
@@ -120,7 +119,7 @@ var runs_default = defineCommand({
120
119
  },
121
120
  async run({ args }) {
122
121
  const jsonOutput = args.output === "json";
123
- const filter = await resolveRepoFilter({ all: args.all, repo: args.repo });
122
+ const filter = await resolveRepoFilter({ repo: args.repo });
124
123
  let runs = await loadRunsFiltered(filter);
125
124
  if (runs.length === 0) {
126
125
  if (!jsonOutput) {
@@ -173,4 +172,4 @@ var runs_default = defineCommand({
173
172
  export {
174
173
  runs_default as default
175
174
  };
176
- //# sourceMappingURL=runs-CHA2JM5K.js.map
175
+ //# sourceMappingURL=runs-LOYOWU55.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/runs.ts"],"sourcesContent":["import type { PersistedRun } from \"@neotx/core\";\nimport { defineCommand } from \"citty\";\nimport { printError, printJson, printTable } from \"../output.js\";\nimport { loadRunsFiltered, resolveRepoFilter } from \"../repo-filter.js\";\n\nfunction formatDuration(ms: number): string {\n if (ms < 1000) return `${ms}ms`;\n return `${(ms / 1000).toFixed(1)}s`;\n}\n\nfunction totalCost(run: PersistedRun): number {\n return Object.values(run.steps).reduce((sum, s) => sum + s.costUsd, 0);\n}\n\nfunction totalDuration(run: PersistedRun): number {\n return Object.values(run.steps).reduce((sum, s) => sum + s.durationMs, 0);\n}\n\nfunction shortId(runId: string): string {\n return runId.slice(0, 8);\n}\n\nfunction repoName(run: PersistedRun): string {\n return run.repo.split(\"/\").pop() ?? run.repo;\n}\n\nfunction showRunDetail(match: PersistedRun, short: boolean): void {\n if (short) {\n console.log(`${match.runId} ${match.status} $${totalCost(match).toFixed(4)}`);\n for (const [name, step] of Object.entries(match.steps)) {\n const out = typeof step.output === \"string\" ? step.output.slice(0, 200) : \"\";\n console.log(` ${name}: ${step.status} ${step.agent} ${out}`);\n }\n return;\n }\n\n console.log(`Run: ${match.runId}`);\n console.log(`Status: ${match.status}`);\n console.log(`Repo: ${match.repo}`);\n console.log(`Prompt: ${match.prompt}`);\n if (match.branch) console.log(`Branch: ${match.branch}`);\n console.log(`Cost: $${totalCost(match).toFixed(4)}`);\n console.log(`Duration: ${formatDuration(totalDuration(match))}`);\n console.log(`Created: ${match.createdAt}`);\n console.log(\"\");\n for (const [name, step] of Object.entries(match.steps)) {\n console.log(`Step: ${name}`);\n console.log(` Agent: ${step.agent}`);\n console.log(` Status: ${step.status}`);\n console.log(` Cost: $${step.costUsd.toFixed(4)}`);\n console.log(` Duration: ${formatDuration(step.durationMs)}`);\n if (step.error) console.log(` Error: ${step.error}`);\n if (step.output) {\n const out = typeof step.output === \"string\" ? step.output : JSON.stringify(step.output);\n console.log(` Output: ${out}`);\n }\n }\n}\n\nfunction listRuns(runs: PersistedRun[], short: boolean): void {\n if (short) {\n for (const r of runs) {\n const agent = Object.values(r.steps)[0]?.agent ?? \"?\";\n console.log(\n `${shortId(r.runId)} ${r.status.padEnd(9)} ${repoName(r).padEnd(14)} ${agent.padEnd(18)} $${totalCost(r).toFixed(4).padStart(8)} ${formatDuration(totalDuration(r)).padStart(7)}`,\n );\n }\n return;\n }\n\n if (runs.length === 0) {\n console.log(\"No runs found.\");\n return;\n }\n\n printTable(\n [\"RUN\", \"STATUS\", \"REPO\", \"AGENT\", \"COST\", \"DURATION\", \"BRANCH\"],\n runs.map((r) => [\n shortId(r.runId),\n r.status,\n repoName(r),\n Object.values(r.steps)[0]?.agent ?? \"unknown\",\n `$${totalCost(r).toFixed(4)}`,\n formatDuration(totalDuration(r)),\n r.branch?.replace(\"feat/run-\", \"\").slice(0, 8) ?? \"-\",\n ]),\n );\n}\n\nexport default defineCommand({\n meta: {\n name: \"runs\",\n description: \"List runs or show details of a specific run\",\n },\n args: {\n runId: {\n type: \"positional\",\n description: \"Run ID to show details (omit to list all runs)\",\n required: false,\n },\n repo: {\n type: \"string\",\n description: \"Filter by repo name or path\",\n },\n last: {\n type: \"string\",\n description: \"Show only the last N runs\",\n },\n status: {\n type: \"string\",\n description: \"Filter by status: completed, failed, running\",\n },\n short: {\n type: \"boolean\",\n description: \"Compact output for supervisor agents (saves tokens)\",\n default: false,\n },\n output: {\n type: \"string\",\n description: \"Output format: json\",\n },\n },\n async run({ args }) {\n const jsonOutput = args.output === \"json\";\n const filter = await resolveRepoFilter({ repo: args.repo });\n let runs = await loadRunsFiltered(filter);\n\n if (runs.length === 0) {\n if (!jsonOutput) {\n printError(\"No runs found. Run 'neo run <agent>' first.\");\n } else {\n printJson([]);\n }\n return;\n }\n\n // If a runId is given (full or prefix), show details\n if (args.runId) {\n const match = runs.find(\n (r) => r.runId === args.runId || r.runId.startsWith(args.runId as string),\n );\n if (!match) {\n printError(`Run \"${args.runId}\" not found.`);\n process.exitCode = 1;\n return;\n }\n\n if (jsonOutput) {\n printJson(match);\n return;\n }\n\n showRunDetail(match, args.short);\n return;\n }\n\n // List mode\n if (args.status) {\n runs = runs.filter((r) => r.status === args.status);\n }\n\n if (args.last) {\n runs = runs.slice(0, Number(args.last));\n }\n\n if (jsonOutput) {\n printJson(\n runs.map((r) => ({\n runId: r.runId,\n status: r.status,\n repo: r.repo,\n agent: Object.values(r.steps)[0]?.agent ?? \"unknown\",\n costUsd: totalCost(r),\n durationMs: totalDuration(r),\n branch: r.branch,\n updatedAt: r.updatedAt,\n })),\n );\n return;\n }\n\n listRuns(runs, args.short);\n },\n});\n"],"mappings":"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","names":[]}