@adhdev/daemon-core 0.9.77-rc.48 → 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
  });
@@ -7138,6 +7204,66 @@ async function syncMeshes(transport) {
7138
7204
 
7139
7205
  // src/index.ts
7140
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
7141
7267
  init_mesh_work_queue();
7142
7268
  init_mesh_events();
7143
7269
 
@@ -24676,6 +24802,35 @@ var DaemonCommandRouter = class {
24676
24802
  return { success: false, error: e.message };
24677
24803
  }
24678
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
+ }
24679
24834
  case "get_mesh_queue": {
24680
24835
  const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
24681
24836
  if (!meshId) return { success: false, error: "meshId required" };
@@ -33440,6 +33595,7 @@ export {
33440
33595
  IdeProviderInstance,
33441
33596
  InMemoryGitSnapshotStore,
33442
33597
  LOG,
33598
+ MAX_LEDGER_SLICE_LIMIT,
33443
33599
  MIN_GIT_WORKSPACE_POLL_INTERVAL_MS,
33444
33600
  MIN_MACHINE_RUNTIME_SUBSCRIPTION_INTERVAL_MS,
33445
33601
  MIN_SESSION_HOST_DIAGNOSTICS_SUBSCRIPTION_INTERVAL_MS,
@@ -33455,12 +33611,15 @@ export {
33455
33611
  addNode,
33456
33612
  appendLedgerEntry,
33457
33613
  appendRecentActivity,
33614
+ appendRemoteLedgerEntries,
33458
33615
  buildAssistantChatMessage,
33459
33616
  buildChatMessage,
33460
33617
  buildChatMessageSignature,
33461
33618
  buildChatTailDeliverySignature,
33462
33619
  buildCoordinatorSystemPrompt,
33463
33620
  buildMachineInfo,
33621
+ buildMeshLedgerReconciliationEvidence,
33622
+ buildMeshLedgerReplicaEvidence,
33464
33623
  buildP2pRelayFailurePayload,
33465
33624
  buildPinnedGlobalInstallCommand,
33466
33625
  buildRuntimeSystemChatMessage,
@@ -33583,6 +33742,7 @@ export {
33583
33742
  probeCdpPort,
33584
33743
  readChatHistory,
33585
33744
  readLedgerEntries,
33745
+ readLedgerSlice,
33586
33746
  recordDebugTrace,
33587
33747
  registerExtensionProviders,
33588
33748
  removeNode,