@evident-ai/cli 3.1.1-dev.702ee74 → 3.1.1-dev.8d786ea
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 +10 -4
- package/dist/index.js +155 -28
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
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
|
-
- `
|
|
109
|
-
that runner and resolves the runner ID automatically, so `--agent`
|
|
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`
|
|
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) {
|
|
@@ -1370,6 +1383,72 @@ function findLastAssistantReplyFor(messages, userMessageId) {
|
|
|
1370
1383
|
}
|
|
1371
1384
|
return lastOk ?? last;
|
|
1372
1385
|
}
|
|
1386
|
+
function messageUsage(messages, userMessageId) {
|
|
1387
|
+
if (!messages || messages.length === 0) return null;
|
|
1388
|
+
const byParentAll = messages.filter(
|
|
1389
|
+
(m) => roleOf(m) === "assistant" && parentIdOf(m) === userMessageId
|
|
1390
|
+
);
|
|
1391
|
+
const byParentNonErrored = byParentAll.filter((m) => errorOf(m) == null);
|
|
1392
|
+
const byParent = byParentNonErrored.length > 0 ? byParentNonErrored : byParentAll;
|
|
1393
|
+
let correlated;
|
|
1394
|
+
if (byParent.length > 0) {
|
|
1395
|
+
correlated = byParent;
|
|
1396
|
+
} else {
|
|
1397
|
+
const reply = findAssistantReplyAfter(messages, userMessageId);
|
|
1398
|
+
correlated = reply ? [reply] : [];
|
|
1399
|
+
}
|
|
1400
|
+
if (correlated.length === 0) return null;
|
|
1401
|
+
let sawAnyUsage = false;
|
|
1402
|
+
let inputSum = 0;
|
|
1403
|
+
let outputSum = 0;
|
|
1404
|
+
let reasoningSum = 0;
|
|
1405
|
+
let cacheReadSum = 0;
|
|
1406
|
+
let cacheWriteSum = 0;
|
|
1407
|
+
let costSum = 0;
|
|
1408
|
+
let sawCost = false;
|
|
1409
|
+
let modelId = null;
|
|
1410
|
+
let providerId = null;
|
|
1411
|
+
for (const m of correlated) {
|
|
1412
|
+
const info = m.info;
|
|
1413
|
+
if (!info) continue;
|
|
1414
|
+
const tokens = info.tokens;
|
|
1415
|
+
if (tokens) {
|
|
1416
|
+
sawAnyUsage = true;
|
|
1417
|
+
inputSum += tokens.input ?? 0;
|
|
1418
|
+
outputSum += tokens.output ?? 0;
|
|
1419
|
+
reasoningSum += tokens.reasoning ?? 0;
|
|
1420
|
+
cacheReadSum += tokens.cache?.read ?? 0;
|
|
1421
|
+
cacheWriteSum += tokens.cache?.write ?? 0;
|
|
1422
|
+
}
|
|
1423
|
+
if (typeof info.cost === "number") {
|
|
1424
|
+
sawAnyUsage = true;
|
|
1425
|
+
sawCost = true;
|
|
1426
|
+
costSum += info.cost;
|
|
1427
|
+
}
|
|
1428
|
+
if (typeof info.modelID === "string") {
|
|
1429
|
+
sawAnyUsage = true;
|
|
1430
|
+
modelId = info.modelID;
|
|
1431
|
+
}
|
|
1432
|
+
if (typeof info.providerID === "string") {
|
|
1433
|
+
sawAnyUsage = true;
|
|
1434
|
+
providerId = info.providerID;
|
|
1435
|
+
}
|
|
1436
|
+
}
|
|
1437
|
+
if (!sawAnyUsage) return null;
|
|
1438
|
+
return {
|
|
1439
|
+
usage_provider_id: providerId,
|
|
1440
|
+
usage_model_id: modelId,
|
|
1441
|
+
usage_tokens_input: inputSum,
|
|
1442
|
+
usage_tokens_output: outputSum,
|
|
1443
|
+
usage_tokens_reasoning: reasoningSum,
|
|
1444
|
+
usage_tokens_cache_read: cacheReadSum,
|
|
1445
|
+
usage_tokens_cache_write: cacheWriteSum,
|
|
1446
|
+
// NULL means "OpenCode never reported a cost" (never inferred from
|
|
1447
|
+
// tokens) — distinct from a genuine 0-cost turn, which would set
|
|
1448
|
+
// `sawCost` true with `costSum === 0`.
|
|
1449
|
+
usage_cost_usd: sawCost ? costSum : null
|
|
1450
|
+
};
|
|
1451
|
+
}
|
|
1373
1452
|
function messageRunState(messages, userMessageId) {
|
|
1374
1453
|
if (!messages || messages.length === 0) return "unknown";
|
|
1375
1454
|
const hasUser = messages.some((m) => idOf(m) === userMessageId);
|
|
@@ -2445,7 +2524,7 @@ var ChannelDriver = class {
|
|
|
2445
2524
|
}
|
|
2446
2525
|
/**
|
|
2447
2526
|
* Fetch ONE inbound image's bytes through Evident's WI-6 endpoint
|
|
2448
|
-
* (`GET {apiUrl}/
|
|
2527
|
+
* (`GET {apiUrl}/runners/{agentId}/attachments/{messageId}/{index}`) using the
|
|
2449
2528
|
* existing authenticated fetch, and base64-encode into a
|
|
2450
2529
|
* `data:<mime>;base64,<…>` URL for the opencode `file` part's `url`.
|
|
2451
2530
|
*
|
|
@@ -2458,7 +2537,7 @@ var ChannelDriver = class {
|
|
|
2458
2537
|
async fetchAttachmentDataUrl(messageId, index, mime) {
|
|
2459
2538
|
try {
|
|
2460
2539
|
const res = await this.fetchImpl(
|
|
2461
|
-
`${this.apiUrl}/
|
|
2540
|
+
`${this.apiUrl}/runners/${this.agentId}/attachments/${messageId}/${index}`,
|
|
2462
2541
|
{ headers: { Authorization: this.getAuthHeader() } }
|
|
2463
2542
|
);
|
|
2464
2543
|
if (!res.ok) {
|
|
@@ -2790,13 +2869,15 @@ var ChannelDriver = class {
|
|
|
2790
2869
|
message_id: inFlight.evidentMessageId
|
|
2791
2870
|
});
|
|
2792
2871
|
const title = await this.resolveSessionTitle(sessionId, watcher.conv.id);
|
|
2872
|
+
const usage = messageUsage(messages, inFlight.opencodeMessageId);
|
|
2793
2873
|
try {
|
|
2794
2874
|
await this.markDone(
|
|
2795
2875
|
conv.id,
|
|
2796
2876
|
inFlight.evidentMessageId,
|
|
2797
2877
|
sessionId,
|
|
2798
2878
|
inFlight.opencodeMessageId,
|
|
2799
|
-
title
|
|
2879
|
+
title,
|
|
2880
|
+
usage
|
|
2800
2881
|
);
|
|
2801
2882
|
} catch (err) {
|
|
2802
2883
|
if (err instanceof ChannelAuthError) throw err;
|
|
@@ -2843,8 +2924,9 @@ var ChannelDriver = class {
|
|
|
2843
2924
|
conversation_id: conv.id,
|
|
2844
2925
|
message_id: inFlight.evidentMessageId
|
|
2845
2926
|
});
|
|
2927
|
+
const usage = messageUsage(messages, inFlight.opencodeMessageId);
|
|
2846
2928
|
try {
|
|
2847
|
-
await this.markFailed(conv.id, inFlight.evidentMessageId, sessionId, error2);
|
|
2929
|
+
await this.markFailed(conv.id, inFlight.evidentMessageId, sessionId, error2, usage);
|
|
2848
2930
|
} catch (err) {
|
|
2849
2931
|
if (err instanceof ChannelAuthError) throw err;
|
|
2850
2932
|
if (err instanceof ChannelTerminalError) {
|
|
@@ -3081,7 +3163,8 @@ var ChannelDriver = class {
|
|
|
3081
3163
|
});
|
|
3082
3164
|
try {
|
|
3083
3165
|
const title = await this.resolveSessionTitle(sessionId, row.conversation_id);
|
|
3084
|
-
|
|
3166
|
+
const usage = messageUsage(messages, ocId ?? "");
|
|
3167
|
+
await this.markDone(row.conversation_id, row.id, sessionId, ocId, title, usage);
|
|
3085
3168
|
} catch (err) {
|
|
3086
3169
|
if (err instanceof ChannelAuthError) throw err;
|
|
3087
3170
|
if (err instanceof ChannelTerminalError) {
|
|
@@ -3109,6 +3192,7 @@ var ChannelDriver = class {
|
|
|
3109
3192
|
}
|
|
3110
3193
|
if (state === "failed") {
|
|
3111
3194
|
const error2 = messageError(messages, ocId ?? "") ?? void 0;
|
|
3195
|
+
const usage = messageUsage(messages, ocId ?? "");
|
|
3112
3196
|
this.log({
|
|
3113
3197
|
level: "error",
|
|
3114
3198
|
message: `Re-adopt: message ${row.id.slice(0, 8)} errored while unwatched \u2014 marking failed: ${error2 ?? "(no error text)"}`,
|
|
@@ -3116,7 +3200,7 @@ var ChannelDriver = class {
|
|
|
3116
3200
|
message_id: row.id
|
|
3117
3201
|
});
|
|
3118
3202
|
try {
|
|
3119
|
-
await this.markFailed(row.conversation_id, row.id, sessionId, error2);
|
|
3203
|
+
await this.markFailed(row.conversation_id, row.id, sessionId, error2, usage);
|
|
3120
3204
|
} catch (err) {
|
|
3121
3205
|
if (err instanceof ChannelAuthError) throw err;
|
|
3122
3206
|
if (err instanceof ChannelTerminalError) {
|
|
@@ -3719,7 +3803,7 @@ var ChannelDriver = class {
|
|
|
3719
3803
|
// Evident API calls (combinedAuth thread routes)
|
|
3720
3804
|
async getPendingConversations() {
|
|
3721
3805
|
const res = await this.fetchImpl(
|
|
3722
|
-
`${this.apiUrl}/
|
|
3806
|
+
`${this.apiUrl}/runners/${this.agentId}/conversations/pending`,
|
|
3723
3807
|
{
|
|
3724
3808
|
headers: { Authorization: this.getAuthHeader() }
|
|
3725
3809
|
}
|
|
@@ -3737,7 +3821,7 @@ var ChannelDriver = class {
|
|
|
3737
3821
|
}
|
|
3738
3822
|
async getPendingMessages(conversationId) {
|
|
3739
3823
|
const res = await this.fetchImpl(
|
|
3740
|
-
`${this.apiUrl}/
|
|
3824
|
+
`${this.apiUrl}/runners/${this.agentId}/threads/${conversationId}/messages?status=pending`,
|
|
3741
3825
|
{ headers: { Authorization: this.getAuthHeader() } }
|
|
3742
3826
|
);
|
|
3743
3827
|
this.assertAuth(res, "fetching pending messages");
|
|
@@ -3761,7 +3845,7 @@ var ChannelDriver = class {
|
|
|
3761
3845
|
*/
|
|
3762
3846
|
async getProcessingMessages() {
|
|
3763
3847
|
const res = await this.fetchImpl(
|
|
3764
|
-
`${this.apiUrl}/
|
|
3848
|
+
`${this.apiUrl}/runners/${this.agentId}/conversations/processing`,
|
|
3765
3849
|
{ headers: { Authorization: this.getAuthHeader() } }
|
|
3766
3850
|
);
|
|
3767
3851
|
this.assertAuth(res, "fetching processing messages");
|
|
@@ -3798,7 +3882,7 @@ var ChannelDriver = class {
|
|
|
3798
3882
|
*/
|
|
3799
3883
|
async markProcessing(conversationId, messageId, sessionId, opencodeMessageId, title) {
|
|
3800
3884
|
const res = await this.fetchImpl(
|
|
3801
|
-
`${this.apiUrl}/
|
|
3885
|
+
`${this.apiUrl}/runners/${this.agentId}/threads/${conversationId}/messages/${messageId}`,
|
|
3802
3886
|
{
|
|
3803
3887
|
method: "PATCH",
|
|
3804
3888
|
headers: { Authorization: this.getAuthHeader(), "Content-Type": "application/json" },
|
|
@@ -3845,9 +3929,9 @@ var ChannelDriver = class {
|
|
|
3845
3929
|
* watcher retries next tick within the
|
|
3846
3930
|
* deadline, Finding 4).
|
|
3847
3931
|
*/
|
|
3848
|
-
async markDone(conversationId, messageId, sessionId, opencodeMessageId, title) {
|
|
3932
|
+
async markDone(conversationId, messageId, sessionId, opencodeMessageId, title, usage) {
|
|
3849
3933
|
const res = await this.fetchImpl(
|
|
3850
|
-
`${this.apiUrl}/
|
|
3934
|
+
`${this.apiUrl}/runners/${this.agentId}/threads/${conversationId}/messages/${messageId}`,
|
|
3851
3935
|
{
|
|
3852
3936
|
method: "PATCH",
|
|
3853
3937
|
headers: { Authorization: this.getAuthHeader(), "Content-Type": "application/json" },
|
|
@@ -3855,7 +3939,8 @@ var ChannelDriver = class {
|
|
|
3855
3939
|
status: "done",
|
|
3856
3940
|
opencode_session_id: sessionId,
|
|
3857
3941
|
...opencodeMessageId ? { opencode_message_id: opencodeMessageId } : {},
|
|
3858
|
-
...title ? { title } : {}
|
|
3942
|
+
...title ? { title } : {},
|
|
3943
|
+
...usage ? usage : {}
|
|
3859
3944
|
})
|
|
3860
3945
|
}
|
|
3861
3946
|
);
|
|
@@ -3873,14 +3958,15 @@ var ChannelDriver = class {
|
|
|
3873
3958
|
* OpenCode turn sends `{status:'failed', opencode_session_id, error}` so the
|
|
3874
3959
|
* failure reason reaches the channel.
|
|
3875
3960
|
*/
|
|
3876
|
-
async markFailed(conversationId, messageId, sessionId, error2) {
|
|
3961
|
+
async markFailed(conversationId, messageId, sessionId, error2, usage) {
|
|
3877
3962
|
const body = { status: "failed" };
|
|
3878
3963
|
if (sessionId !== void 0) body.opencode_session_id = sessionId;
|
|
3879
3964
|
if (error2 !== void 0) body.error = error2;
|
|
3965
|
+
if (usage) Object.assign(body, usage);
|
|
3880
3966
|
await this.callWithRetry(
|
|
3881
3967
|
"marking message as failed",
|
|
3882
3968
|
() => this.fetchImpl(
|
|
3883
|
-
`${this.apiUrl}/
|
|
3969
|
+
`${this.apiUrl}/runners/${this.agentId}/threads/${conversationId}/messages/${messageId}`,
|
|
3884
3970
|
{
|
|
3885
3971
|
method: "PATCH",
|
|
3886
3972
|
headers: { Authorization: this.getAuthHeader(), "Content-Type": "application/json" },
|
|
@@ -3907,7 +3993,7 @@ var ChannelDriver = class {
|
|
|
3907
3993
|
async postSignal(conversationId, messageId, signal, extra) {
|
|
3908
3994
|
try {
|
|
3909
3995
|
const res = await this.fetchImpl(
|
|
3910
|
-
`${this.apiUrl}/
|
|
3996
|
+
`${this.apiUrl}/runners/${this.agentId}/threads/${conversationId}/messages/${messageId}/signal`,
|
|
3911
3997
|
{
|
|
3912
3998
|
method: "POST",
|
|
3913
3999
|
headers: { Authorization: this.getAuthHeader(), "Content-Type": "application/json" },
|
|
@@ -3936,7 +4022,7 @@ var ChannelDriver = class {
|
|
|
3936
4022
|
}
|
|
3937
4023
|
async persistSession(conversationId, sessionId) {
|
|
3938
4024
|
const res = await this.fetchImpl(
|
|
3939
|
-
`${this.apiUrl}/
|
|
4025
|
+
`${this.apiUrl}/runners/${this.agentId}/threads/${conversationId}`,
|
|
3940
4026
|
{
|
|
3941
4027
|
method: "PATCH",
|
|
3942
4028
|
headers: { Authorization: this.getAuthHeader(), "Content-Type": "application/json" },
|
|
@@ -3962,7 +4048,7 @@ var ChannelDriver = class {
|
|
|
3962
4048
|
await this.callWithRetry(
|
|
3963
4049
|
"reporting interactive event",
|
|
3964
4050
|
() => this.fetchImpl(
|
|
3965
|
-
`${this.apiUrl}/
|
|
4051
|
+
`${this.apiUrl}/runners/${this.agentId}/threads/${conversationId}/interactive-event`,
|
|
3966
4052
|
{
|
|
3967
4053
|
method: "POST",
|
|
3968
4054
|
headers: { Authorization: this.getAuthHeader(), "Content-Type": "application/json" },
|
|
@@ -4205,7 +4291,7 @@ async function resolveAgentIdFromKey(authHeader) {
|
|
|
4205
4291
|
async function notifyAgentDisconnected(agentId, authHeader) {
|
|
4206
4292
|
const apiUrl = getApiUrlConfig();
|
|
4207
4293
|
try {
|
|
4208
|
-
const response = await fetch(`${apiUrl}/
|
|
4294
|
+
const response = await fetch(`${apiUrl}/runners/${agentId}/disconnect`, {
|
|
4209
4295
|
method: "POST",
|
|
4210
4296
|
headers: { Authorization: authHeader }
|
|
4211
4297
|
});
|
|
@@ -4224,7 +4310,7 @@ async function notifyAgentDisconnected(agentId, authHeader) {
|
|
|
4224
4310
|
async function getAgentInfo(agentId, authHeader) {
|
|
4225
4311
|
const apiUrl = getApiUrlConfig();
|
|
4226
4312
|
try {
|
|
4227
|
-
const response = await fetch(`${apiUrl}/
|
|
4313
|
+
const response = await fetch(`${apiUrl}/runners/${agentId}`, {
|
|
4228
4314
|
headers: { Authorization: authHeader }
|
|
4229
4315
|
});
|
|
4230
4316
|
if (response.status === 401) {
|
|
@@ -4611,7 +4697,7 @@ async function run(options) {
|
|
|
4611
4697
|
return;
|
|
4612
4698
|
}
|
|
4613
4699
|
const state = {
|
|
4614
|
-
agentId: options.agent || "",
|
|
4700
|
+
agentId: options.runner || options.agent || "",
|
|
4615
4701
|
agentName: null,
|
|
4616
4702
|
port: options.port ?? 4096,
|
|
4617
4703
|
conversationFilter: options.conversation ?? null,
|
|
@@ -4633,6 +4719,19 @@ async function run(options) {
|
|
|
4633
4719
|
sessionCleanupTimers: [],
|
|
4634
4720
|
authHeader: ""
|
|
4635
4721
|
};
|
|
4722
|
+
if (!options.runner && options.agent) {
|
|
4723
|
+
telemetry.info(
|
|
4724
|
+
EventTypes.DEPRECATED_AGENT_FLAG_USED,
|
|
4725
|
+
"Deprecated --agent flag used instead of --runner",
|
|
4726
|
+
{ command: "run" },
|
|
4727
|
+
state.agentId
|
|
4728
|
+
);
|
|
4729
|
+
const agentFlagNotice = "--agent is deprecated, use --runner instead; will be removed in a future release.";
|
|
4730
|
+
log2(state, agentFlagNotice, "warn");
|
|
4731
|
+
if (state.interactive && !state.json) {
|
|
4732
|
+
logActivity(state, { type: "info", level: "warn", message: agentFlagNotice });
|
|
4733
|
+
}
|
|
4734
|
+
}
|
|
4636
4735
|
if (state.idleTimeout === null && (process.env.GITHUB_ACTIONS || process.env.CI)) {
|
|
4637
4736
|
log2(
|
|
4638
4737
|
state,
|
|
@@ -4661,7 +4760,9 @@ async function run(options) {
|
|
|
4661
4760
|
if (!interactive) {
|
|
4662
4761
|
printError("Authentication required");
|
|
4663
4762
|
blank();
|
|
4664
|
-
console.log(
|
|
4763
|
+
console.log(
|
|
4764
|
+
chalk6.dim("Set EVIDENT_RUNNER_KEY (or EVIDENT_AGENT_KEY) environment variable for CI")
|
|
4765
|
+
);
|
|
4665
4766
|
console.log(chalk6.dim("Or run `evident login` for interactive authentication"));
|
|
4666
4767
|
blank();
|
|
4667
4768
|
process.exit(1);
|
|
@@ -4675,6 +4776,25 @@ async function run(options) {
|
|
|
4675
4776
|
);
|
|
4676
4777
|
}
|
|
4677
4778
|
state.authHeader = getAuthHeader(credentials2);
|
|
4779
|
+
if (credentials2.notice) {
|
|
4780
|
+
log2(state, credentials2.notice, "warn");
|
|
4781
|
+
if (state.interactive && !state.json) {
|
|
4782
|
+
logActivity(state, { type: "info", level: "warn", message: credentials2.notice });
|
|
4783
|
+
}
|
|
4784
|
+
}
|
|
4785
|
+
if (credentials2.keySource === "agent_key") {
|
|
4786
|
+
telemetry.info(
|
|
4787
|
+
EventTypes.DEPRECATED_AGENT_KEY_ENV_USED,
|
|
4788
|
+
"Deprecated EVIDENT_AGENT_KEY env var used instead of EVIDENT_RUNNER_KEY",
|
|
4789
|
+
{ command: "run" },
|
|
4790
|
+
state.agentId
|
|
4791
|
+
);
|
|
4792
|
+
const agentKeyNotice = "EVIDENT_AGENT_KEY is deprecated, use EVIDENT_RUNNER_KEY instead; will be removed in a future release.";
|
|
4793
|
+
log2(state, agentKeyNotice, "warn");
|
|
4794
|
+
if (state.interactive && !state.json) {
|
|
4795
|
+
logActivity(state, { type: "info", level: "warn", message: agentKeyNotice });
|
|
4796
|
+
}
|
|
4797
|
+
}
|
|
4678
4798
|
if (!state.agentId) {
|
|
4679
4799
|
if (credentials2.authType === "agent_key") {
|
|
4680
4800
|
const resolved = await resolveAgentIdFromKey(state.authHeader);
|
|
@@ -4692,9 +4812,15 @@ async function run(options) {
|
|
|
4692
4812
|
process.exit(1);
|
|
4693
4813
|
}
|
|
4694
4814
|
} else {
|
|
4695
|
-
printError(
|
|
4815
|
+
printError(
|
|
4816
|
+
"--runner (or --agent) is required when not using EVIDENT_RUNNER_KEY or EVIDENT_AGENT_KEY"
|
|
4817
|
+
);
|
|
4696
4818
|
blank();
|
|
4697
|
-
console.log(
|
|
4819
|
+
console.log(
|
|
4820
|
+
chalk6.dim(
|
|
4821
|
+
"Either provide --runner/--agent <id> or set EVIDENT_RUNNER_KEY/EVIDENT_AGENT_KEY"
|
|
4822
|
+
)
|
|
4823
|
+
);
|
|
4698
4824
|
blank();
|
|
4699
4825
|
process.exit(1);
|
|
4700
4826
|
}
|
|
@@ -4909,7 +5035,7 @@ async function run(options) {
|
|
|
4909
5035
|
}
|
|
4910
5036
|
telemetry.error(EventTypes.CLI_ERROR, `Run command failed: ${message}`, {
|
|
4911
5037
|
command: "run",
|
|
4912
|
-
agentId: options.agent
|
|
5038
|
+
agentId: options.runner || options.agent
|
|
4913
5039
|
});
|
|
4914
5040
|
await shutdownTelemetry();
|
|
4915
5041
|
process.exit(1);
|
|
@@ -4934,7 +5060,7 @@ program.name("evident").description("Run OpenCode locally and connect it to Evid
|
|
|
4934
5060
|
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);
|
|
4935
5061
|
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 }));
|
|
4936
5062
|
program.command("whoami").description("Show the currently logged in user").action(whoami);
|
|
4937
|
-
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(
|
|
5063
|
+
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(
|
|
4938
5064
|
"--log-level <level>",
|
|
4939
5065
|
"Log verbosity: debug | info | warn | error (default: info). Env: EVIDENT_LOG_LEVEL"
|
|
4940
5066
|
).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(
|
|
@@ -4950,6 +5076,7 @@ program.command("run").description("Connect to Evident and process messages").op
|
|
|
4950
5076
|
(options) => {
|
|
4951
5077
|
run({
|
|
4952
5078
|
agent: options.agent,
|
|
5079
|
+
runner: options.runner,
|
|
4953
5080
|
port: parseInt(options.port, 10),
|
|
4954
5081
|
// Raw string — validation/precedence is single-sourced in run.ts's
|
|
4955
5082
|
// resolveLogLevel (flag > -v > EVIDENT_LOG_LEVEL > info).
|