@evident-ai/cli 3.6.1-dev.2fd7890 → 3.6.1-dev.391e5fd

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/README.md CHANGED
@@ -125,6 +125,10 @@ Options:
125
125
  - `--opencode-config-overlay <path>` — Apply a runner-provided OpenCode config
126
126
  before starting OpenCode. Relative paths are resolved from the working directory;
127
127
  an existing `opencode.jsonc` is replaced before `opencode.json`.
128
+ - `--auto-configure-credentials-proxy` — Install Evident's generated `evident-*`
129
+ OpenCode provider entries for the runner's credential pool. This is off by default;
130
+ without it, the CLI only delivers `EVIDENT_PROXY_TOKEN` and leaves provider
131
+ configuration to you.
128
132
  - `--credential-sync-marker <path>` — Own the interval credential sync and write
129
133
  this marker once the shutdown flush has finished, so the runner image's lifecycle
130
134
  hooks can wait on it.
package/dist/index.js CHANGED
@@ -1442,7 +1442,7 @@ import ora4 from "ora";
1442
1442
  import { select as select4 } from "@inquirer/prompts";
1443
1443
 
1444
1444
  // src/lib/telemetry.ts
1445
- var CLI_VERSION = (true ? "3.6.1-dev.2fd7890" : void 0) ?? process.env.npm_package_version ?? "unknown";
1445
+ var CLI_VERSION = (true ? "3.6.1-dev.391e5fd" : void 0) ?? process.env.npm_package_version ?? "unknown";
1446
1446
  function getCliVersion() {
1447
1447
  return CLI_VERSION;
1448
1448
  }
@@ -5621,7 +5621,11 @@ function isSessionDbProvenanceRecord(value) {
5621
5621
  var OPENCODE2_PACKAGE_SPEC = "@opencode-ai/cli@0.0.0-beta-17823";
5622
5622
 
5623
5623
  // src/lib/opencode/opencode-version-gate.ts
5624
- var QUEUE_VALIDATED_OPENCODE_VERSIONS = ["1.17.11", "1.18.3"];
5624
+ var QUEUE_VALIDATED_OPENCODE_VERSIONS = [
5625
+ "1.17.11",
5626
+ "1.18.3",
5627
+ "1.18.35"
5628
+ ];
5625
5629
  function isQueueValidatedVersion(version2) {
5626
5630
  if (!version2) return false;
5627
5631
  return QUEUE_VALIDATED_OPENCODE_VERSIONS.includes(version2);
@@ -6666,6 +6670,7 @@ function connectTunnel(options) {
6666
6670
  }, 3e4);
6667
6671
  let relaySilenceTimeout;
6668
6672
  let relaySilenceTimedOut = false;
6673
+ let relayConnectionId;
6669
6674
  const clearRelaySilenceTimeout = () => {
6670
6675
  if (relaySilenceTimeout === void 0) return;
6671
6676
  clearTimeout(relaySilenceTimeout);
@@ -6751,7 +6756,8 @@ function connectTunnel(options) {
6751
6756
  armRelaySilenceTimeout();
6752
6757
  forwarder.setBinaryFramesSupported(message.binary_frames === true);
6753
6758
  const connectedAgentId = message.agent_id ?? agentId;
6754
- onConnected?.(connectedAgentId);
6759
+ relayConnectionId = message.connection_id;
6760
+ onConnected?.(connectedAgentId, relayConnectionId);
6755
6761
  resolve5({
6756
6762
  ws,
6757
6763
  close: () => ws.close(1e3, "CLI shutdown")
@@ -6788,7 +6794,7 @@ function connectTunnel(options) {
6788
6794
  clearRelaySilenceTimeout();
6789
6795
  const reasonStr = (relaySilenceTimedOut ? "no relay heartbeat for 90s \u2014 reconnecting" : void 0) || reason.toString() || upgradeRejection || (code === 1006 ? "abnormal closure" : "No reason provided");
6790
6796
  forwarder.abortAll();
6791
- onDisconnected?.(code, reasonStr);
6797
+ onDisconnected?.(code, reasonStr, relayConnectionId);
6792
6798
  });
6793
6799
  });
6794
6800
  }
@@ -6851,7 +6857,7 @@ var RunnerConnection = class _RunnerConnection {
6851
6857
  authHeader: this.opts.getAuthHeader(),
6852
6858
  port: this.opts.port,
6853
6859
  openCodePassword: this.opts.openCodePassword,
6854
- onConnected: (agentId) => {
6860
+ onConnected: (agentId, relayConnectionId) => {
6855
6861
  const attempt = this.reconnectAttempt + 1;
6856
6862
  this.reconnectAttempt = 0;
6857
6863
  this.reconnecting = false;
@@ -6861,13 +6867,17 @@ var RunnerConnection = class _RunnerConnection {
6861
6867
  this.disconnectedAtMs = null;
6862
6868
  events.onConnected(agentId, isReconnect, {
6863
6869
  generation: this.generation,
6870
+ relayConnectionId: relayConnectionId ?? null,
6864
6871
  attempt,
6865
6872
  downtimeMs
6866
6873
  });
6867
6874
  },
6868
- onDisconnected: (code, reason) => {
6875
+ onDisconnected: (code, reason, relayConnectionId) => {
6869
6876
  this.disconnectedAtMs = this.now();
6870
- events.onDisconnected(code, reason, { generation: this.generation });
6877
+ events.onDisconnected(code, reason, {
6878
+ generation: this.generation,
6879
+ relayConnectionId: relayConnectionId ?? null
6880
+ });
6871
6881
  const relayRequestedReconnect = code === 1e3 && _RunnerConnection.RELAY_RECONNECT_CLOSE_REASONS.has(reason);
6872
6882
  if (this.opts.isRunning() && (code !== 1e3 || relayRequestedReconnect) && !this.reconnecting) {
6873
6883
  this.reconnectPromise = this.connectWithRetry(true).catch((err) => {
@@ -13910,22 +13920,6 @@ function mergeManagedOpenCodeConfigContent(content, managedProviders) {
13910
13920
  }
13911
13921
  return JSON.stringify({ ...config, provider: { ...provider, ...managedProviders } });
13912
13922
  }
13913
- function removeManagedOpenCodeConfigContent(content) {
13914
- if (!content?.trim()) return content;
13915
- const config = parseConfigContent(content);
13916
- if (typeof config.provider !== "object" || config.provider === null || Array.isArray(config.provider)) {
13917
- return content;
13918
- }
13919
- const provider = { ...config.provider };
13920
- let changed = false;
13921
- for (const namespace of CREDENTIAL_PROXY_NATIVE_NAMESPACES) {
13922
- if (namespace in provider) {
13923
- delete provider[namespace];
13924
- changed = true;
13925
- }
13926
- }
13927
- return changed ? JSON.stringify({ ...config, provider }) : content;
13928
- }
13929
13923
  function isFile(filePath) {
13930
13924
  return existsSync2(filePath) && statSync6(filePath).isFile();
13931
13925
  }
@@ -14387,7 +14381,7 @@ async function responseJson(response) {
14387
14381
  function readSetup(value) {
14388
14382
  if (typeof value !== "object" || value === null || Array.isArray(value)) return null;
14389
14383
  const setup = value;
14390
- if (typeof setup.runner_id !== "string" || typeof setup.generation !== "string" || typeof setup.status !== "string" || setup.token_id !== null && typeof setup.token_id !== "string") {
14384
+ if (typeof setup.runner_id !== "string" || typeof setup.generation !== "string" || typeof setup.status !== "string" || setup.token_id !== null && typeof setup.token_id !== "string" || typeof setup.acknowledged_at !== "string" && setup.acknowledged_at !== null) {
14391
14385
  return null;
14392
14386
  }
14393
14387
  return setup;
@@ -14396,16 +14390,6 @@ function clearLocalSetup(options) {
14396
14390
  const env = options.env ?? process.env;
14397
14391
  (options.store ?? defaultStore).clear(options.agentId);
14398
14392
  delete env.EVIDENT_PROXY_TOKEN;
14399
- try {
14400
- const content = removeManagedOpenCodeConfigContent(env.OPENCODE_CONFIG_CONTENT);
14401
- if (content === void 0) delete env.OPENCODE_CONFIG_CONTENT;
14402
- else env.OPENCODE_CONFIG_CONTENT = content;
14403
- } catch (error2) {
14404
- options.log(
14405
- "MANAGED-INFERENCE-CLEANUP-PARTIAL: stored credentials were removed, but malformed OPENCODE_CONFIG_CONTENT could not be inspected",
14406
- "warn"
14407
- );
14408
- }
14409
14393
  }
14410
14394
  async function discoverManagedInferenceSetup(options) {
14411
14395
  const headers = requestHeaders(options);
@@ -14429,6 +14413,25 @@ async function discoverManagedInferenceSetup(options) {
14429
14413
  const setup = readSetup(body?.setup);
14430
14414
  return setup ? { kind: "setup", setup } : { kind: "failed", reason: "Managed setup discovery returned an invalid response" };
14431
14415
  }
14416
+ async function enrollManagedInferenceSetup(options) {
14417
+ const response = await post(options, "enroll", {});
14418
+ if (!response) {
14419
+ return { kind: "failed", reason: safeFailure("Managed credential enrollment") };
14420
+ }
14421
+ if (response.status === 404) {
14422
+ return { kind: "none" };
14423
+ }
14424
+ const body = await responseJson(response);
14425
+ if (!response.ok) {
14426
+ const serverError = body?.error;
14427
+ return {
14428
+ kind: "failed",
14429
+ reason: typeof serverError === "string" && serverError.trim() ? redactDiagnosticText(serverError).slice(0, 500) : safeFailure("Managed credential enrollment", response.status)
14430
+ };
14431
+ }
14432
+ const setup = readSetup(body?.setup);
14433
+ return setup ? { kind: "setup", setup } : { kind: "failed", reason: "Managed credential enrollment returned an invalid response" };
14434
+ }
14432
14435
  async function post(options, operation, body) {
14433
14436
  const headers = requestHeaders(options);
14434
14437
  try {
@@ -14443,31 +14446,37 @@ async function post(options, operation, body) {
14443
14446
  }
14444
14447
  }
14445
14448
  function applyCredential(options, credential) {
14446
- const { config, unsupportedProviders } = buildCredentialProxyNativeConfig({
14447
- inferenceBaseUrl: credential.inferenceBaseUrl,
14448
- modelDescriptors: credential.modelDescriptors
14449
- });
14450
- if (unsupportedProviders.length > 0 || Object.keys(config.provider).length === 0) {
14451
- return "Managed setup contains unsupported provider descriptors";
14452
- }
14453
14449
  const env = options.env ?? process.env;
14454
14450
  let merged;
14455
- try {
14456
- merged = mergeManagedOpenCodeConfigContent(env.OPENCODE_CONFIG_CONTENT, config.provider);
14457
- } catch (error2) {
14458
- return "OPENCODE_CONFIG_CONTENT is malformed; managed providers were not installed";
14451
+ if (options.autoConfigureCredentialsProxy) {
14452
+ const { config, unsupportedProviders } = buildCredentialProxyNativeConfig({
14453
+ inferenceBaseUrl: credential.inferenceBaseUrl,
14454
+ modelDescriptors: credential.modelDescriptors
14455
+ });
14456
+ if (unsupportedProviders.length > 0 || Object.keys(config.provider).length === 0) {
14457
+ return "Managed setup contains unsupported provider descriptors";
14458
+ }
14459
+ try {
14460
+ merged = mergeManagedOpenCodeConfigContent(env.OPENCODE_CONFIG_CONTENT, config.provider);
14461
+ } catch (error2) {
14462
+ return "OPENCODE_CONFIG_CONTENT is malformed; managed providers were not installed";
14463
+ }
14459
14464
  }
14460
14465
  try {
14461
14466
  (options.store ?? defaultStore).set(options.agentId, credential);
14462
14467
  } catch (error2) {
14468
+ const detail = (error2 instanceof Error ? error2.message : String(error2)).replaceAll(
14469
+ credential.token,
14470
+ "[redacted]"
14471
+ );
14463
14472
  options.log(
14464
- `MANAGED-INFERENCE-STORE-FAILED: runner=${options.agentId} generation=${credential.generation}`,
14473
+ `MANAGED-INFERENCE-STORE-FAILED: runner=${options.agentId} generation=${credential.generation} detail=${redactDiagnosticText(detail)}`,
14465
14474
  "warn"
14466
14475
  );
14467
14476
  return "Managed credentials could not be written to the protected store";
14468
14477
  }
14469
14478
  env.EVIDENT_PROXY_TOKEN = credential.token;
14470
- env.OPENCODE_CONFIG_CONTENT = merged;
14479
+ if (merged !== void 0) env.OPENCODE_CONFIG_CONTENT = merged;
14471
14480
  return null;
14472
14481
  }
14473
14482
  async function reportManagedInferenceApplyFailure(options, failure) {
@@ -14518,7 +14527,7 @@ async function prepareManagedInferenceSetup(options, discovery, health) {
14518
14527
  }
14519
14528
  return reaffirmStored(options, stored);
14520
14529
  }
14521
- if (discovery.setup.status === "acknowledged" && stored?.generation === discovery.setup.generation && stored.tokenId === discovery.setup.token_id) {
14530
+ if (discovery.setup.acknowledged_at !== null && stored?.generation === discovery.setup.generation && stored.tokenId === discovery.setup.token_id) {
14522
14531
  return reaffirmStored(options, stored);
14523
14532
  }
14524
14533
  const response = await post(options, "bootstrap", { generation: discovery.setup.generation });
@@ -14556,7 +14565,7 @@ async function acknowledgeManagedInferenceSetup(options, preparation) {
14556
14565
  const response = await post(options, "acknowledge", {
14557
14566
  generation: preparation.generation,
14558
14567
  token_id: preparation.tokenId,
14559
- config_validated: true
14568
+ config_validated: options.autoConfigureCredentialsProxy === true
14560
14569
  });
14561
14570
  if (!response?.ok) {
14562
14571
  throw new Error(
@@ -16359,13 +16368,17 @@ async function run(options) {
16359
16368
  agentId: state.agentId,
16360
16369
  apiUrl: getApiUrlConfig(),
16361
16370
  getAuthHeader: () => state.authHeader,
16371
+ autoConfigureCredentialsProxy: options.autoConfigureCredentialsProxy,
16362
16372
  log: (message, level = "info") => logActivity(state, {
16363
16373
  type: level === "error" ? "error" : "info",
16364
16374
  level,
16365
16375
  ...level === "error" ? { error: message } : { message }
16366
16376
  })
16367
16377
  };
16368
- const managedDiscovery = await discoverManagedInferenceSetup(managedSetupOptions);
16378
+ let managedDiscovery = await discoverManagedInferenceSetup(managedSetupOptions);
16379
+ if (managedDiscovery.kind === "none") {
16380
+ managedDiscovery = await enrollManagedInferenceSetup(managedSetupOptions);
16381
+ }
16369
16382
  let managedPreparation = { kind: "none" };
16370
16383
  if (managedDiscovery.kind === "failed") {
16371
16384
  managedPreparation = managedDiscovery;
@@ -16689,7 +16702,7 @@ async function run(options) {
16689
16702
  onConnected: (agentId, isReconnect, transition) => {
16690
16703
  state.connected = true;
16691
16704
  state.agentId = agentId;
16692
- const connectionMessage = isReconnect ? `Tunnel reconnected (runner: ${agentId}, generation: ${transition.generation}, attempt: ${transition.attempt}, offline for ${transition.downtimeMs}ms)` : `Tunnel connected (runner: ${agentId}, generation: ${transition.generation})`;
16705
+ const connectionMessage = isReconnect ? `Tunnel reconnected (runner: ${agentId}, generation: ${transition.generation}, relay connection: ${transition.relayConnectionId ?? "unknown"}, attempt: ${transition.attempt}, offline for ${transition.downtimeMs}ms)` : `Tunnel connected (runner: ${agentId}, generation: ${transition.generation}, relay connection: ${transition.relayConnectionId ?? "unknown"})`;
16693
16706
  logActivity(state, {
16694
16707
  type: "info",
16695
16708
  message: connectionMessage
@@ -16722,6 +16735,7 @@ async function run(options) {
16722
16735
  connected: state.opencodeConnected
16723
16736
  }),
16724
16737
  connection_generation: transition.generation,
16738
+ ...transition.relayConnectionId !== null ? { relay_connection_id: transition.relayConnectionId } : {},
16725
16739
  ...isReconnect && transition.downtimeMs !== null ? {
16726
16740
  reconnect_attempt: transition.attempt,
16727
16741
  downtime_ms: transition.downtimeMs
@@ -16752,12 +16766,13 @@ async function run(options) {
16752
16766
  const safeReason2 = redactDiagnosticText(reason).slice(0, MAX_DISCONNECT_REASON_LENGTH);
16753
16767
  logActivity(state, {
16754
16768
  type: "info",
16755
- message: `Tunnel disconnected (generation: ${transition.generation}, code: ${code}, reason: ${safeReason2})`
16769
+ message: `Tunnel disconnected (generation: ${transition.generation}, relay connection: ${transition.relayConnectionId ?? "unknown"}, code: ${code}, reason: ${safeReason2})`
16756
16770
  });
16757
16771
  emitAgentDisconnected(state.agentId, {
16758
16772
  code,
16759
16773
  reason: safeReason2,
16760
- connection_generation: transition.generation
16774
+ connection_generation: transition.generation,
16775
+ ...transition.relayConnectionId !== null ? { relay_connection_id: transition.relayConnectionId } : {}
16761
16776
  });
16762
16777
  if (state.interactive) displayStatus(state);
16763
16778
  },
@@ -16984,6 +16999,9 @@ program.command("run").description("Connect to Evident and process messages").op
16984
16999
  ).option(
16985
17000
  "--opencode-config-overlay <path>",
16986
17001
  "Apply this runner-provided OpenCode config before starting OpenCode."
17002
+ ).option(
17003
+ "--auto-configure-credentials-proxy",
17004
+ "Install Evident's generated OpenCode providers for the runner's credential pool (off by default)."
16987
17005
  ).option(
16988
17006
  "--credential-sync-marker <path>",
16989
17007
  "Own the interval credential sync and write this marker once the shutdown flush has finished, so the runner image's lifecycle hooks can wait on it."
@@ -17027,6 +17045,7 @@ program.command("run").description("Connect to Evident and process messages").op
17027
17045
  restoreSessionDb: options.restoreSessionDb,
17028
17046
  restoreRunnerCredentials: options.restoreRunnerCredentials,
17029
17047
  opencodeConfigOverlay: options.opencodeConfigOverlay,
17048
+ autoConfigureCredentialsProxy: options.autoConfigureCredentialsProxy,
17030
17049
  credentialSyncMarker: options.credentialSyncMarker
17031
17050
  });
17032
17051
  }