@cargo-ai/cli 1.0.120 → 1.0.122
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 +2 -1
- package/build/api.d.ts +6 -1
- package/build/api.d.ts.map +1 -1
- package/build/commands/connection/action.d.ts +1 -1
- package/build/commands/connection/action.d.ts.map +1 -1
- package/build/commands/connection/action.js +4 -2
- package/build/commands/connection/index.d.ts +1 -1
- package/build/commands/connection/index.d.ts.map +1 -1
- package/build/commands/connection/index.js +4 -4
- package/build/commands/connection/integration.d.ts +1 -1
- package/build/commands/connection/integration.d.ts.map +1 -1
- package/build/commands/connection/integration.js +11 -5
- package/build/commands/connection/nativeIntegration.d.ts +1 -1
- package/build/commands/connection/nativeIntegration.d.ts.map +1 -1
- package/build/commands/connection/nativeIntegration.js +4 -2
- package/build/commands/content/file.d.ts.map +1 -1
- package/build/commands/content/file.js +163 -2
- package/build/commands/orchestration/action.d.ts +1 -1
- package/build/commands/orchestration/action.d.ts.map +1 -1
- package/build/commands/orchestration/action.js +100 -4
- package/build/commands/orchestration/index.d.ts +1 -1
- package/build/commands/orchestration/index.d.ts.map +1 -1
- package/build/commands/orchestration/index.js +2 -2
- package/build/commands/signedOutNotice.d.ts +4 -0
- package/build/commands/signedOutNotice.d.ts.map +1 -0
- package/build/commands/signedOutNotice.js +11 -0
- package/build/index.js +18 -3
- package/build/utils/actionDryRun.d.ts +90 -0
- package/build/utils/actionDryRun.d.ts.map +1 -0
- package/build/utils/actionDryRun.js +145 -0
- package/build/utils/sampleFromSchema.d.ts +15 -0
- package/build/utils/sampleFromSchema.d.ts.map +1 -0
- package/build/utils/sampleFromSchema.js +474 -0
- package/package.json +6 -5
package/README.md
CHANGED
|
@@ -31,7 +31,8 @@ Driving Cargo from an agent instead? `cargo-ai mcp` serves the same actions over
|
|
|
31
31
|
## Requirements
|
|
32
32
|
|
|
33
33
|
- Node.js 22.x
|
|
34
|
-
- A Cargo account. `cargo-ai login --email` creates one if needed (see [Authentication](#authentication)); an API token is only needed for CI and shared machines
|
|
34
|
+
- A Cargo account to run anything. `cargo-ai login --email` creates one if needed (see [Authentication](#authentication)); an API token is only needed for CI and shared machines
|
|
35
|
+
- Before signing up, `orchestration action list`, `connection integration list|get`, `orchestration action execute --dry-run` (a free sample result in the shape of a real run) and `project plan|types` already work
|
|
35
36
|
|
|
36
37
|
## Installation
|
|
37
38
|
|
package/build/api.d.ts
CHANGED
|
@@ -3,7 +3,12 @@ import { type AccessTokenProvider } from "@cargo-ai/cdk/cli";
|
|
|
3
3
|
export type { Api };
|
|
4
4
|
export declare function createApi(opts: {
|
|
5
5
|
baseUrl: string;
|
|
6
|
-
|
|
6
|
+
/**
|
|
7
|
+
* `undefined` sends no Authorization header at all, which only the routes
|
|
8
|
+
* that answer without a workspace accept. `getPublicApi` is the one caller
|
|
9
|
+
* that passes it.
|
|
10
|
+
*/
|
|
11
|
+
getAccessToken: AccessTokenProvider | undefined;
|
|
7
12
|
workspaceUuid: string | undefined;
|
|
8
13
|
}): Api;
|
|
9
14
|
//# sourceMappingURL=api.d.ts.map
|
package/build/api.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,GAAG,EAAY,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,KAAK,mBAAmB,EAAqB,MAAM,mBAAmB,CAAC;AAIhF,YAAY,EAAE,GAAG,EAAE,CAAC;AAQpB,wBAAgB,SAAS,CAAC,IAAI,EAAE;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,GAAG,EAAY,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,KAAK,mBAAmB,EAAqB,MAAM,mBAAmB,CAAC;AAIhF,YAAY,EAAE,GAAG,EAAE,CAAC;AAQpB,wBAAgB,SAAS,CAAC,IAAI,EAAE;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,cAAc,EAAE,mBAAmB,GAAG,SAAS,CAAC;IAChD,aAAa,EAAE,MAAM,GAAG,SAAS,CAAC;CACnC,GAAG,GAAG,CAeN"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { Command } from "commander";
|
|
2
2
|
import type { Api } from "../../api.js";
|
|
3
|
-
export declare function registerActionSearchCommands(parent: Command,
|
|
3
|
+
export declare function registerActionSearchCommands(parent: Command, getPublicApi: () => Api): void;
|
|
4
4
|
//# sourceMappingURL=action.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"action.d.ts","sourceRoot":"","sources":["../../../src/commands/connection/action.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"action.d.ts","sourceRoot":"","sources":["../../../src/commands/connection/action.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAmDxC,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,OAAO,EACf,YAAY,EAAE,MAAM,GAAG,GACtB,IAAI,CAqIN"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { ExitCodes, failWith, handleApiCall, outputJson, } from "../runHandler.js";
|
|
2
|
+
import { noteSignedOut } from "../signedOutNotice.js";
|
|
2
3
|
const DEFAULT_LIMIT = 20;
|
|
3
4
|
const DESCRIPTION_MAX_LENGTH = 300;
|
|
4
|
-
export function registerActionSearchCommands(parent,
|
|
5
|
+
export function registerActionSearchCommands(parent, getPublicApi) {
|
|
5
6
|
const action = parent
|
|
6
7
|
.command("action")
|
|
7
8
|
.description("Discover integration actions");
|
|
@@ -31,7 +32,8 @@ Examples:
|
|
|
31
32
|
code: ExitCodes.InvalidUsage,
|
|
32
33
|
});
|
|
33
34
|
}
|
|
34
|
-
|
|
35
|
+
noteSignedOut();
|
|
36
|
+
const api = getPublicApi();
|
|
35
37
|
const { integrations } = await handleApiCall(() => api.connection.integration.list({
|
|
36
38
|
hasActions: true,
|
|
37
39
|
category: opts.category,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { Command } from "commander";
|
|
2
2
|
import type { Api } from "../../api.js";
|
|
3
|
-
export declare function registerConnectionCommands(parent: Command, getApi: () => Api): void;
|
|
3
|
+
export declare function registerConnectionCommands(parent: Command, getApi: () => Api, getPublicApi: () => Api): void;
|
|
4
4
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/connection/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAOxC,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,OAAO,EACf,MAAM,EAAE,MAAM,GAAG,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/connection/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAOxC,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,OAAO,EACf,MAAM,EAAE,MAAM,GAAG,EACjB,YAAY,EAAE,MAAM,GAAG,GACtB,IAAI,CAUN"}
|
|
@@ -3,13 +3,13 @@ import { registerConnectorCommands } from "./connector.js";
|
|
|
3
3
|
import { registerCustomIntegrationCommands } from "./customIntegration.js";
|
|
4
4
|
import { registerIntegrationCommands } from "./integration.js";
|
|
5
5
|
import { registerNativeIntegrationCommands } from "./nativeIntegration.js";
|
|
6
|
-
export function registerConnectionCommands(parent, getApi) {
|
|
6
|
+
export function registerConnectionCommands(parent, getApi, getPublicApi) {
|
|
7
7
|
const connection = parent
|
|
8
8
|
.command("connection")
|
|
9
9
|
.description("Connectors and integrations");
|
|
10
10
|
registerConnectorCommands(connection, getApi);
|
|
11
|
-
registerIntegrationCommands(connection, getApi);
|
|
12
|
-
registerActionSearchCommands(connection,
|
|
13
|
-
registerNativeIntegrationCommands(connection,
|
|
11
|
+
registerIntegrationCommands(connection, getApi, getPublicApi);
|
|
12
|
+
registerActionSearchCommands(connection, getPublicApi);
|
|
13
|
+
registerNativeIntegrationCommands(connection, getPublicApi);
|
|
14
14
|
registerCustomIntegrationCommands(connection, getApi);
|
|
15
15
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { Command } from "commander";
|
|
2
2
|
import type { Api } from "../../api.js";
|
|
3
|
-
export declare function registerIntegrationCommands(parent: Command, getApi: () => Api): void;
|
|
3
|
+
export declare function registerIntegrationCommands(parent: Command, getApi: () => Api, getPublicApi: () => Api): void;
|
|
4
4
|
//# sourceMappingURL=integration.d.ts.map
|
|
@@ -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;
|
|
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;AAIxC,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,OAAO,EACf,MAAM,EAAE,MAAM,GAAG,EACjB,YAAY,EAAE,MAAM,GAAG,GACtB,IAAI,CA4JN"}
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { handleApiCall, outputJson, parseJson } from "../runHandler.js";
|
|
2
|
-
|
|
2
|
+
import { noteSignedOut } from "../signedOutNotice.js";
|
|
3
|
+
export function registerIntegrationCommands(parent, getApi, getPublicApi) {
|
|
3
4
|
const integration = parent
|
|
4
5
|
.command("integration")
|
|
5
|
-
.description("Browse and manage integrations")
|
|
6
|
+
.description("Browse and manage integrations")
|
|
7
|
+
.addHelpText("after", `
|
|
8
|
+
list, get and get-documentation work before you sign up.`);
|
|
6
9
|
integration
|
|
7
10
|
.command("list")
|
|
8
11
|
.description("List all integrations")
|
|
@@ -19,7 +22,8 @@ when they are named through --slugs. They cannot be connected any more, but they
|
|
|
19
22
|
keep running for the workspaces already on them, and \`integration get <slug>\`
|
|
20
23
|
always returns one.`)
|
|
21
24
|
.action(async (opts) => {
|
|
22
|
-
|
|
25
|
+
noteSignedOut();
|
|
26
|
+
const api = getPublicApi();
|
|
23
27
|
const slugs = opts.slugs !== undefined
|
|
24
28
|
? opts.slugs
|
|
25
29
|
.split(",")
|
|
@@ -65,7 +69,8 @@ always returns one.`)
|
|
|
65
69
|
.command("get <slug>")
|
|
66
70
|
.description("Get an integration by slug")
|
|
67
71
|
.action(async (slug) => {
|
|
68
|
-
|
|
72
|
+
noteSignedOut();
|
|
73
|
+
const api = getPublicApi();
|
|
69
74
|
const result = await handleApiCall(() => api.connection.integration.get({ slug }));
|
|
70
75
|
outputJson(result);
|
|
71
76
|
});
|
|
@@ -73,7 +78,8 @@ always returns one.`)
|
|
|
73
78
|
.command("get-documentation <slug>")
|
|
74
79
|
.description("Get integration documentation by slug")
|
|
75
80
|
.action(async (slug) => {
|
|
76
|
-
|
|
81
|
+
noteSignedOut();
|
|
82
|
+
const api = getPublicApi();
|
|
77
83
|
const result = await handleApiCall(() => api.connection.integration.getDocumentation(slug));
|
|
78
84
|
outputJson(result);
|
|
79
85
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { Command } from "commander";
|
|
2
2
|
import type { Api } from "../../api.js";
|
|
3
|
-
export declare function registerNativeIntegrationCommands(parent: Command,
|
|
3
|
+
export declare function registerNativeIntegrationCommands(parent: Command, getPublicApi: () => Api): void;
|
|
4
4
|
//# sourceMappingURL=nativeIntegration.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nativeIntegration.d.ts","sourceRoot":"","sources":["../../../src/commands/connection/nativeIntegration.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"nativeIntegration.d.ts","sourceRoot":"","sources":["../../../src/commands/connection/nativeIntegration.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAIxC,wBAAgB,iCAAiC,CAC/C,MAAM,EAAE,OAAO,EACf,YAAY,EAAE,MAAM,GAAG,GACtB,IAAI,CAgBN"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { handleApiCall, outputJson } from "../runHandler.js";
|
|
2
|
-
|
|
2
|
+
import { noteSignedOut } from "../signedOutNotice.js";
|
|
3
|
+
export function registerNativeIntegrationCommands(parent, getPublicApi) {
|
|
3
4
|
const nativeIntegration = parent
|
|
4
5
|
.command("native-integration")
|
|
5
6
|
.description("Native integration");
|
|
@@ -7,7 +8,8 @@ export function registerNativeIntegrationCommands(parent, getApi) {
|
|
|
7
8
|
.command("get")
|
|
8
9
|
.description("Get native integration")
|
|
9
10
|
.action(async () => {
|
|
10
|
-
|
|
11
|
+
noteSignedOut();
|
|
12
|
+
const api = getPublicApi();
|
|
11
13
|
const result = await handleApiCall(() => api.connection.nativeIntegration.get());
|
|
12
14
|
outputJson(result);
|
|
13
15
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file.d.ts","sourceRoot":"","sources":["../../../src/commands/content/file.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"file.d.ts","sourceRoot":"","sources":["../../../src/commands/content/file.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAGxC,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,GAAG,IAAI,CAwQ7E"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { readFile } from "node:fs/promises";
|
|
2
|
-
import { basename } from "node:path";
|
|
1
|
+
import { readFile, writeFile } from "node:fs/promises";
|
|
2
|
+
import { basename, extname } from "node:path";
|
|
3
3
|
import { handleApiCall, outputJson } from "../runHandler.js";
|
|
4
4
|
export function registerFileCommands(parent, getApi) {
|
|
5
5
|
const file = parent.command("file").description("Storage file operations");
|
|
@@ -47,6 +47,8 @@ export function registerFileCommands(parent, getApi) {
|
|
|
47
47
|
.description("Upload a file")
|
|
48
48
|
.requiredOption("--file <path>", "Path to the file to upload")
|
|
49
49
|
.option("--folder-uuid <uuid>", "Folder UUID")
|
|
50
|
+
.option("--index <none|vectorStore>", "vectorStore (default) makes the file searchable by agents; none only stores it")
|
|
51
|
+
.option("--visibility <private|public>", "Defaults to private")
|
|
50
52
|
.action(async (opts) => {
|
|
51
53
|
const buffer = await readFile(opts.file);
|
|
52
54
|
const name = basename(opts.file);
|
|
@@ -56,6 +58,8 @@ export function registerFileCommands(parent, getApi) {
|
|
|
56
58
|
api.content.file.upload({
|
|
57
59
|
file: fileObj,
|
|
58
60
|
folderUuid: opts.folderUuid,
|
|
61
|
+
indexMode: parseIndexMode(opts.index),
|
|
62
|
+
visibility: parseVisibility(opts.visibility),
|
|
59
63
|
onProgress: (pct) => {
|
|
60
64
|
process.stderr.write(`\rUpload progress: ${pct}%`);
|
|
61
65
|
},
|
|
@@ -71,4 +75,161 @@ export function registerFileCommands(parent, getApi) {
|
|
|
71
75
|
});
|
|
72
76
|
}));
|
|
73
77
|
});
|
|
78
|
+
file
|
|
79
|
+
.command("put <path>")
|
|
80
|
+
.description("Store a file at a path (e.g. reports/2026-q3/summary.pdf), creating folders and overwriting what is there. Any size: large files go straight to storage in parts.")
|
|
81
|
+
.requiredOption("--file <path>", "Path to the local file")
|
|
82
|
+
.option("--content-type <type>", "MIME type (guessed from the extension)")
|
|
83
|
+
.option("--index <none|vectorStore>", "none (default for a new file) only stores it; vectorStore makes it searchable by agents")
|
|
84
|
+
.option("--visibility <private|public>", "Defaults to private")
|
|
85
|
+
.option("--mirror-to-context", "Also write it under .files/ in the context")
|
|
86
|
+
.action(async (path, opts) => {
|
|
87
|
+
const contentType = opts.contentType !== undefined
|
|
88
|
+
? opts.contentType
|
|
89
|
+
: guessContentType(opts.file);
|
|
90
|
+
const buffer = await readFile(opts.file);
|
|
91
|
+
const fileObj = new File([buffer], basename(opts.file), { type: contentType });
|
|
92
|
+
const api = getApi();
|
|
93
|
+
const uploaded = await handleApiCall(() => new Promise((resolve, reject) => {
|
|
94
|
+
api.workspaceManagement.file.upload({
|
|
95
|
+
file: fileObj,
|
|
96
|
+
onProgress: (pct) => {
|
|
97
|
+
process.stderr.write(`\rUpload progress: ${pct}%`);
|
|
98
|
+
},
|
|
99
|
+
onComplete: (result) => {
|
|
100
|
+
process.stderr.write("\n");
|
|
101
|
+
resolve(result);
|
|
102
|
+
},
|
|
103
|
+
onError: () => {
|
|
104
|
+
process.stderr.write("\n");
|
|
105
|
+
reject(new Error("Upload failed"));
|
|
106
|
+
},
|
|
107
|
+
});
|
|
108
|
+
}));
|
|
109
|
+
const result = await handleApiCall(() => api.content.file.import({
|
|
110
|
+
s3Filename: uploaded.s3Filename,
|
|
111
|
+
path,
|
|
112
|
+
contentType,
|
|
113
|
+
indexMode: parseIndexMode(opts.index),
|
|
114
|
+
visibility: parseVisibility(opts.visibility),
|
|
115
|
+
mirrorToContext: opts.mirrorToContext,
|
|
116
|
+
}));
|
|
117
|
+
outputJson(result);
|
|
118
|
+
});
|
|
119
|
+
file
|
|
120
|
+
.command("download <path>")
|
|
121
|
+
.description("Download the file at a path, at any size")
|
|
122
|
+
.option("--out <file>", "Write to this local file instead of stdout")
|
|
123
|
+
.action(async (path, opts) => {
|
|
124
|
+
const api = getApi();
|
|
125
|
+
const blob = await handleApiCall(() => api.content.object.get(path));
|
|
126
|
+
const bytes = Buffer.from(await blob.arrayBuffer());
|
|
127
|
+
if (opts.out !== undefined) {
|
|
128
|
+
await writeFile(opts.out, bytes);
|
|
129
|
+
outputJson({ path, out: opts.out, size: bytes.length });
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
process.stdout.write(bytes);
|
|
133
|
+
});
|
|
134
|
+
file
|
|
135
|
+
.command("url <path>")
|
|
136
|
+
.description("Create a signed URL for the file at a path that anyone can open until it expires (plus its public link when the file is public)")
|
|
137
|
+
.option("--expires <seconds>", "Lifetime in seconds, up to 10800 (3h)")
|
|
138
|
+
.option("--download", "Make browsers save the file instead of showing it")
|
|
139
|
+
.action(async (path, opts) => {
|
|
140
|
+
const api = getApi();
|
|
141
|
+
const result = await handleApiCall(async () => {
|
|
142
|
+
const { file: found } = await api.content.object.stat(path);
|
|
143
|
+
return api.content.file.getUrl({
|
|
144
|
+
uuid: found.uuid,
|
|
145
|
+
expiresInSeconds: opts.expires !== undefined ? Number(opts.expires) : undefined,
|
|
146
|
+
download: opts.download,
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
outputJson(result);
|
|
150
|
+
});
|
|
151
|
+
file
|
|
152
|
+
.command("ls [prefix]")
|
|
153
|
+
.description("List files whose path starts with a prefix (e.g. reports/), ordered by path")
|
|
154
|
+
.option("--limit <n>", "Page size, up to 1000", "100")
|
|
155
|
+
.option("--cursor <cursor>", "nextCursor from the previous page")
|
|
156
|
+
.action(async (prefix, opts) => {
|
|
157
|
+
const api = getApi();
|
|
158
|
+
const result = await handleApiCall(() => api.content.object.list({
|
|
159
|
+
prefix,
|
|
160
|
+
cursor: opts.cursor,
|
|
161
|
+
limit: Number(opts.limit),
|
|
162
|
+
}));
|
|
163
|
+
outputJson(result);
|
|
164
|
+
});
|
|
165
|
+
file
|
|
166
|
+
.command("rm <path>")
|
|
167
|
+
.description("Remove the file at a path")
|
|
168
|
+
.action(async (path) => {
|
|
169
|
+
const api = getApi();
|
|
170
|
+
const result = await handleApiCall(() => api.content.object.remove(path));
|
|
171
|
+
outputJson(result);
|
|
172
|
+
});
|
|
173
|
+
file
|
|
174
|
+
.command("visibility <path> <visibility>")
|
|
175
|
+
.description("Make the file at a path public (served without auth from a stable link) or private (revokes the link at once)")
|
|
176
|
+
.action(async (path, visibility) => {
|
|
177
|
+
const parsedVisibility = parseVisibility(visibility);
|
|
178
|
+
if (parsedVisibility === undefined) {
|
|
179
|
+
throw new Error("visibility must be private or public");
|
|
180
|
+
}
|
|
181
|
+
const api = getApi();
|
|
182
|
+
const result = await handleApiCall(async () => {
|
|
183
|
+
const { file: found } = await api.content.object.stat(path);
|
|
184
|
+
return api.content.file.update({
|
|
185
|
+
uuid: found.uuid,
|
|
186
|
+
visibility: parsedVisibility,
|
|
187
|
+
});
|
|
188
|
+
});
|
|
189
|
+
outputJson(result);
|
|
190
|
+
});
|
|
74
191
|
}
|
|
192
|
+
const parseIndexMode = (value) => {
|
|
193
|
+
if (value === undefined) {
|
|
194
|
+
return undefined;
|
|
195
|
+
}
|
|
196
|
+
if (value === "none" || value === "vectorStore") {
|
|
197
|
+
return value;
|
|
198
|
+
}
|
|
199
|
+
throw new Error(`--index must be none or vectorStore, got ${value}`);
|
|
200
|
+
};
|
|
201
|
+
const parseVisibility = (value) => {
|
|
202
|
+
if (value === undefined) {
|
|
203
|
+
return undefined;
|
|
204
|
+
}
|
|
205
|
+
if (value === "private" || value === "public") {
|
|
206
|
+
return value;
|
|
207
|
+
}
|
|
208
|
+
throw new Error(`--visibility must be private or public, got ${value}`);
|
|
209
|
+
};
|
|
210
|
+
const CONTENT_TYPES_BY_EXTENSION = {
|
|
211
|
+
".csv": "text/csv",
|
|
212
|
+
".gif": "image/gif",
|
|
213
|
+
".html": "text/html",
|
|
214
|
+
".jpeg": "image/jpeg",
|
|
215
|
+
".jpg": "image/jpeg",
|
|
216
|
+
".json": "application/json",
|
|
217
|
+
".md": "text/markdown",
|
|
218
|
+
".mp3": "audio/mpeg",
|
|
219
|
+
".mp4": "video/mp4",
|
|
220
|
+
".pdf": "application/pdf",
|
|
221
|
+
".png": "image/png",
|
|
222
|
+
".pptx": "application/vnd.openxmlformats-officedocument.presentationml.presentation",
|
|
223
|
+
".svg": "image/svg+xml",
|
|
224
|
+
".txt": "text/plain",
|
|
225
|
+
".wav": "audio/wav",
|
|
226
|
+
".webm": "video/webm",
|
|
227
|
+
".webp": "image/webp",
|
|
228
|
+
".docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
229
|
+
".xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
230
|
+
".zip": "application/zip",
|
|
231
|
+
};
|
|
232
|
+
const guessContentType = (filePath) => {
|
|
233
|
+
const contentType = CONTENT_TYPES_BY_EXTENSION[extname(filePath).toLowerCase()];
|
|
234
|
+
return contentType !== undefined ? contentType : "application/octet-stream";
|
|
235
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { Command } from "commander";
|
|
2
2
|
import type { Api } from "../../api.js";
|
|
3
|
-
export declare function registerActionCommands(parent: Command, getApi: () => Api): void;
|
|
3
|
+
export declare function registerActionCommands(parent: Command, getApi: () => Api, getPublicApi: () => Api): void;
|
|
4
4
|
//# sourceMappingURL=action.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"action.d.ts","sourceRoot":"","sources":["../../../src/commands/orchestration/action.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"action.d.ts","sourceRoot":"","sources":["../../../src/commands/orchestration/action.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAuBxC,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,OAAO,EACf,MAAM,EAAE,MAAM,GAAG,EACjB,YAAY,EAAE,MAAM,GAAG,GACtB,IAAI,CA6UN"}
|
|
@@ -1,6 +1,10 @@
|
|
|
1
|
+
import { isSignedIn } from "@cargo-ai/cdk/cli";
|
|
2
|
+
import { buildDryRunResult, estimateCredits, sampleSubjectFor, validateActionData, } from "../../utils/actionDryRun.js";
|
|
1
3
|
import { parseBooleanOption } from "../../utils/booleanOption.js";
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
+
import { describesOutput } from "../../utils/sampleFromSchema.js";
|
|
5
|
+
import { applyRecordsLimit, ExitCodes, failWith, handleApiCall, info, outputJson, parseJson, parsePositiveInt, pollUntilFinished, } from "../runHandler.js";
|
|
6
|
+
import { noteSignedOut, SIGNED_OUT_NOTICE } from "../signedOutNotice.js";
|
|
7
|
+
export function registerActionCommands(parent, getApi, getPublicApi) {
|
|
4
8
|
const action = parent
|
|
5
9
|
.command("action")
|
|
6
10
|
.description("List and execute actions (single run or batch)")
|
|
@@ -14,6 +18,8 @@ graph needed. Creates a run and consumes credits.
|
|
|
14
18
|
- Inputs go in --data, not in the action. 'config' is optional; omit it.
|
|
15
19
|
- The run is asynchronous: pass --wait-until-finished, or poll it with
|
|
16
20
|
'cargo-ai orchestration run get <uuid>'.
|
|
21
|
+
- Not signed in yet? 'list' works without an account, and 'execute --dry-run'
|
|
22
|
+
shows what a connector or native action returns, for free.
|
|
17
23
|
|
|
18
24
|
To debug a node inside an existing workflow instead, use
|
|
19
25
|
'cargo-ai orchestration node'.`);
|
|
@@ -64,7 +70,8 @@ Examples:
|
|
|
64
70
|
? undefined
|
|
65
71
|
: parsePositiveInt(opts.limit, "--limit");
|
|
66
72
|
const query = queryTerms.length === 0 ? undefined : queryTerms.join(" ");
|
|
67
|
-
|
|
73
|
+
noteSignedOut();
|
|
74
|
+
const result = await handleApiCall(() => getPublicApi().orchestration.action.list({
|
|
68
75
|
query,
|
|
69
76
|
kind,
|
|
70
77
|
integrationSlug: opts.integrationSlug,
|
|
@@ -85,13 +92,25 @@ Examples:
|
|
|
85
92
|
.option("--polling-interval <ms>", "Polling interval in milliseconds, used with --wait-until-finished (integer, default: 5000)", "5000")
|
|
86
93
|
.option("--webhook-url <url>", "URL to call when the run completes")
|
|
87
94
|
.option("--webhook-secret <secret>", "Secret used to sign webhook deliveries")
|
|
95
|
+
.option("--dry-run", "Run nothing: check --data against the action's inputs and print a sample result in the shape of a finished run, with its credit price. Free, and needs no account (connector and native actions)")
|
|
88
96
|
.addHelpText("after", `
|
|
97
|
+
--dry-run reads the action's definition from the routes that answer without a
|
|
98
|
+
workspace, so it works before you sign up. The output is sample data generated
|
|
99
|
+
from the action's output schema, marked
|
|
100
|
+
"dryRun", with no provider called and no credits used. An action whose output
|
|
101
|
+
depends on its configuration has no fixed shape to show, and the dry run says so.
|
|
102
|
+
|
|
89
103
|
Examples:
|
|
90
104
|
$ cargo-ai orchestration action execute --action '{"kind":"tool","toolUuid":"550e8400-..."}' --data '{"email":"user@example.com"}'
|
|
91
|
-
$ cargo-ai orchestration action execute --action '{"kind":"connector","integrationSlug":"slack","actionSlug":"postMessage","connectorUuid":"..."}' --data '{"channelId":"C0123456789","format":"markdown","body":"hello"}' --wait-until-finished
|
|
105
|
+
$ cargo-ai orchestration action execute --action '{"kind":"connector","integrationSlug":"slack","actionSlug":"postMessage","connectorUuid":"..."}' --data '{"channelId":"C0123456789","format":"markdown","body":"hello"}' --wait-until-finished
|
|
106
|
+
$ cargo-ai orchestration action execute --action '{"kind":"connector","integrationSlug":"aiArk","actionSlug":"enrichCompany"}' --data '{"domain":"example.com"}' --dry-run`)
|
|
92
107
|
.action(async (opts) => {
|
|
93
108
|
const actionPayload = parseJson(opts.action, "--action");
|
|
94
109
|
const data = parseJson(opts.data, "--data");
|
|
110
|
+
if (opts.dryRun === true) {
|
|
111
|
+
await dryRunAction(getPublicApi, actionPayload, data);
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
95
114
|
const api = getApi();
|
|
96
115
|
const result = await handleApiCall(() => api.orchestration.action.execute({
|
|
97
116
|
action: actionPayload,
|
|
@@ -176,3 +195,80 @@ Examples:
|
|
|
176
195
|
outputJson(result);
|
|
177
196
|
});
|
|
178
197
|
}
|
|
198
|
+
/**
|
|
199
|
+
* `action execute --dry-run`. Reads the action from the routes that answer
|
|
200
|
+
* without a workspace, so it
|
|
201
|
+
* needs no token and no workspace, and calls nothing that bills: no run is
|
|
202
|
+
* created, and the backend's own dry execution is not used either, since it is
|
|
203
|
+
* neither free nor honoured by connector actions.
|
|
204
|
+
*/
|
|
205
|
+
async function dryRunAction(getPublicApi, actionPayload, data) {
|
|
206
|
+
const target = dryRunTarget(actionPayload);
|
|
207
|
+
const api = getPublicApi();
|
|
208
|
+
const label = target.kind === "connector"
|
|
209
|
+
? `${target.integrationSlug}.${target.actionSlug}`
|
|
210
|
+
: `native.${target.actionSlug}`;
|
|
211
|
+
const definition = await fetchDryRunDefinition(api, target, label);
|
|
212
|
+
const validation = validateActionData(definition.config === undefined ? undefined : definition.config.schema, data);
|
|
213
|
+
if (validation.valid === false) {
|
|
214
|
+
failWith(`--data does not match the inputs of ${label}.`, {
|
|
215
|
+
code: ExitCodes.InvalidUsage,
|
|
216
|
+
extra: { errors: validation.errors },
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
const outputSchema = definition.output === undefined ? undefined : definition.output.schema;
|
|
220
|
+
if (describesOutput(outputSchema) === false) {
|
|
221
|
+
failWith(`${label} has no fixed output schema: what it returns depends on its configuration, so a dry run cannot show it. Signed in, 'cargo-ai orchestration action get-output-schema' resolves it for your inputs.`);
|
|
222
|
+
}
|
|
223
|
+
const estimate = estimateCredits(definition.credits === undefined ? undefined : definition.credits.costs, data);
|
|
224
|
+
outputJson(buildDryRunResult({
|
|
225
|
+
title: definition.name === undefined ? target.actionSlug : definition.name,
|
|
226
|
+
data,
|
|
227
|
+
outputSchema,
|
|
228
|
+
subject: sampleSubjectFor(target.actionSlug, definition.name),
|
|
229
|
+
estimate,
|
|
230
|
+
}));
|
|
231
|
+
if (isSignedIn() === false) {
|
|
232
|
+
info(SIGNED_OUT_NOTICE);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
function dryRunTarget(actionPayload) {
|
|
236
|
+
const action = typeof actionPayload === "object" && actionPayload !== null
|
|
237
|
+
? actionPayload
|
|
238
|
+
: {};
|
|
239
|
+
const kind = action["kind"];
|
|
240
|
+
const actionSlug = action["actionSlug"];
|
|
241
|
+
if (kind === "connector") {
|
|
242
|
+
const integrationSlug = action["integrationSlug"];
|
|
243
|
+
if (typeof integrationSlug === "string" && typeof actionSlug === "string") {
|
|
244
|
+
return { kind, integrationSlug, actionSlug };
|
|
245
|
+
}
|
|
246
|
+
failWith("--dry-run needs integrationSlug and actionSlug in a connector --action.", { code: ExitCodes.InvalidUsage });
|
|
247
|
+
}
|
|
248
|
+
if (kind === "native") {
|
|
249
|
+
if (typeof actionSlug === "string") {
|
|
250
|
+
return { kind, actionSlug };
|
|
251
|
+
}
|
|
252
|
+
failWith("--dry-run needs actionSlug in a native --action.", {
|
|
253
|
+
code: ExitCodes.InvalidUsage,
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
failWith("--dry-run covers connector and native actions. A tool or agent runs your workspace's own workflow, so only a real run shows its output.", { code: ExitCodes.InvalidUsage });
|
|
257
|
+
}
|
|
258
|
+
async function fetchDryRunDefinition(api, target, label) {
|
|
259
|
+
const actions = await fetchActionsOfIntegration(api, target);
|
|
260
|
+
const definition = actions[target.actionSlug];
|
|
261
|
+
if (definition === undefined) {
|
|
262
|
+
failWith(`No action ${label}. Find one with 'cargo-ai orchestration action list'.`, { code: ExitCodes.NotFound });
|
|
263
|
+
}
|
|
264
|
+
return definition;
|
|
265
|
+
}
|
|
266
|
+
/** The action map of the one integration `target` names. */
|
|
267
|
+
async function fetchActionsOfIntegration(api, target) {
|
|
268
|
+
if (target.kind === "connector") {
|
|
269
|
+
const { integration } = await handleApiCall(() => api.connection.integration.get({ slug: target.integrationSlug }));
|
|
270
|
+
return integration.actions;
|
|
271
|
+
}
|
|
272
|
+
const { nativeIntegration } = await handleApiCall(() => api.connection.nativeIntegration.get());
|
|
273
|
+
return nativeIntegration.actions;
|
|
274
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { Command } from "commander";
|
|
2
2
|
import type { Api } from "../../api.js";
|
|
3
|
-
export declare function registerOrchestrationCommands(parent: Command, getApi: () => Api): void;
|
|
3
|
+
export declare function registerOrchestrationCommands(parent: Command, getApi: () => Api, getPublicApi: () => Api): void;
|
|
4
4
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/orchestration/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAexC,wBAAgB,6BAA6B,CAC3C,MAAM,EAAE,OAAO,EACf,MAAM,EAAE,MAAM,GAAG,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/orchestration/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAexC,wBAAgB,6BAA6B,CAC3C,MAAM,EAAE,OAAO,EACf,MAAM,EAAE,MAAM,GAAG,EACjB,YAAY,EAAE,MAAM,GAAG,GACtB,IAAI,CA0BN"}
|
|
@@ -11,7 +11,7 @@ import { registerTemplateCommands } from "./template.js";
|
|
|
11
11
|
import { registerToolCommands } from "./tool.js";
|
|
12
12
|
import { registerTraceCommands } from "./trace.js";
|
|
13
13
|
import { registerWorkflowCommands } from "./workflow.js";
|
|
14
|
-
export function registerOrchestrationCommands(parent, getApi) {
|
|
14
|
+
export function registerOrchestrationCommands(parent, getApi, getPublicApi) {
|
|
15
15
|
const orchestration = parent
|
|
16
16
|
.command("orchestration")
|
|
17
17
|
.description("Workflows, plays, runs, batches, tools, templates")
|
|
@@ -20,7 +20,7 @@ Running vs. debugging:
|
|
|
20
20
|
action Run a tool or connector action — no workflow needed. The usual choice.
|
|
21
21
|
node Debug one node of an existing workflow ('node compute' is free,
|
|
22
22
|
'node execute' really runs it and consumes credits).`);
|
|
23
|
-
registerActionCommands(orchestration, getApi);
|
|
23
|
+
registerActionCommands(orchestration, getApi, getPublicApi);
|
|
24
24
|
registerWorkflowCommands(orchestration, getApi);
|
|
25
25
|
registerPlayCommands(orchestration, getApi);
|
|
26
26
|
registerRunCommands(orchestration, getApi);
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export declare const SIGN_UP_COMMAND = "cargo-ai login --email you@company.com";
|
|
2
|
+
export declare const SIGNED_OUT_NOTICE = "Not signed in: reading the official integrations and their actions only. Sign up with `cargo-ai login --email you@company.com` (100 free credits, no card) to run one.";
|
|
3
|
+
export declare function noteSignedOut(): void;
|
|
4
|
+
//# sourceMappingURL=signedOutNotice.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signedOutNotice.d.ts","sourceRoot":"","sources":["../../src/commands/signedOutNotice.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,eAAe,2CAA2C,CAAC;AAExE,eAAO,MAAM,iBAAiB,2KAAyJ,CAAC;AAExL,wBAAgB,aAAa,IAAI,IAAI,CAIpC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// What a signed-out caller of a command that reads the public routes is told,
|
|
2
|
+
// once, on stderr: stdout stays the JSON the command was asked for.
|
|
3
|
+
import { isSignedIn } from "@cargo-ai/cdk/cli";
|
|
4
|
+
import { info } from "./runHandler.js";
|
|
5
|
+
export const SIGN_UP_COMMAND = "cargo-ai login --email you@company.com";
|
|
6
|
+
export const SIGNED_OUT_NOTICE = `Not signed in: reading the official integrations and their actions only. Sign up with \`${SIGN_UP_COMMAND}\` (100 free credits, no card) to run one.`;
|
|
7
|
+
export function noteSignedOut() {
|
|
8
|
+
if (isSignedIn() === false) {
|
|
9
|
+
info(SIGNED_OUT_NOTICE);
|
|
10
|
+
}
|
|
11
|
+
}
|
package/build/index.js
CHANGED
|
@@ -59,6 +59,11 @@ Agent skills:
|
|
|
59
59
|
Standalone one-job GTM skills (find leads, work emails, TAM, signals):
|
|
60
60
|
Any agent (skills.sh): npx skills add getcargohq/gtm-skills
|
|
61
61
|
|
|
62
|
+
Try it before signing up (no account needed):
|
|
63
|
+
cargo-ai orchestration action list find email Browse actions and their credit prices
|
|
64
|
+
cargo-ai orchestration action execute ... --dry-run Sample result of one action, free
|
|
65
|
+
cargo-ai project plan / project types Plan a workspace-as-code project offline
|
|
66
|
+
|
|
62
67
|
Authentication:
|
|
63
68
|
Emailed code: cargo-ai login --email you@company.com (no browser; signs you up on first use)
|
|
64
69
|
Browser sign-in: cargo-ai login --oauth
|
|
@@ -139,6 +144,16 @@ const getApi = () => {
|
|
|
139
144
|
}
|
|
140
145
|
return createApi({ baseUrl, getAccessToken, workspaceUuid });
|
|
141
146
|
};
|
|
147
|
+
// For the commands that read only the routes answering without a workspace
|
|
148
|
+
// (the official integrations, their actions, and the definitions
|
|
149
|
+
// `action execute --dry-run` reads), so an agent can try them before signing
|
|
150
|
+
// up. Signed in, it still sends the token, which
|
|
151
|
+
// is what keeps a workspace's own custom integrations in what it returns.
|
|
152
|
+
// Every other command keeps `getApi`, which refuses to run without a token.
|
|
153
|
+
const getPublicApi = () => {
|
|
154
|
+
const { baseUrl, getAccessToken, workspaceUuid } = getConfig();
|
|
155
|
+
return createApi({ baseUrl, getAccessToken, workspaceUuid });
|
|
156
|
+
};
|
|
142
157
|
// Where the palette finds answers for an option that wants an id. Keyed by the
|
|
143
158
|
// flag, because `--model-uuid` asks the same question in all 28 places it
|
|
144
159
|
// appears; the uuid entries cover the 84 uuid options this CLI declares, and
|
|
@@ -233,11 +248,11 @@ registerVersionCommand(program, version);
|
|
|
233
248
|
registerDoctorCommand(program, version);
|
|
234
249
|
registerBookDemoCommand(program);
|
|
235
250
|
registerObservabilityCommands(program, getApi);
|
|
236
|
-
registerOrchestrationCommands(program, getApi);
|
|
251
|
+
registerOrchestrationCommands(program, getApi, getPublicApi);
|
|
237
252
|
registerWorkspaceManagementCommands(program, getApi);
|
|
238
253
|
registerStorageCommands(program, getApi);
|
|
239
254
|
registerContentCommands(program, getApi);
|
|
240
|
-
registerConnectionCommands(program, getApi);
|
|
255
|
+
registerConnectionCommands(program, getApi, getPublicApi);
|
|
241
256
|
registerContextCommands(program, getApi);
|
|
242
257
|
registerBillingCommands(program, getApi);
|
|
243
258
|
registerSegmentationCommands(program, getApi);
|
|
@@ -256,7 +271,7 @@ registerMcpCommand(program, getApi);
|
|
|
256
271
|
registerCdkCommands(program
|
|
257
272
|
.command("project")
|
|
258
273
|
.alias("cdk")
|
|
259
|
-
.description("Define this workspace in a repo and deploy it (init/plan/deploy)"), getApi);
|
|
274
|
+
.description("Define this workspace in a repo and deploy it (init/plan/deploy)"), getApi, getPublicApi);
|
|
260
275
|
// Bare `cargo-ai` in a terminal opens the palette instead of printing the help
|
|
261
276
|
// wall: twenty command groups is a list to navigate, not one to read. Anything
|
|
262
277
|
// non-interactive (a pipe, CI, an agent) keeps the help it has always had.
|