@orchagent/cli 0.3.88 → 0.3.89
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/config.js +29 -6
- package/dist/commands/dag.js +259 -0
- package/dist/commands/env.js +15 -4
- package/dist/commands/fork.js +6 -6
- package/dist/commands/index.js +2 -4
- package/dist/commands/publish.js +20 -19
- package/package.json +1 -1
- package/dist/commands/call.js +0 -23
- package/dist/commands/keys.js +0 -22
package/dist/commands/config.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.setConfigValue = setConfigValue;
|
|
4
4
|
exports.registerConfigCommand = registerConfigCommand;
|
|
5
|
+
const output_1 = require("../lib/output");
|
|
5
6
|
const config_1 = require("../lib/config");
|
|
6
7
|
const errors_1 = require("../lib/errors");
|
|
7
8
|
const adapters_1 = require("../adapters");
|
|
@@ -49,13 +50,17 @@ async function setConfigValue(key, value) {
|
|
|
49
50
|
process.stdout.write(`Set default-provider to: ${value}\n`);
|
|
50
51
|
}
|
|
51
52
|
}
|
|
52
|
-
async function getConfigValue(key) {
|
|
53
|
+
async function getConfigValue(key, options = {}) {
|
|
53
54
|
if (!isValidKey(key)) {
|
|
54
55
|
throw new errors_1.CliError(`Unknown config key: ${key}. Supported keys: ${SUPPORTED_KEYS.join(', ')}`);
|
|
55
56
|
}
|
|
56
57
|
if (key === 'default-format') {
|
|
57
58
|
const resolved = await (0, config_1.getResolvedConfig)();
|
|
58
59
|
const formats = await (0, config_1.getDefaultFormats)(resolved);
|
|
60
|
+
if (options.json) {
|
|
61
|
+
(0, output_1.printJson)({ key, value: formats.length > 0 ? formats : [] });
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
59
64
|
if (formats.length === 0) {
|
|
60
65
|
process.stdout.write('(not set)\n');
|
|
61
66
|
}
|
|
@@ -65,6 +70,10 @@ async function getConfigValue(key) {
|
|
|
65
70
|
}
|
|
66
71
|
if (key === 'default-scope') {
|
|
67
72
|
const scope = await (0, config_1.getDefaultScope)();
|
|
73
|
+
if (options.json) {
|
|
74
|
+
(0, output_1.printJson)({ key, value: scope ?? null });
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
68
77
|
if (!scope) {
|
|
69
78
|
process.stdout.write('(not set)\n');
|
|
70
79
|
}
|
|
@@ -74,6 +83,10 @@ async function getConfigValue(key) {
|
|
|
74
83
|
}
|
|
75
84
|
if (key === 'default-provider') {
|
|
76
85
|
const provider = await (0, config_1.getDefaultProvider)();
|
|
86
|
+
if (options.json) {
|
|
87
|
+
(0, output_1.printJson)({ key, value: provider ?? null });
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
77
90
|
if (!provider) {
|
|
78
91
|
process.stdout.write('(not set)\n');
|
|
79
92
|
}
|
|
@@ -89,8 +102,16 @@ async function unsetConfigValue(key) {
|
|
|
89
102
|
await (0, config_1.unsetConfigKey)(key);
|
|
90
103
|
process.stdout.write(`Unset ${key}\n`);
|
|
91
104
|
}
|
|
92
|
-
async function listConfigValues() {
|
|
105
|
+
async function listConfigValues(options = {}) {
|
|
93
106
|
const config = await (0, config_1.loadConfig)();
|
|
107
|
+
if (options.json) {
|
|
108
|
+
(0, output_1.printJson)({
|
|
109
|
+
default_format: config.default_formats ?? [],
|
|
110
|
+
default_scope: config.default_scope ?? null,
|
|
111
|
+
default_provider: config.default_provider ?? null,
|
|
112
|
+
});
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
94
115
|
process.stdout.write('CLI Configuration:\n\n');
|
|
95
116
|
// default-format
|
|
96
117
|
const formats = config.default_formats ?? [];
|
|
@@ -131,8 +152,9 @@ function registerConfigCommand(program) {
|
|
|
131
152
|
config
|
|
132
153
|
.command('get <key>')
|
|
133
154
|
.description('Get a configuration value')
|
|
134
|
-
.
|
|
135
|
-
|
|
155
|
+
.option('--json', 'Output as JSON')
|
|
156
|
+
.action(async (key, options) => {
|
|
157
|
+
await getConfigValue(key, options);
|
|
136
158
|
});
|
|
137
159
|
config
|
|
138
160
|
.command('unset <key>')
|
|
@@ -143,7 +165,8 @@ function registerConfigCommand(program) {
|
|
|
143
165
|
config
|
|
144
166
|
.command('list')
|
|
145
167
|
.description('List all configuration values')
|
|
146
|
-
.
|
|
147
|
-
|
|
168
|
+
.option('--json', 'Output as JSON')
|
|
169
|
+
.action(async (options) => {
|
|
170
|
+
await listConfigValues(options);
|
|
148
171
|
});
|
|
149
172
|
}
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.registerDagCommand = registerDagCommand;
|
|
7
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
8
|
+
const config_1 = require("../lib/config");
|
|
9
|
+
const api_1 = require("../lib/api");
|
|
10
|
+
const errors_1 = require("../lib/errors");
|
|
11
|
+
const output_1 = require("../lib/output");
|
|
12
|
+
const spinner_1 = require("../lib/spinner");
|
|
13
|
+
// ============================================
|
|
14
|
+
// HELPERS
|
|
15
|
+
// ============================================
|
|
16
|
+
async function resolveWorkspaceId(config, slug) {
|
|
17
|
+
const configFile = await (0, config_1.loadConfig)();
|
|
18
|
+
const targetSlug = slug ?? configFile.workspace;
|
|
19
|
+
if (!targetSlug) {
|
|
20
|
+
throw new errors_1.CliError('No workspace specified. Use --workspace <slug> or run `orch workspace use <slug>` first.');
|
|
21
|
+
}
|
|
22
|
+
const response = await (0, api_1.request)(config, 'GET', '/workspaces');
|
|
23
|
+
const workspace = response.workspaces.find((w) => w.slug === targetSlug);
|
|
24
|
+
if (!workspace) {
|
|
25
|
+
throw new errors_1.CliError(`Workspace '${targetSlug}' not found.`);
|
|
26
|
+
}
|
|
27
|
+
return workspace.id;
|
|
28
|
+
}
|
|
29
|
+
function isUuid(value) {
|
|
30
|
+
return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(value);
|
|
31
|
+
}
|
|
32
|
+
function isShortUuid(value) {
|
|
33
|
+
return /^[0-9a-f]{7,}$/i.test(value) && !value.includes('/');
|
|
34
|
+
}
|
|
35
|
+
async function resolveShortRunId(config, workspaceId, shortId) {
|
|
36
|
+
const result = await (0, api_1.request)(config, 'GET', `/workspaces/${workspaceId}/runs?limit=200&run_id_prefix=${encodeURIComponent(shortId)}`);
|
|
37
|
+
if (result.runs.length === 0) {
|
|
38
|
+
throw new errors_1.CliError(`No run found matching '${shortId}'.`);
|
|
39
|
+
}
|
|
40
|
+
if (result.runs.length > 1) {
|
|
41
|
+
throw new errors_1.CliError(`Ambiguous run ID '${shortId}' — matches ${result.runs.length} runs. Use more characters.`);
|
|
42
|
+
}
|
|
43
|
+
return result.runs[0].id;
|
|
44
|
+
}
|
|
45
|
+
// ============================================
|
|
46
|
+
// FORMATTERS
|
|
47
|
+
// ============================================
|
|
48
|
+
function statusColor(status) {
|
|
49
|
+
switch (status) {
|
|
50
|
+
case 'completed':
|
|
51
|
+
return chalk_1.default.green(status);
|
|
52
|
+
case 'failed':
|
|
53
|
+
case 'timeout':
|
|
54
|
+
case 'dead_letter':
|
|
55
|
+
return chalk_1.default.red(status);
|
|
56
|
+
case 'running':
|
|
57
|
+
return chalk_1.default.yellow(status);
|
|
58
|
+
case 'queued':
|
|
59
|
+
case 'claimed':
|
|
60
|
+
return chalk_1.default.cyan(status);
|
|
61
|
+
default:
|
|
62
|
+
return chalk_1.default.gray(status);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
function statusIcon(status) {
|
|
66
|
+
switch (status) {
|
|
67
|
+
case 'completed':
|
|
68
|
+
return chalk_1.default.green('✓');
|
|
69
|
+
case 'failed':
|
|
70
|
+
case 'timeout':
|
|
71
|
+
case 'dead_letter':
|
|
72
|
+
return chalk_1.default.red('✗');
|
|
73
|
+
case 'running':
|
|
74
|
+
return chalk_1.default.yellow('◉');
|
|
75
|
+
case 'queued':
|
|
76
|
+
case 'claimed':
|
|
77
|
+
return chalk_1.default.cyan('○');
|
|
78
|
+
default:
|
|
79
|
+
return chalk_1.default.gray('?');
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
function formatDuration(ms) {
|
|
83
|
+
if (ms == null)
|
|
84
|
+
return '-';
|
|
85
|
+
if (ms < 1000)
|
|
86
|
+
return `${ms}ms`;
|
|
87
|
+
if (ms < 60000)
|
|
88
|
+
return `${(ms / 1000).toFixed(1)}s`;
|
|
89
|
+
return `${(ms / 60000).toFixed(1)}m`;
|
|
90
|
+
}
|
|
91
|
+
function formatCost(usd) {
|
|
92
|
+
if (usd === 0)
|
|
93
|
+
return '-';
|
|
94
|
+
if (usd < 0.01)
|
|
95
|
+
return `$${usd.toFixed(6)}`;
|
|
96
|
+
return `$${usd.toFixed(4)}`;
|
|
97
|
+
}
|
|
98
|
+
function formatTokens(n) {
|
|
99
|
+
if (n >= 1_000_000)
|
|
100
|
+
return `${(n / 1_000_000).toFixed(1)}M`;
|
|
101
|
+
if (n >= 1_000)
|
|
102
|
+
return `${(n / 1_000).toFixed(1)}K`;
|
|
103
|
+
return String(n);
|
|
104
|
+
}
|
|
105
|
+
// ============================================
|
|
106
|
+
// ASCII DAG RENDERER
|
|
107
|
+
// ============================================
|
|
108
|
+
function renderDagHeader(dag) {
|
|
109
|
+
const liveTag = dag.is_live ? chalk_1.default.blue(' [LIVE]') : '';
|
|
110
|
+
process.stdout.write(chalk_1.default.bold(`\nOrchestration DAG`) + liveTag + '\n' +
|
|
111
|
+
` Root: ${dag.root_run_id.slice(0, 8)}...\n` +
|
|
112
|
+
` Agents: ${dag.node_count}\n` +
|
|
113
|
+
` Duration: ${formatDuration(dag.total_duration_ms)}\n` +
|
|
114
|
+
` Cost: ${formatCost(dag.total_cost_usd)}\n`);
|
|
115
|
+
if (dag.active_count > 0 || dag.failed_count > 0) {
|
|
116
|
+
const parts = [];
|
|
117
|
+
if (dag.completed_count > 0)
|
|
118
|
+
parts.push(chalk_1.default.green(`${dag.completed_count} completed`));
|
|
119
|
+
if (dag.active_count > 0)
|
|
120
|
+
parts.push(chalk_1.default.yellow(`${dag.active_count} active`));
|
|
121
|
+
if (dag.failed_count > 0)
|
|
122
|
+
parts.push(chalk_1.default.red(`${dag.failed_count} failed`));
|
|
123
|
+
process.stdout.write(` Status: ${parts.join(', ')}\n`);
|
|
124
|
+
}
|
|
125
|
+
if (dag.most_expensive_agent) {
|
|
126
|
+
process.stdout.write(` Costly: ${chalk_1.default.yellow(dag.most_expensive_agent)}\n`);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
function renderDagTree(node, prefix, isLast, isRoot) {
|
|
130
|
+
// Connector characters
|
|
131
|
+
const connector = isRoot ? '' : (isLast ? '└── ' : '├── ');
|
|
132
|
+
const childPrefix = isRoot ? '' : (isLast ? ' ' : '│ ');
|
|
133
|
+
// Status icon + agent name
|
|
134
|
+
const icon = statusIcon(node.status);
|
|
135
|
+
const name = chalk_1.default.bold(node.agent_name);
|
|
136
|
+
const version = chalk_1.default.gray(node.agent_version);
|
|
137
|
+
// Metrics line
|
|
138
|
+
const metricParts = [];
|
|
139
|
+
metricParts.push(statusColor(node.status));
|
|
140
|
+
if (node.duration_ms != null)
|
|
141
|
+
metricParts.push(chalk_1.default.gray(formatDuration(node.duration_ms)));
|
|
142
|
+
if (node.self_cost_usd > 0)
|
|
143
|
+
metricParts.push(chalk_1.default.gray(formatCost(node.self_cost_usd)));
|
|
144
|
+
if (node.llm_model)
|
|
145
|
+
metricParts.push(chalk_1.default.gray(node.llm_model));
|
|
146
|
+
const metrics = metricParts.join(chalk_1.default.gray(' | '));
|
|
147
|
+
// Trace summary
|
|
148
|
+
const ts = node.trace_summary;
|
|
149
|
+
const traceParts = [];
|
|
150
|
+
if (ts.llm_calls > 0)
|
|
151
|
+
traceParts.push(`${ts.llm_calls} LLM`);
|
|
152
|
+
if (ts.tool_calls > 0)
|
|
153
|
+
traceParts.push(`${ts.tool_calls} tool`);
|
|
154
|
+
if (ts.errors > 0)
|
|
155
|
+
traceParts.push(chalk_1.default.red(`${ts.errors} err`));
|
|
156
|
+
if (ts.total_tokens > 0)
|
|
157
|
+
traceParts.push(`${formatTokens(ts.total_tokens)} tok`);
|
|
158
|
+
const traceInfo = traceParts.length > 0 ? chalk_1.default.gray(` (${traceParts.join(', ')})`) : '';
|
|
159
|
+
process.stdout.write(`${prefix}${connector}${icon} ${name} ${version}\n` +
|
|
160
|
+
`${prefix}${childPrefix} ${metrics}${traceInfo}\n`);
|
|
161
|
+
// Render children
|
|
162
|
+
for (let i = 0; i < node.children.length; i++) {
|
|
163
|
+
const isChildLast = i === node.children.length - 1;
|
|
164
|
+
renderDagTree(node.children[i], prefix + childPrefix, isChildLast, false);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
function clearScreen() {
|
|
168
|
+
process.stdout.write('\x1b[2J\x1b[H');
|
|
169
|
+
}
|
|
170
|
+
// ============================================
|
|
171
|
+
// COMMAND
|
|
172
|
+
// ============================================
|
|
173
|
+
function registerDagCommand(program) {
|
|
174
|
+
program
|
|
175
|
+
.command('dag <run-id>')
|
|
176
|
+
.description('Visualize the orchestration call graph for a run. Shows all agents in the chain with real-time status.')
|
|
177
|
+
.option('--workspace <slug>', 'Workspace slug (default: current workspace)')
|
|
178
|
+
.option('--live', 'Keep polling for updates while the run is active')
|
|
179
|
+
.option('--interval <seconds>', 'Poll interval in seconds for --live mode', '2')
|
|
180
|
+
.option('--json', 'Output as JSON')
|
|
181
|
+
.action(async (runId, options) => {
|
|
182
|
+
const config = await (0, config_1.getResolvedConfig)();
|
|
183
|
+
if (!config.apiKey) {
|
|
184
|
+
throw new errors_1.CliError('Missing API key. Run `orch login` first.');
|
|
185
|
+
}
|
|
186
|
+
const workspaceId = await resolveWorkspaceId(config, options.workspace);
|
|
187
|
+
// Resolve short run IDs
|
|
188
|
+
let resolvedRunId = runId;
|
|
189
|
+
if (isUuid(runId)) {
|
|
190
|
+
resolvedRunId = runId;
|
|
191
|
+
}
|
|
192
|
+
else if (isShortUuid(runId)) {
|
|
193
|
+
resolvedRunId = await resolveShortRunId(config, workspaceId, runId);
|
|
194
|
+
}
|
|
195
|
+
else {
|
|
196
|
+
throw new errors_1.CliError(`Invalid run ID '${runId}'. Provide a full UUID or a short hex prefix (7+ characters).`);
|
|
197
|
+
}
|
|
198
|
+
const interval = Math.max(1, Math.min(30, parseFloat(options.interval || '2')));
|
|
199
|
+
// Fetch DAG
|
|
200
|
+
const spinner = (0, spinner_1.createSpinner)('Fetching orchestration DAG...');
|
|
201
|
+
spinner.start();
|
|
202
|
+
let dag;
|
|
203
|
+
try {
|
|
204
|
+
dag = await (0, api_1.request)(config, 'GET', `/workspaces/${workspaceId}/runs/${resolvedRunId}/dag`);
|
|
205
|
+
spinner.stop();
|
|
206
|
+
}
|
|
207
|
+
catch (e) {
|
|
208
|
+
spinner.stop();
|
|
209
|
+
const msg = e instanceof Error ? e.message : 'Unknown error';
|
|
210
|
+
if (msg.includes('404') || msg.includes('not found') || msg.includes('Not part of')) {
|
|
211
|
+
throw new errors_1.CliError(`Run ${resolvedRunId.slice(0, 8)}... is not part of an orchestration chain.`);
|
|
212
|
+
}
|
|
213
|
+
throw e;
|
|
214
|
+
}
|
|
215
|
+
if (options.json && !options.live) {
|
|
216
|
+
(0, output_1.printJson)(dag);
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
// Render initial DAG
|
|
220
|
+
renderDagHeader(dag);
|
|
221
|
+
process.stdout.write('\n');
|
|
222
|
+
renderDagTree(dag.tree, ' ', true, true);
|
|
223
|
+
process.stdout.write('\n');
|
|
224
|
+
// Live mode: poll for updates
|
|
225
|
+
if (options.live && dag.is_live) {
|
|
226
|
+
process.stdout.write(chalk_1.default.gray(`Live mode: polling every ${interval}s. Press Ctrl+C to stop.\n\n`));
|
|
227
|
+
while (true) {
|
|
228
|
+
await new Promise((resolve) => setTimeout(resolve, interval * 1000));
|
|
229
|
+
try {
|
|
230
|
+
dag = await (0, api_1.request)(config, 'GET', `/workspaces/${workspaceId}/runs/${resolvedRunId}/dag`);
|
|
231
|
+
}
|
|
232
|
+
catch {
|
|
233
|
+
// Ignore transient errors during polling
|
|
234
|
+
continue;
|
|
235
|
+
}
|
|
236
|
+
if (options.json) {
|
|
237
|
+
(0, output_1.printJson)(dag);
|
|
238
|
+
}
|
|
239
|
+
else {
|
|
240
|
+
clearScreen();
|
|
241
|
+
renderDagHeader(dag);
|
|
242
|
+
process.stdout.write('\n');
|
|
243
|
+
renderDagTree(dag.tree, ' ', true, true);
|
|
244
|
+
process.stdout.write('\n');
|
|
245
|
+
}
|
|
246
|
+
if (!dag.is_live) {
|
|
247
|
+
process.stdout.write(chalk_1.default.green('Execution complete.\n'));
|
|
248
|
+
break;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
else if (options.live && !dag.is_live) {
|
|
253
|
+
process.stdout.write(chalk_1.default.gray('Run is not active. Showing final state.\n'));
|
|
254
|
+
}
|
|
255
|
+
// Footer hints
|
|
256
|
+
process.stdout.write(chalk_1.default.gray(`View trace: orch trace ${resolvedRunId.slice(0, 8)}\n`) +
|
|
257
|
+
chalk_1.default.gray(`View logs: orch logs ${resolvedRunId.slice(0, 8)}\n`));
|
|
258
|
+
});
|
|
259
|
+
}
|
package/dist/commands/env.js
CHANGED
|
@@ -43,6 +43,7 @@ const fs = __importStar(require("fs/promises"));
|
|
|
43
43
|
const config_1 = require("../lib/config");
|
|
44
44
|
const api_1 = require("../lib/api");
|
|
45
45
|
const errors_1 = require("../lib/errors");
|
|
46
|
+
const output_1 = require("../lib/output");
|
|
46
47
|
const analytics_1 = require("../lib/analytics");
|
|
47
48
|
async function resolveWorkspaceId(config, slug) {
|
|
48
49
|
const configFile = await (0, config_1.loadConfig)();
|
|
@@ -83,6 +84,10 @@ function statusColor(status) {
|
|
|
83
84
|
async function listEnvs(config, options) {
|
|
84
85
|
const workspaceId = await resolveWorkspaceId(config, options.workspace);
|
|
85
86
|
const result = await (0, api_1.listEnvironments)(config, workspaceId);
|
|
87
|
+
if (options.json) {
|
|
88
|
+
(0, output_1.printJson)(result);
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
86
91
|
if (result.environments.length === 0) {
|
|
87
92
|
console.log(chalk_1.default.gray('No environments found.'));
|
|
88
93
|
console.log(chalk_1.default.gray('Use `orchagent env create` to create one, or include a Dockerfile in your agent bundle.'));
|
|
@@ -108,7 +113,7 @@ async function listEnvs(config, options) {
|
|
|
108
113
|
statusColor(env.build?.status),
|
|
109
114
|
env.agent_count.toString(),
|
|
110
115
|
env.environment.is_predefined ? chalk_1.default.blue('predefined') : chalk_1.default.gray('custom'),
|
|
111
|
-
env.environment.id
|
|
116
|
+
env.environment.id,
|
|
112
117
|
]);
|
|
113
118
|
}
|
|
114
119
|
console.log();
|
|
@@ -123,8 +128,12 @@ async function listEnvs(config, options) {
|
|
|
123
128
|
}
|
|
124
129
|
}
|
|
125
130
|
}
|
|
126
|
-
async function getEnvStatus(config, environmentId) {
|
|
131
|
+
async function getEnvStatus(config, environmentId, options) {
|
|
127
132
|
const result = await (0, api_1.getEnvironment)(config, environmentId);
|
|
133
|
+
if (options.json) {
|
|
134
|
+
(0, output_1.printJson)(result);
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
128
137
|
console.log();
|
|
129
138
|
console.log(chalk_1.default.bold(`Environment: ${result.environment.name}`));
|
|
130
139
|
console.log();
|
|
@@ -206,6 +215,7 @@ function registerEnvCommand(program) {
|
|
|
206
215
|
.command('list')
|
|
207
216
|
.description('List environments in workspace')
|
|
208
217
|
.option('-w, --workspace <slug>', 'Workspace slug')
|
|
218
|
+
.option('--json', 'Output as JSON')
|
|
209
219
|
.action(async (options) => {
|
|
210
220
|
const config = await (0, config_1.getResolvedConfig)();
|
|
211
221
|
await listEnvs(config, options);
|
|
@@ -213,9 +223,10 @@ function registerEnvCommand(program) {
|
|
|
213
223
|
env
|
|
214
224
|
.command('status <environment-id>')
|
|
215
225
|
.description('Check environment build status')
|
|
216
|
-
.
|
|
226
|
+
.option('--json', 'Output as JSON')
|
|
227
|
+
.action(async (environmentId, options) => {
|
|
217
228
|
const config = await (0, config_1.getResolvedConfig)();
|
|
218
|
-
await getEnvStatus(config, environmentId);
|
|
229
|
+
await getEnvStatus(config, environmentId, options);
|
|
219
230
|
});
|
|
220
231
|
env
|
|
221
232
|
.command('create')
|
package/dist/commands/fork.js
CHANGED
|
@@ -36,16 +36,16 @@ async function resolveWorkspace(config, workspaceSlug) {
|
|
|
36
36
|
function registerForkCommand(program) {
|
|
37
37
|
program
|
|
38
38
|
.command('fork <agent>')
|
|
39
|
-
.description('Fork
|
|
39
|
+
.description('Fork an agent into your workspace')
|
|
40
40
|
.option('--name <new-name>', 'Rename the forked agent')
|
|
41
41
|
.option('-w, --workspace <workspace-slug>', 'Target workspace slug')
|
|
42
42
|
.option('--json', 'Output raw JSON')
|
|
43
43
|
.addHelpText('after', `
|
|
44
44
|
Examples:
|
|
45
|
-
orch fork orchagent/
|
|
46
|
-
orch fork orchagent/
|
|
47
|
-
orch fork orchagent/
|
|
48
|
-
orch fork
|
|
45
|
+
orch fork orchagent/security-agent
|
|
46
|
+
orch fork orchagent/security-agent --workspace acme-corp
|
|
47
|
+
orch fork orchagent/security-agent --name my-security-scanner
|
|
48
|
+
orch fork joe/my-agent --workspace acme-corp # fork your own private agent into another workspace
|
|
49
49
|
`)
|
|
50
50
|
.action(async (agentRef, options) => {
|
|
51
51
|
const write = (message) => {
|
|
@@ -58,7 +58,7 @@ Examples:
|
|
|
58
58
|
}
|
|
59
59
|
const { org, agent, version } = (0, agent_ref_1.parseAgentRef)(agentRef);
|
|
60
60
|
write('Resolving source agent...\n');
|
|
61
|
-
const source = await (0, api_1.
|
|
61
|
+
const source = await (0, api_1.getAgentWithFallback)(config, org, agent, version);
|
|
62
62
|
if (!source.id) {
|
|
63
63
|
throw new errors_1.CliError(`Could not resolve source agent ID for '${org}/${agent}@${version}'.`);
|
|
64
64
|
}
|
package/dist/commands/index.js
CHANGED
|
@@ -3,12 +3,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.registerCommands = registerCommands;
|
|
4
4
|
const login_1 = require("./login");
|
|
5
5
|
const logout_1 = require("./logout");
|
|
6
|
-
const call_1 = require("./call");
|
|
7
6
|
const agents_1 = require("./agents");
|
|
8
7
|
const init_1 = require("./init");
|
|
9
8
|
const publish_1 = require("./publish");
|
|
10
9
|
const whoami_1 = require("./whoami");
|
|
11
|
-
const keys_1 = require("./keys");
|
|
12
10
|
const run_1 = require("./run");
|
|
13
11
|
const info_1 = require("./info");
|
|
14
12
|
const skill_1 = require("./skill");
|
|
@@ -43,17 +41,16 @@ const estimate_1 = require("./estimate");
|
|
|
43
41
|
const replay_1 = require("./replay");
|
|
44
42
|
const trace_1 = require("./trace");
|
|
45
43
|
const metrics_1 = require("./metrics");
|
|
44
|
+
const dag_1 = require("./dag");
|
|
46
45
|
function registerCommands(program) {
|
|
47
46
|
(0, login_1.registerLoginCommand)(program);
|
|
48
47
|
(0, logout_1.registerLogoutCommand)(program);
|
|
49
48
|
(0, whoami_1.registerWhoamiCommand)(program);
|
|
50
49
|
(0, init_1.registerInitCommand)(program);
|
|
51
50
|
(0, publish_1.registerPublishCommand)(program);
|
|
52
|
-
(0, call_1.registerCallCommand)(program);
|
|
53
51
|
(0, run_1.registerRunCommand)(program);
|
|
54
52
|
(0, info_1.registerInfoCommand)(program);
|
|
55
53
|
(0, agents_1.registerAgentsCommand)(program);
|
|
56
|
-
(0, keys_1.registerKeysCommand)(program);
|
|
57
54
|
(0, skill_1.registerSkillCommand)(program);
|
|
58
55
|
(0, delete_1.registerDeleteCommand)(program);
|
|
59
56
|
(0, fork_1.registerForkCommand)(program);
|
|
@@ -86,4 +83,5 @@ function registerCommands(program) {
|
|
|
86
83
|
(0, replay_1.registerReplayCommand)(program);
|
|
87
84
|
(0, trace_1.registerTraceCommand)(program);
|
|
88
85
|
(0, metrics_1.registerMetricsCommand)(program);
|
|
86
|
+
(0, dag_1.registerDagCommand)(program);
|
|
89
87
|
}
|
package/dist/commands/publish.js
CHANGED
|
@@ -982,6 +982,26 @@ function registerPublishCommand(program) {
|
|
|
982
982
|
` the field to use the default) and republish each dependency.\n\n`);
|
|
983
983
|
}
|
|
984
984
|
}
|
|
985
|
+
// C-1: Block publish if tool/agent type has no required_secrets declared.
|
|
986
|
+
// Prompt and skill types are exempt (prompt agents get LLM keys from platform,
|
|
987
|
+
// skills don't run standalone).
|
|
988
|
+
// An explicit empty array (required_secrets: []) is a valid declaration
|
|
989
|
+
// meaning "this agent deliberately needs no secrets."
|
|
990
|
+
// Runs before dry-run so --dry-run catches the same errors as real publish (BUG-11).
|
|
991
|
+
if ((canonicalType === 'tool' || canonicalType === 'agent') &&
|
|
992
|
+
manifest.required_secrets === undefined &&
|
|
993
|
+
options.requiredSecrets !== false) {
|
|
994
|
+
process.stderr.write(chalk_1.default.red(`\nError: ${canonicalType} agents must declare required_secrets in orchagent.json.\n\n`) +
|
|
995
|
+
` Add the env vars your code needs at runtime:\n` +
|
|
996
|
+
` ${chalk_1.default.cyan('"required_secrets": ["ANTHROPIC_API_KEY", "MY_TOKEN"]')}\n\n` +
|
|
997
|
+
` If this agent genuinely needs no secrets, add an empty array:\n` +
|
|
998
|
+
` ${chalk_1.default.cyan('"required_secrets": []')}\n\n` +
|
|
999
|
+
` These are matched by name against your workspace secrets vault.\n` +
|
|
1000
|
+
` Use ${chalk_1.default.cyan('--no-required-secrets')} to skip this check.\n`);
|
|
1001
|
+
const err = new errors_1.CliError('Missing required_secrets declaration', errors_1.ExitCodes.INVALID_INPUT);
|
|
1002
|
+
err.displayed = true;
|
|
1003
|
+
throw err;
|
|
1004
|
+
}
|
|
985
1005
|
// Handle dry-run for agents
|
|
986
1006
|
if (options.dryRun) {
|
|
987
1007
|
const preview = await (0, api_1.previewAgentVersion)(config, manifest.name, workspaceId);
|
|
@@ -1166,25 +1186,6 @@ function registerPublishCommand(program) {
|
|
|
1166
1186
|
` env var to detect the reserved port.\n\n`);
|
|
1167
1187
|
}
|
|
1168
1188
|
}
|
|
1169
|
-
// C-1: Block publish if tool/agent type has no required_secrets declared.
|
|
1170
|
-
// Prompt and skill types are exempt (prompt agents get LLM keys from platform,
|
|
1171
|
-
// skills don't run standalone).
|
|
1172
|
-
// An explicit empty array (required_secrets: []) is a valid declaration
|
|
1173
|
-
// meaning "this agent deliberately needs no secrets."
|
|
1174
|
-
if ((canonicalType === 'tool' || canonicalType === 'agent') &&
|
|
1175
|
-
manifest.required_secrets === undefined &&
|
|
1176
|
-
options.requiredSecrets !== false) {
|
|
1177
|
-
process.stderr.write(chalk_1.default.red(`\nError: ${canonicalType} agents must declare required_secrets in orchagent.json.\n\n`) +
|
|
1178
|
-
` Add the env vars your code needs at runtime:\n` +
|
|
1179
|
-
` ${chalk_1.default.cyan('"required_secrets": ["ANTHROPIC_API_KEY", "MY_TOKEN"]')}\n\n` +
|
|
1180
|
-
` If this agent genuinely needs no secrets, add an empty array:\n` +
|
|
1181
|
-
` ${chalk_1.default.cyan('"required_secrets": []')}\n\n` +
|
|
1182
|
-
` These are matched by name against your workspace secrets vault.\n` +
|
|
1183
|
-
` Use ${chalk_1.default.cyan('--no-required-secrets')} to skip this check.\n`);
|
|
1184
|
-
const err = new errors_1.CliError('Missing required_secrets declaration', errors_1.ExitCodes.INVALID_INPUT);
|
|
1185
|
-
err.displayed = true;
|
|
1186
|
-
throw err;
|
|
1187
|
-
}
|
|
1188
1189
|
// Create the agent (server auto-assigns version)
|
|
1189
1190
|
let result;
|
|
1190
1191
|
try {
|
package/package.json
CHANGED
package/dist/commands/call.js
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.registerCallCommand = registerCallCommand;
|
|
4
|
-
/**
|
|
5
|
-
* Deprecated: The 'call' command has been merged into 'run'.
|
|
6
|
-
* Cloud execution is now the default behavior of 'orchagent run'.
|
|
7
|
-
* This file provides a thin alias that prints a deprecation notice and exits.
|
|
8
|
-
*/
|
|
9
|
-
function registerCallCommand(program) {
|
|
10
|
-
program
|
|
11
|
-
.command('call')
|
|
12
|
-
.description('Deprecated: use "orchagent run" instead')
|
|
13
|
-
.allowUnknownOption()
|
|
14
|
-
.allowExcessArguments()
|
|
15
|
-
.action(() => {
|
|
16
|
-
process.stderr.write(`The 'call' command has been merged into 'run'.\n\n` +
|
|
17
|
-
`Cloud execution is now the default behavior of 'orchagent run':\n` +
|
|
18
|
-
` orchagent run <agent> --data '{...}' # runs on server (cloud)\n` +
|
|
19
|
-
` orchagent run <agent> --local --data '...' # runs locally\n\n` +
|
|
20
|
-
`Replace 'orchagent call' with 'orchagent run' in your commands.\n`);
|
|
21
|
-
process.exit(1);
|
|
22
|
-
});
|
|
23
|
-
}
|
package/dist/commands/keys.js
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.registerKeysCommand = registerKeysCommand;
|
|
7
|
-
const chalk_1 = __importDefault(require("chalk"));
|
|
8
|
-
function registerKeysCommand(program) {
|
|
9
|
-
program
|
|
10
|
-
.command('keys')
|
|
11
|
-
.description('(Deprecated) Use "orch secrets" instead')
|
|
12
|
-
.allowUnknownOption(true)
|
|
13
|
-
.action(() => {
|
|
14
|
-
process.stderr.write(chalk_1.default.yellow('\nThe `orch keys` command has been removed.\n\n') +
|
|
15
|
-
`LLM API keys are now managed through the unified workspace secrets vault.\n` +
|
|
16
|
-
`Use ${chalk_1.default.cyan('orch secrets')} instead:\n\n` +
|
|
17
|
-
` ${chalk_1.default.cyan('orch secrets set ANTHROPIC_API_KEY <key>')} Add an LLM key\n` +
|
|
18
|
-
` ${chalk_1.default.cyan('orch secrets list')} List all secrets\n` +
|
|
19
|
-
` ${chalk_1.default.cyan('orch secrets delete ANTHROPIC_API_KEY')} Remove a key\n\n`);
|
|
20
|
-
process.exit(1);
|
|
21
|
-
});
|
|
22
|
-
}
|