@adhdev/daemon-core 0.9.82-rc.495 → 0.9.82-rc.497

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.d.ts CHANGED
@@ -62,6 +62,7 @@ export type { MeshWorkQueueEntry, MeshTaskStatus, MeshTaskMode, MeshTaskPriority
62
62
  export { buildCompactStaleDirectWorkSummary, buildMeshActiveWork, buildMeshActiveWorkSummary, collectPendingApprovals, classifyStaleDirectForPrune, pruneStaleDirectDispatches, PRUNABLE_ORPHAN_STALE_REASONS } from './mesh/mesh-active-work.js';
63
63
  export type { StaleDirectPruneClassification, StaleDirectPruneResult, PruneStaleDirectDispatchesOptions } from './mesh/mesh-active-work.js';
64
64
  export type { MeshActiveWorkRecord, MeshActiveWorkStatus, MeshActiveWorkSummary, MeshActiveWorkSource, MeshStaleDirectWorkSummary, MeshPendingApproval } from './mesh/mesh-active-work.js';
65
+ export { maybeInjectIdleActiveMissionReminder, shouldFireIdleReminder, buildIdleReminderMessage, missionSetHash, IDLE_REMINDER_DEBOUNCE_MS } from './mesh/mesh-idle-reminder.js';
65
66
  export { buildMeshAsyncRefineJobs, summarizeMeshAsyncRefineJobs, STALE_TERMINAL_REFINE_WINDOW_MS, RECENT_TERMINAL_REFINE_CAP } from './mesh/mesh-refine-status.js';
66
67
  export type { MeshAsyncRefineJobStatus, MeshAsyncRefineJobSummary, MeshAsyncRefineJobsSummary } from './mesh/mesh-refine-status.js';
67
68
  export { buildMeshMagiActivity, summarizeMeshMagiActivity, getMeshMagiActivityByGroup, STALE_MAGI_WINDOW_MS, RECENT_MAGI_CAP, MAGI_NEEDS_VERIFICATION_PREVIEW_CAP } from './mesh/mesh-magi-status.js';
package/dist/index.js CHANGED
@@ -175,7 +175,10 @@ var init_repo_mesh_types = __esm({
175
175
  // auto-launched sessions are cleaned — see RepoMeshMagiSessionCleanupMode.
176
176
  magiSessionCleanup: "stop_and_delete",
177
177
  autoFastForward: { enabled: true },
178
- maxTaskRetries: 1
178
+ maxTaskRetries: 1,
179
+ // Nudge the coordinator when the mesh is fully idle but active missions linger,
180
+ // so a mission is never left drifting in `active` after its work is really done.
181
+ idleActiveMissionReminder: true
179
182
  };
180
183
  SESSION_CLEANUP_MODES = /* @__PURE__ */ new Set([
181
184
  "preserve",
@@ -414,10 +417,10 @@ function readInjected(value) {
414
417
  }
415
418
  function getDaemonBuildInfo() {
416
419
  if (cached) return cached;
417
- const commit = readInjected(true ? "47035018816052344f4c6a8b03886c363a89fe01" : void 0) ?? "unknown";
418
- const commitShort = readInjected(true ? "47035018" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
419
- const version = readInjected(true ? "0.9.82-rc.495" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
420
- const builtAt = readInjected(true ? "2026-07-11T03:38:06.794Z" : void 0);
420
+ const commit = readInjected(true ? "bafa66a406e7efc123493af30c0779646ea02c5c" : void 0) ?? "unknown";
421
+ const commitShort = readInjected(true ? "bafa66a4" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
422
+ const version = readInjected(true ? "0.9.82-rc.497" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
423
+ const builtAt = readInjected(true ? "2026-07-11T16:51:08.308Z" : void 0);
421
424
  cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
422
425
  return cached;
423
426
  }
@@ -6497,6 +6500,13 @@ var init_mesh_runtime_store = __esm({
6497
6500
  db;
6498
6501
  dbPath;
6499
6502
  migratedMeshIds = /* @__PURE__ */ new Set();
6503
+ // Idle-active-mission-reminder debounce (mesh-idle-reminder.ts). In-memory only:
6504
+ // this is a spam guard for a best-effort coordinator nudge, so a daemon restart
6505
+ // resetting it (at most one extra reminder) is harmless — no SQLite persistence
6506
+ // is warranted. Keyed by meshId; the value records when the last reminder fired
6507
+ // and the hash of the active-mission id set it named, so a changed mission set
6508
+ // re-fires before the time window elapses.
6509
+ idleReminderState = /* @__PURE__ */ new Map();
6500
6510
  fingerprintSweepCounter = 0;
6501
6511
  walWriteCounter = 0;
6502
6512
  // Independent cadence for the tool-call-log sweep. Must NOT share walWriteCounter:
@@ -8092,6 +8102,22 @@ var init_mesh_runtime_store = __esm({
8092
8102
  "UPDATE mesh_missions SET close_candidate_emitted_at = ? WHERE mesh_id = ? AND id = ?"
8093
8103
  ).run(emittedAt, meshId, missionId).changes;
8094
8104
  }
8105
+ /**
8106
+ * Read the last idle-active-mission-reminder debounce marker for a mesh, or null if
8107
+ * none has fired this process. In-memory only (see idleReminderState) — best-effort
8108
+ * spam guard for a coordinator nudge, intentionally not SQLite-backed.
8109
+ */
8110
+ getIdleReminderState(meshId) {
8111
+ return this.idleReminderState.get(meshId) ?? null;
8112
+ }
8113
+ /** Record that an idle-active-mission reminder just fired for a mesh (debounce marker). */
8114
+ setIdleReminderState(meshId, state) {
8115
+ this.idleReminderState.set(meshId, state);
8116
+ }
8117
+ /** Clear the idle-reminder debounce marker for a mesh — mesh deletion / test cleanup. */
8118
+ clearIdleReminderState(meshId) {
8119
+ this.idleReminderState.delete(meshId);
8120
+ }
8095
8121
  /** Remove all missions for a mesh — mesh deletion / test cleanup. */
8096
8122
  clearMissionsForMesh(meshId) {
8097
8123
  return this.db.prepare("DELETE FROM mesh_missions WHERE mesh_id = ?").run(meshId).changes;
@@ -12599,6 +12625,72 @@ var init_mesh_active_work = __esm({
12599
12625
  }
12600
12626
  });
12601
12627
 
12628
+ // src/mesh/mesh-idle-reminder.ts
12629
+ function missionSetHash(missions) {
12630
+ return missions.map((m) => m.id).sort().join(",");
12631
+ }
12632
+ function shouldFireIdleReminder(last, hash, now, debounceMs = IDLE_REMINDER_DEBOUNCE_MS) {
12633
+ if (!last) return true;
12634
+ if (now - last.emittedAt > debounceMs) return true;
12635
+ return hash !== last.missionSetHash;
12636
+ }
12637
+ function buildIdleReminderMessage(missions) {
12638
+ const shown = missions.slice(0, MISSION_LIST_CAP);
12639
+ const lines = shown.map((m) => `- ${m.title} (${m.id})`);
12640
+ const overflow = missions.length - shown.length;
12641
+ if (overflow > 0) lines.push(`- \u2026and ${overflow} more`);
12642
+ return `[System] Coordinator idle with ${missions.length} active mission(s):
12643
+ ${lines.join("\n")}
12644
+ The mesh has no work in flight. For each mission, decide its outcome: continue it (enqueue/dispatch the remaining work) or close it with mesh_mission_upsert(mission_id, status: "completed" | "abandoned"). Do not leave a finished mission in 'active'. This is a one-time reminder.`;
12645
+ }
12646
+ function maybeInjectIdleActiveMissionReminder(meshId, coordinator, policy, now = Date.now()) {
12647
+ try {
12648
+ if (!coordinator) return false;
12649
+ if (policy?.idleActiveMissionReminder === false) return false;
12650
+ const activeMissions = getMeshMissions(meshId, ["active"]);
12651
+ if (activeMissions.length === 0) return false;
12652
+ const summary = buildMeshActiveWork({
12653
+ meshId,
12654
+ queue: getQueue(meshId),
12655
+ directDispatches: getActiveDirectDispatches(meshId),
12656
+ ledgerEntries: readLedgerEntries(meshId, { tail: 200 }),
12657
+ now
12658
+ }).summary;
12659
+ if (summary.totalActiveCount !== 0 || summary.generatingCount !== 0) return false;
12660
+ const store = MeshRuntimeStore.getInstance();
12661
+ const hash = missionSetHash(activeMissions);
12662
+ const last = store.getIdleReminderState(meshId);
12663
+ if (!shouldFireIdleReminder(last, hash, now)) return false;
12664
+ const message = buildIdleReminderMessage(activeMissions);
12665
+ coordinator.onEvent("send_message", {
12666
+ input: { text: message, textFallback: message }
12667
+ });
12668
+ store.setIdleReminderState(meshId, { emittedAt: now, missionSetHash: hash });
12669
+ LOG.info(
12670
+ "MeshIdleReminder",
12671
+ `Injected idle reminder for mesh ${meshId} (${activeMissions.length} active mission(s), fully idle)`
12672
+ );
12673
+ return true;
12674
+ } catch (e) {
12675
+ LOG.warn("MeshIdleReminder", `maybeInjectIdleActiveMissionReminder failed for mesh ${meshId}: ${e?.message || e}`);
12676
+ return false;
12677
+ }
12678
+ }
12679
+ var IDLE_REMINDER_DEBOUNCE_MS, MISSION_LIST_CAP;
12680
+ var init_mesh_idle_reminder = __esm({
12681
+ "src/mesh/mesh-idle-reminder.ts"() {
12682
+ "use strict";
12683
+ init_logger();
12684
+ init_mesh_runtime_store();
12685
+ init_mesh_missions();
12686
+ init_mesh_work_queue();
12687
+ init_mesh_ledger();
12688
+ init_mesh_active_work();
12689
+ IDLE_REMINDER_DEBOUNCE_MS = 3e5;
12690
+ MISSION_LIST_CAP = 10;
12691
+ }
12692
+ });
12693
+
12602
12694
  // src/mesh/mesh-magi-status.ts
12603
12695
  var mesh_magi_status_exports = {};
12604
12696
  __export(mesh_magi_status_exports, {
@@ -20476,6 +20568,12 @@ function setupMeshEventForwarding(components) {
20476
20568
  ...forcePending ? { force: true } : {}
20477
20569
  });
20478
20570
  }
20571
+ } else {
20572
+ maybeInjectIdleActiveMissionReminder(
20573
+ coordinatorMeshId,
20574
+ flushSource,
20575
+ getMesh(coordinatorMeshId)?.policy
20576
+ );
20479
20577
  }
20480
20578
  } catch (e) {
20481
20579
  LOG.warn("MeshEvents", `Failed to auto-flush pending coordinator events: ${e?.message || e}`);
@@ -20535,6 +20633,7 @@ var init_mesh_event_forwarding = __esm({
20535
20633
  init_mesh_work_queue();
20536
20634
  init_mesh_delivery_policy();
20537
20635
  init_mesh_runtime_store();
20636
+ init_mesh_idle_reminder();
20538
20637
  init_mesh_events_pending();
20539
20638
  init_mesh_routing();
20540
20639
  init_mesh_host_ownership();
@@ -20869,7 +20968,7 @@ async function collectLiveNodesWithSessions(components, mesh, selfIds, localDaem
20869
20968
  let statusResult;
20870
20969
  try {
20871
20970
  if (isLocalNode) {
20872
- statusResult = await components.commandHandler.handle("get_status_metadata", {});
20971
+ statusResult = await components.router.execute("get_status_metadata", {}, "mesh");
20873
20972
  } else if (dispatchMeshCommand) {
20874
20973
  statusResult = await dispatchMeshCommand(nodeDaemonId, "get_status_metadata", {});
20875
20974
  } else {
@@ -21836,7 +21935,14 @@ async function runMeshReconcileTick(components) {
21836
21935
  }
21837
21936
  if (store) {
21838
21937
  try {
21839
- if (store.pendingEventCount(meshId) === 0) continue;
21938
+ if (store.pendingEventCount(meshId) === 0) {
21939
+ maybeInjectIdleActiveMissionReminder(
21940
+ meshId,
21941
+ targetCoordinators[0].instance,
21942
+ getMesh(meshId)?.policy
21943
+ );
21944
+ continue;
21945
+ }
21840
21946
  } catch {
21841
21947
  }
21842
21948
  }
@@ -22010,6 +22116,7 @@ var init_mesh_reconcile_loop = __esm({
22010
22116
  "use strict";
22011
22117
  init_config();
22012
22118
  init_mesh_config();
22119
+ init_mesh_idle_reminder();
22013
22120
  init_logger();
22014
22121
  init_mesh_events_pending();
22015
22122
  init_mesh_ledger();
@@ -27943,6 +28050,7 @@ __export(index_exports, {
27943
28050
  GOAL_PREVIEW_MAX: () => GOAL_PREVIEW_MAX,
27944
28051
  GitCommandError: () => GitCommandError,
27945
28052
  GitWorkspaceMonitor: () => GitWorkspaceMonitor,
28053
+ IDLE_REMINDER_DEBOUNCE_MS: () => IDLE_REMINDER_DEBOUNCE_MS,
27946
28054
  IdeProviderInstance: () => IdeProviderInstance,
27947
28055
  InMemoryGitSnapshotStore: () => InMemoryGitSnapshotStore,
27948
28056
  LOG: () => LOG,
@@ -28003,6 +28111,7 @@ __export(index_exports, {
28003
28111
  buildClaudeInteractiveToolResult: () => buildClaudeInteractiveToolResult,
28004
28112
  buildCompactStaleDirectWorkSummary: () => buildCompactStaleDirectWorkSummary,
28005
28113
  buildCoordinatorSystemPrompt: () => buildCoordinatorSystemPrompt,
28114
+ buildIdleReminderMessage: () => buildIdleReminderMessage,
28006
28115
  buildIpcStatusHttpResponse: () => buildIpcStatusHttpResponse,
28007
28116
  buildMachineInfo: () => buildMachineInfo,
28008
28117
  buildMeshActiveWork: () => buildMeshActiveWork,
@@ -28177,11 +28286,13 @@ __export(index_exports, {
28177
28286
  markSessionDeliveriesTerminal: () => markSessionDeliveriesTerminal,
28178
28287
  markSetupComplete: () => markSetupComplete,
28179
28288
  markStaleDirectDispatches: () => markStaleDirectDispatches,
28289
+ maybeInjectIdleActiveMissionReminder: () => maybeInjectIdleActiveMissionReminder,
28180
28290
  maybeRunDaemonUpgradeHelperFromEnv: () => maybeRunDaemonUpgradeHelperFromEnv,
28181
28291
  mergeAndNormalizePolicy: () => mergeAndNormalizePolicy,
28182
28292
  meshNodeIdMatches: () => meshNodeIdMatches,
28183
28293
  meshTaskNotBeforeReady: () => meshTaskNotBeforeReady,
28184
28294
  meshTaskPriorityRank: () => meshTaskPriorityRank,
28295
+ missionSetHash: () => missionSetHash,
28185
28296
  namedKeyToAnsi: () => namedKeyToAnsi,
28186
28297
  namedKeysToAnsi: () => namedKeysToAnsi,
28187
28298
  nodeSatisfiesRequiredTags: () => nodeSatisfiesRequiredTags,
@@ -28278,6 +28389,7 @@ __export(index_exports, {
28278
28389
  setupIdeInstance: () => setupIdeInstance,
28279
28390
  shouldAutoRestoreHostedSessionsOnStartup: () => shouldAutoRestoreHostedSessionsOnStartup,
28280
28391
  shouldCollectTraceCategory: () => shouldCollectTraceCategory,
28392
+ shouldFireIdleReminder: () => shouldFireIdleReminder,
28281
28393
  shutdownDaemonComponents: () => shutdownDaemonComponents,
28282
28394
  spawnDetachedDaemonUpgradeHelper: () => spawnDetachedDaemonUpgradeHelper,
28283
28395
  startDaemonDevSupport: () => startDaemonDevSupport,
@@ -29677,6 +29789,7 @@ function buildMeshLedgerReconciliationEvidence(meshId, replicas) {
29677
29789
  // src/index.ts
29678
29790
  init_mesh_work_queue();
29679
29791
  init_mesh_active_work();
29792
+ init_mesh_idle_reminder();
29680
29793
  init_mesh_refine_status();
29681
29794
  init_mesh_magi_status();
29682
29795
  init_mesh_scheduling_runtime();
@@ -70763,6 +70876,7 @@ var V1_CONTRACT_VERSION = "1.0.0";
70763
70876
  GOAL_PREVIEW_MAX,
70764
70877
  GitCommandError,
70765
70878
  GitWorkspaceMonitor,
70879
+ IDLE_REMINDER_DEBOUNCE_MS,
70766
70880
  IdeProviderInstance,
70767
70881
  InMemoryGitSnapshotStore,
70768
70882
  LOG,
@@ -70823,6 +70937,7 @@ var V1_CONTRACT_VERSION = "1.0.0";
70823
70937
  buildClaudeInteractiveToolResult,
70824
70938
  buildCompactStaleDirectWorkSummary,
70825
70939
  buildCoordinatorSystemPrompt,
70940
+ buildIdleReminderMessage,
70826
70941
  buildIpcStatusHttpResponse,
70827
70942
  buildMachineInfo,
70828
70943
  buildMeshActiveWork,
@@ -70997,11 +71112,13 @@ var V1_CONTRACT_VERSION = "1.0.0";
70997
71112
  markSessionDeliveriesTerminal,
70998
71113
  markSetupComplete,
70999
71114
  markStaleDirectDispatches,
71115
+ maybeInjectIdleActiveMissionReminder,
71000
71116
  maybeRunDaemonUpgradeHelperFromEnv,
71001
71117
  mergeAndNormalizePolicy,
71002
71118
  meshNodeIdMatches,
71003
71119
  meshTaskNotBeforeReady,
71004
71120
  meshTaskPriorityRank,
71121
+ missionSetHash,
71005
71122
  namedKeyToAnsi,
71006
71123
  namedKeysToAnsi,
71007
71124
  nodeSatisfiesRequiredTags,
@@ -71098,6 +71215,7 @@ var V1_CONTRACT_VERSION = "1.0.0";
71098
71215
  setupIdeInstance,
71099
71216
  shouldAutoRestoreHostedSessionsOnStartup,
71100
71217
  shouldCollectTraceCategory,
71218
+ shouldFireIdleReminder,
71101
71219
  shutdownDaemonComponents,
71102
71220
  spawnDetachedDaemonUpgradeHelper,
71103
71221
  startDaemonDevSupport,