@orchagent/cli 0.3.100 → 0.3.102
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/dist/commands/agent-keys.js +5 -9
- package/dist/commands/diff.js +4 -2
- package/dist/commands/docs.js +6 -1
- package/dist/commands/fork.js +2 -1
- package/dist/commands/init.js +28 -25
- package/dist/commands/install.js +18 -30
- package/dist/commands/logs.js +3 -1
- package/dist/commands/publish.js +117 -4
- package/dist/commands/pull.js +27 -39
- package/dist/commands/replay.js +40 -7
- package/dist/commands/run.js +60 -96
- package/dist/commands/schedule.js +39 -5
- package/dist/commands/security.js +9 -25
- package/dist/commands/templates/cron-job.js +1 -1
- package/dist/commands/templates/github-weekly-summary.js +1 -1
- package/dist/commands/test.js +2 -2
- package/dist/commands/transfer.js +15 -5
- package/dist/commands/tree.js +15 -3
- package/dist/commands/validate.js +9 -0
- package/dist/lib/bundle.js +7 -1
- package/dist/lib/llm.js +37 -1
- package/dist/lib/resolve-agent.js +62 -0
- package/package.json +1 -1
|
@@ -162,6 +162,7 @@ function registerScheduleCommand(program) {
|
|
|
162
162
|
.option('--alert-webhook <url>', 'Webhook URL to POST on failure (HTTPS required)')
|
|
163
163
|
.option('--alert-on-failure-count <n>', 'Number of consecutive failures before alerting (default: 3)', parseInt)
|
|
164
164
|
.option('--workspace <slug>', 'Workspace slug (default: current workspace)')
|
|
165
|
+
.option('--json', 'Output as JSON')
|
|
165
166
|
.action(async (agentArg, options) => {
|
|
166
167
|
const config = await (0, config_1.getResolvedConfig)();
|
|
167
168
|
if (!config.apiKey) {
|
|
@@ -217,6 +218,10 @@ function registerScheduleCommand(program) {
|
|
|
217
218
|
body: JSON.stringify(body),
|
|
218
219
|
headers: { 'Content-Type': 'application/json' },
|
|
219
220
|
});
|
|
221
|
+
if (options.json) {
|
|
222
|
+
(0, output_1.printJson)(result);
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
220
225
|
const s = result.schedule;
|
|
221
226
|
process.stdout.write(chalk_1.default.green('\u2713') + ` Schedule created\n\n`);
|
|
222
227
|
process.stdout.write(` ID: ${s.id}\n`);
|
|
@@ -264,6 +269,7 @@ function registerScheduleCommand(program) {
|
|
|
264
269
|
.option('--alert-on-failure-count <n>', 'Number of consecutive failures before alerting', parseInt)
|
|
265
270
|
.option('--clear-alert-webhook', 'Remove the alert webhook URL')
|
|
266
271
|
.option('--workspace <slug>', 'Workspace slug (default: current workspace)')
|
|
272
|
+
.option('--json', 'Output as JSON')
|
|
267
273
|
.action(async (partialScheduleId, options) => {
|
|
268
274
|
const config = await (0, config_1.getResolvedConfig)();
|
|
269
275
|
if (!config.apiKey) {
|
|
@@ -322,6 +328,10 @@ function registerScheduleCommand(program) {
|
|
|
322
328
|
body: JSON.stringify(updates),
|
|
323
329
|
headers: { 'Content-Type': 'application/json' },
|
|
324
330
|
});
|
|
331
|
+
if (options.json) {
|
|
332
|
+
(0, output_1.printJson)(result);
|
|
333
|
+
return;
|
|
334
|
+
}
|
|
325
335
|
const s = result.schedule;
|
|
326
336
|
process.stdout.write(chalk_1.default.green('\u2713') + ` Schedule updated\n\n`);
|
|
327
337
|
process.stdout.write(` ID: ${s.id}\n`);
|
|
@@ -349,6 +359,7 @@ function registerScheduleCommand(program) {
|
|
|
349
359
|
.description('Delete a schedule')
|
|
350
360
|
.option('-y, --yes', 'Skip confirmation prompt')
|
|
351
361
|
.option('--workspace <slug>', 'Workspace slug (default: current workspace)')
|
|
362
|
+
.option('--json', 'Output as JSON (implies --yes)')
|
|
352
363
|
.action(async (partialScheduleId, options) => {
|
|
353
364
|
const config = await (0, config_1.getResolvedConfig)();
|
|
354
365
|
if (!config.apiKey) {
|
|
@@ -356,7 +367,7 @@ function registerScheduleCommand(program) {
|
|
|
356
367
|
}
|
|
357
368
|
const workspaceId = await resolveWorkspaceId(config, options.workspace);
|
|
358
369
|
const scheduleId = await resolveScheduleId(config, partialScheduleId, workspaceId);
|
|
359
|
-
if (!options.yes) {
|
|
370
|
+
if (!options.yes && !options.json) {
|
|
360
371
|
const rl = promises_1.default.createInterface({
|
|
361
372
|
input: process.stdin,
|
|
362
373
|
output: process.stdout,
|
|
@@ -368,7 +379,11 @@ function registerScheduleCommand(program) {
|
|
|
368
379
|
return;
|
|
369
380
|
}
|
|
370
381
|
}
|
|
371
|
-
await (0, api_1.request)(config, 'DELETE', `/workspaces/${workspaceId}/schedules/${scheduleId}`);
|
|
382
|
+
const result = await (0, api_1.request)(config, 'DELETE', `/workspaces/${workspaceId}/schedules/${scheduleId}`);
|
|
383
|
+
if (options.json) {
|
|
384
|
+
(0, output_1.printJson)({ ...result, id: scheduleId });
|
|
385
|
+
return;
|
|
386
|
+
}
|
|
372
387
|
process.stdout.write(chalk_1.default.green('\u2713') + ` Schedule ${scheduleId} deleted\n`);
|
|
373
388
|
});
|
|
374
389
|
// orch schedule trigger <schedule-id>
|
|
@@ -378,6 +393,7 @@ function registerScheduleCommand(program) {
|
|
|
378
393
|
.option('--data <json>', 'Override input data as JSON')
|
|
379
394
|
.addOption(new commander_1.Option('--input <json>').hideHelp())
|
|
380
395
|
.option('--workspace <slug>', 'Workspace slug (default: current workspace)')
|
|
396
|
+
.option('--json', 'Output as JSON')
|
|
381
397
|
.action(async (partialScheduleId, options) => {
|
|
382
398
|
const config = await (0, config_1.getResolvedConfig)();
|
|
383
399
|
if (!config.apiKey) {
|
|
@@ -396,11 +412,17 @@ function registerScheduleCommand(program) {
|
|
|
396
412
|
throw new errors_1.CliError('Invalid JSON in --data');
|
|
397
413
|
}
|
|
398
414
|
}
|
|
399
|
-
|
|
415
|
+
if (!options.json) {
|
|
416
|
+
process.stdout.write('Triggering schedule...\n');
|
|
417
|
+
}
|
|
400
418
|
const result = await (0, api_1.request)(config, 'POST', `/workspaces/${workspaceId}/schedules/${scheduleId}/trigger`, body ? {
|
|
401
419
|
body,
|
|
402
420
|
headers: { 'Content-Type': 'application/json' },
|
|
403
421
|
} : {});
|
|
422
|
+
if (options.json) {
|
|
423
|
+
(0, output_1.printJson)(result);
|
|
424
|
+
return;
|
|
425
|
+
}
|
|
404
426
|
// Status-aware header message
|
|
405
427
|
const isAsync = result.status === 'queued' || result.status === 'deduplicated';
|
|
406
428
|
if (isAsync) {
|
|
@@ -565,6 +587,7 @@ function registerScheduleCommand(program) {
|
|
|
565
587
|
.command('test-alert <schedule-id>')
|
|
566
588
|
.description('Send a test alert to the schedule\'s configured webhook URL')
|
|
567
589
|
.option('--workspace <slug>', 'Workspace slug (default: current workspace)')
|
|
590
|
+
.option('--json', 'Output as JSON')
|
|
568
591
|
.action(async (partialScheduleId, options) => {
|
|
569
592
|
const config = await (0, config_1.getResolvedConfig)();
|
|
570
593
|
if (!config.apiKey) {
|
|
@@ -572,8 +595,14 @@ function registerScheduleCommand(program) {
|
|
|
572
595
|
}
|
|
573
596
|
const workspaceId = await resolveWorkspaceId(config, options.workspace);
|
|
574
597
|
const scheduleId = await resolveScheduleId(config, partialScheduleId, workspaceId);
|
|
575
|
-
|
|
598
|
+
if (!options.json) {
|
|
599
|
+
process.stdout.write('Sending test alert...\n');
|
|
600
|
+
}
|
|
576
601
|
const result = await (0, api_1.request)(config, 'POST', `/workspaces/${workspaceId}/schedules/${scheduleId}/test-alert`);
|
|
602
|
+
if (options.json) {
|
|
603
|
+
(0, output_1.printJson)({ ...result, schedule_id: scheduleId });
|
|
604
|
+
return;
|
|
605
|
+
}
|
|
577
606
|
if (result.success) {
|
|
578
607
|
process.stdout.write(chalk_1.default.green('\u2713') + ' Test alert delivered successfully\n');
|
|
579
608
|
}
|
|
@@ -587,6 +616,7 @@ function registerScheduleCommand(program) {
|
|
|
587
616
|
.description('Regenerate the webhook secret (invalidates old URL)')
|
|
588
617
|
.option('--workspace <slug>', 'Workspace slug (default: current workspace)')
|
|
589
618
|
.option('-y, --yes', 'Skip confirmation prompt')
|
|
619
|
+
.option('--json', 'Output as JSON (implies --yes)')
|
|
590
620
|
.action(async (partialScheduleId, options) => {
|
|
591
621
|
const config = await (0, config_1.getResolvedConfig)();
|
|
592
622
|
if (!config.apiKey) {
|
|
@@ -594,7 +624,7 @@ function registerScheduleCommand(program) {
|
|
|
594
624
|
}
|
|
595
625
|
const workspaceId = await resolveWorkspaceId(config, options.workspace);
|
|
596
626
|
const scheduleId = await resolveScheduleId(config, partialScheduleId, workspaceId);
|
|
597
|
-
if (!options.yes) {
|
|
627
|
+
if (!options.yes && !options.json) {
|
|
598
628
|
const rl = promises_1.default.createInterface({
|
|
599
629
|
input: process.stdin,
|
|
600
630
|
output: process.stdout,
|
|
@@ -609,6 +639,10 @@ function registerScheduleCommand(program) {
|
|
|
609
639
|
}
|
|
610
640
|
}
|
|
611
641
|
const result = await (0, api_1.request)(config, 'POST', `/workspaces/${workspaceId}/schedules/${scheduleId}/regenerate-webhook`);
|
|
642
|
+
if (options.json) {
|
|
643
|
+
(0, output_1.printJson)({ ...result, schedule_id: scheduleId });
|
|
644
|
+
return;
|
|
645
|
+
}
|
|
612
646
|
process.stdout.write(chalk_1.default.green('\u2713') + ' Webhook secret regenerated\n\n');
|
|
613
647
|
process.stdout.write(` ${chalk_1.default.bold('New Webhook URL')} (save this — retrieve later with ${chalk_1.default.cyan('orch schedule info --reveal')}):\n`);
|
|
614
648
|
process.stdout.write(` ${result.webhook_url}\n\n`);
|
|
@@ -11,26 +11,11 @@ const chalk_1 = __importDefault(require("chalk"));
|
|
|
11
11
|
const config_1 = require("../lib/config");
|
|
12
12
|
const api_1 = require("../lib/api");
|
|
13
13
|
const errors_1 = require("../lib/errors");
|
|
14
|
+
const resolve_agent_1 = require("../lib/resolve-agent");
|
|
14
15
|
const output_1 = require("../lib/output");
|
|
15
16
|
const spinner_1 = require("../lib/spinner");
|
|
16
17
|
const llm_1 = require("../lib/llm");
|
|
17
18
|
const analytics_1 = require("../lib/analytics");
|
|
18
|
-
const DEFAULT_VERSION = 'latest';
|
|
19
|
-
function parseAgentRef(value) {
|
|
20
|
-
const [ref, versionPart] = value.split('@');
|
|
21
|
-
const version = versionPart?.trim() || DEFAULT_VERSION;
|
|
22
|
-
const segments = ref.split('/');
|
|
23
|
-
if (segments.length === 1) {
|
|
24
|
-
return { agent: segments[0], version };
|
|
25
|
-
}
|
|
26
|
-
if (segments.length === 2) {
|
|
27
|
-
return { org: segments[0], agent: segments[1], version };
|
|
28
|
-
}
|
|
29
|
-
if (segments.length === 3) {
|
|
30
|
-
return { org: segments[0], agent: segments[1], version: segments[2] };
|
|
31
|
-
}
|
|
32
|
-
throw new errors_1.CliError('Invalid agent reference. Use org/agent/version or org/agent@version format.');
|
|
33
|
-
}
|
|
34
19
|
// Severity color mapping
|
|
35
20
|
function severityColor(severity) {
|
|
36
21
|
switch (severity.toLowerCase()) {
|
|
@@ -189,15 +174,8 @@ Examples:
|
|
|
189
174
|
if (!resolved.apiKey) {
|
|
190
175
|
throw new errors_1.CliError('Missing API key. Run `orchagent login` first.');
|
|
191
176
|
}
|
|
192
|
-
const
|
|
193
|
-
const
|
|
194
|
-
const org = parsed.org ?? configFile.workspace ?? resolved.defaultOrg;
|
|
195
|
-
if (!org) {
|
|
196
|
-
throw new errors_1.CliError('Missing org. Use org/agent or set default org.');
|
|
197
|
-
}
|
|
198
|
-
const agentId = `${org}/${parsed.agent}/${parsed.version}`;
|
|
199
|
-
// Resolve workspace context for the target org
|
|
200
|
-
const workspaceId = await (0, api_1.resolveWorkspaceIdForOrg)(resolved, org);
|
|
177
|
+
const { org, agent: agentName, version, workspaceId } = await (0, resolve_agent_1.resolveAgentContext)(agentRef, resolved);
|
|
178
|
+
const agentId = `${org}/${agentName}/${version}`;
|
|
201
179
|
// Detect LLM key for the scan
|
|
202
180
|
let llmKey;
|
|
203
181
|
let llmProvider;
|
|
@@ -235,6 +213,12 @@ Examples:
|
|
|
235
213
|
if (options.maxAttacks) {
|
|
236
214
|
requestBody.max_attacks = options.maxAttacks;
|
|
237
215
|
}
|
|
216
|
+
// Send provider preference so gateway can narrow vault key search
|
|
217
|
+
// (even when no local key is found, the gateway resolves from vault)
|
|
218
|
+
const effectiveProvider = llmProvider || options.provider;
|
|
219
|
+
if (effectiveProvider) {
|
|
220
|
+
requestBody.llm_provider = effectiveProvider;
|
|
221
|
+
}
|
|
238
222
|
const url = `${resolved.apiUrl.replace(/\/$/, '')}/security/test`;
|
|
239
223
|
// Make the API call with a spinner
|
|
240
224
|
const spinner = (0, spinner_1.createSpinner)(`Scanning ${agentId} for vulnerabilities...`);
|
|
@@ -14,7 +14,7 @@ exports.TEMPLATE_MANIFEST = `{
|
|
|
14
14
|
"type": "agent",
|
|
15
15
|
"description": "Weekly GitHub activity summary delivered to Discord. Uses Claude to analyse commits, PRs, and issues — surfaces patterns, risks, and trends.",
|
|
16
16
|
"runtime": {
|
|
17
|
-
"command": "
|
|
17
|
+
"command": "python3 main.py"
|
|
18
18
|
},
|
|
19
19
|
"required_secrets": [
|
|
20
20
|
"ORCHAGENT_API_KEY",
|
package/dist/commands/test.js
CHANGED
|
@@ -640,7 +640,7 @@ function runEntrypointWithInput(agentDir, entrypoint, stdinData, verbose) {
|
|
|
640
640
|
/**
|
|
641
641
|
* Run fixture tests for code_runtime agents by executing the entrypoint
|
|
642
642
|
* with fixture input as stdin and validating the JSON output.
|
|
643
|
-
* Same interface as E2B:
|
|
643
|
+
* Same interface as E2B: python3 main.py < input.json
|
|
644
644
|
*/
|
|
645
645
|
async function runCodeRuntimeFixtureTests(agentDir, fixtures, entrypoint, verbose) {
|
|
646
646
|
process.stderr.write(chalk_1.default.blue('\nRunning fixture tests (code runtime)...\n\n'));
|
|
@@ -660,7 +660,7 @@ async function runCodeRuntimeFixtureTests(agentDir, fixtures, entrypoint, verbos
|
|
|
660
660
|
throw new errors_1.CliError(`Invalid JSON in ${fixtureName}: ${e.message}`);
|
|
661
661
|
}
|
|
662
662
|
const fixture = validateFixture(parsed, fixturePath);
|
|
663
|
-
// Run entrypoint with fixture input as stdin (same as E2B:
|
|
663
|
+
// Run entrypoint with fixture input as stdin (same as E2B: python3 main.py < input.json)
|
|
664
664
|
const inputJson = JSON.stringify(fixture.input);
|
|
665
665
|
const result = await runEntrypointWithInput(agentDir, entrypoint, inputJson, verbose);
|
|
666
666
|
if (result.code !== 0) {
|
|
@@ -8,6 +8,7 @@ const promises_1 = __importDefault(require("readline/promises"));
|
|
|
8
8
|
const chalk_1 = __importDefault(require("chalk"));
|
|
9
9
|
const config_1 = require("../lib/config");
|
|
10
10
|
const api_1 = require("../lib/api");
|
|
11
|
+
const agent_ref_1 = require("../lib/agent-ref");
|
|
11
12
|
const errors_1 = require("../lib/errors");
|
|
12
13
|
const analytics_1 = require("../lib/analytics");
|
|
13
14
|
const output_1 = require("../lib/output");
|
|
@@ -34,7 +35,7 @@ async function promptText(message) {
|
|
|
34
35
|
}
|
|
35
36
|
function registerTransferCommand(program) {
|
|
36
37
|
program
|
|
37
|
-
.command('transfer <agent
|
|
38
|
+
.command('transfer <agent>')
|
|
38
39
|
.description('Transfer an agent to another workspace')
|
|
39
40
|
.requiredOption('--to <workspace-slug>', 'Target workspace slug')
|
|
40
41
|
.option('-w, --workspace <workspace-slug>', 'Source workspace slug (defaults to active workspace)')
|
|
@@ -43,12 +44,13 @@ function registerTransferCommand(program) {
|
|
|
43
44
|
.option('--json', 'Output result as JSON')
|
|
44
45
|
.addHelpText('after', `
|
|
45
46
|
Examples:
|
|
46
|
-
orch transfer my-agent --to team-workspace # Transfer
|
|
47
|
+
orch transfer my-agent --to team-workspace # Transfer by name
|
|
48
|
+
orch transfer my-org/my-agent --to team-workspace # Transfer using org/agent format
|
|
47
49
|
orch transfer my-agent --to team-workspace --workspace my-team
|
|
48
50
|
orch transfer my-agent --to team-workspace --dry-run # Preview transfer
|
|
49
51
|
orch transfer my-agent --to team-workspace --yes # Skip confirmation
|
|
50
52
|
`)
|
|
51
|
-
.action(async (
|
|
53
|
+
.action(async (agentArg, options) => {
|
|
52
54
|
const write = (message) => {
|
|
53
55
|
if (!options.json)
|
|
54
56
|
process.stdout.write(message);
|
|
@@ -58,6 +60,14 @@ Examples:
|
|
|
58
60
|
if (!config.apiKey) {
|
|
59
61
|
throw new errors_1.CliError('Not logged in. Run `orchagent login` first.');
|
|
60
62
|
}
|
|
63
|
+
// Parse org/agent[@version] or bare agent name
|
|
64
|
+
const parsed = (0, agent_ref_1.parseAgentRef)(agentArg);
|
|
65
|
+
const agentName = parsed.agent;
|
|
66
|
+
// If org was provided via org/agent format, use it as source workspace
|
|
67
|
+
// --workspace flag takes precedence if both are given
|
|
68
|
+
if (parsed.org && options.workspace && parsed.org !== options.workspace) {
|
|
69
|
+
throw new errors_1.CliError(`Conflicting source workspace: '${parsed.org}' (from agent ref) vs '${options.workspace}' (from --workspace flag).`);
|
|
70
|
+
}
|
|
61
71
|
write('Finding agent and workspaces...\n');
|
|
62
72
|
// Fetch workspace list first (needed to resolve source/target IDs).
|
|
63
73
|
const workspacesResponse = await (0, api_1.request)(config, 'GET', '/workspaces');
|
|
@@ -66,8 +76,8 @@ Examples:
|
|
|
66
76
|
if (!targetWorkspace) {
|
|
67
77
|
throw new errors_1.CliError(`Workspace '${options.to}' not found. Run \`orchagent workspace list\` to see available workspaces.`);
|
|
68
78
|
}
|
|
69
|
-
// Resolve source workspace
|
|
70
|
-
const sourceWorkspaceSlug = options.workspace ?? configFile.workspace;
|
|
79
|
+
// Resolve source workspace: --workspace flag > org from ref > config workspace
|
|
80
|
+
const sourceWorkspaceSlug = options.workspace ?? parsed.org ?? configFile.workspace;
|
|
71
81
|
const sourceWorkspace = sourceWorkspaceSlug
|
|
72
82
|
? workspacesResponse.workspaces.find((w) => w.slug === sourceWorkspaceSlug)
|
|
73
83
|
: null;
|
package/dist/commands/tree.js
CHANGED
|
@@ -27,9 +27,21 @@ function registerTreeCommand(program) {
|
|
|
27
27
|
throw new errors_1.CliError('Missing org. Use org/agent format or set default org.');
|
|
28
28
|
}
|
|
29
29
|
const { agent, version } = parsed;
|
|
30
|
-
//
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
// Public-first fallback: try public tree endpoint (works for any public
|
|
31
|
+
// agent regardless of caller context), then fall back to authenticated
|
|
32
|
+
// endpoint with workspace header for private agents. Matches the pattern
|
|
33
|
+
// used by info/fork/estimate commands. (T12-04)
|
|
34
|
+
let tree;
|
|
35
|
+
try {
|
|
36
|
+
tree = await (0, api_1.publicRequest)(config, `/public/agents/${org}/${agent}/${version}/tree`);
|
|
37
|
+
}
|
|
38
|
+
catch (err) {
|
|
39
|
+
if (!(err instanceof api_1.ApiError) || err.status !== 404)
|
|
40
|
+
throw err;
|
|
41
|
+
// Public endpoint returned 404 — try authenticated endpoint for private agents
|
|
42
|
+
const workspaceId = await (0, api_1.resolveWorkspaceIdForOrg)(config, org);
|
|
43
|
+
tree = await (0, api_1.request)(config, 'GET', `/agents/${org}/${agent}/${version}/tree`, workspaceId ? { headers: { 'X-Workspace-Id': workspaceId } } : undefined);
|
|
44
|
+
}
|
|
33
45
|
if (options.json) {
|
|
34
46
|
console.log(JSON.stringify(tree, null, 2));
|
|
35
47
|
return;
|
|
@@ -172,6 +172,7 @@ Options:
|
|
|
172
172
|
const org = await (0, api_1.getOrg)(config, workspaceId);
|
|
173
173
|
const depResults = await (0, publish_1.checkDependencies)(config, deps, org.slug, workspaceId);
|
|
174
174
|
const notFound = depResults.filter(r => r.status === 'not_found');
|
|
175
|
+
const notFoundCrossOrg = depResults.filter(r => r.status === 'not_found_cross_org');
|
|
175
176
|
const notCallable = depResults.filter(r => r.status === 'found_not_callable');
|
|
176
177
|
if (notFound.length > 0) {
|
|
177
178
|
for (const dep of notFound) {
|
|
@@ -181,6 +182,14 @@ Options:
|
|
|
181
182
|
});
|
|
182
183
|
}
|
|
183
184
|
}
|
|
185
|
+
if (notFoundCrossOrg.length > 0) {
|
|
186
|
+
for (const dep of notFoundCrossOrg) {
|
|
187
|
+
serverIssues.push({
|
|
188
|
+
level: 'warning',
|
|
189
|
+
message: `Dependency not found (unpublished or not accessible from this workspace): ${dep.ref}`,
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
}
|
|
184
193
|
if (notCallable.length > 0) {
|
|
185
194
|
for (const dep of notCallable) {
|
|
186
195
|
serverIssues.push({
|
package/dist/lib/bundle.js
CHANGED
|
@@ -137,18 +137,23 @@ async function createCodeBundle(sourceDir, outputPath, options = {}) {
|
|
|
137
137
|
const output = (0, fs_1.createWriteStream)(outputPath);
|
|
138
138
|
const archive = (0, archiver_1.default)('zip', { zlib: { level: 9 } });
|
|
139
139
|
let fileCount = 0;
|
|
140
|
+
const files = [];
|
|
140
141
|
output.on('close', () => {
|
|
141
142
|
resolve({
|
|
142
143
|
path: outputPath,
|
|
143
144
|
sizeBytes: archive.pointer(),
|
|
144
145
|
fileCount,
|
|
146
|
+
files,
|
|
145
147
|
});
|
|
146
148
|
});
|
|
147
149
|
archive.on('error', (err) => {
|
|
148
150
|
reject(err);
|
|
149
151
|
});
|
|
150
|
-
archive.on('entry', () => {
|
|
152
|
+
archive.on('entry', (entry) => {
|
|
151
153
|
fileCount++;
|
|
154
|
+
if (entry.name) {
|
|
155
|
+
files.push(entry.name);
|
|
156
|
+
}
|
|
152
157
|
});
|
|
153
158
|
archive.pipe(output);
|
|
154
159
|
// Add directory contents with exclusions
|
|
@@ -235,6 +240,7 @@ async function previewBundle(sourceDir, options = {}) {
|
|
|
235
240
|
totalSizeBytes,
|
|
236
241
|
entrypoint,
|
|
237
242
|
excludePatterns,
|
|
243
|
+
files,
|
|
238
244
|
};
|
|
239
245
|
}
|
|
240
246
|
/**
|
package/dist/lib/llm.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* Used by run, call, and skill commands.
|
|
7
7
|
*/
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.DEFAULT_MODELS = exports.PROVIDER_ENV_VARS = exports.LlmError = void 0;
|
|
9
|
+
exports.MODEL_PROVIDER_PATTERNS = exports.DEFAULT_MODELS = exports.PROVIDER_ENV_VARS = exports.LlmError = void 0;
|
|
10
10
|
exports.isRateLimitError = isRateLimitError;
|
|
11
11
|
exports.detectLlmKeyFromEnv = detectLlmKeyFromEnv;
|
|
12
12
|
exports.detectLlmKey = detectLlmKey;
|
|
@@ -15,6 +15,8 @@ exports.buildPrompt = buildPrompt;
|
|
|
15
15
|
exports.callLlm = callLlm;
|
|
16
16
|
exports.callLlmWithFallback = callLlmWithFallback;
|
|
17
17
|
exports.validateProvider = validateProvider;
|
|
18
|
+
exports.detectProviderFromModel = detectProviderFromModel;
|
|
19
|
+
exports.warnProviderModelMismatch = warnProviderModelMismatch;
|
|
18
20
|
const errors_1 = require("./errors");
|
|
19
21
|
const llm_errors_1 = require("./llm-errors");
|
|
20
22
|
class LlmError extends errors_1.CliError {
|
|
@@ -265,3 +267,37 @@ function validateProvider(provider) {
|
|
|
265
267
|
throw new errors_1.CliError(`Invalid provider: ${provider}. Valid: ${validProviders.join(', ')}`);
|
|
266
268
|
}
|
|
267
269
|
}
|
|
270
|
+
/**
|
|
271
|
+
* Model-name patterns for auto-detecting the LLM provider.
|
|
272
|
+
* Tested against the lowercased model string.
|
|
273
|
+
*/
|
|
274
|
+
exports.MODEL_PROVIDER_PATTERNS = {
|
|
275
|
+
openai: /^(gpt-|o1-|o3-|o4-|davinci|text-)/,
|
|
276
|
+
anthropic: /^claude-/,
|
|
277
|
+
gemini: /^gemini-/,
|
|
278
|
+
ollama: /^(llama|mistral|deepseek|phi|qwen)/,
|
|
279
|
+
};
|
|
280
|
+
/**
|
|
281
|
+
* Auto-detect the LLM provider from a model name using prefix patterns.
|
|
282
|
+
* Returns the provider string if a match is found, or null if ambiguous/unknown.
|
|
283
|
+
*/
|
|
284
|
+
function detectProviderFromModel(model) {
|
|
285
|
+
const modelLower = model.toLowerCase();
|
|
286
|
+
for (const [provider, pattern] of Object.entries(exports.MODEL_PROVIDER_PATTERNS)) {
|
|
287
|
+
if (pattern.test(modelLower)) {
|
|
288
|
+
return provider;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
return null;
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Warn if a model name doesn't match the expected provider's pattern.
|
|
295
|
+
* Used when both --model and --provider are explicitly specified.
|
|
296
|
+
*/
|
|
297
|
+
function warnProviderModelMismatch(model, provider) {
|
|
298
|
+
const modelLower = model.toLowerCase();
|
|
299
|
+
const expectedPattern = exports.MODEL_PROVIDER_PATTERNS[provider];
|
|
300
|
+
if (expectedPattern && !expectedPattern.test(modelLower)) {
|
|
301
|
+
process.stderr.write(`Warning: Model '${model}' may not be a ${provider} model.\n\n`);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.resolveOrg = resolveOrg;
|
|
4
|
+
exports.resolveAgentContext = resolveAgentContext;
|
|
5
|
+
const agent_ref_1 = require("./agent-ref");
|
|
6
|
+
const config_1 = require("./config");
|
|
7
|
+
const api_1 = require("./api");
|
|
8
|
+
const errors_1 = require("./errors");
|
|
9
|
+
/**
|
|
10
|
+
* Resolve the org from a parsed AgentRef using the standard fallback chain:
|
|
11
|
+
* 1. Explicit org from ref (org/agent@version)
|
|
12
|
+
* 2. Workspace from config file
|
|
13
|
+
* 3. defaultOrg from resolved config
|
|
14
|
+
*
|
|
15
|
+
* Throws CliError if no org can be determined.
|
|
16
|
+
*/
|
|
17
|
+
async function resolveOrg(parsed, config, options) {
|
|
18
|
+
if (parsed.org)
|
|
19
|
+
return parsed.org;
|
|
20
|
+
const configFile = await (0, config_1.loadConfig)();
|
|
21
|
+
const org = configFile.workspace ?? config.defaultOrg;
|
|
22
|
+
if (!org) {
|
|
23
|
+
throw new errors_1.CliError(options?.missingOrgMessage ??
|
|
24
|
+
'Missing org. Use org/agent format or set default org.');
|
|
25
|
+
}
|
|
26
|
+
return org;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Central agent-reference resolution pipeline used by all commands.
|
|
30
|
+
*
|
|
31
|
+
* Takes a raw agent reference string (e.g., "org/agent@v2", "agent", "agent@latest")
|
|
32
|
+
* and resolves it to a full context with org, agent name, version, and workspace ID.
|
|
33
|
+
*
|
|
34
|
+
* Resolution steps:
|
|
35
|
+
* 1. Parse the ref string into { org?, agent, version }
|
|
36
|
+
* 2. Resolve org via fallback chain: ref → config workspace → defaultOrg
|
|
37
|
+
* 3. Resolve workspace ID for team workspace context (optional)
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* const ctx = await resolveAgentContext('acme/my-agent@v2', config)
|
|
41
|
+
* // ctx = { org: 'acme', agent: 'my-agent', version: 'v2', workspaceId: 'ws-123' }
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* const ctx = await resolveAgentContext('my-agent', config)
|
|
45
|
+
* // ctx = { org: 'default-org', agent: 'my-agent', version: 'latest', workspaceId: undefined }
|
|
46
|
+
*/
|
|
47
|
+
async function resolveAgentContext(agentRefString, config, options) {
|
|
48
|
+
const parsed = (0, agent_ref_1.parseAgentRef)(agentRefString);
|
|
49
|
+
const org = await resolveOrg(parsed, config, {
|
|
50
|
+
missingOrgMessage: options?.missingOrgMessage,
|
|
51
|
+
});
|
|
52
|
+
let workspaceId;
|
|
53
|
+
if (!options?.skipWorkspaceResolution) {
|
|
54
|
+
workspaceId = await (0, api_1.resolveWorkspaceIdForOrg)(config, org);
|
|
55
|
+
}
|
|
56
|
+
return {
|
|
57
|
+
org,
|
|
58
|
+
agent: parsed.agent,
|
|
59
|
+
version: parsed.version,
|
|
60
|
+
workspaceId,
|
|
61
|
+
};
|
|
62
|
+
}
|
package/package.json
CHANGED