@eve-horizon/cli 0.2.1 → 0.2.5
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/auth.js +40 -0
- package/dist/commands/build.js +350 -0
- package/dist/commands/env.js +7 -2
- package/dist/commands/org.js +2 -1
- package/dist/commands/profile.js +2 -1
- package/dist/commands/system.js +124 -3
- package/dist/index.js +4 -0
- package/dist/lib/help.js +147 -2
- package/package.json +1 -1
package/dist/commands/auth.js
CHANGED
|
@@ -271,6 +271,46 @@ async function handleAuth(subcommand, flags, context, credentials) {
|
|
|
271
271
|
console.log(tokenEntry.access_token);
|
|
272
272
|
return;
|
|
273
273
|
}
|
|
274
|
+
case 'mint': {
|
|
275
|
+
const email = (0, args_1.getStringFlag)(flags, ['email']);
|
|
276
|
+
const orgId = (0, args_1.getStringFlag)(flags, ['org']);
|
|
277
|
+
const projectId = (0, args_1.getStringFlag)(flags, ['project']);
|
|
278
|
+
const role = (0, args_1.getStringFlag)(flags, ['role']) ?? 'member';
|
|
279
|
+
const ttlStr = (0, args_1.getStringFlag)(flags, ['ttl']);
|
|
280
|
+
const ttlDays = ttlStr ? parseInt(ttlStr, 10) : undefined;
|
|
281
|
+
if (ttlDays !== undefined && (isNaN(ttlDays) || ttlDays < 1 || ttlDays > 90)) {
|
|
282
|
+
throw new Error('--ttl must be between 1 and 90 days');
|
|
283
|
+
}
|
|
284
|
+
if (!email) {
|
|
285
|
+
throw new Error('Usage: eve auth mint --email <email> [--org <org_id> | --project <project_id>] [--role <role>]');
|
|
286
|
+
}
|
|
287
|
+
if (!orgId && !projectId) {
|
|
288
|
+
throw new Error('Usage: eve auth mint --email <email> [--org <org_id> | --project <project_id>] [--role <role>]');
|
|
289
|
+
}
|
|
290
|
+
if (!['admin', 'member'].includes(role)) {
|
|
291
|
+
throw new Error(`Invalid role: ${role}. Must be one of: admin, member`);
|
|
292
|
+
}
|
|
293
|
+
const response = await (0, client_1.requestJson)(context, '/auth/mint', {
|
|
294
|
+
method: 'POST',
|
|
295
|
+
body: {
|
|
296
|
+
email,
|
|
297
|
+
org_id: orgId,
|
|
298
|
+
project_id: projectId,
|
|
299
|
+
role,
|
|
300
|
+
ttl_days: ttlDays,
|
|
301
|
+
},
|
|
302
|
+
});
|
|
303
|
+
if (json) {
|
|
304
|
+
(0, output_1.outputJson)(response, json);
|
|
305
|
+
return;
|
|
306
|
+
}
|
|
307
|
+
if (!response.access_token) {
|
|
308
|
+
throw new Error('Mint response missing access_token');
|
|
309
|
+
}
|
|
310
|
+
// Print only the token to stdout, nothing else
|
|
311
|
+
console.log(response.access_token);
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
274
314
|
case 'sync': {
|
|
275
315
|
const claudeOnly = (0, args_1.getBooleanFlag)(flags, ['claude']) ?? false;
|
|
276
316
|
const codexOnly = (0, args_1.getBooleanFlag)(flags, ['codex']) ?? false;
|
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.handleBuild = handleBuild;
|
|
4
|
+
const args_1 = require("../lib/args");
|
|
5
|
+
const client_1 = require("../lib/client");
|
|
6
|
+
const output_1 = require("../lib/output");
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
// Entry point
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
async function handleBuild(subcommand, positionals, flags, context) {
|
|
11
|
+
const json = Boolean(flags.json);
|
|
12
|
+
switch (subcommand) {
|
|
13
|
+
case 'create':
|
|
14
|
+
return handleCreate(flags, context, json);
|
|
15
|
+
case 'list':
|
|
16
|
+
return handleList(positionals, flags, context, json);
|
|
17
|
+
case 'show':
|
|
18
|
+
return handleShow(positionals, flags, context, json);
|
|
19
|
+
case 'run':
|
|
20
|
+
return handleRun(positionals, flags, context, json);
|
|
21
|
+
case 'runs':
|
|
22
|
+
return handleRuns(positionals, flags, context, json);
|
|
23
|
+
case 'logs':
|
|
24
|
+
return handleLogs(positionals, flags, context, json);
|
|
25
|
+
case 'artifacts':
|
|
26
|
+
return handleArtifacts(positionals, flags, context, json);
|
|
27
|
+
case 'diagnose':
|
|
28
|
+
return handleDiagnose(positionals, flags, context, json);
|
|
29
|
+
case 'cancel':
|
|
30
|
+
return handleCancel(positionals, flags, context, json);
|
|
31
|
+
default:
|
|
32
|
+
throw new Error('Usage: eve build <create|list|show|run|runs|logs|artifacts|diagnose|cancel>\n' +
|
|
33
|
+
' create --project <id> --ref <sha> [--services <list>] - create a build spec\n' +
|
|
34
|
+
' list [--project <id>] - list build specs\n' +
|
|
35
|
+
' show <build_id> - show build spec details\n' +
|
|
36
|
+
' run <build_id> - start a build run\n' +
|
|
37
|
+
' runs <build_id> - list runs for a build\n' +
|
|
38
|
+
' logs <build_id> [--run <id>] - show build logs\n' +
|
|
39
|
+
' artifacts <build_id> - list build artifacts\n' +
|
|
40
|
+
' diagnose <build_id> - show full build state\n' +
|
|
41
|
+
' cancel <build_id> - cancel active build run');
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
// ---------------------------------------------------------------------------
|
|
45
|
+
// Subcommands
|
|
46
|
+
// ---------------------------------------------------------------------------
|
|
47
|
+
async function handleCreate(flags, context, json) {
|
|
48
|
+
const projectId = (0, args_1.getStringFlag)(flags, ['project']) ?? context.projectId;
|
|
49
|
+
const ref = (0, args_1.getStringFlag)(flags, ['ref']);
|
|
50
|
+
const manifestHash = (0, args_1.getStringFlag)(flags, ['manifest-hash', 'manifest']);
|
|
51
|
+
const services = (0, args_1.getStringFlag)(flags, ['services']);
|
|
52
|
+
if (!projectId || !ref || !manifestHash) {
|
|
53
|
+
throw new Error('Usage: eve build create --project <id> --ref <sha> --manifest-hash <hash> [--services <s1,s2>]');
|
|
54
|
+
}
|
|
55
|
+
const body = { git_sha: ref, manifest_hash: manifestHash };
|
|
56
|
+
if (services) {
|
|
57
|
+
body.services = services.split(',').map(s => s.trim());
|
|
58
|
+
}
|
|
59
|
+
const build = await (0, client_1.requestJson)(context, `/projects/${projectId}/builds`, { method: 'POST', body });
|
|
60
|
+
if (json) {
|
|
61
|
+
(0, output_1.outputJson)(build, json);
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
console.log(`Build created: ${build.id}`);
|
|
65
|
+
console.log(` Project: ${build.project_id}`);
|
|
66
|
+
console.log(` SHA: ${build.git_sha}`);
|
|
67
|
+
if (build.manifest_hash) {
|
|
68
|
+
console.log(` Manifest: ${build.manifest_hash.substring(0, 12)}...`);
|
|
69
|
+
}
|
|
70
|
+
console.log(` Created: ${build.created_at}`);
|
|
71
|
+
}
|
|
72
|
+
async function handleList(positionals, flags, context, json) {
|
|
73
|
+
const projectId = positionals[0] ?? (0, args_1.getStringFlag)(flags, ['project']) ?? context.projectId;
|
|
74
|
+
if (!projectId) {
|
|
75
|
+
throw new Error('Usage: eve build list [--project <id>]');
|
|
76
|
+
}
|
|
77
|
+
const query = buildQuery({
|
|
78
|
+
limit: (0, args_1.getStringFlag)(flags, ['limit']),
|
|
79
|
+
offset: (0, args_1.getStringFlag)(flags, ['offset']),
|
|
80
|
+
});
|
|
81
|
+
const response = await (0, client_1.requestJson)(context, `/projects/${projectId}/builds${query}`);
|
|
82
|
+
if (json) {
|
|
83
|
+
(0, output_1.outputJson)(response, json);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
if (response.data.length === 0) {
|
|
87
|
+
console.log('No builds found.');
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
formatBuildList(response.data);
|
|
91
|
+
}
|
|
92
|
+
async function handleShow(positionals, flags, context, json) {
|
|
93
|
+
const buildId = positionals[0] ?? (0, args_1.getStringFlag)(flags, ['id']);
|
|
94
|
+
if (!buildId) {
|
|
95
|
+
throw new Error('Usage: eve build show <build_id>');
|
|
96
|
+
}
|
|
97
|
+
const build = await (0, client_1.requestJson)(context, `/builds/${buildId}`);
|
|
98
|
+
if (json) {
|
|
99
|
+
(0, output_1.outputJson)(build, json);
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
formatBuildDetail(build);
|
|
103
|
+
}
|
|
104
|
+
async function handleRun(positionals, flags, context, json) {
|
|
105
|
+
const buildId = positionals[0] ?? (0, args_1.getStringFlag)(flags, ['id']);
|
|
106
|
+
if (!buildId) {
|
|
107
|
+
throw new Error('Usage: eve build run <build_id>');
|
|
108
|
+
}
|
|
109
|
+
const run = await (0, client_1.requestJson)(context, `/builds/${buildId}/runs`, { method: 'POST' });
|
|
110
|
+
if (json) {
|
|
111
|
+
(0, output_1.outputJson)(run, json);
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
console.log(`Build run started: ${run.id}`);
|
|
115
|
+
console.log(` Build: ${run.build_id}`);
|
|
116
|
+
console.log(` Status: ${run.status}`);
|
|
117
|
+
if (run.backend) {
|
|
118
|
+
console.log(` Backend: ${run.backend}`);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
async function handleRuns(positionals, flags, context, json) {
|
|
122
|
+
const buildId = positionals[0] ?? (0, args_1.getStringFlag)(flags, ['id']);
|
|
123
|
+
if (!buildId) {
|
|
124
|
+
throw new Error('Usage: eve build runs <build_id>');
|
|
125
|
+
}
|
|
126
|
+
const query = buildQuery({
|
|
127
|
+
limit: (0, args_1.getStringFlag)(flags, ['limit']),
|
|
128
|
+
offset: (0, args_1.getStringFlag)(flags, ['offset']),
|
|
129
|
+
});
|
|
130
|
+
const response = await (0, client_1.requestJson)(context, `/builds/${buildId}/runs${query}`);
|
|
131
|
+
if (json) {
|
|
132
|
+
(0, output_1.outputJson)(response, json);
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
if (response.data.length === 0) {
|
|
136
|
+
console.log('No runs found for this build.');
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
formatRunList(response.data);
|
|
140
|
+
}
|
|
141
|
+
async function handleLogs(positionals, flags, context, json) {
|
|
142
|
+
const buildId = positionals[0] ?? (0, args_1.getStringFlag)(flags, ['id']);
|
|
143
|
+
const runId = (0, args_1.getStringFlag)(flags, ['run']);
|
|
144
|
+
if (!buildId) {
|
|
145
|
+
throw new Error('Usage: eve build logs <build_id> [--run <run_id>]');
|
|
146
|
+
}
|
|
147
|
+
const query = runId ? `?run_id=${encodeURIComponent(runId)}` : '';
|
|
148
|
+
const logs = await (0, client_1.requestJson)(context, `/builds/${buildId}/logs${query}`);
|
|
149
|
+
if (json) {
|
|
150
|
+
(0, output_1.outputJson)(logs, json);
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
if (logs.logs.length === 0) {
|
|
154
|
+
console.log('No logs available.');
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
for (const entry of logs.logs) {
|
|
158
|
+
const line = entry.line;
|
|
159
|
+
if (typeof line.message === 'string') {
|
|
160
|
+
console.log(line.message);
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
163
|
+
if (Array.isArray(line.lines)) {
|
|
164
|
+
for (const item of line.lines) {
|
|
165
|
+
if (typeof item === 'string') {
|
|
166
|
+
console.log(item);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
171
|
+
console.log(JSON.stringify(line));
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
async function handleArtifacts(positionals, flags, context, json) {
|
|
175
|
+
const buildId = positionals[0] ?? (0, args_1.getStringFlag)(flags, ['id']);
|
|
176
|
+
if (!buildId) {
|
|
177
|
+
throw new Error('Usage: eve build artifacts <build_id>');
|
|
178
|
+
}
|
|
179
|
+
const response = await (0, client_1.requestJson)(context, `/builds/${buildId}/artifacts`);
|
|
180
|
+
if (json) {
|
|
181
|
+
(0, output_1.outputJson)(response, json);
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
if (response.data.length === 0) {
|
|
185
|
+
console.log('No artifacts found for this build.');
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
formatArtifactList(response.data);
|
|
189
|
+
}
|
|
190
|
+
async function handleCancel(positionals, flags, context, json) {
|
|
191
|
+
const buildId = positionals[0] ?? (0, args_1.getStringFlag)(flags, ['id']);
|
|
192
|
+
if (!buildId) {
|
|
193
|
+
throw new Error('Usage: eve build cancel <build_id>');
|
|
194
|
+
}
|
|
195
|
+
const result = await (0, client_1.requestJson)(context, `/builds/${buildId}/cancel`, { method: 'POST' });
|
|
196
|
+
if (json) {
|
|
197
|
+
(0, output_1.outputJson)(result, json);
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
console.log(`Build cancelled: ${buildId}`);
|
|
201
|
+
}
|
|
202
|
+
async function handleDiagnose(positionals, flags, context, json) {
|
|
203
|
+
const buildId = positionals[0] ?? (0, args_1.getStringFlag)(flags, ['id']);
|
|
204
|
+
if (!buildId) {
|
|
205
|
+
throw new Error('Usage: eve build diagnose <build_id>');
|
|
206
|
+
}
|
|
207
|
+
const spec = await (0, client_1.requestJson)(context, `/builds/${buildId}`);
|
|
208
|
+
const runs = await (0, client_1.requestJson)(context, `/builds/${buildId}/runs?limit=20&offset=0`);
|
|
209
|
+
const artifacts = await (0, client_1.requestJson)(context, `/builds/${buildId}/artifacts`);
|
|
210
|
+
const latestRun = runs.data[0];
|
|
211
|
+
const logs = latestRun
|
|
212
|
+
? await (0, client_1.requestJson)(context, `/builds/${buildId}/logs?run_id=${encodeURIComponent(latestRun.id)}`)
|
|
213
|
+
: { logs: [] };
|
|
214
|
+
const payload = { spec, runs: runs.data, artifacts: artifacts.data, logs: logs.logs };
|
|
215
|
+
if (json) {
|
|
216
|
+
(0, output_1.outputJson)(payload, json);
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
console.log(`Build diagnose: ${spec.id}`);
|
|
220
|
+
formatBuildDetail(spec);
|
|
221
|
+
console.log('');
|
|
222
|
+
if (runs.data.length > 0) {
|
|
223
|
+
formatRunList(runs.data);
|
|
224
|
+
}
|
|
225
|
+
else {
|
|
226
|
+
console.log('No runs found.');
|
|
227
|
+
}
|
|
228
|
+
console.log('');
|
|
229
|
+
if (artifacts.data.length > 0) {
|
|
230
|
+
formatArtifactList(artifacts.data);
|
|
231
|
+
}
|
|
232
|
+
else {
|
|
233
|
+
console.log('No artifacts found.');
|
|
234
|
+
}
|
|
235
|
+
console.log('');
|
|
236
|
+
if (logs.logs.length > 0) {
|
|
237
|
+
console.log('Recent logs:');
|
|
238
|
+
for (const entry of logs.logs.slice(-50)) {
|
|
239
|
+
const line = entry.line;
|
|
240
|
+
if (typeof line.message === 'string') {
|
|
241
|
+
console.log(line.message);
|
|
242
|
+
continue;
|
|
243
|
+
}
|
|
244
|
+
if (Array.isArray(line.lines)) {
|
|
245
|
+
for (const item of line.lines) {
|
|
246
|
+
if (typeof item === 'string') {
|
|
247
|
+
console.log(item);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
continue;
|
|
251
|
+
}
|
|
252
|
+
console.log(JSON.stringify(line));
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
else {
|
|
256
|
+
console.log('No logs found.');
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
// ---------------------------------------------------------------------------
|
|
260
|
+
// Formatters
|
|
261
|
+
// ---------------------------------------------------------------------------
|
|
262
|
+
function formatBuildList(builds) {
|
|
263
|
+
console.log('Build ID'.padEnd(30) + 'SHA'.padEnd(12) + 'Created By'.padEnd(20) + 'Created');
|
|
264
|
+
console.log('-'.repeat(90));
|
|
265
|
+
for (const build of builds) {
|
|
266
|
+
const id = build.id.padEnd(30);
|
|
267
|
+
const sha = build.git_sha.substring(0, 8).padEnd(12);
|
|
268
|
+
const creator = (build.created_by ?? '-').padEnd(20);
|
|
269
|
+
const created = new Date(build.created_at).toLocaleString();
|
|
270
|
+
console.log(`${id}${sha}${creator}${created}`);
|
|
271
|
+
}
|
|
272
|
+
console.log('');
|
|
273
|
+
console.log(`Total: ${builds.length} builds`);
|
|
274
|
+
}
|
|
275
|
+
function formatBuildDetail(build) {
|
|
276
|
+
console.log(`Build: ${build.id}`);
|
|
277
|
+
console.log(` Project: ${build.project_id}`);
|
|
278
|
+
console.log(` SHA: ${build.git_sha}`);
|
|
279
|
+
console.log(` Manifest Hash: ${build.manifest_hash}`);
|
|
280
|
+
console.log(` Created By: ${build.created_by ?? '-'}`);
|
|
281
|
+
console.log(` Created: ${build.created_at}`);
|
|
282
|
+
if (build.services_json) {
|
|
283
|
+
console.log(` Services: ${JSON.stringify(build.services_json)}`);
|
|
284
|
+
}
|
|
285
|
+
if (build.inputs_json) {
|
|
286
|
+
console.log(` Inputs: ${JSON.stringify(build.inputs_json)}`);
|
|
287
|
+
}
|
|
288
|
+
if (build.registry_json) {
|
|
289
|
+
console.log(` Registry: ${JSON.stringify(build.registry_json)}`);
|
|
290
|
+
}
|
|
291
|
+
if (build.cache_json) {
|
|
292
|
+
console.log(` Cache: ${JSON.stringify(build.cache_json)}`);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
function formatRunList(runs) {
|
|
296
|
+
console.log('Run ID'.padEnd(30) + 'Status'.padEnd(15) + 'Backend'.padEnd(15) + 'Started');
|
|
297
|
+
console.log('-'.repeat(80));
|
|
298
|
+
for (const run of runs) {
|
|
299
|
+
const id = run.id.padEnd(30);
|
|
300
|
+
const status = run.status.padEnd(15);
|
|
301
|
+
const backend = (run.backend ?? '-').padEnd(15);
|
|
302
|
+
const started = run.started_at ? new Date(run.started_at).toLocaleString() : '-';
|
|
303
|
+
console.log(`${id}${status}${backend}${started}`);
|
|
304
|
+
if (run.error_message) {
|
|
305
|
+
console.log(` Error: ${run.error_message}`);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
console.log('');
|
|
309
|
+
console.log(`Total: ${runs.length} runs`);
|
|
310
|
+
}
|
|
311
|
+
function formatArtifactList(artifacts) {
|
|
312
|
+
console.log('Service'.padEnd(25) + 'Image'.padEnd(50) + 'Size');
|
|
313
|
+
console.log('-'.repeat(90));
|
|
314
|
+
for (const artifact of artifacts) {
|
|
315
|
+
const service = artifact.service_name.padEnd(25);
|
|
316
|
+
const image = artifact.image_ref.padEnd(50);
|
|
317
|
+
const size = artifact.size_bytes ? formatBytes(artifact.size_bytes) : '-';
|
|
318
|
+
console.log(`${service}${image}${size}`);
|
|
319
|
+
if (artifact.digest) {
|
|
320
|
+
console.log(` Digest: ${artifact.digest}`);
|
|
321
|
+
}
|
|
322
|
+
if (artifact.platforms_json && artifact.platforms_json.length > 0) {
|
|
323
|
+
console.log(` Platforms: ${artifact.platforms_json.join(', ')}`);
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
console.log('');
|
|
327
|
+
console.log(`Total: ${artifacts.length} artifacts`);
|
|
328
|
+
}
|
|
329
|
+
function formatBytes(bytes) {
|
|
330
|
+
if (bytes < 1024)
|
|
331
|
+
return `${bytes} B`;
|
|
332
|
+
if (bytes < 1024 * 1024)
|
|
333
|
+
return `${(bytes / 1024).toFixed(1)} KB`;
|
|
334
|
+
if (bytes < 1024 * 1024 * 1024)
|
|
335
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
336
|
+
return `${(bytes / (1024 * 1024 * 1024)).toFixed(1)} GB`;
|
|
337
|
+
}
|
|
338
|
+
// ---------------------------------------------------------------------------
|
|
339
|
+
// Utilities
|
|
340
|
+
// ---------------------------------------------------------------------------
|
|
341
|
+
function buildQuery(params) {
|
|
342
|
+
const search = new URLSearchParams();
|
|
343
|
+
Object.entries(params).forEach(([key, value]) => {
|
|
344
|
+
if (value === undefined || value === '')
|
|
345
|
+
return;
|
|
346
|
+
search.set(key, value);
|
|
347
|
+
});
|
|
348
|
+
const query = search.toString();
|
|
349
|
+
return query ? `?${query}` : '';
|
|
350
|
+
}
|
package/dist/commands/env.js
CHANGED
|
@@ -161,7 +161,7 @@ async function handleCreate(positionals, flags, context, json) {
|
|
|
161
161
|
}
|
|
162
162
|
}
|
|
163
163
|
/**
|
|
164
|
-
* eve env deploy [project] <name> --ref <sha> [--direct] [--inputs <json>]
|
|
164
|
+
* eve env deploy [project] <name> --ref <sha> [--direct] [--inputs <json>] [--image-tag <tag>]
|
|
165
165
|
* Deploy to an environment
|
|
166
166
|
* If project is in profile, can use: eve env deploy <name> --ref <sha>
|
|
167
167
|
*/
|
|
@@ -194,7 +194,7 @@ async function handleDeploy(positionals, flags, context, json) {
|
|
|
194
194
|
envName = flagName;
|
|
195
195
|
}
|
|
196
196
|
if (!projectId || !envName) {
|
|
197
|
-
throw new Error('Usage: eve env deploy <env> --ref <sha> [--direct] [--inputs <json>] [--project=<id>]');
|
|
197
|
+
throw new Error('Usage: eve env deploy <env> --ref <sha> [--direct] [--inputs <json>] [--image-tag <tag>] [--project=<id>]');
|
|
198
198
|
}
|
|
199
199
|
// --ref flag is now required
|
|
200
200
|
const gitSha = (0, args_1.getStringFlag)(flags, ['ref']);
|
|
@@ -226,6 +226,8 @@ async function handleDeploy(positionals, flags, context, json) {
|
|
|
226
226
|
'Example: --inputs \'{"release_id":"rel_xxx","smoke_test":false}\'');
|
|
227
227
|
}
|
|
228
228
|
}
|
|
229
|
+
// Parse --image-tag flag (optional)
|
|
230
|
+
const imageTag = (0, args_1.getStringFlag)(flags, ['image-tag', 'image_tag', 'imageTag']);
|
|
229
231
|
// POST deployment
|
|
230
232
|
const body = {
|
|
231
233
|
git_sha: gitSha,
|
|
@@ -237,6 +239,9 @@ async function handleDeploy(positionals, flags, context, json) {
|
|
|
237
239
|
if (inputs) {
|
|
238
240
|
body.inputs = inputs;
|
|
239
241
|
}
|
|
242
|
+
if (imageTag) {
|
|
243
|
+
body.image_tag = imageTag;
|
|
244
|
+
}
|
|
240
245
|
const response = await (0, client_1.requestJson)(context, `/projects/${projectId}/envs/${envName}/deploy`, {
|
|
241
246
|
method: 'POST',
|
|
242
247
|
body,
|
package/dist/commands/org.js
CHANGED
|
@@ -12,6 +12,7 @@ async function handleOrg(subcommand, positionals, flags, context) {
|
|
|
12
12
|
case 'ensure': {
|
|
13
13
|
let orgId = typeof flags.id === 'string' ? flags.id : '';
|
|
14
14
|
let orgName = typeof flags.name === 'string' ? flags.name : '';
|
|
15
|
+
let orgSlug = typeof flags.slug === 'string' ? flags.slug : '';
|
|
15
16
|
const nameOrId = positionals[0];
|
|
16
17
|
if (!orgId && nameOrId) {
|
|
17
18
|
if (/^org_[a-zA-Z0-9]+$/.test(nameOrId)) {
|
|
@@ -25,7 +26,7 @@ async function handleOrg(subcommand, positionals, flags, context) {
|
|
|
25
26
|
}
|
|
26
27
|
orgId = orgId || context.orgId || DEFAULT_ORG_ID;
|
|
27
28
|
orgName = orgName || DEFAULT_ORG_NAME;
|
|
28
|
-
const body = { id: orgId, name: orgName };
|
|
29
|
+
const body = { id: orgId, name: orgName, ...(orgSlug ? { slug: orgSlug } : {}) };
|
|
29
30
|
const org = await (0, client_1.requestJson)(context, '/orgs/ensure', {
|
|
30
31
|
method: 'POST',
|
|
31
32
|
body,
|
package/dist/commands/profile.js
CHANGED
|
@@ -126,8 +126,9 @@ function handleProfile(subcommand, positionals, flags, config) {
|
|
|
126
126
|
config.profiles[name] = {};
|
|
127
127
|
}
|
|
128
128
|
config.profiles[name] = applyProfileFlags(config.profiles[name], flags);
|
|
129
|
+
config.active_profile = name;
|
|
129
130
|
(0, config_1.saveConfig)(config);
|
|
130
|
-
(0, output_1.outputJson)({ name, ...config.profiles[name] }, json, `✓ Profile
|
|
131
|
+
(0, output_1.outputJson)({ active_profile: name, ...config.profiles[name] }, json, `✓ Profile set: ${name}`);
|
|
131
132
|
return;
|
|
132
133
|
}
|
|
133
134
|
case 'remove': {
|
package/dist/commands/system.js
CHANGED
|
@@ -34,8 +34,10 @@ async function handleSystem(subcommand, positionals, flags, context) {
|
|
|
34
34
|
return handleConfig(context, json);
|
|
35
35
|
case 'settings':
|
|
36
36
|
return handleSettings(positionals, flags, context, json);
|
|
37
|
+
case 'orchestrator':
|
|
38
|
+
return handleOrchestrator(positionals, flags, context, json);
|
|
37
39
|
default:
|
|
38
|
-
throw new Error('Usage: eve system <status|health|jobs|envs|logs|pods|events|config|settings>');
|
|
40
|
+
throw new Error('Usage: eve system <status|health|jobs|envs|logs|pods|events|config|settings|orchestrator>');
|
|
39
41
|
}
|
|
40
42
|
}
|
|
41
43
|
// ============================================================================
|
|
@@ -61,10 +63,10 @@ async function handleStatus(context, json) {
|
|
|
61
63
|
}
|
|
62
64
|
}
|
|
63
65
|
catch (error) {
|
|
64
|
-
// If /system/status
|
|
66
|
+
// If /system/status is missing, fall back to basic health check
|
|
65
67
|
const err = error;
|
|
66
68
|
if (err.message?.includes('HTTP 404')) {
|
|
67
|
-
console.log('Note:
|
|
69
|
+
console.log('Note: /system/status not available on this API version.');
|
|
68
70
|
console.log('Falling back to basic health check...');
|
|
69
71
|
console.log('');
|
|
70
72
|
return handleHealth(context, json);
|
|
@@ -318,6 +320,47 @@ async function handleConfig(context, json) {
|
|
|
318
320
|
response.deployments.forEach((deployment) => console.log(` - ${deployment}`));
|
|
319
321
|
}
|
|
320
322
|
}
|
|
323
|
+
/**
|
|
324
|
+
* eve system orchestrator <status|set-concurrency>
|
|
325
|
+
* Manage orchestrator concurrency settings
|
|
326
|
+
*/
|
|
327
|
+
async function handleOrchestrator(positionals, flags, context, json) {
|
|
328
|
+
const subcommand = positionals[0];
|
|
329
|
+
if (subcommand === 'status') {
|
|
330
|
+
const response = await requestOrchestratorJson(context, '/system/orchestrator/status');
|
|
331
|
+
if (json) {
|
|
332
|
+
(0, output_1.outputJson)(response, json);
|
|
333
|
+
}
|
|
334
|
+
else {
|
|
335
|
+
formatOrchestratorStatus(response);
|
|
336
|
+
}
|
|
337
|
+
return;
|
|
338
|
+
}
|
|
339
|
+
if (subcommand === 'set-concurrency') {
|
|
340
|
+
const limitStr = positionals[1];
|
|
341
|
+
if (!limitStr) {
|
|
342
|
+
throw new Error('Usage: eve system orchestrator set-concurrency <n>');
|
|
343
|
+
}
|
|
344
|
+
const limit = parseInt(limitStr, 10);
|
|
345
|
+
if (isNaN(limit) || limit < 1) {
|
|
346
|
+
throw new Error('Concurrency limit must be a positive integer');
|
|
347
|
+
}
|
|
348
|
+
const response = await requestOrchestratorJson(context, '/system/orchestrator/concurrency', {
|
|
349
|
+
method: 'POST',
|
|
350
|
+
body: JSON.stringify({ limit }),
|
|
351
|
+
});
|
|
352
|
+
if (json) {
|
|
353
|
+
(0, output_1.outputJson)(response, json);
|
|
354
|
+
}
|
|
355
|
+
else {
|
|
356
|
+
console.log(`Concurrency limit updated to ${limit}`);
|
|
357
|
+
console.log('');
|
|
358
|
+
formatOrchestratorStatus(response);
|
|
359
|
+
}
|
|
360
|
+
return;
|
|
361
|
+
}
|
|
362
|
+
throw new Error('Usage: eve system orchestrator <status|set-concurrency>');
|
|
363
|
+
}
|
|
321
364
|
/**
|
|
322
365
|
* eve system settings [get <key>] [set <key> <value>]
|
|
323
366
|
* Admin only: Get or set system settings
|
|
@@ -526,3 +569,81 @@ function padRight(str, width) {
|
|
|
526
569
|
return str;
|
|
527
570
|
return str + ' '.repeat(width - str.length);
|
|
528
571
|
}
|
|
572
|
+
/**
|
|
573
|
+
* Get orchestrator URL from context.
|
|
574
|
+
* Derives from API URL by replacing the port with the orchestrator port.
|
|
575
|
+
*/
|
|
576
|
+
function getOrchestratorUrl(context) {
|
|
577
|
+
const envUrl = process.env.EVE_ORCHESTRATOR_URL;
|
|
578
|
+
if (envUrl) {
|
|
579
|
+
return envUrl;
|
|
580
|
+
}
|
|
581
|
+
// Derive from API URL by changing the port
|
|
582
|
+
const orchPort = process.env.EVE_ORCHESTRATOR_PORT || '4802';
|
|
583
|
+
const apiUrl = new URL(context.apiUrl);
|
|
584
|
+
apiUrl.port = orchPort;
|
|
585
|
+
return apiUrl.toString().replace(/\/$/, '');
|
|
586
|
+
}
|
|
587
|
+
/**
|
|
588
|
+
* Request JSON from the orchestrator service.
|
|
589
|
+
* Similar to requestJson but targets the orchestrator directly.
|
|
590
|
+
*/
|
|
591
|
+
async function requestOrchestratorJson(context, path, options) {
|
|
592
|
+
const orchUrl = getOrchestratorUrl(context);
|
|
593
|
+
const url = `${orchUrl}${path}`;
|
|
594
|
+
const headers = {};
|
|
595
|
+
if (options?.body) {
|
|
596
|
+
headers['Content-Type'] = 'application/json';
|
|
597
|
+
}
|
|
598
|
+
if (context.token) {
|
|
599
|
+
headers.Authorization = `Bearer ${context.token}`;
|
|
600
|
+
}
|
|
601
|
+
const response = await fetch(url, {
|
|
602
|
+
method: options?.method ?? 'GET',
|
|
603
|
+
headers,
|
|
604
|
+
body: options?.body,
|
|
605
|
+
});
|
|
606
|
+
const text = await response.text();
|
|
607
|
+
let data = null;
|
|
608
|
+
if (text) {
|
|
609
|
+
try {
|
|
610
|
+
data = JSON.parse(text);
|
|
611
|
+
}
|
|
612
|
+
catch {
|
|
613
|
+
data = text;
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
if (!response.ok) {
|
|
617
|
+
const message = typeof data === 'string' ? data : text;
|
|
618
|
+
throw new Error(`HTTP ${response.status}: ${message}`);
|
|
619
|
+
}
|
|
620
|
+
return data;
|
|
621
|
+
}
|
|
622
|
+
/**
|
|
623
|
+
* Format orchestrator status for human-readable output
|
|
624
|
+
*/
|
|
625
|
+
function formatOrchestratorStatus(status) {
|
|
626
|
+
console.log('Orchestrator Concurrency Status');
|
|
627
|
+
console.log('═══════════════════════════════════════');
|
|
628
|
+
console.log('');
|
|
629
|
+
console.log(` Limit: ${status.limit}`);
|
|
630
|
+
console.log(` In-Flight: ${status.inFlight}`);
|
|
631
|
+
console.log(` Uptime: ${formatUptime(status.uptimeSeconds)}`);
|
|
632
|
+
console.log(` Last Change: ${status.lastChange}`);
|
|
633
|
+
console.log('');
|
|
634
|
+
}
|
|
635
|
+
/**
|
|
636
|
+
* Format uptime seconds to human-readable format
|
|
637
|
+
*/
|
|
638
|
+
function formatUptime(seconds) {
|
|
639
|
+
const hours = Math.floor(seconds / 3600);
|
|
640
|
+
const minutes = Math.floor((seconds % 3600) / 60);
|
|
641
|
+
const secs = seconds % 60;
|
|
642
|
+
if (hours > 0) {
|
|
643
|
+
return `${hours}h ${minutes}m ${secs}s`;
|
|
644
|
+
}
|
|
645
|
+
if (minutes > 0) {
|
|
646
|
+
return `${minutes}m ${secs}s`;
|
|
647
|
+
}
|
|
648
|
+
return `${secs}s`;
|
|
649
|
+
}
|
package/dist/index.js
CHANGED
|
@@ -25,6 +25,7 @@ const agents_1 = require("./commands/agents");
|
|
|
25
25
|
const init_1 = require("./commands/init");
|
|
26
26
|
const release_1 = require("./commands/release");
|
|
27
27
|
const manifest_1 = require("./commands/manifest");
|
|
28
|
+
const build_1 = require("./commands/build");
|
|
28
29
|
async function main() {
|
|
29
30
|
const { flags, positionals } = (0, args_1.parseArgs)(process.argv.slice(2));
|
|
30
31
|
const command = positionals[0];
|
|
@@ -111,6 +112,9 @@ async function main() {
|
|
|
111
112
|
case 'manifest':
|
|
112
113
|
await (0, manifest_1.handleManifest)(subcommand, rest, flags, context);
|
|
113
114
|
return;
|
|
115
|
+
case 'build':
|
|
116
|
+
await (0, build_1.handleBuild)(subcommand, rest, flags, context);
|
|
117
|
+
return;
|
|
114
118
|
default:
|
|
115
119
|
(0, help_1.showMainHelp)();
|
|
116
120
|
}
|
package/dist/lib/help.js
CHANGED
|
@@ -598,7 +598,7 @@ have to specify them on every command. Useful when working with multiple environ
|
|
|
598
598
|
auth: {
|
|
599
599
|
description: `Authenticate with Eve Horizon. Auth is optional for local development but required
|
|
600
600
|
for cloud deployments. Credentials are stored per-profile.`,
|
|
601
|
-
usage: 'eve auth <login|logout|status|whoami|bootstrap|sync|creds|token>',
|
|
601
|
+
usage: 'eve auth <login|logout|status|whoami|bootstrap|sync|creds|token|mint>',
|
|
602
602
|
subcommands: {
|
|
603
603
|
login: {
|
|
604
604
|
description: 'Login via GitHub SSH challenge (default) or Supabase (legacy)',
|
|
@@ -643,6 +643,23 @@ for cloud deployments. Credentials are stored per-profile.`,
|
|
|
643
643
|
'eve auth token # Share with reviewers for PR preview access',
|
|
644
644
|
],
|
|
645
645
|
},
|
|
646
|
+
mint: {
|
|
647
|
+
description: 'Mint a user token (admin-only, no SSH login required)',
|
|
648
|
+
usage: 'eve auth mint --email <email> [--org <org_id> | --project <project_id>] [--role <role>] [--ttl <days>]',
|
|
649
|
+
options: [
|
|
650
|
+
'--email <email> Target user email (created if missing)',
|
|
651
|
+
'--org <org_id> Org scope for membership and permission checks',
|
|
652
|
+
'--project <id> Project scope for membership and permission checks',
|
|
653
|
+
'--role <role> Role to assign (member|admin), default member',
|
|
654
|
+
'--ttl <days> Token TTL in days (1-90, default: server configured)',
|
|
655
|
+
],
|
|
656
|
+
examples: [
|
|
657
|
+
'eve auth mint --email app-bot@example.com --org org_xxx',
|
|
658
|
+
'eve auth mint --email app-bot@example.com --project proj_xxx',
|
|
659
|
+
'eve auth mint --email app-bot@example.com --project proj_xxx --role admin',
|
|
660
|
+
'eve auth mint --email bot@example.com --org org_xxx --ttl 90',
|
|
661
|
+
],
|
|
662
|
+
},
|
|
646
663
|
bootstrap: {
|
|
647
664
|
description: 'Bootstrap the first admin user with flexible security modes',
|
|
648
665
|
usage: 'eve auth bootstrap --email <email> [--token <token>] [options]',
|
|
@@ -736,12 +753,13 @@ for cloud deployments. Credentials are stored per-profile.`,
|
|
|
736
753
|
},
|
|
737
754
|
deploy: {
|
|
738
755
|
description: 'Deploy to an environment',
|
|
739
|
-
usage: 'eve env deploy <env> --ref <sha> [--direct] [--inputs <json>] [--project <id>]',
|
|
756
|
+
usage: 'eve env deploy <env> --ref <sha> [--direct] [--inputs <json>] [--image-tag <tag>] [--project <id>]',
|
|
740
757
|
options: [
|
|
741
758
|
'<env> Environment name (staging, production, test)',
|
|
742
759
|
'--ref <sha> Git SHA or commit reference (required)',
|
|
743
760
|
'--direct Bypass pipeline and do direct deploy',
|
|
744
761
|
'--inputs <json> JSON inputs for the deployment (e.g., \'{"release_id":"rel_xxx"}\')',
|
|
762
|
+
'--image-tag <tag> Use a specific image tag for deploy (direct only)',
|
|
745
763
|
'--project <id> Project ID or slug (uses profile default if omitted)',
|
|
746
764
|
'--watch Poll deployment status until ready (default: true)',
|
|
747
765
|
'--timeout <seconds> Watch timeout in seconds (default: 120)',
|
|
@@ -751,6 +769,7 @@ for cloud deployments. Credentials are stored per-profile.`,
|
|
|
751
769
|
'eve env deploy staging --ref abc123 --direct',
|
|
752
770
|
'eve env deploy staging --ref abc123 --inputs \'{"release_id":"rel_xxx","smoke_test":false}\'',
|
|
753
771
|
'eve env deploy staging --ref abc123 --direct --inputs \'{"release_id":"rel_xxx"}\'',
|
|
772
|
+
'eve env deploy staging --ref abc123 --direct --image-tag demo-abc123',
|
|
754
773
|
],
|
|
755
774
|
},
|
|
756
775
|
diagnose: {
|
|
@@ -1091,6 +1110,105 @@ for cloud deployments. Credentials are stored per-profile.`,
|
|
|
1091
1110
|
'eve release resolve v1.2.3 --json',
|
|
1092
1111
|
],
|
|
1093
1112
|
},
|
|
1113
|
+
build: {
|
|
1114
|
+
description: 'Manage builds. Builds are first-class primitives for container image creation (specs, runs, artifacts).',
|
|
1115
|
+
usage: 'eve build <subcommand> [options]',
|
|
1116
|
+
subcommands: {
|
|
1117
|
+
create: {
|
|
1118
|
+
description: 'Create a new build spec',
|
|
1119
|
+
usage: 'eve build create --project <id> --ref <sha> --manifest-hash <hash> [--services <s1,s2>]',
|
|
1120
|
+
options: [
|
|
1121
|
+
'--project <id> Project ID (uses profile default)',
|
|
1122
|
+
'--ref <sha> Git SHA or commit reference (required)',
|
|
1123
|
+
'--manifest-hash <h> Manifest hash (required)',
|
|
1124
|
+
'--services <list> Comma-separated service names to build',
|
|
1125
|
+
],
|
|
1126
|
+
examples: [
|
|
1127
|
+
'eve build create --ref abc123 --manifest-hash mfst_123',
|
|
1128
|
+
'eve build create --project proj_xxx --ref abc123 --manifest-hash mfst_123 --services api,web',
|
|
1129
|
+
],
|
|
1130
|
+
},
|
|
1131
|
+
list: {
|
|
1132
|
+
description: 'List build specs for a project',
|
|
1133
|
+
usage: 'eve build list [--project <id>] [--limit <n>] [--offset <n>]',
|
|
1134
|
+
options: [
|
|
1135
|
+
'--project <id> Project ID (uses profile default)',
|
|
1136
|
+
'--limit <n> Number of results',
|
|
1137
|
+
'--offset <n> Skip first n results',
|
|
1138
|
+
],
|
|
1139
|
+
examples: [
|
|
1140
|
+
'eve build list',
|
|
1141
|
+
'eve build list --project proj_xxx --limit 20',
|
|
1142
|
+
],
|
|
1143
|
+
},
|
|
1144
|
+
show: {
|
|
1145
|
+
description: 'Show build spec details',
|
|
1146
|
+
usage: 'eve build show <build_id>',
|
|
1147
|
+
examples: [
|
|
1148
|
+
'eve build show build_xxx',
|
|
1149
|
+
],
|
|
1150
|
+
},
|
|
1151
|
+
run: {
|
|
1152
|
+
description: 'Start a build run for an existing build spec',
|
|
1153
|
+
usage: 'eve build run <build_id>',
|
|
1154
|
+
examples: [
|
|
1155
|
+
'eve build run build_xxx',
|
|
1156
|
+
],
|
|
1157
|
+
},
|
|
1158
|
+
runs: {
|
|
1159
|
+
description: 'List runs for a build spec',
|
|
1160
|
+
usage: 'eve build runs <build_id> [--limit <n>]',
|
|
1161
|
+
options: [
|
|
1162
|
+
'--limit <n> Number of results',
|
|
1163
|
+
'--offset <n> Skip first n results',
|
|
1164
|
+
],
|
|
1165
|
+
examples: [
|
|
1166
|
+
'eve build runs build_xxx',
|
|
1167
|
+
],
|
|
1168
|
+
},
|
|
1169
|
+
logs: {
|
|
1170
|
+
description: 'Show build logs',
|
|
1171
|
+
usage: 'eve build logs <build_id> [--run <run_id>]',
|
|
1172
|
+
options: [
|
|
1173
|
+
'--run <id> Specific run ID (default: latest)',
|
|
1174
|
+
],
|
|
1175
|
+
examples: [
|
|
1176
|
+
'eve build logs build_xxx',
|
|
1177
|
+
'eve build logs build_xxx --run brun_yyy',
|
|
1178
|
+
],
|
|
1179
|
+
},
|
|
1180
|
+
artifacts: {
|
|
1181
|
+
description: 'List build artifacts (images produced)',
|
|
1182
|
+
usage: 'eve build artifacts <build_id>',
|
|
1183
|
+
examples: [
|
|
1184
|
+
'eve build artifacts build_xxx',
|
|
1185
|
+
],
|
|
1186
|
+
},
|
|
1187
|
+
diagnose: {
|
|
1188
|
+
description: 'Show full build state (spec, runs, artifacts, logs)',
|
|
1189
|
+
usage: 'eve build diagnose <build_id>',
|
|
1190
|
+
examples: [
|
|
1191
|
+
'eve build diagnose build_xxx',
|
|
1192
|
+
],
|
|
1193
|
+
},
|
|
1194
|
+
cancel: {
|
|
1195
|
+
description: 'Cancel an active build run',
|
|
1196
|
+
usage: 'eve build cancel <build_id>',
|
|
1197
|
+
examples: [
|
|
1198
|
+
'eve build cancel build_xxx',
|
|
1199
|
+
],
|
|
1200
|
+
},
|
|
1201
|
+
},
|
|
1202
|
+
examples: [
|
|
1203
|
+
'eve build create --ref abc123 --manifest-hash mfst_123 --services api,web',
|
|
1204
|
+
'eve build list',
|
|
1205
|
+
'eve build show build_xxx',
|
|
1206
|
+
'eve build run build_xxx',
|
|
1207
|
+
'eve build logs build_xxx',
|
|
1208
|
+
'eve build artifacts build_xxx',
|
|
1209
|
+
'eve build diagnose build_xxx',
|
|
1210
|
+
],
|
|
1211
|
+
},
|
|
1094
1212
|
init: {
|
|
1095
1213
|
description: `Initialize a new Eve Horizon project from a template.
|
|
1096
1214
|
|
|
@@ -1196,6 +1314,31 @@ eve-new-project-setup skill to complete configuration.`,
|
|
|
1196
1314
|
usage: 'eve system config',
|
|
1197
1315
|
examples: ['eve system config'],
|
|
1198
1316
|
},
|
|
1317
|
+
settings: {
|
|
1318
|
+
description: 'Get or set system settings (admin only)',
|
|
1319
|
+
usage: 'eve system settings [get <key>] [set <key> <value>]',
|
|
1320
|
+
options: [
|
|
1321
|
+
'get <key> Get specific setting',
|
|
1322
|
+
'set <key> <value> Update setting value',
|
|
1323
|
+
],
|
|
1324
|
+
examples: [
|
|
1325
|
+
'eve system settings',
|
|
1326
|
+
'eve system settings get some-key',
|
|
1327
|
+
'eve system settings set some-key some-value',
|
|
1328
|
+
],
|
|
1329
|
+
},
|
|
1330
|
+
orchestrator: {
|
|
1331
|
+
description: 'Manage orchestrator concurrency settings',
|
|
1332
|
+
usage: 'eve system orchestrator <status|set-concurrency>',
|
|
1333
|
+
options: [
|
|
1334
|
+
'status Show concurrency status',
|
|
1335
|
+
'set-concurrency <n> Set concurrency limit',
|
|
1336
|
+
],
|
|
1337
|
+
examples: [
|
|
1338
|
+
'eve system orchestrator status',
|
|
1339
|
+
'eve system orchestrator set-concurrency 8',
|
|
1340
|
+
],
|
|
1341
|
+
},
|
|
1199
1342
|
},
|
|
1200
1343
|
examples: [
|
|
1201
1344
|
'eve system health',
|
|
@@ -1203,6 +1346,7 @@ eve-new-project-setup skill to complete configuration.`,
|
|
|
1203
1346
|
'eve system jobs',
|
|
1204
1347
|
'eve system envs',
|
|
1205
1348
|
'eve system logs api',
|
|
1349
|
+
'eve system orchestrator status',
|
|
1206
1350
|
],
|
|
1207
1351
|
},
|
|
1208
1352
|
};
|
|
@@ -1220,6 +1364,7 @@ function showMainHelp() {
|
|
|
1220
1364
|
console.log(' manifest Validate manifests (schema, secrets)');
|
|
1221
1365
|
console.log(' job Manage jobs (create, list, show, update, claim, etc.)');
|
|
1222
1366
|
console.log(' env Manage environments (list, show, deploy)');
|
|
1367
|
+
console.log(' build Manage builds (create, run, logs, artifacts)');
|
|
1223
1368
|
console.log(' release Manage and inspect releases');
|
|
1224
1369
|
console.log(' api Explore API sources and call endpoints');
|
|
1225
1370
|
console.log(' db Inspect env DB schema, RLS, and SQL');
|