@cargo-ai/cli 1.0.35 → 1.0.37
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/build/api.d.ts.map +1 -1
- package/build/api.js +5 -2
- package/build/commands/auth/index.js +1 -1
- package/build/commands/connection/action.d.ts +4 -0
- package/build/commands/connection/action.d.ts.map +1 -0
- package/build/commands/connection/action.js +131 -0
- package/build/commands/connection/index.d.ts.map +1 -1
- package/build/commands/connection/index.js +2 -0
- package/build/commands/doctor.d.ts +3 -0
- package/build/commands/doctor.d.ts.map +1 -0
- package/build/commands/doctor.js +155 -0
- package/build/commands/orchestration/action.d.ts.map +1 -1
- package/build/commands/orchestration/action.js +14 -3
- package/build/commands/orchestration/batch.d.ts.map +1 -1
- package/build/commands/orchestration/batch.js +3 -2
- package/build/commands/runHandler.d.ts +6 -0
- package/build/commands/runHandler.d.ts.map +1 -1
- package/build/commands/runHandler.js +17 -0
- package/build/config.d.ts.map +1 -1
- package/build/config.js +9 -41
- package/build/index.js +2 -0
- package/build/proxy.d.ts +2 -17
- package/build/proxy.d.ts.map +1 -1
- package/build/proxy.js +2 -28
- package/package.json +4 -6
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;AAInD,YAAY,EAAE,GAAG,EAAE,CAAC;AAQpB,wBAAgB,SAAS,CAAC,IAAI,EAAE;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,GAAG,SAAS,CAAC;CACnC,GAAG,GAAG,
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,GAAG,EAAY,MAAM,eAAe,CAAC;AAInD,YAAY,EAAE,GAAG,EAAE,CAAC;AAQpB,wBAAgB,SAAS,CAAC,IAAI,EAAE;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,GAAG,SAAS,CAAC;CACnC,GAAG,GAAG,CAWN"}
|
package/build/api.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createRequire } from "node:module";
|
|
2
2
|
import { buildApi } from "@cargo-ai/api";
|
|
3
|
-
import {
|
|
3
|
+
import { getProxyFetch } from "./proxy.js";
|
|
4
4
|
const require = createRequire(import.meta.url);
|
|
5
5
|
const { version } = require("../package.json");
|
|
6
6
|
const ORIGIN = { name: "cli", version };
|
|
@@ -10,6 +10,9 @@ export function createApi(opts) {
|
|
|
10
10
|
workspaceUuid: opts.workspaceUuid,
|
|
11
11
|
accessToken: opts.accessToken,
|
|
12
12
|
origin: ORIGIN,
|
|
13
|
-
|
|
13
|
+
// The client is `fetch`-based; supply a proxy-tunneling `fetch` (undici
|
|
14
|
+
// `ProxyAgent`) when proxy env vars are set, since Node's global `fetch`
|
|
15
|
+
// does not honor them. `undefined` when no proxy applies.
|
|
16
|
+
transport: { fetch: getProxyFetch(opts.baseUrl) },
|
|
14
17
|
});
|
|
15
18
|
}
|
|
@@ -23,7 +23,7 @@ Examples:
|
|
|
23
23
|
$ cargo-ai login --oauth --workspace-uuid 550e8400-e29b-41d4-a716-446655440000
|
|
24
24
|
|
|
25
25
|
Credentials are stored in ~/.config/cargo-ai/credentials.json.
|
|
26
|
-
Environment variables (CARGO_API_TOKEN, CARGO_WORKSPACE_UUID, CARGO_BASE_URL) take precedence over saved credentials.`)
|
|
26
|
+
Environment variables (CARGO_API_TOKEN, CARGO_WORKSPACE_UUID, CARGO_BASE_URL) take precedence over saved credentials, and the nearest project .env (walking up from the current directory) fills them in when they are not already exported.`)
|
|
27
27
|
.action(async (opts) => {
|
|
28
28
|
await runLogin(opts);
|
|
29
29
|
});
|
|
@@ -0,0 +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;AA+CxC,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,OAAO,EACf,MAAM,EAAE,MAAM,GAAG,GAChB,IAAI,CAuHN"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { ExitCodes, failWith, handleApiCall, outputJson, } from "../runHandler.js";
|
|
2
|
+
const DEFAULT_LIMIT = 20;
|
|
3
|
+
const DESCRIPTION_MAX_LENGTH = 300;
|
|
4
|
+
export function registerActionSearchCommands(parent, getApi) {
|
|
5
|
+
const action = parent
|
|
6
|
+
.command("action")
|
|
7
|
+
.description("Discover integration actions");
|
|
8
|
+
action
|
|
9
|
+
.command("search [query...]")
|
|
10
|
+
.description("Search integration actions by keyword across action slug, name, description, and integration — " +
|
|
11
|
+
"instead of scanning the full `integration list` payload")
|
|
12
|
+
.option("--category <category>", "Filter by integration category (string)")
|
|
13
|
+
.option("--integration <slug>", "Filter by integration slug (string)")
|
|
14
|
+
.option("--credits-only", "Only return credits-based (paid) actions (boolean flag)")
|
|
15
|
+
.option("--limit <n>", `Maximum results to return (integer, default: ${String(DEFAULT_LIMIT)})`, String(DEFAULT_LIMIT))
|
|
16
|
+
.addHelpText("after", `
|
|
17
|
+
All query terms must match somewhere (action slug/name, integration, or description).
|
|
18
|
+
Matches on the action slug or name rank above integration matches, which rank above
|
|
19
|
+
description matches. Without a query, lists actions filtered by the flags alone.
|
|
20
|
+
|
|
21
|
+
Examples:
|
|
22
|
+
$ cargo-ai connection action search email verify
|
|
23
|
+
$ cargo-ai connection action search "job change" --credits-only
|
|
24
|
+
$ cargo-ai connection action search enrich --integration waterfall
|
|
25
|
+
$ cargo-ai connection action search --category crm --limit 50`)
|
|
26
|
+
.action(async (queryTerms, opts) => {
|
|
27
|
+
const limit = parseInt(opts.limit, 10);
|
|
28
|
+
if (Number.isNaN(limit) === true || limit < 1) {
|
|
29
|
+
failWith("--limit must be a positive integer.", {
|
|
30
|
+
code: ExitCodes.InvalidUsage,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
const api = getApi();
|
|
34
|
+
const { integrations } = await handleApiCall(() => api.connection.integration.list({
|
|
35
|
+
hasActions: true,
|
|
36
|
+
category: opts.category,
|
|
37
|
+
slug: opts.integration,
|
|
38
|
+
}));
|
|
39
|
+
const terms = queryTerms
|
|
40
|
+
.flatMap((term) => term.split(/\s+/))
|
|
41
|
+
.map((term) => term.toLowerCase())
|
|
42
|
+
.filter((term) => term.length > 0);
|
|
43
|
+
const results = [];
|
|
44
|
+
for (const integration of integrations) {
|
|
45
|
+
const actions = integration.actions;
|
|
46
|
+
if (actions === undefined) {
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
for (const [actionSlug, actionDef] of Object.entries(actions)) {
|
|
50
|
+
const costs = actionDef.credits?.costs;
|
|
51
|
+
if (opts.creditsOnly === true &&
|
|
52
|
+
(costs === undefined || costs.length === 0)) {
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
const score = scoreAction(terms, {
|
|
56
|
+
actionText: `${actionSlug} ${actionDef.name ?? ""}`,
|
|
57
|
+
integrationText: `${integration.slug} ${integration.name}`,
|
|
58
|
+
descriptionText: actionDef.description ?? "",
|
|
59
|
+
});
|
|
60
|
+
if (score === 0) {
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
results.push({
|
|
64
|
+
integrationSlug: integration.slug,
|
|
65
|
+
integrationName: integration.name,
|
|
66
|
+
category: integration.category,
|
|
67
|
+
actionSlug,
|
|
68
|
+
name: actionDef.name,
|
|
69
|
+
description: truncate(actionDef.description),
|
|
70
|
+
credits: costs?.map((cost) => mapSearchableCreditsCost(cost)),
|
|
71
|
+
score,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
results.sort((a, b) => b.score - a.score || a.actionSlug.localeCompare(b.actionSlug));
|
|
76
|
+
outputJson({
|
|
77
|
+
query: terms.join(" "),
|
|
78
|
+
totalMatches: results.length,
|
|
79
|
+
results: results.slice(0, limit),
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
// Every term must match somewhere (AND semantics); the sum of the strongest
|
|
84
|
+
// match per term ranks the result. Action slug/name beats integration beats
|
|
85
|
+
// description.
|
|
86
|
+
function scoreAction(terms, fields) {
|
|
87
|
+
if (terms.length === 0) {
|
|
88
|
+
return 1;
|
|
89
|
+
}
|
|
90
|
+
const actionText = fields.actionText.toLowerCase();
|
|
91
|
+
const integrationText = fields.integrationText.toLowerCase();
|
|
92
|
+
const descriptionText = fields.descriptionText.toLowerCase();
|
|
93
|
+
let total = 0;
|
|
94
|
+
for (const term of terms) {
|
|
95
|
+
if (actionText.includes(term) === true) {
|
|
96
|
+
total += 3;
|
|
97
|
+
}
|
|
98
|
+
else if (integrationText.includes(term) === true) {
|
|
99
|
+
total += 2;
|
|
100
|
+
}
|
|
101
|
+
else if (descriptionText.includes(term) === true) {
|
|
102
|
+
total += 1;
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
return 0;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return total;
|
|
109
|
+
}
|
|
110
|
+
function mapSearchableCreditsCost(cost) {
|
|
111
|
+
const mapped = {
|
|
112
|
+
type: cost.type,
|
|
113
|
+
cost: cost.cost,
|
|
114
|
+
};
|
|
115
|
+
if (cost.unit !== undefined) {
|
|
116
|
+
mapped.unit = cost.unit;
|
|
117
|
+
}
|
|
118
|
+
if (cost.unitsCount !== undefined) {
|
|
119
|
+
mapped.unitsCount = cost.unitsCount;
|
|
120
|
+
}
|
|
121
|
+
if (cost.fixedCost !== undefined) {
|
|
122
|
+
mapped.fixedCost = cost.fixedCost;
|
|
123
|
+
}
|
|
124
|
+
return mapped;
|
|
125
|
+
}
|
|
126
|
+
function truncate(value) {
|
|
127
|
+
if (value === undefined || value.length <= DESCRIPTION_MAX_LENGTH) {
|
|
128
|
+
return value;
|
|
129
|
+
}
|
|
130
|
+
return `${value.slice(0, DESCRIPTION_MAX_LENGTH)}…`;
|
|
131
|
+
}
|
|
@@ -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;
|
|
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,GAChB,IAAI,CAUN"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { registerActionSearchCommands } from "./action.js";
|
|
1
2
|
import { registerConnectorCommands } from "./connector.js";
|
|
2
3
|
import { registerCustomIntegrationCommands } from "./customIntegration.js";
|
|
3
4
|
import { registerIntegrationCommands } from "./integration.js";
|
|
@@ -8,6 +9,7 @@ export function registerConnectionCommands(parent, getApi) {
|
|
|
8
9
|
.description("Connectors and integrations");
|
|
9
10
|
registerConnectorCommands(connection, getApi);
|
|
10
11
|
registerIntegrationCommands(connection, getApi);
|
|
12
|
+
registerActionSearchCommands(connection, getApi);
|
|
11
13
|
registerNativeIntegrationCommands(connection, getApi);
|
|
12
14
|
registerCustomIntegrationCommands(connection, getApi);
|
|
13
15
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAgKzC,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,OAAO,EAChB,cAAc,EAAE,MAAM,GACrB,IAAI,CAoDN"}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import * as os from "node:os";
|
|
3
|
+
import * as path from "node:path";
|
|
4
|
+
import { determineIfIsFetcherError } from "@cargo-ai/api";
|
|
5
|
+
import { createApi } from "../api.js";
|
|
6
|
+
import { getConfig } from "../config.js";
|
|
7
|
+
import { getCredentialsPath } from "../credentials.js";
|
|
8
|
+
import { fetchLatestVersion, isOutdated } from "../version.js";
|
|
9
|
+
import { ExitCodes, outputJson } from "./runHandler.js";
|
|
10
|
+
const SEMVER_PATTERN = /^\d+\.\d+\.\d+$/;
|
|
11
|
+
function getSkillsPinCandidates() {
|
|
12
|
+
const home = os.homedir();
|
|
13
|
+
const envDir = process.env["CARGO_SKILLS_DIR"];
|
|
14
|
+
const candidates = [];
|
|
15
|
+
if (envDir !== undefined && envDir.length > 0) {
|
|
16
|
+
candidates.push(path.join(envDir, "cargo", "cli-version"));
|
|
17
|
+
}
|
|
18
|
+
candidates.push(path.join(home, ".claude", "skills", "cargo", "cli-version"), path.join(home, ".claude", "plugins", "marketplaces", "cargo", "cargo", "cli-version"), path.join(home, ".openclaw", "skills", "cargo", "cli-version"));
|
|
19
|
+
return candidates;
|
|
20
|
+
}
|
|
21
|
+
function readSkillsPin() {
|
|
22
|
+
for (const candidate of getSkillsPinCandidates()) {
|
|
23
|
+
try {
|
|
24
|
+
const raw = fs.readFileSync(candidate, "utf8").trim();
|
|
25
|
+
if (SEMVER_PATTERN.test(raw)) {
|
|
26
|
+
return { version: raw, path: candidate };
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
// Missing or unreadable — try the next candidate.
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return undefined;
|
|
34
|
+
}
|
|
35
|
+
function buildCliCheck(currentVersion, latestVersion) {
|
|
36
|
+
if (latestVersion === undefined) {
|
|
37
|
+
return { current: currentVersion, latest: null, upToDate: null };
|
|
38
|
+
}
|
|
39
|
+
return {
|
|
40
|
+
current: currentVersion,
|
|
41
|
+
latest: latestVersion,
|
|
42
|
+
upToDate: !isOutdated(currentVersion, latestVersion),
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
function buildSkillsPinCheck(currentVersion) {
|
|
46
|
+
const pin = readSkillsPin();
|
|
47
|
+
if (pin === undefined) {
|
|
48
|
+
return { found: false };
|
|
49
|
+
}
|
|
50
|
+
return {
|
|
51
|
+
found: true,
|
|
52
|
+
pinned: pin.version,
|
|
53
|
+
path: pin.path,
|
|
54
|
+
matchesCli: pin.version === currentVersion,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
async function checkApi(config) {
|
|
58
|
+
if (config.accessToken === undefined) {
|
|
59
|
+
return {
|
|
60
|
+
check: {
|
|
61
|
+
ok: false,
|
|
62
|
+
error: {
|
|
63
|
+
status: "no-credentials",
|
|
64
|
+
message: 'Not authenticated. Run "cargo-ai login --token <token>" or "cargo-ai login --oauth".',
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
exitCode: ExitCodes.NotAuthenticated,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
const client = createApi({
|
|
71
|
+
baseUrl: config.baseUrl,
|
|
72
|
+
accessToken: config.accessToken,
|
|
73
|
+
workspaceUuid: config.workspaceUuid,
|
|
74
|
+
});
|
|
75
|
+
try {
|
|
76
|
+
const { user } = await client.userManagement.user.getCurrent();
|
|
77
|
+
const { workspace } = await client.workspaceManagement.workspace.getCurrent();
|
|
78
|
+
return {
|
|
79
|
+
check: {
|
|
80
|
+
ok: true,
|
|
81
|
+
user: { uuid: user.uuid, email: user.email },
|
|
82
|
+
workspace: { uuid: workspace.uuid, name: workspace.name },
|
|
83
|
+
},
|
|
84
|
+
exitCode: ExitCodes.Success,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
catch (error) {
|
|
88
|
+
const status = determineIfIsFetcherError(error)
|
|
89
|
+
? (error.status ?? 0)
|
|
90
|
+
: 0;
|
|
91
|
+
let exitCode;
|
|
92
|
+
if (status === 401) {
|
|
93
|
+
exitCode = ExitCodes.NotAuthenticated;
|
|
94
|
+
}
|
|
95
|
+
else if (status === 403) {
|
|
96
|
+
exitCode = ExitCodes.PermissionDenied;
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
exitCode = ExitCodes.GenericError;
|
|
100
|
+
}
|
|
101
|
+
return {
|
|
102
|
+
check: {
|
|
103
|
+
ok: false,
|
|
104
|
+
error: {
|
|
105
|
+
status,
|
|
106
|
+
message: error instanceof Error ? error.message : String(error),
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
exitCode,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
export function registerDoctorCommand(program, currentVersion) {
|
|
114
|
+
program
|
|
115
|
+
.command("doctor")
|
|
116
|
+
.description("Diagnose the CLI setup: version vs latest and the skills-bundle pin, credentials, and API reachability")
|
|
117
|
+
.addHelpText("after", `
|
|
118
|
+
Runs every check and reports all results as one JSON object, then exits with the
|
|
119
|
+
most severe failure:
|
|
120
|
+
|
|
121
|
+
0 healthy (an outdated CLI or a pin mismatch is reported but never fails the check)
|
|
122
|
+
1 API unreachable or returned an unexpected error
|
|
123
|
+
3 not authenticated (no credentials, or the API rejected them)
|
|
124
|
+
4 permission denied for the configured workspace
|
|
125
|
+
|
|
126
|
+
Scripts and agents should branch on the exit code and read the JSON for details.
|
|
127
|
+
|
|
128
|
+
Examples:
|
|
129
|
+
$ cargo-ai doctor
|
|
130
|
+
$ cargo-ai doctor || echo "exit: $?"`)
|
|
131
|
+
.action(async () => {
|
|
132
|
+
let latestVersion;
|
|
133
|
+
try {
|
|
134
|
+
latestVersion = await fetchLatestVersion();
|
|
135
|
+
}
|
|
136
|
+
catch {
|
|
137
|
+
latestVersion = undefined;
|
|
138
|
+
}
|
|
139
|
+
const cli = buildCliCheck(currentVersion, latestVersion);
|
|
140
|
+
const skillsPin = buildSkillsPinCheck(currentVersion);
|
|
141
|
+
const config = getConfig();
|
|
142
|
+
const credentials = {
|
|
143
|
+
source: config.source,
|
|
144
|
+
baseUrl: config.baseUrl,
|
|
145
|
+
workspaceUuid: config.workspaceUuid !== undefined ? config.workspaceUuid : null,
|
|
146
|
+
credentialsFile: getCredentialsPath(),
|
|
147
|
+
};
|
|
148
|
+
const { check: api, exitCode } = await checkApi(config);
|
|
149
|
+
outputJson({
|
|
150
|
+
ok: exitCode === ExitCodes.Success,
|
|
151
|
+
checks: { cli, skillsPin, credentials, api },
|
|
152
|
+
});
|
|
153
|
+
process.exit(exitCode);
|
|
154
|
+
});
|
|
155
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"action.d.ts","sourceRoot":"","sources":["../../../src/commands/orchestration/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/orchestration/action.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAaxC,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,OAAO,EACf,MAAM,EAAE,MAAM,GAAG,GAChB,IAAI,CA+KN"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { handleApiCall, outputJson, parseJson, pollBatchUntilFinished, pollRunUntilFinished, } from "../runHandler.js";
|
|
1
|
+
import { applyRecordsLimit, ExitCodes, failWith, handleApiCall, outputJson, parseJson, parsePositiveInt, pollBatchUntilFinished, pollRunUntilFinished, } from "../runHandler.js";
|
|
2
2
|
export function registerActionCommands(parent, getApi) {
|
|
3
3
|
const action = parent
|
|
4
4
|
.command("action")
|
|
@@ -37,15 +37,26 @@ Examples:
|
|
|
37
37
|
.requiredOption("--records <json>", 'Records to process (JSON array, required). Example: \'[{"email":"a@b.com"},{"email":"c@d.com"}]\'')
|
|
38
38
|
.option("--webhook-url <url>", "URL to call when the batch completes")
|
|
39
39
|
.option("--webhook-secret <secret>", "Secret used to sign webhook deliveries")
|
|
40
|
+
.option("--limit <n>", "Pilot: only submit the first N records (integer). Inspect the pilot's output before re-running on the full set — credits-based actions bill per record.")
|
|
40
41
|
.option("--wait-until-finished", "Poll the batch until it reaches a terminal status before returning (boolean flag)")
|
|
41
42
|
.option("--polling-interval <ms>", "Polling interval in milliseconds, used with --wait-until-finished (integer, default: 5000)", "5000")
|
|
42
43
|
.addHelpText("after", `
|
|
43
44
|
Examples:
|
|
44
45
|
$ cargo-ai orchestration action execute-batch --action '{"kind":"tool","toolUuid":"550e8400-...","config":{}}' --records '[{"email":"a@b.com"},{"email":"c@d.com"}]'
|
|
45
|
-
$ cargo-ai orchestration action execute-batch --action '{"kind":"connector","integrationSlug":"slack","actionSlug":"send-message","config":{}}' --records '[{"channel":"#general"}]' --wait-until-finished
|
|
46
|
+
$ cargo-ai orchestration action execute-batch --action '{"kind":"connector","integrationSlug":"slack","actionSlug":"send-message","config":{}}' --records '[{"channel":"#general"}]' --wait-until-finished
|
|
47
|
+
$ cargo-ai orchestration action execute-batch --action '{"kind":"connector","integrationSlug":"waterfall","actionSlug":"findEmail","config":{}}' --records "$(cat records.json)" --limit 1 --wait-until-finished`)
|
|
46
48
|
.action(async (opts) => {
|
|
47
49
|
const actionPayload = parseJson(opts.action, "--action");
|
|
48
|
-
|
|
50
|
+
let records = parseJson(opts.records, "--records");
|
|
51
|
+
if (opts.limit !== undefined) {
|
|
52
|
+
const limit = parsePositiveInt(opts.limit, "--limit");
|
|
53
|
+
if (Array.isArray(records) === false) {
|
|
54
|
+
failWith("--limit requires --records to be a JSON array.", {
|
|
55
|
+
code: ExitCodes.InvalidUsage,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
records = applyRecordsLimit(records, limit).records;
|
|
59
|
+
}
|
|
49
60
|
const api = getApi();
|
|
50
61
|
const result = await handleApiCall(() => api.orchestration.action.executeBatch({
|
|
51
62
|
action: actionPayload,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"batch.d.ts","sourceRoot":"","sources":["../../../src/commands/orchestration/batch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAexC,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,OAAO,EACf,MAAM,EAAE,MAAM,GAAG,GAChB,IAAI,
|
|
1
|
+
{"version":3,"file":"batch.d.ts","sourceRoot":"","sources":["../../../src/commands/orchestration/batch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAexC,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,OAAO,EACf,MAAM,EAAE,MAAM,GAAG,GAChB,IAAI,CAgRN"}
|
|
@@ -64,7 +64,7 @@ export function registerBatchCommands(parent, getApi) {
|
|
|
64
64
|
.description("Create a batch. Pass --file to test-run a Workflow SDK module (compiled and " +
|
|
65
65
|
"run as custom nodes, with @cargo-ai/cdk handles resolved from cargo.state.json — no deploy).")
|
|
66
66
|
.option("--workflow-uuid <uuid>", "Workflow UUID (string)")
|
|
67
|
-
.requiredOption("--data <json>", 'Batch data source (JSON object, required).
|
|
67
|
+
.requiredOption("--data <json>", 'Batch data source (JSON object, required). Kinds: {"kind":"segment","segmentUuid"}, {"kind":"file","s3Filename","mappings?"}, {"kind":"filter","modelUuid","filter?","sort?","limit?"}, {"kind":"recordIds","modelUuid","ids"}, {"kind":"records","records"}, {"kind":"change","changeUuid","changeKinds"}, {"kind":"runs","filter","reset"}')
|
|
68
68
|
.option("--release-uuid <uuid>", "Release UUID to pin the batch to (string)")
|
|
69
69
|
.option("--file <path>", "Path to a Workflow SDK module (its default export must be the compiled workflow returned by defineWorkflow()). Compiles it, resolves any @cargo-ai/cdk resource handles to real uuids from cargo.state.json, and runs the resulting nodes. Rejected with --nodes.")
|
|
70
70
|
.option("--nodes <json>", "Custom nodes to override the workflow definition (JSON array). Rejected with --file.")
|
|
@@ -93,11 +93,12 @@ Examples:
|
|
|
93
93
|
nodes = parseJson(opts.nodes, "--nodes");
|
|
94
94
|
}
|
|
95
95
|
const api = getApi();
|
|
96
|
+
const data = parseJson(opts.data, "--data");
|
|
96
97
|
const result = await handleApiCall(() => api.orchestration.batch.create({
|
|
97
98
|
workflowUuid: opts.workflowUuid,
|
|
98
99
|
releaseUuid: opts.releaseUuid,
|
|
99
100
|
nodes,
|
|
100
|
-
data
|
|
101
|
+
data,
|
|
101
102
|
}));
|
|
102
103
|
if (opts.waitUntilFinished === true) {
|
|
103
104
|
const intervalMs = parseInt(opts.pollingInterval, 10);
|
|
@@ -31,6 +31,12 @@ export type Spinner = {
|
|
|
31
31
|
};
|
|
32
32
|
export declare function startSpinner(message: string): Spinner;
|
|
33
33
|
export declare function parseJson(value: string, optionName: string): any;
|
|
34
|
+
export declare function parsePositiveInt(value: string, optionName: string): number;
|
|
35
|
+
export declare function applyRecordsLimit<T>(records: T[], limit: number): {
|
|
36
|
+
records: T[];
|
|
37
|
+
wasTruncated: boolean;
|
|
38
|
+
total: number;
|
|
39
|
+
};
|
|
34
40
|
type HandleApiCallOpts = {
|
|
35
41
|
spinner?: string | false;
|
|
36
42
|
};
|
|
@@ -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;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"}
|
|
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;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAQ1E;AAED,wBAAgB,iBAAiB,CAAC,CAAC,EACjC,OAAO,EAAE,CAAC,EAAE,EACZ,KAAK,EAAE,MAAM,GACZ;IAAE,OAAO,EAAE,CAAC,EAAE,CAAC;IAAC,YAAY,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CASxD;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"}
|
|
@@ -131,6 +131,23 @@ export function parseJson(value, optionName) {
|
|
|
131
131
|
});
|
|
132
132
|
}
|
|
133
133
|
}
|
|
134
|
+
export function parsePositiveInt(value, optionName) {
|
|
135
|
+
const n = parseInt(value, 10);
|
|
136
|
+
if (Number.isNaN(n) === true || n < 1) {
|
|
137
|
+
failWith(`${optionName} must be a positive integer.`, {
|
|
138
|
+
code: ExitCodes.InvalidUsage,
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
return n;
|
|
142
|
+
}
|
|
143
|
+
export function applyRecordsLimit(records, limit) {
|
|
144
|
+
const total = records.length;
|
|
145
|
+
if (limit < total) {
|
|
146
|
+
info(`Piloting: submitting the first ${String(limit)} of ${String(total)} record(s). Re-run without --limit for the full set.`);
|
|
147
|
+
return { records: records.slice(0, limit), wasTruncated: true, total };
|
|
148
|
+
}
|
|
149
|
+
return { records, wasTruncated: false, total };
|
|
150
|
+
}
|
|
134
151
|
const SPINNER_DELAY_MS = 200;
|
|
135
152
|
const DEFAULT_SPINNER_MESSAGE = "Loading...";
|
|
136
153
|
export async function handleApiCall(fn, opts) {
|
package/build/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,YAAY,GAAG,aAAa,GAAG,kBAAkB,GAAG,MAAM,CAAC;AAEvE,MAAM,MAAM,MAAM,GAAG;IACnB,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,MAAM,EAAE,YAAY,CAAC;CACtB,CAAC;AAEF,wBAAgB,SAAS,IAAI,MAAM,CAclC"}
|
package/build/config.js
CHANGED
|
@@ -1,47 +1,15 @@
|
|
|
1
|
+
import { loadProjectEnv, resolveAuthConfig } from "@cargo-ai/cdk/cli";
|
|
1
2
|
import { loadCredentials } from "./credentials.js";
|
|
2
|
-
const DEFAULT_BASE_URL = "https://api.getcargo.io";
|
|
3
3
|
export function getConfig() {
|
|
4
|
+
// Fold project `.env` into the environment first (never overriding explicit
|
|
5
|
+
// exports): a repo pinned to one workspace must win over a personal login.
|
|
6
|
+
loadProjectEnv();
|
|
4
7
|
const credentials = loadCredentials();
|
|
5
|
-
const
|
|
6
|
-
let accessToken;
|
|
7
|
-
let source;
|
|
8
|
-
if (envToken !== undefined) {
|
|
9
|
-
accessToken = envToken;
|
|
10
|
-
source = "environment";
|
|
11
|
-
}
|
|
12
|
-
else if (credentials !== undefined &&
|
|
13
|
-
credentials.accessToken !== undefined) {
|
|
14
|
-
accessToken = credentials.accessToken;
|
|
15
|
-
source = "credentials-file";
|
|
16
|
-
}
|
|
17
|
-
else {
|
|
18
|
-
accessToken = undefined;
|
|
19
|
-
source = "none";
|
|
20
|
-
}
|
|
8
|
+
const resolved = resolveAuthConfig(process.env, credentials);
|
|
21
9
|
return {
|
|
22
|
-
accessToken,
|
|
23
|
-
baseUrl:
|
|
24
|
-
workspaceUuid:
|
|
25
|
-
source,
|
|
10
|
+
accessToken: resolved.accessToken,
|
|
11
|
+
baseUrl: resolved.baseUrl,
|
|
12
|
+
workspaceUuid: resolved.workspaceUuid,
|
|
13
|
+
source: resolved.tokenSource,
|
|
26
14
|
};
|
|
27
15
|
}
|
|
28
|
-
const getBaseUrl = (credentials) => {
|
|
29
|
-
const envUrl = process.env["CARGO_BASE_URL"];
|
|
30
|
-
if (envUrl !== undefined) {
|
|
31
|
-
return envUrl;
|
|
32
|
-
}
|
|
33
|
-
if (credentials !== undefined && credentials.baseUrl !== undefined) {
|
|
34
|
-
return credentials.baseUrl;
|
|
35
|
-
}
|
|
36
|
-
return DEFAULT_BASE_URL;
|
|
37
|
-
};
|
|
38
|
-
const getWorkspaceUuid = (credentials) => {
|
|
39
|
-
const envUuid = process.env["CARGO_WORKSPACE_UUID"];
|
|
40
|
-
if (envUuid !== undefined) {
|
|
41
|
-
return envUuid;
|
|
42
|
-
}
|
|
43
|
-
if (credentials !== undefined) {
|
|
44
|
-
return credentials.workspaceUuid;
|
|
45
|
-
}
|
|
46
|
-
return undefined;
|
|
47
|
-
};
|
package/build/index.js
CHANGED
|
@@ -9,6 +9,7 @@ import { registerBillingCommands } from "./commands/billing/index.js";
|
|
|
9
9
|
import { registerConnectionCommands } from "./commands/connection/index.js";
|
|
10
10
|
import { registerContentCommands } from "./commands/content/index.js";
|
|
11
11
|
import { registerContextCommands } from "./commands/context/index.js";
|
|
12
|
+
import { registerDoctorCommand } from "./commands/doctor.js";
|
|
12
13
|
import { registerExpressionCommands } from "./commands/expression/index.js";
|
|
13
14
|
import { registerHostingCommands } from "./commands/hosting/index.js";
|
|
14
15
|
import { registerInitCommand } from "./commands/init.js";
|
|
@@ -59,6 +60,7 @@ const getApi = () => {
|
|
|
59
60
|
};
|
|
60
61
|
registerAuthCommands(program, getApi);
|
|
61
62
|
registerVersionCommand(program, version);
|
|
63
|
+
registerDoctorCommand(program, version);
|
|
62
64
|
registerInitCommand(program, getApi);
|
|
63
65
|
registerOrchestrationCommands(program, getApi);
|
|
64
66
|
registerWorkspaceManagementCommands(program, getApi);
|
package/build/proxy.d.ts
CHANGED
|
@@ -1,22 +1,7 @@
|
|
|
1
|
-
import type { ClientTransport } from "@cargo-ai/api";
|
|
2
|
-
/**
|
|
3
|
-
* Build Axios transport overrides that tunnel requests through an
|
|
4
|
-
* HTTP/HTTPS proxy when one is configured via the standard proxy env
|
|
5
|
-
* vars (`HTTPS_PROXY`, `HTTP_PROXY`, `ALL_PROXY`, honoring `NO_PROXY`).
|
|
6
|
-
*
|
|
7
|
-
* This works around Axios' unreliable built-in proxy handling, which can
|
|
8
|
-
* fall into a 308 redirect loop (`ERR_FR_TOO_MANY_REDIRECTS`) for HTTPS
|
|
9
|
-
* targets inside proxied environments such as cloud agent sandboxes. We
|
|
10
|
-
* disable Axios' env-based proxy (`proxy: false`) and tunnel via the
|
|
11
|
-
* dedicated proxy agents instead.
|
|
12
|
-
*
|
|
13
|
-
* Returns `undefined` when no proxy applies, so the client keeps its
|
|
14
|
-
* default direct-egress behavior.
|
|
15
|
-
*/
|
|
16
|
-
export declare const getProxyTransport: (targetUrl: string) => ClientTransport | undefined;
|
|
17
1
|
/**
|
|
18
2
|
* Build a `fetch` implementation that tunnels through an HTTP/HTTPS proxy
|
|
19
|
-
* when one is configured via the
|
|
3
|
+
* when one is configured via the standard proxy env vars (`HTTPS_PROXY`,
|
|
4
|
+
* `HTTP_PROXY`, `ALL_PROXY`, honoring `NO_PROXY`).
|
|
20
5
|
*
|
|
21
6
|
* Node's built-in `fetch` (and therefore MCP's `StreamableHTTPClientTransport`)
|
|
22
7
|
* does not honor `HTTPS_PROXY` / `HTTP_PROXY` on its own. Callers that need
|
package/build/proxy.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"proxy.d.ts","sourceRoot":"","sources":["../src/proxy.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"proxy.d.ts","sourceRoot":"","sources":["../src/proxy.ts"],"names":[],"mappings":"AAgEA;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,aAAa,cACb,MAAM,YAER,MAAM,GAAG,GAAG,SAAS,WAAW,KAAK,QAAQ,QAAQ,CAAC,aAchE,CAAC"}
|
package/build/proxy.js
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { HttpProxyAgent } from "http-proxy-agent";
|
|
2
|
-
import { HttpsProxyAgent } from "https-proxy-agent";
|
|
3
1
|
import { fetch as undiciFetch, ProxyAgent, } from "undici";
|
|
4
2
|
const getEnv = (...names) => {
|
|
5
3
|
for (const name of names) {
|
|
@@ -48,34 +46,10 @@ const resolveProxyUrl = (targetUrl) => {
|
|
|
48
46
|
? getEnv("HTTPS_PROXY", "https_proxy", "ALL_PROXY", "all_proxy")
|
|
49
47
|
: getEnv("HTTP_PROXY", "http_proxy", "ALL_PROXY", "all_proxy");
|
|
50
48
|
};
|
|
51
|
-
/**
|
|
52
|
-
* Build Axios transport overrides that tunnel requests through an
|
|
53
|
-
* HTTP/HTTPS proxy when one is configured via the standard proxy env
|
|
54
|
-
* vars (`HTTPS_PROXY`, `HTTP_PROXY`, `ALL_PROXY`, honoring `NO_PROXY`).
|
|
55
|
-
*
|
|
56
|
-
* This works around Axios' unreliable built-in proxy handling, which can
|
|
57
|
-
* fall into a 308 redirect loop (`ERR_FR_TOO_MANY_REDIRECTS`) for HTTPS
|
|
58
|
-
* targets inside proxied environments such as cloud agent sandboxes. We
|
|
59
|
-
* disable Axios' env-based proxy (`proxy: false`) and tunnel via the
|
|
60
|
-
* dedicated proxy agents instead.
|
|
61
|
-
*
|
|
62
|
-
* Returns `undefined` when no proxy applies, so the client keeps its
|
|
63
|
-
* default direct-egress behavior.
|
|
64
|
-
*/
|
|
65
|
-
export const getProxyTransport = (targetUrl) => {
|
|
66
|
-
const proxyUrl = resolveProxyUrl(targetUrl);
|
|
67
|
-
if (proxyUrl === undefined) {
|
|
68
|
-
return undefined;
|
|
69
|
-
}
|
|
70
|
-
return {
|
|
71
|
-
httpAgent: new HttpProxyAgent(proxyUrl),
|
|
72
|
-
httpsAgent: new HttpsProxyAgent(proxyUrl),
|
|
73
|
-
proxy: false,
|
|
74
|
-
};
|
|
75
|
-
};
|
|
76
49
|
/**
|
|
77
50
|
* Build a `fetch` implementation that tunnels through an HTTP/HTTPS proxy
|
|
78
|
-
* when one is configured via the
|
|
51
|
+
* when one is configured via the standard proxy env vars (`HTTPS_PROXY`,
|
|
52
|
+
* `HTTP_PROXY`, `ALL_PROXY`, honoring `NO_PROXY`).
|
|
79
53
|
*
|
|
80
54
|
* Node's built-in `fetch` (and therefore MCP's `StreamableHTTPClientTransport`)
|
|
81
55
|
* does not honor `HTTPS_PROXY` / `HTTP_PROXY` on its own. Callers that need
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cargo-ai/cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.37",
|
|
4
4
|
"private": false,
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"description": "Command-line interface for the Cargo API",
|
|
@@ -30,17 +30,15 @@
|
|
|
30
30
|
"format:check": "prettier --check ."
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@cargo-ai/api": "^1.0.
|
|
33
|
+
"@cargo-ai/api": "^1.0.47",
|
|
34
34
|
"@cargo-ai/app-sdk": "^1.0.5",
|
|
35
35
|
"@cargo-ai/cdk": "*",
|
|
36
36
|
"@cargo-ai/types": "*",
|
|
37
|
-
"@cargo-ai/worker-sdk": "^1.0.
|
|
37
|
+
"@cargo-ai/worker-sdk": "^1.0.10",
|
|
38
38
|
"@modelcontextprotocol/sdk": "1.29.0",
|
|
39
39
|
"commander": "^12.1.0",
|
|
40
|
-
"http-proxy-agent": "^9.1.0",
|
|
41
|
-
"https-proxy-agent": "^9.1.0",
|
|
42
40
|
"tsx": "^4.19.2",
|
|
43
|
-
"undici": "^7.
|
|
41
|
+
"undici": "^7.28.0"
|
|
44
42
|
},
|
|
45
43
|
"devDependencies": {
|
|
46
44
|
"@cargo-ai/eslint-config": "*",
|