@adhdev/daemon-standalone 1.0.58-rc.30 → 1.0.58-rc.31
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.js +439 -17
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/vendor/mcp-server/index.js.map +1 -1
package/dist/index.js
CHANGED
|
@@ -36885,10 +36885,10 @@ var require_dist3 = __commonJS({
|
|
|
36885
36885
|
}
|
|
36886
36886
|
function getDaemonBuildInfo() {
|
|
36887
36887
|
if (cached2) return cached2;
|
|
36888
|
-
const commit = readInjected(true ? "
|
|
36889
|
-
const commitShort = readInjected(true ? "
|
|
36890
|
-
const version2 = readInjected(true ? "1.0.58-rc.
|
|
36891
|
-
const builtAt = readInjected(true ? "2026-08-
|
|
36888
|
+
const commit = readInjected(true ? "d999ca9754d675f6c465f5bab1ff747fc444f7c6" : void 0) ?? "unknown";
|
|
36889
|
+
const commitShort = readInjected(true ? "d999ca97" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
|
|
36890
|
+
const version2 = readInjected(true ? "1.0.58-rc.31" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
|
|
36891
|
+
const builtAt = readInjected(true ? "2026-08-28T04:19:17.942Z" : void 0);
|
|
36892
36892
|
cached2 = builtAt ? { commit, commitShort, version: version2, builtAt } : { commit, commitShort, version: version2 };
|
|
36893
36893
|
return cached2;
|
|
36894
36894
|
}
|
|
@@ -43741,7 +43741,8 @@ child.on('exit', () => process.exit(0));
|
|
|
43741
43741
|
"command_result",
|
|
43742
43742
|
"error",
|
|
43743
43743
|
"agent_event",
|
|
43744
|
-
"log"
|
|
43744
|
+
"log",
|
|
43745
|
+
"beacon_vectors"
|
|
43745
43746
|
];
|
|
43746
43747
|
SERVER_TO_DAEMON_WS_MSGS = [
|
|
43747
43748
|
"auth_ok",
|
|
@@ -43753,7 +43754,8 @@ child.on('exit', () => process.exit(0));
|
|
|
43753
43754
|
"force_update_required",
|
|
43754
43755
|
"command",
|
|
43755
43756
|
"agent_command",
|
|
43756
|
-
"resolve_action"
|
|
43757
|
+
"resolve_action",
|
|
43758
|
+
"beacon_vectors_result"
|
|
43757
43759
|
];
|
|
43758
43760
|
}
|
|
43759
43761
|
});
|
|
@@ -50985,7 +50987,7 @@ The instruction it carried was never delivered to anyone. If it still matters, r
|
|
|
50985
50987
|
// bound a hostile peer streams arbitrarily many distinct in-range chunks into
|
|
50986
50988
|
// one map. 64 MiB = 256 × MAX_FRAME_BYTES; the largest library-bounded
|
|
50987
50989
|
// legitimate body is a ring-tail SNAP of RING_DEFAULT (500) rows ×
|
|
50988
|
-
// MAX_ROW_BYTES (65_536)
|
|
50990
|
+
// MAX_ROW_BYTES (65_536) = 31.25 MiB, ≈ 41.7 MiB after base64 — comfortably
|
|
50989
50991
|
// under. Hosts serving bigger (policy-unbounded) view tables raise this.
|
|
50990
50992
|
MAX_REASSEMBLY_BYTES: 67108864,
|
|
50991
50993
|
INFLIGHT_CREDITS: 4,
|
|
@@ -51910,27 +51912,47 @@ The instruction it carried was never delivered to anyone. If it still matters, r
|
|
|
51910
51912
|
var init_beacon = __esm2({
|
|
51911
51913
|
"../../vendor/seqscribe/dist/beacon.js"() {
|
|
51912
51914
|
"use strict";
|
|
51915
|
+
init_encoding();
|
|
51913
51916
|
init_errors3();
|
|
51914
51917
|
BeaconHub = class {
|
|
51915
51918
|
deps;
|
|
51916
51919
|
known = [];
|
|
51917
51920
|
transport = null;
|
|
51918
51921
|
debounceTimer = null;
|
|
51919
|
-
|
|
51922
|
+
// Node-level teardown (proposals-v3.5 P28). Terminal and distinct from an
|
|
51923
|
+
// arming's stop(): a BeaconHub that outlived its owning node's close() must
|
|
51924
|
+
// never push again, so this is the one latch that is genuinely one-way.
|
|
51925
|
+
closed = false;
|
|
51926
|
+
hostHints = null;
|
|
51927
|
+
// Monotonic arming id. stop() is a PAUSE — the hub is re-startable, matching
|
|
51928
|
+
// the shape of start() itself (a handle you can stop() reads as something you
|
|
51929
|
+
// can start() again) and the reconnect-scoped re-arm hosts actually write.
|
|
51930
|
+
// Handles are per-arming: a stale handle's stop() must not tear down a LATER
|
|
51931
|
+
// arming, which is why stop() compares its own generation before acting.
|
|
51932
|
+
armGen = 0;
|
|
51920
51933
|
constructor(deps) {
|
|
51921
51934
|
this.deps = deps;
|
|
51922
51935
|
}
|
|
51923
|
-
start(t) {
|
|
51936
|
+
start(t, o) {
|
|
51937
|
+
if (this.closed)
|
|
51938
|
+
throw misuse("beacon closed \u2014 the node is closed");
|
|
51924
51939
|
if (this.transport)
|
|
51925
51940
|
throw misuse("beacon already started");
|
|
51941
|
+
const gen = ++this.armGen;
|
|
51926
51942
|
this.transport = t;
|
|
51943
|
+
this.hostHints = o?.hints ?? null;
|
|
51927
51944
|
this.push();
|
|
51928
51945
|
return {
|
|
51929
51946
|
stop: () => {
|
|
51930
|
-
this.
|
|
51931
|
-
|
|
51947
|
+
if (this.armGen !== gen)
|
|
51948
|
+
return;
|
|
51949
|
+
this.armGen++;
|
|
51950
|
+
if (this.debounceTimer !== null) {
|
|
51932
51951
|
this.deps.timers.clearTimeout(this.debounceTimer);
|
|
51952
|
+
this.debounceTimer = null;
|
|
51953
|
+
}
|
|
51933
51954
|
this.transport = null;
|
|
51955
|
+
this.hostHints = null;
|
|
51934
51956
|
}
|
|
51935
51957
|
};
|
|
51936
51958
|
}
|
|
@@ -51938,16 +51960,18 @@ The instruction it carried was never delivered to anyone. If it still matters, r
|
|
|
51938
51960
|
// core.vectors() when it fires, so node.close() must cancel it like every
|
|
51939
51961
|
// other hub timer rather than rely on the host calling the handle's stop().
|
|
51940
51962
|
close() {
|
|
51941
|
-
this.
|
|
51963
|
+
this.closed = true;
|
|
51964
|
+
this.armGen++;
|
|
51942
51965
|
if (this.debounceTimer !== null) {
|
|
51943
51966
|
this.deps.timers.clearTimeout(this.debounceTimer);
|
|
51944
51967
|
this.debounceTimer = null;
|
|
51945
51968
|
}
|
|
51946
51969
|
this.transport = null;
|
|
51970
|
+
this.hostHints = null;
|
|
51947
51971
|
}
|
|
51948
51972
|
// called from the applied fan-out — 5 s debounce after append (§5.7)
|
|
51949
51973
|
notifyApplied() {
|
|
51950
|
-
if (!this.transport || this.
|
|
51974
|
+
if (!this.transport || this.closed || this.debounceTimer !== null)
|
|
51951
51975
|
return;
|
|
51952
51976
|
this.debounceTimer = this.deps.timers.setTimeout(() => {
|
|
51953
51977
|
this.debounceTimer = null;
|
|
@@ -51990,17 +52014,73 @@ The instruction it carried was never delivered to anyone. If it still matters, r
|
|
|
51990
52014
|
}
|
|
51991
52015
|
return out;
|
|
51992
52016
|
}
|
|
52017
|
+
// §5.7 hints (P27). `hintKeys` is the per-topic opt-in gate: a topic that has
|
|
52018
|
+
// not set it contributes nothing and, if the host names it anyway, is dropped
|
|
52019
|
+
// — the SPEC wire format implies the gate, and honoring it is what stops a
|
|
52020
|
+
// "hash" declaration from leaking plaintext keys by omission.
|
|
52021
|
+
// "plain" — the key as authored
|
|
52022
|
+
// "hash" — sha256 hex of the key, so a board operator sees change activity
|
|
52023
|
+
// without learning key names
|
|
52024
|
+
// Host-supplied entries are merged OVER library-derived ones for the same
|
|
52025
|
+
// topic: the host asked for a specific advertisement, so it wins.
|
|
52026
|
+
buildHints() {
|
|
52027
|
+
const out = {};
|
|
52028
|
+
const modeOf = (topic) => {
|
|
52029
|
+
try {
|
|
52030
|
+
return this.deps.topics.get(topic).policy.hintKeys;
|
|
52031
|
+
} catch {
|
|
52032
|
+
return void 0;
|
|
52033
|
+
}
|
|
52034
|
+
};
|
|
52035
|
+
const add = (topic, mode, raw) => {
|
|
52036
|
+
const dst = out[topic] ??= {};
|
|
52037
|
+
for (const [key2, at] of Object.entries(raw))
|
|
52038
|
+
dst[mode === "hash" ? sha256HexUtf8(key2) : key2] = at;
|
|
52039
|
+
};
|
|
52040
|
+
const registers = this.deps.registers;
|
|
52041
|
+
if (registers)
|
|
52042
|
+
for (const topic of this.deps.topics.list()) {
|
|
52043
|
+
const mode = modeOf(topic);
|
|
52044
|
+
if (mode === void 0)
|
|
52045
|
+
continue;
|
|
52046
|
+
if (this.deps.topics.get(topic).policy.kind !== "register")
|
|
52047
|
+
continue;
|
|
52048
|
+
add(topic, mode, registers.hintsFor(topic));
|
|
52049
|
+
}
|
|
52050
|
+
if (this.hostHints) {
|
|
52051
|
+
let supplied;
|
|
52052
|
+
try {
|
|
52053
|
+
supplied = this.hostHints();
|
|
52054
|
+
} catch {
|
|
52055
|
+
supplied = {};
|
|
52056
|
+
}
|
|
52057
|
+
for (const [topic, raw] of Object.entries(supplied)) {
|
|
52058
|
+
const mode = modeOf(topic);
|
|
52059
|
+
if (mode === void 0)
|
|
52060
|
+
continue;
|
|
52061
|
+
add(topic, mode, raw);
|
|
52062
|
+
}
|
|
52063
|
+
}
|
|
52064
|
+
for (const topic of Object.keys(out))
|
|
52065
|
+
if (Object.keys(out[topic]).length === 0)
|
|
52066
|
+
delete out[topic];
|
|
52067
|
+
return Object.keys(out).length > 0 ? out : void 0;
|
|
52068
|
+
}
|
|
51993
52069
|
push() {
|
|
51994
52070
|
const t = this.transport;
|
|
51995
|
-
if (!t || this.
|
|
52071
|
+
if (!t || this.closed)
|
|
51996
52072
|
return;
|
|
52073
|
+
const gen = this.armGen;
|
|
51997
52074
|
const report = {
|
|
51998
52075
|
node: this.deps.writerId,
|
|
51999
52076
|
at: new Date(this.deps.clock()).toISOString(),
|
|
52000
52077
|
vectors: this.deps.core.vectors()
|
|
52001
52078
|
};
|
|
52079
|
+
const hints = this.buildHints();
|
|
52080
|
+
if (hints)
|
|
52081
|
+
report.hints = hints;
|
|
52002
52082
|
void t.put(report).then(() => t.get()).then((reports) => {
|
|
52003
|
-
if (!this.
|
|
52083
|
+
if (!this.closed && this.armGen === gen)
|
|
52004
52084
|
this.known = reports;
|
|
52005
52085
|
}).catch(() => {
|
|
52006
52086
|
});
|
|
@@ -53593,6 +53673,38 @@ The instruction it carried was never delivered to anyone. If it still matters, r
|
|
|
53593
53673
|
ownerOf(topic, key2) {
|
|
53594
53674
|
return this.topicState(topic).keys.get(key2)?.owner ?? null;
|
|
53595
53675
|
}
|
|
53676
|
+
// §5.7 pre-write warning source (proposals-v3.5 P27): the latest change this
|
|
53677
|
+
// node knows about per key, as the [writer, seq] shape BeaconReport.hints
|
|
53678
|
+
// declares. Sourced from the MATERIALIZED winner, NOT from scopeTails —
|
|
53679
|
+
// scopeTails is the §11.2 own-uncommitted tail and is deleted as each own
|
|
53680
|
+
// write materializes (and never holds a peer's write at all), so it is empty
|
|
53681
|
+
// in exactly the steady state a hint has to describe. `winner` is the fold's
|
|
53682
|
+
// per-key judgment over the total order, which is what "latest known change
|
|
53683
|
+
// to this key" means, and it covers peer writes and own writes alike.
|
|
53684
|
+
//
|
|
53685
|
+
// Member-only keys (a set with no scalar winner) report their highest member
|
|
53686
|
+
// entry: under §11.5 mirror rules such a key never has a `winner`, but an
|
|
53687
|
+
// add/remove is still a change a concurrent editor would overwrite.
|
|
53688
|
+
hintsFor(topic) {
|
|
53689
|
+
const out = {};
|
|
53690
|
+
for (const [key2, ks] of this.topicState(topic).keys) {
|
|
53691
|
+
let best;
|
|
53692
|
+
let bestOrder;
|
|
53693
|
+
if (ks.winner && ks.winnerOrder) {
|
|
53694
|
+
best = [ks.winner[1], ks.winner[2]];
|
|
53695
|
+
bestOrder = ks.winnerOrder;
|
|
53696
|
+
}
|
|
53697
|
+
for (const ms of ks.members.values()) {
|
|
53698
|
+
if (bestOrder !== void 0 && orderCompare(ms.order, bestOrder) <= 0)
|
|
53699
|
+
continue;
|
|
53700
|
+
best = [ms.entry[1], ms.entry[2]];
|
|
53701
|
+
bestOrder = ms.order;
|
|
53702
|
+
}
|
|
53703
|
+
if (best)
|
|
53704
|
+
out[key2] = best;
|
|
53705
|
+
}
|
|
53706
|
+
return out;
|
|
53707
|
+
}
|
|
53596
53708
|
pendingRequests(topic, now) {
|
|
53597
53709
|
const cutoff = (now ?? this.deps.clock()) - this.deps.constants.REQUEST_TTL_MS;
|
|
53598
53710
|
const out = [];
|
|
@@ -57362,7 +57474,15 @@ CREATE TABLE IF NOT EXISTS sq_archive (
|
|
|
57362
57474
|
sync.setSnapshotHub(snapshots);
|
|
57363
57475
|
const archive = new ArchiveHub({ core: core2, store, topics, views, registers, constants: constants2, clock, emitAnomaly });
|
|
57364
57476
|
consumers.setOnAdvance((topic) => archive.onConsumerAdvance(topic));
|
|
57365
|
-
const beaconHub = new BeaconHub({
|
|
57477
|
+
const beaconHub = new BeaconHub({
|
|
57478
|
+
core: core2,
|
|
57479
|
+
topics,
|
|
57480
|
+
writerId: opts.writerId,
|
|
57481
|
+
constants: constants2,
|
|
57482
|
+
timers,
|
|
57483
|
+
clock,
|
|
57484
|
+
registers
|
|
57485
|
+
});
|
|
57366
57486
|
finalityHub.setOnAccepted((cert) => {
|
|
57367
57487
|
views.notifyApplied(cert.topic);
|
|
57368
57488
|
sync.onCertAccepted();
|
|
@@ -57407,7 +57527,7 @@ CREATE TABLE IF NOT EXISTS sq_archive (
|
|
|
57407
57527
|
vectors: () => core2.vectors(),
|
|
57408
57528
|
setKnownVectors: (v) => beaconHub.setKnownVectors(v),
|
|
57409
57529
|
staleness: (topic, key2) => beaconHub.staleness(topic, key2),
|
|
57410
|
-
beacon: (t) => beaconHub.start(t),
|
|
57530
|
+
beacon: (t, o) => beaconHub.start(t, o),
|
|
57411
57531
|
finality: (topic) => finalityHub.finality(topic),
|
|
57412
57532
|
proposeFinality: (topic) => finalityHub.proposeFinality(topic),
|
|
57413
57533
|
ingestFinality: (cert) => finalityHub.ingestFinality(cert),
|
|
@@ -96908,6 +97028,7 @@ ${e?.stderr || ""}`;
|
|
|
96908
97028
|
ASSISTANT_JOURNAL_TOPIC: () => ASSISTANT_JOURNAL_TOPIC,
|
|
96909
97029
|
AcpProviderInstance: () => AcpProviderInstance,
|
|
96910
97030
|
AgentStreamPoller: () => AgentStreamPoller,
|
|
97031
|
+
BEACON_ENV: () => BEACON_ENV,
|
|
96911
97032
|
BUILD_CHANNEL_ENV_VAR: () => BUILD_CHANNEL_ENV_VAR,
|
|
96912
97033
|
BUILTIN_CHAT_MESSAGE_KINDS: () => BUILTIN_CHAT_MESSAGE_KINDS,
|
|
96913
97034
|
CANONICAL_MESH_TOOL_COUNT: () => CANONICAL_MESH_TOOL_COUNT,
|
|
@@ -96988,6 +97109,7 @@ ${e?.stderr || ""}`;
|
|
|
96988
97109
|
LowDiskSpaceError: () => LowDiskSpaceError,
|
|
96989
97110
|
MAGI_NEEDS_VERIFICATION_PREVIEW_CAP: () => MAGI_NEEDS_VERIFICATION_PREVIEW_CAP,
|
|
96990
97111
|
MAGI_RAW_ANSWER_CAP: () => MAGI_RAW_ANSWER_CAP,
|
|
97112
|
+
MAX_BEACON_GET_QUERIES: () => MAX_BEACON_GET_QUERIES,
|
|
96991
97113
|
MAX_CAPTURE_LOG_GENERATIONS: () => MAX_CAPTURE_LOG_GENERATIONS,
|
|
96992
97114
|
MAX_CAPTURE_LOG_SIZE: () => MAX_CAPTURE_LOG_SIZE,
|
|
96993
97115
|
MAX_INFLIGHT: () => MAX_INFLIGHT,
|
|
@@ -97100,7 +97222,9 @@ ${e?.stderr || ""}`;
|
|
|
97100
97222
|
appendLedgerEntry: () => appendLedgerEntry,
|
|
97101
97223
|
appendRecentActivity: () => appendRecentActivity,
|
|
97102
97224
|
appendRemoteLedgerEntries: () => appendRemoteLedgerEntries,
|
|
97225
|
+
armBeacon: () => armBeacon,
|
|
97103
97226
|
assertNoDependencyCycle: () => assertNoDependencyCycle,
|
|
97227
|
+
assertNoPlaintextHintTopics: () => assertNoPlaintextHintTopics,
|
|
97104
97228
|
assistantJournalPolicy: () => assistantJournalPolicy,
|
|
97105
97229
|
backfillMeshEventShadow: () => backfillMeshEventShadow,
|
|
97106
97230
|
baseTopicDefinitions: () => baseTopicDefinitions,
|
|
@@ -97208,6 +97332,7 @@ ${e?.stderr || ""}`;
|
|
|
97208
97332
|
daemonIdsEquivalent: () => daemonIdsEquivalent,
|
|
97209
97333
|
decideMissingSessionAttempt: () => decideMissingSessionAttempt2,
|
|
97210
97334
|
declareWorkspaceIntents: () => declareWorkspaceIntents,
|
|
97335
|
+
defaultBeaconTopicScope: () => defaultBeaconTopicScope,
|
|
97211
97336
|
delegatedWorkerAutoApproveSettings: () => delegatedWorkerAutoApproveSettings,
|
|
97212
97337
|
deleteDirectDispatchesByTaskId: () => deleteDirectDispatchesByTaskId,
|
|
97213
97338
|
deleteMesh: () => deleteMesh,
|
|
@@ -97472,6 +97597,7 @@ ${e?.stderr || ""}`;
|
|
|
97472
97597
|
printQuotaInstallError: () => printQuotaInstallError2,
|
|
97473
97598
|
printQuotaRefreshOutcome: () => printQuotaRefreshOutcome2,
|
|
97474
97599
|
probeCdpPort: () => probeCdpPort,
|
|
97600
|
+
projectBeaconReport: () => projectBeaconReport,
|
|
97475
97601
|
projectGraphPublicPolicy: () => projectGraphPublicPolicy,
|
|
97476
97602
|
projectMeshLedgerEntry: () => projectMeshLedgerEntry,
|
|
97477
97603
|
pruneOperatingNotes: () => pruneOperatingNotes,
|
|
@@ -97538,6 +97664,7 @@ ${e?.stderr || ""}`;
|
|
|
97538
97664
|
resolveAllowSendKeysDestructive: () => resolveAllowSendKeysDestructive,
|
|
97539
97665
|
resolveAutoConvergeCodeChange: () => resolveAutoConvergeCodeChange,
|
|
97540
97666
|
resolveBackoffMs: () => resolveBackoffMs,
|
|
97667
|
+
resolveBeaconMode: () => resolveBeaconMode,
|
|
97541
97668
|
resolveBuildTrack: () => resolveBuildTrack,
|
|
97542
97669
|
resolveChatMessageKind: () => resolveChatMessageKind,
|
|
97543
97670
|
resolveConsoleSymbols: () => resolveConsoleSymbols,
|
|
@@ -147984,10 +148111,22 @@ data: ${JSON.stringify(msg.data)}
|
|
|
147984
148111
|
"Seqscribe",
|
|
147985
148112
|
`node open writer=${writerId} topics=${defs.length} authority=${authority ? "on" : "off"}${opts.isCoordinator ? " role=coordinator" : ""}`
|
|
147986
148113
|
);
|
|
148114
|
+
const closeCallbacks = [];
|
|
147987
148115
|
let closed = false;
|
|
147988
148116
|
const close = async () => {
|
|
147989
148117
|
if (closed) return;
|
|
147990
148118
|
closed = true;
|
|
148119
|
+
while (closeCallbacks.length > 0) {
|
|
148120
|
+
const fn = closeCallbacks.shift();
|
|
148121
|
+
try {
|
|
148122
|
+
fn();
|
|
148123
|
+
} catch (err) {
|
|
148124
|
+
LOG2.warn(
|
|
148125
|
+
"Seqscribe",
|
|
148126
|
+
`close callback failed: ${err instanceof Error ? err.message : String(err)}`
|
|
148127
|
+
);
|
|
148128
|
+
}
|
|
148129
|
+
}
|
|
147991
148130
|
try {
|
|
147992
148131
|
finalityLoop?.stop();
|
|
147993
148132
|
} catch {
|
|
@@ -148018,6 +148157,16 @@ data: ${JSON.stringify(msg.data)}
|
|
|
148018
148157
|
topics: defs,
|
|
148019
148158
|
authorityEnabled: authority !== null,
|
|
148020
148159
|
finalityLoop,
|
|
148160
|
+
onClose: (fn) => {
|
|
148161
|
+
if (closed) {
|
|
148162
|
+
try {
|
|
148163
|
+
fn();
|
|
148164
|
+
} catch {
|
|
148165
|
+
}
|
|
148166
|
+
return;
|
|
148167
|
+
}
|
|
148168
|
+
closeCallbacks.push(fn);
|
|
148169
|
+
},
|
|
148021
148170
|
close
|
|
148022
148171
|
};
|
|
148023
148172
|
}
|
|
@@ -149415,6 +149564,279 @@ ${upgradeFailureNotice.notice}${supersededHint}`);
|
|
|
149415
149564
|
\u2717 ${message}
|
|
149416
149565
|
`));
|
|
149417
149566
|
}
|
|
149567
|
+
init_logger();
|
|
149568
|
+
init_topics2();
|
|
149569
|
+
var BEACON_ENV = "ADHDEV_SEQSCRIBE_BEACON";
|
|
149570
|
+
function resolveBeaconMode(env2 = process.env) {
|
|
149571
|
+
const raw = env2[BEACON_ENV]?.trim().toLowerCase();
|
|
149572
|
+
if (!raw) return "on";
|
|
149573
|
+
if (raw === "off") return "off";
|
|
149574
|
+
if (raw === "on") return "on";
|
|
149575
|
+
warnOnce4(
|
|
149576
|
+
`unrecognized ${BEACON_ENV}=${raw}; treating as 'on'. Valid values are 'on' (default) and 'off'.`
|
|
149577
|
+
);
|
|
149578
|
+
return "on";
|
|
149579
|
+
}
|
|
149580
|
+
var warnedUnrecognized = false;
|
|
149581
|
+
function warnOnce4(message) {
|
|
149582
|
+
if (warnedUnrecognized) return;
|
|
149583
|
+
warnedUnrecognized = true;
|
|
149584
|
+
LOG2.warn("Seqscribe", message);
|
|
149585
|
+
}
|
|
149586
|
+
var CHAIN_RE2 = /^[0-9a-f]{64}$/;
|
|
149587
|
+
var WRITER_ID_RE = /^[A-Za-z0-9._:-]{1,128}$/;
|
|
149588
|
+
var TOPIC_RE2 = /^[A-Za-z0-9._*-]{1,160}$/;
|
|
149589
|
+
var MAX_TOPICS_PER_REPORT = 512;
|
|
149590
|
+
var MAX_WRITERS_PER_TOPIC = 512;
|
|
149591
|
+
function finiteCount(v) {
|
|
149592
|
+
return typeof v === "number" && Number.isFinite(v) && v >= 0 ? Math.floor(v) : void 0;
|
|
149593
|
+
}
|
|
149594
|
+
function hash64(v) {
|
|
149595
|
+
return typeof v === "string" && CHAIN_RE2.test(v) ? v : void 0;
|
|
149596
|
+
}
|
|
149597
|
+
function projectWriterEntry(raw) {
|
|
149598
|
+
if (!raw || typeof raw !== "object") return null;
|
|
149599
|
+
const v = raw;
|
|
149600
|
+
const rgen = finiteCount(v.rgen);
|
|
149601
|
+
if (v.retired === true) {
|
|
149602
|
+
const finalSeq = finiteCount(v.finalSeq);
|
|
149603
|
+
const finalChain = hash64(v.finalChain);
|
|
149604
|
+
if (finalSeq === void 0 || finalChain === void 0 || rgen === void 0) return null;
|
|
149605
|
+
return { retired: true, finalSeq, finalChain, rgen };
|
|
149606
|
+
}
|
|
149607
|
+
const contig = finiteCount(v.contig);
|
|
149608
|
+
const chain = hash64(v.chain);
|
|
149609
|
+
if (contig === void 0 || chain === void 0) return null;
|
|
149610
|
+
return rgen === void 0 ? { contig, chain } : { contig, chain, rgen };
|
|
149611
|
+
}
|
|
149612
|
+
function projectBeaconReport(raw) {
|
|
149613
|
+
if (!raw || typeof raw !== "object") return null;
|
|
149614
|
+
const v = raw;
|
|
149615
|
+
const node = typeof v.node === "string" && WRITER_ID_RE.test(v.node) ? v.node : null;
|
|
149616
|
+
if (!node) return null;
|
|
149617
|
+
const at = typeof v.at === "string" && !Number.isNaN(Date.parse(v.at)) ? new Date(v.at).toISOString() : (/* @__PURE__ */ new Date(0)).toISOString();
|
|
149618
|
+
const vectors = {};
|
|
149619
|
+
const rawVectors = v.vectors;
|
|
149620
|
+
if (rawVectors && typeof rawVectors === "object") {
|
|
149621
|
+
let topicCount = 0;
|
|
149622
|
+
for (const [topic, vec] of Object.entries(rawVectors)) {
|
|
149623
|
+
if (topicCount >= MAX_TOPICS_PER_REPORT) break;
|
|
149624
|
+
if (!TOPIC_RE2.test(topic)) continue;
|
|
149625
|
+
if (!vec || typeof vec !== "object") continue;
|
|
149626
|
+
const rawWriters = vec.writers;
|
|
149627
|
+
if (!rawWriters || typeof rawWriters !== "object") continue;
|
|
149628
|
+
const writers = {};
|
|
149629
|
+
let writerCount = 0;
|
|
149630
|
+
for (const [writerId, entry] of Object.entries(rawWriters)) {
|
|
149631
|
+
if (writerCount >= MAX_WRITERS_PER_TOPIC) break;
|
|
149632
|
+
if (!WRITER_ID_RE.test(writerId)) continue;
|
|
149633
|
+
const clean2 = projectWriterEntry(entry);
|
|
149634
|
+
if (!clean2) continue;
|
|
149635
|
+
writers[writerId] = clean2;
|
|
149636
|
+
writerCount++;
|
|
149637
|
+
}
|
|
149638
|
+
if (writerCount === 0) continue;
|
|
149639
|
+
const fgen = finiteCount(vec.fgen);
|
|
149640
|
+
vectors[topic] = fgen === void 0 ? { writers } : { fgen, writers };
|
|
149641
|
+
topicCount++;
|
|
149642
|
+
}
|
|
149643
|
+
}
|
|
149644
|
+
return { node, at, vectors };
|
|
149645
|
+
}
|
|
149646
|
+
function assertNoPlaintextHintTopics(defs) {
|
|
149647
|
+
const offenders = defs.filter((d) => d.policy.hintKeys === "plain").map((d) => d.topic);
|
|
149648
|
+
if (offenders.length === 0) return;
|
|
149649
|
+
throw new Error(
|
|
149650
|
+
`seqscribe beacon: topic(s) ${offenders.join(", ")} declare hintKeys:'plain'. Only 'hash' (or omitting the field) is permitted \u2014 plaintext register keys on the server exceed the approved Beacon content-boundary exception (CLAUDE.md).`
|
|
149651
|
+
);
|
|
149652
|
+
}
|
|
149653
|
+
function defaultBeaconTopicScope(vectors) {
|
|
149654
|
+
return Object.keys(vectors).filter(
|
|
149655
|
+
(topic) => topic === FLEET_STATUS_TOPIC || meshIdFromEventsTopic(topic) !== null
|
|
149656
|
+
);
|
|
149657
|
+
}
|
|
149658
|
+
function emptyCounters() {
|
|
149659
|
+
return {
|
|
149660
|
+
put: 0,
|
|
149661
|
+
putFailed: 0,
|
|
149662
|
+
get: 0,
|
|
149663
|
+
getFailed: 0,
|
|
149664
|
+
truncated: 0,
|
|
149665
|
+
rejected: 0,
|
|
149666
|
+
splitRetries: 0
|
|
149667
|
+
};
|
|
149668
|
+
}
|
|
149669
|
+
var MAX_BEACON_GET_QUERIES = 16;
|
|
149670
|
+
function mergeBeaconReportsByNode(left, right) {
|
|
149671
|
+
const byNode = /* @__PURE__ */ new Map();
|
|
149672
|
+
const unkeyed = [];
|
|
149673
|
+
const ingest2 = (report) => {
|
|
149674
|
+
const node = report && typeof report === "object" && typeof report.node === "string" ? report.node : void 0;
|
|
149675
|
+
if (!node) {
|
|
149676
|
+
unkeyed.push(report);
|
|
149677
|
+
return;
|
|
149678
|
+
}
|
|
149679
|
+
const existing = byNode.get(node);
|
|
149680
|
+
if (!existing) {
|
|
149681
|
+
byNode.set(node, report);
|
|
149682
|
+
return;
|
|
149683
|
+
}
|
|
149684
|
+
const existingAt = existing.at;
|
|
149685
|
+
const candidateAt = report.at;
|
|
149686
|
+
const existingTime = typeof existingAt === "string" ? Date.parse(existingAt) : NaN;
|
|
149687
|
+
const candidateTime = typeof candidateAt === "string" ? Date.parse(candidateAt) : NaN;
|
|
149688
|
+
if (!Number.isNaN(candidateTime) && (Number.isNaN(existingTime) || candidateTime > existingTime)) {
|
|
149689
|
+
byNode.set(node, report);
|
|
149690
|
+
}
|
|
149691
|
+
};
|
|
149692
|
+
for (const r of left) ingest2(r);
|
|
149693
|
+
for (const r of right) ingest2(r);
|
|
149694
|
+
return [...byNode.values(), ...unkeyed];
|
|
149695
|
+
}
|
|
149696
|
+
function armBeacon(handle, transport, opts = {}) {
|
|
149697
|
+
const mode = resolveBeaconMode(opts.env ?? process.env);
|
|
149698
|
+
if (mode === "off") {
|
|
149699
|
+
LOG2.info("Seqscribe", `beacon disabled (${BEACON_ENV}=off)`);
|
|
149700
|
+
return null;
|
|
149701
|
+
}
|
|
149702
|
+
assertNoPlaintextHintTopics(handle.topics);
|
|
149703
|
+
const counters5 = emptyCounters();
|
|
149704
|
+
const scopeOf = opts.topicScope ?? defaultBeaconTopicScope;
|
|
149705
|
+
let stopped = false;
|
|
149706
|
+
let lastScope = [];
|
|
149707
|
+
const doPut = async (rawReport) => {
|
|
149708
|
+
const projected = projectBeaconReport(rawReport);
|
|
149709
|
+
if (!projected) {
|
|
149710
|
+
counters5.rejected++;
|
|
149711
|
+
LOG2.warn("Seqscribe", "beacon report failed the content projection; not sent");
|
|
149712
|
+
return;
|
|
149713
|
+
}
|
|
149714
|
+
lastScope = scopeOf(projected.vectors);
|
|
149715
|
+
try {
|
|
149716
|
+
await transport.put(projected);
|
|
149717
|
+
counters5.put++;
|
|
149718
|
+
} catch (err) {
|
|
149719
|
+
counters5.putFailed++;
|
|
149720
|
+
LOG2.info(
|
|
149721
|
+
"Seqscribe",
|
|
149722
|
+
`beacon put failed (advisory, ignored): ${err instanceof Error ? err.message : String(err)}`
|
|
149723
|
+
);
|
|
149724
|
+
throw err;
|
|
149725
|
+
}
|
|
149726
|
+
};
|
|
149727
|
+
const rawQuery = async (topics) => {
|
|
149728
|
+
try {
|
|
149729
|
+
const res = await transport.get(topics);
|
|
149730
|
+
counters5.get++;
|
|
149731
|
+
return res;
|
|
149732
|
+
} catch (err) {
|
|
149733
|
+
counters5.getFailed++;
|
|
149734
|
+
LOG2.info(
|
|
149735
|
+
"Seqscribe",
|
|
149736
|
+
`beacon get failed (advisory, ignored): ${err instanceof Error ? err.message : String(err)}`
|
|
149737
|
+
);
|
|
149738
|
+
throw err;
|
|
149739
|
+
}
|
|
149740
|
+
};
|
|
149741
|
+
const queryWithSplitRetry = async (topics, queriesUsed) => {
|
|
149742
|
+
if (queriesUsed.count >= MAX_BEACON_GET_QUERIES) {
|
|
149743
|
+
return { reports: [], truncated: topics.length };
|
|
149744
|
+
}
|
|
149745
|
+
queriesUsed.count++;
|
|
149746
|
+
const res = await rawQuery(topics);
|
|
149747
|
+
const truncated = typeof res?.truncated === "number" ? res.truncated : 0;
|
|
149748
|
+
const reports = Array.isArray(res?.reports) ? res.reports : [];
|
|
149749
|
+
if (truncated === 0 || topics.length <= 1) {
|
|
149750
|
+
return { reports, truncated };
|
|
149751
|
+
}
|
|
149752
|
+
if (queriesUsed.count + 2 > MAX_BEACON_GET_QUERIES) {
|
|
149753
|
+
return { reports, truncated };
|
|
149754
|
+
}
|
|
149755
|
+
const mid = Math.ceil(topics.length / 2);
|
|
149756
|
+
const left = topics.slice(0, mid);
|
|
149757
|
+
const right = topics.slice(mid);
|
|
149758
|
+
counters5.splitRetries++;
|
|
149759
|
+
const [leftRes, rightRes] = await Promise.all([
|
|
149760
|
+
queryWithSplitRetry(left, queriesUsed),
|
|
149761
|
+
queryWithSplitRetry(right, queriesUsed)
|
|
149762
|
+
]);
|
|
149763
|
+
return {
|
|
149764
|
+
reports: mergeBeaconReportsByNode(leftRes.reports, rightRes.reports),
|
|
149765
|
+
truncated: leftRes.truncated + rightRes.truncated
|
|
149766
|
+
};
|
|
149767
|
+
};
|
|
149768
|
+
const doGet = async () => {
|
|
149769
|
+
const queriesUsed = { count: 0 };
|
|
149770
|
+
let truncated = 0;
|
|
149771
|
+
let reports = [];
|
|
149772
|
+
try {
|
|
149773
|
+
const res = await queryWithSplitRetry(lastScope, queriesUsed);
|
|
149774
|
+
reports = res.reports;
|
|
149775
|
+
truncated = res.truncated;
|
|
149776
|
+
} catch (err) {
|
|
149777
|
+
counters5.getFailed++;
|
|
149778
|
+
LOG2.info(
|
|
149779
|
+
"Seqscribe",
|
|
149780
|
+
`beacon get failed (advisory, ignored): ${err instanceof Error ? err.message : String(err)}`
|
|
149781
|
+
);
|
|
149782
|
+
throw err;
|
|
149783
|
+
}
|
|
149784
|
+
if (truncated > 0) {
|
|
149785
|
+
counters5.truncated += truncated;
|
|
149786
|
+
LOG2.info(
|
|
149787
|
+
"Seqscribe",
|
|
149788
|
+
`beacon get: ${truncated} peer report(s) remained truncated after split-retry (${queriesUsed.count} quer${queriesUsed.count === 1 ? "y" : "ies"})`
|
|
149789
|
+
);
|
|
149790
|
+
}
|
|
149791
|
+
const clean2 = reports.map((r) => projectBeaconReport(r)).filter((r) => r !== null);
|
|
149792
|
+
LOG2.info(
|
|
149793
|
+
"Seqscribe",
|
|
149794
|
+
`beacon get writer=${handle.writerId} peers=${clean2.length} topics=${lastScope.length}`
|
|
149795
|
+
);
|
|
149796
|
+
return clean2;
|
|
149797
|
+
};
|
|
149798
|
+
const libHandle = handle.node.beacon({
|
|
149799
|
+
async put(rawReport) {
|
|
149800
|
+
if (stopped) return;
|
|
149801
|
+
await doPut(rawReport);
|
|
149802
|
+
},
|
|
149803
|
+
async get() {
|
|
149804
|
+
if (stopped) return [];
|
|
149805
|
+
return await doGet();
|
|
149806
|
+
}
|
|
149807
|
+
});
|
|
149808
|
+
LOG2.info("Seqscribe", `beacon armed writer=${handle.writerId}`);
|
|
149809
|
+
const beaconHandle = {
|
|
149810
|
+
stop() {
|
|
149811
|
+
if (stopped) return;
|
|
149812
|
+
stopped = true;
|
|
149813
|
+
try {
|
|
149814
|
+
libHandle.stop();
|
|
149815
|
+
} catch {
|
|
149816
|
+
}
|
|
149817
|
+
LOG2.info(
|
|
149818
|
+
"Seqscribe",
|
|
149819
|
+
`beacon stopped writer=${handle.writerId} put=${counters5.put}/${counters5.put + counters5.putFailed} get=${counters5.get}/${counters5.get + counters5.getFailed} splitRetries=${counters5.splitRetries} truncated=${counters5.truncated} rejected=${counters5.rejected}`
|
|
149820
|
+
);
|
|
149821
|
+
},
|
|
149822
|
+
counters: () => ({ ...counters5 }),
|
|
149823
|
+
async pushNow() {
|
|
149824
|
+
if (stopped) return;
|
|
149825
|
+
try {
|
|
149826
|
+
await doPut({
|
|
149827
|
+
node: handle.writerId,
|
|
149828
|
+
at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
149829
|
+
vectors: handle.node.vectors()
|
|
149830
|
+
});
|
|
149831
|
+
const board = await doGet();
|
|
149832
|
+
if (!stopped) handle.node.setKnownVectors(board);
|
|
149833
|
+
} catch {
|
|
149834
|
+
}
|
|
149835
|
+
}
|
|
149836
|
+
};
|
|
149837
|
+
handle.onClose(() => beaconHandle.stop());
|
|
149838
|
+
return beaconHandle;
|
|
149839
|
+
}
|
|
149418
149840
|
init_topics2();
|
|
149419
149841
|
init_authority();
|
|
149420
149842
|
init_mesh_dual_write();
|