@eve-horizon/cli 0.2.29 → 0.2.31

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.
Files changed (2) hide show
  1. package/dist/index.js +250 -57
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -48721,6 +48721,7 @@ function resolveContext(flags, credentials) {
48721
48721
  const projectId = getStringFlag(flags, ["project"]) || process.env.EVE_PROJECT_ID || profile.project_id;
48722
48722
  const authKey = toAuthKey(apiUrl);
48723
48723
  const tokenEntry = credentials.tokens[authKey] || credentials.profiles?.[profileName];
48724
+ const jobToken = process.env.EVE_JOB_TOKEN;
48724
48725
  return {
48725
48726
  apiUrl,
48726
48727
  orgId,
@@ -48728,9 +48729,9 @@ function resolveContext(flags, credentials) {
48728
48729
  profileName,
48729
48730
  profile,
48730
48731
  authKey,
48731
- token: tokenEntry?.access_token,
48732
- refreshToken: tokenEntry?.refresh_token,
48733
- expiresAt: tokenEntry?.expires_at,
48732
+ token: jobToken || tokenEntry?.access_token,
48733
+ refreshToken: jobToken ? void 0 : tokenEntry?.refresh_token,
48734
+ expiresAt: jobToken ? void 0 : tokenEntry?.expires_at,
48734
48735
  profileSource
48735
48736
  };
48736
48737
  }
@@ -51203,7 +51204,7 @@ Requires Docker Desktop; k3d and kubectl are auto-managed by the CLI.`,
51203
51204
  ]
51204
51205
  },
51205
51206
  ollama: {
51206
- description: "Manage inference targets, installs, models, and aliases for managed model routing.",
51207
+ description: "Manage inference targets, installs, models, aliases, and platform managed availability.",
51207
51208
  usage: "eve ollama <subcommand> [options]",
51208
51209
  subcommands: {
51209
51210
  targets: {
@@ -51216,7 +51217,7 @@ Requires Docker Desktop; k3d and kubectl are auto-managed by the CLI.`,
51216
51217
  options: [
51217
51218
  "add: --name <name> --base-url <url> [--scope-kind <kind>] [--scope-id <id>] [--target-type <type>] [--transport-profile <profile>] [--api-key-ref <secret-ref>]",
51218
51219
  "rm: <target-id>",
51219
- "test: <target-id> [--org-id <id>] [--project-id <id>]"
51220
+ "test: <target-id>"
51220
51221
  ]
51221
51222
  },
51222
51223
  models: {
@@ -51266,15 +51267,25 @@ Requires Docker Desktop; k3d and kubectl are auto-managed by the CLI.`,
51266
51267
  "set: --scope-kind <kind> [--scope-id <id>] --preferred-target-id <target-id> [--fallback-to-alias-target true|false]",
51267
51268
  "rm: --scope-kind <kind> [--scope-id <id>]"
51268
51269
  ]
51270
+ },
51271
+ managed: {
51272
+ description: "List, publish, and unpublish platform-managed catalog models",
51273
+ usage: "eve ollama managed <list|publish|unpublish> [options]",
51274
+ options: [
51275
+ "list: [--json]",
51276
+ "publish: --canonical <id> --provider <name> --slug <provider_model_slug> --target-id <id> [--requires-warm-start true|false] [--enabled true|false] [--json]",
51277
+ "unpublish: --canonical <id> [--json]"
51278
+ ]
51269
51279
  }
51270
51280
  },
51271
51281
  examples: [
51272
51282
  "eve ollama target add --name local --base-url http://localhost:11434 --scope-kind platform --target-type external_ollama",
51273
51283
  "eve ollama model add --canonical gpt-oss:120b --provider ollama --slug gpt-oss:120b",
51274
51284
  "eve ollama install add --target-id itgt_xxx --model-id imod_xxx --min-target-capacity 1",
51275
- "eve ollama alias set --alias gpt-oss --target-id itgt_xxx --model-id imod_xxx --scope-kind project --scope-id proj_xxx",
51276
- "eve ollama assignments --scope-kind project --scope-id proj_xxx",
51277
- "eve ollama route-policy set --scope-kind project --scope-id proj_xxx --preferred-target-id itgt_xxx"
51285
+ "eve ollama assignments --scope-kind platform",
51286
+ "eve ollama managed list",
51287
+ "eve ollama managed publish --canonical deepseek-r1 --provider ollama --slug deepseek-r1:latest --target-id itgt_xxx",
51288
+ "eve ollama managed unpublish --canonical deepseek-r1"
51278
51289
  ]
51279
51290
  },
51280
51291
  migrate: {
@@ -51416,6 +51427,7 @@ function showSubcommandHelp(command, subcommand) {
51416
51427
  // src/lib/client.ts
51417
51428
  async function requestJson(context2, path6, options = {}) {
51418
51429
  const response = await requestRaw(context2, path6, options);
51430
+ const method = options.method ?? "GET";
51419
51431
  if (response.status === 401 && options.tokenOverride === void 0) {
51420
51432
  const refreshed = await attemptRefresh(context2);
51421
51433
  if (refreshed?.access_token) {
@@ -51427,14 +51439,16 @@ async function requestJson(context2, path6, options = {}) {
51427
51439
  tokenOverride: refreshed.access_token
51428
51440
  });
51429
51441
  if (!retry.ok && !options.allowError) {
51430
- const message = typeof retry.data === "string" ? retry.data : retry.text;
51431
- throw new Error(`HTTP ${retry.status}: ${message}`);
51442
+ const message = formatErrorMessage(retry);
51443
+ throw new Error(`HTTP ${retry.status}: ${method} ${path6}: ${message}`);
51432
51444
  }
51433
51445
  return retry.data;
51434
51446
  }
51435
51447
  }
51436
51448
  if (!response.ok && !options.allowError) {
51437
- const message = typeof response.data === "string" ? response.data : response.text;
51449
+ const message = formatErrorMessage(response);
51450
+ const requestTarget = `${method} ${path6}`;
51451
+ const requestFailedContext = `while calling ${requestTarget}: ${message}`;
51438
51452
  if ((response.status === 404 || response.status === 500) && message.includes("Project not found")) {
51439
51453
  const projectIdMatch = message.match(/Project not found: (proj_[a-z0-9]+)/);
51440
51454
  const projectId = projectIdMatch?.[1] ?? "unknown";
@@ -51452,7 +51466,7 @@ To fix this, either:
51452
51466
  To list available projects: eve project list`
51453
51467
  );
51454
51468
  }
51455
- throw new Error(`HTTP ${response.status}: ${message}`);
51469
+ throw new Error(`HTTP ${response.status}: ${requestFailedContext}`);
51456
51470
  }
51457
51471
  return response.data;
51458
51472
  }
@@ -51476,11 +51490,19 @@ async function requestRaw(context2, path6, options = {}) {
51476
51490
  if (token) {
51477
51491
  headers.Authorization = `Bearer ${token}`;
51478
51492
  }
51479
- const response = await fetch(`${context2.apiUrl}${path6}`, {
51480
- method: options.method ?? "GET",
51481
- headers,
51482
- body: options.body ? JSON.stringify(options.body) : void 0
51483
- });
51493
+ const url = `${context2.apiUrl}${path6}`;
51494
+ const method = options.method ?? "GET";
51495
+ let response;
51496
+ try {
51497
+ response = await fetch(url, {
51498
+ method: options.method ?? "GET",
51499
+ headers,
51500
+ body: options.body ? JSON.stringify(options.body) : void 0
51501
+ });
51502
+ } catch (error) {
51503
+ const message = error instanceof Error ? error.message : String(error);
51504
+ throw new Error(`Request failed for ${method} ${url}: ${message}`);
51505
+ }
51484
51506
  const text = await response.text();
51485
51507
  let data = null;
51486
51508
  if (text) {
@@ -51492,6 +51514,19 @@ async function requestRaw(context2, path6, options = {}) {
51492
51514
  }
51493
51515
  return { status: response.status, ok: response.ok, data, text };
51494
51516
  }
51517
+ function formatErrorMessage(response) {
51518
+ if (typeof response.data === "string") {
51519
+ return response.data;
51520
+ }
51521
+ if (response.data && typeof response.data === "object") {
51522
+ const payload = response.data;
51523
+ return [payload.message, payload.error, payload.detail, response.text].map((entry) => {
51524
+ if (typeof entry === "string" && entry.trim()) return entry;
51525
+ return "";
51526
+ }).find((entry) => entry.length > 0) ?? response.text;
51527
+ }
51528
+ return response.text;
51529
+ }
51495
51530
  async function attemptRefresh(context2) {
51496
51531
  if (!context2.refreshToken) return void 0;
51497
51532
  if (!context2.profile.supabase_url || !context2.profile.supabase_anon_key) return void 0;
@@ -57838,7 +57873,8 @@ var SecretResolveResponseSchema = external_exports.object({
57838
57873
  });
57839
57874
  var SecretMissingItemSchema = external_exports.object({
57840
57875
  key: external_exports.string(),
57841
- hints: external_exports.array(external_exports.string())
57876
+ hints: external_exports.array(external_exports.string()),
57877
+ suggestion: external_exports.string().optional()
57842
57878
  });
57843
57879
  var SecretValidationResultSchema = external_exports.object({
57844
57880
  missing: external_exports.array(SecretMissingItemSchema)
@@ -59578,7 +59614,7 @@ var ManagedModelRegistrySchema = external_exports.record(ManagedModelConfigSchem
59578
59614
  var InferenceScopeKindSchema = external_exports.enum(["platform", "org", "project"]);
59579
59615
  var InferenceTargetTypeSchema = external_exports.enum(["ollama_pool", "external_ollama", "openai_compat"]);
59580
59616
  var InferenceTransportProfileSchema = external_exports.enum(["ollama_api", "openai_compat"]);
59581
- var InferenceTargetStatusSchema = external_exports.enum(["unknown", "healthy", "unhealthy", "draining", "disabled"]);
59617
+ var InferenceTargetStatusSchema = external_exports.enum(["unknown", "healthy", "unhealthy", "waking", "draining", "disabled"]);
59582
59618
  var InferenceTargetSchema = external_exports.object({
59583
59619
  id: external_exports.string(),
59584
59620
  scope_kind: InferenceScopeKindSchema,
@@ -61731,6 +61767,8 @@ var HARNESS_ENV_MAP = deriveHarnessEnvMap();
61731
61767
 
61732
61768
  // ../shared/dist/permissions.js
61733
61769
  var ALL_PERMISSIONS = [
61770
+ // Inference
61771
+ "inference:write",
61734
61772
  // Jobs
61735
61773
  "jobs:read",
61736
61774
  "jobs:write",
@@ -67315,7 +67353,8 @@ async function handleDelete(positionals, flags, context2, json) {
67315
67353
  context2,
67316
67354
  `/projects/${projectId}/envs/${envName}`,
67317
67355
  {
67318
- method: "DELETE"
67356
+ method: "DELETE",
67357
+ ...force ? { body: { force: true } } : {}
67319
67358
  }
67320
67359
  );
67321
67360
  if (json) {
@@ -71459,6 +71498,7 @@ async function applyMigrations(options) {
71459
71498
  `;
71460
71499
  const appliedMap = new Map(appliedRows.map((row) => [row.name, row.checksum]));
71461
71500
  const results = [];
71501
+ const isBaseline = appliedMap.size === 0;
71462
71502
  for (const migration of migrations) {
71463
71503
  const checksum = (0, import_crypto6.createHash)("sha256").update(migration.sql).digest("hex");
71464
71504
  const existingChecksum = appliedMap.get(migration.name);
@@ -71475,10 +71515,25 @@ Current checksum: ${checksum}`);
71475
71515
  });
71476
71516
  continue;
71477
71517
  }
71478
- await db.begin(async (tx) => {
71479
- await tx.unsafe(migration.sql);
71480
- await tx.unsafe("INSERT INTO schema_migrations (name, checksum) VALUES ($1, $2)", [migration.name, checksum]);
71481
- });
71518
+ try {
71519
+ await db.begin(async (tx) => {
71520
+ await tx.unsafe(migration.sql);
71521
+ await tx.unsafe("INSERT INTO schema_migrations (name, checksum) VALUES ($1, $2)", [migration.name, checksum]);
71522
+ });
71523
+ } catch (error) {
71524
+ const msg = error instanceof Error ? error.message : String(error);
71525
+ const isAlreadyExists = /already exists/i.test(msg);
71526
+ if (isBaseline && isAlreadyExists) {
71527
+ console.log(` \u2192 ${migration.name} (baselined \u2014 schema already present)`);
71528
+ await db`
71529
+ INSERT INTO schema_migrations (name, checksum)
71530
+ VALUES (${migration.name}, ${checksum})
71531
+ `;
71532
+ results.push({ filename: migration.name, applied: true, checksum });
71533
+ continue;
71534
+ }
71535
+ throw error;
71536
+ }
71482
71537
  results.push({
71483
71538
  filename: migration.name,
71484
71539
  applied: true,
@@ -75189,20 +75244,18 @@ async function handleModels(subcommand, positionals, flags, context2) {
75189
75244
  switch (subcommand) {
75190
75245
  case "list":
75191
75246
  case void 0:
75192
- return handleList8(flags, context2, json);
75247
+ return handleList8(context2, json);
75193
75248
  default:
75194
- throw new Error("Usage: eve models list [--managed] [--json]");
75249
+ throw new Error("Usage: eve models list [--json]");
75195
75250
  }
75196
75251
  }
75197
- async function handleList8(flags, context2, json) {
75198
- const managedOnly = Boolean(flags.managed);
75199
- const query = managedOnly ? "?managed=true" : "";
75200
- const response = await requestJson(context2, `/models${query}`);
75252
+ async function handleList8(context2, json) {
75253
+ const response = await requestJson(context2, "/models");
75201
75254
  if (json) {
75202
75255
  outputJson(response, json);
75203
75256
  return;
75204
75257
  }
75205
- if (response.byok && !managedOnly) {
75258
+ if (response.byok) {
75206
75259
  console.log("BYOK (Bring Your Own Key)");
75207
75260
  console.log("========================");
75208
75261
  console.log(` ${response.byok.description}`);
@@ -78009,6 +78062,14 @@ function requireString(flags, key) {
78009
78062
  if (!value) throw new Error(`Missing required flag --${key}`);
78010
78063
  return value;
78011
78064
  }
78065
+ function asBoolean(flags, key) {
78066
+ const value = asString(flags, key);
78067
+ if (value === void 0) return void 0;
78068
+ return value === "true" || value === "1";
78069
+ }
78070
+ function normalizeManagedModelRows(payload) {
78071
+ return Array.isArray(payload) ? payload : payload.data;
78072
+ }
78012
78073
  function printTable(headers, rows) {
78013
78074
  const widths = headers.map((header, idx) => Math.max(header.length, ...rows.map((row) => row[idx]?.length ?? 0)));
78014
78075
  const line = `+${widths.map((w) => "-".repeat(w + 2)).join("+")}+`;
@@ -78099,21 +78160,44 @@ async function handleOllama(subcommand, positionals, flags, context2) {
78099
78160
  }
78100
78161
  if (action === "test") {
78101
78162
  const targetId = positionals[1];
78102
- if (!targetId) throw new Error("Usage: eve ollama target test <target-id> [--org-id <id>] [--project-id <id>]");
78163
+ if (!targetId) throw new Error("Usage: eve ollama target test <target-id>");
78164
+ const result = await requestJson(context2, `/inference/targets/${targetId}/test`, {
78165
+ method: "POST"
78166
+ });
78167
+ outputJson(result, json);
78168
+ if (!json) console.log("Target test completed");
78169
+ return;
78170
+ }
78171
+ if (action === "wake") {
78172
+ const targetId = positionals[1];
78173
+ if (!targetId) throw new Error("Usage: eve ollama target wake <target-id> [--wait=true] [--timeout-ms <ms>]");
78103
78174
  const query = new URLSearchParams();
78104
- const orgId = asString(flags, "org-id");
78105
- const projectId = asString(flags, "project-id");
78106
- if (orgId) query.set("org_id", orgId);
78107
- if (projectId) query.set("project_id", projectId);
78175
+ const wait = asString(flags, "wait");
78176
+ const timeoutMs = asString(flags, "timeout-ms");
78177
+ if (wait === "true" || wait === "1") query.set("wait", "true");
78178
+ if (timeoutMs) query.set("timeout_ms", timeoutMs);
78108
78179
  const suffix = query.toString() ? `?${query.toString()}` : "";
78109
- const result = await requestJson(context2, `/inference/targets/${targetId}/test${suffix}`, {
78180
+ const result = await requestJson(context2, `/inference/targets/${targetId}/wake${suffix}`, {
78110
78181
  method: "POST"
78111
78182
  });
78112
78183
  outputJson(result, json);
78113
- if (!json) console.log("Target test completed");
78184
+ if (!json) {
78185
+ const nextState = result.ready ? "ready" : result.state;
78186
+ console.log(`Wake request state: ${result.state}`);
78187
+ console.log(`Target: ${result.target_id}`);
78188
+ if (result.waited_ms !== void 0) {
78189
+ console.log(`Waited: ${result.waited_ms}ms`);
78190
+ } else {
78191
+ console.log(`Retry after: ${result.retry_after_seconds}s`);
78192
+ }
78193
+ console.log(`Message: ${result.message}`);
78194
+ if (result.ready) {
78195
+ console.log(`Wake result: ${nextState}`);
78196
+ }
78197
+ }
78114
78198
  return;
78115
78199
  }
78116
- throw new Error("Usage: eve ollama target <add|rm|test> ...");
78200
+ throw new Error("Usage: eve ollama target <add|rm|test|wake> ...");
78117
78201
  }
78118
78202
  case "models": {
78119
78203
  const models = await requestJson(context2, "/inference/models");
@@ -78362,8 +78446,78 @@ async function handleOllama(subcommand, positionals, flags, context2) {
78362
78446
  }
78363
78447
  throw new Error("Usage: eve ollama install <add|rm> --target-id <id> --model-id <id>");
78364
78448
  }
78449
+ case "managed": {
78450
+ const action = positionals[0];
78451
+ if (action === "list") {
78452
+ const response = await requestJson(
78453
+ context2,
78454
+ "/inference/managed-models"
78455
+ );
78456
+ const managed = normalizeManagedModelRows(response);
78457
+ outputJson(managed, json);
78458
+ if (json) return;
78459
+ if (managed.length === 0) {
78460
+ console.log("No managed models published.");
78461
+ return;
78462
+ }
78463
+ printTable(
78464
+ ["Canonical", "Provider", "Slug", "Target ID", "Warm Start", "Enabled"],
78465
+ managed.map((item) => [
78466
+ item.canonical_model_id,
78467
+ item.provider,
78468
+ item.provider_model_slug,
78469
+ item.target_id,
78470
+ item.requires_warm_start ? "yes" : "no",
78471
+ item.enabled ? "yes" : "no"
78472
+ ])
78473
+ );
78474
+ return;
78475
+ }
78476
+ if (action === "publish") {
78477
+ const body = {
78478
+ canonical_model_id: requireString(flags, "canonical"),
78479
+ provider: requireString(flags, "provider"),
78480
+ provider_model_slug: requireString(flags, "slug"),
78481
+ target_id: requireString(flags, "target-id")
78482
+ };
78483
+ const requiresWarmStart = asBoolean(flags, "requires-warm-start");
78484
+ const enabled = asBoolean(flags, "enabled");
78485
+ if (requiresWarmStart !== void 0) {
78486
+ body.requires_warm_start = requiresWarmStart;
78487
+ }
78488
+ if (enabled !== void 0) {
78489
+ body.enabled = enabled;
78490
+ }
78491
+ const result = await requestJson(context2, "/inference/managed-models", {
78492
+ method: "POST",
78493
+ body
78494
+ });
78495
+ outputJson(result, json);
78496
+ if (!json) {
78497
+ console.log(
78498
+ `Published managed model ${result.data.canonical_model_id} (install ${result.created_install ? "created" : "already present"}).`
78499
+ );
78500
+ }
78501
+ return;
78502
+ }
78503
+ if (action === "unpublish") {
78504
+ const canonicalModelId = requireString(flags, "canonical");
78505
+ await requestJson(context2, `/inference/managed-models/${encodeURIComponent(canonicalModelId)}`, {
78506
+ method: "DELETE"
78507
+ });
78508
+ const payload = { canonical_model_id: canonicalModelId };
78509
+ outputJson(payload, json);
78510
+ if (!json) {
78511
+ console.log(`Unpublished managed model ${canonicalModelId}`);
78512
+ }
78513
+ return;
78514
+ }
78515
+ throw new Error("Usage: eve ollama managed <list|publish|unpublish> ...");
78516
+ }
78365
78517
  default:
78366
- throw new Error("Usage: eve ollama <targets|target|models|model|aliases|alias|installs|install|assignments|route-policies|route-policy>");
78518
+ throw new Error(
78519
+ "Usage: eve ollama <targets|target|models|model|aliases|alias|installs|install|assignments|route-policies|route-policy|managed>"
78520
+ );
78367
78521
  }
78368
78522
  }
78369
78523
 
@@ -78662,6 +78816,10 @@ var KUBECTL_STABLE_URL = "https://dl.k8s.io/release/stable.txt";
78662
78816
  var LOCAL_STACK_ROOT = (0, import_node_path18.resolve)(__dirname, "..", "assets", "local-k8s");
78663
78817
  var LOCAL_STACK_OVERLAY = (0, import_node_path18.join)(LOCAL_STACK_ROOT, "overlays", "local");
78664
78818
  var LOCAL_STACK_BASE = (0, import_node_path18.join)(LOCAL_STACK_ROOT, "base");
78819
+ var DEFAULT_PLATFORM_NAMESPACE = "eve-horizon";
78820
+ var CONFIGURED_REGISTRY = process.env.ECR_REGISTRY?.trim();
78821
+ var CONFIGURED_NAMESPACE = process.env.ECR_NAMESPACE?.trim() || DEFAULT_PLATFORM_NAMESPACE;
78822
+ var PLATFORM_IMAGE_REGISTRY = buildPlatformImageRegistry();
78665
78823
  var SERVICE_DEFINITIONS = [
78666
78824
  { id: "api", workload: "eve-api", kind: "deployment" },
78667
78825
  { id: "orchestrator", workload: "eve-orchestrator", kind: "deployment" },
@@ -78672,14 +78830,7 @@ var SERVICE_DEFINITIONS = [
78672
78830
  { id: "mailpit", workload: "mailpit", kind: "deployment" },
78673
78831
  { id: "sso", workload: "eve-sso", kind: "deployment" }
78674
78832
  ];
78675
- var PLATFORM_IMAGES = [
78676
- { component: "api", remote: "ghcr.io/eve-horizon/api", local: "eve-horizon/api:local" },
78677
- { component: "orchestrator", remote: "ghcr.io/eve-horizon/orchestrator", local: "eve-horizon/orchestrator:local" },
78678
- { component: "worker", remote: "ghcr.io/eve-horizon/worker", local: "eve-horizon/worker:local" },
78679
- { component: "gateway", remote: "ghcr.io/eve-horizon/gateway", local: "eve-horizon/gateway:local" },
78680
- { component: "agent-runtime", remote: "ghcr.io/eve-horizon/agent-runtime", local: "eve-horizon/agent-runtime:local" },
78681
- { component: "sso", remote: "ghcr.io/eve-horizon/sso", local: "eve-horizon/sso:local" }
78682
- ];
78833
+ var PLATFORM_IMAGES = buildPlatformImages();
78683
78834
  var LOG_TARGETS = {
78684
78835
  api: { resource: "eve-api", kind: "deployment" },
78685
78836
  orchestrator: { resource: "eve-orchestrator", kind: "deployment" },
@@ -78734,9 +78885,21 @@ async function handleUp(flags, json) {
78734
78885
  await ensureClusterReady(runtimeOptions);
78735
78886
  let deployedVersion = null;
78736
78887
  if (!skipDeploy) {
78888
+ const kubectl = requireToolPath("kubectl", "Run 'eve local up' again to auto-install managed tools.");
78889
+ const marker = readManagerMarker(kubectl);
78890
+ if (marker && marker !== "cli") {
78891
+ throw new Error(
78892
+ `This local stack is managed by './bin/eh k8s deploy' (marker: ${marker}).
78893
+ 'eve local up' would overwrite source-built images with released registry images.
78894
+
78895
+ To switch to CLI management: eve local reset --force
78896
+ To continue with repo scripts: ./bin/eh k8s deploy`
78897
+ );
78898
+ }
78737
78899
  deployedVersion = await resolveRequestedVersion(requestedVersion, runtimeOptions);
78738
78900
  await importPlatformImages(deployedVersion, runtimeOptions);
78739
78901
  applyLocalManifests(runtimeOptions);
78902
+ writeManagerMarker(kubectl, runtimeOptions);
78740
78903
  waitForStatefulSetRollout("postgres", Math.max(timeoutSeconds, 180), runtimeOptions);
78741
78904
  runDbMigration(Math.max(timeoutSeconds, 180), runtimeOptions);
78742
78905
  generateAuthSecrets(runtimeOptions);
@@ -79224,22 +79387,21 @@ async function resolveLatestPlatformVersion() {
79224
79387
  const candidates = Array.from(intersection);
79225
79388
  if (candidates.length === 0) {
79226
79389
  throw new Error(
79227
- "Unable to resolve a common platform version from GHCR tags. Re-run with --version <x.y.z>."
79390
+ "Unable to resolve a common platform version from configured registry tags. Re-run with --version <x.y.z>."
79228
79391
  );
79229
79392
  }
79230
79393
  candidates.sort(compareSemverDesc);
79231
79394
  return candidates[0];
79232
79395
  }
79233
79396
  async function fetchRegistryTags(imageRef) {
79234
- const repository = imageRef.replace(/^ghcr\.io\//, "");
79235
- const tokenPayload = await fetchText(`https://ghcr.io/token?scope=repository:${repository}:pull`);
79236
- const token = JSON.parse(tokenPayload).token;
79237
- if (!token) {
79238
- throw new Error(`Unable to fetch GHCR token for ${imageRef}.`);
79397
+ const slashIndex = imageRef.indexOf("/");
79398
+ if (slashIndex < 0) {
79399
+ throw new Error(`Invalid image reference '${imageRef}'.`);
79239
79400
  }
79401
+ const registry = imageRef.slice(0, slashIndex);
79402
+ const repository = imageRef.slice(slashIndex + 1);
79240
79403
  const tagsPayload = await fetchText(
79241
- `https://ghcr.io/v2/${repository}/tags/list?n=200`,
79242
- { Authorization: `Bearer ${token}` }
79404
+ `https://${registry}/v2/${repository}/tags/list?n=200`
79243
79405
  );
79244
79406
  return JSON.parse(tagsPayload).tags ?? [];
79245
79407
  }
@@ -79275,7 +79437,7 @@ async function importPlatformImages(version2, runtimeOptions) {
79275
79437
  const pull = pullImageWithRetry(docker, remoteTag, stdio, runtimeOptions);
79276
79438
  if (pull.status !== 0) {
79277
79439
  throw new Error(
79278
- `Failed to pull ${remoteTag}. Ensure GHCR image visibility is public and the version exists. Try: eve local up --version <x.y.z>`
79440
+ `Failed to pull ${remoteTag}. Ensure image availability/access at ${image.remote} and the version exists. Try: eve local up --version <x.y.z>`
79279
79441
  );
79280
79442
  }
79281
79443
  run(docker, ["tag", remoteTag, image.local], { stdio });
@@ -79324,6 +79486,37 @@ function applyLocalManifests(runtimeOptions) {
79324
79486
  { stdio: runtimeOptions.verbose && !runtimeOptions.quiet ? "inherit" : "pipe" }
79325
79487
  );
79326
79488
  }
79489
+ function buildPlatformImageRegistry() {
79490
+ if (CONFIGURED_REGISTRY) {
79491
+ return `${CONFIGURED_REGISTRY}/${CONFIGURED_NAMESPACE}`;
79492
+ }
79493
+ return `public.ecr.aws/w7c4v0w3/${DEFAULT_PLATFORM_NAMESPACE}`;
79494
+ }
79495
+ function buildPlatformImages() {
79496
+ return [
79497
+ { component: "api", remote: `${PLATFORM_IMAGE_REGISTRY}/api`, local: "eve-horizon/api:local" },
79498
+ { component: "orchestrator", remote: `${PLATFORM_IMAGE_REGISTRY}/orchestrator`, local: "eve-horizon/orchestrator:local" },
79499
+ { component: "worker", remote: `${PLATFORM_IMAGE_REGISTRY}/worker`, local: "eve-horizon/worker:local" },
79500
+ { component: "gateway", remote: `${PLATFORM_IMAGE_REGISTRY}/gateway`, local: "eve-horizon/gateway:local" },
79501
+ { component: "agent-runtime", remote: `${PLATFORM_IMAGE_REGISTRY}/agent-runtime`, local: "eve-horizon/agent-runtime:local" },
79502
+ { component: "sso", remote: `${PLATFORM_IMAGE_REGISTRY}/sso`, local: "eve-horizon/sso:local" }
79503
+ ];
79504
+ }
79505
+ function readManagerMarker(kubectl) {
79506
+ const result = run(
79507
+ kubectl,
79508
+ ["--context", DEFAULT_KUBE_CONTEXT, "get", "namespace", "eve", "-o", "jsonpath={.metadata.annotations.eve-managed-by}"],
79509
+ { stdio: "pipe", allowFailure: true }
79510
+ );
79511
+ return result.status === 0 ? result.stdout.trim() : "";
79512
+ }
79513
+ function writeManagerMarker(kubectl, runtimeOptions) {
79514
+ run(
79515
+ kubectl,
79516
+ ["--context", DEFAULT_KUBE_CONTEXT, "annotate", "namespace", "eve", "eve-managed-by=cli", "--overwrite"],
79517
+ { stdio: runtimeOptions.verbose && !runtimeOptions.quiet ? "inherit" : "pipe", allowFailure: true }
79518
+ );
79519
+ }
79327
79520
  function runDbMigration(timeoutSeconds, runtimeOptions) {
79328
79521
  const kubectl = requireToolPath("kubectl", "Run 'eve local up' again to auto-install managed tools.");
79329
79522
  const migrateJobPath = (0, import_node_path18.join)(LOCAL_STACK_BASE, "db-migrate-job.yaml");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eve-horizon/cli",
3
- "version": "0.2.29",
3
+ "version": "0.2.31",
4
4
  "description": "Eve Horizon CLI",
5
5
  "license": "MIT",
6
6
  "repository": {