@cargo-ai/cli 1.0.25 → 1.0.26

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 (30) hide show
  1. package/README.md +17 -17
  2. package/build/commands/cdk/index.d.ts +4 -0
  3. package/build/commands/cdk/index.d.ts.map +1 -0
  4. package/build/commands/cdk/index.js +539 -0
  5. package/build/commands/cdk/init.d.ts +3 -0
  6. package/build/commands/cdk/init.d.ts.map +1 -0
  7. package/build/commands/cdk/init.js +86 -0
  8. package/build/commands/{workflow → cdk}/inputTypes.d.ts +6 -0
  9. package/build/commands/cdk/inputTypes.d.ts.map +1 -0
  10. package/build/commands/{workflow → cdk}/inputTypes.js +115 -17
  11. package/build/commands/cdk/types.d.ts +4 -0
  12. package/build/commands/cdk/types.d.ts.map +1 -0
  13. package/build/commands/{workflow/sync.js → cdk/types.js} +139 -208
  14. package/build/commands/hosting/app.js +1 -1
  15. package/build/commands/hosting/worker.js +1 -1
  16. package/build/commands/runHandler.d.ts +5 -1
  17. package/build/commands/runHandler.d.ts.map +1 -1
  18. package/build/commands/runHandler.js +36 -4
  19. package/build/commands/templateUtils.d.ts.map +1 -0
  20. package/build/index.js +2 -0
  21. package/package.json +4 -3
  22. package/build/commands/hosting/templateUtils.d.ts.map +0 -1
  23. package/build/commands/workflow/index.d.ts +0 -4
  24. package/build/commands/workflow/index.d.ts.map +0 -1
  25. package/build/commands/workflow/index.js +0 -10
  26. package/build/commands/workflow/inputTypes.d.ts.map +0 -1
  27. package/build/commands/workflow/sync.d.ts +0 -4
  28. package/build/commands/workflow/sync.d.ts.map +0 -1
  29. /package/build/commands/{hosting/templateUtils.d.ts → templateUtils.d.ts} +0 -0
  30. /package/build/commands/{hosting/templateUtils.js → templateUtils.js} +0 -0
@@ -1,7 +1,7 @@
1
1
  import { mkdirSync, writeFileSync } from "node:fs";
2
2
  import { resolve } from "node:path";
3
3
  import { handleApiCall, info, success } from "../runHandler.js";
4
- import { AGENT_INPUT_TYPE_SRC, printFormFieldsInput, printJsonSchemaInput, } from "./inputTypes.js";
4
+ import { printJsonSchemaInput, printJsonSchemaType } from "./inputTypes.js";
5
5
  // Composite natives surfaced via dedicated SDK syntax / scope helpers —
6
6
  // excluded so we don't double-register them. Mirrors the codegen exclusion
7
7
  // list in `packages/workflow-sdk/scripts/generateNativeIntegration.ts`
@@ -34,15 +34,19 @@ const BUNDLED_NATIVE = new Set([
34
34
  "scoring",
35
35
  "script",
36
36
  ]);
37
- export function registerSyncCommand(parent, getApi) {
37
+ export function registerTypesCommand(parent, getApi) {
38
38
  parent
39
- .command("sync")
40
- .description("Generate per-workspace TypeScript types + eager registration for the Cargo Workflow SDK")
41
- .option("--out <dir>", "Output directory for generated files (default: .cargo-ai)", ".cargo-ai")
42
- .option("--cwd <dir>", "Working directory the --out path is resolved against (default: process.cwd())")
39
+ .command("types")
40
+ .description("Generate per-workspace TypeScript types for the Cargo CDK — typed defineConnector/defineModel config + integration actions in workflow bodies")
41
+ .option("--dir <path>", "Repo root the generated files are written into (default: cwd)")
42
+ .option("--out <dir>", "Output subdirectory for generated files (default: .cargo-ai)", ".cargo-ai")
43
43
  .action(async (opts) => {
44
44
  const api = getApi();
45
- const baseDir = opts.cwd !== undefined ? opts.cwd : process.cwd();
45
+ // Match the other `cdk` commands: `--dir` selects the repo root, and the
46
+ // generated `.cargo-ai` lands there (not wherever the CLI happens to run).
47
+ if (opts.dir !== undefined)
48
+ process.chdir(opts.dir);
49
+ const baseDir = process.cwd();
46
50
  const outDir = resolve(baseDir, opts.out);
47
51
  info(`Fetching workspace surface…`);
48
52
  const payload = await fetchWorkspaceSurface(api);
@@ -56,27 +60,70 @@ export function registerSyncCommand(parent, getApi) {
56
60
  info(``);
57
61
  info([
58
62
  `Next steps:`,
59
- ` 1. Add ${relativeToBase(baseDir, outDir)} to your tsconfig include`,
60
- ` so the .d.ts is picked up.`,
61
- ` 2. Add \`import "./${relativeToBase(baseDir, eagerPath).replace(/\.ts$/, ".js")}";\``,
62
- ` to your project's entry file (or before any defineWorkflow call)`,
63
- ` so the workspace's integrations / tools / agents register at runtime.`,
63
+ ` 1. Add "${relativeToBase(baseDir, outDir)}/**/*.d.ts" to your tsconfig`,
64
+ ` include so the types are picked up (a bare dot-dir path is ignored by`,
65
+ ` TypeScript). Enables typed defineConnector/defineModel config.`,
66
+ ` 2. To also type integration actions inside workflow bodies, add`,
67
+ ` \`import "./${relativeToBase(baseDir, eagerPath).replace(/\.ts$/, ".js")}";\``,
68
+ ` to your entry file so the workspace's integrations register at runtime.`,
64
69
  ].join("\n"));
65
70
  info(``);
66
- info(`Synced ${String(payload.integrations.length)} integration(s), ${String(payload.tools.length)} tool(s), ${String(payload.agents.length)} agent(s), ${String(payload.native.length)} native action(s).`);
71
+ const extractorCount = payload.extractorConfigs.reduce((n, e) => n + e.extractors.length, 0);
72
+ info(`Typed ${String(payload.connectorConfigs.length)} connector config(s), ${String(extractorCount)} extractor config(s), ${String(payload.integrations.length)} integration(s), ${String(payload.native.length)} native action(s).`);
67
73
  });
68
74
  }
69
75
  async function fetchWorkspaceSurface(api) {
70
76
  const integrationsResult = await handleApiCall(() => api.connection.integration.list({}));
71
77
  const nativeIntegrationResult = await handleApiCall(() => api.connection.nativeIntegration.get());
72
- const orchestrationToolsResult = await handleApiCall(() => api.orchestration.tool.all());
73
- const aiAgentsResult = await handleApiCall(() => api.ai.agent.all());
74
- const integrations = collectIntegrations(integrationsResult.integrations);
75
- const tools = collectTools(orchestrationToolsResult.tools);
76
- await resolveToolInputTypes(api, tools);
77
- const agents = collectAgents(aiAgentsResult);
78
+ const rawIntegrations = integrationsResult.integrations;
79
+ const integrations = collectIntegrations(rawIntegrations);
78
80
  const native = collectNative(nativeIntegrationResult.nativeIntegration.actions);
79
- return { integrations, tools, agents, native };
81
+ const connectorConfigs = collectConnectorConfigs(rawIntegrations);
82
+ const extractorConfigs = collectExtractorConfigs(rawIntegrations);
83
+ return { integrations, native, connectorConfigs, extractorConfigs };
84
+ }
85
+ // integrationSlug → connector config type. Skips integrations whose schema
86
+ // prints as a bare record (no typing gained — the builder already falls back to
87
+ // that), keeping the generated file to connectors that actually add types.
88
+ function collectConnectorConfigs(integrations) {
89
+ const out = [];
90
+ for (const integration of integrations) {
91
+ const schema = integration.connector?.config?.schema;
92
+ if (schema === undefined)
93
+ continue;
94
+ const typeSrc = printJsonSchemaType(schema);
95
+ if (typeSrc === "Record<string, unknown>")
96
+ continue;
97
+ out.push({
98
+ slug: integration.slug,
99
+ name: trimOrUndefined(integration.name),
100
+ typeSrc,
101
+ });
102
+ }
103
+ out.sort((a, b) => a.slug.localeCompare(b.slug));
104
+ return out;
105
+ }
106
+ // integrationSlug → its extractors' config types. Skips extractors whose schema
107
+ // prints as a bare record, and integrations left with none.
108
+ function collectExtractorConfigs(integrations) {
109
+ const out = [];
110
+ for (const integration of integrations) {
111
+ const extractors = [];
112
+ for (const [slug, extractor] of Object.entries(integration.extractors ?? {}).sort(([a], [b]) => a.localeCompare(b))) {
113
+ const schema = extractor.config?.schema;
114
+ if (schema === undefined)
115
+ continue;
116
+ const typeSrc = printJsonSchemaType(schema);
117
+ if (typeSrc === "Record<string, unknown>")
118
+ continue;
119
+ extractors.push({ slug, typeSrc });
120
+ }
121
+ if (extractors.length === 0)
122
+ continue;
123
+ out.push({ integrationSlug: integration.slug, extractors });
124
+ }
125
+ out.sort((a, b) => a.integrationSlug.localeCompare(b.integrationSlug));
126
+ return out;
80
127
  }
81
128
  function collectIntegrations(integrations) {
82
129
  const out = [];
@@ -103,77 +150,6 @@ function collectIntegrations(integrations) {
103
150
  out.sort((a, b) => a.slug.localeCompare(b.slug));
104
151
  return out;
105
152
  }
106
- function collectTools(workspaceTools) {
107
- const out = [];
108
- const used = new Set();
109
- for (const t of workspaceTools) {
110
- out.push({
111
- slug: pickSlug(t.name, t.uuid, used),
112
- name: t.name,
113
- description: trimOrUndefined(t.description),
114
- uuid: t.uuid,
115
- workflowUuid: t.workflowUuid,
116
- updatedAt: dateToIso(t.updatedAt),
117
- inputTypeSrc: "Record<string, unknown>",
118
- });
119
- }
120
- out.sort((a, b) => a.slug.localeCompare(b.slug));
121
- return out;
122
- }
123
- // The tools list endpoint doesn't carry input schemas — they live on each
124
- // tool workflow's deployed release as `formFields`. Resolve them with one
125
- // `release.getDeployed` call per tool (bounded concurrency). A tool without
126
- // a deployed release (or whose release fetch fails) keeps the
127
- // `Record<string, unknown>` fallback; sync must not abort over one tool.
128
- const TOOL_RELEASE_CONCURRENCY = 5;
129
- async function resolveToolInputTypes(api, tools) {
130
- const queue = [...tools];
131
- const workers = Array.from({ length: Math.min(TOOL_RELEASE_CONCURRENCY, queue.length) }, async () => {
132
- for (;;) {
133
- const tool = queue.shift();
134
- if (tool === undefined)
135
- return;
136
- try {
137
- const result = await api.orchestration.release.getDeployed({
138
- workflowUuid: tool.workflowUuid,
139
- });
140
- const formFields = result.release?.formFields;
141
- const printed = printFormFieldsInput(formFields);
142
- if (printed !== undefined) {
143
- tool.inputTypeSrc = printed;
144
- }
145
- }
146
- catch {
147
- // Not deployed / not accessible — keep the loose fallback type.
148
- }
149
- }
150
- });
151
- await Promise.all(workers);
152
- }
153
- function collectAgents(workspaceAgents) {
154
- const out = [];
155
- const used = new Set();
156
- const allAgents = isAgentsResult(workspaceAgents)
157
- ? workspaceAgents.agents
158
- : [];
159
- for (const a of allAgents) {
160
- out.push({
161
- slug: pickSlug(a.name, a.uuid, used),
162
- name: a.name,
163
- description: trimOrUndefined(a.description),
164
- uuid: a.uuid,
165
- updatedAt: dateToIso(a.updatedAt),
166
- });
167
- }
168
- out.sort((a, b) => a.slug.localeCompare(b.slug));
169
- return out;
170
- }
171
- function isAgentsResult(value) {
172
- if (value === null || typeof value !== "object")
173
- return false;
174
- const v = value;
175
- return Array.isArray(v.agents);
176
- }
177
153
  function collectNative(actions) {
178
154
  const out = [];
179
155
  for (const [slug, meta] of Object.entries(actions)) {
@@ -197,54 +173,45 @@ function trimOrUndefined(value) {
197
173
  const trimmed = value.trim();
198
174
  return trimmed.length > 0 ? trimmed : undefined;
199
175
  }
200
- function dateToIso(value) {
201
- if (value === null || value === undefined)
202
- return undefined;
203
- if (value instanceof Date) {
204
- return Number.isNaN(value.getTime()) ? undefined : value.toISOString();
205
- }
206
- if (typeof value === "string") {
207
- const date = new Date(value);
208
- return Number.isNaN(date.getTime()) ? undefined : date.toISOString();
209
- }
210
- return undefined;
211
- }
212
- // Slugify `name` to a JS identifier; append a UUID-based suffix on collision
213
- // (or when the name slugifies to nothing). `used` is mutated.
214
- function pickSlug(name, uuid, used) {
215
- const base = slugify(name);
216
- if (base.length > 0 && !used.has(base)) {
217
- used.add(base);
218
- return base;
219
- }
220
- const suffix = uuid.replace(/-/g, "_");
221
- const fallback = base.length > 0 ? `${base}_${suffix}` : `_${suffix}`;
222
- used.add(fallback);
223
- return fallback;
224
- }
225
- function slugify(name) {
226
- const normalized = name
227
- .normalize("NFKD")
228
- .replace(/[^\w]+/g, "_")
229
- .replace(/^_+|_+$/g, "")
230
- .toLowerCase();
231
- if (normalized.length === 0)
232
- return "";
233
- // JS identifiers can't start with a digit.
234
- return /^\d/.test(normalized) ? `_${normalized}` : normalized;
235
- }
236
176
  const GENERATED_AT = new Date().toISOString();
237
- const HEADER = `// THIS FILE IS GENERATED by \`cargo-ai workflow sync\`. Do not edit by hand.
238
- // Re-run the command to refresh after adding/removing workspace integrations,
239
- // tools, or agents.
177
+ const HEADER = `// THIS FILE IS GENERATED by \`cargo-ai cdk types\`. Do not edit by hand.
178
+ // Re-run the command to refresh after adding/removing workspace integrations
179
+ // or connectors.
240
180
  // Last regenerated: ${GENERATED_AT}
241
181
 
242
182
  `;
243
183
  function renderTypes(payload) {
244
- const lines = [];
245
- lines.push(`declare module "@cargo-ai/workflow-sdk" {`);
184
+ const blocks = [];
185
+ // ── @cargo-ai/cdk — typed define* config (connector + extractor schemas) ──
186
+ const cdkLines = [];
187
+ if (payload.connectorConfigs.length > 0) {
188
+ cdkLines.push(` interface ConnectorConfigs {`);
189
+ for (const c of payload.connectorConfigs) {
190
+ const doc = formatJsDoc({ name: c.name ?? c.slug, updatedAt: GENERATED_AT }, " ");
191
+ if (doc !== "")
192
+ cdkLines.push(doc.trimEnd());
193
+ cdkLines.push(` ${jsonKey(c.slug)}: ${c.typeSrc};`);
194
+ }
195
+ cdkLines.push(` }`);
196
+ }
197
+ if (payload.extractorConfigs.length > 0) {
198
+ cdkLines.push(` interface ExtractorConfigs {`);
199
+ for (const e of payload.extractorConfigs) {
200
+ cdkLines.push(` ${jsonKey(e.integrationSlug)}: {`);
201
+ for (const x of e.extractors) {
202
+ cdkLines.push(` ${jsonKey(x.slug)}: ${x.typeSrc};`);
203
+ }
204
+ cdkLines.push(` };`);
205
+ }
206
+ cdkLines.push(` }`);
207
+ }
208
+ if (cdkLines.length > 0) {
209
+ blocks.push([`declare module "@cargo-ai/cdk" {`, ...cdkLines, `}`].join("\n"));
210
+ }
211
+ // ── @cargo-ai/workflow-sdk — integration actions + natives (workflow bodies) ──
212
+ const wfLines = [];
246
213
  if (payload.integrations.length > 0) {
247
- lines.push(` interface Integrations {`);
214
+ wfLines.push(` interface Integrations {`);
248
215
  for (const c of payload.integrations) {
249
216
  const intDoc = formatJsDoc({
250
217
  name: c.name ?? c.slug,
@@ -252,8 +219,8 @@ function renderTypes(payload) {
252
219
  updatedAt: GENERATED_AT,
253
220
  }, " ");
254
221
  if (intDoc !== "")
255
- lines.push(intDoc.trimEnd());
256
- lines.push(` ${jsonKey(c.slug)}: {`);
222
+ wfLines.push(intDoc.trimEnd());
223
+ wfLines.push(` ${jsonKey(c.slug)}: {`);
257
224
  for (const action of c.actions) {
258
225
  const actionDoc = formatJsDoc({
259
226
  name: action.name,
@@ -262,76 +229,50 @@ function renderTypes(payload) {
262
229
  updatedAt: GENERATED_AT,
263
230
  }, " ");
264
231
  if (actionDoc !== "")
265
- lines.push(actionDoc.trimEnd());
266
- lines.push(` ${jsonKey(action.slug)}: IntegrationAction<${action.inputTypeSrc}, Record<string, unknown>>;`);
232
+ wfLines.push(actionDoc.trimEnd());
233
+ wfLines.push(` ${jsonKey(action.slug)}: IntegrationAction<${action.inputTypeSrc}, Record<string, unknown>>;`);
267
234
  }
268
- lines.push(` };`);
269
- }
270
- lines.push(` }`);
271
- }
272
- if (payload.tools.length > 0) {
273
- lines.push(` interface Tools {`);
274
- for (const t of payload.tools) {
275
- const doc = formatJsDoc({
276
- name: t.name,
277
- description: t.description,
278
- updatedAt: t.updatedAt ?? GENERATED_AT,
279
- }, " ");
280
- if (doc !== "")
281
- lines.push(doc.trimEnd());
282
- lines.push(` ${jsonKey(t.slug)}: ToolFn<${t.inputTypeSrc}, Record<string, unknown>>;`);
283
- }
284
- lines.push(` }`);
285
- }
286
- if (payload.agents.length > 0) {
287
- lines.push(` interface Agents {`);
288
- for (const a of payload.agents) {
289
- const doc = formatJsDoc({
290
- name: a.name,
291
- description: a.description,
292
- updatedAt: a.updatedAt ?? GENERATED_AT,
293
- }, " ");
294
- if (doc !== "")
295
- lines.push(doc.trimEnd());
296
- lines.push(` ${jsonKey(a.slug)}: AgentFn<${AGENT_INPUT_TYPE_SRC}, AgentDefaultOutput>;`);
235
+ wfLines.push(` };`);
297
236
  }
298
- lines.push(` }`);
237
+ wfLines.push(` }`);
299
238
  }
300
239
  if (payload.native.length > 0) {
301
- lines.push(` interface Native {`);
240
+ wfLines.push(` interface Native {`);
302
241
  for (const n of payload.native) {
303
- const doc = formatJsDoc({
304
- name: n.name,
305
- description: n.description,
306
- updatedAt: GENERATED_AT,
307
- }, " ");
242
+ const doc = formatJsDoc({ name: n.name, description: n.description, updatedAt: GENERATED_AT }, " ");
308
243
  if (doc !== "")
309
- lines.push(doc.trimEnd());
310
- lines.push(` ${jsonKey(n.slug)}: NativeAction<Record<string, unknown>, Record<string, unknown>>;`);
244
+ wfLines.push(doc.trimEnd());
245
+ wfLines.push(` ${jsonKey(n.slug)}: NativeAction<Record<string, unknown>, Record<string, unknown>>;`);
311
246
  }
312
- lines.push(` }`);
247
+ wfLines.push(` }`);
313
248
  }
314
- lines.push(`}`);
315
- lines.push(``);
316
- const body = lines.join("\n");
317
- // `Ref` only appears when at least one entry has a typed input, so import
318
- // it conditionally to keep the generated .d.ts free of unused imports.
319
- const imports = [
320
- "AgentDefaultOutput",
321
- "AgentFn",
322
- "IntegrationAction",
323
- "NativeAction",
324
- ...(body.includes("Ref<") ? ["Ref"] : []),
325
- "ToolFn",
326
- ];
327
- const header = [
328
- HEADER.trim(),
329
- `import type {`,
330
- ...imports.map((name) => ` ${name},`),
331
- `} from "@cargo-ai/workflow-sdk";`,
332
- ``,
333
- ].join("\n");
334
- return `${header}\n${body}`;
249
+ // The workflow-sdk augmentation needs its builder types imported; `Ref` only
250
+ // when a typed action input references it.
251
+ const preamble = [];
252
+ // The cdk augmentation references `EncryptionRef` at encryption-typed fields.
253
+ if (cdkLines.some((l) => l.includes("EncryptionRef"))) {
254
+ preamble.push(`import type { EncryptionRef } from "@cargo-ai/cdk";`);
255
+ }
256
+ if (wfLines.length > 0) {
257
+ const wfBody = wfLines.join("\n");
258
+ const imports = [
259
+ "IntegrationAction",
260
+ "NativeAction",
261
+ ...(wfBody.includes("Ref<") ? ["Ref"] : []),
262
+ ];
263
+ preamble.push([
264
+ `import type {`,
265
+ ...imports.map((name) => ` ${name},`),
266
+ `} from "@cargo-ai/workflow-sdk";`,
267
+ ].join("\n"));
268
+ blocks.push([`declare module "@cargo-ai/workflow-sdk" {`, wfBody, `}`].join("\n"));
269
+ }
270
+ // `declare module` only *augments* an existing module when this file is itself
271
+ // a module. The workflow-sdk import makes it one; when only the cdk block is
272
+ // emitted there's no import, so force module mode with an empty export.
273
+ if (preamble.length === 0)
274
+ preamble.push(`export {};`);
275
+ return `${HEADER.trim()}\n\n${[...preamble, ...blocks].join("\n\n")}\n`;
335
276
  }
336
277
  function renderEagerRegistration(payload) {
337
278
  const lines = [];
@@ -339,15 +280,11 @@ function renderEagerRegistration(payload) {
339
280
  const imports = [];
340
281
  if (payload.integrations.length > 0)
341
282
  imports.push("registerIntegration");
342
- if (payload.tools.length > 0)
343
- imports.push("registerTool");
344
- if (payload.agents.length > 0)
345
- imports.push("registerAgent");
346
283
  if (payload.native.length > 0)
347
284
  imports.push("registerNative");
348
285
  if (imports.length === 0) {
349
286
  lines.push(``);
350
- lines.push(`// Workspace surface is empty (no custom integrations / tools / agents / natives).`);
287
+ lines.push(`// Workspace surface is empty (no custom integrations / natives).`);
351
288
  lines.push(``);
352
289
  return lines.join("\n");
353
290
  }
@@ -363,12 +300,6 @@ function renderEagerRegistration(payload) {
363
300
  }
364
301
  lines.push(`});`);
365
302
  }
366
- for (const t of payload.tools) {
367
- lines.push(`registerTool(${JSON.stringify(t.slug)}, { toolUuid: ${JSON.stringify(t.uuid)} }, ${JSON.stringify(t.name)});`);
368
- }
369
- for (const a of payload.agents) {
370
- lines.push(`registerAgent(${JSON.stringify(a.slug)}, { agentUuid: ${JSON.stringify(a.uuid)} }, ${JSON.stringify(a.name)});`);
371
- }
372
303
  for (const n of payload.native) {
373
304
  lines.push(`registerNative(${JSON.stringify(n.slug)}, ${JSON.stringify(n.name)});`);
374
305
  }
@@ -3,7 +3,7 @@ import { createRequire } from "node:module";
3
3
  import path from "node:path";
4
4
  import { fileURLToPath } from "node:url";
5
5
  import { handleApiCall, outputJson } from "../runHandler.js";
6
- import { copyDirectory, listTemplates } from "./templateUtils.js";
6
+ import { copyDirectory, listTemplates } from "../templateUtils.js";
7
7
  const require = createRequire(import.meta.url);
8
8
  export function registerAppCommands(parent, getApi) {
9
9
  const app = parent
@@ -3,7 +3,7 @@ import { createRequire } from "node:module";
3
3
  import path from "node:path";
4
4
  import { fileURLToPath } from "node:url";
5
5
  import { handleApiCall, outputJson } from "../runHandler.js";
6
- import { copyDirectory, listTemplates } from "./templateUtils.js";
6
+ import { copyDirectory, listTemplates } from "../templateUtils.js";
7
7
  const require = createRequire(import.meta.url);
8
8
  export function registerWorkerCommands(parent, getApi) {
9
9
  const worker = parent
@@ -18,14 +18,18 @@ export declare const colors: {
18
18
  export declare function outputJson(value: unknown): void;
19
19
  export declare function info(message: string): void;
20
20
  export declare function success(message: string): void;
21
+ export declare function confirm(question: string): Promise<boolean>;
21
22
  type FailWithOpts = {
22
23
  code?: ExitCode;
23
24
  extra?: Record<string, unknown>;
24
25
  };
25
26
  export declare function failWith(message: string, opts?: FailWithOpts): never;
26
- export declare function startSpinner(message: string): {
27
+ export type Spinner = {
28
+ update: (message: string) => void;
29
+ log: (line: string) => void;
27
30
  stop: () => void;
28
31
  };
32
+ export declare function startSpinner(message: string): Spinner;
29
33
  export declare function parseJson(value: string, optionName: string): any;
30
34
  type HandleApiCallOpts = {
31
35
  spinner?: string | false;
@@ -1 +1 @@
1
- {"version":3,"file":"runHandler.d.ts","sourceRoot":"","sources":["../../src/commands/runHandler.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,SAAS;;;;;;;CAOZ,CAAC;AAEX,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,SAAS,CAAC,CAAC,MAAM,OAAO,SAAS,CAAC,CAAC;AAclE,eAAO,MAAM,MAAM;aACR,MAAM,KAAG,MAAM;eACb,MAAM,KAAG,MAAM;gBACd,MAAM,KAAG,MAAM;cACjB,MAAM,KAAG,MAAM;aAChB,MAAM,KAAG,MAAM;cACd,MAAM,KAAG,MAAM;CAC1B,CAAC;AAEF,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAM/C;AAED,wBAAgB,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE1C;AAED,wBAAgB,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE7C;AAED,KAAK,YAAY,GAAG;IAClB,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC,CAAC;AAEF,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,YAAY,GAAG,KAAK,CAyBpE;AAKD,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,IAAI,CAAA;CAAE,CA4BlE;AAGD,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,GAAG,CAQhE;AAKD,KAAK,iBAAiB,GAAG;IACvB,OAAO,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;CAC1B,CAAC;AAEF,wBAAsB,aAAa,CAAC,CAAC,EACnC,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACpB,IAAI,CAAC,EAAE,iBAAiB,GACvB,OAAO,CAAC,CAAC,CAAC,CAiDZ;AAmFD,wBAAsB,oBAAoB,CAAC,CAAC,EAC1C,SAAS,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAC3B,SAAS,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,MAAM,EAChC,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,CAAC,CAAC,CASZ;AAED,wBAAsB,sBAAsB,CAAC,CAAC,EAC5C,SAAS,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAC3B,SAAS,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,MAAM,EAChC,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,CAAC,CAAC,CASZ;AAED,wBAAsB,wBAAwB,CAAC,CAAC,EAC9C,SAAS,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAC3B,aAAa,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,MAAM,GAAG,IAAI,GAAG,SAAS,EACvD,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,CAAC,CAAC,CAWZ"}
1
+ {"version":3,"file":"runHandler.d.ts","sourceRoot":"","sources":["../../src/commands/runHandler.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,SAAS;;;;;;;CAOZ,CAAC;AAEX,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,SAAS,CAAC,CAAC,MAAM,OAAO,SAAS,CAAC,CAAC;AAclE,eAAO,MAAM,MAAM;aACR,MAAM,KAAG,MAAM;eACb,MAAM,KAAG,MAAM;gBACd,MAAM,KAAG,MAAM;cACjB,MAAM,KAAG,MAAM;aAChB,MAAM,KAAG,MAAM;cACd,MAAM,KAAG,MAAM;CAC1B,CAAC;AAEF,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAM/C;AAED,wBAAgB,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE1C;AAED,wBAAgB,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE7C;AAID,wBAAsB,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAUhE;AAED,KAAK,YAAY,GAAG;IAClB,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC,CAAC;AAEF,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,YAAY,GAAG,KAAK,CAyBpE;AAKD,MAAM,MAAM,OAAO,GAAG;IAEpB,MAAM,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAGlC,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5B,IAAI,EAAE,MAAM,IAAI,CAAC;CAClB,CAAC;AAEF,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CA6CrD;AAGD,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,GAAG,CAQhE;AAKD,KAAK,iBAAiB,GAAG;IACvB,OAAO,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;CAC1B,CAAC;AAEF,wBAAsB,aAAa,CAAC,CAAC,EACnC,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACpB,IAAI,CAAC,EAAE,iBAAiB,GACvB,OAAO,CAAC,CAAC,CAAC,CAiDZ;AAmFD,wBAAsB,oBAAoB,CAAC,CAAC,EAC1C,SAAS,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAC3B,SAAS,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,MAAM,EAChC,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,CAAC,CAAC,CASZ;AAED,wBAAsB,sBAAsB,CAAC,CAAC,EAC5C,SAAS,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAC3B,SAAS,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,MAAM,EAChC,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,CAAC,CAAC,CASZ;AAED,wBAAsB,wBAAwB,CAAC,CAAC,EAC9C,SAAS,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAC3B,aAAa,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,MAAM,GAAG,IAAI,GAAG,SAAS,EACvD,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,CAAC,CAAC,CAWZ"}
@@ -37,6 +37,21 @@ export function info(message) {
37
37
  export function success(message) {
38
38
  console.error(`${colors.green("✓")} ${message}`);
39
39
  }
40
+ // Ask a yes/no question on stderr (stdout stays reserved for JSON). Resolves
41
+ // false on a non-TTY stdin (callers should require an explicit --yes there).
42
+ export async function confirm(question) {
43
+ if (process.stdin.isTTY !== true)
44
+ return false;
45
+ const { createInterface } = await import("node:readline/promises");
46
+ const rl = createInterface({ input: process.stdin, output: process.stderr });
47
+ try {
48
+ const answer = await rl.question(`${question} [y/N] `);
49
+ return /^y(es)?$/i.test(answer.trim());
50
+ }
51
+ finally {
52
+ rl.close();
53
+ }
54
+ }
40
55
  export function failWith(message, opts) {
41
56
  const code = opts !== undefined && opts.code !== undefined
42
57
  ? opts.code
@@ -64,20 +79,37 @@ const SPINNER_FRAMES = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧",
64
79
  const SPINNER_INTERVAL_MS = 80;
65
80
  export function startSpinner(message) {
66
81
  if (process.stderr.isTTY !== true) {
82
+ // Non-TTY (CI, piped): no animation — just emit each line so progress is
83
+ // still visible in logs.
67
84
  process.stderr.write(`${message}\n`);
68
- return { stop: () => undefined };
85
+ return {
86
+ update: (m) => process.stderr.write(`${m}\n`),
87
+ log: (line) => process.stderr.write(`${line}\n`),
88
+ stop: () => undefined,
89
+ };
69
90
  }
70
91
  process.stderr.write("\x1B[?25l");
92
+ let current = message;
71
93
  let frame = 0;
72
- const id = setInterval(() => {
94
+ const render = () => {
73
95
  const ch = SPINNER_FRAMES[frame % SPINNER_FRAMES.length];
74
96
  if (ch !== undefined) {
75
- process.stderr.write(`\r${colors.cyan(ch)} ${colors.dim(message)}`);
97
+ // \x1B[K clears any stale characters when the message shrinks.
98
+ process.stderr.write(`\r\x1B[K${colors.cyan(ch)} ${colors.dim(current)}`);
76
99
  }
77
100
  frame += 1;
78
- }, SPINNER_INTERVAL_MS);
101
+ };
102
+ const id = setInterval(render, SPINNER_INTERVAL_MS);
79
103
  let stopped = false;
80
104
  return {
105
+ update: (m) => {
106
+ current = m;
107
+ },
108
+ log: (line) => {
109
+ // Wipe the spinner line, drop a permanent line, let the next frame redraw
110
+ // the spinner beneath it.
111
+ process.stderr.write(`\r\x1B[K${line}\n`);
112
+ },
81
113
  stop: () => {
82
114
  if (stopped) {
83
115
  return;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templateUtils.d.ts","sourceRoot":"","sources":["../../src/commands/templateUtils.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,aAAa,SAAgB,MAAM,KAAG,QAAQ,MAAM,EAAE,CAUlE,CAAC;AAEF,eAAO,MAAM,aAAa,QACnB,MAAM,QACL,MAAM,UACJ;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,EAAE,KACrC,QAAQ,IAAI,CAmBd,CAAC"}
package/build/index.js CHANGED
@@ -5,6 +5,7 @@ import { createApi } from "./api.js";
5
5
  import { registerAiCommands } from "./commands/ai/index.js";
6
6
  import { registerAuthCommands } from "./commands/auth/index.js";
7
7
  import { registerBillingCommands } from "./commands/billing/index.js";
8
+ import { registerCdkCommands } from "./commands/cdk/index.js";
8
9
  import { registerConnectionCommands } from "./commands/connection/index.js";
9
10
  import { registerContentCommands } from "./commands/content/index.js";
10
11
  import { registerContextCommands } from "./commands/context/index.js";
@@ -72,6 +73,7 @@ registerSystemOfRecordIntegrationCommands(program, getApi);
72
73
  registerUserManagementCommands(program, getApi);
73
74
  registerAiCommands(program, getApi);
74
75
  registerHostingCommands(program, getApi);
76
+ registerCdkCommands(program, getApi);
75
77
  program
76
78
  .parseAsync()
77
79
  .then(() => maybeNotifyUpdate(version))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cargo-ai/cli",
3
- "version": "1.0.25",
3
+ "version": "1.0.26",
4
4
  "private": false,
5
5
  "license": "UNLICENSED",
6
6
  "description": "Command-line interface for the Cargo API",
@@ -29,9 +29,10 @@
29
29
  "format:check": "prettier --check ."
30
30
  },
31
31
  "dependencies": {
32
- "@cargo-ai/api": "^1.0.30",
32
+ "@cargo-ai/api": "^1.0.31",
33
33
  "@cargo-ai/app-sdk": "^1.0.2",
34
- "@cargo-ai/worker-sdk": "^1.0.2",
34
+ "@cargo-ai/cdk": "*",
35
+ "@cargo-ai/worker-sdk": "^1.0.3",
35
36
  "commander": "^12.1.0",
36
37
  "http-proxy-agent": "^9.1.0",
37
38
  "https-proxy-agent": "^9.1.0",
@@ -1 +0,0 @@
1
- {"version":3,"file":"templateUtils.d.ts","sourceRoot":"","sources":["../../../src/commands/hosting/templateUtils.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,aAAa,SAAgB,MAAM,KAAG,QAAQ,MAAM,EAAE,CAUlE,CAAC;AAEF,eAAO,MAAM,aAAa,QACnB,MAAM,QACL,MAAM,UACJ;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,EAAE,KACrC,QAAQ,IAAI,CAmBd,CAAC"}
@@ -1,4 +0,0 @@
1
- import type { Command } from "commander";
2
- import type { Api } from "../../api.js";
3
- export declare function registerWorkflowCommands(parent: Command, getApi: () => Api): void;
4
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/workflow/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAMxC,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,OAAO,EACf,MAAM,EAAE,MAAM,GAAG,GAChB,IAAI,CAMN"}
@@ -1,10 +0,0 @@
1
- import { registerSyncCommand } from "./sync.js";
2
- // SDK deploy lives under `cargo-ai orchestration release deploy-draft --file
3
- // <path>` (alongside the raw-JSON deploy path), so this group only ships the
4
- // `sync` developer tool today.
5
- export function registerWorkflowCommands(parent, getApi) {
6
- const workflow = parent
7
- .command("workflow")
8
- .description("Workflow SDK developer tools (type sync, codegen)");
9
- registerSyncCommand(workflow, getApi);
10
- }
@@ -1 +0,0 @@
1
- {"version":3,"file":"inputTypes.d.ts","sourceRoot":"","sources":["../../../src/commands/workflow/inputTypes.ts"],"names":[],"mappings":"AAgCA;;;GAGG;AACH,eAAO,MAAM,oBAAoB,QAE+D,CAAC;AAEjG;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,CAM5D;AAgGD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAU5E"}
@@ -1,4 +0,0 @@
1
- import type { Command } from "commander";
2
- import type { Api } from "../../api.js";
3
- export declare function registerSyncCommand(parent: Command, getApi: () => Api): void;
4
- //# sourceMappingURL=sync.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../../src/commands/workflow/sync.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAgGxC,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,GAAG,IAAI,CAsD5E"}