@evident-ai/cli 3.5.1 → 3.5.2-dev.4912967
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/dist/index.js +133 -44
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1063,7 +1063,7 @@ async function claudeUsage() {
|
|
|
1063
1063
|
|
|
1064
1064
|
// src/commands/run.ts
|
|
1065
1065
|
import { chmodSync as chmodSync3, existsSync as existsSync3, readFileSync as readFileSync7, writeFileSync as writeFileSync6 } from "node:fs";
|
|
1066
|
-
import { homedir as
|
|
1066
|
+
import { homedir as homedir7 } from "node:os";
|
|
1067
1067
|
import { isAbsolute as isAbsolute3, join as join11, parse, resolve as resolvePath2 } from "node:path";
|
|
1068
1068
|
import chalk7 from "chalk";
|
|
1069
1069
|
|
|
@@ -1158,7 +1158,7 @@ import ora4 from "ora";
|
|
|
1158
1158
|
import { select as select4 } from "@inquirer/prompts";
|
|
1159
1159
|
|
|
1160
1160
|
// src/lib/telemetry.ts
|
|
1161
|
-
var CLI_VERSION = (true ? "3.5.
|
|
1161
|
+
var CLI_VERSION = (true ? "3.5.2-dev.4912967" : void 0) ?? process.env.npm_package_version ?? "unknown";
|
|
1162
1162
|
function getCliVersion() {
|
|
1163
1163
|
return CLI_VERSION;
|
|
1164
1164
|
}
|
|
@@ -1299,8 +1299,14 @@ var EventTypes = {
|
|
|
1299
1299
|
};
|
|
1300
1300
|
|
|
1301
1301
|
// src/lib/runner-activity-telemetry.ts
|
|
1302
|
-
|
|
1302
|
+
import { homedir as homedir2 } from "node:os";
|
|
1303
|
+
var FORWARDED_LEVELS_BY_SOURCE = {
|
|
1304
|
+
"cli.run": /* @__PURE__ */ new Set(["warn", "error"]),
|
|
1305
|
+
opencode: /* @__PURE__ */ new Set(["warn", "error"]),
|
|
1306
|
+
"cli.session-cleanup": /* @__PURE__ */ new Set(["info", "warn", "error"])
|
|
1307
|
+
};
|
|
1303
1308
|
var SEVERITY_BY_LEVEL = {
|
|
1309
|
+
info: "info",
|
|
1304
1310
|
warn: "warning",
|
|
1305
1311
|
error: "error"
|
|
1306
1312
|
};
|
|
@@ -1346,8 +1352,29 @@ var MAX_MESSAGE_LENGTH = 500;
|
|
|
1346
1352
|
var MAX_METADATA_VALUE_LENGTH = 200;
|
|
1347
1353
|
var MAX_METADATA_ENTRIES = 20;
|
|
1348
1354
|
var TRUNCATION_MARKER = "\u2026";
|
|
1355
|
+
function redactHomeDirectory(message) {
|
|
1356
|
+
const home = homedir2();
|
|
1357
|
+
if (!home || home === "/") {
|
|
1358
|
+
return message;
|
|
1359
|
+
}
|
|
1360
|
+
const pathSegmentCharacters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._-";
|
|
1361
|
+
let result = "";
|
|
1362
|
+
let searchFrom = 0;
|
|
1363
|
+
let homeIndex;
|
|
1364
|
+
while ((homeIndex = message.indexOf(home, searchFrom)) !== -1) {
|
|
1365
|
+
const homeEnd = homeIndex + home.length;
|
|
1366
|
+
const previousCharacter = message[homeIndex - 1];
|
|
1367
|
+
const nextCharacter = message[homeEnd];
|
|
1368
|
+
const atPathBoundary = home === "/" || (!previousCharacter || !pathSegmentCharacters.includes(previousCharacter)) && (!nextCharacter || !pathSegmentCharacters.includes(nextCharacter));
|
|
1369
|
+
result += message.slice(searchFrom, homeIndex);
|
|
1370
|
+
result += atPathBoundary ? "~" : home;
|
|
1371
|
+
searchFrom = homeEnd;
|
|
1372
|
+
}
|
|
1373
|
+
return result + message.slice(searchFrom);
|
|
1374
|
+
}
|
|
1349
1375
|
function redact(message) {
|
|
1350
|
-
|
|
1376
|
+
const redacted = message.replace(/esk_[A-Za-z0-9_-]+/g, "esk_***").replace(/ct_[A-Za-z0-9_-]+/g, "ct_***").replace(/(?<![A-Za-z0-9_-])sk-ant-[A-Za-z0-9_-]{20,}(?![A-Za-z0-9_-])/g, "sk-ant-***").replace(/(?<![A-Za-z0-9_-])sk-proj-[A-Za-z0-9_-]{20,}(?![A-Za-z0-9_-])/g, "sk-proj-***").replace(/(?<![A-Za-z0-9_-])sk-[A-Za-z0-9]{20,}(?![A-Za-z0-9_-])/g, "sk-***").replace(/(?<![A-Za-z0-9_-])(gh[oprsu])_[A-Za-z0-9]{20,}(?![A-Za-z0-9_-])/g, "$1_***").replace(/(?<![A-Za-z0-9_-])github_pat_[A-Za-z0-9_]{20,}(?![A-Za-z0-9_-])/g, "github_pat_***").replace(/https?:\/\/\S+/g, "<url>");
|
|
1377
|
+
return redactHomeDirectory(redacted);
|
|
1351
1378
|
}
|
|
1352
1379
|
function truncate(message) {
|
|
1353
1380
|
if (message.length <= MAX_MESSAGE_LENGTH) return message;
|
|
@@ -1404,9 +1431,9 @@ function admitUnderRateLimit(source, now) {
|
|
|
1404
1431
|
}
|
|
1405
1432
|
function forwardRunnerActivity(entry, context) {
|
|
1406
1433
|
try {
|
|
1407
|
-
if (!FORWARDED_LEVELS.has(entry.level)) return;
|
|
1408
|
-
if (!context.agentId || !context.authHeader) return;
|
|
1409
1434
|
const source = entry.source ?? "cli.run";
|
|
1435
|
+
if (!FORWARDED_LEVELS_BY_SOURCE[source].has(entry.level)) return;
|
|
1436
|
+
if (!context.agentId || !context.authHeader) return;
|
|
1410
1437
|
if (!admitUnderRateLimit(source, Date.now())) return;
|
|
1411
1438
|
const rawMessage = entry.error ?? entry.message ?? "";
|
|
1412
1439
|
const message = truncate(redact(rawMessage));
|
|
@@ -3214,7 +3241,7 @@ import { join as join4 } from "node:path";
|
|
|
3214
3241
|
|
|
3215
3242
|
// src/lib/openai-usage.ts
|
|
3216
3243
|
import { readFileSync as readFileSync3 } from "node:fs";
|
|
3217
|
-
import { homedir as
|
|
3244
|
+
import { homedir as homedir3 } from "node:os";
|
|
3218
3245
|
import { join as join3 } from "node:path";
|
|
3219
3246
|
var CODEX_RESPONSES_URL = "https://chatgpt.com/backend-api/codex/responses";
|
|
3220
3247
|
var OPENCODE_AUTH_SEGMENTS = [".local", "share", "opencode", "auth.json"];
|
|
@@ -3229,7 +3256,7 @@ function isLocalCredentialProblem2(err) {
|
|
|
3229
3256
|
}
|
|
3230
3257
|
function readOpenCodeChatGptCredentials() {
|
|
3231
3258
|
try {
|
|
3232
|
-
const raw = readFileSync3(join3(
|
|
3259
|
+
const raw = readFileSync3(join3(homedir3(), ...OPENCODE_AUTH_SEGMENTS), "utf-8");
|
|
3233
3260
|
let parsed;
|
|
3234
3261
|
try {
|
|
3235
3262
|
parsed = JSON.parse(raw);
|
|
@@ -3661,7 +3688,7 @@ async function importOpenCodeV2Credentials({
|
|
|
3661
3688
|
// src/lib/opencode/session-db-boot.ts
|
|
3662
3689
|
import { spawn as spawn2 } from "node:child_process";
|
|
3663
3690
|
import { mkdirSync, statSync as statSync2, unlinkSync as unlinkSync2, writeFileSync } from "node:fs";
|
|
3664
|
-
import { homedir as
|
|
3691
|
+
import { homedir as homedir4 } from "node:os";
|
|
3665
3692
|
import { dirname as dirname2, resolve as resolvePath } from "node:path";
|
|
3666
3693
|
|
|
3667
3694
|
// src/lib/runner-synchroniser.ts
|
|
@@ -4017,14 +4044,14 @@ async function restoreSessionDb(options, configPath, env) {
|
|
|
4017
4044
|
case 0:
|
|
4018
4045
|
return;
|
|
4019
4046
|
case 31:
|
|
4020
|
-
acknowledgeSessionDbRecoveryReport(sessionDbRecoveryReportPath(
|
|
4047
|
+
acknowledgeSessionDbRecoveryReport(sessionDbRecoveryReportPath(homedir4(), env));
|
|
4021
4048
|
options.log(
|
|
4022
4049
|
"SESSION-DB-REPLICA-UNUSABLE: booting with a fresh opencode.db and replicating into the existing prefix this boot",
|
|
4023
4050
|
"warn"
|
|
4024
4051
|
);
|
|
4025
4052
|
return;
|
|
4026
4053
|
case 32:
|
|
4027
|
-
acknowledgeSessionDbRecoveryReport(sessionDbRecoveryReportPath(
|
|
4054
|
+
acknowledgeSessionDbRecoveryReport(sessionDbRecoveryReportPath(homedir4(), env));
|
|
4028
4055
|
discardSessionDbDebris(options);
|
|
4029
4056
|
markNoReplicate(
|
|
4030
4057
|
options,
|
|
@@ -4113,7 +4140,7 @@ function fileExists(path) {
|
|
|
4113
4140
|
async function restoreAndVerifySessionDb(options) {
|
|
4114
4141
|
const env = options.env ?? process.env;
|
|
4115
4142
|
clearMarker(options);
|
|
4116
|
-
acknowledgeSessionDbRecoveryReport(sessionDbRecoveryReportPath(
|
|
4143
|
+
acknowledgeSessionDbRecoveryReport(sessionDbRecoveryReportPath(homedir4(), env));
|
|
4117
4144
|
const synchroniserEnv = await runSynchroniser(["env"], {
|
|
4118
4145
|
timeoutMs: SESSION_DB_SYNCHRONISER_TIMEOUT_MS,
|
|
4119
4146
|
env
|
|
@@ -4493,12 +4520,15 @@ function findProcessesByPattern(pgrepPattern, psPattern) {
|
|
|
4493
4520
|
}
|
|
4494
4521
|
} catch {
|
|
4495
4522
|
try {
|
|
4496
|
-
const psOutput = execSync(
|
|
4523
|
+
const psOutput = execSync("ps aux", {
|
|
4497
4524
|
encoding: "utf-8",
|
|
4498
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
4525
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
4526
|
+
// The whole table reaches Node; the 1 MiB default would surface a spurious failure.
|
|
4527
|
+
maxBuffer: 16 * 1024 * 1024
|
|
4499
4528
|
}).trim();
|
|
4500
4529
|
if (psOutput) {
|
|
4501
4530
|
for (const line of psOutput.split("\n")) {
|
|
4531
|
+
if (!psPattern.test(line)) continue;
|
|
4502
4532
|
const parts = line.trim().split(/\s+/);
|
|
4503
4533
|
if (parts.length >= 2) {
|
|
4504
4534
|
const pid = parseInt(parts[1], 10);
|
|
@@ -4507,8 +4537,9 @@ function findProcessesByPattern(pgrepPattern, psPattern) {
|
|
|
4507
4537
|
}
|
|
4508
4538
|
}
|
|
4509
4539
|
} catch (err) {
|
|
4540
|
+
const reason = (typeof err === "object" && err !== null && "stderr" in err && typeof err.stderr === "string" ? err.stderr : "").split("\n").map((line) => line.trim()).find(Boolean) ?? (err instanceof Error ? err.message : String(err)).split("\n").map((line) => line.trim()).find(Boolean) ?? "no error detail available";
|
|
4510
4541
|
console.warn(
|
|
4511
|
-
`
|
|
4542
|
+
`Could not list running processes, so an already-running OpenCode may not be detected: ${reason}`
|
|
4512
4543
|
);
|
|
4513
4544
|
}
|
|
4514
4545
|
}
|
|
@@ -4540,7 +4571,7 @@ function findProcessesByPattern(pgrepPattern, psPattern) {
|
|
|
4540
4571
|
return instances;
|
|
4541
4572
|
}
|
|
4542
4573
|
function findOpenCodeProcesses() {
|
|
4543
|
-
return findProcessesByPattern("opencode serve|opencode-serve",
|
|
4574
|
+
return findProcessesByPattern("opencode serve|opencode-serve", /opencode (serve|--port)/);
|
|
4544
4575
|
}
|
|
4545
4576
|
async function scanPortsForOpenCode() {
|
|
4546
4577
|
const instances = [];
|
|
@@ -4928,11 +4959,11 @@ function buildSessionStoreSizeWarning(input) {
|
|
|
4928
4959
|
|
|
4929
4960
|
// src/lib/opencode/log-tail.ts
|
|
4930
4961
|
import { statSync as statSync4 } from "node:fs";
|
|
4931
|
-
import { homedir as
|
|
4962
|
+
import { homedir as homedir5 } from "node:os";
|
|
4932
4963
|
import { join as join7 } from "node:path";
|
|
4933
4964
|
import { open as open2, stat } from "node:fs/promises";
|
|
4934
4965
|
var DEFAULT_POLL_INTERVAL_MS = 1e3;
|
|
4935
|
-
function resolveOpenCodeLogPath(homeDir =
|
|
4966
|
+
function resolveOpenCodeLogPath(homeDir = homedir5(), env = process.env) {
|
|
4936
4967
|
const dataDir = env.XDG_DATA_HOME || join7(homeDir, ".local", "share");
|
|
4937
4968
|
return join7(dataDir, "opencode", "log", "opencode.log");
|
|
4938
4969
|
}
|
|
@@ -5087,7 +5118,11 @@ async function reclaimSessionDbSpace(input) {
|
|
|
5087
5118
|
console.warn(
|
|
5088
5119
|
`[reclaimSessionDbSpace] skipping VACUUM conversion of ${dbPath}: a session turn is live`
|
|
5089
5120
|
);
|
|
5090
|
-
return {
|
|
5121
|
+
return {
|
|
5122
|
+
ok: false,
|
|
5123
|
+
skipped: "full-vacuum-blocked",
|
|
5124
|
+
detail: "a session turn is live"
|
|
5125
|
+
};
|
|
5091
5126
|
}
|
|
5092
5127
|
const fileBytesForGuard = statSync5(dbPath).size;
|
|
5093
5128
|
const skipReason = insufficientSpaceReason(dbPath, fileBytesForGuard);
|
|
@@ -5095,7 +5130,7 @@ async function reclaimSessionDbSpace(input) {
|
|
|
5095
5130
|
console.warn(
|
|
5096
5131
|
`[reclaimSessionDbSpace] skipping VACUUM conversion of ${dbPath}: ${skipReason}`
|
|
5097
5132
|
);
|
|
5098
|
-
return { ok: false, skipped: "insufficient-disk-space" };
|
|
5133
|
+
return { ok: false, skipped: "insufficient-disk-space", detail: skipReason };
|
|
5099
5134
|
}
|
|
5100
5135
|
const beforeBytes = readLogicalBytes(db);
|
|
5101
5136
|
db.exec("PRAGMA auto_vacuum=INCREMENTAL");
|
|
@@ -5976,7 +6011,7 @@ function createResourceUsageCollector(homeDir) {
|
|
|
5976
6011
|
}
|
|
5977
6012
|
|
|
5978
6013
|
// src/lib/channels/driver.ts
|
|
5979
|
-
import { homedir as
|
|
6014
|
+
import { homedir as homedir6 } from "node:os";
|
|
5980
6015
|
|
|
5981
6016
|
// src/lib/runner-file-sync.ts
|
|
5982
6017
|
import { join as join9 } from "node:path";
|
|
@@ -6859,7 +6894,7 @@ var ChannelDriver = class _ChannelDriver {
|
|
|
6859
6894
|
this.stuckQueuedMs = config.stuckQueuedMs ?? DEFAULT_STUCK_QUEUED_MS;
|
|
6860
6895
|
this.now = config.now ?? (() => Date.now());
|
|
6861
6896
|
this.fileSyncDirectories = config.fileSyncDirectories ?? [];
|
|
6862
|
-
this.homeDir = config.homeDir ??
|
|
6897
|
+
this.homeDir = config.homeDir ?? homedir6();
|
|
6863
6898
|
this.maxActiveSessions = config.maxActiveSessions;
|
|
6864
6899
|
this.watcherStallMs = config.watcherStallMs ?? WATCHER_STALL_MS;
|
|
6865
6900
|
this.wedgeWarningIntervalMs = config.wedgeWarningIntervalMs ?? WEDGE_WARNING_INTERVAL_MS;
|
|
@@ -12267,7 +12302,13 @@ function logActivity(state, entry) {
|
|
|
12267
12302
|
const level = entry.level ?? (entry.type === "error" ? "error" : "info");
|
|
12268
12303
|
if (!meetsThreshold(state, level)) return;
|
|
12269
12304
|
forwardRunnerActivity(
|
|
12270
|
-
{
|
|
12305
|
+
{
|
|
12306
|
+
level,
|
|
12307
|
+
message: entry.message,
|
|
12308
|
+
error: entry.error,
|
|
12309
|
+
metadata: entry.metadata,
|
|
12310
|
+
...entry.source ? { source: entry.source } : {}
|
|
12311
|
+
},
|
|
12271
12312
|
{ agentId: state.agentId, authHeader: state.authHeader }
|
|
12272
12313
|
);
|
|
12273
12314
|
const fullEntry = {
|
|
@@ -12289,7 +12330,7 @@ function logActivity(state, entry) {
|
|
|
12289
12330
|
}
|
|
12290
12331
|
function reportSessionDbRecovery(state) {
|
|
12291
12332
|
try {
|
|
12292
|
-
const report = drainSessionDbRecoveryReport({ homeDir:
|
|
12333
|
+
const report = drainSessionDbRecoveryReport({ homeDir: homedir7(), env: process.env });
|
|
12293
12334
|
for (const record of report.records) {
|
|
12294
12335
|
const activity = buildSessionDbRecoveryActivity(record);
|
|
12295
12336
|
if (!activity) throw new Error("could not map session-DB recovery record");
|
|
@@ -12368,7 +12409,7 @@ async function importOpenCodeV2CredentialsForState(state) {
|
|
|
12368
12409
|
}
|
|
12369
12410
|
const result = await importOpenCodeV2Credentials({
|
|
12370
12411
|
request: client.request,
|
|
12371
|
-
homeDir:
|
|
12412
|
+
homeDir: homedir7(),
|
|
12372
12413
|
directory,
|
|
12373
12414
|
guard: state.opencodeV2CredentialImportGuard,
|
|
12374
12415
|
log: (message, level = "info") => logActivity(state, { type: "info", level, message })
|
|
@@ -12587,7 +12628,14 @@ function shouldWarnForReclaimSkip(reason) {
|
|
|
12587
12628
|
return major > 22 || major === 22 && (minor > 13 || minor === 13 && patch >= 0);
|
|
12588
12629
|
}
|
|
12589
12630
|
function sessionDbPath() {
|
|
12590
|
-
return join11(
|
|
12631
|
+
return join11(homedir7(), ".local", "share", "opencode", "opencode.db");
|
|
12632
|
+
}
|
|
12633
|
+
function logSessionCleanupActivity(state, phase, entry) {
|
|
12634
|
+
logActivity(state, {
|
|
12635
|
+
...entry,
|
|
12636
|
+
source: "cli.session-cleanup",
|
|
12637
|
+
metadata: { ...entry.metadata, phase }
|
|
12638
|
+
});
|
|
12591
12639
|
}
|
|
12592
12640
|
function logSessionDbProvenanceMismatch(state, provenance, currentVersion, preBootMigrationCount) {
|
|
12593
12641
|
const record = {
|
|
@@ -12630,9 +12678,13 @@ async function runSweep(state, driver, config) {
|
|
|
12630
12678
|
try {
|
|
12631
12679
|
const sessions = await listSessions(state.port, state.opencodeClient ?? void 0);
|
|
12632
12680
|
if (sessions === null) {
|
|
12633
|
-
|
|
12681
|
+
logSessionCleanupActivity(state, "sweep", {
|
|
12634
12682
|
type: "info",
|
|
12635
|
-
message: `Session cleanup: could not list sessions (opencode unreachable); skipping this sweep (${mode})
|
|
12683
|
+
message: `Session cleanup: could not list sessions (opencode unreachable); skipping this sweep (${mode})`,
|
|
12684
|
+
metadata: {
|
|
12685
|
+
outcome: "sweep-skipped",
|
|
12686
|
+
reason: "opencode-unreachable"
|
|
12687
|
+
}
|
|
12636
12688
|
});
|
|
12637
12689
|
return;
|
|
12638
12690
|
}
|
|
@@ -12676,21 +12728,47 @@ async function runSweep(state, driver, config) {
|
|
|
12676
12728
|
const beforeMib = (reclaimResult.beforeBytes / 1024 / 1024).toFixed(1);
|
|
12677
12729
|
const afterMib = (reclaimResult.afterBytes / 1024 / 1024).toFixed(1);
|
|
12678
12730
|
const checkpointNote = reclaimResult.checkpoint.busy ? ` (on-disk file truncation deferred: checkpoint busy, ${reclaimResult.checkpoint.log} WAL frames pending)` : "";
|
|
12679
|
-
|
|
12731
|
+
logSessionCleanupActivity(state, "sweep", {
|
|
12680
12732
|
type: "info",
|
|
12681
|
-
message: `Session cleanup: reclaimed session-db space (${reclaimResult.mode}): ${beforeMib} MiB -> ${afterMib} MiB${checkpointNote}
|
|
12733
|
+
message: `Session cleanup: reclaimed session-db space (${reclaimResult.mode}): ${beforeMib} MiB -> ${afterMib} MiB${checkpointNote}`,
|
|
12734
|
+
metadata: {
|
|
12735
|
+
outcome: "reclaimed",
|
|
12736
|
+
mode: reclaimResult.mode,
|
|
12737
|
+
before_bytes: reclaimResult.beforeBytes,
|
|
12738
|
+
after_bytes: reclaimResult.afterBytes,
|
|
12739
|
+
checkpoint_busy: reclaimResult.checkpoint.busy,
|
|
12740
|
+
wal_frames_pending: reclaimResult.checkpoint.log,
|
|
12741
|
+
sessions_inspected: sessions.length,
|
|
12742
|
+
sessions_deleted: deleted,
|
|
12743
|
+
sessions_failed: failed,
|
|
12744
|
+
sessions_skipped_active: skippedNewlyActive
|
|
12745
|
+
}
|
|
12682
12746
|
});
|
|
12683
12747
|
} else {
|
|
12684
|
-
|
|
12748
|
+
logSessionCleanupActivity(state, "sweep", {
|
|
12685
12749
|
type: "info",
|
|
12686
|
-
|
|
12750
|
+
level: reclaimResult.skipped === "reclaim-error" || reclaimResult.skipped === "insufficient-disk-space" ? "warn" : "info",
|
|
12751
|
+
message: `Session cleanup: session-db space reclaim skipped (${reclaimResult.skipped})` + (reclaimResult.detail ? `: ${reclaimResult.detail}` : ""),
|
|
12752
|
+
metadata: {
|
|
12753
|
+
outcome: "reclaim-skipped",
|
|
12754
|
+
reason: reclaimResult.skipped,
|
|
12755
|
+
...reclaimResult.detail !== void 0 ? { detail: reclaimResult.detail } : {},
|
|
12756
|
+
sessions_inspected: sessions.length,
|
|
12757
|
+
sessions_deleted: deleted,
|
|
12758
|
+
sessions_failed: failed,
|
|
12759
|
+
sessions_skipped_active: skippedNewlyActive
|
|
12760
|
+
}
|
|
12687
12761
|
});
|
|
12688
12762
|
}
|
|
12689
12763
|
} catch (error2) {
|
|
12690
12764
|
const message = error2 instanceof Error ? error2.message : String(error2);
|
|
12691
|
-
|
|
12765
|
+
logSessionCleanupActivity(state, "sweep", {
|
|
12692
12766
|
type: "error",
|
|
12693
|
-
error: `Session cleanup sweep failed (non-fatal, ${mode}): ${message}
|
|
12767
|
+
error: `Session cleanup sweep failed (non-fatal, ${mode}): ${message}`,
|
|
12768
|
+
metadata: {
|
|
12769
|
+
outcome: "sweep-failed",
|
|
12770
|
+
reason: "sweep-error"
|
|
12771
|
+
}
|
|
12694
12772
|
});
|
|
12695
12773
|
}
|
|
12696
12774
|
}
|
|
@@ -12706,14 +12784,19 @@ function scheduleSessionCleanup(state, driver, options) {
|
|
|
12706
12784
|
for (const warning2 of config.warnings) {
|
|
12707
12785
|
logActivity(state, { type: "info", level: "warn", message: `Session cleanup: ${warning2}` });
|
|
12708
12786
|
}
|
|
12709
|
-
const dbBytes = statSessionDbBytes(
|
|
12787
|
+
const dbBytes = statSessionDbBytes(homedir7());
|
|
12710
12788
|
void (async () => {
|
|
12711
12789
|
const reclaimAvailability = dbBytes !== null && config.enabled ? await probeReclaimAvailability({ dbPath: sessionDbPath(), requiredBytes: dbBytes }) : null;
|
|
12712
12790
|
if (reclaimAvailability !== null) {
|
|
12713
|
-
|
|
12791
|
+
logSessionCleanupActivity(state, "startup", {
|
|
12714
12792
|
type: "info",
|
|
12715
12793
|
level: shouldWarnForReclaimSkip(reclaimAvailability.reason) ? "warn" : "info",
|
|
12716
|
-
message: `Session cleanup: reclaim preflight skipped (${reclaimAvailability.reason})` + (reclaimAvailability.detail ? `: ${reclaimAvailability.detail}` : "")
|
|
12794
|
+
message: `Session cleanup: reclaim preflight skipped (${reclaimAvailability.reason})` + (reclaimAvailability.detail ? `: ${reclaimAvailability.detail}` : ""),
|
|
12795
|
+
metadata: {
|
|
12796
|
+
outcome: "preflight-skipped",
|
|
12797
|
+
reason: reclaimAvailability.reason,
|
|
12798
|
+
...reclaimAvailability.detail !== void 0 ? { detail: reclaimAvailability.detail } : {}
|
|
12799
|
+
}
|
|
12717
12800
|
});
|
|
12718
12801
|
}
|
|
12719
12802
|
const sizeWarning = buildSessionStoreSizeWarning({
|
|
@@ -12730,9 +12813,15 @@ function scheduleSessionCleanup(state, driver, options) {
|
|
|
12730
12813
|
);
|
|
12731
12814
|
});
|
|
12732
12815
|
if (!config.enabled) return;
|
|
12733
|
-
|
|
12816
|
+
logSessionCleanupActivity(state, "startup", {
|
|
12734
12817
|
type: "info",
|
|
12735
|
-
message: `Session cleanup enabled (age=${config.maxAgeMs ?? "\u2014"}, count=${config.maxCount ?? "\u2014"}, interval=${config.intervalMs}ms)
|
|
12818
|
+
message: `Session cleanup enabled (age=${config.maxAgeMs ?? "\u2014"}, count=${config.maxCount ?? "\u2014"}, interval=${config.intervalMs}ms)`,
|
|
12819
|
+
metadata: {
|
|
12820
|
+
outcome: "armed",
|
|
12821
|
+
interval_ms: config.intervalMs,
|
|
12822
|
+
max_age_ms: config.maxAgeMs ?? null,
|
|
12823
|
+
max_count: config.maxCount ?? null
|
|
12824
|
+
}
|
|
12736
12825
|
});
|
|
12737
12826
|
const interval = setInterval(() => void runSweep(state, driver, config), config.intervalMs);
|
|
12738
12827
|
const firstSweep = setTimeout(
|
|
@@ -12911,7 +13000,7 @@ function scheduleResourceUsageReporting(state, options) {
|
|
|
12911
13000
|
});
|
|
12912
13001
|
return;
|
|
12913
13002
|
}
|
|
12914
|
-
const { collect, stop } = createResourceUsageCollector(
|
|
13003
|
+
const { collect, stop } = createResourceUsageCollector(homedir7());
|
|
12915
13004
|
state.stopResourceUsageSampling = stop;
|
|
12916
13005
|
let consecutiveFailures = 0;
|
|
12917
13006
|
const tick = async () => {
|
|
@@ -13136,7 +13225,7 @@ async function run(options) {
|
|
|
13136
13225
|
let fileSyncDirectories;
|
|
13137
13226
|
try {
|
|
13138
13227
|
logLevel = resolveLogLevel(options);
|
|
13139
|
-
fileSyncDirectories = resolveFileSyncDirectories(options.enableFileSyncTo,
|
|
13228
|
+
fileSyncDirectories = resolveFileSyncDirectories(options.enableFileSyncTo, homedir7());
|
|
13140
13229
|
if (options.restoreSessionDb && !options.sessionDbNoReplicateMarker) {
|
|
13141
13230
|
throw new Error(
|
|
13142
13231
|
"--restore-session-db requires --session-db-no-replicate-marker <path>; restore failures must block Litestream replication"
|
|
@@ -13377,7 +13466,7 @@ async function run(options) {
|
|
|
13377
13466
|
}
|
|
13378
13467
|
state.credentialSync?.arm();
|
|
13379
13468
|
state.stopOpenCodeLogTail = tailOpenCodeLogFile(
|
|
13380
|
-
resolveOpenCodeLogPath(
|
|
13469
|
+
resolveOpenCodeLogPath(homedir7(), process.env),
|
|
13381
13470
|
createOpenCodeActivityForwarder(() => ({
|
|
13382
13471
|
agentId: state.agentId,
|
|
13383
13472
|
authHeader: state.authHeader
|
|
@@ -13499,7 +13588,7 @@ async function run(options) {
|
|
|
13499
13588
|
const provenance = checkSessionDbProvenance({
|
|
13500
13589
|
dbPath: sessionDbPath(),
|
|
13501
13590
|
currentVersion: state.opencodeVersion,
|
|
13502
|
-
homeDir:
|
|
13591
|
+
homeDir: homedir7(),
|
|
13503
13592
|
env: process.env
|
|
13504
13593
|
});
|
|
13505
13594
|
if (provenance.anomaly) {
|
|
@@ -13669,7 +13758,7 @@ async function run(options) {
|
|
|
13669
13758
|
// #559: the `--enable-file-sync-to` allow-list. Empty ⇒ pending files are
|
|
13670
13759
|
// REJECTED with `file_sync_disabled` on the ack, not silently ignored.
|
|
13671
13760
|
fileSyncDirectories,
|
|
13672
|
-
homeDir:
|
|
13761
|
+
homeDir: homedir7(),
|
|
13673
13762
|
maxActiveSessions,
|
|
13674
13763
|
log: (entry) => (
|
|
13675
13764
|
// Thread the driver's real level straight through so `debug`/`warn`
|