@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 +4 -2
- package/dist/index.js +171 -24
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +166 -24
- 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/dist/mesh/mesh-sync.d.ts +4 -12
- 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/src/mesh/mesh-sync.ts +4 -34
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
|
});
|
|
@@ -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,
|