@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.d.ts +4 -2
- package/dist/index.js +171 -6
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +166 -6
- package/dist/index.mjs.map +1 -1
- package/dist/mesh/mesh-ledger-reconciliation.d.ts +55 -0
- package/dist/mesh/mesh-ledger.d.ts +46 -4
- package/package.json +1 -1
- package/src/commands/router.ts +35 -0
- package/src/index.ts +4 -2
- package/src/mesh/mesh-ledger-reconciliation.ts +115 -0
- package/src/mesh/mesh-ledger.ts +120 -7
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
|
|
851
|
-
|
|
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 =
|
|
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,
|