@agent-nexus/cli 0.1.0

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 (2) hide show
  1. package/dist/index.js +3992 -0
  2. package/package.json +46 -0
package/dist/index.js ADDED
@@ -0,0 +1,3992 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __esm = (fn, res) => function __init() {
10
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
11
+ };
12
+ var __export = (target, all) => {
13
+ for (var name in all)
14
+ __defProp(target, name, { get: all[name], enumerable: true });
15
+ };
16
+ var __copyProps = (to, from, except, desc) => {
17
+ if (from && typeof from === "object" || typeof from === "function") {
18
+ for (let key of __getOwnPropNames(from))
19
+ if (!__hasOwnProp.call(to, key) && key !== except)
20
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
21
+ }
22
+ return to;
23
+ };
24
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
25
+ // If the importer is in node compatibility mode or this is not an ESM
26
+ // file that has been converted to a CommonJS file using a Babel-
27
+ // compatible transform (i.e. "__esModule" has not been set), then set
28
+ // "default" to the CommonJS "module.exports" for node compatibility.
29
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
30
+ mod
31
+ ));
32
+
33
+ // src/output.ts
34
+ var output_exports = {};
35
+ __export(output_exports, {
36
+ color: () => color,
37
+ isJsonMode: () => isJsonMode,
38
+ printList: () => printList,
39
+ printPaginationMeta: () => printPaginationMeta,
40
+ printRecord: () => printRecord,
41
+ printSuccess: () => printSuccess,
42
+ printTable: () => printTable,
43
+ setJsonMode: () => setJsonMode
44
+ });
45
+ function setJsonMode(enabled) {
46
+ _jsonMode = enabled;
47
+ }
48
+ function isJsonMode() {
49
+ return _jsonMode;
50
+ }
51
+ function c2(code, text) {
52
+ return NO_COLOR2 ? text : `\x1B[${code}m${text}\x1B[0m`;
53
+ }
54
+ function printTable(rows, columns) {
55
+ if (_jsonMode) {
56
+ console.log(JSON.stringify(rows, null, 2));
57
+ return;
58
+ }
59
+ if (rows.length === 0) {
60
+ console.log(color.dim("No results."));
61
+ return;
62
+ }
63
+ const widths = columns.map((col) => {
64
+ const headerLen = col.label.length;
65
+ const maxDataLen = rows.reduce((max, row) => {
66
+ const val = col.format ? col.format(row[col.key]) : String(row[col.key] ?? "");
67
+ return Math.max(max, val.length);
68
+ }, 0);
69
+ return col.width ?? Math.min(Math.max(headerLen, maxDataLen), 50);
70
+ });
71
+ const header = columns.map((col, i) => color.bold(col.label.padEnd(widths[i]))).join(" ");
72
+ console.log(header);
73
+ console.log(columns.map((_, i) => "\u2500".repeat(widths[i])).join(" "));
74
+ for (const row of rows) {
75
+ const line = columns.map((col, i) => {
76
+ const val = col.format ? col.format(row[col.key]) : String(row[col.key] ?? "");
77
+ return val.padEnd(widths[i]).slice(0, widths[i]);
78
+ }).join(" ");
79
+ console.log(line);
80
+ }
81
+ }
82
+ function printRecord(data, fields) {
83
+ if (_jsonMode) {
84
+ console.log(JSON.stringify(data, null, 2));
85
+ return;
86
+ }
87
+ const entries = fields ? fields.map((f) => [f.label, f.format ? f.format(data[f.key]) : String(data[f.key] ?? "")]) : Object.entries(data).map(([k, v]) => [k, String(v ?? "")]);
88
+ const maxLabel = entries.reduce((max, [label]) => Math.max(max, label.length), 0);
89
+ for (const [label, value] of entries) {
90
+ console.log(`${color.bold(label.padEnd(maxLabel))} ${value}`);
91
+ }
92
+ }
93
+ function printSuccess(message, data) {
94
+ if (_jsonMode) {
95
+ console.log(JSON.stringify({ success: true, ...data }, null, 2));
96
+ return;
97
+ }
98
+ console.log(color.green("\u2713") + " " + message);
99
+ if (data) {
100
+ for (const [key, value] of Object.entries(data)) {
101
+ console.log(` ${color.dim(key + ":")} ${value}`);
102
+ }
103
+ }
104
+ }
105
+ function printPaginationMeta(meta) {
106
+ if (_jsonMode) return;
107
+ const parts = [];
108
+ if (meta.total != null) parts.push(`${meta.total} total`);
109
+ if (meta.page != null) parts.push(`page ${meta.page}`);
110
+ if (meta.hasMore) parts.push("more available");
111
+ if (parts.length > 0) {
112
+ console.log(color.dim(`
113
+ ${parts.join(" \xB7 ")}`));
114
+ }
115
+ }
116
+ function printList(data, meta, columns) {
117
+ if (_jsonMode) {
118
+ console.log(JSON.stringify({ data, meta }, null, 2));
119
+ return;
120
+ }
121
+ printTable(data, columns);
122
+ if (meta) {
123
+ printPaginationMeta(meta);
124
+ }
125
+ }
126
+ var _jsonMode, NO_COLOR2, color;
127
+ var init_output = __esm({
128
+ "src/output.ts"() {
129
+ "use strict";
130
+ _jsonMode = false;
131
+ NO_COLOR2 = !!process.env.NO_COLOR || process.argv.includes("--no-color") || !process.stdout.isTTY;
132
+ color = {
133
+ orange: (t) => c2("38;2;245;70;26", t),
134
+ teal: (t) => c2("38;2;0;183;165", t),
135
+ dim: (t) => c2("2", t),
136
+ bold: (t) => c2("1", t),
137
+ red: (t) => c2("31", t),
138
+ green: (t) => c2("32", t),
139
+ yellow: (t) => c2("33", t),
140
+ cyan: (t) => c2("36", t)
141
+ };
142
+ }
143
+ });
144
+
145
+ // src/index.ts
146
+ var import_commander = require("commander");
147
+
148
+ // src/banner.ts
149
+ var NO_COLOR = !!process.env.NO_COLOR || process.argv.includes("--no-color") || !process.stdout.isTTY;
150
+ function c(code, text) {
151
+ return NO_COLOR ? text : `\x1B[${code}m${text}\x1B[0m`;
152
+ }
153
+ var teal = (t) => c("38;2;0;183;165", t);
154
+ var dim = (t) => c("2", t);
155
+ var bold = (t) => c("1", t);
156
+ var WORDMARK = [
157
+ " \u2588\u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557",
158
+ " \u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u255A\u2588\u2588\u2557\u2588\u2588\u2554\u255D\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D",
159
+ " \u2588\u2588\u2554\u2588\u2588\u2557 \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2557 \u255A\u2588\u2588\u2588\u2554\u255D \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557",
160
+ " \u2588\u2588\u2551\u255A\u2588\u2588\u2557\u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u255D \u2588\u2588\u2554\u2588\u2588\u2557 \u2588\u2588\u2551 \u2588\u2588\u2551\u255A\u2550\u2550\u2550\u2550\u2588\u2588\u2551",
161
+ " \u2588\u2588\u2551 \u255A\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2554\u255D \u2588\u2588\u2557\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551",
162
+ " \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u255D\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D"
163
+ ];
164
+ function getBanner(version) {
165
+ const lines = [""];
166
+ for (const line of WORDMARK) {
167
+ lines.push(bold(line));
168
+ }
169
+ lines.push("");
170
+ lines.push(dim(" The AI agent platform") + " " + teal("v" + version));
171
+ lines.push("");
172
+ return lines.join("\n");
173
+ }
174
+
175
+ // src/client.ts
176
+ var import_sdk = require("@agent-nexus/sdk");
177
+
178
+ // src/config.ts
179
+ var import_node_fs = __toESM(require("fs"));
180
+ var import_node_os = __toESM(require("os"));
181
+ var import_node_path = __toESM(require("path"));
182
+ var URL_MAP = {
183
+ production: "https://api.nexusgpt.io",
184
+ dev: "http://localhost:3001"
185
+ };
186
+ var CONFIG_DIR = import_node_path.default.join(import_node_os.default.homedir(), ".nexus-mcp");
187
+ var CONFIG_FILE = import_node_path.default.join(CONFIG_DIR, "config.json");
188
+ function loadConfig() {
189
+ try {
190
+ const raw = import_node_fs.default.readFileSync(CONFIG_FILE, "utf-8");
191
+ return JSON.parse(raw);
192
+ } catch {
193
+ return {};
194
+ }
195
+ }
196
+ function saveConfig(config) {
197
+ import_node_fs.default.mkdirSync(CONFIG_DIR, { recursive: true, mode: 448 });
198
+ import_node_fs.default.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2) + "\n", {
199
+ mode: 384
200
+ });
201
+ }
202
+ function clearConfig() {
203
+ try {
204
+ import_node_fs.default.unlinkSync(CONFIG_FILE);
205
+ } catch {
206
+ }
207
+ }
208
+ function resolveBaseUrl(override) {
209
+ if (override) return override;
210
+ if (process.env.NEXUS_BASE_URL) return process.env.NEXUS_BASE_URL;
211
+ const config = loadConfig();
212
+ if (config.baseUrl) return config.baseUrl;
213
+ const env = process.env.NEXUS_ENV ?? "production";
214
+ return URL_MAP[env] ?? URL_MAP.production;
215
+ }
216
+ function resolveApiKey(override) {
217
+ if (override) return override;
218
+ if (process.env.NEXUS_API_KEY) return process.env.NEXUS_API_KEY;
219
+ const config = loadConfig();
220
+ if (config.apiKey) return config.apiKey;
221
+ throw new Error("No API key found. Set NEXUS_API_KEY or run:\n nexus auth login");
222
+ }
223
+
224
+ // src/client.ts
225
+ function createClient(opts) {
226
+ return new import_sdk.NexusClient({
227
+ apiKey: resolveApiKey(opts?.apiKey),
228
+ baseUrl: resolveBaseUrl(opts?.baseUrl)
229
+ });
230
+ }
231
+
232
+ // src/errors.ts
233
+ var import_sdk2 = require("@agent-nexus/sdk");
234
+ init_output();
235
+ function handleError(err) {
236
+ if (err instanceof import_sdk2.NexusAuthenticationError) {
237
+ printCliError(
238
+ "Authentication failed \u2014 invalid or missing API key.",
239
+ 'Run "nexus auth login" to re-authenticate, or set NEXUS_API_KEY.'
240
+ );
241
+ return 1;
242
+ }
243
+ if (err instanceof import_sdk2.NexusApiError) {
244
+ if (err.status === 404) {
245
+ printCliError(
246
+ `Not found: ${err.message}`,
247
+ 'Run "nexus <resource> list" to see available resources.'
248
+ );
249
+ } else if (err.status === 422 || err.code === "VALIDATION_ERROR") {
250
+ printCliError(
251
+ `Validation error: ${err.message}`,
252
+ err.details ? `Details: ${JSON.stringify(err.details)}` : void 0
253
+ );
254
+ } else {
255
+ printCliError(`API error (${err.status}): ${err.message}`);
256
+ }
257
+ return 1;
258
+ }
259
+ if (err instanceof import_sdk2.NexusConnectionError) {
260
+ printCliError(
261
+ "Could not reach the Nexus API.",
262
+ "Check your network connection and base URL configuration."
263
+ );
264
+ return 1;
265
+ }
266
+ if (err instanceof import_sdk2.NexusError) {
267
+ printCliError(err.message);
268
+ return 1;
269
+ }
270
+ if (err instanceof Error) {
271
+ printCliError(err.message);
272
+ return 1;
273
+ }
274
+ printCliError(String(err));
275
+ return 1;
276
+ }
277
+ function printCliError(message, hint) {
278
+ if (isJsonMode()) {
279
+ console.log(JSON.stringify({ error: { message, hint } }, null, 2));
280
+ return;
281
+ }
282
+ console.error(color.red("Error:") + " " + message);
283
+ if (hint) {
284
+ console.error(color.dim(" " + hint));
285
+ }
286
+ }
287
+
288
+ // src/commands/agent.ts
289
+ init_output();
290
+
291
+ // src/util/stdin.ts
292
+ function readStdin() {
293
+ return new Promise((resolve, reject) => {
294
+ const chunks = [];
295
+ process.stdin.on("data", (chunk) => chunks.push(chunk));
296
+ process.stdin.on("end", () => resolve(Buffer.concat(chunks).toString("utf-8").trim()));
297
+ process.stdin.on("error", reject);
298
+ if (process.stdin.isTTY) {
299
+ resolve("");
300
+ }
301
+ });
302
+ }
303
+ async function resolveInputValue(value) {
304
+ if (value === "-") {
305
+ return readStdin();
306
+ }
307
+ try {
308
+ const fs5 = await import("fs");
309
+ if (fs5.existsSync(value) && fs5.statSync(value).isFile()) {
310
+ return fs5.readFileSync(value, "utf-8").trim();
311
+ }
312
+ } catch {
313
+ }
314
+ return value;
315
+ }
316
+
317
+ // src/util/body.ts
318
+ async function resolveBody(raw) {
319
+ if (raw === void 0) return void 0;
320
+ let jsonStr;
321
+ if (raw === "-") {
322
+ jsonStr = await readStdin();
323
+ } else if (raw.endsWith(".json")) {
324
+ try {
325
+ const fs5 = await import("fs/promises");
326
+ jsonStr = (await fs5.readFile(raw, "utf-8")).trim();
327
+ } catch (err) {
328
+ throw new Error(
329
+ `Could not read file "${raw}": ${err instanceof Error ? err.message : String(err)}`
330
+ );
331
+ }
332
+ } else {
333
+ jsonStr = raw;
334
+ }
335
+ try {
336
+ return JSON.parse(jsonStr);
337
+ } catch {
338
+ throw new Error(
339
+ `Invalid JSON in --body: ${jsonStr.length > 120 ? jsonStr.slice(0, 120) + "\u2026" : jsonStr}`
340
+ );
341
+ }
342
+ }
343
+ function mergeBodyWithFlags(body, flags) {
344
+ const merged = { ...body };
345
+ for (const [key, value] of Object.entries(flags)) {
346
+ if (value !== void 0) merged[key] = value;
347
+ }
348
+ return merged;
349
+ }
350
+
351
+ // src/util/pagination.ts
352
+ function addPaginationOptions(cmd) {
353
+ return cmd.option("--page <number>", "Page number", parseInt).option("--limit <number>", "Items per page", parseInt);
354
+ }
355
+ function getPaginationParams(opts) {
356
+ const params = {};
357
+ if (typeof opts.page === "number") params.page = opts.page;
358
+ if (typeof opts.limit === "number") params.limit = opts.limit;
359
+ return params;
360
+ }
361
+
362
+ // src/commands/agent.ts
363
+ function registerAgentCommands(program2) {
364
+ const agent = program2.command("agent").description("Manage AI agents");
365
+ addPaginationOptions(
366
+ agent.command("list").description("List agents").option("--status <status>", "Filter by status (ACTIVE, DRAFT)").option("--search <query>", "Search by name or role").addHelpText(
367
+ "after",
368
+ `
369
+ Examples:
370
+ $ nexus agent list
371
+ $ nexus agent list --limit 5 --status ACTIVE
372
+ $ nexus agent list --search "support" --json`
373
+ )
374
+ ).action(async (opts) => {
375
+ try {
376
+ const client = createClient(program2.optsWithGlobals());
377
+ const { data, meta } = await client.agents.list({
378
+ ...getPaginationParams(opts),
379
+ status: opts.status,
380
+ search: opts.search
381
+ });
382
+ printList(
383
+ data,
384
+ meta,
385
+ [
386
+ { key: "id", label: "ID", width: 36 },
387
+ { key: "firstName", label: "FIRST NAME", width: 15 },
388
+ { key: "lastName", label: "LAST NAME", width: 15 },
389
+ { key: "role", label: "ROLE", width: 25 },
390
+ { key: "status", label: "STATUS", width: 10 }
391
+ ]
392
+ );
393
+ } catch (err) {
394
+ process.exitCode = handleError(err);
395
+ }
396
+ });
397
+ agent.command("get").description("Get agent details").argument("<id>", "Agent ID").addHelpText(
398
+ "after",
399
+ `
400
+ Examples:
401
+ $ nexus agent get abc-123
402
+ $ nexus agent get abc-123 --json`
403
+ ).action(async (id) => {
404
+ try {
405
+ const client = createClient(program2.optsWithGlobals());
406
+ const agent2 = await client.agents.get(id);
407
+ printRecord(agent2, [
408
+ { key: "id", label: "ID" },
409
+ { key: "firstName", label: "First Name" },
410
+ { key: "lastName", label: "Last Name" },
411
+ { key: "role", label: "Role" },
412
+ { key: "status", label: "Status" },
413
+ { key: "model", label: "Model" },
414
+ { key: "tone", label: "Tone" },
415
+ { key: "createdAt", label: "Created" }
416
+ ]);
417
+ } catch (err) {
418
+ process.exitCode = handleError(err);
419
+ }
420
+ });
421
+ agent.command("create").description("Create a new agent").requiredOption("--first-name <name>", "Agent first name").requiredOption("--last-name <name>", "Agent last name").requiredOption("--role <role>", "Agent role, e.g. 'Customer Support'").option("--bio <text>", "Full biography").option("--short-bio <text>", "Short biography for cards").option("--model <model>", "Model ID").option("--tone <tone>", "Communication tone").option("--prompt <file-or-->", "System prompt (file path, or '-' for stdin)").option("--body <json>", "Request body as JSON, .json file, or '-' for stdin").addHelpText(
422
+ "after",
423
+ `
424
+ Examples:
425
+ $ nexus agent create --first-name Ada --last-name Lovelace --role "Assistant"
426
+ $ nexus agent create --first-name Bot --last-name Helper --role "Support" --model gpt-4o
427
+ $ cat prompt.md | nexus agent create --first-name Ada --last-name Lovelace --role "Assistant" --prompt -
428
+ $ nexus agent create --body '{"firstName":"Ada","lastName":"Lovelace","role":"Assistant"}'`
429
+ ).action(async (opts) => {
430
+ try {
431
+ const client = createClient(program2.optsWithGlobals());
432
+ const base = await resolveBody(opts.body);
433
+ const flags = {};
434
+ if (opts.firstName !== void 0) flags.firstName = opts.firstName;
435
+ if (opts.lastName !== void 0) flags.lastName = opts.lastName;
436
+ if (opts.role !== void 0) flags.role = opts.role;
437
+ if (opts.bio !== void 0) flags.bio = opts.bio;
438
+ if (opts.shortBio !== void 0) flags.shortBio = opts.shortBio;
439
+ if (opts.model !== void 0) flags.model = opts.model;
440
+ if (opts.tone !== void 0) flags.tone = opts.tone;
441
+ if (opts.prompt) flags.prompt = await resolveInputValue(opts.prompt);
442
+ const body = mergeBodyWithFlags(base, flags);
443
+ const agent2 = await client.agents.create(body);
444
+ printSuccess("Agent created.", {
445
+ id: agent2.id,
446
+ name: `${agent2.firstName} ${agent2.lastName}`
447
+ });
448
+ } catch (err) {
449
+ process.exitCode = handleError(err);
450
+ }
451
+ });
452
+ agent.command("update").description("Update an agent").argument("<id>", "Agent ID").option("--first-name <name>", "Agent first name").option("--last-name <name>", "Agent last name").option("--role <role>", "Agent role").option("--bio <text>", "Full biography").option("--short-bio <text>", "Short biography").option("--model <model>", "Model ID").option("--tone <tone>", "Communication tone").option("--prompt <file-or-->", "System prompt (file path, or '-' for stdin)").option("--body <json>", "Request body as JSON, .json file, or '-' for stdin").addHelpText(
453
+ "after",
454
+ `
455
+ Examples:
456
+ $ nexus agent update abc-123 --role "Senior Assistant"
457
+ $ echo "You are helpful" | nexus agent update abc-123 --prompt -
458
+ $ nexus agent update abc-123 --model gpt-4o --tone professional
459
+ $ nexus agent update abc-123 --body '{"tone":"friendly"}'`
460
+ ).action(async (id, opts) => {
461
+ try {
462
+ const client = createClient(program2.optsWithGlobals());
463
+ const base = await resolveBody(opts.body);
464
+ const flags = {};
465
+ if (opts.firstName !== void 0) flags.firstName = opts.firstName;
466
+ if (opts.lastName !== void 0) flags.lastName = opts.lastName;
467
+ if (opts.role !== void 0) flags.role = opts.role;
468
+ if (opts.bio !== void 0) flags.bio = opts.bio;
469
+ if (opts.shortBio !== void 0) flags.shortBio = opts.shortBio;
470
+ if (opts.model !== void 0) flags.model = opts.model;
471
+ if (opts.tone !== void 0) flags.tone = opts.tone;
472
+ if (opts.prompt) flags.prompt = await resolveInputValue(opts.prompt);
473
+ const body = mergeBodyWithFlags(base, flags);
474
+ const agent2 = await client.agents.update(id, body);
475
+ printSuccess("Agent updated.", { id: agent2.id });
476
+ } catch (err) {
477
+ process.exitCode = handleError(err);
478
+ }
479
+ });
480
+ agent.command("delete").description("Delete an agent").argument("<id>", "Agent ID").option("--yes", "Skip confirmation").option("--dry-run", "Preview without deleting").addHelpText(
481
+ "after",
482
+ `
483
+ Examples:
484
+ $ nexus agent delete abc-123
485
+ $ nexus agent delete abc-123 --yes
486
+ $ nexus agent delete abc-123 --dry-run`
487
+ ).action(async (id, opts) => {
488
+ try {
489
+ const client = createClient(program2.optsWithGlobals());
490
+ if (opts.dryRun) {
491
+ const agent2 = await client.agents.get(id);
492
+ console.log(
493
+ color.yellow("DRY RUN:") + ` Would delete agent "${agent2.firstName} ${agent2.lastName}" (${id})`
494
+ );
495
+ return;
496
+ }
497
+ if (!opts.yes && process.stdout.isTTY) {
498
+ const readline2 = await import("readline/promises");
499
+ const rl = readline2.createInterface({
500
+ input: process.stdin,
501
+ output: process.stdout
502
+ });
503
+ const answer = await rl.question(`Delete agent ${id}? This cannot be undone. [y/N] `);
504
+ rl.close();
505
+ if (answer.toLowerCase() !== "y") {
506
+ console.log("Aborted.");
507
+ return;
508
+ }
509
+ }
510
+ await client.agents.delete(id);
511
+ printSuccess("Agent deleted.", { id });
512
+ } catch (err) {
513
+ process.exitCode = handleError(err);
514
+ }
515
+ });
516
+ agent.command("duplicate").description("Duplicate an agent").argument("<id>", "Agent ID to duplicate").addHelpText(
517
+ "after",
518
+ `
519
+ Examples:
520
+ $ nexus agent duplicate abc-123
521
+ $ nexus agent duplicate abc-123 --json`
522
+ ).action(async (id) => {
523
+ try {
524
+ const client = createClient(program2.optsWithGlobals());
525
+ const agent2 = await client.agents.duplicate(id);
526
+ printSuccess("Agent duplicated.", {
527
+ id: agent2.id,
528
+ name: `${agent2.firstName} ${agent2.lastName}`
529
+ });
530
+ } catch (err) {
531
+ process.exitCode = handleError(err);
532
+ }
533
+ });
534
+ }
535
+
536
+ // src/commands/agent-tool.ts
537
+ init_output();
538
+ function registerAgentToolCommands(program2) {
539
+ const agentTool = program2.command("agent-tool").description("Manage agent tool configurations");
540
+ agentTool.command("list").description("List tools attached to an agent").argument("<agent-id>", "Agent ID").addHelpText(
541
+ "after",
542
+ `
543
+ Examples:
544
+ $ nexus agent-tool list agt-123
545
+ $ nexus agent-tool list agt-123 --json`
546
+ ).action(async (agentId) => {
547
+ try {
548
+ const client = createClient(program2.optsWithGlobals());
549
+ const tools = await client.agents.tools.list(agentId);
550
+ printTable(tools, [
551
+ { key: "id", label: "ID", width: 36 },
552
+ { key: "label", label: "LABEL", width: 25 },
553
+ { key: "type", label: "TYPE", width: 15 },
554
+ { key: "isActive", label: "ACTIVE", width: 8, format: (v) => v ? "yes" : "no" }
555
+ ]);
556
+ } catch (err) {
557
+ process.exitCode = handleError(err);
558
+ }
559
+ });
560
+ agentTool.command("get").description("Get tool configuration details").argument("<agent-id>", "Agent ID").argument("<tool-id>", "Tool config ID").addHelpText(
561
+ "after",
562
+ `
563
+ Examples:
564
+ $ nexus agent-tool get agt-123 tool-456
565
+ $ nexus agent-tool get agt-123 tool-456 --json`
566
+ ).action(async (agentId, toolId) => {
567
+ try {
568
+ const client = createClient(program2.optsWithGlobals());
569
+ const tool = await client.agents.tools.get(agentId, toolId);
570
+ printRecord(tool);
571
+ } catch (err) {
572
+ process.exitCode = handleError(err);
573
+ }
574
+ });
575
+ agentTool.command("create").description("Add a tool to an agent").argument("<agent-id>", "Agent ID").requiredOption("--label <label>", "Tool label").requiredOption("--type <type>", "Tool type (PLUGIN, WORKFLOW, TASK, COLLECTION, etc.)").option("--config <json>", "Tool configuration as JSON").option("--body <json>", "Request body as JSON, .json file, or '-' for stdin").addHelpText(
576
+ "after",
577
+ `
578
+ Examples:
579
+ $ nexus agent-tool create agt-123 --label "Gmail Send" --type PLUGIN
580
+ $ nexus agent-tool create agt-123 --label "Search KB" --type COLLECTION --config '{"collectionId":"col-789"}'
581
+ $ nexus agent-tool create agt-123 --body '{"label":"Search","type":"COLLECTION"}'`
582
+ ).action(async (agentId, opts) => {
583
+ try {
584
+ const client = createClient(program2.optsWithGlobals());
585
+ const base = await resolveBody(opts.body);
586
+ const flags = {};
587
+ if (opts.label !== void 0) flags.label = opts.label;
588
+ if (opts.type !== void 0) flags.type = opts.type;
589
+ if (opts.config) Object.assign(flags, JSON.parse(opts.config));
590
+ const body = mergeBodyWithFlags(base, flags);
591
+ const tool = await client.agents.tools.create(agentId, body);
592
+ printSuccess("Tool added to agent.", {
593
+ id: tool.id,
594
+ label: tool.label
595
+ });
596
+ } catch (err) {
597
+ process.exitCode = handleError(err);
598
+ }
599
+ });
600
+ agentTool.command("update").description("Update a tool configuration").argument("<agent-id>", "Agent ID").argument("<tool-id>", "Tool config ID").option("--label <label>", "New label").option("--config <json>", "Updated configuration as JSON").option("--body <json>", "Request body as JSON, .json file, or '-' for stdin").addHelpText(
601
+ "after",
602
+ `
603
+ Examples:
604
+ $ nexus agent-tool update agt-123 tool-456 --label "Renamed Tool"
605
+ $ nexus agent-tool update agt-123 tool-456 --body '{"label":"Renamed"}'`
606
+ ).action(async (agentId, toolId, opts) => {
607
+ try {
608
+ const client = createClient(program2.optsWithGlobals());
609
+ const base = await resolveBody(opts.body);
610
+ const flags = {};
611
+ if (opts.label !== void 0) flags.label = opts.label;
612
+ if (opts.config) Object.assign(flags, JSON.parse(opts.config));
613
+ const body = mergeBodyWithFlags(base, flags);
614
+ await client.agents.tools.update(agentId, toolId, body);
615
+ printSuccess("Tool updated.", { id: toolId });
616
+ } catch (err) {
617
+ process.exitCode = handleError(err);
618
+ }
619
+ });
620
+ agentTool.command("delete").description("Remove a tool from an agent").argument("<agent-id>", "Agent ID").argument("<tool-id>", "Tool config ID").option("--yes", "Skip confirmation").addHelpText(
621
+ "after",
622
+ `
623
+ Examples:
624
+ $ nexus agent-tool delete agt-123 tool-456
625
+ $ nexus agent-tool delete agt-123 tool-456 --yes`
626
+ ).action(async (agentId, toolId, opts) => {
627
+ try {
628
+ const client = createClient(program2.optsWithGlobals());
629
+ if (!opts.yes && process.stdout.isTTY) {
630
+ const readline2 = await import("readline/promises");
631
+ const rl = readline2.createInterface({ input: process.stdin, output: process.stdout });
632
+ const answer = await rl.question(`Remove tool ${toolId} from agent? [y/N] `);
633
+ rl.close();
634
+ if (answer.toLowerCase() !== "y") {
635
+ console.log("Aborted.");
636
+ return;
637
+ }
638
+ }
639
+ await client.agents.tools.delete(agentId, toolId);
640
+ printSuccess("Tool removed from agent.", { id: toolId });
641
+ } catch (err) {
642
+ process.exitCode = handleError(err);
643
+ }
644
+ });
645
+ agentTool.command("attach-collection").description("Attach a knowledge collection to an agent").argument("<agent-id>", "Agent ID").requiredOption("--collection-id <id>", "Collection ID").option("--label <label>", "Tool label").option("--instructions <text>", "Usage instructions").option("--body <json>", "Request body as JSON, .json file, or '-' for stdin").addHelpText(
646
+ "after",
647
+ `
648
+ Examples:
649
+ $ nexus agent-tool attach-collection agt-123 --collection-id col-456
650
+ $ nexus agent-tool attach-collection agt-123 --collection-id col-456 --label "FAQ Search"
651
+ $ nexus agent-tool attach-collection agt-123 --body '{"collectionId":"col-456","label":"FAQ"}'`
652
+ ).action(async (agentId, opts) => {
653
+ try {
654
+ const client = createClient(program2.optsWithGlobals());
655
+ const base = await resolveBody(opts.body);
656
+ const body = mergeBodyWithFlags(base, {
657
+ ...opts.collectionId !== void 0 && { collectionId: opts.collectionId },
658
+ ...opts.label !== void 0 && { label: opts.label },
659
+ ...opts.instructions !== void 0 && { instructions: opts.instructions }
660
+ });
661
+ const tool = await client.agents.tools.attachCollection(agentId, body);
662
+ printSuccess("Collection attached to agent.", {
663
+ id: tool.id,
664
+ label: tool.label
665
+ });
666
+ } catch (err) {
667
+ process.exitCode = handleError(err);
668
+ }
669
+ });
670
+ }
671
+
672
+ // src/commands/analytics.ts
673
+ init_output();
674
+ function registerAnalyticsCommands(program2) {
675
+ const analytics = program2.command("analytics").description("View analytics and metrics");
676
+ analytics.command("overview").description("Get analytics overview").option("--time-period <period>", "Time period (7d, 30d, 90d, etc.)").option("--deployment-id <id>", "Filter by deployment ID").addHelpText(
677
+ "after",
678
+ `
679
+ Examples:
680
+ $ nexus analytics overview
681
+ $ nexus analytics overview --time-period 30d
682
+ $ nexus analytics overview --deployment-id dep-123 --json`
683
+ ).action(async (opts) => {
684
+ try {
685
+ const client = createClient(program2.optsWithGlobals());
686
+ const result = await client.analytics.getOverview({
687
+ timePeriod: opts.timePeriod,
688
+ deploymentId: opts.deploymentId
689
+ });
690
+ printRecord(result);
691
+ } catch (err) {
692
+ process.exitCode = handleError(err);
693
+ }
694
+ });
695
+ addPaginationOptions(
696
+ analytics.command("feedback").description("List satisfaction feedback").option("--time-period <period>", "Time period").option("--deployment-id <id>", "Filter by deployment").option("--score <number>", "Filter by score", parseInt).addHelpText(
697
+ "after",
698
+ `
699
+ Examples:
700
+ $ nexus analytics feedback
701
+ $ nexus analytics feedback --time-period 7d --score 5
702
+ $ nexus analytics feedback --limit 20 --json`
703
+ )
704
+ ).action(async (opts) => {
705
+ try {
706
+ const client = createClient(program2.optsWithGlobals());
707
+ const result = await client.analytics.listFeedback({
708
+ ...getPaginationParams(opts),
709
+ timePeriod: opts.timePeriod,
710
+ deploymentId: opts.deploymentId,
711
+ score: opts.score
712
+ });
713
+ const data = result.data ?? [];
714
+ const meta = result.meta;
715
+ printList(data, meta, [
716
+ { key: "id", label: "ID", width: 36 },
717
+ { key: "score", label: "SCORE", width: 6 },
718
+ { key: "comment", label: "COMMENT", width: 40 },
719
+ { key: "createdAt", label: "DATE", width: 20 }
720
+ ]);
721
+ } catch (err) {
722
+ process.exitCode = handleError(err);
723
+ }
724
+ });
725
+ analytics.command("export").description("Export analytics as CSV").option("--time-period <period>", "Time period").option("--deployment-id <id>", "Filter by deployment").addHelpText(
726
+ "after",
727
+ `
728
+ Examples:
729
+ $ nexus analytics export
730
+ $ nexus analytics export --time-period 30d > analytics.csv
731
+ $ nexus analytics export --deployment-id dep-123`
732
+ ).action(async (opts) => {
733
+ try {
734
+ const client = createClient(program2.optsWithGlobals());
735
+ const result = await client.analytics.exportCsv({
736
+ timePeriod: opts.timePeriod,
737
+ deploymentId: opts.deploymentId
738
+ });
739
+ if (typeof result === "string") {
740
+ console.log(result);
741
+ } else {
742
+ console.log(JSON.stringify(result, null, 2));
743
+ }
744
+ } catch (err) {
745
+ process.exitCode = handleError(err);
746
+ }
747
+ });
748
+ }
749
+
750
+ // src/commands/api.ts
751
+ var import_sdk3 = require("@agent-nexus/sdk");
752
+ init_output();
753
+ function registerApiCommand(program2) {
754
+ program2.command("api").description("Call any Nexus API endpoint directly").argument("<method>", "HTTP method (GET, POST, PATCH, PUT, DELETE)").argument("<path>", "API path relative to /api/public/v1 (e.g. /models)").option("--body <json>", "Request body as JSON string, .json file path, or '-' for stdin").option("--query <key=value...>", "Query parameters (repeatable)", collect, []).addHelpText(
755
+ "after",
756
+ `
757
+ Examples:
758
+ $ nexus api GET /models
759
+ $ nexus api POST /agents --body '{"firstName":"Test","lastName":"Bot","role":"QA"}'
760
+ $ nexus api GET /agents --query page=1 --query limit=5
761
+ $ nexus api PATCH /agents/abc-123 --body payload.json
762
+ $ echo '{"text":"hello"}' | nexus api POST /emulator/dep-1/sessions/s-1/messages --body -`
763
+ ).action(async (method, path5, opts) => {
764
+ try {
765
+ const globals = program2.optsWithGlobals();
766
+ const http = new import_sdk3.HttpClient({
767
+ baseUrl: resolveBaseUrl(globals.baseUrl),
768
+ apiKey: resolveApiKey(globals.apiKey)
769
+ });
770
+ const body = await resolveBody(opts.body);
771
+ const query = parseQueryPairs(opts.query);
772
+ const normalizedPath = path5.startsWith("/") ? path5 : `/${path5}`;
773
+ const { data, meta } = await http.requestWithMeta(
774
+ method.toUpperCase(),
775
+ normalizedPath,
776
+ { body, query }
777
+ );
778
+ const output = meta ? { data, meta } : { data };
779
+ console.log(JSON.stringify(output, null, isJsonMode() ? void 0 : 2));
780
+ } catch (err) {
781
+ process.exitCode = handleError(err);
782
+ }
783
+ });
784
+ }
785
+ function collect(value, previous) {
786
+ return [...previous, value];
787
+ }
788
+ function parseQueryPairs(pairs) {
789
+ if (pairs.length === 0) return void 0;
790
+ const result = {};
791
+ for (const pair of pairs) {
792
+ const eq = pair.indexOf("=");
793
+ if (eq === -1) {
794
+ result[pair] = "true";
795
+ } else {
796
+ result[pair.slice(0, eq)] = pair.slice(eq + 1);
797
+ }
798
+ }
799
+ return result;
800
+ }
801
+
802
+ // src/commands/auth.ts
803
+ var import_node_child_process = require("child_process");
804
+ var import_node_process = require("process");
805
+ var import_promises = __toESM(require("readline/promises"));
806
+ init_output();
807
+ var SETTINGS_URL = "https://app.nexusgpt.io/app/settings/api-keys";
808
+ function registerAuthCommands(program2) {
809
+ const auth = program2.command("auth").description("Manage authentication");
810
+ auth.command("login").description("Authenticate with the Nexus API").option("--api-key <key>", "API key (skip interactive prompt)").option("--env <env>", "Environment: dev or production", "production").addHelpText(
811
+ "after",
812
+ `
813
+ Examples:
814
+ $ nexus auth login
815
+ $ nexus auth login --api-key nxs_abc123
816
+ $ nexus auth login --env dev`
817
+ ).action(async (opts) => {
818
+ const config = loadConfig();
819
+ if (opts.env === "dev") {
820
+ config.baseUrl = "http://localhost:3001";
821
+ }
822
+ const baseUrl = config.baseUrl ?? resolveBaseUrl();
823
+ let apiKey = opts.apiKey;
824
+ if (!apiKey) {
825
+ console.log(`Opening ${color.cyan(SETTINGS_URL)} ...`);
826
+ console.log("Create or copy an API key from the settings page.\n");
827
+ openUrl(SETTINGS_URL);
828
+ const rl = import_promises.default.createInterface({ input: import_node_process.stdin, output: import_node_process.stdout });
829
+ try {
830
+ apiKey = (await rl.question("Paste your API key (nxs_...): ")).trim();
831
+ } finally {
832
+ rl.close();
833
+ }
834
+ }
835
+ if (!apiKey) {
836
+ console.error(color.red("Error:") + " No key entered. Aborting.");
837
+ process.exitCode = 1;
838
+ return;
839
+ }
840
+ if (!apiKey.startsWith("nxs_")) {
841
+ console.error(
842
+ color.red("Error:") + ' Invalid key format \u2014 API keys start with "nxs_".\n nexus auth login --api-key nxs_YOUR_KEY'
843
+ );
844
+ process.exitCode = 1;
845
+ return;
846
+ }
847
+ console.log("Validating...");
848
+ const res = await fetch(`${baseUrl}/api/public/v1/agents?limit=1`, {
849
+ headers: { "api-key": apiKey, Accept: "application/json" }
850
+ });
851
+ if (!res.ok) {
852
+ console.error(
853
+ color.red("Error:") + ` Validation failed (HTTP ${res.status}). Check your key and try again.`
854
+ );
855
+ process.exitCode = 1;
856
+ return;
857
+ }
858
+ config.apiKey = apiKey;
859
+ if (opts.env === "dev") config.baseUrl = "http://localhost:3001";
860
+ saveConfig(config);
861
+ printSuccess("Logged in successfully.", {
862
+ config: "~/.nexus-mcp/config.json"
863
+ });
864
+ });
865
+ auth.command("logout").description("Remove stored credentials").addHelpText(
866
+ "after",
867
+ `
868
+ Examples:
869
+ $ nexus auth logout`
870
+ ).action(() => {
871
+ clearConfig();
872
+ printSuccess("Logged out. Credentials removed from ~/.nexus-mcp/config.json");
873
+ });
874
+ auth.command("whoami").description("Show current authentication status").addHelpText(
875
+ "after",
876
+ `
877
+ Examples:
878
+ $ nexus auth whoami`
879
+ ).action(async () => {
880
+ try {
881
+ const apiKey = resolveApiKey();
882
+ const baseUrl = resolveBaseUrl();
883
+ const res = await fetch(`${baseUrl}/api/public/v1/agents?limit=1`, {
884
+ headers: { "api-key": apiKey, Accept: "application/json" }
885
+ });
886
+ if (!res.ok) {
887
+ console.error(
888
+ color.red("Error:") + " API key is invalid or expired. Run: nexus auth login"
889
+ );
890
+ process.exitCode = 1;
891
+ return;
892
+ }
893
+ printSuccess("Authenticated.", {
894
+ api: baseUrl,
895
+ key: apiKey.slice(0, 8) + "..." + apiKey.slice(-4)
896
+ });
897
+ } catch (err) {
898
+ console.error(color.red("Error:") + " Not logged in. Run: nexus auth login");
899
+ process.exitCode = 1;
900
+ }
901
+ });
902
+ }
903
+ function openUrl(url) {
904
+ const platform = process.platform;
905
+ const cmd = platform === "darwin" ? "open" : platform === "win32" ? "start" : "xdg-open";
906
+ (0, import_node_child_process.exec)(`${cmd} ${JSON.stringify(url)}`);
907
+ }
908
+
909
+ // src/commands/collection.ts
910
+ init_output();
911
+ function registerCollectionCommands(program2) {
912
+ const collection = program2.command("collection").description("Manage knowledge collections");
913
+ collection.command("list").description("List knowledge collections").option("--search <query>", "Search by name").option("--limit <number>", "Max results", parseInt).addHelpText(
914
+ "after",
915
+ `
916
+ Examples:
917
+ $ nexus collection list
918
+ $ nexus collection list --search "product" --limit 10
919
+ $ nexus collection list --json`
920
+ ).action(async (opts) => {
921
+ try {
922
+ const client = createClient(program2.optsWithGlobals());
923
+ const result = await client.skills.listCollections({
924
+ search: opts.search,
925
+ limit: opts.limit
926
+ });
927
+ const items = result.items ?? [];
928
+ printTable(items, [
929
+ { key: "id", label: "ID", width: 36 },
930
+ { key: "name", label: "NAME", width: 25 },
931
+ { key: "displayName", label: "DISPLAY NAME", width: 25 },
932
+ { key: "documentCount", label: "DOCS", width: 6 }
933
+ ]);
934
+ } catch (err) {
935
+ process.exitCode = handleError(err);
936
+ }
937
+ });
938
+ collection.command("get").description("Get collection details").argument("<id>", "Collection ID").addHelpText(
939
+ "after",
940
+ `
941
+ Examples:
942
+ $ nexus collection get col-123
943
+ $ nexus collection get col-123 --json`
944
+ ).action(async (id) => {
945
+ try {
946
+ const client = createClient(program2.optsWithGlobals());
947
+ const col = await client.skills.getCollection(id);
948
+ printRecord(col, [
949
+ { key: "id", label: "ID" },
950
+ { key: "name", label: "Name" },
951
+ { key: "displayName", label: "Display Name" },
952
+ { key: "description", label: "Description" },
953
+ { key: "k", label: "k (results)" },
954
+ { key: "reranker", label: "Reranker", format: (v) => v ? "yes" : "no" },
955
+ { key: "documentCount", label: "Documents" }
956
+ ]);
957
+ } catch (err) {
958
+ process.exitCode = handleError(err);
959
+ }
960
+ });
961
+ collection.command("create").description("Create a knowledge collection").requiredOption("--name <name>", "Collection name (unique slug)").option("--display-name <name>", "Human-readable display name").option("--description <text>", "Collection description").option("--k <number>", "Number of results to retrieve", parseInt).option("--body <json>", "Request body as JSON, .json file, or '-' for stdin").addHelpText(
962
+ "after",
963
+ `
964
+ Examples:
965
+ $ nexus collection create --name "product-docs"
966
+ $ nexus collection create --name "faq" --display-name "FAQ" --k 15
967
+ $ nexus collection create --body '{"name":"faq","displayName":"FAQ"}'`
968
+ ).action(async (opts) => {
969
+ try {
970
+ const client = createClient(program2.optsWithGlobals());
971
+ const base = await resolveBody(opts.body);
972
+ const body = mergeBodyWithFlags(base, {
973
+ ...opts.name !== void 0 && { name: opts.name },
974
+ ...opts.displayName !== void 0 && { displayName: opts.displayName },
975
+ ...opts.description !== void 0 && { description: opts.description },
976
+ ...opts.k !== void 0 && { k: opts.k }
977
+ });
978
+ const col = await client.skills.createCollection(body);
979
+ printSuccess("Collection created.", {
980
+ id: col.id,
981
+ name: col.name
982
+ });
983
+ } catch (err) {
984
+ process.exitCode = handleError(err);
985
+ }
986
+ });
987
+ collection.command("update").description("Update a collection").argument("<id>", "Collection ID").option("--display-name <name>", "Display name").option("--description <text>", "Description").option("--k <number>", "Number of results", parseInt).option("--reranker <bool>", "Enable reranker (true/false)").option("--body <json>", "Request body as JSON, .json file, or '-' for stdin").addHelpText(
988
+ "after",
989
+ `
990
+ Examples:
991
+ $ nexus collection update col-123 --display-name "Updated FAQ"
992
+ $ nexus collection update col-123 --k 20 --reranker true
993
+ $ nexus collection update col-123 --body '{"displayName":"Updated"}'`
994
+ ).action(async (id, opts) => {
995
+ try {
996
+ const client = createClient(program2.optsWithGlobals());
997
+ const base = await resolveBody(opts.body);
998
+ const flags = {};
999
+ if (opts.displayName !== void 0) flags.displayName = opts.displayName;
1000
+ if (opts.description !== void 0) flags.description = opts.description;
1001
+ if (opts.k !== void 0) flags.k = opts.k;
1002
+ if (opts.reranker !== void 0) flags.reranker = opts.reranker === "true";
1003
+ const body = mergeBodyWithFlags(base, flags);
1004
+ await client.skills.updateCollection(id, body);
1005
+ printSuccess("Collection updated.", { id });
1006
+ } catch (err) {
1007
+ process.exitCode = handleError(err);
1008
+ }
1009
+ });
1010
+ collection.command("delete").description("Delete a collection").argument("<id>", "Collection ID").option("--yes", "Skip confirmation").addHelpText(
1011
+ "after",
1012
+ `
1013
+ Examples:
1014
+ $ nexus collection delete col-123
1015
+ $ nexus collection delete col-123 --yes`
1016
+ ).action(async (id, opts) => {
1017
+ try {
1018
+ const client = createClient(program2.optsWithGlobals());
1019
+ if (!opts.yes && process.stdout.isTTY) {
1020
+ const readline2 = await import("readline/promises");
1021
+ const rl = readline2.createInterface({ input: process.stdin, output: process.stdout });
1022
+ const answer = await rl.question(`Delete collection ${id}? [y/N] `);
1023
+ rl.close();
1024
+ if (answer.toLowerCase() !== "y") {
1025
+ console.log("Aborted.");
1026
+ return;
1027
+ }
1028
+ }
1029
+ await client.skills.deleteCollection(id);
1030
+ printSuccess("Collection deleted.", { id });
1031
+ } catch (err) {
1032
+ process.exitCode = handleError(err);
1033
+ }
1034
+ });
1035
+ collection.command("search").description("Search a collection").argument("<id>", "Collection ID").requiredOption("--query <query>", "Search query").option("--limit <number>", "Max results", parseInt).addHelpText(
1036
+ "after",
1037
+ `
1038
+ Examples:
1039
+ $ nexus collection search col-123 --query "how to reset password"
1040
+ $ nexus collection search col-123 --query "pricing" --limit 5 --json`
1041
+ ).action(async (id, opts) => {
1042
+ try {
1043
+ const client = createClient(program2.optsWithGlobals());
1044
+ const result = await client.skills.searchCollection(id, {
1045
+ query: opts.query,
1046
+ limit: opts.limit
1047
+ });
1048
+ if (isJsonMode()) {
1049
+ console.log(JSON.stringify(result, null, 2));
1050
+ } else {
1051
+ const results = result.results ?? result;
1052
+ if (Array.isArray(results)) {
1053
+ for (const r of results) {
1054
+ console.log(
1055
+ `\u2500 ${r.score?.toFixed(3) ?? "N/A"} ${r.content?.slice(0, 100) ?? JSON.stringify(r).slice(0, 100)}...`
1056
+ );
1057
+ }
1058
+ } else {
1059
+ console.log(JSON.stringify(result, null, 2));
1060
+ }
1061
+ }
1062
+ } catch (err) {
1063
+ process.exitCode = handleError(err);
1064
+ }
1065
+ });
1066
+ addPaginationOptions(
1067
+ collection.command("documents").description("List documents in a collection").argument("<id>", "Collection ID").addHelpText(
1068
+ "after",
1069
+ `
1070
+ Examples:
1071
+ $ nexus collection documents col-123
1072
+ $ nexus collection documents col-123 --limit 20 --json`
1073
+ )
1074
+ ).action(async (id, opts) => {
1075
+ try {
1076
+ const client = createClient(program2.optsWithGlobals());
1077
+ const result = await client.skills.listCollectionDocuments(
1078
+ id,
1079
+ getPaginationParams(opts)
1080
+ );
1081
+ const data = result.data ?? result.items ?? result;
1082
+ const meta = result.meta;
1083
+ printList(Array.isArray(data) ? data : [data], meta, [
1084
+ { key: "id", label: "ID", width: 36 },
1085
+ { key: "name", label: "NAME", width: 30 },
1086
+ { key: "type", label: "TYPE", width: 12 },
1087
+ { key: "status", label: "STATUS", width: 12 }
1088
+ ]);
1089
+ } catch (err) {
1090
+ process.exitCode = handleError(err);
1091
+ }
1092
+ });
1093
+ collection.command("attach-documents").description("Attach documents to a collection").argument("<id>", "Collection ID").requiredOption("--document-ids <ids>", "Comma-separated document IDs").addHelpText(
1094
+ "after",
1095
+ `
1096
+ Examples:
1097
+ $ nexus collection attach-documents col-123 --document-ids doc-1,doc-2,doc-3`
1098
+ ).action(async (id, opts) => {
1099
+ try {
1100
+ const client = createClient(program2.optsWithGlobals());
1101
+ await client.skills.attachDocumentsToCollection(id, {
1102
+ documentIds: opts.documentIds.split(",")
1103
+ });
1104
+ printSuccess("Documents attached to collection.", { id });
1105
+ } catch (err) {
1106
+ process.exitCode = handleError(err);
1107
+ }
1108
+ });
1109
+ collection.command("remove-document").description("Remove a document from a collection").argument("<id>", "Collection ID").argument("<document-id>", "Document ID").addHelpText(
1110
+ "after",
1111
+ `
1112
+ Examples:
1113
+ $ nexus collection remove-document col-123 doc-456`
1114
+ ).action(async (id, documentId) => {
1115
+ try {
1116
+ const client = createClient(program2.optsWithGlobals());
1117
+ await client.skills.removeCollectionDocument(id, documentId);
1118
+ printSuccess("Document removed from collection.", { id, documentId });
1119
+ } catch (err) {
1120
+ process.exitCode = handleError(err);
1121
+ }
1122
+ });
1123
+ collection.command("stats").description("Get collection statistics").argument("<id>", "Collection ID").addHelpText(
1124
+ "after",
1125
+ `
1126
+ Examples:
1127
+ $ nexus collection stats col-123
1128
+ $ nexus collection stats col-123 --json`
1129
+ ).action(async (id) => {
1130
+ try {
1131
+ const client = createClient(program2.optsWithGlobals());
1132
+ const stats = await client.skills.getCollectionStatistics(id);
1133
+ printRecord(stats);
1134
+ } catch (err) {
1135
+ process.exitCode = handleError(err);
1136
+ }
1137
+ });
1138
+ }
1139
+
1140
+ // src/commands/deployment.ts
1141
+ init_output();
1142
+ function registerDeploymentCommands(program2) {
1143
+ const deployment = program2.command("deployment").description("Manage agent deployments");
1144
+ addPaginationOptions(
1145
+ deployment.command("list").description("List deployments").option("--search <query>", "Search by name").option("--type <type>", "Filter by deployment type").option("--active", "Show only active deployments").addHelpText(
1146
+ "after",
1147
+ `
1148
+ Examples:
1149
+ $ nexus deployment list
1150
+ $ nexus deployment list --type whatsapp --limit 10
1151
+ $ nexus deployment list --active --json`
1152
+ )
1153
+ ).action(async (opts) => {
1154
+ try {
1155
+ const client = createClient(program2.optsWithGlobals());
1156
+ const { data, meta } = await client.deployments.list({
1157
+ ...getPaginationParams(opts),
1158
+ search: opts.search,
1159
+ type: opts.type,
1160
+ isActive: opts.active ? true : void 0
1161
+ });
1162
+ printList(data, meta, [
1163
+ { key: "id", label: "ID", width: 36 },
1164
+ { key: "name", label: "NAME", width: 25 },
1165
+ { key: "type", label: "TYPE", width: 15 },
1166
+ { key: "isActive", label: "ACTIVE", width: 8, format: (v) => v ? "yes" : "no" },
1167
+ { key: "agentId", label: "AGENT ID", width: 36 }
1168
+ ]);
1169
+ } catch (err) {
1170
+ process.exitCode = handleError(err);
1171
+ }
1172
+ });
1173
+ deployment.command("get").description("Get deployment details").argument("<id>", "Deployment ID").addHelpText(
1174
+ "after",
1175
+ `
1176
+ Examples:
1177
+ $ nexus deployment get dep-123
1178
+ $ nexus deployment get dep-123 --json`
1179
+ ).action(async (id) => {
1180
+ try {
1181
+ const client = createClient(program2.optsWithGlobals());
1182
+ const dep = await client.deployments.get(id);
1183
+ printRecord(dep, [
1184
+ { key: "id", label: "ID" },
1185
+ { key: "name", label: "Name" },
1186
+ { key: "type", label: "Type" },
1187
+ { key: "isActive", label: "Active", format: (v) => v ? "yes" : "no" },
1188
+ { key: "agentId", label: "Agent ID" },
1189
+ { key: "description", label: "Description" },
1190
+ { key: "createdAt", label: "Created" }
1191
+ ]);
1192
+ } catch (err) {
1193
+ process.exitCode = handleError(err);
1194
+ }
1195
+ });
1196
+ deployment.command("create").description("Create a new deployment").requiredOption("--name <name>", "Deployment name").requiredOption("--type <type>", "Deployment type (web, whatsapp, telegram, slack, etc.)").option("--agent-id <id>", "Agent ID to deploy").option("--description <text>", "Deployment description").option("--body <json>", "Request body as JSON, .json file, or '-' for stdin").addHelpText(
1197
+ "after",
1198
+ `
1199
+ Examples:
1200
+ $ nexus deployment create --name "Web Widget" --type web --agent-id agt-123
1201
+ $ nexus deployment create --name "WhatsApp Bot" --type whatsapp --agent-id agt-456
1202
+ $ nexus deployment create --body '{"name":"Widget","type":"web","agentId":"agt-123"}'`
1203
+ ).action(async (opts) => {
1204
+ try {
1205
+ const client = createClient(program2.optsWithGlobals());
1206
+ const base = await resolveBody(opts.body);
1207
+ const body = mergeBodyWithFlags(base, {
1208
+ ...opts.name !== void 0 && { name: opts.name },
1209
+ ...opts.type !== void 0 && { type: opts.type },
1210
+ ...opts.agentId !== void 0 && { agentId: opts.agentId },
1211
+ ...opts.description !== void 0 && { description: opts.description }
1212
+ });
1213
+ const dep = await client.deployments.create(body);
1214
+ printSuccess("Deployment created.", {
1215
+ id: dep.id,
1216
+ name: dep.name,
1217
+ type: dep.type
1218
+ });
1219
+ } catch (err) {
1220
+ process.exitCode = handleError(err);
1221
+ }
1222
+ });
1223
+ deployment.command("update").description("Update a deployment").argument("<id>", "Deployment ID").option("--name <name>", "Deployment name").option("--description <text>", "Description (use 'null' to clear)").option("--agent-id <id>", "Agent ID (use 'null' to detach)").option("--active <bool>", "Set active status (true/false)").option("--body <json>", "Request body as JSON, .json file, or '-' for stdin").addHelpText(
1224
+ "after",
1225
+ `
1226
+ Examples:
1227
+ $ nexus deployment update dep-123 --name "Renamed Widget"
1228
+ $ nexus deployment update dep-123 --active false
1229
+ $ nexus deployment update dep-123 --agent-id agt-456
1230
+ $ nexus deployment update dep-123 --body '{"name":"Renamed"}'`
1231
+ ).action(async (id, opts) => {
1232
+ try {
1233
+ const client = createClient(program2.optsWithGlobals());
1234
+ const base = await resolveBody(opts.body);
1235
+ const flags = {};
1236
+ if (opts.name !== void 0) flags.name = opts.name;
1237
+ if (opts.description !== void 0) {
1238
+ flags.description = opts.description === "null" ? null : opts.description;
1239
+ }
1240
+ if (opts.agentId !== void 0) {
1241
+ flags.agentId = opts.agentId === "null" ? null : opts.agentId;
1242
+ }
1243
+ if (opts.active !== void 0) {
1244
+ flags.isActive = opts.active === "true";
1245
+ }
1246
+ const body = mergeBodyWithFlags(base, flags);
1247
+ await client.deployments.update(id, body);
1248
+ printSuccess("Deployment updated.", { id });
1249
+ } catch (err) {
1250
+ process.exitCode = handleError(err);
1251
+ }
1252
+ });
1253
+ deployment.command("delete").description("Delete a deployment").argument("<id>", "Deployment ID").option("--yes", "Skip confirmation").option("--dry-run", "Preview without deleting").addHelpText(
1254
+ "after",
1255
+ `
1256
+ Examples:
1257
+ $ nexus deployment delete dep-123
1258
+ $ nexus deployment delete dep-123 --yes
1259
+ $ nexus deployment delete dep-123 --dry-run`
1260
+ ).action(async (id, opts) => {
1261
+ try {
1262
+ const client = createClient(program2.optsWithGlobals());
1263
+ if (opts.dryRun) {
1264
+ const dep = await client.deployments.get(id);
1265
+ console.log(
1266
+ color.yellow("DRY RUN:") + ` Would delete deployment "${dep.name}" (${id})`
1267
+ );
1268
+ return;
1269
+ }
1270
+ if (!opts.yes && process.stdout.isTTY) {
1271
+ const readline2 = await import("readline/promises");
1272
+ const rl = readline2.createInterface({
1273
+ input: process.stdin,
1274
+ output: process.stdout
1275
+ });
1276
+ const answer = await rl.question(
1277
+ `Delete deployment ${id}? This cannot be undone. [y/N] `
1278
+ );
1279
+ rl.close();
1280
+ if (answer.toLowerCase() !== "y") {
1281
+ console.log("Aborted.");
1282
+ return;
1283
+ }
1284
+ }
1285
+ await client.deployments.delete(id);
1286
+ printSuccess("Deployment deleted.", { id });
1287
+ } catch (err) {
1288
+ process.exitCode = handleError(err);
1289
+ }
1290
+ });
1291
+ deployment.command("stats").description("Get deployment statistics").argument("<id>", "Deployment ID").addHelpText(
1292
+ "after",
1293
+ `
1294
+ Examples:
1295
+ $ nexus deployment stats dep-123
1296
+ $ nexus deployment stats dep-123 --json`
1297
+ ).action(async (id) => {
1298
+ try {
1299
+ const client = createClient(program2.optsWithGlobals());
1300
+ const stats = await client.deployments.getStatistics(id);
1301
+ printRecord(stats);
1302
+ } catch (err) {
1303
+ process.exitCode = handleError(err);
1304
+ }
1305
+ });
1306
+ deployment.command("duplicate").description("Duplicate a deployment").argument("<id>", "Deployment ID").addHelpText(
1307
+ "after",
1308
+ `
1309
+ Examples:
1310
+ $ nexus deployment duplicate dep-123`
1311
+ ).action(async (id) => {
1312
+ try {
1313
+ const client = createClient(program2.optsWithGlobals());
1314
+ const dep = await client.deployments.duplicate(id);
1315
+ printSuccess("Deployment duplicated.", {
1316
+ id: dep.id,
1317
+ name: dep.name
1318
+ });
1319
+ } catch (err) {
1320
+ process.exitCode = handleError(err);
1321
+ }
1322
+ });
1323
+ deployment.command("embed-config").description("Get deployment embed configuration").argument("<id>", "Deployment ID").addHelpText(
1324
+ "after",
1325
+ `
1326
+ Examples:
1327
+ $ nexus deployment embed-config dep-123
1328
+ $ nexus deployment embed-config dep-123 --json`
1329
+ ).action(async (id) => {
1330
+ try {
1331
+ const client = createClient(program2.optsWithGlobals());
1332
+ const config = await client.deployments.getEmbedConfig(id);
1333
+ printRecord(config);
1334
+ } catch (err) {
1335
+ process.exitCode = handleError(err);
1336
+ }
1337
+ });
1338
+ deployment.command("embed-config-update").description("Update deployment embed configuration").argument("<id>", "Deployment ID").option("--body <json>", "Request body as JSON, .json file, or '-' for stdin").addHelpText(
1339
+ "after",
1340
+ `
1341
+ Examples:
1342
+ $ nexus deployment embed-config-update dep-123 --body '{"theme":"dark"}'
1343
+ $ nexus deployment embed-config-update dep-123 --body config.json`
1344
+ ).action(async (id, opts) => {
1345
+ try {
1346
+ const client = createClient(program2.optsWithGlobals());
1347
+ const body = await resolveBody(opts.body) ?? {};
1348
+ await client.deployments.updateEmbedConfig(id, body);
1349
+ printSuccess("Embed config updated.", { id });
1350
+ } catch (err) {
1351
+ process.exitCode = handleError(err);
1352
+ }
1353
+ });
1354
+ const depFolder = deployment.command("folder").description("Manage deployment folders");
1355
+ depFolder.command("list").description("List deployment folders").addHelpText(
1356
+ "after",
1357
+ `
1358
+ Examples:
1359
+ $ nexus deployment folder list
1360
+ $ nexus deployment folder list --json`
1361
+ ).action(async () => {
1362
+ try {
1363
+ const client = createClient(program2.optsWithGlobals());
1364
+ const result = await client.deploymentFolders.list();
1365
+ const folders = result.folders ?? result.data ?? result;
1366
+ printTable(Array.isArray(folders) ? folders : [folders], [
1367
+ { key: "id", label: "ID", width: 36 },
1368
+ { key: "name", label: "NAME", width: 30 }
1369
+ ]);
1370
+ } catch (err) {
1371
+ process.exitCode = handleError(err);
1372
+ }
1373
+ });
1374
+ depFolder.command("create").description("Create a deployment folder").requiredOption("--name <name>", "Folder name").option("--body <json>", "Request body as JSON, .json file, or '-' for stdin").addHelpText(
1375
+ "after",
1376
+ `
1377
+ Examples:
1378
+ $ nexus deployment folder create --name "Production"
1379
+ $ nexus deployment folder create --body '{"name":"Staging"}'`
1380
+ ).action(async (opts) => {
1381
+ try {
1382
+ const client = createClient(program2.optsWithGlobals());
1383
+ const base = await resolveBody(opts.body);
1384
+ const body = mergeBodyWithFlags(base, {
1385
+ ...opts.name !== void 0 && { name: opts.name }
1386
+ });
1387
+ const folder = await client.deploymentFolders.create(body);
1388
+ printSuccess("Deployment folder created.", {
1389
+ id: folder.id,
1390
+ name: folder.name
1391
+ });
1392
+ } catch (err) {
1393
+ process.exitCode = handleError(err);
1394
+ }
1395
+ });
1396
+ depFolder.command("update").description("Update a deployment folder").argument("<id>", "Folder ID").option("--name <name>", "Folder name").option("--body <json>", "Request body as JSON, .json file, or '-' for stdin").addHelpText(
1397
+ "after",
1398
+ `
1399
+ Examples:
1400
+ $ nexus deployment folder update fld-123 --name "Renamed"
1401
+ $ nexus deployment folder update fld-123 --body '{"name":"Renamed"}'`
1402
+ ).action(async (id, opts) => {
1403
+ try {
1404
+ const client = createClient(program2.optsWithGlobals());
1405
+ const base = await resolveBody(opts.body);
1406
+ const body = mergeBodyWithFlags(base, {
1407
+ ...opts.name !== void 0 && { name: opts.name }
1408
+ });
1409
+ await client.deploymentFolders.update(id, body);
1410
+ printSuccess("Deployment folder updated.", { id });
1411
+ } catch (err) {
1412
+ process.exitCode = handleError(err);
1413
+ }
1414
+ });
1415
+ depFolder.command("delete").description("Delete a deployment folder").argument("<id>", "Folder ID").option("--yes", "Skip confirmation").addHelpText(
1416
+ "after",
1417
+ `
1418
+ Examples:
1419
+ $ nexus deployment folder delete fld-123
1420
+ $ nexus deployment folder delete fld-123 --yes`
1421
+ ).action(async (id, opts) => {
1422
+ try {
1423
+ const client = createClient(program2.optsWithGlobals());
1424
+ if (!opts.yes && process.stdout.isTTY) {
1425
+ const readline2 = await import("readline/promises");
1426
+ const rl = readline2.createInterface({ input: process.stdin, output: process.stdout });
1427
+ const answer = await rl.question(`Delete deployment folder ${id}? [y/N] `);
1428
+ rl.close();
1429
+ if (answer.toLowerCase() !== "y") {
1430
+ console.log("Aborted.");
1431
+ return;
1432
+ }
1433
+ }
1434
+ await client.deploymentFolders.delete(id);
1435
+ printSuccess("Deployment folder deleted.", { id });
1436
+ } catch (err) {
1437
+ process.exitCode = handleError(err);
1438
+ }
1439
+ });
1440
+ depFolder.command("assign").description("Assign a deployment to a folder").requiredOption("--deployment-id <id>", "Deployment ID").requiredOption("--folder-id <id>", "Folder ID").addHelpText(
1441
+ "after",
1442
+ `
1443
+ Examples:
1444
+ $ nexus deployment folder assign --deployment-id dep-123 --folder-id fld-456`
1445
+ ).action(async (opts) => {
1446
+ try {
1447
+ const client = createClient(program2.optsWithGlobals());
1448
+ await client.deploymentFolders.assign({
1449
+ deploymentId: opts.deploymentId,
1450
+ folderId: opts.folderId
1451
+ });
1452
+ printSuccess("Deployment assigned to folder.", {
1453
+ deploymentId: opts.deploymentId,
1454
+ folderId: opts.folderId
1455
+ });
1456
+ } catch (err) {
1457
+ process.exitCode = handleError(err);
1458
+ }
1459
+ });
1460
+ }
1461
+
1462
+ // src/commands/document.ts
1463
+ var import_node_fs2 = __toESM(require("fs"));
1464
+ var import_node_path2 = __toESM(require("path"));
1465
+ init_output();
1466
+ function registerDocumentCommands(program2) {
1467
+ const document = program2.command("document").description("Manage knowledge documents");
1468
+ addPaginationOptions(
1469
+ document.command("list").description("List documents").option("--search <query>", "Search by name").option("--type <type>", "Filter by type").option("--status <status>", "Filter by status").addHelpText(
1470
+ "after",
1471
+ `
1472
+ Examples:
1473
+ $ nexus document list
1474
+ $ nexus document list --search "report" --limit 10
1475
+ $ nexus document list --status PROCESSED --json`
1476
+ )
1477
+ ).action(async (opts) => {
1478
+ try {
1479
+ const client = createClient(program2.optsWithGlobals());
1480
+ const { data, meta } = await client.documents.list({
1481
+ ...getPaginationParams(opts),
1482
+ search: opts.search,
1483
+ type: opts.type,
1484
+ status: opts.status
1485
+ });
1486
+ printList(data, meta, [
1487
+ { key: "id", label: "ID", width: 36 },
1488
+ { key: "name", label: "NAME", width: 30 },
1489
+ { key: "type", label: "TYPE", width: 12 },
1490
+ { key: "status", label: "STATUS", width: 12 }
1491
+ ]);
1492
+ } catch (err) {
1493
+ process.exitCode = handleError(err);
1494
+ }
1495
+ });
1496
+ document.command("get").description("Get document details").argument("<id>", "Document ID").addHelpText(
1497
+ "after",
1498
+ `
1499
+ Examples:
1500
+ $ nexus document get doc-123
1501
+ $ nexus document get doc-123 --json`
1502
+ ).action(async (id) => {
1503
+ try {
1504
+ const client = createClient(program2.optsWithGlobals());
1505
+ const doc = await client.documents.get(id);
1506
+ printRecord(doc, [
1507
+ { key: "id", label: "ID" },
1508
+ { key: "name", label: "Name" },
1509
+ { key: "type", label: "Type" },
1510
+ { key: "status", label: "Status" },
1511
+ { key: "processingProgress", label: "Progress" },
1512
+ { key: "createdAt", label: "Created" }
1513
+ ]);
1514
+ } catch (err) {
1515
+ process.exitCode = handleError(err);
1516
+ }
1517
+ });
1518
+ document.command("upload").description("Upload a file as a document").argument("<file-path>", "Path to the file").option("--description <text>", "Document description").addHelpText(
1519
+ "after",
1520
+ `
1521
+ Examples:
1522
+ $ nexus document upload ./report.pdf
1523
+ $ nexus document upload ./data.csv --description "Q4 sales data"
1524
+ $ nexus document upload ./manual.txt --json`
1525
+ ).action(async (filePath, opts) => {
1526
+ try {
1527
+ const client = createClient(program2.optsWithGlobals());
1528
+ const absPath = import_node_path2.default.resolve(filePath);
1529
+ if (!import_node_fs2.default.existsSync(absPath)) {
1530
+ console.error(`Error: File not found: ${absPath}`);
1531
+ process.exitCode = 1;
1532
+ return;
1533
+ }
1534
+ const buffer = import_node_fs2.default.readFileSync(absPath);
1535
+ const blob = new Blob([buffer]);
1536
+ const fileName = import_node_path2.default.basename(absPath);
1537
+ const doc = await client.documents.uploadFile(blob, fileName, opts.description);
1538
+ printSuccess("Document uploaded.", {
1539
+ id: doc.id,
1540
+ name: doc.name ?? fileName
1541
+ });
1542
+ } catch (err) {
1543
+ process.exitCode = handleError(err);
1544
+ }
1545
+ });
1546
+ document.command("create-text").description("Create a text document").requiredOption("--name <name>", "Document name").requiredOption("--content <text-or-->", "Content (text, or '-' for stdin)").option("--description <text>", "Document description").option("--body <json>", "Request body as JSON, .json file, or '-' for stdin").addHelpText(
1547
+ "after",
1548
+ `
1549
+ Examples:
1550
+ $ nexus document create-text --name "FAQ" --content "Q: How do I...\\nA: You can..."
1551
+ $ cat content.md | nexus document create-text --name "Guide" --content -
1552
+ $ nexus document create-text --body '{"name":"FAQ","content":"..."}'`
1553
+ ).action(async (opts) => {
1554
+ try {
1555
+ const client = createClient(program2.optsWithGlobals());
1556
+ const base = await resolveBody(opts.body);
1557
+ const flags = {};
1558
+ if (opts.name !== void 0) flags.name = opts.name;
1559
+ if (opts.content) flags.content = await resolveInputValue(opts.content);
1560
+ if (opts.description !== void 0) flags.description = opts.description;
1561
+ const body = mergeBodyWithFlags(base, flags);
1562
+ const doc = await client.documents.createText(body);
1563
+ printSuccess("Text document created.", {
1564
+ id: doc.id,
1565
+ name: doc.name
1566
+ });
1567
+ } catch (err) {
1568
+ process.exitCode = handleError(err);
1569
+ }
1570
+ });
1571
+ document.command("add-website").description("Crawl a website and create document(s)").requiredOption("--url <url>", "Website URL").option("--mode <mode>", "Crawl mode: sitemap, single, etc.", "single").option("--body <json>", "Request body as JSON, .json file, or '-' for stdin").addHelpText(
1572
+ "after",
1573
+ `
1574
+ Examples:
1575
+ $ nexus document add-website --url https://docs.example.com --mode sitemap
1576
+ $ nexus document add-website --url https://example.com/page --mode single
1577
+ $ nexus document add-website --body '{"url":"https://example.com","mode":"sitemap"}'`
1578
+ ).action(async (opts) => {
1579
+ try {
1580
+ const client = createClient(program2.optsWithGlobals());
1581
+ const base = await resolveBody(opts.body);
1582
+ const body = mergeBodyWithFlags(base, {
1583
+ ...opts.url !== void 0 && { url: opts.url },
1584
+ ...opts.mode !== void 0 && { mode: opts.mode }
1585
+ });
1586
+ const doc = await client.documents.addWebsite(body);
1587
+ printSuccess("Website document created.", {
1588
+ id: doc.id,
1589
+ name: doc.name
1590
+ });
1591
+ } catch (err) {
1592
+ process.exitCode = handleError(err);
1593
+ }
1594
+ });
1595
+ document.command("delete").description("Delete a document").argument("<id>", "Document ID").option("--yes", "Skip confirmation").addHelpText(
1596
+ "after",
1597
+ `
1598
+ Examples:
1599
+ $ nexus document delete doc-123
1600
+ $ nexus document delete doc-123 --yes`
1601
+ ).action(async (id, opts) => {
1602
+ try {
1603
+ const client = createClient(program2.optsWithGlobals());
1604
+ if (!opts.yes && process.stdout.isTTY) {
1605
+ const readline2 = await import("readline/promises");
1606
+ const rl = readline2.createInterface({ input: process.stdin, output: process.stdout });
1607
+ const answer = await rl.question(`Delete document ${id}? [y/N] `);
1608
+ rl.close();
1609
+ if (answer.toLowerCase() !== "y") {
1610
+ console.log("Aborted.");
1611
+ return;
1612
+ }
1613
+ }
1614
+ await client.documents.delete(id);
1615
+ printSuccess("Document deleted.", { id });
1616
+ } catch (err) {
1617
+ process.exitCode = handleError(err);
1618
+ }
1619
+ });
1620
+ }
1621
+
1622
+ // src/commands/emulator.ts
1623
+ init_output();
1624
+ function registerEmulatorCommands(program2) {
1625
+ const emulator = program2.command("emulator").description("Test deployments via the emulator");
1626
+ const session = emulator.command("session").description("Manage emulator sessions");
1627
+ session.command("create").description("Create an emulator session").argument("<deployment-id>", "Deployment ID").option("--body <json>", "Request body as JSON, .json file, or '-' for stdin").addHelpText(
1628
+ "after",
1629
+ `
1630
+ Examples:
1631
+ $ nexus emulator session create dep-123
1632
+ $ nexus emulator session create dep-123 --body '{"participant":"user-1"}'
1633
+ $ nexus emulator session create dep-123 --json`
1634
+ ).action(async (deploymentId, opts) => {
1635
+ try {
1636
+ const client = createClient(program2.optsWithGlobals());
1637
+ const body = await resolveBody(opts.body);
1638
+ const s = await client.emulator.createSession(deploymentId, body);
1639
+ printRecord(s, [
1640
+ { key: "id", label: "ID" },
1641
+ { key: "deploymentId", label: "Deployment ID" },
1642
+ { key: "status", label: "Status" },
1643
+ { key: "createdAt", label: "Created" }
1644
+ ]);
1645
+ } catch (err) {
1646
+ process.exitCode = handleError(err);
1647
+ }
1648
+ });
1649
+ session.command("list").description("List emulator sessions").argument("<deployment-id>", "Deployment ID").addHelpText(
1650
+ "after",
1651
+ `
1652
+ Examples:
1653
+ $ nexus emulator session list dep-123
1654
+ $ nexus emulator session list dep-123 --json`
1655
+ ).action(async (deploymentId) => {
1656
+ try {
1657
+ const client = createClient(program2.optsWithGlobals());
1658
+ const result = await client.emulator.listSessions(deploymentId);
1659
+ const items = Array.isArray(result) ? result : result.data ?? result;
1660
+ printList(items, void 0, [
1661
+ { key: "id", label: "ID", width: 36 },
1662
+ { key: "createdAt", label: "CREATED", width: 26 }
1663
+ ]);
1664
+ } catch (err) {
1665
+ process.exitCode = handleError(err);
1666
+ }
1667
+ });
1668
+ session.command("get").description("Get emulator session details (with messages)").argument("<deployment-id>", "Deployment ID").argument("<session-id>", "Session ID").addHelpText(
1669
+ "after",
1670
+ `
1671
+ Examples:
1672
+ $ nexus emulator session get dep-123 sess-456
1673
+ $ nexus emulator session get dep-123 sess-456 --json`
1674
+ ).action(async (deploymentId, sessionId) => {
1675
+ try {
1676
+ const client = createClient(program2.optsWithGlobals());
1677
+ const s = await client.emulator.getSession(deploymentId, sessionId);
1678
+ printRecord(s, [
1679
+ { key: "id", label: "ID" },
1680
+ { key: "deploymentId", label: "Deployment ID" },
1681
+ { key: "status", label: "Status" },
1682
+ { key: "messages", label: "Messages" },
1683
+ { key: "createdAt", label: "Created" }
1684
+ ]);
1685
+ } catch (err) {
1686
+ process.exitCode = handleError(err);
1687
+ }
1688
+ });
1689
+ session.command("delete").description("Delete an emulator session").argument("<deployment-id>", "Deployment ID").argument("<session-id>", "Session ID").option("--yes", "Skip confirmation").addHelpText(
1690
+ "after",
1691
+ `
1692
+ Examples:
1693
+ $ nexus emulator session delete dep-123 sess-456
1694
+ $ nexus emulator session delete dep-123 sess-456 --yes`
1695
+ ).action(async (deploymentId, sessionId, opts) => {
1696
+ try {
1697
+ const client = createClient(program2.optsWithGlobals());
1698
+ if (!opts.yes && process.stdout.isTTY) {
1699
+ const readline2 = await import("readline/promises");
1700
+ const rl = readline2.createInterface({ input: process.stdin, output: process.stdout });
1701
+ const answer = await rl.question(`Delete emulator session ${sessionId}? [y/N] `);
1702
+ rl.close();
1703
+ if (answer.toLowerCase() !== "y") {
1704
+ console.log("Aborted.");
1705
+ return;
1706
+ }
1707
+ }
1708
+ await client.emulator.deleteSession(deploymentId, sessionId);
1709
+ printSuccess("Session deleted.", { sessionId });
1710
+ } catch (err) {
1711
+ process.exitCode = handleError(err);
1712
+ }
1713
+ });
1714
+ emulator.command("send").description("Send a message in an emulator session").argument("<deployment-id>", "Deployment ID").argument("<session-id>", "Session ID").option("--text <message>", "Message text").option("--body <json>", "Request body as JSON, .json file, or '-' for stdin").addHelpText(
1715
+ "after",
1716
+ `
1717
+ Examples:
1718
+ $ nexus emulator send dep-123 sess-456 --text "Hello, agent!"
1719
+ $ nexus emulator send dep-123 sess-456 --body '{"text":"Hi","participant":"user-1","debug":true}'
1720
+ $ nexus emulator send dep-123 sess-456 --text "Test" --json`
1721
+ ).action(async (deploymentId, sessionId, opts) => {
1722
+ try {
1723
+ const client = createClient(program2.optsWithGlobals());
1724
+ const base = await resolveBody(opts.body);
1725
+ const body = mergeBodyWithFlags(base, {
1726
+ text: opts.text
1727
+ });
1728
+ const result = await client.emulator.sendMessage(deploymentId, sessionId, body);
1729
+ printRecord(result);
1730
+ } catch (err) {
1731
+ process.exitCode = handleError(err);
1732
+ }
1733
+ });
1734
+ const scenario = emulator.command("scenario").description("Manage emulator scenarios");
1735
+ scenario.command("save").description("Save an emulator session as a scenario").option("--session-id <id>", "Session ID").option("--deployment-id <id>", "Deployment ID").option("--name <name>", "Scenario name").option("--description <text>", "Scenario description").option("--body <json>", "Request body as JSON, .json file, or '-' for stdin").addHelpText(
1736
+ "after",
1737
+ `
1738
+ Examples:
1739
+ $ nexus emulator scenario save --session-id sess-123 --deployment-id dep-456 --name "Happy path"
1740
+ $ nexus emulator scenario save --body '{"sessionId":"sess-123","deploymentId":"dep-456","name":"Edge case"}'`
1741
+ ).action(async (opts) => {
1742
+ try {
1743
+ const client = createClient(program2.optsWithGlobals());
1744
+ const base = await resolveBody(opts.body);
1745
+ const body = mergeBodyWithFlags(base, {
1746
+ sessionId: opts.sessionId,
1747
+ deploymentId: opts.deploymentId,
1748
+ name: opts.name,
1749
+ description: opts.description
1750
+ });
1751
+ const result = await client.emulator.saveScenario(body);
1752
+ printRecord(result, [
1753
+ { key: "id", label: "ID" },
1754
+ { key: "name", label: "Name" },
1755
+ { key: "description", label: "Description" },
1756
+ { key: "deploymentId", label: "Deployment ID" },
1757
+ { key: "sessionId", label: "Session ID" },
1758
+ { key: "createdAt", label: "Created" }
1759
+ ]);
1760
+ } catch (err) {
1761
+ process.exitCode = handleError(err);
1762
+ }
1763
+ });
1764
+ scenario.command("list").description("List emulator scenarios").option("--deployment-id <id>", "Filter by deployment ID").addHelpText(
1765
+ "after",
1766
+ `
1767
+ Examples:
1768
+ $ nexus emulator scenario list
1769
+ $ nexus emulator scenario list --deployment-id dep-123
1770
+ $ nexus emulator scenario list --json`
1771
+ ).action(async (opts) => {
1772
+ try {
1773
+ const client = createClient(program2.optsWithGlobals());
1774
+ const result = await client.emulator.listScenarios({
1775
+ deploymentId: opts.deploymentId
1776
+ });
1777
+ const items = Array.isArray(result) ? result : result.data ?? result;
1778
+ printList(items, void 0, [
1779
+ { key: "id", label: "ID", width: 36 },
1780
+ { key: "name", label: "NAME", width: 30 },
1781
+ { key: "deploymentId", label: "DEPLOYMENT", width: 36 },
1782
+ { key: "createdAt", label: "CREATED", width: 26 }
1783
+ ]);
1784
+ } catch (err) {
1785
+ process.exitCode = handleError(err);
1786
+ }
1787
+ });
1788
+ scenario.command("get").description("Get scenario details").argument("<scenario-id>", "Scenario ID").addHelpText(
1789
+ "after",
1790
+ `
1791
+ Examples:
1792
+ $ nexus emulator scenario get scn-123
1793
+ $ nexus emulator scenario get scn-123 --json`
1794
+ ).action(async (scenarioId) => {
1795
+ try {
1796
+ const client = createClient(program2.optsWithGlobals());
1797
+ const s = await client.emulator.getScenario(scenarioId);
1798
+ printRecord(s, [
1799
+ { key: "id", label: "ID" },
1800
+ { key: "name", label: "Name" },
1801
+ { key: "description", label: "Description" },
1802
+ { key: "deploymentId", label: "Deployment ID" },
1803
+ { key: "sessionId", label: "Session ID" },
1804
+ { key: "messages", label: "Messages" },
1805
+ { key: "createdAt", label: "Created" }
1806
+ ]);
1807
+ } catch (err) {
1808
+ process.exitCode = handleError(err);
1809
+ }
1810
+ });
1811
+ scenario.command("replay").description("Replay a scenario against a deployment").argument("<scenario-id>", "Scenario ID").option("--deployment-id <id>", "Deployment ID to replay against").option("--body <json>", "Request body as JSON, .json file, or '-' for stdin").addHelpText(
1812
+ "after",
1813
+ `
1814
+ Examples:
1815
+ $ nexus emulator scenario replay scn-123 --deployment-id dep-456
1816
+ $ nexus emulator scenario replay scn-123 --body '{"deploymentId":"dep-456"}'
1817
+ $ nexus emulator scenario replay scn-123 --deployment-id dep-456 --json`
1818
+ ).action(async (scenarioId, opts) => {
1819
+ try {
1820
+ const client = createClient(program2.optsWithGlobals());
1821
+ const base = await resolveBody(opts.body);
1822
+ const body = mergeBodyWithFlags(base, {
1823
+ deploymentId: opts.deploymentId
1824
+ });
1825
+ const result = await client.emulator.replayScenario(scenarioId, body);
1826
+ printRecord(result);
1827
+ } catch (err) {
1828
+ process.exitCode = handleError(err);
1829
+ }
1830
+ });
1831
+ scenario.command("delete").description("Delete a scenario").argument("<scenario-id>", "Scenario ID").option("--yes", "Skip confirmation").addHelpText(
1832
+ "after",
1833
+ `
1834
+ Examples:
1835
+ $ nexus emulator scenario delete scn-123
1836
+ $ nexus emulator scenario delete scn-123 --yes`
1837
+ ).action(async (scenarioId, opts) => {
1838
+ try {
1839
+ const client = createClient(program2.optsWithGlobals());
1840
+ if (!opts.yes && process.stdout.isTTY) {
1841
+ const readline2 = await import("readline/promises");
1842
+ const rl = readline2.createInterface({ input: process.stdin, output: process.stdout });
1843
+ const answer = await rl.question(`Delete scenario ${scenarioId}? [y/N] `);
1844
+ rl.close();
1845
+ if (answer.toLowerCase() !== "y") {
1846
+ console.log("Aborted.");
1847
+ return;
1848
+ }
1849
+ }
1850
+ await client.emulator.deleteScenario(scenarioId);
1851
+ printSuccess("Scenario deleted.", { scenarioId });
1852
+ } catch (err) {
1853
+ process.exitCode = handleError(err);
1854
+ }
1855
+ });
1856
+ }
1857
+
1858
+ // src/commands/evaluation.ts
1859
+ init_output();
1860
+ function registerEvaluationCommands(program2) {
1861
+ const eval_ = program2.command("eval").description("Manage evaluations for AI tasks");
1862
+ const session = eval_.command("session").description("Manage evaluation sessions");
1863
+ session.command("create").description("Create an evaluation session").argument("<task-id>", "Task ID").option("--name <name>", "Session name").option("--description <text>", "Session description").option("--body <json>", "Request body as JSON, .json file, or '-' for stdin").addHelpText(
1864
+ "after",
1865
+ `
1866
+ Examples:
1867
+ $ nexus eval session create task-123 --name "Accuracy Test v1"
1868
+ $ nexus eval session create task-123 --name "Edge cases" --description "Tests edge cases"
1869
+ $ nexus eval session create task-123 --body '{"name":"Full test","description":"..."}'`
1870
+ ).action(async (taskId, opts) => {
1871
+ try {
1872
+ const client = createClient(program2.optsWithGlobals());
1873
+ const base = await resolveBody(opts.body);
1874
+ const body = mergeBodyWithFlags(base, {
1875
+ name: opts.name,
1876
+ description: opts.description
1877
+ });
1878
+ const s = await client.evaluations.createSession(taskId, body);
1879
+ printRecord(s, [
1880
+ { key: "id", label: "ID" },
1881
+ { key: "name", label: "Name" },
1882
+ { key: "description", label: "Description" },
1883
+ { key: "status", label: "Status" },
1884
+ { key: "createdAt", label: "Created" }
1885
+ ]);
1886
+ } catch (err) {
1887
+ process.exitCode = handleError(err);
1888
+ }
1889
+ });
1890
+ addPaginationOptions(
1891
+ session.command("list").description("List evaluation sessions").argument("<task-id>", "Task ID").addHelpText(
1892
+ "after",
1893
+ `
1894
+ Examples:
1895
+ $ nexus eval session list task-123
1896
+ $ nexus eval session list task-123 --limit 10
1897
+ $ nexus eval session list task-123 --json`
1898
+ )
1899
+ ).action(async (taskId, opts) => {
1900
+ try {
1901
+ const client = createClient(program2.optsWithGlobals());
1902
+ const { data, meta } = await client.evaluations.listSessions(taskId, {
1903
+ ...getPaginationParams(opts)
1904
+ });
1905
+ printList(
1906
+ data,
1907
+ meta,
1908
+ [
1909
+ { key: "id", label: "ID", width: 36 },
1910
+ { key: "name", label: "NAME", width: 30 },
1911
+ { key: "status", label: "STATUS", width: 15 },
1912
+ { key: "createdAt", label: "CREATED", width: 26 }
1913
+ ]
1914
+ );
1915
+ } catch (err) {
1916
+ process.exitCode = handleError(err);
1917
+ }
1918
+ });
1919
+ session.command("get").description("Get evaluation session details").argument("<task-id>", "Task ID").argument("<session-id>", "Session ID").addHelpText(
1920
+ "after",
1921
+ `
1922
+ Examples:
1923
+ $ nexus eval session get task-123 sess-456
1924
+ $ nexus eval session get task-123 sess-456 --json`
1925
+ ).action(async (taskId, sessionId) => {
1926
+ try {
1927
+ const client = createClient(program2.optsWithGlobals());
1928
+ const s = await client.evaluations.getSession(taskId, sessionId);
1929
+ printRecord(s, [
1930
+ { key: "id", label: "ID" },
1931
+ { key: "name", label: "Name" },
1932
+ { key: "description", label: "Description" },
1933
+ { key: "status", label: "Status" },
1934
+ { key: "rowCount", label: "Rows" },
1935
+ { key: "createdAt", label: "Created" }
1936
+ ]);
1937
+ } catch (err) {
1938
+ process.exitCode = handleError(err);
1939
+ }
1940
+ });
1941
+ session.command("delete").description("Delete an evaluation session").argument("<task-id>", "Task ID").argument("<session-id>", "Session ID").option("--yes", "Skip confirmation").addHelpText(
1942
+ "after",
1943
+ `
1944
+ Examples:
1945
+ $ nexus eval session delete task-123 sess-456
1946
+ $ nexus eval session delete task-123 sess-456 --yes`
1947
+ ).action(async (taskId, sessionId, opts) => {
1948
+ try {
1949
+ const client = createClient(program2.optsWithGlobals());
1950
+ if (!opts.yes && process.stdout.isTTY) {
1951
+ const readline2 = await import("readline/promises");
1952
+ const rl = readline2.createInterface({ input: process.stdin, output: process.stdout });
1953
+ const answer = await rl.question(`Delete evaluation session ${sessionId}? [y/N] `);
1954
+ rl.close();
1955
+ if (answer.toLowerCase() !== "y") {
1956
+ console.log("Aborted.");
1957
+ return;
1958
+ }
1959
+ }
1960
+ await client.evaluations.deleteSession(taskId, sessionId);
1961
+ printSuccess("Evaluation session deleted.", { sessionId });
1962
+ } catch (err) {
1963
+ process.exitCode = handleError(err);
1964
+ }
1965
+ });
1966
+ const dataset = eval_.command("dataset").description("Manage evaluation dataset rows");
1967
+ addPaginationOptions(
1968
+ dataset.command("list").description("List dataset rows").argument("<task-id>", "Task ID").argument("<session-id>", "Session ID").addHelpText(
1969
+ "after",
1970
+ `
1971
+ Examples:
1972
+ $ nexus eval dataset list task-123 sess-456
1973
+ $ nexus eval dataset list task-123 sess-456 --limit 20
1974
+ $ nexus eval dataset list task-123 sess-456 --json`
1975
+ )
1976
+ ).action(async (taskId, sessionId, opts) => {
1977
+ try {
1978
+ const client = createClient(program2.optsWithGlobals());
1979
+ const { data, meta } = await client.evaluations.getDatasetRows(taskId, sessionId, {
1980
+ ...getPaginationParams(opts)
1981
+ });
1982
+ printList(
1983
+ data,
1984
+ meta,
1985
+ [
1986
+ { key: "id", label: "ID", width: 36 },
1987
+ { key: "input", label: "INPUT", width: 40 },
1988
+ { key: "expectedOutput", label: "EXPECTED OUTPUT", width: 40 }
1989
+ ]
1990
+ );
1991
+ } catch (err) {
1992
+ process.exitCode = handleError(err);
1993
+ }
1994
+ });
1995
+ dataset.command("add").description("Add a row to the evaluation dataset").argument("<task-id>", "Task ID").argument("<session-id>", "Session ID").option("--body <json>", "Request body as JSON, .json file, or '-' for stdin").addHelpText(
1996
+ "after",
1997
+ `
1998
+ Examples:
1999
+ $ nexus eval dataset add task-123 sess-456 --body '{"input":"Hello","expectedOutput":"Hi there"}'
2000
+ $ nexus eval dataset add task-123 sess-456 --body dataset-row.json`
2001
+ ).action(async (taskId, sessionId, opts) => {
2002
+ try {
2003
+ const client = createClient(program2.optsWithGlobals());
2004
+ const body = await resolveBody(opts.body);
2005
+ const row = await client.evaluations.addDatasetRow(taskId, sessionId, body);
2006
+ printRecord(row, [
2007
+ { key: "id", label: "ID" },
2008
+ { key: "input", label: "Input" },
2009
+ { key: "expectedOutput", label: "Expected Output" }
2010
+ ]);
2011
+ } catch (err) {
2012
+ process.exitCode = handleError(err);
2013
+ }
2014
+ });
2015
+ eval_.command("execute").description("Execute an evaluation run").argument("<task-id>", "Task ID").argument("<session-id>", "Session ID").addHelpText(
2016
+ "after",
2017
+ `
2018
+ Examples:
2019
+ $ nexus eval execute task-123 sess-456
2020
+ $ nexus eval execute task-123 sess-456 --json`
2021
+ ).action(async (taskId, sessionId) => {
2022
+ try {
2023
+ const client = createClient(program2.optsWithGlobals());
2024
+ const result = await client.evaluations.execute(taskId, sessionId);
2025
+ printRecord(result);
2026
+ } catch (err) {
2027
+ process.exitCode = handleError(err);
2028
+ }
2029
+ });
2030
+ eval_.command("judge").description("Judge evaluation results with AI").argument("<task-id>", "Task ID").argument("<session-id>", "Session ID").option("--body <json>", "Request body as JSON, .json file, or '-' for stdin").addHelpText(
2031
+ "after",
2032
+ `
2033
+ Examples:
2034
+ $ nexus eval judge task-123 sess-456
2035
+ $ nexus eval judge task-123 sess-456 --body '{"judgeModel":"gpt-4o","judgePrompt":"Rate accuracy"}'
2036
+ $ nexus eval judge task-123 sess-456 --json`
2037
+ ).action(async (taskId, sessionId, opts) => {
2038
+ try {
2039
+ const client = createClient(program2.optsWithGlobals());
2040
+ const body = await resolveBody(opts.body);
2041
+ const result = await client.evaluations.judge(taskId, sessionId, body);
2042
+ printRecord(result);
2043
+ } catch (err) {
2044
+ process.exitCode = handleError(err);
2045
+ }
2046
+ });
2047
+ addPaginationOptions(
2048
+ eval_.command("results").description("Get evaluation results").argument("<task-id>", "Task ID").argument("<session-id>", "Session ID").addHelpText(
2049
+ "after",
2050
+ `
2051
+ Examples:
2052
+ $ nexus eval results task-123 sess-456
2053
+ $ nexus eval results task-123 sess-456 --limit 50
2054
+ $ nexus eval results task-123 sess-456 --json`
2055
+ )
2056
+ ).action(async (taskId, sessionId, opts) => {
2057
+ try {
2058
+ const client = createClient(program2.optsWithGlobals());
2059
+ const { data, meta } = await client.evaluations.getResults(taskId, sessionId, {
2060
+ ...getPaginationParams(opts)
2061
+ });
2062
+ printList(
2063
+ data,
2064
+ meta,
2065
+ [
2066
+ { key: "id", label: "ID", width: 36 },
2067
+ { key: "input", label: "INPUT", width: 30 },
2068
+ { key: "output", label: "OUTPUT", width: 30 },
2069
+ { key: "score", label: "SCORE", width: 8 },
2070
+ { key: "passed", label: "PASSED", width: 8 }
2071
+ ]
2072
+ );
2073
+ } catch (err) {
2074
+ process.exitCode = handleError(err);
2075
+ }
2076
+ });
2077
+ eval_.command("formats").description("List available evaluation formats").addHelpText(
2078
+ "after",
2079
+ `
2080
+ Examples:
2081
+ $ nexus eval formats
2082
+ $ nexus eval formats --json`
2083
+ ).action(async () => {
2084
+ try {
2085
+ const client = createClient(program2.optsWithGlobals());
2086
+ const result = await client.evaluations.listFormats();
2087
+ const items = Array.isArray(result) ? result : result.data ?? result;
2088
+ printList(items, void 0, [
2089
+ { key: "id", label: "ID", width: 36 },
2090
+ { key: "name", label: "NAME", width: 30 },
2091
+ { key: "description", label: "DESCRIPTION", width: 50 }
2092
+ ]);
2093
+ } catch (err) {
2094
+ process.exitCode = handleError(err);
2095
+ }
2096
+ });
2097
+ eval_.command("judges").description("List available judge models").addHelpText(
2098
+ "after",
2099
+ `
2100
+ Examples:
2101
+ $ nexus eval judges
2102
+ $ nexus eval judges --json`
2103
+ ).action(async () => {
2104
+ try {
2105
+ const client = createClient(program2.optsWithGlobals());
2106
+ const result = await client.evaluations.listJudges();
2107
+ const items = Array.isArray(result) ? result : result.data ?? result;
2108
+ printList(items, void 0, [
2109
+ { key: "id", label: "ID", width: 36 },
2110
+ { key: "name", label: "NAME", width: 30 },
2111
+ { key: "provider", label: "PROVIDER", width: 20 }
2112
+ ]);
2113
+ } catch (err) {
2114
+ process.exitCode = handleError(err);
2115
+ }
2116
+ });
2117
+ }
2118
+
2119
+ // src/commands/execution.ts
2120
+ init_output();
2121
+ function registerExecutionCommands(program2) {
2122
+ const execution = program2.command("execution").description("View workflow execution history");
2123
+ addPaginationOptions(
2124
+ execution.command("list").description("List workflow executions").option("--workflow-id <id>", "Filter by workflow ID").option("--status <status>", "Filter by status").addHelpText(
2125
+ "after",
2126
+ `
2127
+ Examples:
2128
+ $ nexus execution list
2129
+ $ nexus execution list --workflow-id wf-123 --limit 5
2130
+ $ nexus execution list --status COMPLETED --json`
2131
+ )
2132
+ ).action(async (opts) => {
2133
+ try {
2134
+ const client = createClient(program2.optsWithGlobals());
2135
+ let result;
2136
+ if (opts.workflowId) {
2137
+ result = await client.workflowExecutions.listByWorkflow(opts.workflowId, {
2138
+ ...getPaginationParams(opts),
2139
+ status: opts.status
2140
+ });
2141
+ } else {
2142
+ result = await client.workflowExecutions.list({
2143
+ ...getPaginationParams(opts),
2144
+ status: opts.status
2145
+ });
2146
+ }
2147
+ const data = result.data ?? result;
2148
+ const meta = result.meta;
2149
+ printList(Array.isArray(data) ? data : [data], meta, [
2150
+ { key: "id", label: "ID", width: 36 },
2151
+ { key: "workflowId", label: "WORKFLOW", width: 36 },
2152
+ { key: "status", label: "STATUS", width: 12 },
2153
+ { key: "createdAt", label: "STARTED", width: 20 }
2154
+ ]);
2155
+ } catch (err) {
2156
+ process.exitCode = handleError(err);
2157
+ }
2158
+ });
2159
+ execution.command("get").description("Get execution details").argument("<id>", "Execution ID").addHelpText(
2160
+ "after",
2161
+ `
2162
+ Examples:
2163
+ $ nexus execution get exec-123
2164
+ $ nexus execution get exec-123 --json`
2165
+ ).action(async (id) => {
2166
+ try {
2167
+ const client = createClient(program2.optsWithGlobals());
2168
+ const exec2 = await client.workflowExecutions.get(id);
2169
+ printRecord(exec2, [
2170
+ { key: "id", label: "ID" },
2171
+ { key: "workflowId", label: "Workflow" },
2172
+ { key: "status", label: "Status" },
2173
+ { key: "createdAt", label: "Started" },
2174
+ { key: "completedAt", label: "Completed" },
2175
+ { key: "duration", label: "Duration" }
2176
+ ]);
2177
+ } catch (err) {
2178
+ process.exitCode = handleError(err);
2179
+ }
2180
+ });
2181
+ execution.command("graph").description("Get execution graph (node-level results)").argument("<id>", "Execution ID").addHelpText(
2182
+ "after",
2183
+ `
2184
+ Examples:
2185
+ $ nexus execution graph exec-123
2186
+ $ nexus execution graph exec-123 --json`
2187
+ ).action(async (id) => {
2188
+ try {
2189
+ const client = createClient(program2.optsWithGlobals());
2190
+ const graph = await client.workflowExecutions.getGraph(id);
2191
+ printRecord(graph);
2192
+ } catch (err) {
2193
+ process.exitCode = handleError(err);
2194
+ }
2195
+ });
2196
+ execution.command("output").description("Get execution output").argument("<id>", "Execution ID").addHelpText(
2197
+ "after",
2198
+ `
2199
+ Examples:
2200
+ $ nexus execution output exec-123
2201
+ $ nexus execution output exec-123 --json`
2202
+ ).action(async (id) => {
2203
+ try {
2204
+ const client = createClient(program2.optsWithGlobals());
2205
+ const output = await client.workflowExecutions.getOutput(id);
2206
+ printRecord(output);
2207
+ } catch (err) {
2208
+ process.exitCode = handleError(err);
2209
+ }
2210
+ });
2211
+ execution.command("retry").description("Retry a failed node in an execution").argument("<id>", "Execution ID").argument("<node-id>", "Node ID to retry").addHelpText(
2212
+ "after",
2213
+ `
2214
+ Examples:
2215
+ $ nexus execution retry exec-123 node-456`
2216
+ ).action(async (id, nodeId) => {
2217
+ try {
2218
+ const client = createClient(program2.optsWithGlobals());
2219
+ const result = await client.workflowExecutions.retryNode(id, nodeId);
2220
+ printSuccess("Node retry initiated.", { executionId: id, nodeId, ...result });
2221
+ } catch (err) {
2222
+ process.exitCode = handleError(err);
2223
+ }
2224
+ });
2225
+ execution.command("export").description("Export execution data").argument("<id>", "Execution ID").addHelpText(
2226
+ "after",
2227
+ `
2228
+ Examples:
2229
+ $ nexus execution export exec-123
2230
+ $ nexus execution export exec-123 --json`
2231
+ ).action(async (id) => {
2232
+ try {
2233
+ const client = createClient(program2.optsWithGlobals());
2234
+ const data = await client.workflowExecutions.export(id);
2235
+ printRecord(data);
2236
+ } catch (err) {
2237
+ process.exitCode = handleError(err);
2238
+ }
2239
+ });
2240
+ execution.command("node-result").description("Get result of a specific node in an execution").argument("<id>", "Execution ID").argument("<node-id>", "Node ID").addHelpText(
2241
+ "after",
2242
+ `
2243
+ Examples:
2244
+ $ nexus execution node-result exec-123 node-456
2245
+ $ nexus execution node-result exec-123 node-456 --json`
2246
+ ).action(async (id, nodeId) => {
2247
+ try {
2248
+ const client = createClient(program2.optsWithGlobals());
2249
+ const result = await client.workflowExecutions.getNodeResult(id, nodeId);
2250
+ printRecord(result);
2251
+ } catch (err) {
2252
+ process.exitCode = handleError(err);
2253
+ }
2254
+ });
2255
+ }
2256
+
2257
+ // src/commands/external-tool.ts
2258
+ init_output();
2259
+ function registerExternalToolCommands(program2) {
2260
+ const externalTool = program2.command("external-tool").description("Manage external tools (OpenAPI integrations)");
2261
+ externalTool.command("list").description("List external tools").option("--search <query>", "Search by name").option("--limit <number>", "Max results", parseInt).addHelpText(
2262
+ "after",
2263
+ `
2264
+ Examples:
2265
+ $ nexus external-tool list
2266
+ $ nexus external-tool list --search "weather" --limit 10
2267
+ $ nexus external-tool list --json`
2268
+ ).action(async (opts) => {
2269
+ try {
2270
+ const client = createClient(program2.optsWithGlobals());
2271
+ const result = await client.skills.listExternalTools({
2272
+ search: opts.search,
2273
+ limit: opts.limit
2274
+ });
2275
+ const items = Array.isArray(result) ? result : result.items ?? result.data ?? result;
2276
+ printList(items, void 0, [
2277
+ { key: "id", label: "ID", width: 36 },
2278
+ { key: "name", label: "NAME", width: 30 },
2279
+ { key: "description", label: "DESCRIPTION", width: 40 },
2280
+ { key: "createdAt", label: "CREATED", width: 26 }
2281
+ ]);
2282
+ } catch (err) {
2283
+ process.exitCode = handleError(err);
2284
+ }
2285
+ });
2286
+ externalTool.command("get").description("Get external tool details").argument("<id>", "External tool ID").addHelpText(
2287
+ "after",
2288
+ `
2289
+ Examples:
2290
+ $ nexus external-tool get ext-123
2291
+ $ nexus external-tool get ext-123 --json`
2292
+ ).action(async (id) => {
2293
+ try {
2294
+ const client = createClient(program2.optsWithGlobals());
2295
+ const t = await client.skills.getExternalTool(id);
2296
+ printRecord(t, [
2297
+ { key: "id", label: "ID" },
2298
+ { key: "name", label: "Name" },
2299
+ { key: "description", label: "Description" },
2300
+ { key: "baseUrl", label: "Base URL" },
2301
+ { key: "createdAt", label: "Created" },
2302
+ { key: "updatedAt", label: "Updated" }
2303
+ ]);
2304
+ } catch (err) {
2305
+ process.exitCode = handleError(err);
2306
+ }
2307
+ });
2308
+ externalTool.command("create").description("Create an external tool from an OpenAPI spec").option("--body <json>", "Request body as JSON, .json file, or '-' for stdin").addHelpText(
2309
+ "after",
2310
+ `
2311
+ Examples:
2312
+ $ nexus external-tool create --body openapi-tool.json
2313
+ $ nexus external-tool create --body '{"name":"Weather API","spec":{...}}'
2314
+ $ cat spec.json | nexus external-tool create --body -`
2315
+ ).action(async (opts) => {
2316
+ try {
2317
+ const client = createClient(program2.optsWithGlobals());
2318
+ const body = await resolveBody(opts.body);
2319
+ const t = await client.skills.createExternalTool(body);
2320
+ printSuccess("External tool created.", {
2321
+ id: t.id,
2322
+ name: t.name
2323
+ });
2324
+ } catch (err) {
2325
+ process.exitCode = handleError(err);
2326
+ }
2327
+ });
2328
+ externalTool.command("test").description("Test an external tool operation").argument("<id>", "External tool ID").option("--operation-id <op>", "Operation ID to test").option("--input <json>", "Input parameters as JSON").option("--body <json>", "Request body as JSON, .json file, or '-' for stdin").addHelpText(
2329
+ "after",
2330
+ `
2331
+ Examples:
2332
+ $ nexus external-tool test ext-123 --operation-id getWeather --input '{"city":"London"}'
2333
+ $ nexus external-tool test ext-123 --body '{"operationId":"getWeather","input":{"city":"London"}}'
2334
+ $ nexus external-tool test ext-123 --operation-id listItems --json`
2335
+ ).action(async (id, opts) => {
2336
+ try {
2337
+ const client = createClient(program2.optsWithGlobals());
2338
+ const base = await resolveBody(opts.body);
2339
+ const flags = {};
2340
+ if (opts.operationId) flags.operationId = opts.operationId;
2341
+ if (opts.input) flags.input = JSON.parse(opts.input);
2342
+ const body = mergeBodyWithFlags(base, flags);
2343
+ const result = await client.skills.testExternalTool(id, body);
2344
+ printRecord(result);
2345
+ } catch (err) {
2346
+ process.exitCode = handleError(err);
2347
+ }
2348
+ });
2349
+ }
2350
+
2351
+ // src/commands/folder.ts
2352
+ init_output();
2353
+ function registerFolderCommands(program2) {
2354
+ const folder = program2.command("folder").description("Manage agent folders");
2355
+ folder.command("list").description("List all folders").addHelpText(
2356
+ "after",
2357
+ `
2358
+ Examples:
2359
+ $ nexus folder list
2360
+ $ nexus folder list --json`
2361
+ ).action(async () => {
2362
+ try {
2363
+ const client = createClient(program2.optsWithGlobals());
2364
+ const result = await client.folders.list();
2365
+ const folders = result.folders ?? result;
2366
+ printTable(Array.isArray(folders) ? folders : [folders], [
2367
+ { key: "id", label: "ID", width: 36 },
2368
+ { key: "name", label: "NAME", width: 30 },
2369
+ { key: "parentId", label: "PARENT", width: 36 }
2370
+ ]);
2371
+ } catch (err) {
2372
+ process.exitCode = handleError(err);
2373
+ }
2374
+ });
2375
+ folder.command("create").description("Create a new folder").requiredOption("--name <name>", "Folder name").option("--parent-id <id>", "Parent folder ID for nesting").option("--body <json>", "Request body as JSON, .json file, or '-' for stdin").addHelpText(
2376
+ "after",
2377
+ `
2378
+ Examples:
2379
+ $ nexus folder create --name "Customer Support"
2380
+ $ nexus folder create --name "Sub Team" --parent-id abc-123
2381
+ $ nexus folder create --body '{"name":"Support"}'`
2382
+ ).action(async (opts) => {
2383
+ try {
2384
+ const client = createClient(program2.optsWithGlobals());
2385
+ const base = await resolveBody(opts.body);
2386
+ const body = mergeBodyWithFlags(base, {
2387
+ ...opts.name !== void 0 && { name: opts.name },
2388
+ ...opts.parentId !== void 0 && { parentId: opts.parentId }
2389
+ });
2390
+ const folder2 = await client.folders.create(body);
2391
+ printSuccess("Folder created.", {
2392
+ id: folder2.id,
2393
+ name: folder2.name
2394
+ });
2395
+ } catch (err) {
2396
+ process.exitCode = handleError(err);
2397
+ }
2398
+ });
2399
+ folder.command("update").description("Update a folder").argument("<id>", "Folder ID").option("--name <name>", "New folder name").option("--parent-id <id>", "New parent folder ID (use 'null' for root)").option("--body <json>", "Request body as JSON, .json file, or '-' for stdin").addHelpText(
2400
+ "after",
2401
+ `
2402
+ Examples:
2403
+ $ nexus folder update abc-123 --name "Renamed Folder"
2404
+ $ nexus folder update abc-123 --parent-id null
2405
+ $ nexus folder update abc-123 --body '{"name":"Renamed"}'`
2406
+ ).action(async (id, opts) => {
2407
+ try {
2408
+ const client = createClient(program2.optsWithGlobals());
2409
+ const base = await resolveBody(opts.body);
2410
+ const flags = {};
2411
+ if (opts.name !== void 0) flags.name = opts.name;
2412
+ if (opts.parentId !== void 0) {
2413
+ flags.parentId = opts.parentId === "null" ? null : opts.parentId;
2414
+ }
2415
+ const body = mergeBodyWithFlags(base, flags);
2416
+ await client.folders.update(id, body);
2417
+ printSuccess("Folder updated.", { id });
2418
+ } catch (err) {
2419
+ process.exitCode = handleError(err);
2420
+ }
2421
+ });
2422
+ folder.command("delete").description("Delete a folder (agents are unassigned, not deleted)").argument("<id>", "Folder ID").option("--yes", "Skip confirmation").addHelpText(
2423
+ "after",
2424
+ `
2425
+ Examples:
2426
+ $ nexus folder delete abc-123
2427
+ $ nexus folder delete abc-123 --yes`
2428
+ ).action(async (id, opts) => {
2429
+ try {
2430
+ const client = createClient(program2.optsWithGlobals());
2431
+ if (!opts.yes && process.stdout.isTTY) {
2432
+ const readline2 = await import("readline/promises");
2433
+ const rl = readline2.createInterface({
2434
+ input: process.stdin,
2435
+ output: process.stdout
2436
+ });
2437
+ const answer = await rl.question(
2438
+ `Delete folder ${id}? Agents will be unassigned. [y/N] `
2439
+ );
2440
+ rl.close();
2441
+ if (answer.toLowerCase() !== "y") {
2442
+ console.log("Aborted.");
2443
+ return;
2444
+ }
2445
+ }
2446
+ await client.folders.delete(id);
2447
+ printSuccess("Folder deleted.", { id });
2448
+ } catch (err) {
2449
+ process.exitCode = handleError(err);
2450
+ }
2451
+ });
2452
+ folder.command("assign").description("Assign an agent to a folder (or remove from folder)").requiredOption("--agent-id <id>", "Agent ID").requiredOption("--folder-id <id>", "Folder ID (use 'null' to remove)").option("--body <json>", "Request body as JSON, .json file, or '-' for stdin").addHelpText(
2453
+ "after",
2454
+ `
2455
+ Examples:
2456
+ $ nexus folder assign --agent-id agt-123 --folder-id fld-456
2457
+ $ nexus folder assign --agent-id agt-123 --folder-id null
2458
+ $ nexus folder assign --body '{"agentId":"agt-123","folderId":"fld-456"}'`
2459
+ ).action(async (opts) => {
2460
+ try {
2461
+ const client = createClient(program2.optsWithGlobals());
2462
+ const base = await resolveBody(opts.body);
2463
+ const flags = {};
2464
+ if (opts.agentId !== void 0) flags.agentId = opts.agentId;
2465
+ if (opts.folderId !== void 0) {
2466
+ flags.folderId = opts.folderId === "null" ? null : opts.folderId;
2467
+ }
2468
+ const assignBody = mergeBodyWithFlags(base, flags);
2469
+ const folderId = assignBody.folderId;
2470
+ await client.folders.assignAgent(assignBody);
2471
+ if (folderId) {
2472
+ printSuccess("Agent assigned to folder.", {
2473
+ agentId: opts.agentId,
2474
+ folderId
2475
+ });
2476
+ } else {
2477
+ printSuccess("Agent removed from folder.", {
2478
+ agentId: opts.agentId
2479
+ });
2480
+ }
2481
+ } catch (err) {
2482
+ process.exitCode = handleError(err);
2483
+ }
2484
+ });
2485
+ }
2486
+
2487
+ // src/commands/model.ts
2488
+ init_output();
2489
+ function registerModelCommands(program2) {
2490
+ const model = program2.command("model").description("Manage AI models");
2491
+ model.command("list").description("List available AI models").addHelpText(
2492
+ "after",
2493
+ `
2494
+ Examples:
2495
+ $ nexus model list
2496
+ $ nexus model list --json`
2497
+ ).action(async () => {
2498
+ try {
2499
+ const client = createClient(program2.optsWithGlobals());
2500
+ const result = await client.models.list();
2501
+ const items = Array.isArray(result) ? result : result.data ?? result;
2502
+ printList(items, void 0, [
2503
+ { key: "name", label: "NAME", width: 30 },
2504
+ { key: "provider", label: "PROVIDER", width: 20 },
2505
+ { key: "id", label: "ID", width: 36 },
2506
+ { key: "contextWindow", label: "CONTEXT", width: 12 }
2507
+ ]);
2508
+ } catch (err) {
2509
+ process.exitCode = handleError(err);
2510
+ }
2511
+ });
2512
+ }
2513
+
2514
+ // src/commands/prompt-assistant.ts
2515
+ init_output();
2516
+ function registerPromptAssistantCommands(program2) {
2517
+ const pa = program2.command("prompt-assistant").description("AI-powered prompt writing assistant");
2518
+ pa.command("chat").description("Send a message to the prompt assistant").option("--message <text-or->", "Message text (or '-' for stdin)").option("--mode <mode>", "Mode: agent or ai-task").option("--thread-id <id>", "Thread ID for multi-turn conversations").option("--body <json>", "Request body as JSON, .json file, or '-' for stdin").addHelpText(
2519
+ "after",
2520
+ `
2521
+ Examples:
2522
+ $ nexus prompt-assistant chat --message "Create a customer support agent" --mode agent
2523
+ $ nexus prompt-assistant chat --message "Improve the prompt" --thread-id thr-123
2524
+ $ echo "Write a summarization task" | nexus prompt-assistant chat --message - --mode ai-task
2525
+ $ nexus prompt-assistant chat --body '{"message":"Help me","mode":"agent"}'`
2526
+ ).action(async (opts) => {
2527
+ try {
2528
+ const client = createClient(program2.optsWithGlobals());
2529
+ const base = await resolveBody(opts.body);
2530
+ const flags = {};
2531
+ if (opts.mode) flags.mode = opts.mode;
2532
+ if (opts.threadId) flags.threadId = opts.threadId;
2533
+ if (opts.message) flags.message = await resolveInputValue(opts.message);
2534
+ const body = mergeBodyWithFlags(base, flags);
2535
+ const result = await client.promptAssistant.chat(body);
2536
+ printRecord(result);
2537
+ } catch (err) {
2538
+ process.exitCode = handleError(err);
2539
+ }
2540
+ });
2541
+ pa.command("get-thread").description("Get a prompt assistant thread with messages").argument("<thread-id>", "Thread ID").addHelpText(
2542
+ "after",
2543
+ `
2544
+ Examples:
2545
+ $ nexus prompt-assistant get-thread thr-123
2546
+ $ nexus prompt-assistant get-thread thr-123 --json`
2547
+ ).action(async (threadId) => {
2548
+ try {
2549
+ const client = createClient(program2.optsWithGlobals());
2550
+ const t = await client.promptAssistant.getThread(threadId);
2551
+ printRecord(t, [
2552
+ { key: "id", label: "ID" },
2553
+ { key: "mode", label: "Mode" },
2554
+ { key: "messages", label: "Messages" },
2555
+ { key: "promptResult", label: "Prompt Result" },
2556
+ { key: "createdAt", label: "Created" }
2557
+ ]);
2558
+ } catch (err) {
2559
+ process.exitCode = handleError(err);
2560
+ }
2561
+ });
2562
+ pa.command("delete-thread").description("Delete a prompt assistant thread").argument("<thread-id>", "Thread ID").option("--yes", "Skip confirmation").addHelpText(
2563
+ "after",
2564
+ `
2565
+ Examples:
2566
+ $ nexus prompt-assistant delete-thread thr-123
2567
+ $ nexus prompt-assistant delete-thread thr-123 --yes`
2568
+ ).action(async (threadId, opts) => {
2569
+ try {
2570
+ const client = createClient(program2.optsWithGlobals());
2571
+ if (!opts.yes && process.stdout.isTTY) {
2572
+ const readline2 = await import("readline/promises");
2573
+ const rl = readline2.createInterface({ input: process.stdin, output: process.stdout });
2574
+ const answer = await rl.question(`Delete thread ${threadId}? [y/N] `);
2575
+ rl.close();
2576
+ if (answer.toLowerCase() !== "y") {
2577
+ console.log("Aborted.");
2578
+ return;
2579
+ }
2580
+ }
2581
+ await client.promptAssistant.deleteThread(threadId);
2582
+ printSuccess("Thread deleted.", { threadId });
2583
+ } catch (err) {
2584
+ process.exitCode = handleError(err);
2585
+ }
2586
+ });
2587
+ }
2588
+
2589
+ // src/commands/task.ts
2590
+ init_output();
2591
+ function registerTaskCommands(program2) {
2592
+ const task = program2.command("task").description("Manage AI tasks");
2593
+ task.command("list").description("List AI tasks").option("--search <query>", "Search by name").option("--limit <number>", "Max results", parseInt).addHelpText(
2594
+ "after",
2595
+ `
2596
+ Examples:
2597
+ $ nexus task list
2598
+ $ nexus task list --search "summarize" --limit 10
2599
+ $ nexus task list --json`
2600
+ ).action(async (opts) => {
2601
+ try {
2602
+ const client = createClient(program2.optsWithGlobals());
2603
+ const result = await client.skills.listTasks({
2604
+ search: opts.search,
2605
+ limit: opts.limit
2606
+ });
2607
+ const items = result.items ?? [];
2608
+ printTable(items, [
2609
+ { key: "id", label: "ID", width: 36 },
2610
+ { key: "name", label: "NAME", width: 30 },
2611
+ { key: "category", label: "CATEGORY", width: 15 },
2612
+ { key: "inputFormat", label: "INPUT", width: 10 },
2613
+ { key: "outputFormat", label: "OUTPUT", width: 10 }
2614
+ ]);
2615
+ } catch (err) {
2616
+ process.exitCode = handleError(err);
2617
+ }
2618
+ });
2619
+ task.command("get").description("Get AI task details").argument("<id>", "Task ID").addHelpText(
2620
+ "after",
2621
+ `
2622
+ Examples:
2623
+ $ nexus task get task-123
2624
+ $ nexus task get task-123 --json`
2625
+ ).action(async (id) => {
2626
+ try {
2627
+ const client = createClient(program2.optsWithGlobals());
2628
+ const t = await client.skills.getTask(id);
2629
+ printRecord(t, [
2630
+ { key: "id", label: "ID" },
2631
+ { key: "name", label: "Name" },
2632
+ { key: "category", label: "Category" },
2633
+ { key: "modelName", label: "Model" },
2634
+ { key: "modelProvider", label: "Provider" },
2635
+ { key: "inputFormat", label: "Input Format" },
2636
+ { key: "outputFormat", label: "Output Format" }
2637
+ ]);
2638
+ } catch (err) {
2639
+ process.exitCode = handleError(err);
2640
+ }
2641
+ });
2642
+ task.command("create").description("Create an AI task").requiredOption("--name <name>", "Task name").requiredOption("--model-name <model>", "Model name (e.g. gpt-4o)").requiredOption("--model-provider <provider>", "Model provider (e.g. OPEN_AI)").option("--expected-input <text>", "Description of expected input").option("--expected-output <text>", "Description of expected output").option("--body <json>", "Request body as JSON, .json file, or '-' for stdin").addHelpText(
2643
+ "after",
2644
+ `
2645
+ Examples:
2646
+ $ nexus task create --name "Summarize Email" --model-name gpt-4o --model-provider OPEN_AI
2647
+ $ nexus task create --name "Classify" --model-name gpt-4o --model-provider OPEN_AI --expected-input "Raw text" --expected-output "Category label"
2648
+ $ nexus task create --body '{"name":"Summarize","modelName":"gpt-4o","modelProvider":"OPEN_AI"}'`
2649
+ ).action(async (opts) => {
2650
+ try {
2651
+ const client = createClient(program2.optsWithGlobals());
2652
+ const base = await resolveBody(opts.body);
2653
+ const flags = {};
2654
+ if (opts.name !== void 0) flags.name = opts.name;
2655
+ if (opts.modelName !== void 0) flags.modelName = opts.modelName;
2656
+ if (opts.modelProvider !== void 0) flags.modelProvider = opts.modelProvider;
2657
+ if (opts.expectedInput || opts.expectedOutput) {
2658
+ flags.generation = {
2659
+ expectedInput: opts.expectedInput,
2660
+ expectedOutput: opts.expectedOutput
2661
+ };
2662
+ }
2663
+ const body = mergeBodyWithFlags(base, flags);
2664
+ const t = await client.skills.createTask(body);
2665
+ printSuccess("Task created.", {
2666
+ id: t.id,
2667
+ name: t.name
2668
+ });
2669
+ } catch (err) {
2670
+ process.exitCode = handleError(err);
2671
+ }
2672
+ });
2673
+ task.command("execute").description("Execute an AI task").argument("<id>", "Task ID").requiredOption("--input <text-or-->", "Input text (or '-' for stdin)").option("--body <json>", "Request body as JSON, .json file, or '-' for stdin").addHelpText(
2674
+ "after",
2675
+ `
2676
+ Examples:
2677
+ $ nexus task execute task-123 --input "Summarize this email..."
2678
+ $ cat document.txt | nexus task execute task-123 --input -
2679
+ $ nexus task execute task-123 --input "Hello world" --json
2680
+ $ nexus task execute task-123 --body '{"input":"Hello world"}'`
2681
+ ).action(async (id, opts) => {
2682
+ try {
2683
+ const client = createClient(program2.optsWithGlobals());
2684
+ const base = await resolveBody(opts.body);
2685
+ const flags = {};
2686
+ if (opts.input) flags.input = await resolveInputValue(opts.input);
2687
+ const execBody = mergeBodyWithFlags(base, flags);
2688
+ const result = await client.skills.executeTask(id, execBody);
2689
+ if (isJsonMode()) {
2690
+ console.log(JSON.stringify(result, null, 2));
2691
+ } else {
2692
+ console.log(result.output ?? JSON.stringify(result, null, 2));
2693
+ }
2694
+ } catch (err) {
2695
+ process.exitCode = handleError(err);
2696
+ }
2697
+ });
2698
+ }
2699
+
2700
+ // src/commands/template.ts
2701
+ var import_node_fs3 = __toESM(require("fs"));
2702
+ var import_node_path3 = __toESM(require("path"));
2703
+ init_output();
2704
+ function registerTemplateCommands(program2) {
2705
+ const template = program2.command("template").description("Manage document templates");
2706
+ template.command("list").description("List document templates").option("--search <query>", "Search by name").option("--limit <number>", "Max results", parseInt).addHelpText(
2707
+ "after",
2708
+ `
2709
+ Examples:
2710
+ $ nexus template list
2711
+ $ nexus template list --search "invoice" --limit 10
2712
+ $ nexus template list --json`
2713
+ ).action(async (opts) => {
2714
+ try {
2715
+ const client = createClient(program2.optsWithGlobals());
2716
+ const result = await client.skills.listDocumentTemplates({
2717
+ search: opts.search,
2718
+ limit: opts.limit
2719
+ });
2720
+ const items = Array.isArray(result) ? result : result.items ?? result.data ?? result;
2721
+ printList(items, void 0, [
2722
+ { key: "id", label: "ID", width: 36 },
2723
+ { key: "name", label: "NAME", width: 30 },
2724
+ { key: "description", label: "DESCRIPTION", width: 40 },
2725
+ { key: "createdAt", label: "CREATED", width: 26 }
2726
+ ]);
2727
+ } catch (err) {
2728
+ process.exitCode = handleError(err);
2729
+ }
2730
+ });
2731
+ template.command("get").description("Get document template details").argument("<id>", "Template ID").addHelpText(
2732
+ "after",
2733
+ `
2734
+ Examples:
2735
+ $ nexus template get tmpl-123
2736
+ $ nexus template get tmpl-123 --json`
2737
+ ).action(async (id) => {
2738
+ try {
2739
+ const client = createClient(program2.optsWithGlobals());
2740
+ const t = await client.skills.getDocumentTemplate(id);
2741
+ printRecord(t, [
2742
+ { key: "id", label: "ID" },
2743
+ { key: "name", label: "Name" },
2744
+ { key: "description", label: "Description" },
2745
+ { key: "fileName", label: "File Name" },
2746
+ { key: "createdAt", label: "Created" },
2747
+ { key: "updatedAt", label: "Updated" }
2748
+ ]);
2749
+ } catch (err) {
2750
+ process.exitCode = handleError(err);
2751
+ }
2752
+ });
2753
+ template.command("create").description("Create a document template").option("--name <name>", "Template name").option("--description <text>", "Template description").option("--body <json>", "Request body as JSON, .json file, or '-' for stdin").addHelpText(
2754
+ "after",
2755
+ `
2756
+ Examples:
2757
+ $ nexus template create --name "Invoice Template"
2758
+ $ nexus template create --name "Report" --description "Monthly report template"
2759
+ $ nexus template create --body '{"name":"Contract","description":"Standard contract"}'`
2760
+ ).action(async (opts) => {
2761
+ try {
2762
+ const client = createClient(program2.optsWithGlobals());
2763
+ const base = await resolveBody(opts.body);
2764
+ const body = mergeBodyWithFlags(base, {
2765
+ name: opts.name,
2766
+ description: opts.description
2767
+ });
2768
+ const t = await client.skills.createDocumentTemplate(body);
2769
+ printSuccess("Template created.", {
2770
+ id: t.id,
2771
+ name: t.name
2772
+ });
2773
+ } catch (err) {
2774
+ process.exitCode = handleError(err);
2775
+ }
2776
+ });
2777
+ template.command("upload").description("Upload a file to a document template").argument("<id>", "Template ID").requiredOption("--file <path>", "Path to the template file").addHelpText(
2778
+ "after",
2779
+ `
2780
+ Examples:
2781
+ $ nexus template upload tmpl-123 --file ./invoice.docx
2782
+ $ nexus template upload tmpl-123 --file ./report.pdf`
2783
+ ).action(async (id, opts) => {
2784
+ try {
2785
+ const client = createClient(program2.optsWithGlobals());
2786
+ const absPath = import_node_path3.default.resolve(opts.file);
2787
+ if (!import_node_fs3.default.existsSync(absPath)) {
2788
+ console.error(`Error: File not found: ${absPath}`);
2789
+ process.exitCode = 1;
2790
+ return;
2791
+ }
2792
+ const buffer = import_node_fs3.default.readFileSync(absPath);
2793
+ const blob = new Blob([buffer]);
2794
+ const fileName = import_node_path3.default.basename(absPath);
2795
+ const result = await client.skills.uploadDocumentTemplateFile(id, blob, fileName);
2796
+ printSuccess("File uploaded to template.", {
2797
+ templateId: id,
2798
+ fileName
2799
+ });
2800
+ } catch (err) {
2801
+ process.exitCode = handleError(err);
2802
+ }
2803
+ });
2804
+ template.command("generate").description("Generate a document from a template").argument("<id>", "Template ID").option("--body <json>", "Request body as JSON, .json file, or '-' for stdin").addHelpText(
2805
+ "after",
2806
+ `
2807
+ Examples:
2808
+ $ nexus template generate tmpl-123 --body '{"variables":{"name":"Acme Corp","date":"2026-01-01"}}'
2809
+ $ nexus template generate tmpl-123 --body variables.json
2810
+ $ nexus template generate tmpl-123 --body '{"variables":{"amount":100}}' --json`
2811
+ ).action(async (id, opts) => {
2812
+ try {
2813
+ const client = createClient(program2.optsWithGlobals());
2814
+ const body = await resolveBody(opts.body);
2815
+ const result = await client.skills.generateDocumentTemplate(id, body);
2816
+ printRecord(result);
2817
+ } catch (err) {
2818
+ process.exitCode = handleError(err);
2819
+ }
2820
+ });
2821
+ }
2822
+
2823
+ // src/commands/ticket.ts
2824
+ init_output();
2825
+ function registerTicketCommands(program2) {
2826
+ const ticket = program2.command("ticket").description("Manage tickets (bugs, feature requests, improvements)");
2827
+ addPaginationOptions(
2828
+ ticket.command("list").description("List tickets").option("--type <type>", "Filter by type (BUG, FEATURE_REQUEST, IMPROVEMENT)").option("--priority <priority>", "Filter by priority (NONE, URGENT, HIGH, MEDIUM, LOW)").option("--status <status>", "Filter by status").option("--search <query>", "Search by title or description").addHelpText(
2829
+ "after",
2830
+ `
2831
+ Examples:
2832
+ $ nexus ticket list
2833
+ $ nexus ticket list --type BUG --priority HIGH
2834
+ $ nexus ticket list --search "login" --json`
2835
+ )
2836
+ ).action(async (opts) => {
2837
+ try {
2838
+ const client = createClient(program2.optsWithGlobals());
2839
+ const { data, meta } = await client.tickets.list({
2840
+ ...getPaginationParams(opts),
2841
+ type: opts.type,
2842
+ priority: opts.priority,
2843
+ status: opts.status,
2844
+ search: opts.search
2845
+ });
2846
+ printList(
2847
+ data,
2848
+ meta,
2849
+ [
2850
+ { key: "identifier", label: "IDENTIFIER", width: 12 },
2851
+ { key: "title", label: "TITLE", width: 40 },
2852
+ { key: "type", label: "TYPE", width: 18 },
2853
+ { key: "priority", label: "PRIORITY", width: 10 },
2854
+ { key: "status", label: "STATUS", width: 15 }
2855
+ ]
2856
+ );
2857
+ } catch (err) {
2858
+ process.exitCode = handleError(err);
2859
+ }
2860
+ });
2861
+ ticket.command("get").description("Get ticket details").argument("<id>", "Ticket ID or identifier").addHelpText(
2862
+ "after",
2863
+ `
2864
+ Examples:
2865
+ $ nexus ticket get TKT-42
2866
+ $ nexus ticket get TKT-42 --json`
2867
+ ).action(async (id) => {
2868
+ try {
2869
+ const client = createClient(program2.optsWithGlobals());
2870
+ const t = await client.tickets.get(id);
2871
+ printRecord(t, [
2872
+ { key: "id", label: "ID" },
2873
+ { key: "identifier", label: "Identifier" },
2874
+ { key: "title", label: "Title" },
2875
+ { key: "type", label: "Type" },
2876
+ { key: "priority", label: "Priority" },
2877
+ { key: "status", label: "Status" },
2878
+ { key: "url", label: "URL" },
2879
+ { key: "description", label: "Description" },
2880
+ { key: "createdAt", label: "Created" },
2881
+ { key: "updatedAt", label: "Updated" }
2882
+ ]);
2883
+ } catch (err) {
2884
+ process.exitCode = handleError(err);
2885
+ }
2886
+ });
2887
+ ticket.command("create").description("Create a new ticket").requiredOption("--title <title>", "Ticket title").option("--type <type>", "Ticket type (BUG, FEATURE_REQUEST, IMPROVEMENT)").option("--priority <priority>", "Priority (NONE, URGENT, HIGH, MEDIUM, LOW)").option("--description <text>", "Ticket description").option("--data <json>", "Request body as JSON, .json file, or '-' for stdin").addHelpText(
2888
+ "after",
2889
+ `
2890
+ Examples:
2891
+ $ nexus ticket create --title "Login fails with SSO"
2892
+ $ nexus ticket create --title "Add dark mode" --type FEATURE_REQUEST --priority MEDIUM
2893
+ $ nexus ticket create --title "Bug report" --type BUG --description "Steps to reproduce..."
2894
+ $ nexus ticket create --data '{"title":"Bug","type":"BUG"}'`
2895
+ ).action(async (opts) => {
2896
+ try {
2897
+ const client = createClient(program2.optsWithGlobals());
2898
+ const base = await resolveBody(opts.data);
2899
+ const body = mergeBodyWithFlags(base, {
2900
+ ...opts.title !== void 0 && { title: opts.title },
2901
+ ...opts.type !== void 0 && { type: opts.type },
2902
+ ...opts.priority !== void 0 && { priority: opts.priority },
2903
+ ...opts.description !== void 0 && { description: opts.description }
2904
+ });
2905
+ const t = await client.tickets.create(body);
2906
+ printRecord(t, [
2907
+ { key: "id", label: "ID" },
2908
+ { key: "identifier", label: "Identifier" },
2909
+ { key: "title", label: "Title" },
2910
+ { key: "type", label: "Type" },
2911
+ { key: "priority", label: "Priority" },
2912
+ { key: "status", label: "Status" },
2913
+ { key: "url", label: "URL" }
2914
+ ]);
2915
+ } catch (err) {
2916
+ process.exitCode = handleError(err);
2917
+ }
2918
+ });
2919
+ ticket.command("update").description("Update a ticket").argument("<id>", "Ticket ID or identifier").option("--title <title>", "Updated title").option("--type <type>", "Updated type (BUG, FEATURE_REQUEST, IMPROVEMENT)").option("--priority <priority>", "Updated priority (NONE, URGENT, HIGH, MEDIUM, LOW)").option("--description <text>", "Updated description").option("--data <json>", "Request body as JSON, .json file, or '-' for stdin").addHelpText(
2920
+ "after",
2921
+ `
2922
+ Examples:
2923
+ $ nexus ticket update TKT-42 --priority URGENT
2924
+ $ nexus ticket update TKT-42 --title "Updated title" --type BUG
2925
+ $ nexus ticket update TKT-42 --data '{"priority":"URGENT"}'`
2926
+ ).action(async (id, opts) => {
2927
+ try {
2928
+ const client = createClient(program2.optsWithGlobals());
2929
+ const base = await resolveBody(opts.data);
2930
+ const body = mergeBodyWithFlags(base, {
2931
+ ...opts.title !== void 0 && { title: opts.title },
2932
+ ...opts.type !== void 0 && { type: opts.type },
2933
+ ...opts.priority !== void 0 && { priority: opts.priority },
2934
+ ...opts.description !== void 0 && { description: opts.description }
2935
+ });
2936
+ const t = await client.tickets.update(id, body);
2937
+ printRecord(t, [
2938
+ { key: "id", label: "ID" },
2939
+ { key: "identifier", label: "Identifier" },
2940
+ { key: "title", label: "Title" },
2941
+ { key: "type", label: "Type" },
2942
+ { key: "priority", label: "Priority" },
2943
+ { key: "status", label: "Status" },
2944
+ { key: "url", label: "URL" }
2945
+ ]);
2946
+ } catch (err) {
2947
+ process.exitCode = handleError(err);
2948
+ }
2949
+ });
2950
+ ticket.command("comment").description("Add a comment to a ticket").argument("<id>", "Ticket ID or identifier").requiredOption("--body <text-or-->", "Comment body (text or '-' for stdin)").addHelpText(
2951
+ "after",
2952
+ `
2953
+ Examples:
2954
+ $ nexus ticket comment TKT-42 --body "This is fixed in v2.1"
2955
+ $ echo "Detailed comment" | nexus ticket comment TKT-42 --body -`
2956
+ ).action(async (id, opts) => {
2957
+ try {
2958
+ const client = createClient(program2.optsWithGlobals());
2959
+ const body = await resolveInputValue(opts.body);
2960
+ await client.tickets.addComment(id, { body });
2961
+ printSuccess("Comment added.", { ticketId: id });
2962
+ } catch (err) {
2963
+ process.exitCode = handleError(err);
2964
+ }
2965
+ });
2966
+ ticket.command("comments").description("List comments on a ticket").argument("<id>", "Ticket ID or identifier").addHelpText(
2967
+ "after",
2968
+ `
2969
+ Examples:
2970
+ $ nexus ticket comments TKT-42
2971
+ $ nexus ticket comments TKT-42 --json`
2972
+ ).action(async (id) => {
2973
+ try {
2974
+ const client = createClient(program2.optsWithGlobals());
2975
+ const result = await client.tickets.listComments(id);
2976
+ const comments = result.comments ?? result;
2977
+ printList(comments, void 0, [
2978
+ { key: "id", label: "ID", width: 36 },
2979
+ { key: "authorName", label: "AUTHOR", width: 20 },
2980
+ { key: "body", label: "BODY", width: 50 },
2981
+ { key: "createdAt", label: "CREATED", width: 20 }
2982
+ ]);
2983
+ } catch (err) {
2984
+ process.exitCode = handleError(err);
2985
+ }
2986
+ });
2987
+ }
2988
+
2989
+ // src/commands/tool.ts
2990
+ init_output();
2991
+ function registerToolCommands(program2) {
2992
+ const tool = program2.command("tool").description("Discover and manage marketplace tools");
2993
+ tool.command("search").description("Search marketplace tools").option("--query <query>", "Search query").option("--category <category>", "Filter by category").option("--type <type>", "Filter by type").option("--limit <number>", "Max results", parseInt).addHelpText(
2994
+ "after",
2995
+ `
2996
+ Examples:
2997
+ $ nexus tool search --query "gmail"
2998
+ $ nexus tool search --category "Communication" --limit 10
2999
+ $ nexus tool search --query "slack" --json`
3000
+ ).action(async (opts) => {
3001
+ try {
3002
+ const client = createClient(program2.optsWithGlobals());
3003
+ const result = await client.tools.search({
3004
+ q: opts.query,
3005
+ category: opts.category,
3006
+ type: opts.type,
3007
+ limit: opts.limit
3008
+ });
3009
+ const tools = result.tools ?? [];
3010
+ printTable(tools, [
3011
+ { key: "id", label: "ID", width: 36 },
3012
+ { key: "name", label: "NAME", width: 25 },
3013
+ { key: "type", label: "TYPE", width: 12 },
3014
+ { key: "description", label: "DESCRIPTION", width: 40 }
3015
+ ]);
3016
+ } catch (err) {
3017
+ process.exitCode = handleError(err);
3018
+ }
3019
+ });
3020
+ tool.command("get").description("Get marketplace tool details").argument("<id>", "Tool ID").addHelpText(
3021
+ "after",
3022
+ `
3023
+ Examples:
3024
+ $ nexus tool get tool-123
3025
+ $ nexus tool get tool-123 --json`
3026
+ ).action(async (id) => {
3027
+ try {
3028
+ const client = createClient(program2.optsWithGlobals());
3029
+ const detail = await client.tools.get(id);
3030
+ printRecord(detail);
3031
+ } catch (err) {
3032
+ process.exitCode = handleError(err);
3033
+ }
3034
+ });
3035
+ tool.command("credentials").description("List credentials for a marketplace tool").argument("<id>", "Tool ID").addHelpText(
3036
+ "after",
3037
+ `
3038
+ Examples:
3039
+ $ nexus tool credentials tool-123
3040
+ $ nexus tool credentials tool-123 --json`
3041
+ ).action(async (id) => {
3042
+ try {
3043
+ const client = createClient(program2.optsWithGlobals());
3044
+ const result = await client.tools.credentials(id);
3045
+ const creds = result.credentials ?? [];
3046
+ printTable(creds, [
3047
+ { key: "id", label: "ID", width: 36 },
3048
+ { key: "name", label: "NAME", width: 25 },
3049
+ { key: "type", label: "TYPE", width: 12 },
3050
+ { key: "createdAt", label: "CREATED", width: 20 }
3051
+ ]);
3052
+ } catch (err) {
3053
+ process.exitCode = handleError(err);
3054
+ }
3055
+ });
3056
+ tool.command("connect").description("Connect a tool via OAuth or HTTP credentials").argument("<id>", "Tool ID").option("--auth-type <type>", "Auth type: oauth or http", "oauth").option("--api-key-value <key>", "API key for HTTP auth").option("--auth-header <header>", "Authorization header type for HTTP auth", "bearer").option("--body <json>", "Request body as JSON, .json file, or '-' for stdin").addHelpText(
3057
+ "after",
3058
+ `
3059
+ Examples:
3060
+ $ nexus tool connect tool-123
3061
+ $ nexus tool connect tool-123 --auth-type http --api-key-value sk-abc123
3062
+ $ nexus tool connect tool-123 --body '{"authType":"http","apiKey":"sk-abc"}'`
3063
+ ).action(async (id, opts) => {
3064
+ try {
3065
+ const client = createClient(program2.optsWithGlobals());
3066
+ const base = await resolveBody(opts.body);
3067
+ if (base) {
3068
+ const flags = {};
3069
+ if (opts.authType !== void 0) flags.authType = opts.authType;
3070
+ if (opts.apiKeyValue !== void 0) flags.apiKey = opts.apiKeyValue;
3071
+ if (opts.authHeader !== void 0) flags.authorizationType = opts.authHeader;
3072
+ const body = mergeBodyWithFlags(base, flags);
3073
+ const result = await client.toolConnection.connect(id, body);
3074
+ printSuccess("Tool connected.", result);
3075
+ } else if (opts.authType === "http") {
3076
+ if (!opts.apiKeyValue) {
3077
+ console.error(
3078
+ "Error: --api-key-value is required for HTTP auth.\n nexus tool connect <id> --auth-type http --api-key-value <key>"
3079
+ );
3080
+ process.exitCode = 1;
3081
+ return;
3082
+ }
3083
+ const result = await client.toolConnection.connect(id, {
3084
+ authType: "http",
3085
+ apiKey: opts.apiKeyValue,
3086
+ authorizationType: opts.authHeader
3087
+ });
3088
+ printSuccess("Tool connected via HTTP.", result);
3089
+ } else {
3090
+ const result = await client.toolConnection.connect(id, {
3091
+ authType: "oauth"
3092
+ });
3093
+ printSuccess("OAuth flow initiated.", result);
3094
+ }
3095
+ } catch (err) {
3096
+ process.exitCode = handleError(err);
3097
+ }
3098
+ });
3099
+ }
3100
+
3101
+ // src/commands/version.ts
3102
+ init_output();
3103
+ function registerVersionCommands(program2) {
3104
+ const version = program2.command("version").description("Manage agent prompt versions");
3105
+ addPaginationOptions(
3106
+ version.command("list").description("List prompt versions for an agent").argument("<agent-id>", "Agent ID").option("--type <type>", "Filter by type (AUTO, CHECKPOINT)").addHelpText(
3107
+ "after",
3108
+ `
3109
+ Examples:
3110
+ $ nexus version list agt-123
3111
+ $ nexus version list agt-123 --type CHECKPOINT
3112
+ $ nexus version list agt-123 --limit 5 --json`
3113
+ )
3114
+ ).action(async (agentId, opts) => {
3115
+ try {
3116
+ const client = createClient(program2.optsWithGlobals());
3117
+ const { data, meta } = await client.agents.versions.list(agentId, {
3118
+ ...getPaginationParams(opts),
3119
+ type: opts.type
3120
+ });
3121
+ printList(
3122
+ data,
3123
+ meta,
3124
+ [
3125
+ { key: "id", label: "ID", width: 36 },
3126
+ { key: "name", label: "NAME", width: 25 },
3127
+ { key: "type", label: "TYPE", width: 12 },
3128
+ { key: "isProduction", label: "PROD", width: 6, format: (v) => v ? "yes" : "no" },
3129
+ { key: "createdAt", label: "CREATED", width: 20 }
3130
+ ]
3131
+ );
3132
+ } catch (err) {
3133
+ process.exitCode = handleError(err);
3134
+ }
3135
+ });
3136
+ version.command("get").description("Get version details with full prompt").argument("<agent-id>", "Agent ID").argument("<version-id>", "Version ID").addHelpText(
3137
+ "after",
3138
+ `
3139
+ Examples:
3140
+ $ nexus version get agt-123 ver-456
3141
+ $ nexus version get agt-123 ver-456 --json`
3142
+ ).action(async (agentId, versionId) => {
3143
+ try {
3144
+ const client = createClient(program2.optsWithGlobals());
3145
+ const ver = await client.agents.versions.get(agentId, versionId);
3146
+ printRecord(ver, [
3147
+ { key: "id", label: "ID" },
3148
+ { key: "name", label: "Name" },
3149
+ { key: "type", label: "Type" },
3150
+ { key: "isProduction", label: "Production", format: (v) => v ? "yes" : "no" },
3151
+ { key: "prompt", label: "Prompt" },
3152
+ { key: "createdAt", label: "Created" }
3153
+ ]);
3154
+ } catch (err) {
3155
+ process.exitCode = handleError(err);
3156
+ }
3157
+ });
3158
+ version.command("create").description("Create a named checkpoint of the current prompt").argument("<agent-id>", "Agent ID").option("--name <name>", "Checkpoint name").option("--description <text>", "Checkpoint description").option("--body <json>", "Request body as JSON, .json file, or '-' for stdin").addHelpText(
3159
+ "after",
3160
+ `
3161
+ Examples:
3162
+ $ nexus version create agt-123
3163
+ $ nexus version create agt-123 --name "v1.0" --description "Initial release"
3164
+ $ nexus version create agt-123 --body '{"name":"v1.0"}'`
3165
+ ).action(async (agentId, opts) => {
3166
+ try {
3167
+ const client = createClient(program2.optsWithGlobals());
3168
+ const base = await resolveBody(opts.body);
3169
+ const body = mergeBodyWithFlags(base, {
3170
+ ...opts.name !== void 0 && { name: opts.name },
3171
+ ...opts.description !== void 0 && { description: opts.description }
3172
+ });
3173
+ const ver = await client.agents.versions.createCheckpoint(agentId, body);
3174
+ printSuccess("Checkpoint created.", {
3175
+ id: ver.id,
3176
+ name: ver.name ?? "(unnamed)"
3177
+ });
3178
+ } catch (err) {
3179
+ process.exitCode = handleError(err);
3180
+ }
3181
+ });
3182
+ version.command("update").description("Update version metadata").argument("<agent-id>", "Agent ID").argument("<version-id>", "Version ID").option("--name <name>", "New name").option("--description <text>", "New description").option("--body <json>", "Request body as JSON, .json file, or '-' for stdin").addHelpText(
3183
+ "after",
3184
+ `
3185
+ Examples:
3186
+ $ nexus version update agt-123 ver-456 --name "v1.1"
3187
+ $ nexus version update agt-123 ver-456 --body '{"name":"v1.1"}'`
3188
+ ).action(async (agentId, versionId, opts) => {
3189
+ try {
3190
+ const client = createClient(program2.optsWithGlobals());
3191
+ const base = await resolveBody(opts.body);
3192
+ const body = mergeBodyWithFlags(base, {
3193
+ ...opts.name !== void 0 && { name: opts.name },
3194
+ ...opts.description !== void 0 && { description: opts.description }
3195
+ });
3196
+ await client.agents.versions.update(agentId, versionId, body);
3197
+ printSuccess("Version updated.", { id: versionId });
3198
+ } catch (err) {
3199
+ process.exitCode = handleError(err);
3200
+ }
3201
+ });
3202
+ version.command("delete").description("Delete a prompt version").argument("<agent-id>", "Agent ID").argument("<version-id>", "Version ID").option("--yes", "Skip confirmation").addHelpText(
3203
+ "after",
3204
+ `
3205
+ Examples:
3206
+ $ nexus version delete agt-123 ver-456
3207
+ $ nexus version delete agt-123 ver-456 --yes`
3208
+ ).action(async (agentId, versionId, opts) => {
3209
+ try {
3210
+ const client = createClient(program2.optsWithGlobals());
3211
+ if (!opts.yes && process.stdout.isTTY) {
3212
+ const readline2 = await import("readline/promises");
3213
+ const rl = readline2.createInterface({ input: process.stdin, output: process.stdout });
3214
+ const answer = await rl.question(`Delete version ${versionId}? [y/N] `);
3215
+ rl.close();
3216
+ if (answer.toLowerCase() !== "y") {
3217
+ console.log("Aborted.");
3218
+ return;
3219
+ }
3220
+ }
3221
+ await client.agents.versions.delete(agentId, versionId);
3222
+ printSuccess("Version deleted.", { id: versionId });
3223
+ } catch (err) {
3224
+ process.exitCode = handleError(err);
3225
+ }
3226
+ });
3227
+ version.command("restore").description("Restore agent prompt to a previous version").argument("<agent-id>", "Agent ID").argument("<version-id>", "Version ID to restore").option("--yes", "Skip confirmation").addHelpText(
3228
+ "after",
3229
+ `
3230
+ Examples:
3231
+ $ nexus version restore agt-123 ver-456
3232
+ $ nexus version restore agt-123 ver-456 --yes`
3233
+ ).action(async (agentId, versionId, opts) => {
3234
+ try {
3235
+ const client = createClient(program2.optsWithGlobals());
3236
+ if (!opts.yes && process.stdout.isTTY) {
3237
+ const readline2 = await import("readline/promises");
3238
+ const rl = readline2.createInterface({ input: process.stdin, output: process.stdout });
3239
+ const answer = await rl.question(
3240
+ `Restore agent ${agentId} to version ${versionId}? This will overwrite the current prompt. [y/N] `
3241
+ );
3242
+ rl.close();
3243
+ if (answer.toLowerCase() !== "y") {
3244
+ console.log("Aborted.");
3245
+ return;
3246
+ }
3247
+ }
3248
+ const result = await client.agents.versions.restore(agentId, versionId);
3249
+ printSuccess("Version restored.", { agentId, versionId, ...result });
3250
+ } catch (err) {
3251
+ process.exitCode = handleError(err);
3252
+ }
3253
+ });
3254
+ version.command("publish").description("Publish a version to production").argument("<agent-id>", "Agent ID").argument("<version-id>", "Version ID to publish").addHelpText(
3255
+ "after",
3256
+ `
3257
+ Examples:
3258
+ $ nexus version publish agt-123 ver-456`
3259
+ ).action(async (agentId, versionId) => {
3260
+ try {
3261
+ const client = createClient(program2.optsWithGlobals());
3262
+ const result = await client.agents.versions.publish(agentId, versionId);
3263
+ printSuccess("Version published to production.", {
3264
+ id: result.id,
3265
+ isProduction: "true"
3266
+ });
3267
+ } catch (err) {
3268
+ process.exitCode = handleError(err);
3269
+ }
3270
+ });
3271
+ }
3272
+
3273
+ // src/commands/workflow.ts
3274
+ init_output();
3275
+
3276
+ // src/commands/workflow-builder.ts
3277
+ init_output();
3278
+ function registerWorkflowBuilderCommands(workflow, program2) {
3279
+ const node = workflow.command("node").description("Manage workflow nodes");
3280
+ node.command("create").description("Create a node in a workflow").argument("<wf-id>", "Workflow ID").requiredOption("--type <type>", "Node type").option("--body <json-or-file-or-->", "Additional body JSON (merged with --type)").addHelpText(
3281
+ "after",
3282
+ `
3283
+ Examples:
3284
+ $ nexus workflow node create wf-123 --type action
3285
+ $ nexus workflow node create wf-123 --type condition --body '{"position":{"x":100,"y":200}}'
3286
+ $ nexus workflow node create wf-123 --type action --body payload.json`
3287
+ ).action(async (wfId, opts) => {
3288
+ try {
3289
+ const client = createClient(program2.optsWithGlobals());
3290
+ const extra = await resolveBody(opts.body);
3291
+ const body = mergeBodyWithFlags(extra, { type: opts.type });
3292
+ const result = await client.workflows.createNode(wfId, body);
3293
+ printRecord(result, [
3294
+ { key: "id", label: "ID" },
3295
+ { key: "type", label: "Type" },
3296
+ { key: "position", label: "Position" }
3297
+ ]);
3298
+ } catch (err) {
3299
+ process.exitCode = handleError(err);
3300
+ }
3301
+ });
3302
+ node.command("get").description("Get node details").argument("<wf-id>", "Workflow ID").argument("<node-id>", "Node ID").addHelpText(
3303
+ "after",
3304
+ `
3305
+ Examples:
3306
+ $ nexus workflow node get wf-123 node-456
3307
+ $ nexus workflow node get wf-123 node-456 --json`
3308
+ ).action(async (wfId, nodeId) => {
3309
+ try {
3310
+ const client = createClient(program2.optsWithGlobals());
3311
+ const result = await client.workflows.getNode(wfId, nodeId);
3312
+ printRecord(result);
3313
+ } catch (err) {
3314
+ process.exitCode = handleError(err);
3315
+ }
3316
+ });
3317
+ node.command("update").description("Update node data/config").argument("<wf-id>", "Workflow ID").argument("<node-id>", "Node ID").requiredOption("--body <json-or-file-or-->", "Node data/config JSON").addHelpText(
3318
+ "after",
3319
+ `
3320
+ Examples:
3321
+ $ nexus workflow node update wf-123 node-456 --body '{"data":{"message":"hello"}}'
3322
+ $ nexus workflow node update wf-123 node-456 --body config.json
3323
+ $ echo '{"data":{"key":"val"}}' | nexus workflow node update wf-123 node-456 --body -`
3324
+ ).action(async (wfId, nodeId, opts) => {
3325
+ try {
3326
+ const client = createClient(program2.optsWithGlobals());
3327
+ const body = await resolveBody(opts.body);
3328
+ const result = await client.workflows.updateNode(wfId, nodeId, body);
3329
+ printRecord(result);
3330
+ } catch (err) {
3331
+ process.exitCode = handleError(err);
3332
+ }
3333
+ });
3334
+ node.command("delete").description("Delete a node from a workflow").argument("<wf-id>", "Workflow ID").argument("<node-id>", "Node ID").option("--yes", "Skip confirmation").addHelpText(
3335
+ "after",
3336
+ `
3337
+ Examples:
3338
+ $ nexus workflow node delete wf-123 node-456
3339
+ $ nexus workflow node delete wf-123 node-456 --yes`
3340
+ ).action(async (wfId, nodeId, opts) => {
3341
+ try {
3342
+ const client = createClient(program2.optsWithGlobals());
3343
+ if (!opts.yes && process.stdout.isTTY) {
3344
+ const readline2 = await import("readline/promises");
3345
+ const rl = readline2.createInterface({
3346
+ input: process.stdin,
3347
+ output: process.stdout
3348
+ });
3349
+ const answer = await rl.question(`Delete node ${nodeId} from workflow ${wfId}? [y/N] `);
3350
+ rl.close();
3351
+ if (answer.toLowerCase() !== "y") {
3352
+ console.log("Aborted.");
3353
+ return;
3354
+ }
3355
+ }
3356
+ await client.workflows.deleteNode(wfId, nodeId);
3357
+ printSuccess("Node deleted.", { workflowId: wfId, nodeId });
3358
+ } catch (err) {
3359
+ process.exitCode = handleError(err);
3360
+ }
3361
+ });
3362
+ node.command("test").description("Run a test execution of a single node").argument("<wf-id>", "Workflow ID").argument("<node-id>", "Node ID").option("--body <json-or-file-or-->", "Optional mock data JSON").addHelpText(
3363
+ "after",
3364
+ `
3365
+ Examples:
3366
+ $ nexus workflow node test wf-123 node-456
3367
+ $ nexus workflow node test wf-123 node-456 --body '{"input":"test"}'`
3368
+ ).action(async (wfId, nodeId, opts) => {
3369
+ try {
3370
+ const client = createClient(program2.optsWithGlobals());
3371
+ const body = await resolveBody(opts.body);
3372
+ const result = await client.workflows.testNode(wfId, nodeId, body);
3373
+ printRecord(result);
3374
+ } catch (err) {
3375
+ process.exitCode = handleError(err);
3376
+ }
3377
+ });
3378
+ node.command("variables").description("List available upstream variables for a node").argument("<wf-id>", "Workflow ID").argument("<node-id>", "Node ID").addHelpText(
3379
+ "after",
3380
+ `
3381
+ Examples:
3382
+ $ nexus workflow node variables wf-123 node-456
3383
+ $ nexus workflow node variables wf-123 node-456 --json`
3384
+ ).action(async (wfId, nodeId) => {
3385
+ try {
3386
+ const client = createClient(program2.optsWithGlobals());
3387
+ const result = await client.workflows.getAvailableVariables(wfId, nodeId);
3388
+ printRecord(result);
3389
+ } catch (err) {
3390
+ process.exitCode = handleError(err);
3391
+ }
3392
+ });
3393
+ node.command("output-format").description("Show node output schema").argument("<wf-id>", "Workflow ID").argument("<node-id>", "Node ID").addHelpText(
3394
+ "after",
3395
+ `
3396
+ Examples:
3397
+ $ nexus workflow node output-format wf-123 node-456
3398
+ $ nexus workflow node output-format wf-123 node-456 --json`
3399
+ ).action(async (wfId, nodeId) => {
3400
+ try {
3401
+ const client = createClient(program2.optsWithGlobals());
3402
+ const result = await client.workflows.getOutputFormat(wfId, nodeId);
3403
+ printRecord(result);
3404
+ } catch (err) {
3405
+ process.exitCode = handleError(err);
3406
+ }
3407
+ });
3408
+ node.command("reload-props").description("Reload dynamic props for a Pipedream node").argument("<wf-id>", "Workflow ID").argument("<node-id>", "Node ID").requiredOption("--body <json-or-file-or-->", "Configured props JSON").addHelpText(
3409
+ "after",
3410
+ `
3411
+ Examples:
3412
+ $ nexus workflow node reload-props wf-123 node-456 --body '{"configuredProps":{"account":"acc-1"}}'
3413
+ $ nexus workflow node reload-props wf-123 node-456 --body props.json`
3414
+ ).action(async (wfId, nodeId, opts) => {
3415
+ try {
3416
+ const client = createClient(program2.optsWithGlobals());
3417
+ const body = await resolveBody(opts.body);
3418
+ const result = await client.workflows.reloadProps(wfId, nodeId, body);
3419
+ printRecord(result);
3420
+ } catch (err) {
3421
+ process.exitCode = handleError(err);
3422
+ }
3423
+ });
3424
+ const edge = workflow.command("edge").description("Manage workflow edges (connections between nodes)");
3425
+ edge.command("create").description("Create an edge between two nodes").argument("<wf-id>", "Workflow ID").requiredOption("--source <node-id>", "Source node ID").requiredOption("--target <node-id>", "Target node ID").option("--source-handle <handle>", "Source handle identifier").option("--body <json-or-file-or-->", "Additional body JSON").addHelpText(
3426
+ "after",
3427
+ `
3428
+ Examples:
3429
+ $ nexus workflow edge create wf-123 --source node-1 --target node-2
3430
+ $ nexus workflow edge create wf-123 --source node-1 --target node-2 --source-handle branch-a
3431
+ $ nexus workflow edge create wf-123 --source node-1 --target node-2 --body '{"type":"conditional"}'`
3432
+ ).action(async (wfId, opts) => {
3433
+ try {
3434
+ const client = createClient(program2.optsWithGlobals());
3435
+ const extra = await resolveBody(opts.body);
3436
+ const body = mergeBodyWithFlags(extra, {
3437
+ source: opts.source,
3438
+ target: opts.target,
3439
+ ...opts.sourceHandle ? { sourceHandle: opts.sourceHandle } : {}
3440
+ });
3441
+ const result = await client.workflows.createEdge(wfId, body);
3442
+ printRecord(result, [
3443
+ { key: "id", label: "ID" },
3444
+ { key: "source", label: "Source" },
3445
+ { key: "target", label: "Target" },
3446
+ { key: "sourceHandle", label: "Source Handle" },
3447
+ { key: "type", label: "Type" }
3448
+ ]);
3449
+ } catch (err) {
3450
+ process.exitCode = handleError(err);
3451
+ }
3452
+ });
3453
+ edge.command("delete").description("Delete an edge from a workflow").argument("<wf-id>", "Workflow ID").argument("<edge-id>", "Edge ID").option("--yes", "Skip confirmation").addHelpText(
3454
+ "after",
3455
+ `
3456
+ Examples:
3457
+ $ nexus workflow edge delete wf-123 edge-789
3458
+ $ nexus workflow edge delete wf-123 edge-789 --yes`
3459
+ ).action(async (wfId, edgeId, opts) => {
3460
+ try {
3461
+ const client = createClient(program2.optsWithGlobals());
3462
+ if (!opts.yes && process.stdout.isTTY) {
3463
+ const readline2 = await import("readline/promises");
3464
+ const rl = readline2.createInterface({
3465
+ input: process.stdin,
3466
+ output: process.stdout
3467
+ });
3468
+ const answer = await rl.question(`Delete edge ${edgeId} from workflow ${wfId}? [y/N] `);
3469
+ rl.close();
3470
+ if (answer.toLowerCase() !== "y") {
3471
+ console.log("Aborted.");
3472
+ return;
3473
+ }
3474
+ }
3475
+ await client.workflows.deleteEdge(wfId, edgeId);
3476
+ printSuccess("Edge deleted.", { workflowId: wfId, edgeId });
3477
+ } catch (err) {
3478
+ process.exitCode = handleError(err);
3479
+ }
3480
+ });
3481
+ const branch = workflow.command("branch").description("Manage branches on condition/router nodes");
3482
+ branch.command("list").description("List branches on a node").argument("<wf-id>", "Workflow ID").argument("<node-id>", "Node ID").addHelpText(
3483
+ "after",
3484
+ `
3485
+ Examples:
3486
+ $ nexus workflow branch list wf-123 node-456
3487
+ $ nexus workflow branch list wf-123 node-456 --json`
3488
+ ).action(async (wfId, nodeId) => {
3489
+ try {
3490
+ const client = createClient(program2.optsWithGlobals());
3491
+ const result = await client.workflows.listBranches(wfId, nodeId);
3492
+ const branches = Array.isArray(result) ? result : result.data ?? result;
3493
+ printList(branches, void 0, [
3494
+ { key: "id", label: "ID", width: 36 },
3495
+ { key: "name", label: "NAME", width: 30 },
3496
+ { key: "conditions", label: "CONDITIONS", width: 40 }
3497
+ ]);
3498
+ } catch (err) {
3499
+ process.exitCode = handleError(err);
3500
+ }
3501
+ });
3502
+ branch.command("create").description("Create a branch on a node").argument("<wf-id>", "Workflow ID").argument("<node-id>", "Node ID").requiredOption("--name <name>", "Branch name").option("--body <json-or-file-or-->", "Additional body JSON (conditions, etc.)").addHelpText(
3503
+ "after",
3504
+ `
3505
+ Examples:
3506
+ $ nexus workflow branch create wf-123 node-456 --name "Has email"
3507
+ $ nexus workflow branch create wf-123 node-456 --name "VIP" --body '{"conditions":[{"field":"tier","op":"eq","value":"vip"}]}'`
3508
+ ).action(async (wfId, nodeId, opts) => {
3509
+ try {
3510
+ const client = createClient(program2.optsWithGlobals());
3511
+ const extra = await resolveBody(opts.body);
3512
+ const body = mergeBodyWithFlags(extra, { name: opts.name });
3513
+ const result = await client.workflows.createBranch(wfId, nodeId, body);
3514
+ printRecord(result, [
3515
+ { key: "id", label: "ID" },
3516
+ { key: "name", label: "Name" },
3517
+ { key: "conditions", label: "Conditions" }
3518
+ ]);
3519
+ } catch (err) {
3520
+ process.exitCode = handleError(err);
3521
+ }
3522
+ });
3523
+ branch.command("update").description("Update a branch").argument("<wf-id>", "Workflow ID").argument("<node-id>", "Node ID").argument("<branch-id>", "Branch ID").requiredOption("--body <json-or-file-or-->", "Updated branch JSON (name, conditions)").addHelpText(
3524
+ "after",
3525
+ `
3526
+ Examples:
3527
+ $ nexus workflow branch update wf-123 node-456 br-789 --body '{"name":"Renamed","conditions":[]}'
3528
+ $ nexus workflow branch update wf-123 node-456 br-789 --body branch.json`
3529
+ ).action(async (wfId, nodeId, branchId, opts) => {
3530
+ try {
3531
+ const client = createClient(program2.optsWithGlobals());
3532
+ const body = await resolveBody(opts.body);
3533
+ const result = await client.workflows.updateBranch(wfId, nodeId, branchId, body);
3534
+ printRecord(result, [
3535
+ { key: "id", label: "ID" },
3536
+ { key: "name", label: "Name" },
3537
+ { key: "conditions", label: "Conditions" }
3538
+ ]);
3539
+ } catch (err) {
3540
+ process.exitCode = handleError(err);
3541
+ }
3542
+ });
3543
+ branch.command("delete").description("Delete a branch from a node").argument("<wf-id>", "Workflow ID").argument("<node-id>", "Node ID").argument("<branch-id>", "Branch ID").option("--yes", "Skip confirmation").addHelpText(
3544
+ "after",
3545
+ `
3546
+ Examples:
3547
+ $ nexus workflow branch delete wf-123 node-456 br-789
3548
+ $ nexus workflow branch delete wf-123 node-456 br-789 --yes`
3549
+ ).action(async (wfId, nodeId, branchId, opts) => {
3550
+ try {
3551
+ const client = createClient(program2.optsWithGlobals());
3552
+ if (!opts.yes && process.stdout.isTTY) {
3553
+ const readline2 = await import("readline/promises");
3554
+ const rl = readline2.createInterface({
3555
+ input: process.stdin,
3556
+ output: process.stdout
3557
+ });
3558
+ const answer = await rl.question(`Delete branch ${branchId} from node ${nodeId}? [y/N] `);
3559
+ rl.close();
3560
+ if (answer.toLowerCase() !== "y") {
3561
+ console.log("Aborted.");
3562
+ return;
3563
+ }
3564
+ }
3565
+ await client.workflows.deleteBranch(wfId, nodeId, branchId);
3566
+ printSuccess("Branch deleted.", { workflowId: wfId, nodeId, branchId });
3567
+ } catch (err) {
3568
+ process.exitCode = handleError(err);
3569
+ }
3570
+ });
3571
+ workflow.command("node-types").description("List available node types").addHelpText(
3572
+ "after",
3573
+ `
3574
+ Examples:
3575
+ $ nexus workflow node-types
3576
+ $ nexus workflow node-types --json`
3577
+ ).action(async () => {
3578
+ try {
3579
+ const client = createClient(program2.optsWithGlobals());
3580
+ const result = await client.workflows.listNodeTypes();
3581
+ const types = Array.isArray(result) ? result : result.data ?? result;
3582
+ printList(types, void 0, [
3583
+ { key: "type", label: "TYPE", width: 30 },
3584
+ { key: "category", label: "CATEGORY", width: 20 },
3585
+ { key: "label", label: "LABEL", width: 30 }
3586
+ ]);
3587
+ } catch (err) {
3588
+ process.exitCode = handleError(err);
3589
+ }
3590
+ });
3591
+ workflow.command("node-type").description("Get full schema for a node type").argument("<type>", "Node type identifier").addHelpText(
3592
+ "after",
3593
+ `
3594
+ Examples:
3595
+ $ nexus workflow node-type action
3596
+ $ nexus workflow node-type condition --json`
3597
+ ).action(async (type) => {
3598
+ try {
3599
+ const client = createClient(program2.optsWithGlobals());
3600
+ const result = await client.workflows.getNodeTypeSchema(type);
3601
+ printRecord(result);
3602
+ } catch (err) {
3603
+ process.exitCode = handleError(err);
3604
+ }
3605
+ });
3606
+ workflow.command("overview").description("Get high-level workflow overview with per-node config status").argument("<wf-id>", "Workflow ID").addHelpText(
3607
+ "after",
3608
+ `
3609
+ Examples:
3610
+ $ nexus workflow overview wf-123
3611
+ $ nexus workflow overview wf-123 --json`
3612
+ ).action(async (wfId) => {
3613
+ try {
3614
+ const client = createClient(program2.optsWithGlobals());
3615
+ const result = await client.workflows.getOverview(wfId);
3616
+ printRecord(result);
3617
+ } catch (err) {
3618
+ process.exitCode = handleError(err);
3619
+ }
3620
+ });
3621
+ workflow.command("layout").description("Auto-position nodes in a workflow").argument("<wf-id>", "Workflow ID").addHelpText(
3622
+ "after",
3623
+ `
3624
+ Examples:
3625
+ $ nexus workflow layout wf-123`
3626
+ ).action(async (wfId) => {
3627
+ try {
3628
+ const client = createClient(program2.optsWithGlobals());
3629
+ await client.workflows.layout(wfId);
3630
+ printSuccess("Workflow layout applied.", { workflowId: wfId });
3631
+ } catch (err) {
3632
+ process.exitCode = handleError(err);
3633
+ }
3634
+ });
3635
+ workflow.command("trigger").description("Replace the trigger node of a workflow").argument("<wf-id>", "Workflow ID").requiredOption("--type <type>", "New trigger type").option("--body <json-or-file-or-->", "Additional body JSON").addHelpText(
3636
+ "after",
3637
+ `
3638
+ Examples:
3639
+ $ nexus workflow trigger wf-123 --type webhook
3640
+ $ nexus workflow trigger wf-123 --type schedule --body '{"cron":"0 9 * * *"}'`
3641
+ ).action(async (wfId, opts) => {
3642
+ try {
3643
+ const client = createClient(program2.optsWithGlobals());
3644
+ const extra = await resolveBody(opts.body);
3645
+ const body = mergeBodyWithFlags(extra, { type: opts.type });
3646
+ const result = await client.workflows.replaceTrigger(wfId, body);
3647
+ printRecord(result);
3648
+ } catch (err) {
3649
+ process.exitCode = handleError(err);
3650
+ }
3651
+ });
3652
+ }
3653
+
3654
+ // src/commands/workflow.ts
3655
+ function registerWorkflowCommands(program2) {
3656
+ const workflow = program2.command("workflow").description("Manage workflows");
3657
+ addPaginationOptions(
3658
+ workflow.command("list").description("List workflows").option("--status <status>", "Filter by status (DRAFT, PUBLISHED)").option("--search <query>", "Search by name").addHelpText(
3659
+ "after",
3660
+ `
3661
+ Examples:
3662
+ $ nexus workflow list
3663
+ $ nexus workflow list --status PUBLISHED --limit 10
3664
+ $ nexus workflow list --search "onboarding" --json`
3665
+ )
3666
+ ).action(async (opts) => {
3667
+ try {
3668
+ const client = createClient(program2.optsWithGlobals());
3669
+ const { data, meta } = await client.workflows.list({
3670
+ ...getPaginationParams(opts),
3671
+ status: opts.status,
3672
+ search: opts.search
3673
+ });
3674
+ printList(
3675
+ data,
3676
+ meta,
3677
+ [
3678
+ { key: "id", label: "ID", width: 36 },
3679
+ { key: "name", label: "NAME", width: 30 },
3680
+ { key: "status", label: "STATUS", width: 12 },
3681
+ { key: "createdAt", label: "CREATED", width: 20 }
3682
+ ]
3683
+ );
3684
+ } catch (err) {
3685
+ process.exitCode = handleError(err);
3686
+ }
3687
+ });
3688
+ workflow.command("get").description("Get workflow details").argument("<id>", "Workflow ID").addHelpText(
3689
+ "after",
3690
+ `
3691
+ Examples:
3692
+ $ nexus workflow get wf-123
3693
+ $ nexus workflow get wf-123 --json`
3694
+ ).action(async (id) => {
3695
+ try {
3696
+ const client = createClient(program2.optsWithGlobals());
3697
+ const wf = await client.workflows.get(id);
3698
+ printRecord(wf, [
3699
+ { key: "id", label: "ID" },
3700
+ { key: "name", label: "Name" },
3701
+ { key: "description", label: "Description" },
3702
+ { key: "status", label: "Status" },
3703
+ { key: "createdAt", label: "Created" },
3704
+ { key: "updatedAt", label: "Updated" }
3705
+ ]);
3706
+ } catch (err) {
3707
+ process.exitCode = handleError(err);
3708
+ }
3709
+ });
3710
+ workflow.command("create").description("Create a new workflow").requiredOption("--name <name>", "Workflow name").option("--description <text>", "Workflow description").option("--body <json>", "Request body as JSON, .json file, or '-' for stdin").addHelpText(
3711
+ "after",
3712
+ `
3713
+ Examples:
3714
+ $ nexus workflow create --name "Customer Onboarding"
3715
+ $ nexus workflow create --name "Data Pipeline" --description "ETL workflow"
3716
+ $ nexus workflow create --body '{"name":"Pipeline","description":"ETL"}'`
3717
+ ).action(async (opts) => {
3718
+ try {
3719
+ const client = createClient(program2.optsWithGlobals());
3720
+ const base = await resolveBody(opts.body);
3721
+ const body = mergeBodyWithFlags(base, {
3722
+ ...opts.name !== void 0 && { name: opts.name },
3723
+ ...opts.description !== void 0 && { description: opts.description }
3724
+ });
3725
+ const wf = await client.workflows.create(body);
3726
+ printSuccess("Workflow created.", {
3727
+ id: wf.id,
3728
+ name: wf.name
3729
+ });
3730
+ } catch (err) {
3731
+ process.exitCode = handleError(err);
3732
+ }
3733
+ });
3734
+ workflow.command("update").description("Update a workflow").argument("<id>", "Workflow ID").option("--name <name>", "Workflow name").option("--description <text>", "Workflow description").option("--body <json>", "Request body as JSON, .json file, or '-' for stdin").addHelpText(
3735
+ "after",
3736
+ `
3737
+ Examples:
3738
+ $ nexus workflow update wf-123 --name "Renamed Workflow"
3739
+ $ nexus workflow update wf-123 --description "Updated description"
3740
+ $ nexus workflow update wf-123 --body '{"name":"Renamed"}'`
3741
+ ).action(async (id, opts) => {
3742
+ try {
3743
+ const client = createClient(program2.optsWithGlobals());
3744
+ const base = await resolveBody(opts.body);
3745
+ const body = mergeBodyWithFlags(base, {
3746
+ ...opts.name !== void 0 && { name: opts.name },
3747
+ ...opts.description !== void 0 && { description: opts.description }
3748
+ });
3749
+ await client.workflows.update(id, body);
3750
+ printSuccess("Workflow updated.", { id });
3751
+ } catch (err) {
3752
+ process.exitCode = handleError(err);
3753
+ }
3754
+ });
3755
+ workflow.command("delete").description("Delete a workflow").argument("<id>", "Workflow ID").option("--yes", "Skip confirmation").option("--dry-run", "Preview without deleting").addHelpText(
3756
+ "after",
3757
+ `
3758
+ Examples:
3759
+ $ nexus workflow delete wf-123
3760
+ $ nexus workflow delete wf-123 --yes
3761
+ $ nexus workflow delete wf-123 --dry-run`
3762
+ ).action(async (id, opts) => {
3763
+ try {
3764
+ const client = createClient(program2.optsWithGlobals());
3765
+ if (opts.dryRun) {
3766
+ const wf = await client.workflows.get(id);
3767
+ console.log(
3768
+ color.yellow("DRY RUN:") + ` Would delete workflow "${wf.name}" (${id})`
3769
+ );
3770
+ return;
3771
+ }
3772
+ if (!opts.yes && process.stdout.isTTY) {
3773
+ const readline2 = await import("readline/promises");
3774
+ const rl = readline2.createInterface({
3775
+ input: process.stdin,
3776
+ output: process.stdout
3777
+ });
3778
+ const answer = await rl.question(`Delete workflow ${id}? This cannot be undone. [y/N] `);
3779
+ rl.close();
3780
+ if (answer.toLowerCase() !== "y") {
3781
+ console.log("Aborted.");
3782
+ return;
3783
+ }
3784
+ }
3785
+ await client.workflows.delete(id);
3786
+ printSuccess("Workflow deleted.", { id });
3787
+ } catch (err) {
3788
+ process.exitCode = handleError(err);
3789
+ }
3790
+ });
3791
+ workflow.command("duplicate").description("Duplicate a workflow").argument("<id>", "Workflow ID").addHelpText(
3792
+ "after",
3793
+ `
3794
+ Examples:
3795
+ $ nexus workflow duplicate wf-123`
3796
+ ).action(async (id) => {
3797
+ try {
3798
+ const client = createClient(program2.optsWithGlobals());
3799
+ const wf = await client.workflows.duplicate(id);
3800
+ printSuccess("Workflow duplicated.", {
3801
+ id: wf.id,
3802
+ name: wf.name
3803
+ });
3804
+ } catch (err) {
3805
+ process.exitCode = handleError(err);
3806
+ }
3807
+ });
3808
+ workflow.command("publish").description("Publish a workflow").argument("<id>", "Workflow ID").addHelpText(
3809
+ "after",
3810
+ `
3811
+ Examples:
3812
+ $ nexus workflow publish wf-123`
3813
+ ).action(async (id) => {
3814
+ try {
3815
+ const client = createClient(program2.optsWithGlobals());
3816
+ const result = await client.workflows.publish(id);
3817
+ printSuccess("Workflow published.", { id, ...result });
3818
+ } catch (err) {
3819
+ process.exitCode = handleError(err);
3820
+ }
3821
+ });
3822
+ workflow.command("unpublish").description("Unpublish a workflow").argument("<id>", "Workflow ID").addHelpText(
3823
+ "after",
3824
+ `
3825
+ Examples:
3826
+ $ nexus workflow unpublish wf-123`
3827
+ ).action(async (id) => {
3828
+ try {
3829
+ const client = createClient(program2.optsWithGlobals());
3830
+ const result = await client.workflows.unpublish(id);
3831
+ printSuccess("Workflow unpublished.", { id, ...result });
3832
+ } catch (err) {
3833
+ process.exitCode = handleError(err);
3834
+ }
3835
+ });
3836
+ workflow.command("validate").description("Validate a workflow").argument("<id>", "Workflow ID").addHelpText(
3837
+ "after",
3838
+ `
3839
+ Examples:
3840
+ $ nexus workflow validate wf-123
3841
+ $ nexus workflow validate wf-123 --json`
3842
+ ).action(async (id) => {
3843
+ try {
3844
+ const client = createClient(program2.optsWithGlobals());
3845
+ const report = await client.workflows.validate(id);
3846
+ printRecord(report);
3847
+ } catch (err) {
3848
+ process.exitCode = handleError(err);
3849
+ }
3850
+ });
3851
+ workflow.command("test").description("Run a test execution of a workflow").argument("<id>", "Workflow ID").option("--input <json>", "Input JSON for the test").option("--body <json>", "Request body as JSON, .json file, or '-' for stdin").addHelpText(
3852
+ "after",
3853
+ `
3854
+ Examples:
3855
+ $ nexus workflow test wf-123 --input '{"message": "hello"}'
3856
+ $ nexus workflow test wf-123 --body '{"message": "hello"}'
3857
+ $ nexus workflow test wf-123 --json`
3858
+ ).action(async (id, opts) => {
3859
+ try {
3860
+ const client = createClient(program2.optsWithGlobals());
3861
+ const base = await resolveBody(opts.body);
3862
+ const input = opts.input ? JSON.parse(opts.input) : base ?? {};
3863
+ const result = await client.workflows.testWorkflow(id, input);
3864
+ printRecord(result);
3865
+ } catch (err) {
3866
+ process.exitCode = handleError(err);
3867
+ }
3868
+ });
3869
+ registerWorkflowBuilderCommands(workflow, program2);
3870
+ }
3871
+
3872
+ // src/index.ts
3873
+ init_output();
3874
+
3875
+ // src/util/version-check.ts
3876
+ var import_node_fs4 = __toESM(require("fs"));
3877
+ var import_node_os2 = __toESM(require("os"));
3878
+ var import_node_path4 = __toESM(require("path"));
3879
+ var PACKAGE_NAME = "@agent-nexus/cli";
3880
+ var CHECK_INTERVAL_MS = 24 * 60 * 60 * 1e3;
3881
+ var FETCH_TIMEOUT_MS = 3e3;
3882
+ var CACHE_FILE = import_node_path4.default.join(import_node_os2.default.homedir(), ".nexus-mcp", "version-check.json");
3883
+ function loadCache() {
3884
+ try {
3885
+ return JSON.parse(import_node_fs4.default.readFileSync(CACHE_FILE, "utf-8"));
3886
+ } catch {
3887
+ return null;
3888
+ }
3889
+ }
3890
+ function saveCache(cache) {
3891
+ try {
3892
+ const dir = import_node_path4.default.dirname(CACHE_FILE);
3893
+ import_node_fs4.default.mkdirSync(dir, { recursive: true, mode: 448 });
3894
+ import_node_fs4.default.writeFileSync(CACHE_FILE, JSON.stringify(cache), { mode: 384 });
3895
+ } catch {
3896
+ }
3897
+ }
3898
+ async function fetchLatestVersion() {
3899
+ try {
3900
+ const controller = new AbortController();
3901
+ const timer = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);
3902
+ const res = await fetch(`https://registry.npmjs.org/${PACKAGE_NAME}/latest`, {
3903
+ signal: controller.signal
3904
+ });
3905
+ clearTimeout(timer);
3906
+ if (!res.ok) return null;
3907
+ const json = await res.json();
3908
+ return json.version ?? null;
3909
+ } catch {
3910
+ return null;
3911
+ }
3912
+ }
3913
+ function compareSemver(a, b) {
3914
+ const pa = a.split(".").map(Number);
3915
+ const pb = b.split(".").map(Number);
3916
+ for (let i = 0; i < 3; i++) {
3917
+ const diff = (pa[i] ?? 0) - (pb[i] ?? 0);
3918
+ if (diff !== 0) return diff < 0 ? -1 : 1;
3919
+ }
3920
+ return 0;
3921
+ }
3922
+ async function checkForUpdate(currentVersion) {
3923
+ try {
3924
+ const cache = loadCache();
3925
+ if (cache && Date.now() - cache.lastChecked < CHECK_INTERVAL_MS) {
3926
+ if (compareSemver(currentVersion, cache.latestVersion) < 0) {
3927
+ return formatUpdateMessage(currentVersion, cache.latestVersion);
3928
+ }
3929
+ return null;
3930
+ }
3931
+ const latest = await fetchLatestVersion();
3932
+ if (!latest) return null;
3933
+ saveCache({ lastChecked: Date.now(), latestVersion: latest });
3934
+ if (compareSemver(currentVersion, latest) < 0) {
3935
+ return formatUpdateMessage(currentVersion, latest);
3936
+ }
3937
+ return null;
3938
+ } catch {
3939
+ return null;
3940
+ }
3941
+ }
3942
+ function formatUpdateMessage(current, latest) {
3943
+ return `
3944
+ Update available: ${current} \u2192 ${latest}
3945
+ Run "npm update -g ${PACKAGE_NAME}" to update.
3946
+ IMPORTANT: You MUST update before running any other nexus commands. Results from an outdated CLI may be incorrect.
3947
+ `;
3948
+ }
3949
+
3950
+ // src/index.ts
3951
+ var VERSION = "0.1.0";
3952
+ var program = new import_commander.Command().name("nexus").description("Official CLI for the Nexus AI agent platform").version(VERSION, "-v, --version").option("--json", "Output as JSON").option("--api-key <key>", "Override API key for this invocation").option("--base-url <url>", "Override API base URL").hook("preAction", (thisCommand) => {
3953
+ const opts = thisCommand.optsWithGlobals();
3954
+ if (opts.json) setJsonMode(true);
3955
+ });
3956
+ program.addHelpText("before", getBanner(VERSION));
3957
+ program.configureHelp({
3958
+ sortSubcommands: true
3959
+ });
3960
+ registerAuthCommands(program);
3961
+ registerAgentCommands(program);
3962
+ registerAgentToolCommands(program);
3963
+ registerVersionCommands(program);
3964
+ registerFolderCommands(program);
3965
+ registerDeploymentCommands(program);
3966
+ registerWorkflowCommands(program);
3967
+ registerExecutionCommands(program);
3968
+ registerDocumentCommands(program);
3969
+ registerCollectionCommands(program);
3970
+ registerTaskCommands(program);
3971
+ registerToolCommands(program);
3972
+ registerAnalyticsCommands(program);
3973
+ registerTicketCommands(program);
3974
+ registerApiCommand(program);
3975
+ registerEmulatorCommands(program);
3976
+ registerEvaluationCommands(program);
3977
+ registerTemplateCommands(program);
3978
+ registerExternalToolCommands(program);
3979
+ registerPromptAssistantCommands(program);
3980
+ registerModelCommands(program);
3981
+ if (process.argv.length <= 2) {
3982
+ program.help();
3983
+ }
3984
+ program.parseAsync(process.argv).then(async () => {
3985
+ const updateMsg = await checkForUpdate(VERSION);
3986
+ if (updateMsg && !isJsonMode()) {
3987
+ const { color: color2 } = await Promise.resolve().then(() => (init_output(), output_exports));
3988
+ process.stderr.write(color2.yellow(updateMsg));
3989
+ }
3990
+ }).catch((err) => {
3991
+ process.exitCode = handleError(err);
3992
+ });