@nodetool-ai/cli-workflow 0.0.0-stage → 0.8.9-beta.2

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 (71) hide show
  1. package/README.md +14 -2
  2. package/dist/.nodetool-build-stamp +1 -0
  3. package/dist/api-client.d.ts +580 -0
  4. package/dist/api-client.d.ts.map +1 -0
  5. package/dist/api-client.js +34 -0
  6. package/dist/api-client.js.map +1 -0
  7. package/dist/commands/collections.d.ts +10 -0
  8. package/dist/commands/collections.d.ts.map +1 -0
  9. package/dist/commands/collections.js +257 -0
  10. package/dist/commands/collections.js.map +1 -0
  11. package/dist/commands/costs.d.ts +15 -0
  12. package/dist/commands/costs.d.ts.map +1 -0
  13. package/dist/commands/costs.js +201 -0
  14. package/dist/commands/costs.js.map +1 -0
  15. package/dist/commands/debug.d.ts +13 -0
  16. package/dist/commands/debug.d.ts.map +1 -0
  17. package/dist/commands/debug.js +149 -0
  18. package/dist/commands/debug.js.map +1 -0
  19. package/dist/commands/errors.d.ts +11 -0
  20. package/dist/commands/errors.d.ts.map +1 -0
  21. package/dist/commands/errors.js +177 -0
  22. package/dist/commands/errors.js.map +1 -0
  23. package/dist/commands/generate.d.ts +17 -0
  24. package/dist/commands/generate.d.ts.map +1 -0
  25. package/dist/commands/generate.js +326 -0
  26. package/dist/commands/generate.js.map +1 -0
  27. package/dist/commands/generations.d.ts +17 -0
  28. package/dist/commands/generations.d.ts.map +1 -0
  29. package/dist/commands/generations.js +408 -0
  30. package/dist/commands/generations.js.map +1 -0
  31. package/dist/commands/install-missing-packs.d.ts +21 -0
  32. package/dist/commands/install-missing-packs.d.ts.map +1 -0
  33. package/dist/commands/install-missing-packs.js +48 -0
  34. package/dist/commands/install-missing-packs.js.map +1 -0
  35. package/dist/commands/node.d.ts +10 -0
  36. package/dist/commands/node.d.ts.map +1 -0
  37. package/dist/commands/node.js +130 -0
  38. package/dist/commands/node.js.map +1 -0
  39. package/dist/commands/projects.d.ts +11 -0
  40. package/dist/commands/projects.d.ts.map +1 -0
  41. package/dist/commands/projects.js +145 -0
  42. package/dist/commands/projects.js.map +1 -0
  43. package/dist/commands/resource-read.d.ts +28 -0
  44. package/dist/commands/resource-read.d.ts.map +1 -0
  45. package/dist/commands/resource-read.js +314 -0
  46. package/dist/commands/resource-read.js.map +1 -0
  47. package/dist/commands/runs.d.ts +7 -0
  48. package/dist/commands/runs.d.ts.map +1 -0
  49. package/dist/commands/runs.js +302 -0
  50. package/dist/commands/runs.js.map +1 -0
  51. package/dist/commands/validate.d.ts +24 -0
  52. package/dist/commands/validate.d.ts.map +1 -0
  53. package/dist/commands/validate.js +132 -0
  54. package/dist/commands/validate.js.map +1 -0
  55. package/dist/index.d.ts +16 -0
  56. package/dist/index.d.ts.map +1 -0
  57. package/dist/index.js +1034 -0
  58. package/dist/index.js.map +1 -0
  59. package/dist/nodetool.d.ts +3 -0
  60. package/dist/nodetool.d.ts.map +1 -0
  61. package/dist/nodetool.js +4 -0
  62. package/dist/nodetool.js.map +1 -0
  63. package/dist/packs/command-service.d.ts +3 -0
  64. package/dist/packs/command-service.d.ts.map +1 -0
  65. package/dist/packs/command-service.js +9 -0
  66. package/dist/packs/command-service.js.map +1 -0
  67. package/dist/workflow-packs.d.ts +7 -0
  68. package/dist/workflow-packs.d.ts.map +1 -0
  69. package/dist/workflow-packs.js +31 -0
  70. package/dist/workflow-packs.js.map +1 -0
  71. package/package.json +73 -4
@@ -0,0 +1,408 @@
1
+ /**
2
+ * `nodetool generations` — the record of every media generation, from the
3
+ * local DB, no server needed.
4
+ *
5
+ * One row per provider media call, opened before the call and closed with
6
+ * its outcome (docs/media-generation-tracking-design.md). `list` and `get`
7
+ * read the rows, `await` waits for one to settle, `cancel` closes a running
8
+ * one, `reconcile` asks the provider what it billed, and `sweep` runs the
9
+ * startup sweep plus one drain of the reconcile queue by hand.
10
+ *
11
+ * `provider-list` and `provider-get` ask the *provider* instead: its own
12
+ * record of what this account ran, from any machine, at the price it billed.
13
+ * The seven actions are the `generations` agent capabilities.
14
+ */
15
+ import { deriveGenerationStatus, Prediction, getSecret } from "@nodetool-ai/models";
16
+ import { drainReconcileQueue, reconcileGeneration, sweepInterruptedGenerations } from "@nodetool-ai/execution";
17
+ import { isProviderGenerationsUnsupported } from "@nodetool-ai/runtime";
18
+ import { createProviderStrict } from "@nodetool-ai/cli-providers";
19
+ import { asJson, printTable, printKv } from "@nodetool-ai/cli-common/commands/output";
20
+ import { setupLocalDb, LOCAL_USER_ID } from "@nodetool-ai/cli-local/local-db";
21
+ import { isString } from "@nodetool-ai/cli-common/predicates";
22
+ const PUBLIC_STATUSES = new Set([
23
+ "pending",
24
+ "running",
25
+ "recovering",
26
+ "completed",
27
+ "failed",
28
+ "cancelled",
29
+ "needs_attention",
30
+ "interrupted"
31
+ ]);
32
+ const TERMINAL = new Set([
33
+ "completed",
34
+ "failed",
35
+ "cancelled",
36
+ "needs_attention",
37
+ "interrupted"
38
+ ]);
39
+ function lifecycleError(row, key) {
40
+ const value = row.metadata?.[key];
41
+ return isString(value) ? value : null;
42
+ }
43
+ /** Completed is public only after the durable output has been saved. */
44
+ function publicGenerationStatus(row) {
45
+ if (row.status === "interrupted")
46
+ return "interrupted";
47
+ if (row.lifecycle_owner !== "durable") {
48
+ return PUBLIC_STATUSES.has(row.status) ? row.status : "pending";
49
+ }
50
+ return deriveGenerationStatus(row);
51
+ }
52
+ function fail(e) {
53
+ console.error(String(e instanceof Error ? e.message : e));
54
+ process.exit(1);
55
+ }
56
+ function costCell(cost) {
57
+ return cost == null ? "unpriced" : `$${cost.toFixed(4)}`;
58
+ }
59
+ /** The row, in the shape `get_generation` answers with. */
60
+ function record(row) {
61
+ const metadata = row.metadata ?? {};
62
+ return {
63
+ generation_id: row.id,
64
+ status: publicGenerationStatus(row),
65
+ submission_status: row.submission_status ?? null,
66
+ provider_status: row.provider_status ?? null,
67
+ output_status: row.output_status ?? null,
68
+ attachment_status: row.attachment_status ?? null,
69
+ provider: row.provider,
70
+ model: row.model,
71
+ capability: row.capability ?? null,
72
+ cost: row.cost,
73
+ currency: row.currency,
74
+ billing_unit: row.billing_unit,
75
+ quantity: row.quantity,
76
+ unit_price: row.unit_price,
77
+ price_source: metadata.price_source ?? null,
78
+ asset_ids: row.asset_ids ?? [],
79
+ started_at: row.started_at,
80
+ completed_at: row.completed_at,
81
+ duration_seconds: row.duration,
82
+ generation_error: row.error,
83
+ submission_error: lifecycleError(row, "submission_error"),
84
+ provider_error: lifecycleError(row, "provider_error"),
85
+ output_error: lifecycleError(row, "output_error"),
86
+ attachment_error: lifecycleError(row, "attachment_error"),
87
+ origin: {
88
+ surface: row.surface ?? null,
89
+ thread_id: row.thread_id ?? null,
90
+ tool_call_id: row.tool_call_id ?? null,
91
+ job_id: row.job_id ?? null,
92
+ node_id: row.node_id,
93
+ workflow_id: row.workflow_id
94
+ },
95
+ provider_request_id: row.provider_request_id,
96
+ reconcile: {
97
+ reconciled_at: row.reconciled_at ?? null,
98
+ attempts: row.reconcile_attempts ?? 0,
99
+ error: metadata.reconcile_error ?? null,
100
+ next_at: metadata.reconcile_next_at ?? null
101
+ },
102
+ parameters: row.parameters
103
+ };
104
+ }
105
+ function summaryRow(row) {
106
+ return {
107
+ id: row.id,
108
+ status: publicGenerationStatus(row),
109
+ provider: row.provider,
110
+ model: row.model,
111
+ capability: row.capability ?? "",
112
+ cost: costCell(row.cost),
113
+ assets: (row.asset_ids ?? []).join(","),
114
+ output: row.output_status ?? "",
115
+ started: row.started_at ?? row.created_at ?? ""
116
+ };
117
+ }
118
+ const resolveSecret = (key, userId) => getSecret(key, userId);
119
+ const PROVIDER_STATUSES = new Set([
120
+ "running",
121
+ "completed",
122
+ "failed",
123
+ "cancelled",
124
+ "unknown"
125
+ ]);
126
+ /** `--status` as the provider vocabulary, rejecting anything else outright. */
127
+ function providerStatusOption(value) {
128
+ if (!PROVIDER_STATUSES.has(value)) {
129
+ fail(`Invalid --status value: ${value}. One of ${[...PROVIDER_STATUSES].join(", ")}.`);
130
+ }
131
+ // SAFETY: the set holds exactly the members of ProviderGenerationStatus.
132
+ return value;
133
+ }
134
+ /** A provider with no history API is a capability answer, not a stack trace. */
135
+ function providerGenerationsMessage(providerId, error) {
136
+ if (isProviderGenerationsUnsupported(error)) {
137
+ return (`${providerId} exposes no generation history. Read this installation's ` +
138
+ `own record with \`nodetool generations list\`.`);
139
+ }
140
+ return String(error instanceof Error ? error.message : error);
141
+ }
142
+ function providerSummaryRow(row) {
143
+ return {
144
+ request_id: row.request_id,
145
+ status: row.status,
146
+ model: row.model ?? "",
147
+ cost: costCell(row.cost),
148
+ started: row.created_at ?? "",
149
+ outputs: String(row.output_urls.length)
150
+ };
151
+ }
152
+ export function registerGenerationsCommands(program) {
153
+ const generations = program
154
+ .command("generations")
155
+ .description("Inspect, wait on, cancel and reconcile media generations");
156
+ generations
157
+ .command("list")
158
+ .description("List generations, newest first")
159
+ .option("--status <status>", "pending, running, recovering, completed, failed, cancelled, needs_attention, interrupted")
160
+ .option("--provider <name>", "Filter by provider")
161
+ .option("--capability <name>", "Filter by capability, e.g. text_to_video")
162
+ .option("--thread-id <id>", "Only generations a chat thread asked for")
163
+ .option("--job-id <id>", "Only generations a workflow run asked for")
164
+ .option("--since <iso>", "Only generations created at or after this time")
165
+ .option("--limit <n>", "Max results", "50")
166
+ .option("--json", "Output as JSON")
167
+ .action(async (opts) => {
168
+ const limit = Number.parseInt(opts.limit, 10);
169
+ if (!Number.isFinite(limit) || limit <= 0) {
170
+ console.error(`Invalid --limit value: ${opts.limit}`);
171
+ process.exit(1);
172
+ }
173
+ try {
174
+ await setupLocalDb();
175
+ const [rows, next] = await Prediction.listGenerations(LOCAL_USER_ID, {
176
+ status: opts.status,
177
+ provider: opts.provider,
178
+ capability: opts.capability,
179
+ threadId: opts.threadId,
180
+ jobId: opts.jobId,
181
+ since: opts.since,
182
+ limit
183
+ });
184
+ if (opts.json) {
185
+ asJson({ generations: rows.map(record), next: next || null });
186
+ return;
187
+ }
188
+ if (rows.length === 0) {
189
+ console.log("No generations recorded.");
190
+ return;
191
+ }
192
+ printTable(rows.map(summaryRow));
193
+ }
194
+ catch (e) {
195
+ fail(e);
196
+ }
197
+ });
198
+ generations
199
+ .command("get <generation_id>")
200
+ .description("Read one generation in full")
201
+ .option("--json", "Output as JSON")
202
+ .action(async (id, opts) => {
203
+ try {
204
+ await setupLocalDb();
205
+ const row = await Prediction.findForUser(LOCAL_USER_ID, id);
206
+ if (!row)
207
+ fail(`Generation ${id} was not found.`);
208
+ const rec = record(row);
209
+ if (opts.json) {
210
+ asJson(rec);
211
+ return;
212
+ }
213
+ printKv(rec);
214
+ }
215
+ catch (e) {
216
+ fail(e);
217
+ }
218
+ });
219
+ generations
220
+ .command("await <generation_id>")
221
+ .description("Wait for a generation to settle, polling the row")
222
+ .option("--timeout <seconds>", "How long to wait", "300")
223
+ .option("--json", "Output as JSON")
224
+ .action(async (id, opts) => {
225
+ const timeoutMs = Math.max(1, Number.parseInt(opts.timeout, 10) || 300) * 1000;
226
+ try {
227
+ await setupLocalDb();
228
+ const deadline = Date.now() + timeoutMs;
229
+ let row = await Prediction.findForUser(LOCAL_USER_ID, id);
230
+ if (!row)
231
+ fail(`Generation ${id} was not found.`);
232
+ while (!TERMINAL.has(publicGenerationStatus(row)) &&
233
+ Date.now() < deadline) {
234
+ await new Promise((r) => setTimeout(r, 2_000));
235
+ row = (await Prediction.findForUser(LOCAL_USER_ID, id)) ?? row;
236
+ }
237
+ const rec = record(row);
238
+ if (opts.json) {
239
+ asJson(rec);
240
+ }
241
+ else {
242
+ printKv(rec);
243
+ }
244
+ // The exit code is the verdict: a generation still running when the
245
+ // wait ran out is not a settled one.
246
+ process.exit(TERMINAL.has(publicGenerationStatus(row)) ? 0 : 1);
247
+ }
248
+ catch (e) {
249
+ fail(e);
250
+ }
251
+ });
252
+ generations
253
+ .command("cancel <generation_id>")
254
+ .description("Close a running generation as cancelled")
255
+ .option("--json", "Output as JSON")
256
+ .action(async (id, opts) => {
257
+ try {
258
+ await setupLocalDb();
259
+ const row = await Prediction.findForUser(LOCAL_USER_ID, id);
260
+ const isDurable = row?.lifecycle_owner === "durable";
261
+ const cancellationRequested = isDurable
262
+ ? await Prediction.requestCancellation(id, LOCAL_USER_ID)
263
+ : false;
264
+ const cancelled = isDurable
265
+ ? false
266
+ : await Prediction.markCancelledIfRunning(id, LOCAL_USER_ID);
267
+ const succeeded = cancellationRequested || cancelled;
268
+ const result = {
269
+ generation_id: id,
270
+ cancelled,
271
+ cancellation_requested: cancellationRequested
272
+ };
273
+ if (opts.json)
274
+ asJson(result);
275
+ else
276
+ console.log(cancellationRequested
277
+ ? `Cancellation requested for durable generation ${id}. The worker will close the record after the provider responds.`
278
+ : cancelled
279
+ ? `Generation ${id} cancelled. A call running in a server process finishes on its own; the record is closed.`
280
+ : `Generation ${id} is not running — it already settled, or it does not exist.`);
281
+ process.exit(succeeded ? 0 : 1);
282
+ }
283
+ catch (e) {
284
+ fail(e);
285
+ }
286
+ });
287
+ generations
288
+ .command("reconcile <generation_id>")
289
+ .description("Ask the provider what it billed, by request id, and update the row")
290
+ .option("--json", "Output as JSON")
291
+ .action(async (id, opts) => {
292
+ try {
293
+ await setupLocalDb();
294
+ const outcome = await reconcileGeneration(id, LOCAL_USER_ID, (key) => resolveSecret(key, LOCAL_USER_ID));
295
+ if (!outcome.found)
296
+ fail(`Generation ${id} was not found.`);
297
+ const result = {
298
+ generation_id: id,
299
+ before: outcome.before,
300
+ after: outcome.after,
301
+ reconciled: outcome.reconciled,
302
+ reason: outcome.reason ?? null
303
+ };
304
+ if (opts.json)
305
+ asJson(result);
306
+ else
307
+ printKv(result);
308
+ process.exit(outcome.reconciled ? 0 : 1);
309
+ }
310
+ catch (e) {
311
+ fail(e);
312
+ }
313
+ });
314
+ generations
315
+ .command("provider-list")
316
+ .description("List the provider's own record of this account's generations")
317
+ .requiredOption("--provider <name>", "Provider id, e.g. fal_ai")
318
+ .option("--model <id>", "Only this endpoint / model id (comma-separated)")
319
+ .option("--status <status>", "running, completed, failed, cancelled, unknown")
320
+ .option("--since <iso>", "Only generations started at or after this time")
321
+ .option("--until <iso>", "Exclusive upper bound")
322
+ .option("--limit <n>", "Max results", "50")
323
+ .option("--cursor <cursor>", "The next_cursor from a previous page")
324
+ .option("--json", "Output as JSON")
325
+ .action(async (opts) => {
326
+ try {
327
+ await setupLocalDb();
328
+ const provider = await createProviderStrict(opts.provider);
329
+ const query = {
330
+ limit: Math.max(1, Number.parseInt(opts.limit, 10) || 50)
331
+ };
332
+ if (opts.model)
333
+ query.model = opts.model.split(",").map((m) => m.trim());
334
+ if (opts.status)
335
+ query.status = providerStatusOption(opts.status);
336
+ if (opts.since)
337
+ query.since = opts.since;
338
+ if (opts.until)
339
+ query.until = opts.until;
340
+ if (opts.cursor)
341
+ query.cursor = opts.cursor;
342
+ const page = await provider.listGenerations(query);
343
+ if (opts.json) {
344
+ asJson(page);
345
+ return;
346
+ }
347
+ if (page.generations.length === 0) {
348
+ console.log(`${opts.provider} reports no generations.`);
349
+ }
350
+ else {
351
+ printTable(page.generations.map(providerSummaryRow));
352
+ }
353
+ if (page.note)
354
+ console.log(page.note);
355
+ if (page.next_cursor)
356
+ console.log(`next_cursor: ${page.next_cursor}`);
357
+ }
358
+ catch (e) {
359
+ fail(providerGenerationsMessage(opts.provider, e));
360
+ }
361
+ });
362
+ generations
363
+ .command("provider-get <request_id>")
364
+ .description("Ask a provider about one generation, by its own request id")
365
+ .requiredOption("--provider <name>", "Provider id, e.g. fal_ai")
366
+ .option("--model <id>", "The endpoint / model id, when known")
367
+ .option("--json", "Output as JSON")
368
+ .action(async (requestId, opts) => {
369
+ try {
370
+ await setupLocalDb();
371
+ const provider = await createProviderStrict(opts.provider);
372
+ const lookup = {};
373
+ if (opts.model)
374
+ lookup.model = opts.model;
375
+ const row = await provider.getGeneration(requestId, lookup);
376
+ if (!row)
377
+ fail(`${opts.provider} has no request ${requestId}.`);
378
+ if (opts.json)
379
+ asJson(row);
380
+ else
381
+ printKv({ ...row });
382
+ }
383
+ catch (e) {
384
+ fail(providerGenerationsMessage(opts.provider, e));
385
+ }
386
+ });
387
+ generations
388
+ .command("sweep")
389
+ .description("Close running rows older than now as interrupted, then drain the reconcile queue once")
390
+ .option("--json", "Output as JSON")
391
+ .action(async (opts) => {
392
+ try {
393
+ await setupLocalDb();
394
+ // Nothing is running in this process, so every open row is orphaned.
395
+ const interrupted = await sweepInterruptedGenerations(new Date().toISOString());
396
+ const reconciled = await drainReconcileQueue(resolveSecret);
397
+ const result = { interrupted, reconcile_attempts: reconciled };
398
+ if (opts.json)
399
+ asJson(result);
400
+ else
401
+ printKv(result);
402
+ }
403
+ catch (e) {
404
+ fail(e);
405
+ }
406
+ });
407
+ }
408
+ //# sourceMappingURL=generations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generations.js","sourceRoot":"","sources":["../../src/commands/generations.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import { spawnSync } from "node:child_process";
2
+ import type { NodeCatalogIndex } from "@nodetool-ai/node-catalog";
3
+ import { loadCliPackSnapshot } from "@nodetool-ai/cli-execution/packs/host";
4
+ import { installPacks } from "@nodetool-ai/pack-manager/packs/installer";
5
+ import { authorizePackInstallCommand } from "@nodetool-ai/pack-manager/commands/pack-install-authorization";
6
+ export type PackRunCommand = "run" | "debug" | "node-run" | "workflows-run";
7
+ /** An authorized run installs once, then delegates the original command to a fresh process. */
8
+ export declare function installMissingPacksAndReexec(value: unknown, options: {
9
+ readonly command: PackRunCommand;
10
+ readonly installMissing?: boolean;
11
+ readonly prompt?: Parameters<typeof authorizePackInstallCommand>[0]["prompt"];
12
+ readonly stateFile?: string;
13
+ readonly catalog?: NodeCatalogIndex;
14
+ }, dependencies?: {
15
+ readonly snapshot?: typeof loadCliPackSnapshot;
16
+ readonly authorize?: typeof authorizePackInstallCommand;
17
+ readonly install?: typeof installPacks;
18
+ readonly spawn?: typeof spawnSync;
19
+ readonly write?: (message: string) => void;
20
+ }): Promise<number | null>;
21
+ //# sourceMappingURL=install-missing-packs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install-missing-packs.d.ts","sourceRoot":"","sources":["../../src/commands/install-missing-packs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAG/C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAIlE,OAAO,EAAE,mBAAmB,EAAE,MAAM,uCAAuC,CAAC;AAC5E,OAAO,EAAE,YAAY,EAAE,MAAM,2CAA2C,CAAC;AAGzE,OAAO,EAAE,2BAA2B,EAAE,MAAM,+DAA+D,CAAC;AAE5G,MAAM,MAAM,cAAc,GAAG,KAAK,GAAG,OAAO,GAAG,UAAU,GAAG,eAAe,CAAC;AAE5E,+FAA+F;AAC/F,wBAAsB,4BAA4B,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE;IAC1E,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC;IACjC,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC;IAClC,QAAQ,CAAC,MAAM,CAAC,EAAE,UAAU,CAAC,OAAO,2BAA2B,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;IAC9E,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,CAAC,EAAE,gBAAgB,CAAC;CACrC,EAAE,YAAY,GAAE;IACf,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,mBAAmB,CAAC;IAC/C,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,2BAA2B,CAAC;IACxD,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,YAAY,CAAC;IACvC,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,SAAS,CAAC;IAClC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACvC,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAgC9B"}
@@ -0,0 +1,48 @@
1
+ import { spawnSync } from "node:child_process";
2
+ import { join } from "node:path";
3
+ import { getNodetoolDataDir } from "@nodetool-ai/config";
4
+ import { isRuntimeNpmPackageId } from "@nodetool-ai/protocol/runtime-npm-packages";
5
+ import { commandMissingPack, commandMissingRuntime } from "@nodetool-ai/pack-manager/command-errors";
6
+ import { childExitCode } from "@nodetool-ai/pack-manager/child-exit";
7
+ import { loadCliPackSnapshot } from "@nodetool-ai/cli-execution/packs/host";
8
+ import { installPacks } from "@nodetool-ai/pack-manager/packs/installer";
9
+ import { restartNotice } from "@nodetool-ai/pack-manager/packs/management";
10
+ import { installWithCommandAuthorization } from "@nodetool-ai/pack-manager/commands/authorized-pack-install";
11
+ import { authorizePackInstallCommand } from "@nodetool-ai/pack-manager/commands/pack-install-authorization";
12
+ /** An authorized run installs once, then delegates the original command to a fresh process. */
13
+ export async function installMissingPacksAndReexec(value, options, dependencies = {}) {
14
+ const missing = commandMissingPack(value);
15
+ const runtime = commandMissingRuntime(value)?.runtimePackage;
16
+ const runtimeLibraries = [...new Set([...(missing?.runtimeLibraries ?? []).filter(isRuntimeNpmPackageId),
17
+ ...(runtime && isRuntimeNpmPackageId(runtime) ? [runtime] : [])])];
18
+ if ((!missing && !runtimeLibraries.length) || process.env["NODETOOL_PACKS_REEXEC"] === "1") {
19
+ return null;
20
+ }
21
+ const snapshot = await (dependencies.snapshot ?? loadCliPackSnapshot)();
22
+ if (snapshot.mode.kind !== "global" && snapshot.mode.kind !== "local") {
23
+ return null;
24
+ }
25
+ const request = {
26
+ mode: snapshot.mode,
27
+ packs: missing?.packs.map(pack => pack.id) ?? [],
28
+ runtimeLibraries,
29
+ stateFile: options.stateFile ?? join(getNodetoolDataDir(), "cli-packs.json"),
30
+ catalog: options.catalog
31
+ };
32
+ const installed = await installWithCommandAuthorization({
33
+ authorize: () => (dependencies.authorize ?? authorizePackInstallCommand)({
34
+ request, command: options.command, installMissing: options.installMissing, prompt: options.prompt
35
+ }),
36
+ install: authorization => (dependencies.install ?? installPacks)(request, authorization)
37
+ });
38
+ if (!installed) {
39
+ return null;
40
+ }
41
+ const write = dependencies.write ?? ((message) => { process.stderr.write(message + "\n"); });
42
+ write(restartNotice([...request.packs, ...request.runtimeLibraries]));
43
+ const child = (dependencies.spawn ?? spawnSync)(process.execPath, [...process.execArgv, ...process.argv.slice(1)], {
44
+ shell: false, stdio: "inherit", env: { ...process.env, NODETOOL_PACKS_REEXEC: "1" }
45
+ });
46
+ return childExitCode(child);
47
+ }
48
+ //# sourceMappingURL=install-missing-packs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install-missing-packs.js","sourceRoot":"","sources":["../../src/commands/install-missing-packs.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * `nodetool node` — inspect and run individual nodes.
3
+ *
4
+ * nodetool node run <type> --props '{"text":"hi"}' # run one node, print outputs
5
+ *
6
+ * Heavy deps (registry + runtime) load lazily inside the action.
7
+ */
8
+ import type { Command } from "commander";
9
+ export declare function registerNodeCommands(program: Command): void;
10
+ //# sourceMappingURL=node.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../src/commands/node.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAazC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAgI3D"}
@@ -0,0 +1,130 @@
1
+ import { asJson, printTable } from "@nodetool-ai/cli-common/commands/output";
2
+ import { printCommandError, commandMissingRuntime, commandMissingPack } from "@nodetool-ai/pack-manager/command-errors";
3
+ import { installMissingPacksAndReexec } from "./install-missing-packs.js";
4
+ export function registerNodeCommands(program) {
5
+ const node = program
6
+ .command("node")
7
+ .description("Inspect and run individual nodes");
8
+ node
9
+ .command("list [query]")
10
+ .description("List installed TypeScript node types (optionally filter by type or title)")
11
+ .option("--json", "Print complete node metadata as JSON")
12
+ .action(async (query, opts) => {
13
+ try {
14
+ const { buildFullRegistry } = await import("@nodetool-ai/cli-execution/node-registry");
15
+ const registry = await buildFullRegistry();
16
+ const search = query?.toLowerCase() ?? "";
17
+ const nodes = registry.listMetadata()
18
+ .filter((meta) => registry.has(meta.node_type))
19
+ .filter((meta) => `${meta.node_type} ${meta.title}`.toLowerCase().includes(search))
20
+ .sort((a, b) => a.node_type.localeCompare(b.node_type));
21
+ if (opts.json) {
22
+ asJson(nodes);
23
+ }
24
+ else if (nodes.length === 0) {
25
+ console.log('No installed node types match. Run "nodetool packs list" to inspect installed packs.');
26
+ }
27
+ else {
28
+ printTable(nodes.map((meta) => ({ type: meta.node_type, title: meta.title })));
29
+ console.log('Use "nodetool node info <type>" for properties and outputs.');
30
+ }
31
+ }
32
+ catch (error) {
33
+ process.exitCode = printCommandError(error, opts.json);
34
+ }
35
+ });
36
+ node
37
+ .command("info <node_type>")
38
+ .description("Show an installed node's properties, defaults, inputs and outputs")
39
+ .option("--json", "Print complete node metadata as JSON")
40
+ .action(async (nodeType, opts) => {
41
+ try {
42
+ const { buildFullRegistry } = await import("@nodetool-ai/cli-execution/node-registry");
43
+ const registry = await buildFullRegistry();
44
+ if (!registry.has(nodeType)) {
45
+ throw new Error(`Node type "${nodeType}" is not installed. Use "nodetool node list" or "nodetool packs list".`);
46
+ }
47
+ asJson(registry.getMetadata(nodeType));
48
+ }
49
+ catch (error) {
50
+ process.exitCode = printCommandError(error, opts.json);
51
+ }
52
+ });
53
+ node
54
+ .command("run <node_type>")
55
+ .description("Run a single node with the given properties and print what it emits")
56
+ .option("--props <json>", "JSON object of property values keyed by @prop name", "{}")
57
+ .option("--no-secrets", "Don't resolve secrets/assets (hermetic run)")
58
+ .option("--json", "Print the full run result as JSON")
59
+ .option("--install-missing", "Authorize missing node pack installation, then re-execute once")
60
+ .action(async (nodeType, opts) => {
61
+ try {
62
+ const { runSingleNode } = await import("@nodetool-ai/cli-execution/node/run-node");
63
+ let props;
64
+ try {
65
+ props = JSON.parse(opts.props ?? "{}");
66
+ }
67
+ catch (e) {
68
+ throw new Error(`--props is not valid JSON: ${String(e)}`);
69
+ }
70
+ // Only touch the DB / SQLite when secrets are actually needed, so a
71
+ // hermetic `--no-secrets` run works without the native binding built.
72
+ const useSecrets = opts.secrets !== false;
73
+ let secretResolver;
74
+ if (useSecrets) {
75
+ const { initDb } = await import("@nodetool-ai/models");
76
+ const { resolveLocalSecret } = await import("@nodetool-ai/cli-local/local-secrets");
77
+ const { initMasterKey } = await import("@nodetool-ai/security");
78
+ const { getDefaultDbPath } = await import("@nodetool-ai/config");
79
+ initDb(getDefaultDbPath());
80
+ try {
81
+ await initMasterKey();
82
+ }
83
+ catch {
84
+ // Secret decryption is best-effort; only nodes needing secrets care.
85
+ }
86
+ secretResolver = resolveLocalSecret;
87
+ }
88
+ const runOptions = { props };
89
+ if (secretResolver) {
90
+ runOptions.secretResolver = secretResolver;
91
+ }
92
+ const result = await runSingleNode(nodeType, runOptions);
93
+ if (!result.ok && (commandMissingRuntime(result) || commandMissingPack(result))) {
94
+ const exit = await installMissingPacksAndReexec(result, { command: "node-run", installMissing: opts.installMissing });
95
+ if (exit !== null) {
96
+ process.exit(exit);
97
+ }
98
+ process.exit(printCommandError(result, opts.json));
99
+ }
100
+ const { printRunJson, previewJson } = await import("@nodetool-ai/cli-execution/run-json");
101
+ if (opts.json) {
102
+ await printRunJson(result);
103
+ }
104
+ else {
105
+ const mark = result.ok ? "✅" : "❌";
106
+ console.log(`\n${mark} ${nodeType}${result.title ? ` (${result.title})` : ""} — ${result.durationMs}ms`);
107
+ if (result.error)
108
+ console.log(`\nError: ${result.error}`);
109
+ if (result.chunks.length > 0) {
110
+ console.log(`\nEmitted ${result.chunks.length} record(s):`);
111
+ for (const chunk of result.chunks) {
112
+ console.log(` ${previewJson(chunk, 500)}`);
113
+ }
114
+ }
115
+ else if (result.ok) {
116
+ console.log("\n(no output emitted)");
117
+ }
118
+ }
119
+ process.exit(result.ok ? 0 : 1);
120
+ }
121
+ catch (e) {
122
+ const exit = await installMissingPacksAndReexec(e, { command: "node-run", installMissing: opts.installMissing });
123
+ if (exit !== null) {
124
+ process.exit(exit);
125
+ }
126
+ process.exit(printCommandError(e, opts.json));
127
+ }
128
+ });
129
+ }
130
+ //# sourceMappingURL=node.js.map