@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 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 ? "a6ef3a58ea926c6fa42f5ec53fae14e0bd5cac1b" : void 0) ?? "unknown";
320
- const commitShort = readInjected(true ? "a6ef3a58" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
321
- const version = readInjected(true ? "0.9.82-rc.331" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
322
- const builtAt = readInjected(true ? "2026-06-20T00:34:05.737Z" : void 0);
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 cached2 = lastKnownGoodStatus.get(workspace);
591
- if (cached2) {
590
+ const cached3 = lastKnownGoodStatus.get(workspace);
591
+ if (cached3) {
592
592
  return {
593
- ...cached2,
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 cached2 = changeImpactConfigCache.get(repoRoot);
717
- if (cached2 && cached2.sourceKey === loaded.sourceKey) {
718
- return { config: cached2.config, sourceKey: loaded.sourceKey };
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 cached2 = ledgerReadCache.get(meshId);
2974
- if (cached2 && now - cached2.cachedAt < LEDGER_CACHE_TTL_MS) return cached2.entries;
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
- const runtimeRequire = typeof require === "function" ? require : (0, import_module.createRequire)(import_meta.url);
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, import_module, import_meta, DatabaseCtor, MeshRuntimeStore;
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
- import_module = require("module");
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 cached2 = meshByWorkspaceCache.get(workspace);
9422
- if (cached2 && now - cached2.cachedAt < MESH_WORKSPACE_CACHE_TTL_MS) return cached2.mesh;
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
- out.push({ meshId, instance: inst, idle: status === "idle" });
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 cached2 = this.parsedStatusCache;
15307
+ const cached3 = this.parsedStatusCache;
15246
15308
  const accumulatedRawBufferKey = this.getAccumulatedRawBufferCacheKey();
15247
- if (cached2 && cached2.responseBuffer === this.responseBuffer && cached2.currentTurnScope === this.engine.currentTurnScope && cached2.recentOutputBuffer === this.recentOutputBuffer && cached2.accumulatedBuffer === this.accumulatedBuffer && cached2.accumulatedRawBufferKey === accumulatedRawBufferKey && cached2.screenText === this.lastScreenText && cached2.currentStatus === this.engine.currentStatus && cached2.activeModal === this.engine.activeModal && cached2.cliName === this.cliName) {
15248
- return cached2.result;
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 cached2 = this.parsedStatusCache;
15772
+ const cached3 = this.parsedStatusCache;
15711
15773
  const accumulatedRawBufferKey = this.getAccumulatedRawBufferCacheKey();
15712
- if (!this.providerOwnsTranscript() && cached2 && cached2.responseBuffer === this.responseBuffer && cached2.currentTurnScope === this.engine.currentTurnScope && cached2.recentOutputBuffer === this.recentOutputBuffer && cached2.accumulatedBuffer === this.accumulatedBuffer && cached2.accumulatedRawBufferKey === accumulatedRawBufferKey && cached2.screenText === parseScreenText && cached2.currentStatus === this.engine.currentStatus && cached2.activeModal === this.engine.activeModal && cached2.cliName === this.cliName) {
15713
- return cached2.result;
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 cached2 = boundedTailReadCache.get(key);
22466
- if (!cached2 || cached2.signature !== signature) return null;
22531
+ const cached3 = boundedTailReadCache.get(key);
22532
+ if (!cached3 || cached3.signature !== signature) return null;
22467
22533
  boundedTailReadCache.delete(key);
22468
- boundedTailReadCache.set(key, cached2);
22469
- return cached2.result;
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 cached2 = savedHistoryFileSummaryCache.get(filePath);
23019
+ const cached3 = savedHistoryFileSummaryCache.get(filePath);
22954
23020
  const persisted = persistedEntries.get(file);
22955
- const reusableEntry = cached2?.signature === signature ? cached2 : persisted?.signature === signature ? persisted : null;
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 cached2 = incrementalTailCache.get(filePath);
23452
- if (cached2) {
23453
- if (cached2.size === size && cached2.mtimeMs === mtimeMs) {
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, cached2);
23456
- if (cached2.coversWholeFile || cached2.lines.length >= needed) {
23457
- return { lines: cached2.lines, coversWholeFile: cached2.coversWholeFile };
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 > cached2.size) {
23460
- const incremental = tryIncrementalTailGrowth(filePath, cached2, size, mtimeMs, needed);
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, cached2, size, mtimeMs, needed) {
23552
+ function tryIncrementalTailGrowth(filePath, cached3, size, mtimeMs, needed) {
23487
23553
  const fd = fs6.openSync(filePath, "r");
23488
23554
  try {
23489
- if (cached2.size > 0) {
23555
+ if (cached3.size > 0) {
23490
23556
  const boundary = Buffer.alloc(1);
23491
- fs6.readSync(fd, boundary, 0, 1, cached2.size - 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 - cached2.size;
23560
+ const appendedLength = size - cached3.size;
23495
23561
  const appended = Buffer.alloc(appendedLength);
23496
- fs6.readSync(fd, appended, 0, appendedLength, cached2.size);
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 = cached2.lines.concat(newLines);
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 = cached2.coversWholeFile && trimmed.length === merged.length;
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 cached2 = readBoundedTailCache(cacheKey, signature);
23567
- if (cached2) return cached2;
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 cached2 = savedHistorySessionCache.get(sanitized);
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 (cached2) {
23616
- const cacheLooksPersisted = cached2.signature.startsWith("index:");
23617
- const cacheStillValid = cacheLooksPersisted ? cached2.signature === indexSignature : (() => {
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 cached2.signature === buildSavedHistoryCacheSignature(files2, fileSignatures2);
23686
+ return cached3.signature === buildSavedHistoryCacheSignature(files2, fileSignatures2);
23621
23687
  })();
23622
23688
  if (cacheStillValid) {
23623
- const sliced2 = cached2.summaries.slice(offset, offset + limit);
23689
+ const sliced2 = cached3.summaries.slice(offset, offset + limit);
23624
23690
  return {
23625
23691
  sessions: sliced2,
23626
- hasMore: cached2.summaries.length > offset + limit
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 = require("better-sqlite3");
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 = require("better-sqlite3");
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 cached2 = this.scriptsCache.get(dir);
40877
- if (cached2) return cached2;
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(cached2, incoming) {
43957
- if (!cached2 || typeof cached2 !== "object" || Array.isArray(cached2)) return incoming;
43958
- if (!incoming || typeof incoming !== "object" || Array.isArray(incoming)) return cached2;
43959
- const cachedNodes = Array.isArray(cached2.nodes) ? cached2.nodes : [];
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 { ...cached2, ...incoming };
43962
- const cachedUpdatedAt = Date.parse(readStringValue(cached2.updatedAt, cached2.updated_at) || "");
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
- ...cached2,
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 cached2 = this.recent.get(key);
44325
- if (cached2 && this.now() - cached2.at < this.reuseMs) {
44326
- return cached2.value;
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 cached2 = this.aggregateMeshStatusCache.get(meshId);
45975
- if (!cached2?.snapshot || cached2.snapshot.success !== true || !Array.isArray(cached2.snapshot.nodes)) return null;
45976
- if (cached2.queueRevision !== getMeshQueueRevision(meshId)) return null;
45977
- let snapshot = this.cloneJsonValue(cached2.snapshot);
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() - cached2.builtAt);
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(cached2.builtAt).toISOString(),
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 cached2 = this.inlineMeshCache.get(meshId);
46039
- if (cached2) {
46040
- const merged = reconcileInlineMeshCache(cached2, sanitizedInlineMesh);
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 cached3 = this.getCachedInlineMesh(meshId);
46051
- if (cached3) {
46151
+ const cached4 = this.getCachedInlineMesh(meshId);
46152
+ if (cached4) {
46052
46153
  if (inlineMeshCarriesTransientNodeTruth(inlineMesh)) {
46053
46154
  const merged = reconcileInlineMeshCache(
46054
- cached3,
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: cached3, inline: true, source: "inline_cache" };
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 cached2 = this.getCachedInlineMesh(meshId);
46074
- if (cached2) return { mesh: cached2, inline: true, source: "inline_cache" };
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 cached2 = repoRootBaseRef.get(repoRoot);
47505
- if (cached2) return cached2;
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" });