@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.
- package/README.md +17 -17
- package/build/commands/cdk/index.d.ts +4 -0
- package/build/commands/cdk/index.d.ts.map +1 -0
- package/build/commands/cdk/index.js +539 -0
- package/build/commands/cdk/init.d.ts +3 -0
- package/build/commands/cdk/init.d.ts.map +1 -0
- package/build/commands/cdk/init.js +86 -0
- package/build/commands/{workflow → cdk}/inputTypes.d.ts +6 -0
- package/build/commands/cdk/inputTypes.d.ts.map +1 -0
- package/build/commands/{workflow → cdk}/inputTypes.js +115 -17
- package/build/commands/cdk/types.d.ts +4 -0
- package/build/commands/cdk/types.d.ts.map +1 -0
- package/build/commands/{workflow/sync.js → cdk/types.js} +139 -208
- package/build/commands/hosting/app.js +1 -1
- package/build/commands/hosting/worker.js +1 -1
- package/build/commands/runHandler.d.ts +5 -1
- package/build/commands/runHandler.d.ts.map +1 -1
- package/build/commands/runHandler.js +36 -4
- package/build/commands/templateUtils.d.ts.map +1 -0
- package/build/index.js +2 -0
- package/package.json +4 -3
- package/build/commands/hosting/templateUtils.d.ts.map +0 -1
- package/build/commands/workflow/index.d.ts +0 -4
- package/build/commands/workflow/index.d.ts.map +0 -1
- package/build/commands/workflow/index.js +0 -10
- package/build/commands/workflow/inputTypes.d.ts.map +0 -1
- package/build/commands/workflow/sync.d.ts +0 -4
- package/build/commands/workflow/sync.d.ts.map +0 -1
- /package/build/commands/{hosting/templateUtils.d.ts → templateUtils.d.ts} +0 -0
- /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 {
|
|
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
|
|
37
|
+
export function registerTypesCommand(parent, getApi) {
|
|
38
38
|
parent
|
|
39
|
-
.command("
|
|
40
|
-
.description("Generate per-workspace TypeScript types
|
|
41
|
-
.option("--
|
|
42
|
-
.option("--
|
|
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
|
-
|
|
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
|
|
60
|
-
` so the
|
|
61
|
-
`
|
|
62
|
-
`
|
|
63
|
-
`
|
|
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
|
-
|
|
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
|
|
73
|
-
const
|
|
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
|
-
|
|
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
|
|
238
|
-
// Re-run the command to refresh after adding/removing workspace integrations
|
|
239
|
-
//
|
|
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
|
|
245
|
-
|
|
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
|
-
|
|
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
|
-
|
|
256
|
-
|
|
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
|
-
|
|
266
|
-
|
|
232
|
+
wfLines.push(actionDoc.trimEnd());
|
|
233
|
+
wfLines.push(` ${jsonKey(action.slug)}: IntegrationAction<${action.inputTypeSrc}, Record<string, unknown>>;`);
|
|
267
234
|
}
|
|
268
|
-
|
|
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
|
-
|
|
237
|
+
wfLines.push(` }`);
|
|
299
238
|
}
|
|
300
239
|
if (payload.native.length > 0) {
|
|
301
|
-
|
|
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
|
-
|
|
310
|
-
|
|
244
|
+
wfLines.push(doc.trimEnd());
|
|
245
|
+
wfLines.push(` ${jsonKey(n.slug)}: NativeAction<Record<string, unknown>, Record<string, unknown>>;`);
|
|
311
246
|
}
|
|
312
|
-
|
|
247
|
+
wfLines.push(` }`);
|
|
313
248
|
}
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
const
|
|
317
|
-
//
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
"
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
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 /
|
|
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 "
|
|
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 "
|
|
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
|
|
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,
|
|
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 {
|
|
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
|
|
94
|
+
const render = () => {
|
|
73
95
|
const ch = SPINNER_FRAMES[frame % SPINNER_FRAMES.length];
|
|
74
96
|
if (ch !== undefined) {
|
|
75
|
-
|
|
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
|
-
}
|
|
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.
|
|
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.
|
|
32
|
+
"@cargo-ai/api": "^1.0.31",
|
|
33
33
|
"@cargo-ai/app-sdk": "^1.0.2",
|
|
34
|
-
"@cargo-ai/
|
|
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 +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 +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"}
|
|
File without changes
|
|
File without changes
|