@adhdev/daemon-core 0.9.77-rc.47 → 0.9.77-rc.49

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
@@ -31,8 +31,10 @@ export { buildCoordinatorSystemPrompt } from './mesh/coordinator-prompt.js';
31
31
  export type { CoordinatorPromptContext } from './mesh/coordinator-prompt.js';
32
32
  export { syncMeshes } from './mesh/mesh-sync.js';
33
33
  export type { MeshSyncTransport, MeshSyncResult, RemoteMeshRecord } from './mesh/mesh-sync.js';
34
- export { appendLedgerEntry, readLedgerEntries, getLedgerSummary, getLedgerDir, getSessionRecoveryContext } from './mesh/mesh-ledger.js';
35
- export type { MeshLedgerEntry, MeshLedgerKind, MeshLedgerSummary, ReadLedgerOptions, SessionRecoveryContext } from './mesh/mesh-ledger.js';
34
+ export { appendLedgerEntry, appendRemoteLedgerEntries, readLedgerEntries, readLedgerSlice, getLedgerSummary, getLedgerDir, getSessionRecoveryContext, MAX_LEDGER_SLICE_LIMIT } from './mesh/mesh-ledger.js';
35
+ export type { AppendRemoteLedgerResult, MeshLedgerEntry, MeshLedgerKind, MeshLedgerSlice, MeshLedgerSummary, ReadLedgerOptions, ReadLedgerSliceOptions, SessionRecoveryContext } from './mesh/mesh-ledger.js';
36
+ export { buildMeshLedgerReconciliationEvidence, buildMeshLedgerReplicaEvidence } from './mesh/mesh-ledger-reconciliation.js';
37
+ export type { MeshLedgerReconciliationEvidence, MeshLedgerReplicaEvidence, MeshLedgerReplicaStatus } from './mesh/mesh-ledger-reconciliation.js';
36
38
  export { enqueueTask, getQueue, claimNextTask, updateTaskStatus, updateSessionTaskStatus, cancelTask, requeueTask, getMeshQueueStats } from './mesh/mesh-work-queue.js';
37
39
  export type { MeshWorkQueueEntry, MeshTaskStatus, MeshWorkQueueStats } from './mesh/mesh-work-queue.js';
38
40
  export { triggerMeshQueue } from './mesh/mesh-events.js';
package/dist/index.js CHANGED
@@ -795,13 +795,15 @@ Follow these recovery rules:
795
795
  // src/mesh/mesh-ledger.ts
796
796
  var mesh_ledger_exports = {};
797
797
  __export(mesh_ledger_exports, {
798
+ MAX_LEDGER_SLICE_LIMIT: () => MAX_LEDGER_SLICE_LIMIT,
798
799
  appendLedgerEntry: () => appendLedgerEntry,
799
800
  appendRemoteLedgerEntries: () => appendRemoteLedgerEntries,
800
801
  getLedgerDir: () => getLedgerDir,
801
802
  getLedgerSummary: () => getLedgerSummary,
802
803
  getSessionRecoveryContext: () => getSessionRecoveryContext,
803
804
  meshLedgerEvents: () => meshLedgerEvents,
804
- readLedgerEntries: () => readLedgerEntries
805
+ readLedgerEntries: () => readLedgerEntries,
806
+ readLedgerSlice: () => readLedgerSlice
805
807
  });
806
808
  function getLedgerDir() {
807
809
  const dir = (0, import_path3.join)(getConfigDir(), LEDGER_DIR_NAME);
@@ -844,15 +846,49 @@ function appendLedgerEntry(meshId, partial) {
844
846
  throw new Error(`Failed to append to ledger for mesh ${meshId}: ${e.message}`);
845
847
  }
846
848
  }
849
+ function clampLedgerSliceLimit(limit) {
850
+ if (typeof limit !== "number" || !Number.isFinite(limit)) return DEFAULT_LEDGER_SLICE_LIMIT;
851
+ return Math.max(1, Math.min(MAX_LEDGER_SLICE_LIMIT, Math.floor(limit)));
852
+ }
853
+ function isValidRemoteLedgerEntry(meshId, value) {
854
+ if (!value || typeof value !== "object" || Array.isArray(value)) return false;
855
+ const entry = value;
856
+ if (typeof entry.id !== "string" || !entry.id.trim()) return false;
857
+ if (entry.meshId !== meshId) return false;
858
+ if (typeof entry.timestamp !== "string" || Number.isNaN(new Date(entry.timestamp).getTime())) return false;
859
+ if (typeof entry.kind !== "string" || !entry.kind.trim()) return false;
860
+ if (!entry.payload || typeof entry.payload !== "object" || Array.isArray(entry.payload)) return false;
861
+ return true;
862
+ }
847
863
  function appendRemoteLedgerEntries(meshId, entries) {
848
- if (entries.length === 0) return;
864
+ if (entries.length === 0) return { accepted: 0, skippedDuplicate: 0, rejectedInvalid: 0, entries: [] };
849
865
  const ledgerPath = getLedgerPath(meshId);
850
866
  const existing = new Set(readLedgerEntries(meshId).map((e) => e.id));
851
- const newEntries = entries.filter((e) => !existing.has(e.id));
852
- if (newEntries.length === 0) return;
867
+ const validEntries = [];
868
+ let rejectedInvalid = 0;
869
+ let skippedDuplicate = 0;
870
+ for (const entry of entries) {
871
+ if (!isValidRemoteLedgerEntry(meshId, entry)) {
872
+ rejectedInvalid++;
873
+ continue;
874
+ }
875
+ if (existing.has(entry.id)) {
876
+ skippedDuplicate++;
877
+ continue;
878
+ }
879
+ existing.add(entry.id);
880
+ validEntries.push(entry);
881
+ }
882
+ if (validEntries.length === 0) {
883
+ return { accepted: 0, skippedDuplicate, rejectedInvalid, entries: [] };
884
+ }
853
885
  try {
854
- const lines = newEntries.map((e) => JSON.stringify(e)).join("\n") + "\n";
886
+ const lines = validEntries.map((e) => JSON.stringify(e)).join("\n") + "\n";
855
887
  (0, import_fs3.appendFileSync)(ledgerPath, lines, { encoding: "utf-8", mode: 384 });
888
+ for (const entry of validEntries) {
889
+ meshLedgerEvents.emit("append", meshId, entry);
890
+ }
891
+ return { accepted: validEntries.length, skippedDuplicate, rejectedInvalid, entries: validEntries };
856
892
  } catch (e) {
857
893
  throw new Error(`Failed to append remote ledger entries for mesh ${meshId}: ${e.message}`);
858
894
  }
@@ -891,6 +927,34 @@ function readLedgerEntries(meshId, opts) {
891
927
  }
892
928
  return entries;
893
929
  }
930
+ function readLedgerSlice(meshId, opts) {
931
+ const limit = clampLedgerSliceLimit(opts?.limit);
932
+ let entries = readLedgerEntries(meshId, { since: opts?.since, kind: opts?.kind });
933
+ const afterId = typeof opts?.afterId === "string" && opts.afterId.trim() ? opts.afterId.trim() : null;
934
+ if (afterId) {
935
+ const index = entries.findIndex((entry) => entry.id === afterId);
936
+ entries = index >= 0 ? entries.slice(index + 1) : entries;
937
+ }
938
+ const bounded = entries.slice(0, limit);
939
+ return {
940
+ protocol: "adhdev.mesh.ledger.slice.v1",
941
+ meshId,
942
+ entries: bounded,
943
+ cursor: {
944
+ afterId,
945
+ nextAfterId: bounded.length ? bounded[bounded.length - 1].id : afterId,
946
+ limit,
947
+ hasMore: entries.length > bounded.length
948
+ },
949
+ summary: getLedgerSummary(meshId),
950
+ sourceOfTruth: {
951
+ kind: "local_jsonl",
952
+ path: getLedgerPath(meshId),
953
+ bounded: true,
954
+ maxLimit: MAX_LEDGER_SLICE_LIMIT
955
+ }
956
+ };
957
+ }
894
958
  function getLedgerSummary(meshId) {
895
959
  const entries = readLedgerEntries(meshId);
896
960
  const now = Date.now();
@@ -1013,7 +1077,7 @@ function rotateLedgerFile(meshId, currentPath) {
1013
1077
  } catch {
1014
1078
  }
1015
1079
  }
1016
- var import_fs3, import_path3, import_crypto4, import_events, LEDGER_DIR_NAME, MAX_FILE_SIZE_BYTES, RECENT_FAILURE_WINDOW_MS, meshLedgerEvents;
1080
+ var import_fs3, import_path3, import_crypto4, import_events, LEDGER_DIR_NAME, MAX_FILE_SIZE_BYTES, RECENT_FAILURE_WINDOW_MS, DEFAULT_LEDGER_SLICE_LIMIT, MAX_LEDGER_SLICE_LIMIT, meshLedgerEvents;
1017
1081
  var init_mesh_ledger = __esm({
1018
1082
  "src/mesh/mesh-ledger.ts"() {
1019
1083
  "use strict";
@@ -1025,6 +1089,8 @@ var init_mesh_ledger = __esm({
1025
1089
  LEDGER_DIR_NAME = "mesh-ledger";
1026
1090
  MAX_FILE_SIZE_BYTES = 10 * 1024 * 1024;
1027
1091
  RECENT_FAILURE_WINDOW_MS = 30 * 60 * 1e3;
1092
+ DEFAULT_LEDGER_SLICE_LIMIT = 100;
1093
+ MAX_LEDGER_SLICE_LIMIT = 500;
1028
1094
  meshLedgerEvents = new import_events.EventEmitter();
1029
1095
  }
1030
1096
  });
@@ -5318,6 +5384,7 @@ __export(index_exports, {
5318
5384
  IdeProviderInstance: () => IdeProviderInstance,
5319
5385
  InMemoryGitSnapshotStore: () => InMemoryGitSnapshotStore,
5320
5386
  LOG: () => LOG,
5387
+ MAX_LEDGER_SLICE_LIMIT: () => MAX_LEDGER_SLICE_LIMIT,
5321
5388
  MIN_GIT_WORKSPACE_POLL_INTERVAL_MS: () => MIN_GIT_WORKSPACE_POLL_INTERVAL_MS,
5322
5389
  MIN_MACHINE_RUNTIME_SUBSCRIPTION_INTERVAL_MS: () => MIN_MACHINE_RUNTIME_SUBSCRIPTION_INTERVAL_MS,
5323
5390
  MIN_SESSION_HOST_DIAGNOSTICS_SUBSCRIPTION_INTERVAL_MS: () => MIN_SESSION_HOST_DIAGNOSTICS_SUBSCRIPTION_INTERVAL_MS,
@@ -5333,12 +5400,15 @@ __export(index_exports, {
5333
5400
  addNode: () => addNode,
5334
5401
  appendLedgerEntry: () => appendLedgerEntry,
5335
5402
  appendRecentActivity: () => appendRecentActivity,
5403
+ appendRemoteLedgerEntries: () => appendRemoteLedgerEntries,
5336
5404
  buildAssistantChatMessage: () => buildAssistantChatMessage,
5337
5405
  buildChatMessage: () => buildChatMessage,
5338
5406
  buildChatMessageSignature: () => buildChatMessageSignature,
5339
5407
  buildChatTailDeliverySignature: () => buildChatTailDeliverySignature,
5340
5408
  buildCoordinatorSystemPrompt: () => buildCoordinatorSystemPrompt,
5341
5409
  buildMachineInfo: () => buildMachineInfo,
5410
+ buildMeshLedgerReconciliationEvidence: () => buildMeshLedgerReconciliationEvidence,
5411
+ buildMeshLedgerReplicaEvidence: () => buildMeshLedgerReplicaEvidence,
5342
5412
  buildP2pRelayFailurePayload: () => buildP2pRelayFailurePayload,
5343
5413
  buildPinnedGlobalInstallCommand: () => buildPinnedGlobalInstallCommand,
5344
5414
  buildRuntimeSystemChatMessage: () => buildRuntimeSystemChatMessage,
@@ -5461,6 +5531,7 @@ __export(index_exports, {
5461
5531
  probeCdpPort: () => probeCdpPort,
5462
5532
  readChatHistory: () => readChatHistory,
5463
5533
  readLedgerEntries: () => readLedgerEntries,
5534
+ readLedgerSlice: () => readLedgerSlice,
5464
5535
  recordDebugTrace: () => recordDebugTrace,
5465
5536
  registerExtensionProviders: () => registerExtensionProviders,
5466
5537
  removeNode: () => removeNode,
@@ -7362,29 +7433,71 @@ async function syncMeshes(transport) {
7362
7433
  }
7363
7434
  }
7364
7435
  }
7365
- if (transport.syncMeshLedger) {
7366
- for (const local of localMeshes) {
7367
- try {
7368
- await syncMeshLedger(local.id, transport);
7369
- } catch (e) {
7370
- result.errors.push(`Ledger sync failed for "${local.name}": ${e.message}`);
7371
- }
7372
- }
7373
- }
7374
7436
  return result;
7375
7437
  }
7376
- async function syncMeshLedger(meshId, transport) {
7377
- if (!transport.syncMeshLedger) return;
7378
- const { readLedgerEntries: readLedgerEntries2, appendRemoteLedgerEntries: appendRemoteLedgerEntries2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
7379
- const localEntries = readLedgerEntries2(meshId);
7380
- const res = await transport.syncMeshLedger(meshId, { newEntries: localEntries });
7381
- if (res.missingEntries && res.missingEntries.length > 0) {
7382
- appendRemoteLedgerEntries2(meshId, res.missingEntries);
7383
- }
7384
- }
7385
7438
 
7386
7439
  // src/index.ts
7387
7440
  init_mesh_ledger();
7441
+
7442
+ // src/mesh/mesh-ledger-reconciliation.ts
7443
+ function lastTimestamp(slice) {
7444
+ const entries = Array.isArray(slice?.entries) ? slice.entries : [];
7445
+ return entries.length ? entries[entries.length - 1].timestamp : null;
7446
+ }
7447
+ function buildMeshLedgerReplicaEvidence(args) {
7448
+ const entriesReceived = Array.isArray(args.slice?.entries) ? args.slice.entries.length : 0;
7449
+ return {
7450
+ nodeId: args.nodeId,
7451
+ ...args.daemonId ? { daemonId: args.daemonId } : {},
7452
+ status: args.status ?? (args.importResult && args.importResult.accepted > 0 ? "imported" : "queried"),
7453
+ transport: args.transport,
7454
+ protocol: "adhdev.mesh.ledger.slice.v1",
7455
+ entriesReceived,
7456
+ entriesImported: args.importResult?.accepted ?? 0,
7457
+ skippedDuplicate: args.importResult?.skippedDuplicate ?? 0,
7458
+ rejectedInvalid: args.importResult?.rejectedInvalid ?? 0,
7459
+ hasMore: args.slice?.cursor?.hasMore === true,
7460
+ nextAfterId: args.slice?.cursor?.nextAfterId ?? null,
7461
+ lastTimestamp: lastTimestamp(args.slice),
7462
+ ...args.slice?.summary ? { summary: args.slice.summary } : {},
7463
+ ...args.error ? {
7464
+ error: args.error,
7465
+ noFallbackReason: "Ledger reconciliation is P2P/local-first only; Cloud/D1 ledger sync is intentionally disabled."
7466
+ } : {}
7467
+ };
7468
+ }
7469
+ function buildMeshLedgerReconciliationEvidence(meshId, replicas) {
7470
+ const failedNodes = replicas.filter((replica) => replica.status === "failed").map((replica) => replica.nodeId);
7471
+ const pendingNodes = replicas.filter((replica) => replica.hasMore && replica.status !== "failed").map((replica) => replica.nodeId);
7472
+ return {
7473
+ protocol: "adhdev.mesh.ledger.reconciliation.v1",
7474
+ meshId,
7475
+ generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
7476
+ sourceOfTruth: {
7477
+ kind: "coordinator_local_jsonl",
7478
+ p2pOnly: true,
7479
+ cloudD1LedgerSync: false,
7480
+ notes: "Coordinator reconciles bounded slices from daemon-local JSONL ledgers over P2P DataChannel; Cloud/D1 is not a ledger source of truth."
7481
+ },
7482
+ replicas,
7483
+ totals: {
7484
+ replicas: replicas.length,
7485
+ queried: replicas.filter((replica) => replica.status !== "failed").length,
7486
+ failed: failedNodes.length,
7487
+ entriesReceived: replicas.reduce((sum, replica) => sum + replica.entriesReceived, 0),
7488
+ entriesImported: replicas.reduce((sum, replica) => sum + replica.entriesImported, 0),
7489
+ skippedDuplicate: replicas.reduce((sum, replica) => sum + replica.skippedDuplicate, 0),
7490
+ rejectedInvalid: replicas.reduce((sum, replica) => sum + replica.rejectedInvalid, 0)
7491
+ },
7492
+ convergence: {
7493
+ complete: failedNodes.length === 0 && pendingNodes.length === 0,
7494
+ pendingNodes,
7495
+ failedNodes
7496
+ }
7497
+ };
7498
+ }
7499
+
7500
+ // src/index.ts
7388
7501
  init_mesh_work_queue();
7389
7502
  init_mesh_events();
7390
7503
 
@@ -24918,6 +25031,35 @@ var DaemonCommandRouter = class {
24918
25031
  return { success: false, error: e.message };
24919
25032
  }
24920
25033
  }
25034
+ case "get_mesh_ledger_slice": {
25035
+ const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
25036
+ if (!meshId) return { success: false, error: "meshId required" };
25037
+ try {
25038
+ const { readLedgerSlice: readLedgerSlice2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
25039
+ const kind = Array.isArray(args?.kind) ? args.kind.filter((k) => typeof k === "string") : void 0;
25040
+ const slice = readLedgerSlice2(meshId, {
25041
+ afterId: typeof args?.afterId === "string" ? args.afterId : void 0,
25042
+ since: typeof args?.since === "string" ? args.since : void 0,
25043
+ kind,
25044
+ limit: typeof args?.limit === "number" ? args.limit : void 0
25045
+ });
25046
+ return { success: true, slice };
25047
+ } catch (e) {
25048
+ return { success: false, error: e.message };
25049
+ }
25050
+ }
25051
+ case "import_mesh_ledger_slice": {
25052
+ const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
25053
+ if (!meshId) return { success: false, error: "meshId required" };
25054
+ try {
25055
+ const { appendRemoteLedgerEntries: appendRemoteLedgerEntries2, getLedgerSummary: getLedgerSummary2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
25056
+ const entries = Array.isArray(args?.entries) ? args.entries : Array.isArray(args?.slice?.entries) ? args.slice.entries : [];
25057
+ const result = appendRemoteLedgerEntries2(meshId, entries);
25058
+ return { success: true, result, summary: getLedgerSummary2(meshId) };
25059
+ } catch (e) {
25060
+ return { success: false, error: e.message };
25061
+ }
25062
+ }
24921
25063
  case "get_mesh_queue": {
24922
25064
  const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
24923
25065
  if (!meshId) return { success: false, error: "meshId required" };
@@ -33678,6 +33820,7 @@ async function shutdownDaemonComponents(components) {
33678
33820
  IdeProviderInstance,
33679
33821
  InMemoryGitSnapshotStore,
33680
33822
  LOG,
33823
+ MAX_LEDGER_SLICE_LIMIT,
33681
33824
  MIN_GIT_WORKSPACE_POLL_INTERVAL_MS,
33682
33825
  MIN_MACHINE_RUNTIME_SUBSCRIPTION_INTERVAL_MS,
33683
33826
  MIN_SESSION_HOST_DIAGNOSTICS_SUBSCRIPTION_INTERVAL_MS,
@@ -33693,12 +33836,15 @@ async function shutdownDaemonComponents(components) {
33693
33836
  addNode,
33694
33837
  appendLedgerEntry,
33695
33838
  appendRecentActivity,
33839
+ appendRemoteLedgerEntries,
33696
33840
  buildAssistantChatMessage,
33697
33841
  buildChatMessage,
33698
33842
  buildChatMessageSignature,
33699
33843
  buildChatTailDeliverySignature,
33700
33844
  buildCoordinatorSystemPrompt,
33701
33845
  buildMachineInfo,
33846
+ buildMeshLedgerReconciliationEvidence,
33847
+ buildMeshLedgerReplicaEvidence,
33702
33848
  buildP2pRelayFailurePayload,
33703
33849
  buildPinnedGlobalInstallCommand,
33704
33850
  buildRuntimeSystemChatMessage,
@@ -33821,6 +33967,7 @@ async function shutdownDaemonComponents(components) {
33821
33967
  probeCdpPort,
33822
33968
  readChatHistory,
33823
33969
  readLedgerEntries,
33970
+ readLedgerSlice,
33824
33971
  recordDebugTrace,
33825
33972
  registerExtensionProviders,
33826
33973
  removeNode,