@cargo-ai/cli 1.0.74 → 1.0.76
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 +1 -1
- package/build/commands/connection/integration.d.ts.map +1 -1
- package/build/commands/connection/integration.js +15 -1
- package/build/commands/orchestration/node.d.ts.map +1 -1
- package/build/commands/orchestration/node.js +3 -2
- package/build/commands/orchestration/nodeDiagram.d.ts +4 -0
- package/build/commands/orchestration/nodeDiagram.d.ts.map +1 -1
- package/build/commands/orchestration/release.d.ts.map +1 -1
- package/build/commands/orchestration/release.js +22 -7
- package/build/index.js +52 -9
- package/build/paletteLayout.d.ts +16 -0
- package/build/paletteLayout.d.ts.map +1 -1
- package/build/paletteLayout.js +70 -27
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -168,7 +168,7 @@ Deploy a draft release of an **existing** workflow. Two input modes share the sa
|
|
|
168
168
|
# Compile a Workflow SDK module and deploy it
|
|
169
169
|
cargo-ai orchestration release deploy-draft --file ./my-workflow.ts
|
|
170
170
|
|
|
171
|
-
# Preview
|
|
171
|
+
# Preview nodes + form fields without deploying
|
|
172
172
|
cargo-ai orchestration release deploy-draft --file ./my-workflow.ts --dry-run
|
|
173
173
|
|
|
174
174
|
# Pin an explicit version + description
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"integration.d.ts","sourceRoot":"","sources":["../../../src/commands/connection/integration.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAGxC,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,OAAO,EACf,MAAM,EAAE,MAAM,GAAG,GAChB,IAAI,
|
|
1
|
+
{"version":3,"file":"integration.d.ts","sourceRoot":"","sources":["../../../src/commands/connection/integration.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAGxC,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,OAAO,EACf,MAAM,EAAE,MAAM,GAAG,GAChB,IAAI,CAwHN"}
|
|
@@ -6,11 +6,12 @@ export function registerIntegrationCommands(parent, getApi) {
|
|
|
6
6
|
integration
|
|
7
7
|
.command("list")
|
|
8
8
|
.description("List all integrations")
|
|
9
|
-
.option("--category <
|
|
9
|
+
.option("--category <category>", "Filter by category (string)")
|
|
10
10
|
.option("--slugs <list>", "Filter by integration slugs (comma-separated strings)")
|
|
11
11
|
.option("--search <search>", "Search by name, case-insensitive (string)")
|
|
12
12
|
.option("--has-actions <bool>", 'Filter by presence of actions (string: "true" or "false")')
|
|
13
13
|
.option("--has-extractors <bool>", 'Filter by presence of extractors (string: "true" or "false")')
|
|
14
|
+
.option("--summary", "Only slug, name, and category — drops actions/schemas so pickers stay under the palette capture limit")
|
|
14
15
|
.action(async (opts) => {
|
|
15
16
|
const api = getApi();
|
|
16
17
|
const result = await handleApiCall(() => api.connection.integration.list({
|
|
@@ -33,6 +34,19 @@ export function registerIntegrationCommands(parent, getApi) {
|
|
|
33
34
|
? false
|
|
34
35
|
: undefined,
|
|
35
36
|
}));
|
|
37
|
+
// Full `integration.list` is multi-megabyte (every action schema). The
|
|
38
|
+
// palette captures at most 2MB; without this trim, JSON truncates and
|
|
39
|
+
// the picker silently falls back to free text.
|
|
40
|
+
if (opts.summary === true) {
|
|
41
|
+
outputJson({
|
|
42
|
+
integrations: result.integrations.map((integration) => ({
|
|
43
|
+
slug: integration.slug,
|
|
44
|
+
name: integration.name,
|
|
45
|
+
category: integration.category,
|
|
46
|
+
})),
|
|
47
|
+
});
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
36
50
|
outputJson(result);
|
|
37
51
|
});
|
|
38
52
|
integration
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../../src/commands/orchestration/node.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAiBxC,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../../src/commands/orchestration/node.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAiBxC,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,GAAG,IAAI,CAqK7E"}
|
|
@@ -12,8 +12,9 @@ Use these commands to inspect or debug the node graph of a workflow. To just
|
|
|
12
12
|
run a tool or connector action, no workflow needed, use instead:
|
|
13
13
|
$ cargo-ai orchestration action execute --action '<json>' --data '<json>'
|
|
14
14
|
|
|
15
|
-
'diagram', 'compute' and 'validate' are free and run nothing.
|
|
16
|
-
a dry run: it performs the node's real action and consumes
|
|
15
|
+
'diagram', 'compute' and 'validate' are free and run nothing.
|
|
16
|
+
'execute' is not a dry run: it performs the node's real action and consumes
|
|
17
|
+
credits.
|
|
17
18
|
|
|
18
19
|
Before deploying a graph:
|
|
19
20
|
$ cargo-ai orchestration node validate --nodes '<json>'
|
|
@@ -15,6 +15,10 @@ export type DiagramNode = {
|
|
|
15
15
|
childrenUuids?: (string | null)[] | null;
|
|
16
16
|
fallbackChildUuid?: string | null;
|
|
17
17
|
config?: Record<string, unknown> | null;
|
|
18
|
+
position?: {
|
|
19
|
+
x?: number;
|
|
20
|
+
y?: number;
|
|
21
|
+
} | null;
|
|
18
22
|
};
|
|
19
23
|
export type DiagramOptions = {
|
|
20
24
|
title?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nodeDiagram.d.ts","sourceRoot":"","sources":["../../../src/commands/orchestration/nodeDiagram.ts"],"names":[],"mappings":"AAgBA;;2CAE2C;AAC3C,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,wEAAwE;IACxE,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,aAAa,CAAC,EAAE,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC;IACzC,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"nodeDiagram.d.ts","sourceRoot":"","sources":["../../../src/commands/orchestration/nodeDiagram.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"release.d.ts","sourceRoot":"","sources":["../../../src/commands/orchestration/release.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"release.d.ts","sourceRoot":"","sources":["../../../src/commands/orchestration/release.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAoCxC,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,OAAO,EACf,MAAM,EAAE,MAAM,GAAG,GAChB,IAAI,CAkLN"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { layoutWorkflowNodes, parseWorkflowLayoutNodes, } from "@cargo-ai/utils/workflow-layout";
|
|
1
2
|
import { parseBooleanOption } from "../../utils/booleanOption.js";
|
|
2
3
|
import { loadCompiledWorkflow, } from "../../utils/loadCompiledWorkflow.js";
|
|
3
4
|
import { ExitCodes, failWith, handleApiCall, info, outputJson, parseJson, success, } from "../runHandler.js";
|
|
@@ -61,12 +62,13 @@ export function registerReleaseCommands(parent, getApi) {
|
|
|
61
62
|
.option("--options <json>", "Options (JSON object)")
|
|
62
63
|
.action(async (opts) => {
|
|
63
64
|
const api = getApi();
|
|
65
|
+
const nodes = opts.nodes !== undefined
|
|
66
|
+
? await layoutOrFail(parseJson(opts.nodes, "--nodes"))
|
|
67
|
+
: undefined;
|
|
64
68
|
const result = await handleApiCall(() => api.orchestration.draftRelease.update({
|
|
65
69
|
workflowUuid: opts.workflowUuid,
|
|
66
70
|
parentUuid: opts.parentUuid,
|
|
67
|
-
nodes
|
|
68
|
-
? parseJson(opts.nodes, "--nodes")
|
|
69
|
-
: undefined,
|
|
71
|
+
nodes,
|
|
70
72
|
testRecords: opts.testRecords !== undefined
|
|
71
73
|
? parseJson(opts.testRecords, "--test-records")
|
|
72
74
|
: undefined,
|
|
@@ -122,11 +124,13 @@ async function runJsonDeploy(getApi, opts) {
|
|
|
122
124
|
const workflowUuid = opts.workflowUuid;
|
|
123
125
|
const nodesJson = opts.nodes;
|
|
124
126
|
const formFieldsJson = opts.formFields;
|
|
127
|
+
const parsedNodes = parseJson(nodesJson, "--nodes");
|
|
128
|
+
const nodes = await layoutOrFail(parsedNodes);
|
|
125
129
|
const api = getApi();
|
|
126
130
|
const result = await handleApiCall(() => api.orchestration.draftRelease.deploy({
|
|
127
131
|
workflowUuid,
|
|
128
132
|
version: opts.version,
|
|
129
|
-
nodes:
|
|
133
|
+
nodes: nodes,
|
|
130
134
|
formFields: formFieldsJson === "null"
|
|
131
135
|
? null
|
|
132
136
|
: parseJson(formFieldsJson, "--form-fields"),
|
|
@@ -153,10 +157,11 @@ async function runFileDeploy(getApi, opts) {
|
|
|
153
157
|
failWith("--form-fields is not allowed with --file (sourced from the module)", { code: ExitCodes.InvalidUsage });
|
|
154
158
|
}
|
|
155
159
|
const compiled = await loadCompiledWorkflow(opts.file);
|
|
160
|
+
const nodes = await layoutOrFail(compiled.nodes);
|
|
156
161
|
if (opts.dryRun === true) {
|
|
157
162
|
outputJson({
|
|
158
163
|
slug: compiled.slug,
|
|
159
|
-
nodes
|
|
164
|
+
nodes,
|
|
160
165
|
formFields: compiled.formFields,
|
|
161
166
|
});
|
|
162
167
|
return;
|
|
@@ -166,11 +171,11 @@ async function runFileDeploy(getApi, opts) {
|
|
|
166
171
|
const version = opts.version !== undefined
|
|
167
172
|
? opts.version
|
|
168
173
|
: await computeNextVersion(api, workflowUuid);
|
|
169
|
-
info(`Deploying "${compiled.slug}" → workflow ${workflowUuid} as v${version} (${String(
|
|
174
|
+
info(`Deploying "${compiled.slug}" → workflow ${workflowUuid} as v${version} (${String(nodes.length)} node(s))…`);
|
|
170
175
|
const payload = {
|
|
171
176
|
workflowUuid,
|
|
172
177
|
version,
|
|
173
|
-
nodes:
|
|
178
|
+
nodes: nodes,
|
|
174
179
|
formFields: compiled.formFields,
|
|
175
180
|
description: opts.description,
|
|
176
181
|
options: opts.options !== undefined
|
|
@@ -181,6 +186,16 @@ async function runFileDeploy(getApi, opts) {
|
|
|
181
186
|
success(`Deployed v${version}.`);
|
|
182
187
|
outputJson(result);
|
|
183
188
|
}
|
|
189
|
+
async function layoutOrFail(value) {
|
|
190
|
+
try {
|
|
191
|
+
return (await layoutWorkflowNodes(parseWorkflowLayoutNodes(value), {
|
|
192
|
+
nested: "recursive",
|
|
193
|
+
}));
|
|
194
|
+
}
|
|
195
|
+
catch (error) {
|
|
196
|
+
failWith(`layout failed: ${error instanceof Error ? error.message : String(error)}`, { code: ExitCodes.InvalidUsage });
|
|
197
|
+
}
|
|
198
|
+
}
|
|
184
199
|
// Resolve the target workflow UUID. The platform `Workflow` has no free-form
|
|
185
200
|
// slug field — the closest stable identifier is `template.slug` — and there
|
|
186
201
|
// is no `workflow.create` endpoint, so an explicit `--workflow-uuid` always
|
package/build/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
|
-
import { availableCodingAgents, BRAND, canRunPalette, cdkProjectRoot, declareSources, fetchCreditsLeft, fetchWorkspaceName, formatWorkspaceSuffix, isInteractive, printSetupIssues, registerCommands as registerCdkCommands, runPalette, SessionExpiredError, } from "@cargo-ai/cdk/cli";
|
|
3
|
+
import { availableCodingAgents, BRAND, canRunPalette, cdkProjectDir, cdkProjectRoot, declareSources, fetchCreditsLeft, fetchWorkspaceName, formatWorkspaceSuffix, isInteractive, printSetupIssues, registerCommands as registerCdkCommands, runPalette, SessionExpiredError, } from "@cargo-ai/cdk/cli";
|
|
4
4
|
import { Command } from "commander";
|
|
5
5
|
import { AGENT_SKILLS_HINT } from "./agentSkills.js";
|
|
6
6
|
import { createApi } from "./api.js";
|
|
@@ -125,10 +125,12 @@ const getApi = () => {
|
|
|
125
125
|
};
|
|
126
126
|
// Where the palette finds answers for an option that wants an id. Keyed by the
|
|
127
127
|
// flag, because `--model-uuid` asks the same question in all 28 places it
|
|
128
|
-
// appears;
|
|
128
|
+
// appears; the uuid entries cover the 84 uuid options this CLI declares, and
|
|
129
|
+
// the integration-slug entries cover every catalog-slug flag the same way.
|
|
129
130
|
//
|
|
130
|
-
// Nobody knows a uuid
|
|
131
|
-
// have to leave the palette
|
|
131
|
+
// Nobody knows a uuid — and few people remember every integration slug. Every
|
|
132
|
+
// one of these replaces a field you would otherwise have to leave the palette
|
|
133
|
+
// to fill.
|
|
132
134
|
declareSources({
|
|
133
135
|
// A workflow row carries a uuid, two timestamps and a toolUuid — nothing to
|
|
134
136
|
// choose between. The plays and tools that own those workflows carry a name
|
|
@@ -173,6 +175,35 @@ declareSources({
|
|
|
173
175
|
"--segment-uuid": [
|
|
174
176
|
{ argv: ["segmentation", "segment", "list"], value: "uuid", label: "name" },
|
|
175
177
|
],
|
|
178
|
+
// Integration slugs are the catalog names (`hubspot`, `linkedin`) — same
|
|
179
|
+
// question for `--integration-slug`, the shorter `--integration` filters,
|
|
180
|
+
// and span filters keyed on the node. `--summary` is required: the full
|
|
181
|
+
// list is multi-megabyte and exceeds the palette's capture limit, which
|
|
182
|
+
// truncates JSON and falls back to a free-text prompt.
|
|
183
|
+
"--integration-slug": [
|
|
184
|
+
{
|
|
185
|
+
argv: ["connection", "integration", "list", "--summary"],
|
|
186
|
+
value: "slug",
|
|
187
|
+
label: "name",
|
|
188
|
+
hint: "slug",
|
|
189
|
+
},
|
|
190
|
+
],
|
|
191
|
+
"--integration": [
|
|
192
|
+
{
|
|
193
|
+
argv: ["connection", "integration", "list", "--summary"],
|
|
194
|
+
value: "slug",
|
|
195
|
+
label: "name",
|
|
196
|
+
hint: "slug",
|
|
197
|
+
},
|
|
198
|
+
],
|
|
199
|
+
"--node-integration-slug": [
|
|
200
|
+
{
|
|
201
|
+
argv: ["connection", "integration", "list", "--summary"],
|
|
202
|
+
value: "slug",
|
|
203
|
+
label: "name",
|
|
204
|
+
hint: "slug",
|
|
205
|
+
},
|
|
206
|
+
],
|
|
176
207
|
});
|
|
177
208
|
const binPath = process.argv[1] === undefined ? "cargo-ai" : process.argv[1];
|
|
178
209
|
// First, so it is the first row of the palette: for someone signed in, this is
|
|
@@ -231,11 +262,23 @@ async function openPalette(startPath) {
|
|
|
231
262
|
// Re-read after each command: signing in or out from inside the palette
|
|
232
263
|
// changes both what the setup line says and which rows are worth pinning.
|
|
233
264
|
// The cwd is re-tested too — a command can create a project in it.
|
|
234
|
-
const rebuildLayout = () =>
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
265
|
+
const rebuildLayout = () => {
|
|
266
|
+
// Read once: a layout describing two different directories could offer to
|
|
267
|
+
// deploy one and name the other.
|
|
268
|
+
const cwd = process.cwd();
|
|
269
|
+
const root = cdkProjectRoot(cwd);
|
|
270
|
+
return buildPaletteLayout({
|
|
271
|
+
signedIn: isSignedIn(),
|
|
272
|
+
agents,
|
|
273
|
+
cdkProjectRoot: root,
|
|
274
|
+
// Resolved from the root, never the cwd. `cdkProjectDir` looks *down* for
|
|
275
|
+
// `infra/` rather than walking up, and a scaffolded `infra/` carries no
|
|
276
|
+
// package.json to be recognised by — so asked from inside one it answers
|
|
277
|
+
// undefined, and `deploy` would fall back to the root it must not use.
|
|
278
|
+
cdkProjectDir: root === undefined ? undefined : cdkProjectDir(root),
|
|
279
|
+
cwd,
|
|
280
|
+
});
|
|
281
|
+
};
|
|
239
282
|
await runPalette({
|
|
240
283
|
program,
|
|
241
284
|
binPath,
|
package/build/paletteLayout.d.ts
CHANGED
|
@@ -4,6 +4,22 @@ export type PaletteLayoutInput = {
|
|
|
4
4
|
agents: readonly CodingAgent[];
|
|
5
5
|
/** The CDK repo root the palette is standing in, or undefined when none. */
|
|
6
6
|
cdkProjectRoot: string | undefined;
|
|
7
|
+
/**
|
|
8
|
+
* The directory holding the CDK project — `infra/` for a scaffolded repo, or
|
|
9
|
+
* the same as `cdkProjectRoot` for a hand-rolled layout. Commands that load
|
|
10
|
+
* the resource tree and state (`cdk deploy`) need this, not the repo root.
|
|
11
|
+
*
|
|
12
|
+
* Resolve it from `cdkProjectRoot` rather than from `cwd`: `cdkProjectDir`
|
|
13
|
+
* looks down for `infra/` instead of walking up, so from inside one it
|
|
14
|
+
* answers undefined.
|
|
15
|
+
*/
|
|
16
|
+
cdkProjectDir: string | undefined;
|
|
17
|
+
/**
|
|
18
|
+
* Where the palette is standing. The project rows are resolved by walking
|
|
19
|
+
* *up* from here, so this is what says whether they point at the directory
|
|
20
|
+
* on screen or one somewhere above it.
|
|
21
|
+
*/
|
|
22
|
+
cwd: string;
|
|
7
23
|
};
|
|
8
24
|
export declare function buildPaletteLayout(input: PaletteLayoutInput): PaletteLayout;
|
|
9
25
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paletteLayout.d.ts","sourceRoot":"","sources":["../src/paletteLayout.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"paletteLayout.d.ts","sourceRoot":"","sources":["../src/paletteLayout.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAwE/E,MAAM,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,SAAS,WAAW,EAAE,CAAC;IAC/B,4EAA4E;IAC5E,cAAc,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC;;;;;;;;OAQG;IACH,aAAa,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC;;;;OAIG;IACH,GAAG,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,kBAAkB,GAAG,aAAa,CAM3E;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,kBAAkB,GAAG,SAAS,EAAE,CA4CjE"}
|
package/build/paletteLayout.js
CHANGED
|
@@ -7,16 +7,19 @@
|
|
|
7
7
|
// most often wants, a coding agent briefed on their workspace, two screens
|
|
8
8
|
// down behind `start`. This is the missing opinion, kept in one place and as
|
|
9
9
|
// data, so it can be read and tested rather than inferred from a menu.
|
|
10
|
+
import { basename, relative, resolve } from "node:path";
|
|
10
11
|
/** Pinned row values. The leading space keeps them out of the command namespace. */
|
|
11
12
|
const SIGN_IN = " sign-in";
|
|
12
13
|
const DEMO = " demo";
|
|
13
14
|
const CODE = " code";
|
|
14
|
-
const
|
|
15
|
+
const ADD = " add";
|
|
16
|
+
const DEPLOY = " deploy";
|
|
15
17
|
/**
|
|
16
18
|
* `start` runs most of these; the pinned row is the shortcut to one of them.
|
|
17
|
-
* The
|
|
18
|
-
* a `start` destination, because
|
|
19
|
-
* choice of where to carry on — you are already in the project.
|
|
19
|
+
* The exceptions are "Add" and "Deploy", which run `cdk add` and `cdk deploy`
|
|
20
|
+
* directly: neither is a `start` destination, because neither needs the sign-in
|
|
21
|
+
* step nor a choice of where to carry on — you are already in the project. Bare
|
|
22
|
+
* `cdk add` asks connector vs cookbook, then shows that kind's list.
|
|
20
23
|
*/
|
|
21
24
|
const ENTRANCE = "start";
|
|
22
25
|
/**
|
|
@@ -95,24 +98,27 @@ export function pinnedRows(input) {
|
|
|
95
98
|
},
|
|
96
99
|
];
|
|
97
100
|
}
|
|
98
|
-
// Inside a CDK project
|
|
99
|
-
//
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
101
|
+
// Inside a CDK project the rows are the loop somebody is actually in — add a
|
|
102
|
+
// resource, deploy it — and the guided demo is not part of it: it is the tour
|
|
103
|
+
// for a workspace you have not built yet, and this one is open on screen.
|
|
104
|
+
// Outside, there is no project to add to or deploy, so offer the tour and the
|
|
105
|
+
// scaffold instead.
|
|
106
|
+
const projectRows = input.cdkProjectRoot !== undefined
|
|
107
|
+
? cdkRows(input.cdkProjectRoot, input.cdkProjectDir, input.cwd)
|
|
108
|
+
: [
|
|
109
|
+
{
|
|
110
|
+
value: DEMO,
|
|
111
|
+
label: "Guided demo",
|
|
112
|
+
hint: "companies, then the people, for your ICP",
|
|
113
|
+
argv: [ENTRANCE, "--continue", "demo"],
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
value: CODE,
|
|
117
|
+
label: "Set up as code",
|
|
118
|
+
hint: "scaffold a CDK project",
|
|
119
|
+
argv: [ENTRANCE, "--continue", "code"],
|
|
120
|
+
},
|
|
121
|
+
];
|
|
116
122
|
return [
|
|
117
123
|
...input.agents.map((agent) => ({
|
|
118
124
|
value: ` agent:${agent.bin}`,
|
|
@@ -120,12 +126,49 @@ export function pinnedRows(input) {
|
|
|
120
126
|
hint: "briefed on this workspace",
|
|
121
127
|
argv: [ENTRANCE, "--continue", agent.bin],
|
|
122
128
|
})),
|
|
129
|
+
...projectRows,
|
|
130
|
+
];
|
|
131
|
+
}
|
|
132
|
+
/** The two rows for a palette standing in the CDK project rooted at `root`. */
|
|
133
|
+
function cdkRows(root, projectDir, cwd) {
|
|
134
|
+
// `cdk deploy` loads the resource tree and `cargo.state.json` from the
|
|
135
|
+
// directory it runs in, so it needs the CDK project — `infra/` in a
|
|
136
|
+
// scaffolded repo — where `add` takes the root and resolves that itself.
|
|
137
|
+
const target = projectDir !== undefined ? projectDir : root;
|
|
138
|
+
return [
|
|
139
|
+
{
|
|
140
|
+
value: ADD,
|
|
141
|
+
label: "Add",
|
|
142
|
+
hint: "a connector or a cookbook into this project",
|
|
143
|
+
// `--dir` because `cdk add` refuses a directory with no package.json,
|
|
144
|
+
// and the palette is as often open in `infra/` — where the scaffold's
|
|
145
|
+
// README sends people — as at the root.
|
|
146
|
+
argv: ["cdk", "add", "--dir", root],
|
|
147
|
+
},
|
|
123
148
|
{
|
|
124
|
-
value:
|
|
125
|
-
label: "
|
|
126
|
-
|
|
127
|
-
|
|
149
|
+
value: DEPLOY,
|
|
150
|
+
label: "Deploy",
|
|
151
|
+
// Name the directory whenever it is not the one on screen. The project is
|
|
152
|
+
// found by walking *up*, so this row can target a project the cwd gives no
|
|
153
|
+
// sign of — and it mutates a live workspace, which in a repo holding more
|
|
154
|
+
// than one project is worth saying out loud before it is picked.
|
|
155
|
+
hint: resolve(target) === resolve(cwd)
|
|
156
|
+
? "this project to your workspace"
|
|
157
|
+
: `${projectName(target, root)}/ to your workspace`,
|
|
158
|
+
// No `--yes`: `deploy` shows the plan and asks, which is the point of
|
|
159
|
+
// reaching it from a menu.
|
|
160
|
+
argv: ["cdk", "deploy", "--dir", target],
|
|
128
161
|
},
|
|
129
|
-
cdkRow,
|
|
130
162
|
];
|
|
131
163
|
}
|
|
164
|
+
/**
|
|
165
|
+
* A short name for the CDK project directory: where it sits inside the repo
|
|
166
|
+
* (`infra`), or the repo's own directory name when it *is* the repo root.
|
|
167
|
+
*
|
|
168
|
+
* `relative` answers "" for two equal paths — the hand-rolled layout that keeps
|
|
169
|
+
* its resources at the root — and "" is not a name anybody can read.
|
|
170
|
+
*/
|
|
171
|
+
function projectName(dir, root) {
|
|
172
|
+
const within = relative(root, dir);
|
|
173
|
+
return within === "" ? basename(root) : within;
|
|
174
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cargo-ai/cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.76",
|
|
4
4
|
"private": false,
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"homepage": "https://getcargo.ai",
|
|
@@ -66,8 +66,9 @@
|
|
|
66
66
|
"dependencies": {
|
|
67
67
|
"@cargo-ai/api": "^1.0.71",
|
|
68
68
|
"@cargo-ai/app-sdk": "^1.0.9",
|
|
69
|
-
"@cargo-ai/cdk": "^1.0.
|
|
70
|
-
"@cargo-ai/types": "^1.0.
|
|
69
|
+
"@cargo-ai/cdk": "^1.0.61",
|
|
70
|
+
"@cargo-ai/types": "^1.0.68",
|
|
71
|
+
"@cargo-ai/utils": "^1.0.28",
|
|
71
72
|
"@cargo-ai/worker-sdk": "^1.0.17",
|
|
72
73
|
"@modelcontextprotocol/sdk": "1.29.0",
|
|
73
74
|
"commander": "^12.1.0",
|