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

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) {
@@ -1782,7 +1795,6 @@ function connectTunnel(options) {
1782
1795
  onConnected,
1783
1796
  onDisconnected,
1784
1797
  onError,
1785
- onRequest,
1786
1798
  onResponse,
1787
1799
  onInfo,
1788
1800
  onDrainPing
@@ -1795,18 +1807,8 @@ function connectTunnel(options) {
1795
1807
  Authorization: authHeader
1796
1808
  }
1797
1809
  });
1798
- const streamStartTimes = /* @__PURE__ */ new Map();
1799
1810
  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
- },
1811
+ onHead: () => onResponse?.(),
1810
1812
  onDrainPing: () => onDrainPing?.()
1811
1813
  });
1812
1814
  const connectionTimeout = setTimeout(() => {
@@ -1882,7 +1884,6 @@ function connectTunnel(options) {
1882
1884
  ws.on("close", (code, reason) => {
1883
1885
  const reasonStr = reason.toString() || upgradeRejection || (code === 1006 ? "abnormal closure" : "No reason provided");
1884
1886
  forwarder.abortAll();
1885
- streamStartTimes.clear();
1886
1887
  onDisconnected?.(code, reasonStr);
1887
1888
  });
1888
1889
  });
@@ -2511,7 +2512,7 @@ var ChannelDriver = class {
2511
2512
  }
2512
2513
  /**
2513
2514
  * Fetch ONE inbound image's bytes through Evident's WI-6 endpoint
2514
- * (`GET {apiUrl}/agents/{agentId}/attachments/{messageId}/{index}`) using the
2515
+ * (`GET {apiUrl}/runners/{agentId}/attachments/{messageId}/{index}`) using the
2515
2516
  * existing authenticated fetch, and base64-encode into a
2516
2517
  * `data:<mime>;base64,<…>` URL for the opencode `file` part's `url`.
2517
2518
  *
@@ -2524,7 +2525,7 @@ var ChannelDriver = class {
2524
2525
  async fetchAttachmentDataUrl(messageId, index, mime) {
2525
2526
  try {
2526
2527
  const res = await this.fetchImpl(
2527
- `${this.apiUrl}/agents/${this.agentId}/attachments/${messageId}/${index}`,
2528
+ `${this.apiUrl}/runners/${this.agentId}/attachments/${messageId}/${index}`,
2528
2529
  { headers: { Authorization: this.getAuthHeader() } }
2529
2530
  );
2530
2531
  if (!res.ok) {
@@ -3790,7 +3791,7 @@ var ChannelDriver = class {
3790
3791
  // Evident API calls (combinedAuth thread routes)
3791
3792
  async getPendingConversations() {
3792
3793
  const res = await this.fetchImpl(
3793
- `${this.apiUrl}/agents/${this.agentId}/conversations/pending`,
3794
+ `${this.apiUrl}/runners/${this.agentId}/conversations/pending`,
3794
3795
  {
3795
3796
  headers: { Authorization: this.getAuthHeader() }
3796
3797
  }
@@ -3808,7 +3809,7 @@ var ChannelDriver = class {
3808
3809
  }
3809
3810
  async getPendingMessages(conversationId) {
3810
3811
  const res = await this.fetchImpl(
3811
- `${this.apiUrl}/agents/${this.agentId}/threads/${conversationId}/messages?status=pending`,
3812
+ `${this.apiUrl}/runners/${this.agentId}/threads/${conversationId}/messages?status=pending`,
3812
3813
  { headers: { Authorization: this.getAuthHeader() } }
3813
3814
  );
3814
3815
  this.assertAuth(res, "fetching pending messages");
@@ -3832,7 +3833,7 @@ var ChannelDriver = class {
3832
3833
  */
3833
3834
  async getProcessingMessages() {
3834
3835
  const res = await this.fetchImpl(
3835
- `${this.apiUrl}/agents/${this.agentId}/conversations/processing`,
3836
+ `${this.apiUrl}/runners/${this.agentId}/conversations/processing`,
3836
3837
  { headers: { Authorization: this.getAuthHeader() } }
3837
3838
  );
3838
3839
  this.assertAuth(res, "fetching processing messages");
@@ -3869,7 +3870,7 @@ var ChannelDriver = class {
3869
3870
  */
3870
3871
  async markProcessing(conversationId, messageId, sessionId, opencodeMessageId, title) {
3871
3872
  const res = await this.fetchImpl(
3872
- `${this.apiUrl}/agents/${this.agentId}/threads/${conversationId}/messages/${messageId}`,
3873
+ `${this.apiUrl}/runners/${this.agentId}/threads/${conversationId}/messages/${messageId}`,
3873
3874
  {
3874
3875
  method: "PATCH",
3875
3876
  headers: { Authorization: this.getAuthHeader(), "Content-Type": "application/json" },
@@ -3918,7 +3919,7 @@ var ChannelDriver = class {
3918
3919
  */
3919
3920
  async markDone(conversationId, messageId, sessionId, opencodeMessageId, title, usage) {
3920
3921
  const res = await this.fetchImpl(
3921
- `${this.apiUrl}/agents/${this.agentId}/threads/${conversationId}/messages/${messageId}`,
3922
+ `${this.apiUrl}/runners/${this.agentId}/threads/${conversationId}/messages/${messageId}`,
3922
3923
  {
3923
3924
  method: "PATCH",
3924
3925
  headers: { Authorization: this.getAuthHeader(), "Content-Type": "application/json" },
@@ -3953,7 +3954,7 @@ var ChannelDriver = class {
3953
3954
  await this.callWithRetry(
3954
3955
  "marking message as failed",
3955
3956
  () => this.fetchImpl(
3956
- `${this.apiUrl}/agents/${this.agentId}/threads/${conversationId}/messages/${messageId}`,
3957
+ `${this.apiUrl}/runners/${this.agentId}/threads/${conversationId}/messages/${messageId}`,
3957
3958
  {
3958
3959
  method: "PATCH",
3959
3960
  headers: { Authorization: this.getAuthHeader(), "Content-Type": "application/json" },
@@ -3980,7 +3981,7 @@ var ChannelDriver = class {
3980
3981
  async postSignal(conversationId, messageId, signal, extra) {
3981
3982
  try {
3982
3983
  const res = await this.fetchImpl(
3983
- `${this.apiUrl}/agents/${this.agentId}/threads/${conversationId}/messages/${messageId}/signal`,
3984
+ `${this.apiUrl}/runners/${this.agentId}/threads/${conversationId}/messages/${messageId}/signal`,
3984
3985
  {
3985
3986
  method: "POST",
3986
3987
  headers: { Authorization: this.getAuthHeader(), "Content-Type": "application/json" },
@@ -4009,7 +4010,7 @@ var ChannelDriver = class {
4009
4010
  }
4010
4011
  async persistSession(conversationId, sessionId) {
4011
4012
  const res = await this.fetchImpl(
4012
- `${this.apiUrl}/agents/${this.agentId}/threads/${conversationId}`,
4013
+ `${this.apiUrl}/runners/${this.agentId}/threads/${conversationId}`,
4013
4014
  {
4014
4015
  method: "PATCH",
4015
4016
  headers: { Authorization: this.getAuthHeader(), "Content-Type": "application/json" },
@@ -4035,7 +4036,7 @@ var ChannelDriver = class {
4035
4036
  await this.callWithRetry(
4036
4037
  "reporting interactive event",
4037
4038
  () => this.fetchImpl(
4038
- `${this.apiUrl}/agents/${this.agentId}/threads/${conversationId}/interactive-event`,
4039
+ `${this.apiUrl}/runners/${this.agentId}/threads/${conversationId}/interactive-event`,
4039
4040
  {
4040
4041
  method: "POST",
4041
4042
  headers: { Authorization: this.getAuthHeader(), "Content-Type": "application/json" },
@@ -4278,7 +4279,7 @@ async function resolveAgentIdFromKey(authHeader) {
4278
4279
  async function notifyAgentDisconnected(agentId, authHeader) {
4279
4280
  const apiUrl = getApiUrlConfig();
4280
4281
  try {
4281
- const response = await fetch(`${apiUrl}/agents/${agentId}/disconnect`, {
4282
+ const response = await fetch(`${apiUrl}/runners/${agentId}/disconnect`, {
4282
4283
  method: "POST",
4283
4284
  headers: { Authorization: authHeader }
4284
4285
  });
@@ -4297,7 +4298,7 @@ async function notifyAgentDisconnected(agentId, authHeader) {
4297
4298
  async function getAgentInfo(agentId, authHeader) {
4298
4299
  const apiUrl = getApiUrlConfig();
4299
4300
  try {
4300
- const response = await fetch(`${apiUrl}/agents/${agentId}`, {
4301
+ const response = await fetch(`${apiUrl}/runners/${agentId}`, {
4301
4302
  headers: { Authorization: authHeader }
4302
4303
  });
4303
4304
  if (response.status === 401) {
@@ -4684,7 +4685,7 @@ async function run(options) {
4684
4685
  return;
4685
4686
  }
4686
4687
  const state = {
4687
- agentId: options.agent || "",
4688
+ agentId: options.runner || options.agent || "",
4688
4689
  agentName: null,
4689
4690
  port: options.port ?? 4096,
4690
4691
  conversationFilter: options.conversation ?? null,
@@ -4706,6 +4707,19 @@ async function run(options) {
4706
4707
  sessionCleanupTimers: [],
4707
4708
  authHeader: ""
4708
4709
  };
4710
+ if (!options.runner && options.agent) {
4711
+ telemetry.info(
4712
+ EventTypes.DEPRECATED_AGENT_FLAG_USED,
4713
+ "Deprecated --agent flag used instead of --runner",
4714
+ { command: "run" },
4715
+ state.agentId
4716
+ );
4717
+ const agentFlagNotice = "--agent is deprecated, use --runner instead; will be removed in a future release.";
4718
+ log2(state, agentFlagNotice, "warn");
4719
+ if (state.interactive && !state.json) {
4720
+ logActivity(state, { type: "info", level: "warn", message: agentFlagNotice });
4721
+ }
4722
+ }
4709
4723
  if (state.idleTimeout === null && (process.env.GITHUB_ACTIONS || process.env.CI)) {
4710
4724
  log2(
4711
4725
  state,
@@ -4734,7 +4748,9 @@ async function run(options) {
4734
4748
  if (!interactive) {
4735
4749
  printError("Authentication required");
4736
4750
  blank();
4737
- console.log(chalk6.dim("Set EVIDENT_AGENT_KEY environment variable for CI"));
4751
+ console.log(
4752
+ chalk6.dim("Set EVIDENT_RUNNER_KEY (or EVIDENT_AGENT_KEY) environment variable for CI")
4753
+ );
4738
4754
  console.log(chalk6.dim("Or run `evident login` for interactive authentication"));
4739
4755
  blank();
4740
4756
  process.exit(1);
@@ -4748,6 +4764,25 @@ async function run(options) {
4748
4764
  );
4749
4765
  }
4750
4766
  state.authHeader = getAuthHeader(credentials2);
4767
+ if (credentials2.notice) {
4768
+ log2(state, credentials2.notice, "warn");
4769
+ if (state.interactive && !state.json) {
4770
+ logActivity(state, { type: "info", level: "warn", message: credentials2.notice });
4771
+ }
4772
+ }
4773
+ if (credentials2.keySource === "agent_key") {
4774
+ telemetry.info(
4775
+ EventTypes.DEPRECATED_AGENT_KEY_ENV_USED,
4776
+ "Deprecated EVIDENT_AGENT_KEY env var used instead of EVIDENT_RUNNER_KEY",
4777
+ { command: "run" },
4778
+ state.agentId
4779
+ );
4780
+ const agentKeyNotice = "EVIDENT_AGENT_KEY is deprecated, use EVIDENT_RUNNER_KEY instead; will be removed in a future release.";
4781
+ log2(state, agentKeyNotice, "warn");
4782
+ if (state.interactive && !state.json) {
4783
+ logActivity(state, { type: "info", level: "warn", message: agentKeyNotice });
4784
+ }
4785
+ }
4751
4786
  if (!state.agentId) {
4752
4787
  if (credentials2.authType === "agent_key") {
4753
4788
  const resolved = await resolveAgentIdFromKey(state.authHeader);
@@ -4765,9 +4800,15 @@ async function run(options) {
4765
4800
  process.exit(1);
4766
4801
  }
4767
4802
  } else {
4768
- printError("--agent is required when not using EVIDENT_AGENT_KEY");
4803
+ printError(
4804
+ "--runner (or --agent) is required when not using EVIDENT_RUNNER_KEY or EVIDENT_AGENT_KEY"
4805
+ );
4769
4806
  blank();
4770
- console.log(chalk6.dim("Either provide --agent <id> or set EVIDENT_AGENT_KEY"));
4807
+ console.log(
4808
+ chalk6.dim(
4809
+ "Either provide --runner/--agent <id> or set EVIDENT_RUNNER_KEY/EVIDENT_AGENT_KEY"
4810
+ )
4811
+ );
4771
4812
  blank();
4772
4813
  process.exit(1);
4773
4814
  }
@@ -4982,7 +5023,7 @@ async function run(options) {
4982
5023
  }
4983
5024
  telemetry.error(EventTypes.CLI_ERROR, `Run command failed: ${message}`, {
4984
5025
  command: "run",
4985
- agentId: options.agent
5026
+ agentId: options.runner || options.agent
4986
5027
  });
4987
5028
  await shutdownTelemetry();
4988
5029
  process.exit(1);
@@ -5007,7 +5048,7 @@ program.name("evident").description("Run OpenCode locally and connect it to Evid
5007
5048
  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
5049
  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
5050
  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(
5051
+ 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
5052
  "--log-level <level>",
5012
5053
  "Log verbosity: debug | info | warn | error (default: info). Env: EVIDENT_LOG_LEVEL"
5013
5054
  ).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 +5064,7 @@ program.command("run").description("Connect to Evident and process messages").op
5023
5064
  (options) => {
5024
5065
  run({
5025
5066
  agent: options.agent,
5067
+ runner: options.runner,
5026
5068
  port: parseInt(options.port, 10),
5027
5069
  // Raw string — validation/precedence is single-sourced in run.ts's
5028
5070
  // resolveLogLevel (flag > -v > EVIDENT_LOG_LEVEL > info).