@eve-horizon/cli 0.2.37 → 0.2.39

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 +336 -56
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -9811,8 +9811,8 @@ var require_sync = __commonJS({
9811
9811
  }
9812
9812
  return x;
9813
9813
  };
9814
- var defaultReadPackageSync = function defaultReadPackageSync2(readFileSync24, pkgfile) {
9815
- var body = readFileSync24(pkgfile);
9814
+ var defaultReadPackageSync = function defaultReadPackageSync2(readFileSync25, pkgfile) {
9815
+ var body = readFileSync25(pkgfile);
9816
9816
  try {
9817
9817
  var pkg = JSON.parse(body);
9818
9818
  return pkg;
@@ -9832,7 +9832,7 @@ var require_sync = __commonJS({
9832
9832
  }
9833
9833
  var opts = normalizeOptions(x, options);
9834
9834
  var isFile = opts.isFile || defaultIsFile;
9835
- var readFileSync24 = opts.readFileSync || fs6.readFileSync;
9835
+ var readFileSync25 = opts.readFileSync || fs6.readFileSync;
9836
9836
  var isDirectory = opts.isDirectory || defaultIsDir;
9837
9837
  var realpathSync = opts.realpathSync || defaultRealpathSync;
9838
9838
  var readPackageSync = opts.readPackageSync || defaultReadPackageSync;
@@ -9889,7 +9889,7 @@ var require_sync = __commonJS({
9889
9889
  if (!isFile(pkgfile)) {
9890
9890
  return loadpkg(path8.dirname(dir));
9891
9891
  }
9892
- var pkg = readPackageSync(readFileSync24, pkgfile);
9892
+ var pkg = readPackageSync(readFileSync25, pkgfile);
9893
9893
  if (pkg && opts.packageFilter) {
9894
9894
  pkg = opts.packageFilter(
9895
9895
  pkg,
@@ -9903,7 +9903,7 @@ var require_sync = __commonJS({
9903
9903
  var pkgfile = path8.join(maybeRealpathSync(realpathSync, x2, opts), "/package.json");
9904
9904
  if (isFile(pkgfile)) {
9905
9905
  try {
9906
- var pkg = readPackageSync(readFileSync24, pkgfile);
9906
+ var pkg = readPackageSync(readFileSync25, pkgfile);
9907
9907
  } catch (e) {
9908
9908
  }
9909
9909
  if (pkg && opts.packageFilter) {
@@ -48552,6 +48552,10 @@ var require_src57 = __commonJS({
48552
48552
  }
48553
48553
  });
48554
48554
 
48555
+ // src/index.ts
48556
+ var import_fs4 = require("fs");
48557
+ var import_path3 = require("path");
48558
+
48555
48559
  // src/lib/args.ts
48556
48560
  function parseArgs(args) {
48557
48561
  const flags = {};
@@ -48648,7 +48652,7 @@ var import_node_fs2 = require("node:fs");
48648
48652
  var import_node_path2 = require("node:path");
48649
48653
  var import_yaml = require("yaml");
48650
48654
  var DEFAULT_PROFILE = "default";
48651
- var DEFAULT_API_URL = "http://api.eve.lvh.me";
48655
+ var DEFAULT_API_URL = "https://api.eh1.incept5.dev";
48652
48656
  function getRepoProfilePath() {
48653
48657
  return (0, import_node_path2.join)(process.cwd(), ".eve", "profile.yaml");
48654
48658
  }
@@ -49522,7 +49526,7 @@ for cloud deployments. Credentials are stored globally per API URL.`,
49522
49526
  options: [
49523
49527
  "--email <email> Email address for SSH login (uses profile default_email if not provided)",
49524
49528
  "--user-id <id> User id for SSH login",
49525
- "--ssh-key <path> Path to SSH private key (uses profile default_ssh_key, then ~/.ssh/id_ed25519)",
49529
+ "--ssh-key <path> Path to SSH private key (auto-discovers from ~/.ssh/ if omitted)",
49526
49530
  "--ttl <days> Token TTL in days (1-90, default: server configured)",
49527
49531
  "--password <pass> Supabase password (triggers Supabase login)",
49528
49532
  "--supabase-url <url> Supabase URL",
@@ -51553,6 +51557,22 @@ async function requestRaw(context2, path8, options = {}) {
51553
51557
  body: options.body ? JSON.stringify(options.body) : void 0
51554
51558
  });
51555
51559
  } catch (error) {
51560
+ const cause = error instanceof Error ? error.cause : void 0;
51561
+ const code = cause?.code;
51562
+ const isConnectionError = code === "ECONNREFUSED" || code === "ENOTFOUND" || code === "ETIMEDOUT" || error instanceof Error && error.message.includes("fetch failed");
51563
+ if (isConnectionError) {
51564
+ throw new Error(
51565
+ `Could not connect to ${context2.apiUrl}
51566
+
51567
+ The API is unreachable. Check that:
51568
+ - The URL is correct (current: ${context2.apiUrl})
51569
+ - Your internet connection is working
51570
+
51571
+ To change the API URL:
51572
+ eve profile set default --api-url <url>
51573
+ or set EVE_API_URL=<url>`
51574
+ );
51575
+ }
51556
51576
  const message = error instanceof Error ? error.message : String(error);
51557
51577
  throw new Error(`Request failed for ${method} ${url}: ${message}`);
51558
51578
  }
@@ -62200,6 +62220,84 @@ var import_child_process = require("child_process");
62200
62220
  var import_util4 = require("util");
62201
62221
  var execFileAsync = (0, import_util4.promisify)(import_child_process.execFile);
62202
62222
 
62223
+ // src/lib/logs.ts
62224
+ function normalizeLogLine(line) {
62225
+ const kind = line.kind;
62226
+ const raw = line.raw;
62227
+ if (!kind || !raw) {
62228
+ return {
62229
+ type: line.type || "log",
62230
+ message: line.message || line.text || void 0,
62231
+ tool: line.tool,
62232
+ toolInput: line.tool_input,
62233
+ raw: line
62234
+ };
62235
+ }
62236
+ const rawType = raw.type;
62237
+ const item = raw.item;
62238
+ if (rawType === "item.completed" && item) {
62239
+ const itemType = item.type;
62240
+ if (itemType === "agent_message" && typeof item.text === "string") {
62241
+ return { type: "assistant", message: item.text, raw: line };
62242
+ }
62243
+ if (itemType === "command_execution") {
62244
+ const cmd = item.command;
62245
+ const exitCode = item.exit_code;
62246
+ const status = item.status;
62247
+ if (status === "completed" || exitCode !== void 0) {
62248
+ return { type: "tool_result", message: `exit ${exitCode ?? "?"}`, tool: "bash", toolInput: cmd, raw: line };
62249
+ }
62250
+ return { type: "tool_use", tool: "bash", toolInput: cmd, raw: line };
62251
+ }
62252
+ if (itemType === "file_change") {
62253
+ const changes = item.changes;
62254
+ if (changes?.length) {
62255
+ const summary = changes.map((c) => {
62256
+ const changeKind = c.kind || "?";
62257
+ const filePath = c.path || "";
62258
+ const shortPath = filePath.split("/").slice(-3).join("/");
62259
+ return `${changeKind}: ${shortPath}`;
62260
+ }).join(", ");
62261
+ return { type: "tool_use", tool: "file_change", toolInput: summary, raw: line };
62262
+ }
62263
+ }
62264
+ }
62265
+ if (rawType === "item.started" && item) {
62266
+ const itemType = item.type;
62267
+ if (itemType === "command_execution") {
62268
+ const cmd = item.command;
62269
+ return { type: "tool_use", tool: "bash", toolInput: cmd, raw: line };
62270
+ }
62271
+ }
62272
+ if (rawType === "turn.completed") {
62273
+ return { type: "skip", raw: line };
62274
+ }
62275
+ if (rawType === "assistant") {
62276
+ const message = raw.message;
62277
+ const text = message?.content?.filter((c) => c.text).map((c) => c.text).join("\n");
62278
+ return { type: "assistant", message: text || void 0, raw: line };
62279
+ }
62280
+ if (kind === "assistant") {
62281
+ const msg = raw.msg;
62282
+ const text = msg?.text || item?.text || void 0;
62283
+ return { type: "assistant", message: text, raw: line };
62284
+ }
62285
+ if (kind === "tool_use") {
62286
+ return { type: "tool_use", tool: line.tool || void 0, raw: line };
62287
+ }
62288
+ if (kind === "error") {
62289
+ return { type: "error", message: raw.error || raw.content || void 0, raw: line };
62290
+ }
62291
+ if (rawType === "stderr") {
62292
+ const content = raw.content;
62293
+ return { type: "status", message: content, raw: line };
62294
+ }
62295
+ if (rawType === "harness_startup") {
62296
+ return { type: "skip", raw: line };
62297
+ }
62298
+ return { type: kind || "log", raw: line };
62299
+ }
62300
+
62203
62301
  // src/commands/job.ts
62204
62302
  async function handleJob(subcommand, positionals, flags, context2) {
62205
62303
  const json = Boolean(flags.json);
@@ -63732,30 +63830,46 @@ function formatLogEntry(log) {
63732
63830
  }
63733
63831
  return;
63734
63832
  }
63735
- const message = line.message || line.text || "";
63736
- const tool = line.tool;
63737
- const toolInput = line.tool_input;
63833
+ const normalized = normalizeLogLine(line);
63834
+ const nType = normalized.type;
63835
+ if (nType === "skip") return;
63836
+ const message = normalized.message || line.message || line.text || "";
63837
+ const tool = normalized.tool || line.tool || void 0;
63838
+ const toolInput = normalized.toolInput || line.tool_input || void 0;
63738
63839
  const toolResult = line.tool_result;
63739
- switch (type) {
63840
+ switch (nType) {
63740
63841
  case "assistant":
63741
63842
  case "text":
63742
- console.log(`[${timestamp}] \u{1F916} ${message || JSON.stringify(line)}`);
63843
+ if (message) {
63844
+ console.log(`[${timestamp}] ${message}`);
63845
+ }
63743
63846
  break;
63744
63847
  case "tool_use":
63745
- console.log(`[${timestamp}] \u{1F527} ${tool || "tool"}: ${toolInput || JSON.stringify(line)}`);
63848
+ if (tool) {
63849
+ const inputPreview = toolInput ? ` ${toolInput.substring(0, 80)}${toolInput.length > 80 ? "..." : ""}` : "";
63850
+ console.log(`[${timestamp}] ${tool}${inputPreview}`);
63851
+ }
63746
63852
  break;
63747
63853
  case "tool_result":
63748
- const resultPreview = (toolResult || "").substring(0, 100);
63749
- console.log(`[${timestamp}] \u2192 ${resultPreview}${(toolResult?.length || 0) > 100 ? "..." : ""}`);
63854
+ const resultPreview = (toolResult || normalized.message || "").substring(0, 100);
63855
+ if (resultPreview) {
63856
+ console.log(`[${timestamp}] -> ${resultPreview}${(toolResult?.length || 0) > 100 ? "..." : ""}`);
63857
+ }
63750
63858
  break;
63751
63859
  case "error":
63752
- console.log(`[${timestamp}] \u274C ${message || JSON.stringify(line)}`);
63860
+ console.log(`[${timestamp}] Error: ${message || JSON.stringify(line)}`);
63753
63861
  break;
63754
63862
  case "status":
63755
- console.log(`[${timestamp}] \u2139\uFE0F ${message || JSON.stringify(line)}`);
63863
+ if (message) {
63864
+ console.log(`[${timestamp}] > ${message}`);
63865
+ }
63756
63866
  break;
63757
63867
  default:
63758
- console.log(`[${timestamp}] ${JSON.stringify(line)}`);
63868
+ if (message) {
63869
+ console.log(`[${timestamp}] ${message}`);
63870
+ } else if (Object.keys(line).length > 0) {
63871
+ console.log(`[${timestamp}] ${JSON.stringify(line)}`);
63872
+ }
63759
63873
  }
63760
63874
  }
63761
63875
  function getLifecycleIcon(phase) {
@@ -64676,10 +64790,13 @@ function formatFollowLogLine(event) {
64676
64790
  );
64677
64791
  return;
64678
64792
  }
64679
- const message = line.message || line.text || "";
64680
- const tool = line.tool;
64681
- const toolInput = line.tool_input;
64682
- switch (type) {
64793
+ const normalized = normalizeLogLine(line);
64794
+ const nType = normalized.type;
64795
+ if (nType === "skip") return;
64796
+ const message = normalized.message || line.message || line.text || "";
64797
+ const tool = normalized.tool || line.tool || void 0;
64798
+ const toolInput = normalized.toolInput || line.tool_input || void 0;
64799
+ switch (nType) {
64683
64800
  case "assistant":
64684
64801
  case "text":
64685
64802
  if (message) {
@@ -64688,14 +64805,16 @@ function formatFollowLogLine(event) {
64688
64805
  break;
64689
64806
  case "tool_use":
64690
64807
  if (tool) {
64691
- const inputPreview = toolInput ? ` ${toolInput.substring(0, 60)}${toolInput.length > 60 ? "..." : ""}` : "";
64692
- console.log(`[${timestamp}] Tool: ${tool}${inputPreview}`);
64808
+ const inputPreview = toolInput ? ` ${toolInput.substring(0, 80)}${toolInput.length > 80 ? "..." : ""}` : "";
64809
+ console.log(`[${timestamp}] ${tool}${inputPreview}`);
64693
64810
  }
64694
64811
  break;
64695
64812
  case "tool_result":
64696
64813
  break;
64697
64814
  case "status":
64698
- console.log(`[${timestamp}] ${message || JSON.stringify(line)}`);
64815
+ if (message) {
64816
+ console.log(`[${timestamp}] > ${message}`);
64817
+ }
64699
64818
  break;
64700
64819
  case "error":
64701
64820
  console.log(`[${timestamp}] Error: ${message || JSON.stringify(line)}`);
@@ -66054,6 +66173,41 @@ function pickFreshestCodeAuth() {
66054
66173
  if (candidates.length === 0) return null;
66055
66174
  return candidates.reduce((best, c) => c.expiresAt > best.expiresAt ? c : best);
66056
66175
  }
66176
+ var SSH_KEY_IGNORE = /* @__PURE__ */ new Set([
66177
+ "config",
66178
+ "known_hosts",
66179
+ "known_hosts.old",
66180
+ "authorized_keys",
66181
+ "environment"
66182
+ ]);
66183
+ var SSH_KEY_PRIORITY = {
66184
+ id_ed25519: 0,
66185
+ id_ecdsa: 1,
66186
+ id_rsa: 2
66187
+ };
66188
+ function discoverSshKeys() {
66189
+ const sshDir = (0, import_node_path5.join)((0, import_node_os3.homedir)(), ".ssh");
66190
+ if (!(0, import_node_fs5.existsSync)(sshDir)) return [];
66191
+ let entries;
66192
+ try {
66193
+ entries = (0, import_node_fs5.readdirSync)(sshDir);
66194
+ } catch {
66195
+ return [];
66196
+ }
66197
+ const candidates = [];
66198
+ for (const name of entries) {
66199
+ if (name.startsWith(".")) continue;
66200
+ if (name.endsWith(".pub")) continue;
66201
+ if (SSH_KEY_IGNORE.has(name)) continue;
66202
+ if (!name.startsWith("id_") && !name.includes("key")) continue;
66203
+ const fullPath = (0, import_node_path5.join)(sshDir, name);
66204
+ const pubPath = `${fullPath}.pub`;
66205
+ if (!(0, import_node_fs5.existsSync)(pubPath)) continue;
66206
+ const priority = SSH_KEY_PRIORITY[name] ?? 10;
66207
+ candidates.push({ path: fullPath, priority });
66208
+ }
66209
+ return candidates.sort((a, b2) => a.priority - b2.priority).map((c) => c.path);
66210
+ }
66057
66211
  function signNonceWithSsh(keyPath, nonce) {
66058
66212
  const tempDir = (0, import_node_fs5.mkdtempSync)((0, import_node_path5.join)((0, import_node_os3.tmpdir)(), "eve-auth-"));
66059
66213
  const noncePath = (0, import_node_path5.join)(tempDir, "nonce");
@@ -66072,12 +66226,17 @@ function signNonceWithSsh(keyPath, nonce) {
66072
66226
  }
66073
66227
  }
66074
66228
  async function attemptSshLogin(context2, credentials, flags, email, userId, ttlDays) {
66229
+ const explicitKey = getStringFlag(flags, ["ssh-key"]) || process.env.EVE_AUTH_SSH_KEY || context2.profile.default_ssh_key;
66230
+ const keysToTry = explicitKey ? [explicitKey] : discoverSshKeys();
66231
+ if (keysToTry.length === 0) {
66232
+ return {
66233
+ success: false,
66234
+ error: "No SSH keys found. Provide --ssh-key <path> or add a keypair to ~/.ssh/"
66235
+ };
66236
+ }
66075
66237
  const challengeResponse = await requestRaw(context2, "/auth/challenge", {
66076
66238
  method: "POST",
66077
- body: {
66078
- email,
66079
- user_id: userId
66080
- }
66239
+ body: { email, user_id: userId }
66081
66240
  });
66082
66241
  if (!challengeResponse.ok) {
66083
66242
  const message = typeof challengeResponse.data === "string" ? challengeResponse.data : challengeResponse.text;
@@ -66087,33 +66246,42 @@ async function attemptSshLogin(context2, credentials, flags, email, userId, ttlD
66087
66246
  if (!challenge.challenge_id || !challenge.nonce) {
66088
66247
  return { success: false, error: "Challenge response missing fields" };
66089
66248
  }
66090
- const sshKeyPath = getStringFlag(flags, ["ssh-key"]) || process.env.EVE_AUTH_SSH_KEY || context2.profile.default_ssh_key || (0, import_node_path5.join)((0, import_node_os3.homedir)(), ".ssh", "id_ed25519");
66091
- let signature;
66092
- try {
66093
- signature = signNonceWithSsh(sshKeyPath, challenge.nonce);
66094
- } catch (err) {
66095
- const msg = err instanceof Error ? err.message : String(err);
66096
- return { success: false, error: `Failed to sign challenge: ${msg}` };
66097
- }
66098
- const verifyResponse = await requestRaw(context2, "/auth/verify", {
66099
- method: "POST",
66100
- body: { challenge_id: challenge.challenge_id, signature, ...ttlDays !== void 0 && { ttl_days: ttlDays } }
66101
- });
66102
- if (!verifyResponse.ok) {
66103
- const message = typeof verifyResponse.data === "string" ? verifyResponse.data : verifyResponse.text;
66104
- return { success: false, error: `Auth verify failed: ${message}` };
66105
- }
66106
- const payload = verifyResponse.data;
66107
- if (!payload.access_token) {
66108
- return { success: false, error: "Auth verify response missing access_token" };
66249
+ let lastError = "";
66250
+ for (const keyPath of keysToTry) {
66251
+ let signature;
66252
+ try {
66253
+ signature = signNonceWithSsh(keyPath, challenge.nonce);
66254
+ } catch {
66255
+ continue;
66256
+ }
66257
+ const verifyResponse = await requestRaw(context2, "/auth/verify", {
66258
+ method: "POST",
66259
+ body: {
66260
+ challenge_id: challenge.challenge_id,
66261
+ signature,
66262
+ ...ttlDays !== void 0 && { ttl_days: ttlDays }
66263
+ }
66264
+ });
66265
+ if (verifyResponse.ok) {
66266
+ const payload = verifyResponse.data;
66267
+ if (!payload.access_token) {
66268
+ return { success: false, error: "Auth verify response missing access_token" };
66269
+ }
66270
+ credentials.tokens[context2.authKey] = {
66271
+ access_token: payload.access_token,
66272
+ expires_at: payload.expires_at,
66273
+ token_type: payload.token_type
66274
+ };
66275
+ saveCredentials(credentials);
66276
+ if (!explicitKey) {
66277
+ const shortPath = keyPath.replace((0, import_node_os3.homedir)(), "~");
66278
+ console.log(`Using SSH key: ${shortPath}`);
66279
+ }
66280
+ return { success: true, tokenType: payload.token_type };
66281
+ }
66282
+ lastError = typeof verifyResponse.data === "string" ? verifyResponse.data : verifyResponse.text;
66109
66283
  }
66110
- credentials.tokens[context2.authKey] = {
66111
- access_token: payload.access_token,
66112
- expires_at: payload.expires_at,
66113
- token_type: payload.token_type
66114
- };
66115
- saveCredentials(credentials);
66116
- return { success: true, tokenType: payload.token_type };
66284
+ return { success: false, error: `Auth verify failed: ${lastError}` };
66117
66285
  }
66118
66286
  async function fetchGitHubKeys(username) {
66119
66287
  const response = await fetch(`https://github.com/${username}.keys`);
@@ -73250,6 +73418,9 @@ var import_node_fs10 = require("node:fs");
73250
73418
  async function handleAdmin(subcommand, positionals, flags, context2) {
73251
73419
  const json = Boolean(flags.json);
73252
73420
  switch (subcommand) {
73421
+ case "users": {
73422
+ return handleUsers(flags, context2, json);
73423
+ }
73253
73424
  case "invite": {
73254
73425
  const githubUsername = getStringFlag(flags, ["github"]);
73255
73426
  const sshKeyPath = getStringFlag(flags, ["ssh-key"]);
@@ -73735,8 +73906,68 @@ ${rows.length} alias(es)`);
73735
73906
  }
73736
73907
  }
73737
73908
  default:
73738
- throw new Error("Usage: eve admin <invite|pricing|receipts|balance|usage|ingress-aliases|access-requests>");
73909
+ throw new Error("Usage: eve admin <users|invite|pricing|receipts|balance|usage|ingress-aliases|access-requests>");
73910
+ }
73911
+ }
73912
+ async function handleUsers(flags, context2, json) {
73913
+ const users = await requestJson(context2, "/system/users");
73914
+ if (json) {
73915
+ outputJson(users, true);
73916
+ return;
73917
+ }
73918
+ if (users.length === 0) {
73919
+ console.log("No users found.");
73920
+ return;
73921
+ }
73922
+ const rows = [];
73923
+ for (const user of users) {
73924
+ const base = {
73925
+ id: user.id,
73926
+ email: user.email,
73927
+ name: user.display_name ?? "-",
73928
+ admin: user.is_admin ? "yes" : "",
73929
+ created: user.created_at?.split("T")[0] ?? ""
73930
+ };
73931
+ if (user.memberships.length === 0) {
73932
+ rows.push({ ...base, org: "-", role: "-" });
73933
+ } else {
73934
+ for (const m of user.memberships) {
73935
+ rows.push({ ...base, org: m.org_slug || m.org_name, role: m.role });
73936
+ }
73937
+ }
73938
+ }
73939
+ const col = (key, header2) => Math.max(header2.length, ...rows.map((r) => r[key].length));
73940
+ const w = {
73941
+ email: col("email", "Email"),
73942
+ name: col("name", "Name"),
73943
+ admin: col("admin", "Admin"),
73944
+ org: col("org", "Org"),
73945
+ role: col("role", "Role"),
73946
+ created: col("created", "Created")
73947
+ };
73948
+ const pad3 = (s, n) => s + " ".repeat(Math.max(0, n - s.length));
73949
+ const header = [
73950
+ pad3("Email", w.email),
73951
+ pad3("Name", w.name),
73952
+ pad3("Admin", w.admin),
73953
+ pad3("Org", w.org),
73954
+ pad3("Role", w.role),
73955
+ pad3("Created", w.created)
73956
+ ].join(" ");
73957
+ console.log(header);
73958
+ console.log("-".repeat(header.length));
73959
+ for (const row of rows) {
73960
+ console.log([
73961
+ pad3(row.email, w.email),
73962
+ pad3(row.name, w.name),
73963
+ pad3(row.admin, w.admin),
73964
+ pad3(row.org, w.org),
73965
+ pad3(row.role, w.role),
73966
+ pad3(row.created, w.created)
73967
+ ].join(" "));
73739
73968
  }
73969
+ console.log("");
73970
+ console.log(`${users.length} user(s)`);
73740
73971
  }
73741
73972
  function formatBalanceSummary(data) {
73742
73973
  if (!data.currency) {
@@ -80399,11 +80630,60 @@ function sleep(ms) {
80399
80630
  }
80400
80631
 
80401
80632
  // src/index.ts
80633
+ function getCliVersion() {
80634
+ try {
80635
+ const pkg = JSON.parse((0, import_fs4.readFileSync)((0, import_path3.join)(__dirname, "..", "package.json"), "utf-8"));
80636
+ return pkg.version;
80637
+ } catch {
80638
+ return "unknown";
80639
+ }
80640
+ }
80641
+ async function showVersion(json, apiUrl) {
80642
+ const cliVersion = getCliVersion();
80643
+ let platformInfo = null;
80644
+ if (apiUrl) {
80645
+ try {
80646
+ const res = await fetch(`${apiUrl}/health/version`);
80647
+ if (res.ok) {
80648
+ platformInfo = await res.json();
80649
+ }
80650
+ } catch {
80651
+ }
80652
+ }
80653
+ if (json) {
80654
+ const result = { cli: cliVersion };
80655
+ if (platformInfo) {
80656
+ result.platform = platformInfo;
80657
+ }
80658
+ if (apiUrl) {
80659
+ result.apiUrl = apiUrl;
80660
+ }
80661
+ console.log(JSON.stringify(result, null, 2));
80662
+ } else {
80663
+ console.log(`eve v${cliVersion}`);
80664
+ if (platformInfo) {
80665
+ const sha = platformInfo.gitSha !== "unknown" ? ` (${platformInfo.gitSha.slice(0, 7)})` : "";
80666
+ console.log(`platform v${platformInfo.version}${sha}`);
80667
+ }
80668
+ }
80669
+ }
80402
80670
  async function main2() {
80403
80671
  const { flags, positionals } = parseArgs(process.argv.slice(2));
80404
80672
  const command = positionals[0];
80405
80673
  const subcommand = positionals[1];
80406
80674
  const rest = positionals.slice(2);
80675
+ if (flags.version || command === "-v" || command === "version") {
80676
+ const json = Boolean(flags.json);
80677
+ let apiUrl;
80678
+ try {
80679
+ const credentials2 = loadCredentials();
80680
+ const context3 = resolveContext(flags, credentials2);
80681
+ apiUrl = context3.apiUrl;
80682
+ } catch {
80683
+ }
80684
+ await showVersion(json, apiUrl);
80685
+ return;
80686
+ }
80407
80687
  if (!command || command === "-h" || command === "--help") {
80408
80688
  showMainHelp();
80409
80689
  return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eve-horizon/cli",
3
- "version": "0.2.37",
3
+ "version": "0.2.39",
4
4
  "description": "Eve Horizon CLI",
5
5
  "license": "MIT",
6
6
  "repository": {