@eve-horizon/cli 0.2.0 → 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.
@@ -0,0 +1,86 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.handleManifest = handleManifest;
4
+ const args_1 = require("../lib/args");
5
+ const client_1 = require("../lib/client");
6
+ const output_1 = require("../lib/output");
7
+ const node_fs_1 = require("node:fs");
8
+ const node_path_1 = require("node:path");
9
+ async function handleManifest(subcommand, positionals, flags, context) {
10
+ const json = Boolean(flags.json);
11
+ switch (subcommand) {
12
+ case 'validate': {
13
+ const useLatest = (0, args_1.toBoolean)(flags.latest) ?? false;
14
+ const strict = (0, args_1.toBoolean)(flags.strict) ?? false;
15
+ const validateSecretsFlag = flags['validate-secrets'] ?? flags.validate_secrets;
16
+ const validateSecrets = (0, args_1.toBoolean)(validateSecretsFlag) ?? false;
17
+ const dir = typeof flags.dir === 'string' ? flags.dir : process.cwd();
18
+ const manifestPath = (0, args_1.getStringFlag)(flags, ['path']) ?? (0, node_path_1.join)(dir, '.eve', 'manifest.yaml');
19
+ let manifestYaml;
20
+ if (!useLatest) {
21
+ try {
22
+ manifestYaml = (0, node_fs_1.readFileSync)(manifestPath, 'utf-8');
23
+ }
24
+ catch (error) {
25
+ throw new Error(`Failed to read manifest at ${manifestPath}: ${error.message}`);
26
+ }
27
+ }
28
+ let projectId = (0, args_1.getStringFlag)(flags, ['project']) ?? context.projectId;
29
+ if (!projectId && manifestYaml) {
30
+ const match = manifestYaml.match(/^project:\s*(\S+)/m);
31
+ if (match) {
32
+ projectId = match[1];
33
+ }
34
+ }
35
+ if (!projectId) {
36
+ throw new Error('Missing project id. Provide --project, set a profile default, or add "project: proj_xxx" to manifest.');
37
+ }
38
+ const response = await (0, client_1.requestJson)(context, `/projects/${projectId}/manifest/validate`, {
39
+ method: 'POST',
40
+ body: {
41
+ manifest_yaml: manifestYaml,
42
+ validate_secrets: validateSecrets || strict,
43
+ strict,
44
+ },
45
+ });
46
+ if (json) {
47
+ (0, output_1.outputJson)(response, json);
48
+ }
49
+ else {
50
+ if (response.valid) {
51
+ console.log('✓ Manifest valid');
52
+ }
53
+ else {
54
+ console.log('✗ Manifest invalid');
55
+ }
56
+ if (response.manifest_hash) {
57
+ console.log(` Hash: ${response.manifest_hash.substring(0, 12)}...`);
58
+ }
59
+ if (response.errors && response.errors.length > 0) {
60
+ console.log('');
61
+ console.log('Errors:');
62
+ response.errors.forEach((error) => console.log(` - ${error}`));
63
+ }
64
+ if (response.warnings && response.warnings.length > 0) {
65
+ console.log('');
66
+ console.log('Warnings:');
67
+ response.warnings.forEach((warning) => console.log(` - ${warning}`));
68
+ }
69
+ if (response.secret_validation?.missing?.length) {
70
+ console.log('');
71
+ console.log('Missing secrets:');
72
+ response.secret_validation.missing.forEach((item) => {
73
+ const hint = item.hints?.[0] ? ` (${item.hints[0]})` : '';
74
+ console.log(` - ${item.key}${hint}`);
75
+ });
76
+ }
77
+ }
78
+ if (!response.valid) {
79
+ process.exitCode = 1;
80
+ }
81
+ return;
82
+ }
83
+ default:
84
+ throw new Error('Usage: eve manifest <validate>');
85
+ }
86
+ }
@@ -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,
@@ -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 updated: ${name}`);
131
+ (0, output_1.outputJson)({ active_profile: name, ...config.profiles[name] }, json, `✓ Profile set: ${name}`);
131
132
  return;
132
133
  }
133
134
  case 'remove': {
@@ -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 doesn't exist yet, fall back to basic health check
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: Full system status endpoint not yet implemented.');
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
@@ -24,6 +24,8 @@ const admin_1 = require("./commands/admin");
24
24
  const agents_1 = require("./commands/agents");
25
25
  const init_1 = require("./commands/init");
26
26
  const release_1 = require("./commands/release");
27
+ const manifest_1 = require("./commands/manifest");
28
+ const build_1 = require("./commands/build");
27
29
  async function main() {
28
30
  const { flags, positionals } = (0, args_1.parseArgs)(process.argv.slice(2));
29
31
  const command = positionals[0];
@@ -107,6 +109,12 @@ async function main() {
107
109
  case 'release':
108
110
  await (0, release_1.handleRelease)(subcommand, rest, flags, context);
109
111
  return;
112
+ case 'manifest':
113
+ await (0, manifest_1.handleManifest)(subcommand, rest, flags, context);
114
+ return;
115
+ case 'build':
116
+ await (0, build_1.handleBuild)(subcommand, rest, flags, context);
117
+ return;
110
118
  default:
111
119
  (0, help_1.showMainHelp)();
112
120
  }
package/dist/lib/help.js CHANGED
@@ -106,6 +106,28 @@ exports.HELP = {
106
106
  },
107
107
  },
108
108
  },
109
+ manifest: {
110
+ description: 'Validate project manifests for schema and required secrets.',
111
+ usage: 'eve manifest <subcommand> [options]',
112
+ subcommands: {
113
+ validate: {
114
+ description: 'Validate a manifest (schema + secrets)',
115
+ usage: 'eve manifest validate [--project <id>] [--path <path>] [--latest]',
116
+ options: [
117
+ '--project <id> Project ID (uses profile default)',
118
+ '--path <path> Path to manifest (default: .eve/manifest.yaml)',
119
+ '--latest Validate latest synced manifest instead of local file',
120
+ '--validate-secrets Validate required secrets (from manifest)',
121
+ '--strict Fail validation if required secrets are missing',
122
+ ],
123
+ examples: [
124
+ 'eve manifest validate',
125
+ 'eve manifest validate --project proj_xxx',
126
+ 'eve manifest validate --latest --project proj_xxx',
127
+ ],
128
+ },
129
+ },
130
+ },
109
131
  secrets: {
110
132
  description: 'Manage secrets at system/org/user/project scope. Values are never returned in plaintext.',
111
133
  usage: 'eve secrets <subcommand> [options]',
@@ -576,7 +598,7 @@ have to specify them on every command. Useful when working with multiple environ
576
598
  auth: {
577
599
  description: `Authenticate with Eve Horizon. Auth is optional for local development but required
578
600
  for cloud deployments. Credentials are stored per-profile.`,
579
- usage: 'eve auth <login|logout|status|whoami|bootstrap|sync|token>',
601
+ usage: 'eve auth <login|logout|status|whoami|bootstrap|sync|creds|token|mint>',
580
602
  subcommands: {
581
603
  login: {
582
604
  description: 'Login via GitHub SSH challenge (default) or Supabase (legacy)',
@@ -621,6 +643,23 @@ for cloud deployments. Credentials are stored per-profile.`,
621
643
  'eve auth token # Share with reviewers for PR preview access',
622
644
  ],
623
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
+ },
624
663
  bootstrap: {
625
664
  description: 'Bootstrap the first admin user with flexible security modes',
626
665
  usage: 'eve auth bootstrap --email <email> [--token <token>] [options]',
@@ -647,18 +686,35 @@ for cloud deployments. Credentials are stored per-profile.`,
647
686
  },
648
687
  sync: {
649
688
  description: 'Extract OAuth tokens from host and set as Eve secrets',
650
- usage: 'eve auth sync [--claude] [--codex] [--project <id>] [--system] [--dry-run]',
689
+ usage: 'eve auth sync [--claude] [--codex] [--org <id>] [--project <id>] [--dry-run]',
651
690
  options: [
652
691
  '--claude Only extract Claude/Anthropic tokens',
653
692
  '--codex Only extract Codex/OpenAI tokens',
654
- '--project <id> Project to set secrets on (uses profile default)',
655
- '--system Set as system secrets instead of project secrets',
693
+ '--org <id> Set as org-level secrets',
694
+ '--project <id> Set as project-level secrets',
656
695
  '--dry-run Show what would be set without actually setting',
696
+ '',
697
+ 'Scope priority: --project > --org > user (default)',
698
+ 'Default scope is user-level, so credentials are available to all your jobs.',
657
699
  ],
658
700
  examples: [
659
- 'eve auth sync',
660
- 'eve auth sync --claude --dry-run',
661
- 'eve auth sync --project proj_xxx',
701
+ 'eve auth sync # Sync to user-level (default)',
702
+ 'eve auth sync --org org_xxx # Sync to org-level',
703
+ 'eve auth sync --project proj_xxx # Sync to project-level',
704
+ 'eve auth sync --dry-run # Preview without syncing',
705
+ ],
706
+ },
707
+ creds: {
708
+ description: 'Show local AI tool credentials (Claude Code, Codex/Code) without syncing',
709
+ usage: 'eve auth creds [--claude] [--codex]',
710
+ options: [
711
+ '--claude Only check Claude/Anthropic credentials',
712
+ '--codex Only check Codex/OpenAI credentials',
713
+ ],
714
+ examples: [
715
+ 'eve auth creds',
716
+ 'eve auth creds --claude',
717
+ 'eve auth creds --json',
662
718
  ],
663
719
  },
664
720
  },
@@ -697,19 +753,36 @@ for cloud deployments. Credentials are stored per-profile.`,
697
753
  },
698
754
  deploy: {
699
755
  description: 'Deploy to an environment',
700
- 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>]',
701
757
  options: [
702
758
  '<env> Environment name (staging, production, test)',
703
759
  '--ref <sha> Git SHA or commit reference (required)',
704
760
  '--direct Bypass pipeline and do direct deploy',
705
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)',
706
763
  '--project <id> Project ID or slug (uses profile default if omitted)',
764
+ '--watch Poll deployment status until ready (default: true)',
765
+ '--timeout <seconds> Watch timeout in seconds (default: 120)',
707
766
  ],
708
767
  examples: [
709
768
  'eve env deploy staging --ref abc123',
710
769
  'eve env deploy staging --ref abc123 --direct',
711
770
  'eve env deploy staging --ref abc123 --inputs \'{"release_id":"rel_xxx","smoke_test":false}\'',
712
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',
773
+ ],
774
+ },
775
+ diagnose: {
776
+ description: 'Diagnose environment deployments (k8s-only)',
777
+ usage: 'eve env diagnose <project> <env> [--events <n>]',
778
+ options: [
779
+ '<project> Project ID or slug',
780
+ '<env> Environment name',
781
+ '--events <n> Limit number of recent events',
782
+ ],
783
+ examples: [
784
+ 'eve env diagnose proj_xxx staging',
785
+ 'eve env diagnose proj_xxx staging --events 20',
713
786
  ],
714
787
  },
715
788
  logs: {
@@ -748,6 +821,7 @@ for cloud deployments. Credentials are stored per-profile.`,
748
821
  'eve env create test --type=persistent',
749
822
  'eve env deploy staging --ref abc123',
750
823
  'eve env logs proj_xxx staging api --tail 200',
824
+ 'eve env diagnose proj_xxx staging',
751
825
  ],
752
826
  },
753
827
  api: {
@@ -1036,6 +1110,105 @@ for cloud deployments. Credentials are stored per-profile.`,
1036
1110
  'eve release resolve v1.2.3 --json',
1037
1111
  ],
1038
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
+ },
1039
1212
  init: {
1040
1213
  description: `Initialize a new Eve Horizon project from a template.
1041
1214
 
@@ -1141,6 +1314,31 @@ eve-new-project-setup skill to complete configuration.`,
1141
1314
  usage: 'eve system config',
1142
1315
  examples: ['eve system config'],
1143
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
+ },
1144
1342
  },
1145
1343
  examples: [
1146
1344
  'eve system health',
@@ -1148,6 +1346,7 @@ eve-new-project-setup skill to complete configuration.`,
1148
1346
  'eve system jobs',
1149
1347
  'eve system envs',
1150
1348
  'eve system logs api',
1349
+ 'eve system orchestrator status',
1151
1350
  ],
1152
1351
  },
1153
1352
  };
@@ -1162,8 +1361,10 @@ function showMainHelp() {
1162
1361
  console.log('Commands:');
1163
1362
  console.log(' org Manage organizations');
1164
1363
  console.log(' project Manage projects');
1364
+ console.log(' manifest Validate manifests (schema, secrets)');
1165
1365
  console.log(' job Manage jobs (create, list, show, update, claim, etc.)');
1166
1366
  console.log(' env Manage environments (list, show, deploy)');
1367
+ console.log(' build Manage builds (create, run, logs, artifacts)');
1167
1368
  console.log(' release Manage and inspect releases');
1168
1369
  console.log(' api Explore API sources and call endpoints');
1169
1370
  console.log(' db Inspect env DB schema, RLS, and SQL');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eve-horizon/cli",
3
- "version": "0.2.0",
3
+ "version": "0.2.5",
4
4
  "description": "Eve Horizon CLI",
5
5
  "license": "MIT",
6
6
  "repository": {