@evident-ai/cli 3.3.1-dev.8abe4d1 → 3.3.1-dev.8e3d9ea
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 +8 -0
- package/dist/index.js +300 -9
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -105,6 +105,11 @@ Options:
|
|
|
105
105
|
keeps retrying) if no usable login is found; `off` disables it entirely — no
|
|
106
106
|
Claude credential is ever read. An unrecognized value falls back to `auto` with
|
|
107
107
|
a warning. Env: `EVIDENT_CLAUDE_USAGE_REPORTING`.
|
|
108
|
+
- `--no-resource-usage-reporting` — Don't report this machine's CPU
|
|
109
|
+
utilization, total and available memory, core count, disk space, and the
|
|
110
|
+
OpenCode session-store size to Evident, so it shows on the runner page. On
|
|
111
|
+
by default; nothing else about the machine leaves it. Env:
|
|
112
|
+
`EVIDENT_RESOURCE_USAGE_REPORTING=off` (the flag wins if both are set).
|
|
108
113
|
- `--json` — Output in JSON format (forces non-interactive mode).
|
|
109
114
|
- `--session-cleanup-max-age <duration>` — Delete OpenCode sessions idle longer
|
|
110
115
|
than this window (format `<number><unit>`, unit one of `s, m, h, d` — e.g.
|
|
@@ -171,6 +176,9 @@ targets the **production** Evident platform by default.
|
|
|
171
176
|
- `EVIDENT_TUNNEL_URL` — Override the tunnel relay URL (equivalent to `--tunnel`).
|
|
172
177
|
- `EVIDENT_CLAUDE_USAGE_REPORTING` — Equivalent to `--claude-usage-reporting`; the
|
|
173
178
|
flag wins if both are set.
|
|
179
|
+
- `EVIDENT_RESOURCE_USAGE_REPORTING` — Equivalent to
|
|
180
|
+
`--no-resource-usage-reporting`; set it to `off` to disable. The flag wins
|
|
181
|
+
if both are set.
|
|
174
182
|
- `EVIDENT_LOG_LEVEL` — Equivalent to `--log-level`; the flag wins if both are
|
|
175
183
|
set, and `-v`/`--verbose` also outranks this env var.
|
|
176
184
|
- `EVIDENT_OPENCODE_START_TIMEOUT` — Equivalent to `--opencode-start-timeout`
|
package/dist/index.js
CHANGED
|
@@ -746,6 +746,35 @@ async function reportClaudeUsage(agentId, authHeader, snapshot) {
|
|
|
746
746
|
return { ok: false, error: describeBestEffortError(error2) };
|
|
747
747
|
}
|
|
748
748
|
}
|
|
749
|
+
async function reportResourceUsage(agentId, authHeader, usage) {
|
|
750
|
+
try {
|
|
751
|
+
const apiUrl = getApiUrlConfig();
|
|
752
|
+
const response = await fetch(`${apiUrl}/runners/${agentId}/resource-usage`, {
|
|
753
|
+
method: "POST",
|
|
754
|
+
headers: { Authorization: authHeader, "Content-Type": "application/json" },
|
|
755
|
+
body: JSON.stringify({
|
|
756
|
+
cpu_percent: usage.cpuPercent,
|
|
757
|
+
cpu_count: usage.cpuCount,
|
|
758
|
+
memory_total_bytes: usage.memoryTotalBytes,
|
|
759
|
+
memory_available_bytes: usage.memoryAvailableBytes,
|
|
760
|
+
disk_total_bytes: usage.diskTotalBytes,
|
|
761
|
+
disk_free_bytes: usage.diskFreeBytes,
|
|
762
|
+
opencode_db_bytes: usage.opencodeDbBytes
|
|
763
|
+
}),
|
|
764
|
+
signal: AbortSignal.timeout(BEST_EFFORT_NOTIFY_TIMEOUT_MS)
|
|
765
|
+
});
|
|
766
|
+
if (!response.ok) {
|
|
767
|
+
const serverMessage = await readErrorMessage(response);
|
|
768
|
+
return {
|
|
769
|
+
ok: false,
|
|
770
|
+
error: `HTTP ${response.status}${serverMessage ? `: ${serverMessage}` : ""}`
|
|
771
|
+
};
|
|
772
|
+
}
|
|
773
|
+
return { ok: true };
|
|
774
|
+
} catch (error2) {
|
|
775
|
+
return { ok: false, error: describeBestEffortError(error2) };
|
|
776
|
+
}
|
|
777
|
+
}
|
|
749
778
|
async function getAgentInfo(agentId, authHeader) {
|
|
750
779
|
const apiUrl = getApiUrlConfig();
|
|
751
780
|
try {
|
|
@@ -2962,6 +2991,21 @@ function writeTunnelReadyMarker(path, agentId) {
|
|
|
2962
2991
|
}
|
|
2963
2992
|
}
|
|
2964
2993
|
|
|
2994
|
+
// src/lib/reporting-schedule.ts
|
|
2995
|
+
function jitteredDelayMs(baseMs, jitterFraction, random = Math.random) {
|
|
2996
|
+
const jitterRangeMs = baseMs * jitterFraction;
|
|
2997
|
+
return baseMs - jitterRangeMs + random() * (2 * jitterRangeMs);
|
|
2998
|
+
}
|
|
2999
|
+
function firstReportDelayMs(random = Math.random) {
|
|
3000
|
+
return 5e3 + random() * 1e4;
|
|
3001
|
+
}
|
|
3002
|
+
function reportFailureLogLevel(consecutiveFailures, reescalationTicks) {
|
|
3003
|
+
return consecutiveFailures === 1 || consecutiveFailures % reescalationTicks === 0 ? "warn" : "debug";
|
|
3004
|
+
}
|
|
3005
|
+
function failureStreakSuffix(consecutiveFailures) {
|
|
3006
|
+
return consecutiveFailures > 1 ? ` (${consecutiveFailures} consecutive failures)` : "";
|
|
3007
|
+
}
|
|
3008
|
+
|
|
2965
3009
|
// src/lib/claude-usage-reporting.ts
|
|
2966
3010
|
var VALID_MODES = ["auto", "on", "off"];
|
|
2967
3011
|
function resolveClaudeUsageReportingMode(flagValue, env) {
|
|
@@ -2984,13 +3028,167 @@ function resolveClaudeUsageReportingMode(flagValue, env) {
|
|
|
2984
3028
|
var BASE_REPORT_DELAY_MS = 10 * 6e4;
|
|
2985
3029
|
var REPORT_DELAY_JITTER_FRACTION = 0.2;
|
|
2986
3030
|
function nextReportDelayMs(random = Math.random) {
|
|
2987
|
-
|
|
2988
|
-
return BASE_REPORT_DELAY_MS - jitterRangeMs + random() * (2 * jitterRangeMs);
|
|
3031
|
+
return jitteredDelayMs(BASE_REPORT_DELAY_MS, REPORT_DELAY_JITTER_FRACTION, random);
|
|
2989
3032
|
}
|
|
2990
|
-
var FIRST_REPORT_DELAY_MS =
|
|
3033
|
+
var FIRST_REPORT_DELAY_MS = firstReportDelayMs();
|
|
2991
3034
|
var CLAUDE_USAGE_FAILURE_REESCALATION_TICKS = 6;
|
|
2992
3035
|
function claudeUsageFailureLogLevel(consecutiveFailures) {
|
|
2993
|
-
return consecutiveFailures
|
|
3036
|
+
return reportFailureLogLevel(consecutiveFailures, CLAUDE_USAGE_FAILURE_REESCALATION_TICKS);
|
|
3037
|
+
}
|
|
3038
|
+
|
|
3039
|
+
// src/lib/resource-usage-reporting.ts
|
|
3040
|
+
var ENABLED_VALUES = /* @__PURE__ */ new Set(["on", "true", "1"]);
|
|
3041
|
+
var DISABLED_VALUES = /* @__PURE__ */ new Set(["off", "false", "0"]);
|
|
3042
|
+
function resolveResourceUsageReportingEnabled(flagValue, env) {
|
|
3043
|
+
if (flagValue === false) {
|
|
3044
|
+
return { enabled: false, warnings: [] };
|
|
3045
|
+
}
|
|
3046
|
+
const raw = env.EVIDENT_RESOURCE_USAGE_REPORTING;
|
|
3047
|
+
if (raw === void 0 || raw === "") {
|
|
3048
|
+
return { enabled: true, warnings: [] };
|
|
3049
|
+
}
|
|
3050
|
+
const normalized = raw.trim().toLowerCase();
|
|
3051
|
+
if (DISABLED_VALUES.has(normalized)) {
|
|
3052
|
+
return { enabled: false, warnings: [] };
|
|
3053
|
+
}
|
|
3054
|
+
if (ENABLED_VALUES.has(normalized)) {
|
|
3055
|
+
return { enabled: true, warnings: [] };
|
|
3056
|
+
}
|
|
3057
|
+
return {
|
|
3058
|
+
enabled: true,
|
|
3059
|
+
warnings: [
|
|
3060
|
+
`Ignoring invalid EVIDENT_RESOURCE_USAGE_REPORTING "${raw}": expected on or off; leaving reporting on`
|
|
3061
|
+
]
|
|
3062
|
+
};
|
|
3063
|
+
}
|
|
3064
|
+
|
|
3065
|
+
// src/lib/resource-usage.ts
|
|
3066
|
+
import { cpus, totalmem, freemem } from "os";
|
|
3067
|
+
import { statfsSync as statfsSync2 } from "fs";
|
|
3068
|
+
|
|
3069
|
+
// src/lib/ecs-task-metadata.ts
|
|
3070
|
+
var ECS_METADATA_TIMEOUT_MS = 2e3;
|
|
3071
|
+
function parseEcsTaskLimits(payload) {
|
|
3072
|
+
if (typeof payload !== "object" || payload === null) return null;
|
|
3073
|
+
const limits = payload.Limits;
|
|
3074
|
+
if (typeof limits !== "object" || limits === null) return null;
|
|
3075
|
+
const cpu = limits.CPU;
|
|
3076
|
+
const memory = limits.Memory;
|
|
3077
|
+
if (typeof cpu !== "number" || !Number.isFinite(cpu) || cpu <= 0) return null;
|
|
3078
|
+
if (typeof memory !== "number" || !Number.isFinite(memory) || memory <= 0) return null;
|
|
3079
|
+
return {
|
|
3080
|
+
cpuCount: Math.max(1, Math.round(cpu)),
|
|
3081
|
+
memoryTotalBytes: memory * 1024 * 1024
|
|
3082
|
+
};
|
|
3083
|
+
}
|
|
3084
|
+
async function readEcsTaskLimits(env) {
|
|
3085
|
+
const uri = env.ECS_CONTAINER_METADATA_URI_V4;
|
|
3086
|
+
if (!uri) {
|
|
3087
|
+
return { limits: null };
|
|
3088
|
+
}
|
|
3089
|
+
const url = `${uri}/task`;
|
|
3090
|
+
try {
|
|
3091
|
+
const response = await fetch(url, { signal: AbortSignal.timeout(ECS_METADATA_TIMEOUT_MS) });
|
|
3092
|
+
if (!response.ok) {
|
|
3093
|
+
return {
|
|
3094
|
+
limits: null,
|
|
3095
|
+
warning: `ECS task metadata fetch (${url}) returned HTTP ${response.status}`
|
|
3096
|
+
};
|
|
3097
|
+
}
|
|
3098
|
+
const payload = await response.json();
|
|
3099
|
+
const limits = parseEcsTaskLimits(payload);
|
|
3100
|
+
if (limits === null) {
|
|
3101
|
+
return {
|
|
3102
|
+
limits: null,
|
|
3103
|
+
warning: `ECS task metadata fetch (${url}) returned an unexpected payload`
|
|
3104
|
+
};
|
|
3105
|
+
}
|
|
3106
|
+
return { limits };
|
|
3107
|
+
} catch (error2) {
|
|
3108
|
+
const message = error2 instanceof Error ? error2.message : String(error2);
|
|
3109
|
+
return { limits: null, warning: `ECS task metadata fetch (${url}) failed: ${message}` };
|
|
3110
|
+
}
|
|
3111
|
+
}
|
|
3112
|
+
|
|
3113
|
+
// src/lib/resource-usage.ts
|
|
3114
|
+
function readCpuSample() {
|
|
3115
|
+
let busyMs = 0;
|
|
3116
|
+
let idleMs = 0;
|
|
3117
|
+
for (const cpu of cpus()) {
|
|
3118
|
+
busyMs += cpu.times.user + cpu.times.nice + cpu.times.sys + cpu.times.irq;
|
|
3119
|
+
idleMs += cpu.times.idle;
|
|
3120
|
+
}
|
|
3121
|
+
return { busyMs, idleMs };
|
|
3122
|
+
}
|
|
3123
|
+
function cpuPercentBetween(previous, current) {
|
|
3124
|
+
const deltaBusy = current.busyMs - previous.busyMs;
|
|
3125
|
+
const deltaIdle = current.idleMs - previous.idleMs;
|
|
3126
|
+
const total = deltaBusy + deltaIdle;
|
|
3127
|
+
if (total === 0) return null;
|
|
3128
|
+
return Math.round((deltaBusy / total * 100 + Number.EPSILON) * 100) / 100;
|
|
3129
|
+
}
|
|
3130
|
+
function clamp(value, min, max) {
|
|
3131
|
+
return Math.min(Math.max(value, min), max);
|
|
3132
|
+
}
|
|
3133
|
+
function round2(value) {
|
|
3134
|
+
return Math.round((value + Number.EPSILON) * 100) / 100;
|
|
3135
|
+
}
|
|
3136
|
+
function readDisk(homeDir) {
|
|
3137
|
+
try {
|
|
3138
|
+
const stats = statfsSync2(homeDir);
|
|
3139
|
+
return {
|
|
3140
|
+
totalBytes: stats.bsize * stats.blocks,
|
|
3141
|
+
freeBytes: stats.bsize * stats.bavail
|
|
3142
|
+
};
|
|
3143
|
+
} catch (error2) {
|
|
3144
|
+
const message = error2 instanceof Error ? error2.message : String(error2);
|
|
3145
|
+
return {
|
|
3146
|
+
totalBytes: null,
|
|
3147
|
+
freeBytes: null,
|
|
3148
|
+
warning: `Could not read disk usage for ${homeDir}: ${message}`
|
|
3149
|
+
};
|
|
3150
|
+
}
|
|
3151
|
+
}
|
|
3152
|
+
function createResourceUsageCollector(homeDir) {
|
|
3153
|
+
let previous = readCpuSample();
|
|
3154
|
+
return async () => {
|
|
3155
|
+
const current = readCpuSample();
|
|
3156
|
+
const hostCpuPercent = cpuPercentBetween(previous, current);
|
|
3157
|
+
const hostCpuCount = cpus().length;
|
|
3158
|
+
previous = current;
|
|
3159
|
+
const disk = readDisk(homeDir);
|
|
3160
|
+
const opencodeDbBytes = statSessionDbBytes(homeDir);
|
|
3161
|
+
const { limits, warning: ecsWarning } = await readEcsTaskLimits(process.env);
|
|
3162
|
+
const warnings = [];
|
|
3163
|
+
if (disk.warning) warnings.push(disk.warning);
|
|
3164
|
+
if (ecsWarning) warnings.push(ecsWarning);
|
|
3165
|
+
let cpuPercent = hostCpuPercent;
|
|
3166
|
+
let cpuCount = hostCpuCount;
|
|
3167
|
+
let memoryTotalBytes = totalmem();
|
|
3168
|
+
let memoryAvailableBytes = freemem();
|
|
3169
|
+
if (limits !== null) {
|
|
3170
|
+
cpuCount = limits.cpuCount;
|
|
3171
|
+
memoryTotalBytes = limits.memoryTotalBytes;
|
|
3172
|
+
memoryAvailableBytes = clamp(
|
|
3173
|
+
limits.memoryTotalBytes - (totalmem() - freemem()),
|
|
3174
|
+
0,
|
|
3175
|
+
limits.memoryTotalBytes
|
|
3176
|
+
);
|
|
3177
|
+
cpuPercent = hostCpuPercent === null ? null : clamp(round2(hostCpuPercent * hostCpuCount / limits.cpuCount), 0, 100);
|
|
3178
|
+
}
|
|
3179
|
+
return {
|
|
3180
|
+
usage: {
|
|
3181
|
+
cpuPercent,
|
|
3182
|
+
cpuCount,
|
|
3183
|
+
memoryTotalBytes,
|
|
3184
|
+
memoryAvailableBytes,
|
|
3185
|
+
diskTotalBytes: disk.totalBytes,
|
|
3186
|
+
diskFreeBytes: disk.freeBytes,
|
|
3187
|
+
opencodeDbBytes
|
|
3188
|
+
},
|
|
3189
|
+
warnings
|
|
3190
|
+
};
|
|
3191
|
+
};
|
|
2994
3192
|
}
|
|
2995
3193
|
|
|
2996
3194
|
// src/lib/channels/driver.ts
|
|
@@ -7746,9 +7944,6 @@ function scheduleSessionCleanup(state, driver, options) {
|
|
|
7746
7944
|
);
|
|
7747
7945
|
state.sessionCleanupTimers.push(interval, firstSweep);
|
|
7748
7946
|
}
|
|
7749
|
-
function claudeUsageFailureStreakSuffix(consecutiveFailures) {
|
|
7750
|
-
return consecutiveFailures > 1 ? ` (${consecutiveFailures} consecutive failures)` : "";
|
|
7751
|
-
}
|
|
7752
7947
|
function scheduleClaudeUsageReporting(state, options) {
|
|
7753
7948
|
const { mode, warnings } = resolveClaudeUsageReportingMode(
|
|
7754
7949
|
options.claudeUsageReporting,
|
|
@@ -7830,7 +8025,7 @@ function scheduleClaudeUsageReporting(state, options) {
|
|
|
7830
8025
|
logActivity(state, {
|
|
7831
8026
|
type: "info",
|
|
7832
8027
|
level: claudeUsageFailureLogLevel(consecutiveFailures),
|
|
7833
|
-
message: `Failed to report Claude usage: ${result.error}${
|
|
8028
|
+
message: `Failed to report Claude usage: ${result.error}${failureStreakSuffix(consecutiveFailures)}`
|
|
7834
8029
|
});
|
|
7835
8030
|
}
|
|
7836
8031
|
scheduleNextTick();
|
|
@@ -7865,7 +8060,7 @@ function scheduleClaudeUsageReporting(state, options) {
|
|
|
7865
8060
|
logActivity(state, {
|
|
7866
8061
|
type: "info",
|
|
7867
8062
|
level: claudeUsageFailureLogLevel(consecutiveFailures),
|
|
7868
|
-
message: `Claude usage reporting failed: ${message}${
|
|
8063
|
+
message: `Claude usage reporting failed: ${message}${failureStreakSuffix(consecutiveFailures)}`
|
|
7869
8064
|
});
|
|
7870
8065
|
scheduleNextTick();
|
|
7871
8066
|
}
|
|
@@ -7874,6 +8069,90 @@ function scheduleClaudeUsageReporting(state, options) {
|
|
|
7874
8069
|
armProbe();
|
|
7875
8070
|
return rearm;
|
|
7876
8071
|
}
|
|
8072
|
+
var RESOURCE_USAGE_BASE_REPORT_DELAY_MS = 10 * 6e4;
|
|
8073
|
+
var RESOURCE_USAGE_REPORT_DELAY_JITTER_FRACTION = 0.2;
|
|
8074
|
+
var RESOURCE_USAGE_FAILURE_REESCALATION_TICKS = 6;
|
|
8075
|
+
function scheduleResourceUsageReporting(state, options) {
|
|
8076
|
+
const { enabled, warnings } = resolveResourceUsageReportingEnabled(
|
|
8077
|
+
options.resourceUsageReporting,
|
|
8078
|
+
process.env
|
|
8079
|
+
);
|
|
8080
|
+
for (const warning2 of warnings) {
|
|
8081
|
+
logActivity(state, {
|
|
8082
|
+
type: "info",
|
|
8083
|
+
level: "warn",
|
|
8084
|
+
message: `Resource usage reporting: ${warning2}`
|
|
8085
|
+
});
|
|
8086
|
+
}
|
|
8087
|
+
if (!enabled) {
|
|
8088
|
+
logActivity(state, {
|
|
8089
|
+
type: "info",
|
|
8090
|
+
level: "debug",
|
|
8091
|
+
message: "Resource usage reporting is off (--no-resource-usage-reporting)"
|
|
8092
|
+
});
|
|
8093
|
+
return;
|
|
8094
|
+
}
|
|
8095
|
+
const collect = createResourceUsageCollector(homedir3());
|
|
8096
|
+
let consecutiveFailures = 0;
|
|
8097
|
+
const tick = async () => {
|
|
8098
|
+
try {
|
|
8099
|
+
const { usage, warnings: collectWarnings } = await collect();
|
|
8100
|
+
for (const warning2 of collectWarnings) {
|
|
8101
|
+
logActivity(state, {
|
|
8102
|
+
type: "info",
|
|
8103
|
+
level: "debug",
|
|
8104
|
+
message: `Resource usage collection: ${warning2}`
|
|
8105
|
+
});
|
|
8106
|
+
}
|
|
8107
|
+
const result = await reportResourceUsage(state.agentId, state.authHeader, usage);
|
|
8108
|
+
if (result.ok) {
|
|
8109
|
+
if (consecutiveFailures > 0) {
|
|
8110
|
+
logActivity(state, {
|
|
8111
|
+
type: "info",
|
|
8112
|
+
level: "info",
|
|
8113
|
+
message: "Resource usage reporting recovered"
|
|
8114
|
+
});
|
|
8115
|
+
}
|
|
8116
|
+
consecutiveFailures = 0;
|
|
8117
|
+
logActivity(state, {
|
|
8118
|
+
type: "info",
|
|
8119
|
+
level: "debug",
|
|
8120
|
+
message: "Reported resource usage to Evident"
|
|
8121
|
+
});
|
|
8122
|
+
} else {
|
|
8123
|
+
consecutiveFailures++;
|
|
8124
|
+
logActivity(state, {
|
|
8125
|
+
type: "info",
|
|
8126
|
+
level: reportFailureLogLevel(
|
|
8127
|
+
consecutiveFailures,
|
|
8128
|
+
RESOURCE_USAGE_FAILURE_REESCALATION_TICKS
|
|
8129
|
+
),
|
|
8130
|
+
message: `Failed to report resource usage: ${result.error}${failureStreakSuffix(consecutiveFailures)}`
|
|
8131
|
+
});
|
|
8132
|
+
}
|
|
8133
|
+
} catch (error2) {
|
|
8134
|
+
consecutiveFailures++;
|
|
8135
|
+
const message = error2 instanceof Error ? error2.message : String(error2);
|
|
8136
|
+
logActivity(state, {
|
|
8137
|
+
type: "info",
|
|
8138
|
+
level: reportFailureLogLevel(
|
|
8139
|
+
consecutiveFailures,
|
|
8140
|
+
RESOURCE_USAGE_FAILURE_REESCALATION_TICKS
|
|
8141
|
+
),
|
|
8142
|
+
message: `Resource usage reporting failed: ${message}${failureStreakSuffix(consecutiveFailures)}`
|
|
8143
|
+
});
|
|
8144
|
+
} finally {
|
|
8145
|
+
state.resourceUsageTimer = setTimeout(
|
|
8146
|
+
() => void tick(),
|
|
8147
|
+
jitteredDelayMs(
|
|
8148
|
+
RESOURCE_USAGE_BASE_REPORT_DELAY_MS,
|
|
8149
|
+
RESOURCE_USAGE_REPORT_DELAY_JITTER_FRACTION
|
|
8150
|
+
)
|
|
8151
|
+
);
|
|
8152
|
+
}
|
|
8153
|
+
};
|
|
8154
|
+
state.resourceUsageTimer = setTimeout(() => void tick(), firstReportDelayMs());
|
|
8155
|
+
}
|
|
7877
8156
|
async function notifyOffline(state) {
|
|
7878
8157
|
if (!state.agentId || !state.authHeader) return;
|
|
7879
8158
|
if (!state.connected) {
|
|
@@ -7914,6 +8193,10 @@ async function cleanup(state, opts = {}) {
|
|
|
7914
8193
|
state.claudeUsageTimer = null;
|
|
7915
8194
|
}
|
|
7916
8195
|
state.claudeUsageRearm = null;
|
|
8196
|
+
if (state.resourceUsageTimer) {
|
|
8197
|
+
clearTimeout(state.resourceUsageTimer);
|
|
8198
|
+
state.resourceUsageTimer = null;
|
|
8199
|
+
}
|
|
7917
8200
|
if (opts.graceful && state.channelDriver) {
|
|
7918
8201
|
state.channelDriver.stop();
|
|
7919
8202
|
log2(state, "Draining in-flight channel work before shutdown...");
|
|
@@ -7996,6 +8279,7 @@ async function run(options) {
|
|
|
7996
8279
|
sessionCleanupTimers: [],
|
|
7997
8280
|
claudeUsageTimer: null,
|
|
7998
8281
|
claudeUsageRearm: null,
|
|
8282
|
+
resourceUsageTimer: null,
|
|
7999
8283
|
authHeader: ""
|
|
8000
8284
|
};
|
|
8001
8285
|
setTelemetryAuthProvider(() => ({ authHeader: state.authHeader, agentId: state.agentId }));
|
|
@@ -8395,6 +8679,7 @@ async function run(options) {
|
|
|
8395
8679
|
}
|
|
8396
8680
|
scheduleSessionCleanup(state, channelDriver, options);
|
|
8397
8681
|
state.claudeUsageRearm = scheduleClaudeUsageReporting(state, options);
|
|
8682
|
+
scheduleResourceUsageReporting(state, options);
|
|
8398
8683
|
if (!interactive || state.json) {
|
|
8399
8684
|
log2(state, "Driving channel messages...");
|
|
8400
8685
|
}
|
|
@@ -8475,6 +8760,9 @@ program.command("run").description("Connect to Evident and process messages").op
|
|
|
8475
8760
|
).option(
|
|
8476
8761
|
"--claude-usage-reporting <mode>",
|
|
8477
8762
|
"Report Claude subscription usage to Evident: auto | on | off (default: auto). Env: EVIDENT_CLAUDE_USAGE_REPORTING"
|
|
8763
|
+
).option(
|
|
8764
|
+
"--no-resource-usage-reporting",
|
|
8765
|
+
"Don't report this machine's CPU and memory usage to Evident (reporting is on by default). Env: EVIDENT_RESOURCE_USAGE_REPORTING=off"
|
|
8478
8766
|
).option(
|
|
8479
8767
|
"--enable-file-sync-to <dir>",
|
|
8480
8768
|
"Allow Evident to write files into this directory (repeatable). Omit to disable file sync entirely.",
|
|
@@ -8507,6 +8795,9 @@ program.command("run").description("Connect to Evident and process messages").op
|
|
|
8507
8795
|
// Raw string — the resolver in run.ts single-sources parsing
|
|
8508
8796
|
// (resolveClaudeUsageReportingMode).
|
|
8509
8797
|
claudeUsageReporting: options.claudeUsageReporting,
|
|
8798
|
+
// Raw value — resolution is single-sourced in run.ts's
|
|
8799
|
+
// resolveResourceUsageReportingEnabled.
|
|
8800
|
+
resourceUsageReporting: options.resourceUsageReporting,
|
|
8510
8801
|
// Raw values — expansion/validation is single-sourced in run.ts's
|
|
8511
8802
|
// resolveFileSyncDirectories.
|
|
8512
8803
|
enableFileSyncTo: options.enableFileSyncTo,
|