@orchagent/cli 0.3.99 → 0.3.101
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 +11 -15
- package/dist/commands/diff.js +4 -2
- package/dist/commands/docs.js +6 -1
- package/dist/commands/estimate.js +2 -1
- package/dist/commands/fork.js +2 -1
- package/dist/commands/init.js +15 -8
- package/dist/commands/install.js +18 -30
- package/dist/commands/logs.js +3 -1
- package/dist/commands/publish.js +28 -2
- package/dist/commands/pull.js +11 -29
- package/dist/commands/replay.js +40 -7
- package/dist/commands/run.js +45 -72
- package/dist/commands/schedule.js +39 -5
- package/dist/commands/security.js +19 -24
- package/dist/commands/test.js +12 -3
- package/dist/commands/transfer.js +15 -5
- package/dist/commands/tree.js +15 -1
- package/dist/lib/api.js +30 -14
- package/dist/lib/bundle.js +7 -1
- package/dist/lib/resolve-agent.js +62 -0
- package/package.json +1 -1
|
@@ -9,18 +9,14 @@ const config_1 = require("../lib/config");
|
|
|
9
9
|
const api_1 = require("../lib/api");
|
|
10
10
|
const errors_1 = require("../lib/errors");
|
|
11
11
|
const key_store_1 = require("../lib/key-store");
|
|
12
|
+
const resolve_agent_1 = require("../lib/resolve-agent");
|
|
12
13
|
/**
|
|
13
14
|
* Resolve an agent reference ("org/agent" or just "agent") to an agent ID.
|
|
14
|
-
* Uses the
|
|
15
|
+
* Uses the shared resolveAgentContext() for parsing and org/workspace resolution,
|
|
16
|
+
* then finds the latest version via the authenticated list-agents endpoint.
|
|
15
17
|
*/
|
|
16
18
|
async function resolveAgentId(config, ref) {
|
|
17
|
-
const
|
|
18
|
-
const agentName = parts.length >= 2 ? parts[1] : parts[0];
|
|
19
|
-
const orgSlug = parts.length >= 2 ? parts[0] : undefined;
|
|
20
|
-
// Resolve workspace context from org slug or config
|
|
21
|
-
const configFile = await (0, config_1.loadConfig)();
|
|
22
|
-
const resolvedOrg = orgSlug ?? configFile.workspace ?? config.defaultOrg;
|
|
23
|
-
const workspaceId = resolvedOrg ? await (0, api_1.resolveWorkspaceIdForOrg)(config, resolvedOrg) : undefined;
|
|
19
|
+
const { org, agent: agentName, workspaceId } = await (0, resolve_agent_1.resolveAgentContext)(ref, config);
|
|
24
20
|
const agents = await (0, api_1.listMyAgents)(config, workspaceId);
|
|
25
21
|
const matching = agents.filter(a => a.name === agentName);
|
|
26
22
|
if (matching.length === 0) {
|
|
@@ -28,7 +24,7 @@ async function resolveAgentId(config, ref) {
|
|
|
28
24
|
}
|
|
29
25
|
// Use the latest version
|
|
30
26
|
const latest = matching.sort((a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime())[0];
|
|
31
|
-
return { agent: latest, agentId: latest.id, orgSlug: latest.org_slug ??
|
|
27
|
+
return { agent: latest, agentId: latest.id, orgSlug: latest.org_slug ?? org, workspaceId };
|
|
32
28
|
}
|
|
33
29
|
function registerAgentKeysCommand(program) {
|
|
34
30
|
const agentKeys = program
|
|
@@ -42,8 +38,8 @@ function registerAgentKeysCommand(program) {
|
|
|
42
38
|
if (!config.apiKey) {
|
|
43
39
|
throw new errors_1.CliError('Missing API key. Run `orchagent login` first.');
|
|
44
40
|
}
|
|
45
|
-
const { agent, agentId, orgSlug } = await resolveAgentId(config, ref);
|
|
46
|
-
const result = await (0, api_1.listAgentKeys)(config, agentId);
|
|
41
|
+
const { agent, agentId, orgSlug, workspaceId } = await resolveAgentId(config, ref);
|
|
42
|
+
const result = await (0, api_1.listAgentKeys)(config, agentId, workspaceId);
|
|
47
43
|
// Load locally-saved keys for this agent
|
|
48
44
|
const localKeys = await (0, key_store_1.loadServiceKeys)(orgSlug, agent.name);
|
|
49
45
|
const localPrefixes = new Set(localKeys.map(k => k.prefix));
|
|
@@ -76,8 +72,8 @@ function registerAgentKeysCommand(program) {
|
|
|
76
72
|
if (!config.apiKey) {
|
|
77
73
|
throw new errors_1.CliError('Missing API key. Run `orchagent login` first.');
|
|
78
74
|
}
|
|
79
|
-
const { agent, orgSlug } = await resolveAgentId(config, ref);
|
|
80
|
-
const result = await (0, api_1.createAgentKey)(config, agent.id);
|
|
75
|
+
const { agent, orgSlug, workspaceId } = await resolveAgentId(config, ref);
|
|
76
|
+
const result = await (0, api_1.createAgentKey)(config, agent.id, workspaceId);
|
|
81
77
|
process.stdout.write(`\nNew service key for ${agent.name}:\n\n`);
|
|
82
78
|
process.stdout.write(` ${result.key}\n\n`);
|
|
83
79
|
try {
|
|
@@ -96,8 +92,8 @@ function registerAgentKeysCommand(program) {
|
|
|
96
92
|
if (!config.apiKey) {
|
|
97
93
|
throw new errors_1.CliError('Missing API key. Run `orchagent login` first.');
|
|
98
94
|
}
|
|
99
|
-
const { agent, agentId } = await resolveAgentId(config, ref);
|
|
100
|
-
await (0, api_1.deleteAgentKey)(config, agentId, keyId);
|
|
95
|
+
const { agent, agentId, workspaceId } = await resolveAgentId(config, ref);
|
|
96
|
+
await (0, api_1.deleteAgentKey)(config, agentId, keyId, workspaceId);
|
|
101
97
|
process.stdout.write(`Deleted key ${keyId} from ${agent.name}.\n`);
|
|
102
98
|
});
|
|
103
99
|
}
|
package/dist/commands/diff.js
CHANGED
|
@@ -246,8 +246,10 @@ function parseSecondRef(value, firstOrg, firstName) {
|
|
|
246
246
|
const parsed = (0, agent_ref_1.parseAgentRef)(value);
|
|
247
247
|
return { org: parsed.org ?? firstOrg, agent: parsed.agent, version: parsed.version };
|
|
248
248
|
}
|
|
249
|
-
// Otherwise treat as a version shorthand for the same agent
|
|
250
|
-
|
|
249
|
+
// Otherwise treat as a version shorthand for the same agent.
|
|
250
|
+
// Strip leading '@' — users naturally type `@v2` since the full form is `org/agent@v2`.
|
|
251
|
+
const version = value.startsWith('@') ? value.slice(1) : value;
|
|
252
|
+
return { org: firstOrg, agent: firstName, version };
|
|
251
253
|
}
|
|
252
254
|
// ── Command ────────────────────────────────────────────────────
|
|
253
255
|
function registerDiffCommand(program) {
|
package/dist/commands/docs.js
CHANGED
|
@@ -10,16 +10,21 @@ const DOCS_ROUTES = {
|
|
|
10
10
|
'': '/',
|
|
11
11
|
'cli': '/using-agents/cli-commands',
|
|
12
12
|
'agents': '/building-agents/agent-types',
|
|
13
|
+
'orchestration': '/building-agents/orchestration',
|
|
13
14
|
'skills': '/building-agents/orchestration',
|
|
14
15
|
'sdk': '/building-agents/sdk',
|
|
15
16
|
'api': '/api-reference/overview',
|
|
16
17
|
'quickstart': '/quickstart',
|
|
18
|
+
'scheduling': '/using-agents/scheduling',
|
|
19
|
+
'services': '/using-agents/services',
|
|
20
|
+
'security': '/concepts/security',
|
|
21
|
+
'billing': '/concepts/billing',
|
|
17
22
|
};
|
|
18
23
|
function registerDocsCommand(program) {
|
|
19
24
|
program
|
|
20
25
|
.command('docs')
|
|
21
26
|
.description('Open documentation in browser')
|
|
22
|
-
.argument('[topic]', 'Topic: cli, agents, skills, sdk, api, quickstart')
|
|
27
|
+
.argument('[topic]', 'Topic: cli, agents, orchestration, skills, sdk, api, quickstart, scheduling, services, security, billing')
|
|
23
28
|
.action(async (topic) => {
|
|
24
29
|
if (topic && !(topic in DOCS_ROUTES)) {
|
|
25
30
|
const validTopics = Object.keys(DOCS_ROUTES).filter(k => k).join(', ');
|
|
@@ -43,9 +43,10 @@ function registerEstimateCommand(program) {
|
|
|
43
43
|
process.exit(1);
|
|
44
44
|
}
|
|
45
45
|
const { agent, version } = parsed;
|
|
46
|
+
const workspaceId = await (0, api_1.resolveWorkspaceIdForOrg)(config, org);
|
|
46
47
|
let data;
|
|
47
48
|
try {
|
|
48
|
-
data = await (0, api_1.getAgentCostEstimate)(config, org, agent, version);
|
|
49
|
+
data = await (0, api_1.getAgentCostEstimate)(config, org, agent, version, workspaceId);
|
|
49
50
|
}
|
|
50
51
|
catch (err) {
|
|
51
52
|
if (err instanceof api_1.ApiError && err.status === 404) {
|
package/dist/commands/fork.js
CHANGED
|
@@ -81,8 +81,9 @@ Examples:
|
|
|
81
81
|
throw new errors_1.CliError('Missing org. Use org/agent format or set default org.');
|
|
82
82
|
}
|
|
83
83
|
const { agent, version } = parsed;
|
|
84
|
+
const workspaceId = await (0, api_1.resolveWorkspaceIdForOrg)(config, org);
|
|
84
85
|
write('Resolving source agent...\n');
|
|
85
|
-
const source = await (0, api_1.getAgentWithFallback)(config, org, agent, version);
|
|
86
|
+
const source = await (0, api_1.getAgentWithFallback)(config, org, agent, version, workspaceId);
|
|
86
87
|
if (!source.id) {
|
|
87
88
|
throw new errors_1.CliError(`Could not resolve source agent ID for '${org}/${agent}@${version}'.`);
|
|
88
89
|
}
|
package/dist/commands/init.js
CHANGED
|
@@ -412,7 +412,8 @@ import asyncio
|
|
|
412
412
|
import json
|
|
413
413
|
import sys
|
|
414
414
|
|
|
415
|
-
|
|
415
|
+
# pip install orchagent-sdk (package name)
|
|
416
|
+
from orchagent import AgentClient # module name
|
|
416
417
|
|
|
417
418
|
|
|
418
419
|
async def run():
|
|
@@ -503,7 +504,8 @@ import asyncio
|
|
|
503
504
|
import json
|
|
504
505
|
import sys
|
|
505
506
|
|
|
506
|
-
|
|
507
|
+
# pip install orchagent-sdk (package name)
|
|
508
|
+
from orchagent import AgentClient # module name
|
|
507
509
|
|
|
508
510
|
|
|
509
511
|
async def run():
|
|
@@ -589,7 +591,8 @@ import asyncio
|
|
|
589
591
|
import json
|
|
590
592
|
import sys
|
|
591
593
|
|
|
592
|
-
|
|
594
|
+
# pip install orchagent-sdk (package name)
|
|
595
|
+
from orchagent import AgentClient # module name
|
|
593
596
|
|
|
594
597
|
|
|
595
598
|
async def run():
|
|
@@ -1207,7 +1210,8 @@ import asyncio
|
|
|
1207
1210
|
import json
|
|
1208
1211
|
import sys
|
|
1209
1212
|
|
|
1210
|
-
|
|
1213
|
+
# pip install orchagent-sdk (package name)
|
|
1214
|
+
from orchagent import AgentClient # module name
|
|
1211
1215
|
|
|
1212
1216
|
|
|
1213
1217
|
def main():
|
|
@@ -1490,7 +1494,10 @@ function resolveInitFlavor(typeOption) {
|
|
|
1490
1494
|
if (normalized === 'prompt') {
|
|
1491
1495
|
return { type: 'prompt', flavor: 'direct_llm' };
|
|
1492
1496
|
}
|
|
1493
|
-
if (normalized === 'agent'
|
|
1497
|
+
if (normalized === 'agent') {
|
|
1498
|
+
return { type: 'agent', flavor: 'managed_loop' };
|
|
1499
|
+
}
|
|
1500
|
+
if (normalized === 'agentic') {
|
|
1494
1501
|
return { type: 'agent', flavor: 'code_runtime' };
|
|
1495
1502
|
}
|
|
1496
1503
|
if (normalized === 'tool' || normalized === 'code') {
|
|
@@ -1507,7 +1514,7 @@ function registerInitCommand(program) {
|
|
|
1507
1514
|
.option('--orchestrator', 'Create an orchestrator agent with dependency scaffolding and SDK boilerplate')
|
|
1508
1515
|
.option('--run-mode <mode>', 'Run mode for agents: on_demand or always_on', 'on_demand')
|
|
1509
1516
|
.option('--language <lang>', 'Language: python or javascript (default: python)', 'python')
|
|
1510
|
-
.option('--loop', 'Use platform-managed LLM loop
|
|
1517
|
+
.option('--loop', 'Use platform-managed LLM loop execution (explicit for --type agentic; default for --type agent)')
|
|
1511
1518
|
.option('--template <name>', 'Start from a template (use --list-templates to see options)')
|
|
1512
1519
|
.option('--list-templates', 'Show available templates with descriptions')
|
|
1513
1520
|
.action(async (name, options) => {
|
|
@@ -1613,7 +1620,7 @@ function registerInitCommand(program) {
|
|
|
1613
1620
|
const isJavaScript = ['javascript', 'js', 'typescript', 'ts'].includes(language);
|
|
1614
1621
|
// Block unsupported JS flavors
|
|
1615
1622
|
if (isJavaScript && initMode.flavor === 'managed_loop') {
|
|
1616
|
-
throw new errors_1.CliError('JavaScript is not supported for
|
|
1623
|
+
throw new errors_1.CliError('JavaScript is not supported for managed-loop agents. Use --type agentic for a code-runtime agent scaffold.');
|
|
1617
1624
|
}
|
|
1618
1625
|
// JS orchestrators are now supported via the orchagent-sdk npm package
|
|
1619
1626
|
// Block --language for types that don't create runtime files
|
|
@@ -2033,7 +2040,7 @@ function registerInitCommand(program) {
|
|
|
2033
2040
|
}
|
|
2034
2041
|
}
|
|
2035
2042
|
if (initMode.flavor !== 'code_runtime' && initMode.flavor !== 'orchestrator' && initMode.flavor !== 'discord' && runMode === 'always_on') {
|
|
2036
|
-
throw new errors_1.CliError("run_mode=always_on requires runtime.command in orchagent.json (e.g. \"runtime\": { \"command\": \"python main.py\" }). Use --type tool for code-runtime agents.");
|
|
2043
|
+
throw new errors_1.CliError("run_mode=always_on requires runtime.command in orchagent.json (e.g. \"runtime\": { \"command\": \"python main.py\" }). Use --type tool or --type agentic for code-runtime agents.");
|
|
2037
2044
|
}
|
|
2038
2045
|
// Create manifest and type-specific files
|
|
2039
2046
|
const manifest = JSON.parse(MANIFEST_TEMPLATE);
|
package/dist/commands/install.js
CHANGED
|
@@ -10,24 +10,12 @@ const os_1 = __importDefault(require("os"));
|
|
|
10
10
|
const config_1 = require("../lib/config");
|
|
11
11
|
const api_1 = require("../lib/api");
|
|
12
12
|
const errors_1 = require("../lib/errors");
|
|
13
|
+
const resolve_agent_1 = require("../lib/resolve-agent");
|
|
13
14
|
const analytics_1 = require("../lib/analytics");
|
|
14
15
|
const adapters_1 = require("../adapters");
|
|
15
16
|
const skill_resolve_1 = require("../lib/skill-resolve");
|
|
16
17
|
const installed_1 = require("../lib/installed");
|
|
17
18
|
const agents_md_utils_1 = require("../lib/agents-md-utils");
|
|
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 { name: segments[0], version };
|
|
25
|
-
}
|
|
26
|
-
if (segments.length === 2) {
|
|
27
|
-
return { org: segments[0], name: segments[1], version };
|
|
28
|
-
}
|
|
29
|
-
throw new errors_1.CliError('Invalid agent reference. Use org/agent or agent format.');
|
|
30
|
-
}
|
|
31
19
|
async function downloadAgentWithFallback(config, org, name, version, workspaceId) {
|
|
32
20
|
// Fetch public metadata first to check if paid
|
|
33
21
|
let publicMeta;
|
|
@@ -135,19 +123,21 @@ function registerInstallCommand(program) {
|
|
|
135
123
|
errors: [],
|
|
136
124
|
};
|
|
137
125
|
const resolved = await (0, config_1.getResolvedConfig)();
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
126
|
+
let agentCtx;
|
|
127
|
+
try {
|
|
128
|
+
agentCtx = await (0, resolve_agent_1.resolveAgentContext)(agentArg, resolved);
|
|
129
|
+
}
|
|
130
|
+
catch (err) {
|
|
131
|
+
if (jsonMode && err instanceof errors_1.CliError) {
|
|
132
|
+
result.errors.push(err.message);
|
|
144
133
|
process.stdout.write(JSON.stringify(result, null, 2) + '\n');
|
|
145
134
|
process.exit(errors_1.ExitCodes.INVALID_INPUT);
|
|
146
135
|
}
|
|
147
|
-
throw
|
|
136
|
+
throw err;
|
|
148
137
|
}
|
|
149
|
-
|
|
150
|
-
result.
|
|
138
|
+
const { org, agent: agentName, version, workspaceId } = agentCtx;
|
|
139
|
+
result.agent = `${org}/${agentName}`;
|
|
140
|
+
result.version = version;
|
|
151
141
|
// Determine target formats
|
|
152
142
|
let targetFormats = [];
|
|
153
143
|
if (options.format) {
|
|
@@ -186,13 +176,11 @@ function registerInstallCommand(program) {
|
|
|
186
176
|
throw new errors_1.CliError(errMsg);
|
|
187
177
|
}
|
|
188
178
|
result.scope = scope;
|
|
189
|
-
// Resolve workspace context for the target org
|
|
190
|
-
const workspaceId = await (0, api_1.resolveWorkspaceIdForOrg)(resolved, org);
|
|
191
179
|
// Download agent
|
|
192
|
-
log(`Fetching ${org}/${
|
|
180
|
+
log(`Fetching ${org}/${agentName}@${version}...\n`);
|
|
193
181
|
let agent;
|
|
194
182
|
try {
|
|
195
|
-
agent = await downloadAgentWithFallback(resolved, org,
|
|
183
|
+
agent = await downloadAgentWithFallback(resolved, org, agentName, version, workspaceId);
|
|
196
184
|
}
|
|
197
185
|
catch (err) {
|
|
198
186
|
if (jsonMode) {
|
|
@@ -273,15 +261,15 @@ function registerInstallCommand(program) {
|
|
|
273
261
|
catch {
|
|
274
262
|
// File doesn't exist, will create new
|
|
275
263
|
}
|
|
276
|
-
const agentRef = `${org}/${
|
|
264
|
+
const agentRef = `${org}/${agentName}`;
|
|
277
265
|
file.content = (0, agents_md_utils_1.mergeAgentsMdContent)(existingContent, file.content, agentRef);
|
|
278
266
|
}
|
|
279
267
|
await promises_1.default.writeFile(fullPath, file.content);
|
|
280
268
|
filesWritten++;
|
|
281
269
|
// Track installation
|
|
282
270
|
const installedAgent = {
|
|
283
|
-
agent: `${org}/${
|
|
284
|
-
version:
|
|
271
|
+
agent: `${org}/${agentName}`,
|
|
272
|
+
version: version,
|
|
285
273
|
format: formatId,
|
|
286
274
|
scope: effectiveScope,
|
|
287
275
|
path: fullPath,
|
|
@@ -297,7 +285,7 @@ function registerInstallCommand(program) {
|
|
|
297
285
|
if (!options.dryRun) {
|
|
298
286
|
if (filesWritten > 0) {
|
|
299
287
|
await (0, analytics_1.track)('cli_agent_install', {
|
|
300
|
-
agent: `${org}/${
|
|
288
|
+
agent: `${org}/${agentName}`,
|
|
301
289
|
formats: targetFormats,
|
|
302
290
|
scope,
|
|
303
291
|
});
|
package/dist/commands/logs.js
CHANGED
|
@@ -182,7 +182,7 @@ async function listRuns(config, workspaceId, agentName, options) {
|
|
|
182
182
|
if (result.total > result.runs.length) {
|
|
183
183
|
process.stdout.write(chalk_1.default.gray(`\nShowing ${result.runs.length} of ${result.total} runs. Use --limit to see more.\n`));
|
|
184
184
|
}
|
|
185
|
-
process.stdout.write(chalk_1.default.gray('\nView detailed logs for a run: orch logs <run-id>\n'));
|
|
185
|
+
process.stdout.write(chalk_1.default.gray('\nView detailed logs for a run: orch logs <run-id> · Replay a run: orch replay <run-id>\n'));
|
|
186
186
|
}
|
|
187
187
|
// ============================================
|
|
188
188
|
// SHOW RUN LOGS
|
|
@@ -229,5 +229,7 @@ async function showRunLogs(config, workspaceId, runId, json) {
|
|
|
229
229
|
process.stdout.write(chalk_1.default.gray('\nNo sandbox output available for this run. ' +
|
|
230
230
|
'Execution logs are captured for agents with a code runtime (tool/agent types with runtime.command).\n'));
|
|
231
231
|
}
|
|
232
|
+
// Footer hints
|
|
233
|
+
process.stdout.write(chalk_1.default.gray(`\nReplay: orch replay ${runId.slice(0, 8)} · Trace: orch trace ${runId.slice(0, 8)}\n`));
|
|
232
234
|
process.stdout.write('\n');
|
|
233
235
|
}
|
package/dist/commands/publish.js
CHANGED
|
@@ -510,6 +510,8 @@ async function batchPublish(rootDir, options) {
|
|
|
510
510
|
forwardArgs.push('--no-local-download');
|
|
511
511
|
if (options.requiredSecrets === false)
|
|
512
512
|
forwardArgs.push('--no-required-secrets');
|
|
513
|
+
if (options.verbose)
|
|
514
|
+
forwardArgs.push('--verbose');
|
|
513
515
|
const results = [];
|
|
514
516
|
for (let i = 0; i < sorted.length; i++) {
|
|
515
517
|
const agent = sorted[i];
|
|
@@ -586,6 +588,7 @@ function registerPublishCommand(program) {
|
|
|
586
588
|
.option('--no-local-download', 'Prevent users from downloading and running locally (default: allowed)')
|
|
587
589
|
.option('--no-required-secrets', '(deprecated) No longer needed — required_secrets defaults to []')
|
|
588
590
|
.option('--all', 'Publish all agents in subdirectories (dependency order)')
|
|
591
|
+
.option('--verbose', 'Show detailed bundle contents (file list)')
|
|
589
592
|
.action(async (options) => {
|
|
590
593
|
const cwd = process.cwd();
|
|
591
594
|
// --all: batch publish all agents in subdirectories
|
|
@@ -696,6 +699,11 @@ function registerPublishCommand(program) {
|
|
|
696
699
|
process.stdout.write(`\n${chalk_1.default.green('✔')} Published ${org.slug}/${skillData.frontmatter.name}@${skillVersion} successfully!\n\n`);
|
|
697
700
|
if (hasMultipleFiles) {
|
|
698
701
|
process.stdout.write(`Files: ${skillFiles.length} files included\n`);
|
|
702
|
+
if (options.verbose) {
|
|
703
|
+
for (const f of skillFiles) {
|
|
704
|
+
process.stdout.write(` ${f.path}\n`);
|
|
705
|
+
}
|
|
706
|
+
}
|
|
699
707
|
}
|
|
700
708
|
process.stdout.write(`Visibility: private\n`);
|
|
701
709
|
process.stdout.write(`\nView analytics and usage: https://orchagent.io/dashboard\n`);
|
|
@@ -1061,6 +1069,12 @@ function registerPublishCommand(program) {
|
|
|
1061
1069
|
process.stderr.write(` Files: ${bundlePreview.fileCount} files\n`);
|
|
1062
1070
|
process.stderr.write(` Size: ${(bundlePreview.totalSizeBytes / 1024).toFixed(1)} KB\n`);
|
|
1063
1071
|
process.stderr.write(` Entrypoint: ${bundlePreview.entrypoint}\n`);
|
|
1072
|
+
if (options.verbose && bundlePreview.files?.length) {
|
|
1073
|
+
process.stderr.write(` Bundled files:\n`);
|
|
1074
|
+
for (const f of bundlePreview.files) {
|
|
1075
|
+
process.stderr.write(` ${f}\n`);
|
|
1076
|
+
}
|
|
1077
|
+
}
|
|
1064
1078
|
}
|
|
1065
1079
|
process.stderr.write('\nAgent Preview:\n');
|
|
1066
1080
|
process.stderr.write(` Name: ${manifest.name}\n`);
|
|
@@ -1324,6 +1338,12 @@ function registerPublishCommand(program) {
|
|
|
1324
1338
|
skipEntrypointCheck: false,
|
|
1325
1339
|
});
|
|
1326
1340
|
process.stdout.write(` Created bundle: ${bundleResult.fileCount} files, ${(bundleResult.sizeBytes / 1024).toFixed(1)}KB\n`);
|
|
1341
|
+
if (options.verbose && bundleResult.files?.length) {
|
|
1342
|
+
process.stdout.write(` Bundled files:\n`);
|
|
1343
|
+
for (const f of bundleResult.files) {
|
|
1344
|
+
process.stdout.write(` ${f}\n`);
|
|
1345
|
+
}
|
|
1346
|
+
}
|
|
1327
1347
|
// Validate bundle size
|
|
1328
1348
|
const validation = await (0, bundle_1.validateBundle)(bundlePath);
|
|
1329
1349
|
if (!validation.valid) {
|
|
@@ -1404,14 +1424,20 @@ function registerPublishCommand(program) {
|
|
|
1404
1424
|
// Show security review result if available
|
|
1405
1425
|
const secReview = result.security_review;
|
|
1406
1426
|
if (secReview?.verdict) {
|
|
1407
|
-
if (secReview.verdict === '
|
|
1427
|
+
if (secReview.verdict === 'approved') {
|
|
1408
1428
|
process.stdout.write(`Security: ${chalk_1.default.green('passed')}\n`);
|
|
1409
1429
|
}
|
|
1410
1430
|
else if (secReview.verdict === 'flagged') {
|
|
1411
1431
|
process.stdout.write(`Security: ${chalk_1.default.yellow('flagged')} — ${secReview.summary || 'review recommended'}\n`);
|
|
1412
1432
|
}
|
|
1433
|
+
else if (secReview.verdict === 'error') {
|
|
1434
|
+
process.stdout.write(`Security: ${chalk_1.default.gray('review unavailable')} — publish succeeded, review will be retried\n`);
|
|
1435
|
+
}
|
|
1436
|
+
else if (secReview.verdict === 'skipped') {
|
|
1437
|
+
process.stdout.write(`Security: ${chalk_1.default.gray('review skipped')} — ${secReview.summary || 'content not eligible for review'}\n`);
|
|
1438
|
+
}
|
|
1413
1439
|
else {
|
|
1414
|
-
process.stdout.write(`Security: ${secReview.verdict}\n`);
|
|
1440
|
+
process.stdout.write(`Security: ${chalk_1.default.gray(secReview.verdict)} — ${secReview.summary || ''}\n`);
|
|
1415
1441
|
}
|
|
1416
1442
|
}
|
|
1417
1443
|
if (result.service_key) {
|
package/dist/commands/pull.js
CHANGED
|
@@ -12,21 +12,10 @@ const child_process_1 = require("child_process");
|
|
|
12
12
|
const config_1 = require("../lib/config");
|
|
13
13
|
const api_1 = require("../lib/api");
|
|
14
14
|
const errors_1 = require("../lib/errors");
|
|
15
|
+
const resolve_agent_1 = require("../lib/resolve-agent");
|
|
15
16
|
const analytics_1 = require("../lib/analytics");
|
|
16
17
|
const output_1 = require("../lib/output");
|
|
17
18
|
// ─── Helpers ────────────────────────────────────────────────────────────────
|
|
18
|
-
function parsePullRef(value) {
|
|
19
|
-
const [ref, versionPart] = value.split('@');
|
|
20
|
-
const version = versionPart?.trim() || 'latest';
|
|
21
|
-
const segments = ref.split('/');
|
|
22
|
-
if (segments.length === 1) {
|
|
23
|
-
return { agent: segments[0], version };
|
|
24
|
-
}
|
|
25
|
-
if (segments.length === 2) {
|
|
26
|
-
return { org: segments[0], agent: segments[1], version };
|
|
27
|
-
}
|
|
28
|
-
throw new errors_1.CliError('Invalid agent reference. Use org/agent[@version] or agent[@version] format.');
|
|
29
|
-
}
|
|
30
19
|
function canonicalType(typeValue) {
|
|
31
20
|
const normalized = (typeValue || 'agent').toLowerCase();
|
|
32
21
|
if (['prompt', 'tool', 'agent', 'skill'].includes(normalized))
|
|
@@ -292,7 +281,7 @@ function buildManifest(data) {
|
|
|
292
281
|
return manifest;
|
|
293
282
|
}
|
|
294
283
|
// ─── Bundle Download + Extraction ───────────────────────────────────────────
|
|
295
|
-
async function downloadBundle(config, org, agent, version, agentId) {
|
|
284
|
+
async function downloadBundle(config, org, agent, version, agentId, workspaceId) {
|
|
296
285
|
try {
|
|
297
286
|
return await (0, api_1.downloadCodeBundle)(config, org, agent, version);
|
|
298
287
|
}
|
|
@@ -305,7 +294,7 @@ async function downloadBundle(config, org, agent, version, agentId) {
|
|
|
305
294
|
}
|
|
306
295
|
if (config.apiKey && agentId) {
|
|
307
296
|
try {
|
|
308
|
-
return await (0, api_1.downloadCodeBundleAuthenticated)(config, agentId);
|
|
297
|
+
return await (0, api_1.downloadCodeBundleAuthenticated)(config, agentId, workspaceId);
|
|
309
298
|
}
|
|
310
299
|
catch (err) {
|
|
311
300
|
if (!(err instanceof api_1.ApiError) || err.status !== 404)
|
|
@@ -359,19 +348,12 @@ Examples:
|
|
|
359
348
|
process.stdout.write(message);
|
|
360
349
|
};
|
|
361
350
|
const config = await (0, config_1.getResolvedConfig)();
|
|
362
|
-
const
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
if (!org) {
|
|
367
|
-
throw new errors_1.CliError('Missing org. Use org/agent[@version] format, or set a default org with:\n' +
|
|
368
|
-
' orch config set default-org <org>');
|
|
369
|
-
}
|
|
370
|
-
// Resolve workspace context for the target org
|
|
371
|
-
const workspaceId = await (0, api_1.resolveWorkspaceIdForOrg)(config, org);
|
|
372
|
-
write(`Resolving ${org}/${parsed.agent}@${parsed.version}...\n`);
|
|
351
|
+
const { org, agent: agentName, version, workspaceId } = await (0, resolve_agent_1.resolveAgentContext)(agentRef, config, {
|
|
352
|
+
missingOrgMessage: 'Missing org. Use org/agent[@version] format, or set a default org with:\n orch config set default-org <org>',
|
|
353
|
+
});
|
|
354
|
+
write(`Resolving ${org}/${agentName}@${version}...\n`);
|
|
373
355
|
// Resolve agent data
|
|
374
|
-
const data = await resolveAgent(config, org,
|
|
356
|
+
const data = await resolveAgent(config, org, agentName, version, workspaceId);
|
|
375
357
|
// Reject skills
|
|
376
358
|
if (canonicalType(data.type) === 'skill') {
|
|
377
359
|
throw new errors_1.CliError("This is a skill. Use 'orch skill install <ref>' instead.");
|
|
@@ -411,7 +393,7 @@ Examples:
|
|
|
411
393
|
// and exit-code 1.
|
|
412
394
|
if (engine === 'code_runtime' && data.has_bundle) {
|
|
413
395
|
write('Downloading code bundle...\n');
|
|
414
|
-
const bundle = await downloadBundle(config, org, data.name, data.version, data.agentId);
|
|
396
|
+
const bundle = await downloadBundle(config, org, data.name, data.version, data.agentId, workspaceId);
|
|
415
397
|
if (bundle) {
|
|
416
398
|
const tempDir = path_1.default.join(os_1.default.tmpdir(), `orchagent-pull-${Date.now()}`);
|
|
417
399
|
const zipPath = path_1.default.join(tempDir, 'bundle.zip');
|
|
@@ -455,7 +437,7 @@ Examples:
|
|
|
455
437
|
// Track analytics
|
|
456
438
|
await (0, analytics_1.track)('cli_pull', {
|
|
457
439
|
org,
|
|
458
|
-
agent:
|
|
440
|
+
agent: agentName,
|
|
459
441
|
version: data.version,
|
|
460
442
|
engine,
|
|
461
443
|
source: data.source,
|
|
@@ -465,7 +447,7 @@ Examples:
|
|
|
465
447
|
if (options.json) {
|
|
466
448
|
const result = {
|
|
467
449
|
success: true,
|
|
468
|
-
requested_ref: `${org}/${
|
|
450
|
+
requested_ref: `${org}/${agentName}@${version}`,
|
|
469
451
|
resolved_ref: resolvedRef,
|
|
470
452
|
output_dir: outputDir,
|
|
471
453
|
engine,
|
package/dist/commands/replay.js
CHANGED
|
@@ -91,6 +91,21 @@ function registerReplayCommand(program) {
|
|
|
91
91
|
.option('--override-policy <id>', 'Override provider policy ID for this replay')
|
|
92
92
|
.option('--no-wait', 'Queue the replay and return immediately without waiting for results')
|
|
93
93
|
.option('--json', 'Output as JSON')
|
|
94
|
+
.addHelpText('after', `
|
|
95
|
+
How snapshots work:
|
|
96
|
+
Every cloud run automatically captures a snapshot of its input, config,
|
|
97
|
+
secrets, and agent version before execution. This snapshot enables
|
|
98
|
+
deterministic replay — even if the agent has been updated since.
|
|
99
|
+
|
|
100
|
+
Local runs (--local) do not create snapshots and cannot be replayed.
|
|
101
|
+
Runs created before snapshot support was added also cannot be replayed.
|
|
102
|
+
|
|
103
|
+
Examples:
|
|
104
|
+
orch replay a1b2c3d4 Replay and wait for results
|
|
105
|
+
orch replay a1b2c3d4 --no-wait Queue and return immediately
|
|
106
|
+
orch replay a1b2c3d4 --reason "debug" Replay with audit reason
|
|
107
|
+
orch replay a1b2c3d4 --json Output as JSON
|
|
108
|
+
`)
|
|
94
109
|
.action(async (runId, options) => {
|
|
95
110
|
const config = await (0, config_1.getResolvedConfig)();
|
|
96
111
|
if (!config.apiKey) {
|
|
@@ -109,15 +124,33 @@ function registerReplayCommand(program) {
|
|
|
109
124
|
throw new errors_1.CliError(`Invalid run ID '${runId}'. Provide a full UUID or a short hex prefix (7+ characters).`);
|
|
110
125
|
}
|
|
111
126
|
// Submit replay request
|
|
112
|
-
const
|
|
127
|
+
const reqBody = {};
|
|
113
128
|
if (options.reason)
|
|
114
|
-
|
|
129
|
+
reqBody.reason = options.reason;
|
|
115
130
|
if (options.overridePolicy)
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
131
|
+
reqBody.override_provider_policy_id = options.overridePolicy;
|
|
132
|
+
let replay;
|
|
133
|
+
try {
|
|
134
|
+
replay = await (0, api_1.request)(config, 'POST', `/workspaces/${workspaceId}/runs/${resolvedRunId}/replay`, {
|
|
135
|
+
body: JSON.stringify(reqBody),
|
|
136
|
+
headers: { 'Content-Type': 'application/json' },
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
catch (err) {
|
|
140
|
+
if (err instanceof api_1.ApiError && err.status === 404) {
|
|
141
|
+
const isSnapshotMissing = err.message.toLowerCase().includes('snapshot');
|
|
142
|
+
if (isSnapshotMissing) {
|
|
143
|
+
throw new errors_1.CliError(`No snapshot available for run ${resolvedRunId.slice(0, 8)}.\n\n` +
|
|
144
|
+
`Snapshots are captured automatically for cloud runs. This run may have been:\n` +
|
|
145
|
+
` - A local run (--local), which does not create snapshots\n` +
|
|
146
|
+
` - Created before snapshot support was added\n\n` +
|
|
147
|
+
`Run \`orch logs ${resolvedRunId.slice(0, 8)}\` to inspect the original run.`);
|
|
148
|
+
}
|
|
149
|
+
throw new errors_1.CliError(`Run ${resolvedRunId.slice(0, 8)} not found. ` +
|
|
150
|
+
`Check the run ID and workspace, or run \`orch logs\` to list recent runs.`);
|
|
151
|
+
}
|
|
152
|
+
throw err;
|
|
153
|
+
}
|
|
121
154
|
if (options.json && options.wait === false) {
|
|
122
155
|
(0, output_1.printJson)(replay);
|
|
123
156
|
return;
|