@evident-ai/cli 3.5.2-dev.8b315dd → 3.5.2-dev.8c3e0f7
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 +5 -3
- package/dist/index.js +60 -27
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -117,9 +117,11 @@ Options:
|
|
|
117
117
|
starting OpenCode. Requires `--litestream-config` for the replica location and
|
|
118
118
|
`--session-db-no-replicate-marker` for give-up records. Omit it for a normal local
|
|
119
119
|
run.
|
|
120
|
-
- `--restore-runner-credentials` — Restore the
|
|
121
|
-
|
|
122
|
-
|
|
120
|
+
- `--restore-runner-credentials` — Restore the persisted credential stores (Claude/OpenCode
|
|
121
|
+
model auth) before starting OpenCode. Intended for runner images; omit it for a normal
|
|
122
|
+
local run. The hosted runner secret's env vars (`GH_TOKEN` and the MCP tokens) are
|
|
123
|
+
fetched on every `evident run` boot regardless of this flag — it's in-memory,
|
|
124
|
+
per-process state, never persisted, so there's no store to restore over.
|
|
123
125
|
- `--opencode-config-overlay <path>` — Apply a runner-provided OpenCode config
|
|
124
126
|
before starting OpenCode. Relative paths are resolved from the working directory;
|
|
125
127
|
an existing `opencode.jsonc` is replaced before `opencode.json`.
|
package/dist/index.js
CHANGED
|
@@ -1322,7 +1322,7 @@ import ora4 from "ora";
|
|
|
1322
1322
|
import { select as select4 } from "@inquirer/prompts";
|
|
1323
1323
|
|
|
1324
1324
|
// src/lib/telemetry.ts
|
|
1325
|
-
var CLI_VERSION = (true ? "3.5.2-dev.
|
|
1325
|
+
var CLI_VERSION = (true ? "3.5.2-dev.8c3e0f7" : void 0) ?? process.env.npm_package_version ?? "unknown";
|
|
1326
1326
|
function getCliVersion() {
|
|
1327
1327
|
return CLI_VERSION;
|
|
1328
1328
|
}
|
|
@@ -1515,9 +1515,10 @@ function redactDiagnosticText(message) {
|
|
|
1515
1515
|
}
|
|
1516
1516
|
|
|
1517
1517
|
// src/lib/opencode/session-db-reclaim.ts
|
|
1518
|
-
var SESSION_DB_RECLAIM_CHUNK_PAGES =
|
|
1518
|
+
var SESSION_DB_RECLAIM_CHUNK_PAGES = 100;
|
|
1519
1519
|
var SESSION_DB_RECLAIM_TIME_BUDGET_MS = 500;
|
|
1520
1520
|
var SESSION_DB_RECLAIM_PAGE_CEILING = 4e4;
|
|
1521
|
+
var SESSION_DB_RECLAIM_BUSY_TIMEOUT_MS = 5e3;
|
|
1521
1522
|
function errorMessage(error2) {
|
|
1522
1523
|
if (!(error2 instanceof Error)) return String(error2);
|
|
1523
1524
|
return error2.cause instanceof Error ? error2.cause.message : error2.message;
|
|
@@ -1642,6 +1643,7 @@ function readFreelistCount(db) {
|
|
|
1642
1643
|
return db.prepare("PRAGMA freelist_count").get().freelist_count;
|
|
1643
1644
|
}
|
|
1644
1645
|
function readCheckpointResult(db) {
|
|
1646
|
+
db.exec("PRAGMA busy_timeout=0");
|
|
1645
1647
|
const row = db.prepare("PRAGMA wal_checkpoint(TRUNCATE)").get();
|
|
1646
1648
|
return { busy: row.busy !== 0, log: row.log, checkpointed: row.checkpointed };
|
|
1647
1649
|
}
|
|
@@ -1659,7 +1661,7 @@ async function probeReclaimAvailability(input) {
|
|
|
1659
1661
|
try {
|
|
1660
1662
|
const db = new sqlite.DatabaseSync(dbPath, { readOnly: true });
|
|
1661
1663
|
try {
|
|
1662
|
-
db.exec(
|
|
1664
|
+
db.exec(`PRAGMA busy_timeout=${SESSION_DB_RECLAIM_BUSY_TIMEOUT_MS}`);
|
|
1663
1665
|
autoVacuum = db.prepare("PRAGMA auto_vacuum").get().auto_vacuum;
|
|
1664
1666
|
} finally {
|
|
1665
1667
|
db.close();
|
|
@@ -1679,7 +1681,8 @@ async function reclaimSessionDbSpace(input) {
|
|
|
1679
1681
|
timeBudgetMs = SESSION_DB_RECLAIM_TIME_BUDGET_MS,
|
|
1680
1682
|
chunkPages = SESSION_DB_RECLAIM_CHUNK_PAGES,
|
|
1681
1683
|
now = () => performance.now(),
|
|
1682
|
-
|
|
1684
|
+
hasLiveTurn = false,
|
|
1685
|
+
hasProvenanceAnomaly = false
|
|
1683
1686
|
} = input;
|
|
1684
1687
|
let sqlite;
|
|
1685
1688
|
try {
|
|
@@ -1695,17 +1698,19 @@ async function reclaimSessionDbSpace(input) {
|
|
|
1695
1698
|
let db;
|
|
1696
1699
|
try {
|
|
1697
1700
|
db = new DatabaseSync(dbPath);
|
|
1698
|
-
db.exec(
|
|
1701
|
+
db.exec(`PRAGMA busy_timeout=${SESSION_DB_RECLAIM_BUSY_TIMEOUT_MS}`);
|
|
1699
1702
|
const autoVacuum = db.prepare("PRAGMA auto_vacuum").get().auto_vacuum;
|
|
1700
1703
|
if (autoVacuum === 0) {
|
|
1701
|
-
if (
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1704
|
+
if (hasLiveTurn || hasProvenanceAnomaly) {
|
|
1705
|
+
const detail = [
|
|
1706
|
+
...hasLiveTurn ? ["a session turn is live"] : [],
|
|
1707
|
+
...hasProvenanceAnomaly ? ["session-DB provenance is anomalous"] : []
|
|
1708
|
+
].join(" and ");
|
|
1709
|
+
console.warn(`[reclaimSessionDbSpace] skipping VACUUM conversion of ${dbPath}: ${detail}`);
|
|
1705
1710
|
return {
|
|
1706
1711
|
ok: false,
|
|
1707
1712
|
skipped: "full-vacuum-blocked",
|
|
1708
|
-
detail
|
|
1713
|
+
detail
|
|
1709
1714
|
};
|
|
1710
1715
|
}
|
|
1711
1716
|
const fileBytesForGuard = statSync2(dbPath).size;
|
|
@@ -1723,7 +1728,9 @@ async function reclaimSessionDbSpace(input) {
|
|
|
1723
1728
|
db.exec("VACUUM");
|
|
1724
1729
|
const afterBytes = readLogicalBytes(db);
|
|
1725
1730
|
const freelistAfter = readFreelistCount(db);
|
|
1731
|
+
const checkpointStartedAt = now();
|
|
1726
1732
|
const checkpoint = readCheckpointResult(db);
|
|
1733
|
+
const checkpointElapsedMs = Math.max(0, now() - checkpointStartedAt);
|
|
1727
1734
|
return {
|
|
1728
1735
|
ok: true,
|
|
1729
1736
|
mode: "convert",
|
|
@@ -1734,10 +1741,18 @@ async function reclaimSessionDbSpace(input) {
|
|
|
1734
1741
|
pagesReclaimed: Math.max(0, freelistBefore - freelistAfter),
|
|
1735
1742
|
stoppedBy: "freelist-drained",
|
|
1736
1743
|
elapsedMs: Math.max(0, now() - startedAt),
|
|
1744
|
+
checkpointElapsedMs,
|
|
1737
1745
|
checkpoint
|
|
1738
1746
|
};
|
|
1739
1747
|
}
|
|
1740
1748
|
if (autoVacuum === 2) {
|
|
1749
|
+
if (hasLiveTurn) {
|
|
1750
|
+
const detail = "a session turn is live";
|
|
1751
|
+
console.warn(
|
|
1752
|
+
`[reclaimSessionDbSpace] skipping incremental reclaim of ${dbPath}: ${detail}`
|
|
1753
|
+
);
|
|
1754
|
+
return { ok: false, skipped: "live-turn", detail };
|
|
1755
|
+
}
|
|
1741
1756
|
const beforeBytes = readLogicalBytes(db);
|
|
1742
1757
|
const freelistBefore = readFreelistCount(db);
|
|
1743
1758
|
const startedAt = now();
|
|
@@ -1762,7 +1777,9 @@ async function reclaimSessionDbSpace(input) {
|
|
|
1762
1777
|
freelistAfter = readFreelistCount(db);
|
|
1763
1778
|
}
|
|
1764
1779
|
const afterBytes = readLogicalBytes(db);
|
|
1780
|
+
const checkpointStartedAt = now();
|
|
1765
1781
|
const checkpoint = readCheckpointResult(db);
|
|
1782
|
+
const checkpointElapsedMs = Math.max(0, now() - checkpointStartedAt);
|
|
1766
1783
|
return {
|
|
1767
1784
|
ok: true,
|
|
1768
1785
|
mode: "incremental",
|
|
@@ -1773,6 +1790,7 @@ async function reclaimSessionDbSpace(input) {
|
|
|
1773
1790
|
pagesReclaimed: Math.max(0, freelistBefore - freelistAfter),
|
|
1774
1791
|
stoppedBy,
|
|
1775
1792
|
elapsedMs: Math.max(0, now() - startedAt),
|
|
1793
|
+
checkpointElapsedMs,
|
|
1776
1794
|
checkpoint
|
|
1777
1795
|
};
|
|
1778
1796
|
}
|
|
@@ -3058,9 +3076,11 @@ function sumAssistantUsage(messages) {
|
|
|
3058
3076
|
let cacheWriteSum = 0;
|
|
3059
3077
|
let costSum = 0;
|
|
3060
3078
|
let sawCost = false;
|
|
3079
|
+
let toolCallCount = 0;
|
|
3061
3080
|
let modelId = null;
|
|
3062
3081
|
let providerId = null;
|
|
3063
3082
|
for (const m of selected) {
|
|
3083
|
+
toolCallCount += m.parts?.filter((part) => part.type === "tool").length ?? 0;
|
|
3064
3084
|
const info = m.info;
|
|
3065
3085
|
if (!info) continue;
|
|
3066
3086
|
const tokens = info.tokens;
|
|
@@ -3097,7 +3117,8 @@ function sumAssistantUsage(messages) {
|
|
|
3097
3117
|
usage_tokens_cache_write: cacheWriteSum,
|
|
3098
3118
|
// NULL means OpenCode never reported a cost; it is distinct from a genuine
|
|
3099
3119
|
// zero-cost message, which sets `sawCost` with `costSum === 0`.
|
|
3100
|
-
usage_cost_usd: sawCost ? costSum : null
|
|
3120
|
+
usage_cost_usd: sawCost ? costSum : null,
|
|
3121
|
+
turn_tool_calls: toolCallCount
|
|
3101
3122
|
};
|
|
3102
3123
|
}
|
|
3103
3124
|
function messageUsage(messages, userMessageId) {
|
|
@@ -12858,7 +12879,9 @@ async function installRunnerSecret({
|
|
|
12858
12879
|
}) {
|
|
12859
12880
|
const arn = env.RUNNER_SECRET_ARN?.trim();
|
|
12860
12881
|
if (!arn) {
|
|
12861
|
-
|
|
12882
|
+
if (!env.GH_TOKEN) {
|
|
12883
|
+
log3("runner secret is not configured; continuing without GitHub and MCP credentials");
|
|
12884
|
+
}
|
|
12862
12885
|
return false;
|
|
12863
12886
|
}
|
|
12864
12887
|
const result = await (commandRunner ?? runCommand2)(
|
|
@@ -13978,21 +14001,31 @@ async function runSweep(state, driver, config) {
|
|
|
13978
14001
|
sessions_remaining: remaining,
|
|
13979
14002
|
...enumerationReason !== null ? { session_enumeration_reason: enumerationReason } : {}
|
|
13980
14003
|
};
|
|
14004
|
+
const protectedForReclaim = driver.protectedSessionIds();
|
|
13981
14005
|
const reclaimResult = await reclaimSessionDbSpace({
|
|
13982
14006
|
dbPath: sessionDbPath(),
|
|
13983
14007
|
chunkPages: SESSION_DB_RECLAIM_CHUNK_PAGES,
|
|
13984
14008
|
pageCeiling: SESSION_DB_RECLAIM_PAGE_CEILING,
|
|
13985
14009
|
timeBudgetMs: SESSION_DB_RECLAIM_TIME_BUDGET_MS,
|
|
13986
|
-
|
|
14010
|
+
hasLiveTurn: protectedForReclaim.size > 0,
|
|
14011
|
+
hasProvenanceAnomaly: state.sessionDbProvenanceAnomaly
|
|
13987
14012
|
});
|
|
13988
14013
|
if (reclaimResult.ok) {
|
|
13989
14014
|
state.sessionStoreHealth.observeWritable();
|
|
13990
14015
|
const beforeMib = (reclaimResult.beforeBytes / 1024 / 1024).toFixed(1);
|
|
13991
14016
|
const afterMib = (reclaimResult.afterBytes / 1024 / 1024).toFixed(1);
|
|
13992
14017
|
const checkpointNote = reclaimResult.checkpoint.busy ? ` (on-disk file truncation deferred: checkpoint busy, ${reclaimResult.checkpoint.log} WAL frames pending)` : "";
|
|
14018
|
+
const loopElapsedMs = Math.max(
|
|
14019
|
+
0,
|
|
14020
|
+
reclaimResult.elapsedMs - reclaimResult.checkpointElapsedMs
|
|
14021
|
+
);
|
|
14022
|
+
const reclaimIsSlow = reclaimResult.elapsedMs >= 4 * SESSION_DB_RECLAIM_TIME_BUDGET_MS;
|
|
14023
|
+
const perPageNote = reclaimResult.pagesReclaimed > 0 ? `, per-page ${(loopElapsedMs / reclaimResult.pagesReclaimed).toFixed(2)} ms/page` : "";
|
|
14024
|
+
const slowReclaimNote = reclaimIsSlow ? ` (slow reclaim: total elapsed ${reclaimResult.elapsedMs} ms, checkpoint ${reclaimResult.checkpointElapsedMs} ms, loop ${loopElapsedMs} ms, budget ${SESSION_DB_RECLAIM_TIME_BUDGET_MS} ms${perPageNote})` : "";
|
|
13993
14025
|
logSessionCleanupActivity(state, "sweep", {
|
|
13994
14026
|
type: "info",
|
|
13995
|
-
|
|
14027
|
+
level: reclaimIsSlow ? "warn" : "info",
|
|
14028
|
+
message: `Session cleanup: reclaimed session-db space (${reclaimResult.mode}): ${beforeMib} MiB -> ${afterMib} MiB (stopped by ${reclaimResult.stoppedBy}; freelist ${reclaimResult.freelistBefore} -> ${reclaimResult.freelistAfter} pages)` + checkpointNote + slowReclaimNote,
|
|
13996
14029
|
metadata: {
|
|
13997
14030
|
outcome: "reclaimed",
|
|
13998
14031
|
mode: reclaimResult.mode,
|
|
@@ -14005,6 +14038,7 @@ async function runSweep(state, driver, config) {
|
|
|
14005
14038
|
freelist_after: reclaimResult.freelistAfter,
|
|
14006
14039
|
pages_reclaimed: reclaimResult.pagesReclaimed,
|
|
14007
14040
|
reclaim_elapsed_ms: reclaimResult.elapsedMs,
|
|
14041
|
+
checkpoint_elapsed_ms: reclaimResult.checkpointElapsedMs,
|
|
14008
14042
|
...sessionMetadata
|
|
14009
14043
|
}
|
|
14010
14044
|
});
|
|
@@ -14757,22 +14791,21 @@ async function run(options) {
|
|
|
14757
14791
|
);
|
|
14758
14792
|
}
|
|
14759
14793
|
}
|
|
14760
|
-
|
|
14761
|
-
|
|
14762
|
-
|
|
14763
|
-
|
|
14764
|
-
|
|
14765
|
-
|
|
14766
|
-
|
|
14767
|
-
} else {
|
|
14768
|
-
logActivity(state, { type: "info", level, message });
|
|
14769
|
-
}
|
|
14794
|
+
const credentialContext = {
|
|
14795
|
+
env: process.env,
|
|
14796
|
+
log: (message, level = "info") => {
|
|
14797
|
+
if (level === "error") {
|
|
14798
|
+
logActivity(state, { type: "error", error: message });
|
|
14799
|
+
} else {
|
|
14800
|
+
logActivity(state, { type: "info", level, message });
|
|
14770
14801
|
}
|
|
14771
|
-
}
|
|
14772
|
-
|
|
14802
|
+
}
|
|
14803
|
+
};
|
|
14804
|
+
const githubTokenPopulated = await installRunnerSecret(credentialContext);
|
|
14805
|
+
if (options.restoreRunnerCredentials) {
|
|
14773
14806
|
await restoreCredentialStores(credentialContext);
|
|
14774
|
-
if (githubTokenPopulated) await configureGitHubAccess(credentialContext);
|
|
14775
14807
|
}
|
|
14808
|
+
if (githubTokenPopulated) await configureGitHubAccess(credentialContext);
|
|
14776
14809
|
state.credentialSync?.arm();
|
|
14777
14810
|
const openCodeActivityForwarder = createOpenCodeActivityForwarder(
|
|
14778
14811
|
() => ({
|