@evident-ai/cli 3.1.1-dev.14c6359 → 3.1.1-dev.3a785a9

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
@@ -85,6 +85,7 @@ Options:
85
85
 
86
86
  - `-a, --agent [id]` — Runner ID to connect to. Optional when `EVIDENT_AGENT_KEY`
87
87
  is set (the runner is then resolved automatically from the key).
88
+ - `--runner [id]` — Alias for `--agent` (preferred name; wins if both are given).
88
89
  - `-p, --port <port>` — OpenCode port (default: `4096`).
89
90
  - `--log-level <level>` — Log verbosity: `debug | info | warn | error` (default:
90
91
  `info`). Env: `EVIDENT_LOG_LEVEL`.
@@ -105,15 +106,18 @@ targets the **production** Evident platform by default.
105
106
 
106
107
  ## Environment variables
107
108
 
108
- - `EVIDENT_AGENT_KEY` — A runner key. When set, `evident run` authenticates as
109
- that runner and resolves the runner ID automatically, so `--agent` is not
110
- required. Ideal for CI/CD.
109
+ - `EVIDENT_RUNNER_KEY` — A runner key. When set, `evident run` authenticates as
110
+ that runner and resolves the runner ID automatically, so `--runner`/`--agent`
111
+ is not required. Ideal for CI/CD. Preferred name; wins over `EVIDENT_AGENT_KEY`
112
+ if both are set.
113
+ - `EVIDENT_AGENT_KEY` — Alias for `EVIDENT_RUNNER_KEY` (still fully supported).
111
114
  - `EVIDENT_TOKEN` — A user token used for authentication (alternative to a
112
115
  keychain login from `evident login`).
113
116
  - `EVIDENT_API_URL` — Override the API base URL (equivalent to `--endpoint`).
114
117
  - `EVIDENT_TUNNEL_URL` — Override the tunnel relay URL (equivalent to `--tunnel`).
115
118
 
116
- Authentication precedence for `run`: `EVIDENT_AGENT_KEY` → `EVIDENT_TOKEN` →
119
+ Authentication precedence for `run`: `EVIDENT_RUNNER_KEY`/`EVIDENT_AGENT_KEY`
120
+ (tied; `EVIDENT_RUNNER_KEY` wins if both are set) → `EVIDENT_TOKEN` →
117
121
  credentials stored by `evident login`. For the URL flags, an explicit
118
122
  `--endpoint` / `--tunnel` flag wins over the matching environment variable, which
119
123
  in turn overrides the production default.
@@ -150,6 +154,8 @@ For CI or unattended use, set `EVIDENT_AGENT_KEY` and omit `--agent`:
150
154
  EVIDENT_AGENT_KEY=<agent-key> evident run --idle-timeout 30
151
155
  ```
152
156
 
157
+ (`EVIDENT_RUNNER_KEY` is equivalent and the preferred name — use whichever you like.)
158
+
153
159
  ## How it works
154
160
 
155
161
  ```
package/dist/index.js CHANGED
@@ -645,14 +645,27 @@ var EventTypes = {
645
645
  // CLI lifecycle
646
646
  CLI_STARTED: "cli.started",
647
647
  CLI_COMMAND: "cli.command",
648
- CLI_ERROR: "cli.error"
648
+ CLI_ERROR: "cli.error",
649
+ // Deprecation telemetry (#412) — usage of the old `--agent`/`EVIDENT_AGENT_KEY`
650
+ // names instead of the preferred `--runner`/`EVIDENT_RUNNER_KEY` (#409).
651
+ DEPRECATED_AGENT_FLAG_USED: "cli.deprecated_agent_flag_used",
652
+ DEPRECATED_AGENT_KEY_ENV_USED: "cli.deprecated_agent_key_env_used"
649
653
  };
650
654
 
651
655
  // src/lib/auth.ts
652
656
  async function getAuthCredentials() {
657
+ const runnerKey = process.env.EVIDENT_RUNNER_KEY;
653
658
  const agentKey = process.env.EVIDENT_AGENT_KEY;
659
+ if (runnerKey) {
660
+ return {
661
+ token: runnerKey,
662
+ authType: "agent_key",
663
+ keySource: "runner_key",
664
+ notice: agentKey ? "Both EVIDENT_RUNNER_KEY and EVIDENT_AGENT_KEY are set; using EVIDENT_RUNNER_KEY." : void 0
665
+ };
666
+ }
654
667
  if (agentKey) {
655
- return { token: agentKey, authType: "agent_key" };
668
+ return { token: agentKey, authType: "agent_key", keySource: "agent_key" };
656
669
  }
657
670
  const userToken = process.env.EVIDENT_TOKEN;
658
671
  if (userToken) {
@@ -721,7 +734,7 @@ function buildOpenCodeVersionWarning(version2) {
721
734
  if (isQueueValidatedVersion(version2)) return null;
722
735
  const detected = version2 ? `v${version2}` : "unknown";
723
736
  const validated = QUEUE_VALIDATED_OPENCODE_VERSIONS.map((v) => `v${v}`).join(", ");
724
- return `Warning: opencode ${detected} is not a queue-validated version (validated: ${validated}). Native message queuing \u2014 which channel (Slack/WhatsApp) message handling relies on \u2014 is unverified on this version; queued/follow-up messages may behave unexpectedly. Continuing anyway. Bumping the validated set requires re-running the queue validation.`;
737
+ return `Warning: opencode ${detected} is not a queue-validated version (validated: ${validated}). Native message queuing \u2014 which channel (Slack) message handling relies on \u2014 is unverified on this version; queued/follow-up messages may behave unexpectedly. Continuing anyway. Bumping the validated set requires re-running the queue validation.`;
725
738
  }
726
739
 
727
740
  // src/lib/opencode/process.ts
@@ -1215,6 +1228,11 @@ async function getModelAttachmentCapability(port, model) {
1215
1228
  }
1216
1229
  const entry = provider.models[modelId];
1217
1230
  if (!entry || typeof entry !== "object") return null;
1231
+ if (entry.capabilities && typeof entry.capabilities === "object") {
1232
+ if (typeof entry.capabilities.attachment === "boolean") {
1233
+ return entry.capabilities.attachment;
1234
+ }
1235
+ }
1218
1236
  return typeof entry.attachment === "boolean" ? entry.attachment : null;
1219
1237
  } catch (err) {
1220
1238
  console.error(
@@ -1782,7 +1800,6 @@ function connectTunnel(options) {
1782
1800
  onConnected,
1783
1801
  onDisconnected,
1784
1802
  onError,
1785
- onRequest,
1786
1803
  onResponse,
1787
1804
  onInfo,
1788
1805
  onDrainPing
@@ -1795,18 +1812,8 @@ function connectTunnel(options) {
1795
1812
  Authorization: authHeader
1796
1813
  }
1797
1814
  });
1798
- const streamStartTimes = /* @__PURE__ */ new Map();
1799
1815
  const forwarder = new StreamForwarder(ws, port, {
1800
- onOpen: (sid, method, path) => {
1801
- if (path === TUNNEL_DRAIN_PING_PATH) return;
1802
- streamStartTimes.set(sid, Date.now());
1803
- onRequest?.(method, path, sid);
1804
- },
1805
- onHead: (sid, status) => {
1806
- const startedAt = streamStartTimes.get(sid);
1807
- streamStartTimes.delete(sid);
1808
- onResponse?.(status, startedAt ? Date.now() - startedAt : 0, sid);
1809
- },
1816
+ onHead: () => onResponse?.(),
1810
1817
  onDrainPing: () => onDrainPing?.()
1811
1818
  });
1812
1819
  const connectionTimeout = setTimeout(() => {
@@ -1882,7 +1889,6 @@ function connectTunnel(options) {
1882
1889
  ws.on("close", (code, reason) => {
1883
1890
  const reasonStr = reason.toString() || upgradeRejection || (code === 1006 ? "abnormal closure" : "No reason provided");
1884
1891
  forwarder.abortAll();
1885
- streamStartTimes.clear();
1886
1892
  onDisconnected?.(code, reasonStr);
1887
1893
  });
1888
1894
  });
@@ -2511,7 +2517,7 @@ var ChannelDriver = class {
2511
2517
  }
2512
2518
  /**
2513
2519
  * Fetch ONE inbound image's bytes through Evident's WI-6 endpoint
2514
- * (`GET {apiUrl}/agents/{agentId}/attachments/{messageId}/{index}`) using the
2520
+ * (`GET {apiUrl}/runners/{agentId}/attachments/{messageId}/{index}`) using the
2515
2521
  * existing authenticated fetch, and base64-encode into a
2516
2522
  * `data:<mime>;base64,<…>` URL for the opencode `file` part's `url`.
2517
2523
  *
@@ -2524,7 +2530,7 @@ var ChannelDriver = class {
2524
2530
  async fetchAttachmentDataUrl(messageId, index, mime) {
2525
2531
  try {
2526
2532
  const res = await this.fetchImpl(
2527
- `${this.apiUrl}/agents/${this.agentId}/attachments/${messageId}/${index}`,
2533
+ `${this.apiUrl}/runners/${this.agentId}/attachments/${messageId}/${index}`,
2528
2534
  { headers: { Authorization: this.getAuthHeader() } }
2529
2535
  );
2530
2536
  if (!res.ok) {
@@ -3790,7 +3796,7 @@ var ChannelDriver = class {
3790
3796
  // Evident API calls (combinedAuth thread routes)
3791
3797
  async getPendingConversations() {
3792
3798
  const res = await this.fetchImpl(
3793
- `${this.apiUrl}/agents/${this.agentId}/conversations/pending`,
3799
+ `${this.apiUrl}/runners/${this.agentId}/conversations/pending`,
3794
3800
  {
3795
3801
  headers: { Authorization: this.getAuthHeader() }
3796
3802
  }
@@ -3808,7 +3814,7 @@ var ChannelDriver = class {
3808
3814
  }
3809
3815
  async getPendingMessages(conversationId) {
3810
3816
  const res = await this.fetchImpl(
3811
- `${this.apiUrl}/agents/${this.agentId}/threads/${conversationId}/messages?status=pending`,
3817
+ `${this.apiUrl}/runners/${this.agentId}/threads/${conversationId}/messages?status=pending`,
3812
3818
  { headers: { Authorization: this.getAuthHeader() } }
3813
3819
  );
3814
3820
  this.assertAuth(res, "fetching pending messages");
@@ -3832,7 +3838,7 @@ var ChannelDriver = class {
3832
3838
  */
3833
3839
  async getProcessingMessages() {
3834
3840
  const res = await this.fetchImpl(
3835
- `${this.apiUrl}/agents/${this.agentId}/conversations/processing`,
3841
+ `${this.apiUrl}/runners/${this.agentId}/conversations/processing`,
3836
3842
  { headers: { Authorization: this.getAuthHeader() } }
3837
3843
  );
3838
3844
  this.assertAuth(res, "fetching processing messages");
@@ -3869,7 +3875,7 @@ var ChannelDriver = class {
3869
3875
  */
3870
3876
  async markProcessing(conversationId, messageId, sessionId, opencodeMessageId, title) {
3871
3877
  const res = await this.fetchImpl(
3872
- `${this.apiUrl}/agents/${this.agentId}/threads/${conversationId}/messages/${messageId}`,
3878
+ `${this.apiUrl}/runners/${this.agentId}/threads/${conversationId}/messages/${messageId}`,
3873
3879
  {
3874
3880
  method: "PATCH",
3875
3881
  headers: { Authorization: this.getAuthHeader(), "Content-Type": "application/json" },
@@ -3918,7 +3924,7 @@ var ChannelDriver = class {
3918
3924
  */
3919
3925
  async markDone(conversationId, messageId, sessionId, opencodeMessageId, title, usage) {
3920
3926
  const res = await this.fetchImpl(
3921
- `${this.apiUrl}/agents/${this.agentId}/threads/${conversationId}/messages/${messageId}`,
3927
+ `${this.apiUrl}/runners/${this.agentId}/threads/${conversationId}/messages/${messageId}`,
3922
3928
  {
3923
3929
  method: "PATCH",
3924
3930
  headers: { Authorization: this.getAuthHeader(), "Content-Type": "application/json" },
@@ -3953,7 +3959,7 @@ var ChannelDriver = class {
3953
3959
  await this.callWithRetry(
3954
3960
  "marking message as failed",
3955
3961
  () => this.fetchImpl(
3956
- `${this.apiUrl}/agents/${this.agentId}/threads/${conversationId}/messages/${messageId}`,
3962
+ `${this.apiUrl}/runners/${this.agentId}/threads/${conversationId}/messages/${messageId}`,
3957
3963
  {
3958
3964
  method: "PATCH",
3959
3965
  headers: { Authorization: this.getAuthHeader(), "Content-Type": "application/json" },
@@ -3980,7 +3986,7 @@ var ChannelDriver = class {
3980
3986
  async postSignal(conversationId, messageId, signal, extra) {
3981
3987
  try {
3982
3988
  const res = await this.fetchImpl(
3983
- `${this.apiUrl}/agents/${this.agentId}/threads/${conversationId}/messages/${messageId}/signal`,
3989
+ `${this.apiUrl}/runners/${this.agentId}/threads/${conversationId}/messages/${messageId}/signal`,
3984
3990
  {
3985
3991
  method: "POST",
3986
3992
  headers: { Authorization: this.getAuthHeader(), "Content-Type": "application/json" },
@@ -4009,7 +4015,7 @@ var ChannelDriver = class {
4009
4015
  }
4010
4016
  async persistSession(conversationId, sessionId) {
4011
4017
  const res = await this.fetchImpl(
4012
- `${this.apiUrl}/agents/${this.agentId}/threads/${conversationId}`,
4018
+ `${this.apiUrl}/runners/${this.agentId}/threads/${conversationId}`,
4013
4019
  {
4014
4020
  method: "PATCH",
4015
4021
  headers: { Authorization: this.getAuthHeader(), "Content-Type": "application/json" },
@@ -4035,7 +4041,7 @@ var ChannelDriver = class {
4035
4041
  await this.callWithRetry(
4036
4042
  "reporting interactive event",
4037
4043
  () => this.fetchImpl(
4038
- `${this.apiUrl}/agents/${this.agentId}/threads/${conversationId}/interactive-event`,
4044
+ `${this.apiUrl}/runners/${this.agentId}/threads/${conversationId}/interactive-event`,
4039
4045
  {
4040
4046
  method: "POST",
4041
4047
  headers: { Authorization: this.getAuthHeader(), "Content-Type": "application/json" },
@@ -4278,7 +4284,7 @@ async function resolveAgentIdFromKey(authHeader) {
4278
4284
  async function notifyAgentDisconnected(agentId, authHeader) {
4279
4285
  const apiUrl = getApiUrlConfig();
4280
4286
  try {
4281
- const response = await fetch(`${apiUrl}/agents/${agentId}/disconnect`, {
4287
+ const response = await fetch(`${apiUrl}/runners/${agentId}/disconnect`, {
4282
4288
  method: "POST",
4283
4289
  headers: { Authorization: authHeader }
4284
4290
  });
@@ -4297,7 +4303,7 @@ async function notifyAgentDisconnected(agentId, authHeader) {
4297
4303
  async function getAgentInfo(agentId, authHeader) {
4298
4304
  const apiUrl = getApiUrlConfig();
4299
4305
  try {
4300
- const response = await fetch(`${apiUrl}/agents/${agentId}`, {
4306
+ const response = await fetch(`${apiUrl}/runners/${agentId}`, {
4301
4307
  headers: { Authorization: authHeader }
4302
4308
  });
4303
4309
  if (response.status === 401) {
@@ -4684,7 +4690,7 @@ async function run(options) {
4684
4690
  return;
4685
4691
  }
4686
4692
  const state = {
4687
- agentId: options.agent || "",
4693
+ agentId: options.runner || options.agent || "",
4688
4694
  agentName: null,
4689
4695
  port: options.port ?? 4096,
4690
4696
  conversationFilter: options.conversation ?? null,
@@ -4706,6 +4712,19 @@ async function run(options) {
4706
4712
  sessionCleanupTimers: [],
4707
4713
  authHeader: ""
4708
4714
  };
4715
+ if (!options.runner && options.agent) {
4716
+ telemetry.info(
4717
+ EventTypes.DEPRECATED_AGENT_FLAG_USED,
4718
+ "Deprecated --agent flag used instead of --runner",
4719
+ { command: "run" },
4720
+ state.agentId
4721
+ );
4722
+ const agentFlagNotice = "--agent is deprecated, use --runner instead; will be removed in a future release.";
4723
+ log2(state, agentFlagNotice, "warn");
4724
+ if (state.interactive && !state.json) {
4725
+ logActivity(state, { type: "info", level: "warn", message: agentFlagNotice });
4726
+ }
4727
+ }
4709
4728
  if (state.idleTimeout === null && (process.env.GITHUB_ACTIONS || process.env.CI)) {
4710
4729
  log2(
4711
4730
  state,
@@ -4734,7 +4753,9 @@ async function run(options) {
4734
4753
  if (!interactive) {
4735
4754
  printError("Authentication required");
4736
4755
  blank();
4737
- console.log(chalk6.dim("Set EVIDENT_AGENT_KEY environment variable for CI"));
4756
+ console.log(
4757
+ chalk6.dim("Set EVIDENT_RUNNER_KEY (or EVIDENT_AGENT_KEY) environment variable for CI")
4758
+ );
4738
4759
  console.log(chalk6.dim("Or run `evident login` for interactive authentication"));
4739
4760
  blank();
4740
4761
  process.exit(1);
@@ -4748,6 +4769,25 @@ async function run(options) {
4748
4769
  );
4749
4770
  }
4750
4771
  state.authHeader = getAuthHeader(credentials2);
4772
+ if (credentials2.notice) {
4773
+ log2(state, credentials2.notice, "warn");
4774
+ if (state.interactive && !state.json) {
4775
+ logActivity(state, { type: "info", level: "warn", message: credentials2.notice });
4776
+ }
4777
+ }
4778
+ if (credentials2.keySource === "agent_key") {
4779
+ telemetry.info(
4780
+ EventTypes.DEPRECATED_AGENT_KEY_ENV_USED,
4781
+ "Deprecated EVIDENT_AGENT_KEY env var used instead of EVIDENT_RUNNER_KEY",
4782
+ { command: "run" },
4783
+ state.agentId
4784
+ );
4785
+ const agentKeyNotice = "EVIDENT_AGENT_KEY is deprecated, use EVIDENT_RUNNER_KEY instead; will be removed in a future release.";
4786
+ log2(state, agentKeyNotice, "warn");
4787
+ if (state.interactive && !state.json) {
4788
+ logActivity(state, { type: "info", level: "warn", message: agentKeyNotice });
4789
+ }
4790
+ }
4751
4791
  if (!state.agentId) {
4752
4792
  if (credentials2.authType === "agent_key") {
4753
4793
  const resolved = await resolveAgentIdFromKey(state.authHeader);
@@ -4765,9 +4805,15 @@ async function run(options) {
4765
4805
  process.exit(1);
4766
4806
  }
4767
4807
  } else {
4768
- printError("--agent is required when not using EVIDENT_AGENT_KEY");
4808
+ printError(
4809
+ "--runner (or --agent) is required when not using EVIDENT_RUNNER_KEY or EVIDENT_AGENT_KEY"
4810
+ );
4769
4811
  blank();
4770
- console.log(chalk6.dim("Either provide --agent <id> or set EVIDENT_AGENT_KEY"));
4812
+ console.log(
4813
+ chalk6.dim(
4814
+ "Either provide --runner/--agent <id> or set EVIDENT_RUNNER_KEY/EVIDENT_AGENT_KEY"
4815
+ )
4816
+ );
4771
4817
  blank();
4772
4818
  process.exit(1);
4773
4819
  }
@@ -4982,7 +5028,7 @@ async function run(options) {
4982
5028
  }
4983
5029
  telemetry.error(EventTypes.CLI_ERROR, `Run command failed: ${message}`, {
4984
5030
  command: "run",
4985
- agentId: options.agent
5031
+ agentId: options.runner || options.agent
4986
5032
  });
4987
5033
  await shutdownTelemetry();
4988
5034
  process.exit(1);
@@ -5007,7 +5053,7 @@ program.name("evident").description("Run OpenCode locally and connect it to Evid
5007
5053
  program.command("login").description("Authenticate with Evident").option("--token", "Use token-based authentication (for CI/CD)").option("--no-browser", "Do not open the browser automatically").action(login);
5008
5054
  program.command("logout").description("Remove stored credentials for the current endpoint").option("--all", "Remove stored credentials for all endpoints").action((options) => logout({ all: options.all }));
5009
5055
  program.command("whoami").description("Show the currently logged in user").action(whoami);
5010
- program.command("run").description("Connect to Evident and process messages").option("-a, --agent [id]", "Runner ID to connect to (optional when EVIDENT_AGENT_KEY is set)").option("-p, --port <port>", "OpenCode port (default: 4096)", "4096").option(
5056
+ program.command("run").description("Connect to Evident and process messages").option("-a, --agent [id]", "Runner ID to connect to (optional when EVIDENT_AGENT_KEY is set)").option("--runner [id]", "Alias for --agent (preferred name; wins if both are given)").option("-p, --port <port>", "OpenCode port (default: 4096)", "4096").option(
5011
5057
  "--log-level <level>",
5012
5058
  "Log verbosity: debug | info | warn | error (default: info). Env: EVIDENT_LOG_LEVEL"
5013
5059
  ).option("-v, --verbose", "Alias for --log-level debug (ignored if --log-level is set)").option("-c, --conversation <id>", "Process only this specific conversation").option("--idle-timeout <seconds>", "Exit after N seconds idle").option("--json", "Output in JSON format").option(
@@ -5023,6 +5069,7 @@ program.command("run").description("Connect to Evident and process messages").op
5023
5069
  (options) => {
5024
5070
  run({
5025
5071
  agent: options.agent,
5072
+ runner: options.runner,
5026
5073
  port: parseInt(options.port, 10),
5027
5074
  // Raw string — validation/precedence is single-sourced in run.ts's
5028
5075
  // resolveLogLevel (flag > -v > EVIDENT_LOG_LEVEL > info).