@adhdev/daemon-core 0.9.82-rc.331 → 0.9.82-rc.333
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 +189 -88
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +187 -86
- package/dist/index.mjs.map +1 -1
- package/dist/providers/cli-provider-instance.d.ts +15 -0
- package/dist/system/load-better-sqlite3.d.ts +21 -0
- package/package.json +2 -2
- package/src/cli-adapters/provider-cli-adapter.ts +12 -0
- package/src/mesh/mesh-events-coordinator.ts +15 -0
- package/src/mesh/mesh-reconcile-loop.ts +38 -2
- package/src/mesh/mesh-runtime-store.ts +2 -5
- package/src/providers/cli-provider-instance.ts +45 -0
- package/src/providers/native-history/hermes-cli-transcript.ts +2 -2
- package/src/providers/spec/native-history-executor.ts +2 -2
- package/src/system/load-better-sqlite3.ts +68 -0
package/dist/index.js
CHANGED
|
@@ -316,10 +316,10 @@ function readInjected(value) {
|
|
|
316
316
|
}
|
|
317
317
|
function getDaemonBuildInfo() {
|
|
318
318
|
if (cached) return cached;
|
|
319
|
-
const commit = readInjected(true ? "
|
|
320
|
-
const commitShort = readInjected(true ? "
|
|
321
|
-
const version = readInjected(true ? "0.9.82-rc.
|
|
322
|
-
const builtAt = readInjected(true ? "2026-06-
|
|
319
|
+
const commit = readInjected(true ? "5d9635b2a6476691469ecfe32b26a17e13484b2b" : void 0) ?? "unknown";
|
|
320
|
+
const commitShort = readInjected(true ? "5d9635b2" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
|
|
321
|
+
const version = readInjected(true ? "0.9.82-rc.333" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
|
|
322
|
+
const builtAt = readInjected(true ? "2026-06-20T02:23:56.856Z" : void 0);
|
|
323
323
|
cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
|
|
324
324
|
return cached;
|
|
325
325
|
}
|
|
@@ -587,10 +587,10 @@ async function getGitRepoStatus(workspace, options = {}) {
|
|
|
587
587
|
} catch (error) {
|
|
588
588
|
const gitError = error instanceof GitCommandError ? error : new GitCommandError("git_command_failed", "Failed to read Git status", { cause: error });
|
|
589
589
|
if (isTransientGitFailure(gitError)) {
|
|
590
|
-
const
|
|
591
|
-
if (
|
|
590
|
+
const cached3 = lastKnownGoodStatus.get(workspace);
|
|
591
|
+
if (cached3) {
|
|
592
592
|
return {
|
|
593
|
-
...
|
|
593
|
+
...cached3,
|
|
594
594
|
lastCheckedAt,
|
|
595
595
|
upstreamStatus: "unavailable",
|
|
596
596
|
error: gitError.stderr || gitError.message,
|
|
@@ -713,9 +713,9 @@ function resolveChangeImpactConfigForRepo(repoRoot, options) {
|
|
|
713
713
|
return { config: null, sourceKey: "no-repo-root" };
|
|
714
714
|
}
|
|
715
715
|
const loaded = loadChangeImpactConfig(repoRoot);
|
|
716
|
-
const
|
|
717
|
-
if (
|
|
718
|
-
return { config:
|
|
716
|
+
const cached3 = changeImpactConfigCache.get(repoRoot);
|
|
717
|
+
if (cached3 && cached3.sourceKey === loaded.sourceKey) {
|
|
718
|
+
return { config: cached3.config, sourceKey: loaded.sourceKey };
|
|
719
719
|
}
|
|
720
720
|
const config = loaded.sourceType === "repo_file" ? loaded.config ?? null : null;
|
|
721
721
|
changeImpactConfigCache.set(repoRoot, { sourceKey: loaded.sourceKey, config });
|
|
@@ -2541,6 +2541,47 @@ Follow these recovery rules:
|
|
|
2541
2541
|
}
|
|
2542
2542
|
});
|
|
2543
2543
|
|
|
2544
|
+
// src/system/load-better-sqlite3.ts
|
|
2545
|
+
function loadBetterSqlite3() {
|
|
2546
|
+
if (cached2) return cached2;
|
|
2547
|
+
const errors = [];
|
|
2548
|
+
if (typeof require === "function") {
|
|
2549
|
+
try {
|
|
2550
|
+
cached2 = require("better-sqlite3");
|
|
2551
|
+
return cached2;
|
|
2552
|
+
} catch (e) {
|
|
2553
|
+
errors.push(e);
|
|
2554
|
+
}
|
|
2555
|
+
}
|
|
2556
|
+
try {
|
|
2557
|
+
const metaUrl = typeof import_meta?.url === "string" ? import_meta.url : void 0;
|
|
2558
|
+
if (metaUrl) {
|
|
2559
|
+
cached2 = (0, import_module.createRequire)(metaUrl)("better-sqlite3");
|
|
2560
|
+
return cached2;
|
|
2561
|
+
}
|
|
2562
|
+
} catch (e) {
|
|
2563
|
+
errors.push(e);
|
|
2564
|
+
}
|
|
2565
|
+
try {
|
|
2566
|
+
cached2 = (0, import_module.createRequire)(`${process.cwd()}/__adhdev_better_sqlite3_loader__.js`)(
|
|
2567
|
+
"better-sqlite3"
|
|
2568
|
+
);
|
|
2569
|
+
return cached2;
|
|
2570
|
+
} catch (e) {
|
|
2571
|
+
errors.push(e);
|
|
2572
|
+
}
|
|
2573
|
+
const detail = errors.map((e) => e instanceof Error ? e.message : String(e)).join("; ");
|
|
2574
|
+
throw new Error(`Failed to load better-sqlite3: ${detail}`);
|
|
2575
|
+
}
|
|
2576
|
+
var import_module, import_meta, cached2;
|
|
2577
|
+
var init_load_better_sqlite3 = __esm({
|
|
2578
|
+
"src/system/load-better-sqlite3.ts"() {
|
|
2579
|
+
"use strict";
|
|
2580
|
+
import_module = require("module");
|
|
2581
|
+
import_meta = {};
|
|
2582
|
+
}
|
|
2583
|
+
});
|
|
2584
|
+
|
|
2544
2585
|
// src/mesh/mesh-ledger.ts
|
|
2545
2586
|
var mesh_ledger_exports = {};
|
|
2546
2587
|
__export(mesh_ledger_exports, {
|
|
@@ -2970,8 +3011,8 @@ function readLedgerFromStore(meshId) {
|
|
|
2970
3011
|
}
|
|
2971
3012
|
function getCachedRawEntries(meshId) {
|
|
2972
3013
|
const now = Date.now();
|
|
2973
|
-
const
|
|
2974
|
-
if (
|
|
3014
|
+
const cached3 = ledgerReadCache.get(meshId);
|
|
3015
|
+
if (cached3 && now - cached3.cachedAt < LEDGER_CACHE_TTL_MS) return cached3.entries;
|
|
2975
3016
|
let entries;
|
|
2976
3017
|
try {
|
|
2977
3018
|
entries = readLedgerFromStore(meshId);
|
|
@@ -3854,8 +3895,7 @@ var init_mesh_work_queue = __esm({
|
|
|
3854
3895
|
// src/mesh/mesh-runtime-store.ts
|
|
3855
3896
|
function loadDatabaseCtor() {
|
|
3856
3897
|
if (DatabaseCtor) return DatabaseCtor;
|
|
3857
|
-
|
|
3858
|
-
DatabaseCtor = runtimeRequire("better-sqlite3");
|
|
3898
|
+
DatabaseCtor = loadBetterSqlite3();
|
|
3859
3899
|
return DatabaseCtor;
|
|
3860
3900
|
}
|
|
3861
3901
|
function safeMeshId(meshId) {
|
|
@@ -3882,16 +3922,15 @@ function meshRuntimeStorePath() {
|
|
|
3882
3922
|
}
|
|
3883
3923
|
return nextPath;
|
|
3884
3924
|
}
|
|
3885
|
-
var import_fs5, import_path5,
|
|
3925
|
+
var import_fs5, import_path5, DatabaseCtor, MeshRuntimeStore;
|
|
3886
3926
|
var init_mesh_runtime_store = __esm({
|
|
3887
3927
|
"src/mesh/mesh-runtime-store.ts"() {
|
|
3888
3928
|
"use strict";
|
|
3889
3929
|
import_fs5 = require("fs");
|
|
3890
3930
|
import_path5 = require("path");
|
|
3891
|
-
|
|
3931
|
+
init_load_better_sqlite3();
|
|
3892
3932
|
init_mesh_ledger();
|
|
3893
3933
|
init_mesh_work_queue();
|
|
3894
|
-
import_meta = {};
|
|
3895
3934
|
MeshRuntimeStore = class _MeshRuntimeStore {
|
|
3896
3935
|
static instance;
|
|
3897
3936
|
db;
|
|
@@ -9418,8 +9457,8 @@ function resolveCoordinatorDrainDaemonIds(components) {
|
|
|
9418
9457
|
}
|
|
9419
9458
|
function getCachedMeshByWorkspace(workspace) {
|
|
9420
9459
|
const now = Date.now();
|
|
9421
|
-
const
|
|
9422
|
-
if (
|
|
9460
|
+
const cached3 = meshByWorkspaceCache.get(workspace);
|
|
9461
|
+
if (cached3 && now - cached3.cachedAt < MESH_WORKSPACE_CACHE_TTL_MS) return cached3.mesh;
|
|
9423
9462
|
const mesh = getMeshByRepo(workspace);
|
|
9424
9463
|
meshByWorkspaceCache.set(workspace, { mesh, cachedAt: now });
|
|
9425
9464
|
return mesh;
|
|
@@ -10669,6 +10708,21 @@ function handleMeshForwardEvent(components, payload) {
|
|
|
10669
10708
|
targetSessionId: readNonEmptyString2(payload.targetSessionId) || readNonEmptyString2(payload.sessionId) || readNonEmptyString2(payload.instanceId),
|
|
10670
10709
|
providerType: readNonEmptyString2(payload.providerType),
|
|
10671
10710
|
providerSessionId: readNonEmptyString2(payload.providerSessionId),
|
|
10711
|
+
// Carry the session identity fields the worker provider event emits so the
|
|
10712
|
+
// coordinator's mirror (updateMeshOwnedSession) gets a real workspace/title/
|
|
10713
|
+
// settings. Without these the remote-relay hop reconstructs metadataEvent with
|
|
10714
|
+
// an empty workspace, and the dashboard flaps to the generic
|
|
10715
|
+
// "Terminal (Mesh Node)" title (and degrades the provider label) between live
|
|
10716
|
+
// events and the periodic get_status_metadata snapshot. The local in-process
|
|
10717
|
+
// forward path (onMeshCoordinatorEventForwarded) already preserves these; this
|
|
10718
|
+
// mirrors them for the remote-only relay path.
|
|
10719
|
+
workspace: readNonEmptyString2(payload.workspace) || readNonEmptyString2(payload.workspaceName),
|
|
10720
|
+
workspaceName: readNonEmptyString2(payload.workspaceName) || readNonEmptyString2(payload.workspace),
|
|
10721
|
+
sessionTitle: readNonEmptyString2(payload.sessionTitle),
|
|
10722
|
+
sessionStatus: readNonEmptyString2(payload.sessionStatus),
|
|
10723
|
+
sessionChatStatus: readNonEmptyString2(payload.sessionChatStatus),
|
|
10724
|
+
providerName: readNonEmptyString2(payload.providerName),
|
|
10725
|
+
...payload.sessionSettings && typeof payload.sessionSettings === "object" && !Array.isArray(payload.sessionSettings) ? { sessionSettings: payload.sessionSettings } : {},
|
|
10672
10726
|
finalSummary: readNonEmptyString2(payload.finalSummary) || readNonEmptyString2(payload.summary),
|
|
10673
10727
|
jobId: readNonEmptyString2(payload.jobId),
|
|
10674
10728
|
interactionId: readNonEmptyString2(payload.interactionId),
|
|
@@ -11549,7 +11603,8 @@ function findLiveCoordinators(components) {
|
|
|
11549
11603
|
const meshId = readNonEmptyString2(settings.meshCoordinatorFor);
|
|
11550
11604
|
if (!meshId) continue;
|
|
11551
11605
|
const status = readNonEmptyString2(state.status).toLowerCase();
|
|
11552
|
-
|
|
11606
|
+
const modalParked = status === "waiting_choice" || status === "waiting_approval";
|
|
11607
|
+
out.push({ meshId, instance: inst, idle: status === "idle", modalParked });
|
|
11553
11608
|
}
|
|
11554
11609
|
return out;
|
|
11555
11610
|
}
|
|
@@ -11638,9 +11693,16 @@ async function runMeshReconcileTick(components) {
|
|
|
11638
11693
|
}
|
|
11639
11694
|
for (const [meshId, meshCoordinators] of byMesh) {
|
|
11640
11695
|
const idleCoordinators = meshCoordinators.filter((c) => c.idle);
|
|
11641
|
-
const generatingCoordinators = meshCoordinators.filter((c) => !c.idle);
|
|
11696
|
+
const generatingCoordinators = meshCoordinators.filter((c) => !c.idle && !c.modalParked);
|
|
11697
|
+
const modalParkedCoordinators = meshCoordinators.filter((c) => !c.idle && c.modalParked);
|
|
11642
11698
|
const targetCoordinators = idleCoordinators.length > 0 ? idleCoordinators : generatingCoordinators;
|
|
11643
11699
|
const forceOnly = idleCoordinators.length === 0;
|
|
11700
|
+
if (targetCoordinators.length === 0) {
|
|
11701
|
+
if (modalParkedCoordinators.length > 0) {
|
|
11702
|
+
LOG.info("MeshReconcile", `Reconcile skip \u2192 modal-parked: holding pending event(s) for mesh ${meshId} (${modalParkedCoordinators.length} coordinator(s) awaiting a modal answer; events left queued)`);
|
|
11703
|
+
}
|
|
11704
|
+
continue;
|
|
11705
|
+
}
|
|
11644
11706
|
if (store) {
|
|
11645
11707
|
try {
|
|
11646
11708
|
if (store.pendingEventCount(meshId) === 0) continue;
|
|
@@ -15242,10 +15304,10 @@ ${lastSnapshot}`;
|
|
|
15242
15304
|
return this.accumulatedRawBuffer.replace(/\x1B\][^\x07]*(?:\x07|\x1B\\)/g, "").replace(/\x1B[P^_X][\s\S]*?(?:\x07|\x1B\\)/g, "").replace(/\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])/g, "");
|
|
15243
15305
|
}
|
|
15244
15306
|
getFreshParsedStatusCache() {
|
|
15245
|
-
const
|
|
15307
|
+
const cached3 = this.parsedStatusCache;
|
|
15246
15308
|
const accumulatedRawBufferKey = this.getAccumulatedRawBufferCacheKey();
|
|
15247
|
-
if (
|
|
15248
|
-
return
|
|
15309
|
+
if (cached3 && cached3.responseBuffer === this.responseBuffer && cached3.currentTurnScope === this.engine.currentTurnScope && cached3.recentOutputBuffer === this.recentOutputBuffer && cached3.accumulatedBuffer === this.accumulatedBuffer && cached3.accumulatedRawBufferKey === accumulatedRawBufferKey && cached3.screenText === this.lastScreenText && cached3.currentStatus === this.engine.currentStatus && cached3.activeModal === this.engine.activeModal && cached3.cliName === this.cliName) {
|
|
15310
|
+
return cached3.result;
|
|
15249
15311
|
}
|
|
15250
15312
|
return null;
|
|
15251
15313
|
}
|
|
@@ -15707,10 +15769,10 @@ ${lastSnapshot}`;
|
|
|
15707
15769
|
getScriptParsedStatus() {
|
|
15708
15770
|
const screenText = this.readTerminalScreenText();
|
|
15709
15771
|
const parseScreenText = this.getParseScreenText(screenText);
|
|
15710
|
-
const
|
|
15772
|
+
const cached3 = this.parsedStatusCache;
|
|
15711
15773
|
const accumulatedRawBufferKey = this.getAccumulatedRawBufferCacheKey();
|
|
15712
|
-
if (!this.providerOwnsTranscript() &&
|
|
15713
|
-
return
|
|
15774
|
+
if (!this.providerOwnsTranscript() && cached3 && cached3.responseBuffer === this.responseBuffer && cached3.currentTurnScope === this.engine.currentTurnScope && cached3.recentOutputBuffer === this.recentOutputBuffer && cached3.accumulatedBuffer === this.accumulatedBuffer && cached3.accumulatedRawBufferKey === accumulatedRawBufferKey && cached3.screenText === parseScreenText && cached3.currentStatus === this.engine.currentStatus && cached3.activeModal === this.engine.activeModal && cached3.cliName === this.cliName) {
|
|
15775
|
+
return cached3.result;
|
|
15714
15776
|
}
|
|
15715
15777
|
const parsed = this.runParseSession();
|
|
15716
15778
|
if (!parsed || !Array.isArray(parsed.messages)) {
|
|
@@ -15957,6 +16019,10 @@ ${lastSnapshot}`;
|
|
|
15957
16019
|
if (!this.ptyProcess) throw new Error(`${this.cliName} is not running`);
|
|
15958
16020
|
const content = String(text || "");
|
|
15959
16021
|
if (!content.trim()) return;
|
|
16022
|
+
if (this.engine.currentStatus === "waiting_approval" || this.engine.hasActionableApproval()) {
|
|
16023
|
+
LOG.info("CLI", `[${this.cliType}] force-send held \u2014 session parked on approval modal (status=${this.engine.currentStatus})`);
|
|
16024
|
+
return;
|
|
16025
|
+
}
|
|
15960
16026
|
LOG.info("CLI", `[${this.cliType}] force-sending prompt while status=${this.engine.currentStatus}`);
|
|
15961
16027
|
await this.writeToPty(content + this.sendKey);
|
|
15962
16028
|
this.onStatusChange?.();
|
|
@@ -22462,11 +22528,11 @@ var savedHistoryRollupInFlight = /* @__PURE__ */ new Set();
|
|
|
22462
22528
|
var BOUNDED_TAIL_CACHE_MAX_ENTRIES = 64;
|
|
22463
22529
|
var boundedTailReadCache = /* @__PURE__ */ new Map();
|
|
22464
22530
|
function readBoundedTailCache(key, signature) {
|
|
22465
|
-
const
|
|
22466
|
-
if (!
|
|
22531
|
+
const cached3 = boundedTailReadCache.get(key);
|
|
22532
|
+
if (!cached3 || cached3.signature !== signature) return null;
|
|
22467
22533
|
boundedTailReadCache.delete(key);
|
|
22468
|
-
boundedTailReadCache.set(key,
|
|
22469
|
-
return
|
|
22534
|
+
boundedTailReadCache.set(key, cached3);
|
|
22535
|
+
return cached3.result;
|
|
22470
22536
|
}
|
|
22471
22537
|
function writeBoundedTailCache(key, signature, result) {
|
|
22472
22538
|
boundedTailReadCache.delete(key);
|
|
@@ -22950,9 +23016,9 @@ function computeSavedHistorySessionSummaries(agentType, dir, files, fileSignatur
|
|
|
22950
23016
|
for (const file of files.slice().sort()) {
|
|
22951
23017
|
const filePath = path14.join(dir, file);
|
|
22952
23018
|
const signature = fileSignatures.get(file) || `${file}:missing`;
|
|
22953
|
-
const
|
|
23019
|
+
const cached3 = savedHistoryFileSummaryCache.get(filePath);
|
|
22954
23020
|
const persisted = persistedEntries.get(file);
|
|
22955
|
-
const reusableEntry =
|
|
23021
|
+
const reusableEntry = cached3?.signature === signature ? cached3 : persisted?.signature === signature ? persisted : null;
|
|
22956
23022
|
const fileSummary = reusableEntry?.summary || computeSavedHistoryFileSummary(dir, file);
|
|
22957
23023
|
const nextEntry = reusableEntry || {
|
|
22958
23024
|
signature,
|
|
@@ -23448,16 +23514,16 @@ function readFileTailLines(filePath, needed) {
|
|
|
23448
23514
|
incrementalTailCache.delete(filePath);
|
|
23449
23515
|
return { lines: [], coversWholeFile: true };
|
|
23450
23516
|
}
|
|
23451
|
-
const
|
|
23452
|
-
if (
|
|
23453
|
-
if (
|
|
23517
|
+
const cached3 = incrementalTailCache.get(filePath);
|
|
23518
|
+
if (cached3) {
|
|
23519
|
+
if (cached3.size === size && cached3.mtimeMs === mtimeMs) {
|
|
23454
23520
|
incrementalTailCache.delete(filePath);
|
|
23455
|
-
incrementalTailCache.set(filePath,
|
|
23456
|
-
if (
|
|
23457
|
-
return { lines:
|
|
23521
|
+
incrementalTailCache.set(filePath, cached3);
|
|
23522
|
+
if (cached3.coversWholeFile || cached3.lines.length >= needed) {
|
|
23523
|
+
return { lines: cached3.lines, coversWholeFile: cached3.coversWholeFile };
|
|
23458
23524
|
}
|
|
23459
|
-
} else if (size >
|
|
23460
|
-
const incremental = tryIncrementalTailGrowth(filePath,
|
|
23525
|
+
} else if (size > cached3.size) {
|
|
23526
|
+
const incremental = tryIncrementalTailGrowth(filePath, cached3, size, mtimeMs, needed);
|
|
23461
23527
|
if (incremental) return { lines: incremental.lines, coversWholeFile: incremental.coversWholeFile };
|
|
23462
23528
|
}
|
|
23463
23529
|
incrementalTailCache.delete(filePath);
|
|
@@ -23483,22 +23549,22 @@ function readFileTailLines(filePath, needed) {
|
|
|
23483
23549
|
storeIncrementalTailCache(filePath, result.size, result.mtimeMs, result.lines, result.coversWholeFile);
|
|
23484
23550
|
return { lines: result.lines, coversWholeFile: result.coversWholeFile };
|
|
23485
23551
|
}
|
|
23486
|
-
function tryIncrementalTailGrowth(filePath,
|
|
23552
|
+
function tryIncrementalTailGrowth(filePath, cached3, size, mtimeMs, needed) {
|
|
23487
23553
|
const fd = fs6.openSync(filePath, "r");
|
|
23488
23554
|
try {
|
|
23489
|
-
if (
|
|
23555
|
+
if (cached3.size > 0) {
|
|
23490
23556
|
const boundary = Buffer.alloc(1);
|
|
23491
|
-
fs6.readSync(fd, boundary, 0, 1,
|
|
23557
|
+
fs6.readSync(fd, boundary, 0, 1, cached3.size - 1);
|
|
23492
23558
|
if (boundary[0] !== 10) return null;
|
|
23493
23559
|
}
|
|
23494
|
-
const appendedLength = size -
|
|
23560
|
+
const appendedLength = size - cached3.size;
|
|
23495
23561
|
const appended = Buffer.alloc(appendedLength);
|
|
23496
|
-
fs6.readSync(fd, appended, 0, appendedLength,
|
|
23562
|
+
fs6.readSync(fd, appended, 0, appendedLength, cached3.size);
|
|
23497
23563
|
const newLines = appended.toString("utf-8").split("\n");
|
|
23498
23564
|
if (newLines.length && newLines[newLines.length - 1] === "") newLines.pop();
|
|
23499
|
-
const merged =
|
|
23565
|
+
const merged = cached3.lines.concat(newLines);
|
|
23500
23566
|
const trimmed = merged.length > TAIL_LINES_RETAINED ? merged.slice(merged.length - TAIL_LINES_RETAINED) : merged;
|
|
23501
|
-
const coversWholeFile =
|
|
23567
|
+
const coversWholeFile = cached3.coversWholeFile && trimmed.length === merged.length;
|
|
23502
23568
|
storeIncrementalTailCache(filePath, size, mtimeMs, trimmed, coversWholeFile);
|
|
23503
23569
|
if (coversWholeFile || trimmed.length >= needed) {
|
|
23504
23570
|
return { lines: trimmed, coversWholeFile };
|
|
@@ -23563,8 +23629,8 @@ function readChatHistory(agentType, offset = 0, limit = 30, historySessionId, ex
|
|
|
23563
23629
|
const fileSignatures = buildSavedHistoryFileSignatureMap(dir, files);
|
|
23564
23630
|
const cacheKey = `${sanitized}\0${historySessionId || ""}\0${offset}\0${limit}\0${excludeRecentCount}\0${historyBehavior?.collapseConsecutiveAssistantTurns ? "1" : "0"}`;
|
|
23565
23631
|
const signature = buildSavedHistoryCacheSignature(files, fileSignatures);
|
|
23566
|
-
const
|
|
23567
|
-
if (
|
|
23632
|
+
const cached3 = readBoundedTailCache(cacheKey, signature);
|
|
23633
|
+
if (cached3) return cached3;
|
|
23568
23634
|
const numericLimit = Math.max(1, Number(limit));
|
|
23569
23635
|
const numericOffset = Math.max(0, Number(offset));
|
|
23570
23636
|
const numericExclude = Math.max(0, Number(excludeRecentCount));
|
|
@@ -23607,23 +23673,23 @@ function listSavedHistorySessions(agentType, options = {}, historyBehavior) {
|
|
|
23607
23673
|
savedHistorySessionCache.delete(sanitized);
|
|
23608
23674
|
return { sessions: [], hasMore: false };
|
|
23609
23675
|
}
|
|
23610
|
-
const
|
|
23676
|
+
const cached3 = savedHistorySessionCache.get(sanitized);
|
|
23611
23677
|
const offset = Math.max(0, options.offset || 0);
|
|
23612
23678
|
const limit = Math.max(1, options.limit || 30);
|
|
23613
23679
|
const indexSignature = buildSavedHistoryIndexFileSignature(dir);
|
|
23614
23680
|
let cacheWasInvalidated = false;
|
|
23615
|
-
if (
|
|
23616
|
-
const cacheLooksPersisted =
|
|
23617
|
-
const cacheStillValid = cacheLooksPersisted ?
|
|
23681
|
+
if (cached3) {
|
|
23682
|
+
const cacheLooksPersisted = cached3.signature.startsWith("index:");
|
|
23683
|
+
const cacheStillValid = cacheLooksPersisted ? cached3.signature === indexSignature : (() => {
|
|
23618
23684
|
const files2 = listHistoryFiles(dir);
|
|
23619
23685
|
const fileSignatures2 = buildSavedHistoryFileSignatureMap(dir, files2);
|
|
23620
|
-
return
|
|
23686
|
+
return cached3.signature === buildSavedHistoryCacheSignature(files2, fileSignatures2);
|
|
23621
23687
|
})();
|
|
23622
23688
|
if (cacheStillValid) {
|
|
23623
|
-
const sliced2 =
|
|
23689
|
+
const sliced2 = cached3.summaries.slice(offset, offset + limit);
|
|
23624
23690
|
return {
|
|
23625
23691
|
sessions: sliced2,
|
|
23626
|
-
hasMore:
|
|
23692
|
+
hasMore: cached3.summaries.length > offset + limit
|
|
23627
23693
|
};
|
|
23628
23694
|
}
|
|
23629
23695
|
cacheWasInvalidated = true;
|
|
@@ -32571,6 +32637,7 @@ var fs13 = __toESM(require("fs"));
|
|
|
32571
32637
|
var os17 = __toESM(require("os"));
|
|
32572
32638
|
var path22 = __toESM(require("path"));
|
|
32573
32639
|
init_logger();
|
|
32640
|
+
init_load_better_sqlite3();
|
|
32574
32641
|
var UUID_RE = /([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})/i;
|
|
32575
32642
|
function executeNativeHistory(cfg, input) {
|
|
32576
32643
|
if (!cfg?.source) return null;
|
|
@@ -32695,7 +32762,7 @@ function executeSqlite(src, input) {
|
|
|
32695
32762
|
if (!resolved || !fs13.existsSync(resolved)) return null;
|
|
32696
32763
|
let Database;
|
|
32697
32764
|
try {
|
|
32698
|
-
Database =
|
|
32765
|
+
Database = loadBetterSqlite3();
|
|
32699
32766
|
} catch {
|
|
32700
32767
|
return null;
|
|
32701
32768
|
}
|
|
@@ -34861,6 +34928,35 @@ var CliProviderInstance = class _CliProviderInstance {
|
|
|
34861
34928
|
this.settings = rest;
|
|
34862
34929
|
this.adapter.updateRuntimeSettings?.(this.settings);
|
|
34863
34930
|
}
|
|
34931
|
+
/**
|
|
34932
|
+
* The resolved modal-park status of this session, or null when it is not
|
|
34933
|
+
* parked on a modal awaiting a human answer. Mirrors the overlay logic in
|
|
34934
|
+
* getState(): an active AskUserQuestion interactive prompt resolves to
|
|
34935
|
+
* waiting_choice; otherwise the adapter's waiting_approval (tool consent)
|
|
34936
|
+
* counts — UNLESS auto-approve will dismiss it, in which case the session is
|
|
34937
|
+
* effectively generating and is NOT modal-parked. This is the single signal
|
|
34938
|
+
* the mesh force-inject guard consults, and the same status string the
|
|
34939
|
+
* reconcile loop reads off get_status_metadata. Lowercase literals only —
|
|
34940
|
+
* the SessionStatus enum is forked across modules and waiting_choice is
|
|
34941
|
+
* absent from some of them.
|
|
34942
|
+
*/
|
|
34943
|
+
resolveModalParkStatus() {
|
|
34944
|
+
if (this.activeInteractivePrompt) return "waiting_choice";
|
|
34945
|
+
let adapterStatus;
|
|
34946
|
+
try {
|
|
34947
|
+
adapterStatus = this.adapter.getStatus({ allowParse: false });
|
|
34948
|
+
} catch {
|
|
34949
|
+
return null;
|
|
34950
|
+
}
|
|
34951
|
+
if (adapterStatus.status === "waiting_approval" && !this.shouldAutoApprove()) {
|
|
34952
|
+
return "waiting_approval";
|
|
34953
|
+
}
|
|
34954
|
+
return null;
|
|
34955
|
+
}
|
|
34956
|
+
/** True when this session is parked on a modal awaiting a human answer. */
|
|
34957
|
+
isModalParked() {
|
|
34958
|
+
return this.resolveModalParkStatus() !== null;
|
|
34959
|
+
}
|
|
34864
34960
|
onEvent(event, data) {
|
|
34865
34961
|
if (event === "send_message") {
|
|
34866
34962
|
const input = normalizeInputEnvelope(data);
|
|
@@ -34868,6 +34964,10 @@ var CliProviderInstance = class _CliProviderInstance {
|
|
|
34868
34964
|
const promptText = buildCliStructuredInputPrompt(input);
|
|
34869
34965
|
if (promptText) {
|
|
34870
34966
|
const force = data?.force === true;
|
|
34967
|
+
if (force && this.isModalParked()) {
|
|
34968
|
+
LOG.info("CLI", `[${this.type}] force send_message held \u2014 coordinator parked on modal (${this.resolveModalParkStatus()})`);
|
|
34969
|
+
return;
|
|
34970
|
+
}
|
|
34871
34971
|
void this.adapter.sendMessage(promptText, force ? { force: true } : {}).catch((e) => {
|
|
34872
34972
|
LOG.warn("CLI", `[${this.type}] send_message failed: ${e?.message || e}`);
|
|
34873
34973
|
});
|
|
@@ -39486,6 +39586,7 @@ function readSession3(sessionPath, sessionId, workspace) {
|
|
|
39486
39586
|
var fs20 = __toESM(require("fs"));
|
|
39487
39587
|
var path30 = __toESM(require("path"));
|
|
39488
39588
|
var os21 = __toESM(require("os"));
|
|
39589
|
+
init_load_better_sqlite3();
|
|
39489
39590
|
var HERMES_STATE_DB = path30.join(os21.homedir(), ".hermes", "state.db");
|
|
39490
39591
|
var HERMES_LEGACY_SESSIONS_DIR = path30.join(os21.homedir(), ".hermes", "sessions");
|
|
39491
39592
|
function statMtimeMs4(p) {
|
|
@@ -39498,7 +39599,7 @@ function statMtimeMs4(p) {
|
|
|
39498
39599
|
function openDb() {
|
|
39499
39600
|
if (!fs20.existsSync(HERMES_STATE_DB)) return null;
|
|
39500
39601
|
try {
|
|
39501
|
-
const Database =
|
|
39602
|
+
const Database = loadBetterSqlite3();
|
|
39502
39603
|
return new Database(HERMES_STATE_DB, { readonly: true, fileMustExist: true });
|
|
39503
39604
|
} catch {
|
|
39504
39605
|
return null;
|
|
@@ -40873,8 +40974,8 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
40873
40974
|
return null;
|
|
40874
40975
|
}
|
|
40875
40976
|
registerProviderScriptRootSafely(path33.dirname(path33.dirname(providerDir)));
|
|
40876
|
-
const
|
|
40877
|
-
if (
|
|
40977
|
+
const cached3 = this.scriptsCache.get(dir);
|
|
40978
|
+
if (cached3) return cached3;
|
|
40878
40979
|
const scriptsJs = path33.join(dir, "scripts.js");
|
|
40879
40980
|
if (fs22.existsSync(scriptsJs)) {
|
|
40880
40981
|
try {
|
|
@@ -43953,13 +44054,13 @@ function sanitizeInlineMesh(inlineMesh) {
|
|
|
43953
44054
|
nodes
|
|
43954
44055
|
};
|
|
43955
44056
|
}
|
|
43956
|
-
function reconcileInlineMeshCache(
|
|
43957
|
-
if (!
|
|
43958
|
-
if (!incoming || typeof incoming !== "object" || Array.isArray(incoming)) return
|
|
43959
|
-
const cachedNodes = Array.isArray(
|
|
44057
|
+
function reconcileInlineMeshCache(cached3, incoming) {
|
|
44058
|
+
if (!cached3 || typeof cached3 !== "object" || Array.isArray(cached3)) return incoming;
|
|
44059
|
+
if (!incoming || typeof incoming !== "object" || Array.isArray(incoming)) return cached3;
|
|
44060
|
+
const cachedNodes = Array.isArray(cached3.nodes) ? cached3.nodes : [];
|
|
43960
44061
|
const incomingNodes = Array.isArray(incoming.nodes) ? incoming.nodes : [];
|
|
43961
|
-
if (!cachedNodes.length || !incomingNodes.length) return { ...
|
|
43962
|
-
const cachedUpdatedAt = Date.parse(readStringValue(
|
|
44062
|
+
if (!cachedNodes.length || !incomingNodes.length) return { ...cached3, ...incoming };
|
|
44063
|
+
const cachedUpdatedAt = Date.parse(readStringValue(cached3.updatedAt, cached3.updated_at) || "");
|
|
43963
44064
|
const incomingUpdatedAt = Date.parse(readStringValue(incoming.updatedAt, incoming.updated_at) || "");
|
|
43964
44065
|
const preserveCachedMembership = Number.isFinite(cachedUpdatedAt) && (!Number.isFinite(incomingUpdatedAt) || cachedUpdatedAt > incomingUpdatedAt);
|
|
43965
44066
|
const cachedById = /* @__PURE__ */ new Map();
|
|
@@ -43988,7 +44089,7 @@ function reconcileInlineMeshCache(cached2, incoming) {
|
|
|
43988
44089
|
}
|
|
43989
44090
|
}
|
|
43990
44091
|
return {
|
|
43991
|
-
...
|
|
44092
|
+
...cached3,
|
|
43992
44093
|
...incoming,
|
|
43993
44094
|
nodes
|
|
43994
44095
|
};
|
|
@@ -44321,9 +44422,9 @@ var MeshGitProbeCache = class {
|
|
|
44321
44422
|
*/
|
|
44322
44423
|
async probe(daemonId, workspace, probe) {
|
|
44323
44424
|
const key = this.key(daemonId, workspace);
|
|
44324
|
-
const
|
|
44325
|
-
if (
|
|
44326
|
-
return
|
|
44425
|
+
const cached3 = this.recent.get(key);
|
|
44426
|
+
if (cached3 && this.now() - cached3.at < this.reuseMs) {
|
|
44427
|
+
return cached3.value;
|
|
44327
44428
|
}
|
|
44328
44429
|
const existing = this.inflight.get(key);
|
|
44329
44430
|
if (existing) return existing;
|
|
@@ -45971,13 +46072,13 @@ var DaemonCommandRouter = class {
|
|
|
45971
46072
|
};
|
|
45972
46073
|
}
|
|
45973
46074
|
getCachedAggregateMeshStatus(meshId, mesh, options) {
|
|
45974
|
-
const
|
|
45975
|
-
if (!
|
|
45976
|
-
if (
|
|
45977
|
-
let snapshot = this.cloneJsonValue(
|
|
46075
|
+
const cached3 = this.aggregateMeshStatusCache.get(meshId);
|
|
46076
|
+
if (!cached3?.snapshot || cached3.snapshot.success !== true || !Array.isArray(cached3.snapshot.nodes)) return null;
|
|
46077
|
+
if (cached3.queueRevision !== getMeshQueueRevision(meshId)) return null;
|
|
46078
|
+
let snapshot = this.cloneJsonValue(cached3.snapshot);
|
|
45978
46079
|
snapshot = this.hydrateCachedAggregateMeshStatusFromInline(snapshot, mesh, options);
|
|
45979
46080
|
if (shouldRefreshStalePendingAggregate(snapshot, options)) return null;
|
|
45980
|
-
const ageMs = Math.max(0, Date.now() -
|
|
46081
|
+
const ageMs = Math.max(0, Date.now() - cached3.builtAt);
|
|
45981
46082
|
const sourceOfTruth = snapshot.sourceOfTruth && typeof snapshot.sourceOfTruth === "object" ? snapshot.sourceOfTruth : {};
|
|
45982
46083
|
snapshot.sourceOfTruth = {
|
|
45983
46084
|
...sourceOfTruth,
|
|
@@ -45988,7 +46089,7 @@ var DaemonCommandRouter = class {
|
|
|
45988
46089
|
source: "memory",
|
|
45989
46090
|
refreshReason: "memory_cache_hit",
|
|
45990
46091
|
ageMs,
|
|
45991
|
-
cachedAt: new Date(
|
|
46092
|
+
cachedAt: new Date(cached3.builtAt).toISOString(),
|
|
45992
46093
|
returnedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
45993
46094
|
}
|
|
45994
46095
|
};
|
|
@@ -46035,9 +46136,9 @@ var DaemonCommandRouter = class {
|
|
|
46035
46136
|
meshId,
|
|
46036
46137
|
sanitizeInlineMesh(normalizeInlineMeshNodeIdentity(inlineMesh))
|
|
46037
46138
|
);
|
|
46038
|
-
const
|
|
46039
|
-
if (
|
|
46040
|
-
const merged = reconcileInlineMeshCache(
|
|
46139
|
+
const cached3 = this.inlineMeshCache.get(meshId);
|
|
46140
|
+
if (cached3) {
|
|
46141
|
+
const merged = reconcileInlineMeshCache(cached3, sanitizedInlineMesh);
|
|
46041
46142
|
this.inlineMeshCache.set(meshId, merged);
|
|
46042
46143
|
return merged;
|
|
46043
46144
|
}
|
|
@@ -46047,17 +46148,17 @@ var DaemonCommandRouter = class {
|
|
|
46047
46148
|
async getMeshForCommand(meshId, inlineMesh, options) {
|
|
46048
46149
|
const preferInline = options?.preferInline === true;
|
|
46049
46150
|
if (preferInline) {
|
|
46050
|
-
const
|
|
46051
|
-
if (
|
|
46151
|
+
const cached4 = this.getCachedInlineMesh(meshId);
|
|
46152
|
+
if (cached4) {
|
|
46052
46153
|
if (inlineMeshCarriesTransientNodeTruth(inlineMesh)) {
|
|
46053
46154
|
const merged = reconcileInlineMeshCache(
|
|
46054
|
-
|
|
46155
|
+
cached4,
|
|
46055
46156
|
this.applyInlineMeshNodeTombstones(meshId, inlineMesh)
|
|
46056
46157
|
);
|
|
46057
46158
|
this.inlineMeshCache.set(meshId, sanitizeInlineMesh(normalizeInlineMeshNodeIdentity(merged)));
|
|
46058
46159
|
return { mesh: merged, inline: true, source: "inline_cache" };
|
|
46059
46160
|
}
|
|
46060
|
-
return { mesh:
|
|
46161
|
+
return { mesh: cached4, inline: true, source: "inline_cache" };
|
|
46061
46162
|
}
|
|
46062
46163
|
if (inlineMeshCarriesTransientNodeTruth(inlineMesh)) {
|
|
46063
46164
|
this.warmInlineMeshCache(meshId, inlineMesh);
|
|
@@ -46070,8 +46171,8 @@ var DaemonCommandRouter = class {
|
|
|
46070
46171
|
if (mesh) return { mesh, inline: false, source: "local_config" };
|
|
46071
46172
|
} catch {
|
|
46072
46173
|
}
|
|
46073
|
-
const
|
|
46074
|
-
if (
|
|
46174
|
+
const cached3 = this.getCachedInlineMesh(meshId);
|
|
46175
|
+
if (cached3) return { mesh: cached3, inline: true, source: "inline_cache" };
|
|
46075
46176
|
const warmedInline = this.warmInlineMeshCache(meshId, inlineMesh);
|
|
46076
46177
|
return warmedInline ? { mesh: warmedInline, inline: true, source: "inline_bootstrap" } : null;
|
|
46077
46178
|
}
|
|
@@ -47501,8 +47602,8 @@ ${hintLines.join("\n")}` : "",
|
|
|
47501
47602
|
const repoRootBaseRef = /* @__PURE__ */ new Map();
|
|
47502
47603
|
const submodulePathsByRepoRoot = /* @__PURE__ */ new Map();
|
|
47503
47604
|
const resolveBaseRef = async (repoRoot) => {
|
|
47504
|
-
const
|
|
47505
|
-
if (
|
|
47605
|
+
const cached3 = repoRootBaseRef.get(repoRoot);
|
|
47606
|
+
if (cached3) return cached3;
|
|
47506
47607
|
let baseBranch = "main";
|
|
47507
47608
|
try {
|
|
47508
47609
|
const { stdout } = await execFileAsync4("git", ["branch", "--show-current"], { cwd: repoRoot, encoding: "utf8" });
|