@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.mjs CHANGED
@@ -790,13 +790,15 @@ Follow these recovery rules:
790
790
  // src/mesh/mesh-ledger.ts
791
791
  var mesh_ledger_exports = {};
792
792
  __export(mesh_ledger_exports, {
793
+ MAX_LEDGER_SLICE_LIMIT: () => MAX_LEDGER_SLICE_LIMIT,
793
794
  appendLedgerEntry: () => appendLedgerEntry,
794
795
  appendRemoteLedgerEntries: () => appendRemoteLedgerEntries,
795
796
  getLedgerDir: () => getLedgerDir,
796
797
  getLedgerSummary: () => getLedgerSummary,
797
798
  getSessionRecoveryContext: () => getSessionRecoveryContext,
798
799
  meshLedgerEvents: () => meshLedgerEvents,
799
- readLedgerEntries: () => readLedgerEntries
800
+ readLedgerEntries: () => readLedgerEntries,
801
+ readLedgerSlice: () => readLedgerSlice
800
802
  });
801
803
  import { existsSync as existsSync5, mkdirSync as mkdirSync3, readFileSync as readFileSync3, appendFileSync, statSync as statSync2, renameSync } from "fs";
802
804
  import { join as join5 } from "path";
@@ -843,15 +845,49 @@ function appendLedgerEntry(meshId, partial) {
843
845
  throw new Error(`Failed to append to ledger for mesh ${meshId}: ${e.message}`);
844
846
  }
845
847
  }
848
+ function clampLedgerSliceLimit(limit) {
849
+ if (typeof limit !== "number" || !Number.isFinite(limit)) return DEFAULT_LEDGER_SLICE_LIMIT;
850
+ return Math.max(1, Math.min(MAX_LEDGER_SLICE_LIMIT, Math.floor(limit)));
851
+ }
852
+ function isValidRemoteLedgerEntry(meshId, value) {
853
+ if (!value || typeof value !== "object" || Array.isArray(value)) return false;
854
+ const entry = value;
855
+ if (typeof entry.id !== "string" || !entry.id.trim()) return false;
856
+ if (entry.meshId !== meshId) return false;
857
+ if (typeof entry.timestamp !== "string" || Number.isNaN(new Date(entry.timestamp).getTime())) return false;
858
+ if (typeof entry.kind !== "string" || !entry.kind.trim()) return false;
859
+ if (!entry.payload || typeof entry.payload !== "object" || Array.isArray(entry.payload)) return false;
860
+ return true;
861
+ }
846
862
  function appendRemoteLedgerEntries(meshId, entries) {
847
- if (entries.length === 0) return;
863
+ if (entries.length === 0) return { accepted: 0, skippedDuplicate: 0, rejectedInvalid: 0, entries: [] };
848
864
  const ledgerPath = getLedgerPath(meshId);
849
865
  const existing = new Set(readLedgerEntries(meshId).map((e) => e.id));
850
- const newEntries = entries.filter((e) => !existing.has(e.id));
851
- if (newEntries.length === 0) return;
866
+ const validEntries = [];
867
+ let rejectedInvalid = 0;
868
+ let skippedDuplicate = 0;
869
+ for (const entry of entries) {
870
+ if (!isValidRemoteLedgerEntry(meshId, entry)) {
871
+ rejectedInvalid++;
872
+ continue;
873
+ }
874
+ if (existing.has(entry.id)) {
875
+ skippedDuplicate++;
876
+ continue;
877
+ }
878
+ existing.add(entry.id);
879
+ validEntries.push(entry);
880
+ }
881
+ if (validEntries.length === 0) {
882
+ return { accepted: 0, skippedDuplicate, rejectedInvalid, entries: [] };
883
+ }
852
884
  try {
853
- const lines = newEntries.map((e) => JSON.stringify(e)).join("\n") + "\n";
885
+ const lines = validEntries.map((e) => JSON.stringify(e)).join("\n") + "\n";
854
886
  appendFileSync(ledgerPath, lines, { encoding: "utf-8", mode: 384 });
887
+ for (const entry of validEntries) {
888
+ meshLedgerEvents.emit("append", meshId, entry);
889
+ }
890
+ return { accepted: validEntries.length, skippedDuplicate, rejectedInvalid, entries: validEntries };
855
891
  } catch (e) {
856
892
  throw new Error(`Failed to append remote ledger entries for mesh ${meshId}: ${e.message}`);
857
893
  }
@@ -890,6 +926,34 @@ function readLedgerEntries(meshId, opts) {
890
926
  }
891
927
  return entries;
892
928
  }
929
+ function readLedgerSlice(meshId, opts) {
930
+ const limit = clampLedgerSliceLimit(opts?.limit);
931
+ let entries = readLedgerEntries(meshId, { since: opts?.since, kind: opts?.kind });
932
+ const afterId = typeof opts?.afterId === "string" && opts.afterId.trim() ? opts.afterId.trim() : null;
933
+ if (afterId) {
934
+ const index = entries.findIndex((entry) => entry.id === afterId);
935
+ entries = index >= 0 ? entries.slice(index + 1) : entries;
936
+ }
937
+ const bounded = entries.slice(0, limit);
938
+ return {
939
+ protocol: "adhdev.mesh.ledger.slice.v1",
940
+ meshId,
941
+ entries: bounded,
942
+ cursor: {
943
+ afterId,
944
+ nextAfterId: bounded.length ? bounded[bounded.length - 1].id : afterId,
945
+ limit,
946
+ hasMore: entries.length > bounded.length
947
+ },
948
+ summary: getLedgerSummary(meshId),
949
+ sourceOfTruth: {
950
+ kind: "local_jsonl",
951
+ path: getLedgerPath(meshId),
952
+ bounded: true,
953
+ maxLimit: MAX_LEDGER_SLICE_LIMIT
954
+ }
955
+ };
956
+ }
893
957
  function getLedgerSummary(meshId) {
894
958
  const entries = readLedgerEntries(meshId);
895
959
  const now = Date.now();
@@ -1012,7 +1076,7 @@ function rotateLedgerFile(meshId, currentPath) {
1012
1076
  } catch {
1013
1077
  }
1014
1078
  }
1015
- var LEDGER_DIR_NAME, MAX_FILE_SIZE_BYTES, RECENT_FAILURE_WINDOW_MS, meshLedgerEvents;
1079
+ var LEDGER_DIR_NAME, MAX_FILE_SIZE_BYTES, RECENT_FAILURE_WINDOW_MS, DEFAULT_LEDGER_SLICE_LIMIT, MAX_LEDGER_SLICE_LIMIT, meshLedgerEvents;
1016
1080
  var init_mesh_ledger = __esm({
1017
1081
  "src/mesh/mesh-ledger.ts"() {
1018
1082
  "use strict";
@@ -1020,6 +1084,8 @@ var init_mesh_ledger = __esm({
1020
1084
  LEDGER_DIR_NAME = "mesh-ledger";
1021
1085
  MAX_FILE_SIZE_BYTES = 10 * 1024 * 1024;
1022
1086
  RECENT_FAILURE_WINDOW_MS = 30 * 60 * 1e3;
1087
+ DEFAULT_LEDGER_SLICE_LIMIT = 100;
1088
+ MAX_LEDGER_SLICE_LIMIT = 500;
1023
1089
  meshLedgerEvents = new EventEmitter();
1024
1090
  }
1025
1091
  });
@@ -7133,29 +7199,71 @@ async function syncMeshes(transport) {
7133
7199
  }
7134
7200
  }
7135
7201
  }
7136
- if (transport.syncMeshLedger) {
7137
- for (const local of localMeshes) {
7138
- try {
7139
- await syncMeshLedger(local.id, transport);
7140
- } catch (e) {
7141
- result.errors.push(`Ledger sync failed for "${local.name}": ${e.message}`);
7142
- }
7143
- }
7144
- }
7145
7202
  return result;
7146
7203
  }
7147
- async function syncMeshLedger(meshId, transport) {
7148
- if (!transport.syncMeshLedger) return;
7149
- const { readLedgerEntries: readLedgerEntries2, appendRemoteLedgerEntries: appendRemoteLedgerEntries2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
7150
- const localEntries = readLedgerEntries2(meshId);
7151
- const res = await transport.syncMeshLedger(meshId, { newEntries: localEntries });
7152
- if (res.missingEntries && res.missingEntries.length > 0) {
7153
- appendRemoteLedgerEntries2(meshId, res.missingEntries);
7154
- }
7155
- }
7156
7204
 
7157
7205
  // src/index.ts
7158
7206
  init_mesh_ledger();
7207
+
7208
+ // src/mesh/mesh-ledger-reconciliation.ts
7209
+ function lastTimestamp(slice) {
7210
+ const entries = Array.isArray(slice?.entries) ? slice.entries : [];
7211
+ return entries.length ? entries[entries.length - 1].timestamp : null;
7212
+ }
7213
+ function buildMeshLedgerReplicaEvidence(args) {
7214
+ const entriesReceived = Array.isArray(args.slice?.entries) ? args.slice.entries.length : 0;
7215
+ return {
7216
+ nodeId: args.nodeId,
7217
+ ...args.daemonId ? { daemonId: args.daemonId } : {},
7218
+ status: args.status ?? (args.importResult && args.importResult.accepted > 0 ? "imported" : "queried"),
7219
+ transport: args.transport,
7220
+ protocol: "adhdev.mesh.ledger.slice.v1",
7221
+ entriesReceived,
7222
+ entriesImported: args.importResult?.accepted ?? 0,
7223
+ skippedDuplicate: args.importResult?.skippedDuplicate ?? 0,
7224
+ rejectedInvalid: args.importResult?.rejectedInvalid ?? 0,
7225
+ hasMore: args.slice?.cursor?.hasMore === true,
7226
+ nextAfterId: args.slice?.cursor?.nextAfterId ?? null,
7227
+ lastTimestamp: lastTimestamp(args.slice),
7228
+ ...args.slice?.summary ? { summary: args.slice.summary } : {},
7229
+ ...args.error ? {
7230
+ error: args.error,
7231
+ noFallbackReason: "Ledger reconciliation is P2P/local-first only; Cloud/D1 ledger sync is intentionally disabled."
7232
+ } : {}
7233
+ };
7234
+ }
7235
+ function buildMeshLedgerReconciliationEvidence(meshId, replicas) {
7236
+ const failedNodes = replicas.filter((replica) => replica.status === "failed").map((replica) => replica.nodeId);
7237
+ const pendingNodes = replicas.filter((replica) => replica.hasMore && replica.status !== "failed").map((replica) => replica.nodeId);
7238
+ return {
7239
+ protocol: "adhdev.mesh.ledger.reconciliation.v1",
7240
+ meshId,
7241
+ generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
7242
+ sourceOfTruth: {
7243
+ kind: "coordinator_local_jsonl",
7244
+ p2pOnly: true,
7245
+ cloudD1LedgerSync: false,
7246
+ notes: "Coordinator reconciles bounded slices from daemon-local JSONL ledgers over P2P DataChannel; Cloud/D1 is not a ledger source of truth."
7247
+ },
7248
+ replicas,
7249
+ totals: {
7250
+ replicas: replicas.length,
7251
+ queried: replicas.filter((replica) => replica.status !== "failed").length,
7252
+ failed: failedNodes.length,
7253
+ entriesReceived: replicas.reduce((sum, replica) => sum + replica.entriesReceived, 0),
7254
+ entriesImported: replicas.reduce((sum, replica) => sum + replica.entriesImported, 0),
7255
+ skippedDuplicate: replicas.reduce((sum, replica) => sum + replica.skippedDuplicate, 0),
7256
+ rejectedInvalid: replicas.reduce((sum, replica) => sum + replica.rejectedInvalid, 0)
7257
+ },
7258
+ convergence: {
7259
+ complete: failedNodes.length === 0 && pendingNodes.length === 0,
7260
+ pendingNodes,
7261
+ failedNodes
7262
+ }
7263
+ };
7264
+ }
7265
+
7266
+ // src/index.ts
7159
7267
  init_mesh_work_queue();
7160
7268
  init_mesh_events();
7161
7269
 
@@ -24694,6 +24802,35 @@ var DaemonCommandRouter = class {
24694
24802
  return { success: false, error: e.message };
24695
24803
  }
24696
24804
  }
24805
+ case "get_mesh_ledger_slice": {
24806
+ const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
24807
+ if (!meshId) return { success: false, error: "meshId required" };
24808
+ try {
24809
+ const { readLedgerSlice: readLedgerSlice2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
24810
+ const kind = Array.isArray(args?.kind) ? args.kind.filter((k) => typeof k === "string") : void 0;
24811
+ const slice = readLedgerSlice2(meshId, {
24812
+ afterId: typeof args?.afterId === "string" ? args.afterId : void 0,
24813
+ since: typeof args?.since === "string" ? args.since : void 0,
24814
+ kind,
24815
+ limit: typeof args?.limit === "number" ? args.limit : void 0
24816
+ });
24817
+ return { success: true, slice };
24818
+ } catch (e) {
24819
+ return { success: false, error: e.message };
24820
+ }
24821
+ }
24822
+ case "import_mesh_ledger_slice": {
24823
+ const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
24824
+ if (!meshId) return { success: false, error: "meshId required" };
24825
+ try {
24826
+ const { appendRemoteLedgerEntries: appendRemoteLedgerEntries2, getLedgerSummary: getLedgerSummary2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
24827
+ const entries = Array.isArray(args?.entries) ? args.entries : Array.isArray(args?.slice?.entries) ? args.slice.entries : [];
24828
+ const result = appendRemoteLedgerEntries2(meshId, entries);
24829
+ return { success: true, result, summary: getLedgerSummary2(meshId) };
24830
+ } catch (e) {
24831
+ return { success: false, error: e.message };
24832
+ }
24833
+ }
24697
24834
  case "get_mesh_queue": {
24698
24835
  const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
24699
24836
  if (!meshId) return { success: false, error: "meshId required" };
@@ -33458,6 +33595,7 @@ export {
33458
33595
  IdeProviderInstance,
33459
33596
  InMemoryGitSnapshotStore,
33460
33597
  LOG,
33598
+ MAX_LEDGER_SLICE_LIMIT,
33461
33599
  MIN_GIT_WORKSPACE_POLL_INTERVAL_MS,
33462
33600
  MIN_MACHINE_RUNTIME_SUBSCRIPTION_INTERVAL_MS,
33463
33601
  MIN_SESSION_HOST_DIAGNOSTICS_SUBSCRIPTION_INTERVAL_MS,
@@ -33473,12 +33611,15 @@ export {
33473
33611
  addNode,
33474
33612
  appendLedgerEntry,
33475
33613
  appendRecentActivity,
33614
+ appendRemoteLedgerEntries,
33476
33615
  buildAssistantChatMessage,
33477
33616
  buildChatMessage,
33478
33617
  buildChatMessageSignature,
33479
33618
  buildChatTailDeliverySignature,
33480
33619
  buildCoordinatorSystemPrompt,
33481
33620
  buildMachineInfo,
33621
+ buildMeshLedgerReconciliationEvidence,
33622
+ buildMeshLedgerReplicaEvidence,
33482
33623
  buildP2pRelayFailurePayload,
33483
33624
  buildPinnedGlobalInstallCommand,
33484
33625
  buildRuntimeSystemChatMessage,
@@ -33601,6 +33742,7 @@ export {
33601
33742
  probeCdpPort,
33602
33743
  readChatHistory,
33603
33744
  readLedgerEntries,
33745
+ readLedgerSlice,
33604
33746
  recordDebugTrace,
33605
33747
  registerExtensionProviders,
33606
33748
  removeNode,