@claude-flow/cli 3.7.0 → 3.8.0
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/src/mcp-tools/wasm-agent-tools.d.ts +4 -0
- package/dist/src/mcp-tools/wasm-agent-tools.d.ts.map +1 -1
- package/dist/src/mcp-tools/wasm-agent-tools.js +549 -0
- package/dist/src/mcp-tools/wasm-agent-tools.js.map +1 -1
- package/dist/src/memory/memory-initializer.d.ts.map +1 -1
- package/dist/src/memory/memory-initializer.js +7 -0
- package/dist/src/memory/memory-initializer.js.map +1 -1
- package/dist/src/ruvector/agent-wasm.d.ts +46 -11
- package/dist/src/ruvector/agent-wasm.d.ts.map +1 -1
- package/dist/src/ruvector/agent-wasm.js +134 -25
- package/dist/src/ruvector/agent-wasm.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/scripts/bench-rvagent.mjs +312 -0
- package/dist/src/__probe.d.ts +0 -2
- package/dist/src/__probe.d.ts.map +0 -1
- package/dist/src/__probe.js +0 -5
- package/dist/src/__probe.js.map +0 -1
- package/dist/src/commands/benchmark-cosign.d.ts +0 -29
- package/dist/src/commands/benchmark-cosign.d.ts.map +0 -1
- package/dist/src/commands/benchmark-cosign.js +0 -222
- package/dist/src/commands/benchmark-cosign.js.map +0 -1
- package/dist/src/commands/benchmark-verify.d.ts +0 -21
- package/dist/src/commands/benchmark-verify.d.ts.map +0 -1
- package/dist/src/commands/benchmark-verify.js +0 -202
- package/dist/src/commands/benchmark-verify.js.map +0 -1
- package/dist/src/mcp-tools/hive-consensus-runtime.d.ts +0 -149
- package/dist/src/mcp-tools/hive-consensus-runtime.d.ts.map +0 -1
- package/dist/src/mcp-tools/hive-consensus-runtime.js +0 -296
- package/dist/src/mcp-tools/hive-consensus-runtime.js.map +0 -1
- package/dist/src/memory/ann-router-registry.d.ts +0 -61
- package/dist/src/memory/ann-router-registry.d.ts.map +0 -1
- package/dist/src/memory/ann-router-registry.js +0 -72
- package/dist/src/memory/ann-router-registry.js.map +0 -1
- package/dist/src/memory/diskann-registry.d.ts +0 -56
- package/dist/src/memory/diskann-registry.d.ts.map +0 -1
- package/dist/src/memory/diskann-registry.js +0 -88
- package/dist/src/memory/diskann-registry.js.map +0 -1
|
@@ -1,202 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ADR-121 Phase 25 — `ruflo benchmark verify` CLI subcommand.
|
|
3
|
-
*
|
|
4
|
-
* Makes the Phase 15-24 witness story end-user-accessible. Anyone
|
|
5
|
-
* publishing benchmark numbers with a witness manifest (single
|
|
6
|
-
* `.json`) or a chained ledger (`bench-witness/ledger.json`) can
|
|
7
|
-
* tell consumers:
|
|
8
|
-
*
|
|
9
|
-
* npx ruflo benchmark verify ./ledger.json
|
|
10
|
-
*
|
|
11
|
-
* The command auto-detects whether the input is a single witness or
|
|
12
|
-
* a ledger (presence of `version` + `entries[]` → ledger), runs the
|
|
13
|
-
* appropriate verifier, and prints a human-readable or JSON report.
|
|
14
|
-
*
|
|
15
|
-
* For Phase 24 multi-signer entries, pass `--threshold N` to require
|
|
16
|
-
* N or more valid signatures per entry.
|
|
17
|
-
*/
|
|
18
|
-
import { promises as fs } from 'node:fs';
|
|
19
|
-
import { resolve } from 'node:path';
|
|
20
|
-
import { output } from '../output.js';
|
|
21
|
-
function isLedger(parsed) {
|
|
22
|
-
return typeof parsed.version === 'number' && Array.isArray(parsed.entries);
|
|
23
|
-
}
|
|
24
|
-
function isWrappedWitness(parsed) {
|
|
25
|
-
return parsed.witness !== undefined && typeof parsed.witness === 'object';
|
|
26
|
-
}
|
|
27
|
-
function isRawWitness(parsed) {
|
|
28
|
-
return typeof parsed.contentHash === 'string' && typeof parsed.signature === 'string';
|
|
29
|
-
}
|
|
30
|
-
export const benchmarkVerifyCommand = {
|
|
31
|
-
name: 'verify',
|
|
32
|
-
description: 'Verify a benchmark witness manifest or chained ledger via the published @claude-flow/embeddings cryptographic primitives',
|
|
33
|
-
options: [
|
|
34
|
-
{
|
|
35
|
-
name: 'threshold',
|
|
36
|
-
short: 't',
|
|
37
|
-
type: 'number',
|
|
38
|
-
description: 'Phase 24 M-of-N: minimum signatures required per entry. Default 1.',
|
|
39
|
-
default: '1',
|
|
40
|
-
},
|
|
41
|
-
{
|
|
42
|
-
name: 'json',
|
|
43
|
-
type: 'boolean',
|
|
44
|
-
description: 'Output JSON instead of human-readable',
|
|
45
|
-
default: 'false',
|
|
46
|
-
},
|
|
47
|
-
],
|
|
48
|
-
examples: [
|
|
49
|
-
{ command: 'ruflo benchmark verify ./bench-witness/ledger.json', description: 'Verify a chained ledger' },
|
|
50
|
-
{ command: 'ruflo benchmark verify ./bench-witness/rag-real-text-*.json', description: 'Verify a single witness manifest' },
|
|
51
|
-
{ command: 'ruflo benchmark verify ledger.json --threshold 3', description: 'Require ≥3 signatures per entry (M-of-N)' },
|
|
52
|
-
{ command: 'ruflo benchmark verify ledger.json --json', description: 'Machine-readable output for CI gating' },
|
|
53
|
-
],
|
|
54
|
-
action: async (ctx) => {
|
|
55
|
-
const pathArg = ctx.args[0];
|
|
56
|
-
const threshold = Number(ctx.flags.threshold ?? 1);
|
|
57
|
-
const asJson = ctx.flags.json === true || ctx.flags.json === 'true';
|
|
58
|
-
if (!pathArg || typeof pathArg !== 'string') {
|
|
59
|
-
const err = 'usage: ruflo benchmark verify <path-to-ledger.json-or-witness.json> [--threshold N] [--json]';
|
|
60
|
-
if (asJson)
|
|
61
|
-
output.printJson({ ok: false, error: err });
|
|
62
|
-
else
|
|
63
|
-
output.printError(err);
|
|
64
|
-
return { success: false, exitCode: 1 };
|
|
65
|
-
}
|
|
66
|
-
if (!Number.isFinite(threshold) || threshold < 1) {
|
|
67
|
-
const err = `--threshold must be a positive integer, got: ${ctx.flags.threshold}`;
|
|
68
|
-
if (asJson)
|
|
69
|
-
output.printJson({ ok: false, error: err });
|
|
70
|
-
else
|
|
71
|
-
output.printError(err);
|
|
72
|
-
return { success: false, exitCode: 1 };
|
|
73
|
-
}
|
|
74
|
-
const absPath = resolve(process.cwd(), pathArg);
|
|
75
|
-
let raw;
|
|
76
|
-
try {
|
|
77
|
-
raw = await fs.readFile(absPath, 'utf8');
|
|
78
|
-
}
|
|
79
|
-
catch (err) {
|
|
80
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
81
|
-
if (asJson)
|
|
82
|
-
output.printJson({ ok: false, error: `cannot read ${absPath}: ${msg}` });
|
|
83
|
-
else
|
|
84
|
-
output.printError(`Cannot read ${absPath}: ${msg}`);
|
|
85
|
-
return { success: false, exitCode: 1 };
|
|
86
|
-
}
|
|
87
|
-
let parsed;
|
|
88
|
-
try {
|
|
89
|
-
parsed = JSON.parse(raw);
|
|
90
|
-
}
|
|
91
|
-
catch (err) {
|
|
92
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
93
|
-
if (asJson)
|
|
94
|
-
output.printJson({ ok: false, error: `not valid JSON: ${msg}` });
|
|
95
|
-
else
|
|
96
|
-
output.printError(`Not valid JSON: ${msg}`);
|
|
97
|
-
return { success: false, exitCode: 1 };
|
|
98
|
-
}
|
|
99
|
-
// Lazy-import the embeddings verifiers so the CLI startup stays fast
|
|
100
|
-
// when this command isn't used.
|
|
101
|
-
const { verify } = await import('@claude-flow/embeddings/witness');
|
|
102
|
-
const { verifyLedger, verifyEntry } = await import('@claude-flow/embeddings/witness-ledger');
|
|
103
|
-
// === Path 1: chained ledger ===
|
|
104
|
-
if (isLedger(parsed)) {
|
|
105
|
-
const ledger = parsed;
|
|
106
|
-
const result = verifyLedger(ledger, { minSignatures: threshold });
|
|
107
|
-
if (asJson) {
|
|
108
|
-
output.printJson({
|
|
109
|
-
ok: result.valid,
|
|
110
|
-
kind: 'ledger',
|
|
111
|
-
entryCount: result.entryCount,
|
|
112
|
-
firstFailureAt: result.firstFailureAt,
|
|
113
|
-
reason: result.reason,
|
|
114
|
-
threshold,
|
|
115
|
-
path: absPath,
|
|
116
|
-
});
|
|
117
|
-
return { success: result.valid, exitCode: result.valid ? 0 : 1 };
|
|
118
|
-
}
|
|
119
|
-
output.writeln();
|
|
120
|
-
output.writeln(output.bold(`Ledger verification (${absPath})`));
|
|
121
|
-
output.writeln(output.dim('─'.repeat(60)));
|
|
122
|
-
output.writeln(` entries: ${result.entryCount}`);
|
|
123
|
-
output.writeln(` threshold: minSignatures = ${threshold}`);
|
|
124
|
-
output.writeln(` verifyLedger(): ${result.valid ? output.success('TRUE') : output.error('FALSE')}`);
|
|
125
|
-
if (!result.valid) {
|
|
126
|
-
output.writeln(` failure at: entry ${result.firstFailureAt}`);
|
|
127
|
-
output.writeln(` reason: ${result.reason}`);
|
|
128
|
-
}
|
|
129
|
-
// Per-entry summary table
|
|
130
|
-
const entries = ledger.entries;
|
|
131
|
-
output.writeln();
|
|
132
|
-
output.writeln(' per-entry:');
|
|
133
|
-
for (const e of entries) {
|
|
134
|
-
const cosigCount = Array.isArray(e.cosignatures) ? e.cosignatures.length : 0;
|
|
135
|
-
const ok = verifyEntry(e, { minSignatures: threshold });
|
|
136
|
-
const verdict = ok ? output.success('✓') : output.error('✗');
|
|
137
|
-
const hashShort = e.contentHash.slice(0, 12) + '…';
|
|
138
|
-
output.writeln(` [${String(e.sequence).padStart(2)}] ${e.benchmark.padEnd(28)} sigs=${1 + cosigCount} ${hashShort} ${verdict}`);
|
|
139
|
-
}
|
|
140
|
-
output.writeln();
|
|
141
|
-
return { success: result.valid, exitCode: result.valid ? 0 : 1 };
|
|
142
|
-
}
|
|
143
|
-
// === Path 2: wrapped single witness (the bench scripts' output shape) ===
|
|
144
|
-
if (isWrappedWitness(parsed)) {
|
|
145
|
-
const w = parsed.witness;
|
|
146
|
-
const ok = verify(w);
|
|
147
|
-
if (asJson) {
|
|
148
|
-
output.printJson({
|
|
149
|
-
ok,
|
|
150
|
-
kind: 'witness',
|
|
151
|
-
benchmark: w.benchmark,
|
|
152
|
-
contentHash: w.contentHash,
|
|
153
|
-
path: absPath,
|
|
154
|
-
});
|
|
155
|
-
return { success: ok, exitCode: ok ? 0 : 1 };
|
|
156
|
-
}
|
|
157
|
-
output.writeln();
|
|
158
|
-
output.writeln(output.bold(`Witness verification (${absPath})`));
|
|
159
|
-
output.writeln(output.dim('─'.repeat(60)));
|
|
160
|
-
output.writeln(` benchmark: ${w.benchmark}`);
|
|
161
|
-
output.writeln(` contentHash: ${w.contentHash}`);
|
|
162
|
-
output.writeln(` signature: ${w.signature.slice(0, 32)}...`);
|
|
163
|
-
output.writeln(` publicKey: ${w.publicKey.slice(0, 32)}...`);
|
|
164
|
-
output.writeln(` algorithm: ${w.signatureAlgorithm}`);
|
|
165
|
-
output.writeln(` verify(): ${ok ? output.success('TRUE') : output.error('FALSE')}`);
|
|
166
|
-
output.writeln();
|
|
167
|
-
return { success: ok, exitCode: ok ? 0 : 1 };
|
|
168
|
-
}
|
|
169
|
-
// === Path 3: raw single witness (top-level fields, no wrapper) ===
|
|
170
|
-
if (isRawWitness(parsed)) {
|
|
171
|
-
const w = parsed;
|
|
172
|
-
const ok = verify(w);
|
|
173
|
-
if (asJson) {
|
|
174
|
-
output.printJson({
|
|
175
|
-
ok,
|
|
176
|
-
kind: 'witness-raw',
|
|
177
|
-
benchmark: w.benchmark,
|
|
178
|
-
contentHash: w.contentHash,
|
|
179
|
-
path: absPath,
|
|
180
|
-
});
|
|
181
|
-
return { success: ok, exitCode: ok ? 0 : 1 };
|
|
182
|
-
}
|
|
183
|
-
output.writeln();
|
|
184
|
-
output.writeln(output.bold(`Witness verification (${absPath})`));
|
|
185
|
-
output.writeln(output.dim('─'.repeat(60)));
|
|
186
|
-
output.writeln(` benchmark: ${w.benchmark}`);
|
|
187
|
-
output.writeln(` contentHash: ${w.contentHash}`);
|
|
188
|
-
output.writeln(` verify(): ${ok ? output.success('TRUE') : output.error('FALSE')}`);
|
|
189
|
-
output.writeln();
|
|
190
|
-
return { success: ok, exitCode: ok ? 0 : 1 };
|
|
191
|
-
}
|
|
192
|
-
// === Path 4: unknown shape ===
|
|
193
|
-
const err = `unrecognized file shape — expected a benchmark ledger ({version, entries}), a wrapped witness ({witness: {...}}), or a raw witness ({contentHash, signature, publicKey})`;
|
|
194
|
-
if (asJson)
|
|
195
|
-
output.printJson({ ok: false, error: err, path: absPath });
|
|
196
|
-
else
|
|
197
|
-
output.printError(err);
|
|
198
|
-
return { success: false, exitCode: 1 };
|
|
199
|
-
},
|
|
200
|
-
};
|
|
201
|
-
export default benchmarkVerifyCommand;
|
|
202
|
-
//# sourceMappingURL=benchmark-verify.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"benchmark-verify.js","sourceRoot":"","sources":["../../../src/commands/benchmark-verify.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,149 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Hive-Mind Consensus Runtime — ADR-095 G2.2.
|
|
3
|
-
*
|
|
4
|
-
* Before this module, `hive-mind_*` MCP tools were a JSON-file state machine
|
|
5
|
-
* that hand-rolled raft/byzantine/quorum voting on top of `state.consensus`
|
|
6
|
-
* and never touched `@claude-flow/swarm`'s real `ConsensusEngine`. That worked
|
|
7
|
-
* for a single MCP server but ignored every cross-host machinery G2 was meant
|
|
8
|
-
* to unlock: real RequestVote/AppendEntries RPCs, Ed25519-signed PBFT
|
|
9
|
-
* messages, FederationTransport over ADR-104 WS, BFT quorum derived from
|
|
10
|
-
* actual cluster size.
|
|
11
|
-
*
|
|
12
|
-
* This module owns a process-level `ConsensusEngine` plus a pluggable
|
|
13
|
-
* `ConsensusTransport`. `hive-mind_init` calls `init()` here; the consensus /
|
|
14
|
-
* broadcast / shutdown MCP tools delegate to it.
|
|
15
|
-
*
|
|
16
|
-
* Transport selection:
|
|
17
|
-
* - `transport: 'local'` → LocalTransport (in-process registry).
|
|
18
|
-
* Matches the legacy single-process path;
|
|
19
|
-
* real engine, just no WS.
|
|
20
|
-
* - `transport: 'federation'` → FederationTransport over an
|
|
21
|
-
* agentic-flow/transport/loader wire.
|
|
22
|
-
* Real cross-host messaging. Requires
|
|
23
|
-
* `agentic-flow` to be resolvable; if
|
|
24
|
-
* it's not, init returns
|
|
25
|
-
* `transport: 'local'` with `degraded:
|
|
26
|
-
* true` and a fallbackReason — the
|
|
27
|
-
* engine still works locally, the caller
|
|
28
|
-
* just knows the cross-host wire didn't
|
|
29
|
-
* come up.
|
|
30
|
-
* - `transport: 'auto'` (default)→ Probe for `agentic-flow`; if loadable
|
|
31
|
-
* AND `peers` were supplied with
|
|
32
|
-
* addresses, use federation; else local.
|
|
33
|
-
*
|
|
34
|
-
* Why peers are passed in (not auto-discovered): the federation plugin's
|
|
35
|
-
* DiscoveryService is the canonical source of peers, but wiring it into the
|
|
36
|
-
* MCP runtime is a separate concern (it has its own lifecycle / consent
|
|
37
|
-
* gates). Until that lands as G2.3, callers explicitly supply the peer
|
|
38
|
-
* list; the runtime is honest about what it received.
|
|
39
|
-
*/
|
|
40
|
-
import type { ConsensusEngine as ConsensusEngineType, ConsensusTransport as ConsensusTransportType, ConsensusVote, ConsensusProposal, ConsensusResult, ConsensusAlgorithm } from '@claude-flow/swarm';
|
|
41
|
-
export type HiveTransportKind = 'local' | 'federation' | 'auto';
|
|
42
|
-
export type HiveAlgorithm = 'raft' | 'byzantine' | 'gossip';
|
|
43
|
-
export interface HivePeerConfig {
|
|
44
|
-
/** Consensus node id used by Raft/PBFT/Gossip as `from`. */
|
|
45
|
-
readonly nodeId: string;
|
|
46
|
-
/**
|
|
47
|
-
* Wire-level address (e.g. `wss://host:port`). Required for
|
|
48
|
-
* `transport: 'federation'`; ignored for `transport: 'local'`.
|
|
49
|
-
*/
|
|
50
|
-
readonly address?: string;
|
|
51
|
-
/**
|
|
52
|
-
* Ed25519 SPKI PEM public key for inbound signature verification.
|
|
53
|
-
* When provided, FederationTransport will fail-closed on unverifiable
|
|
54
|
-
* messages from this peer.
|
|
55
|
-
*/
|
|
56
|
-
readonly publicKeyPem?: string;
|
|
57
|
-
}
|
|
58
|
-
export interface HiveRuntimeInitOptions {
|
|
59
|
-
readonly nodeId: string;
|
|
60
|
-
readonly algorithm?: HiveAlgorithm;
|
|
61
|
-
readonly transport?: HiveTransportKind;
|
|
62
|
-
readonly peers?: readonly HivePeerConfig[];
|
|
63
|
-
/** Default per-send timeout for transports. */
|
|
64
|
-
readonly timeoutMs?: number;
|
|
65
|
-
/** Consensus threshold (0-1). Forwarded to ConsensusEngine. */
|
|
66
|
-
readonly threshold?: number;
|
|
67
|
-
}
|
|
68
|
-
export interface HiveRuntimeInitResult {
|
|
69
|
-
readonly initialized: true;
|
|
70
|
-
readonly nodeId: string;
|
|
71
|
-
readonly algorithm: HiveAlgorithm;
|
|
72
|
-
/** What we actually got — may differ from requested if federation degraded. */
|
|
73
|
-
readonly transport: 'local' | 'federation';
|
|
74
|
-
/** True when the caller asked for federation but we fell back to local. */
|
|
75
|
-
readonly degraded: boolean;
|
|
76
|
-
/** Human-readable reason for the degradation. */
|
|
77
|
-
readonly fallbackReason?: string;
|
|
78
|
-
readonly peerCount: number;
|
|
79
|
-
readonly source: 'engine';
|
|
80
|
-
}
|
|
81
|
-
export interface HiveRuntimeStatus {
|
|
82
|
-
readonly initialized: boolean;
|
|
83
|
-
readonly nodeId?: string;
|
|
84
|
-
readonly algorithm?: HiveAlgorithm;
|
|
85
|
-
readonly transport: 'local' | 'federation' | null;
|
|
86
|
-
readonly degraded: boolean;
|
|
87
|
-
readonly peers: readonly string[];
|
|
88
|
-
readonly engine: {
|
|
89
|
-
readonly algorithm: ConsensusAlgorithm;
|
|
90
|
-
readonly totalProposals: number;
|
|
91
|
-
readonly pendingProposals: number;
|
|
92
|
-
readonly acceptedProposals: number;
|
|
93
|
-
readonly rejectedProposals: number;
|
|
94
|
-
readonly expiredProposals: number;
|
|
95
|
-
} | null;
|
|
96
|
-
}
|
|
97
|
-
declare class HiveConsensusRuntime {
|
|
98
|
-
private engine;
|
|
99
|
-
private transport;
|
|
100
|
-
private wire;
|
|
101
|
-
private transportKind;
|
|
102
|
-
private nodeId;
|
|
103
|
-
private algorithm;
|
|
104
|
-
private peers;
|
|
105
|
-
private degraded;
|
|
106
|
-
private fallbackReason;
|
|
107
|
-
isInitialized(): boolean;
|
|
108
|
-
/**
|
|
109
|
-
* Lazy-initialize the consensus engine + transport. Idempotent on the
|
|
110
|
-
* same nodeId/algorithm/transport tuple — subsequent calls return the
|
|
111
|
-
* existing state. Different parameters trigger a clean shutdown + reinit.
|
|
112
|
-
*/
|
|
113
|
-
init(opts: HiveRuntimeInitOptions): Promise<HiveRuntimeInitResult>;
|
|
114
|
-
/**
|
|
115
|
-
* Probe for the agentic-flow QUIC/WS transport loader. Returns the wire
|
|
116
|
-
* when loadable; an explanatory reason when not. Never throws — failure
|
|
117
|
-
* is data, not control flow, so the runtime can degrade cleanly.
|
|
118
|
-
*/
|
|
119
|
-
private tryLoadFederationWire;
|
|
120
|
-
/** Propose a value through the real ConsensusEngine. */
|
|
121
|
-
propose(value: unknown, proposerId?: string): Promise<ConsensusProposal>;
|
|
122
|
-
/** Record a vote against an active proposal. */
|
|
123
|
-
vote(proposalId: string, vote: ConsensusVote): Promise<void>;
|
|
124
|
-
/**
|
|
125
|
-
* Block until a proposal resolves (accepted / rejected / expired).
|
|
126
|
-
* Used by the MCP tool when callers want a synchronous result instead
|
|
127
|
-
* of polling `proposal-status`.
|
|
128
|
-
*/
|
|
129
|
-
awaitConsensus(proposalId: string): Promise<ConsensusResult>;
|
|
130
|
-
/**
|
|
131
|
-
* Broadcast a free-form payload to all known peers via the transport.
|
|
132
|
-
* Gossip-style, no reply expected. Wraps the payload so peers don't
|
|
133
|
-
* confuse it with protocol messages — `type: 'hive-broadcast'`.
|
|
134
|
-
*/
|
|
135
|
-
broadcast(payload: unknown, priority?: 'low' | 'normal' | 'high' | 'critical'): Promise<{
|
|
136
|
-
delivered: number;
|
|
137
|
-
transport: 'local' | 'federation';
|
|
138
|
-
}>;
|
|
139
|
-
status(): HiveRuntimeStatus;
|
|
140
|
-
shutdown(): Promise<void>;
|
|
141
|
-
/** Test seam: replace the singleton's underlying engine + transport. */
|
|
142
|
-
__setForTest(engine: ConsensusEngineType, transport: ConsensusTransportType, nodeId: string, kind?: 'local' | 'federation'): void;
|
|
143
|
-
private toInitResult;
|
|
144
|
-
}
|
|
145
|
-
/** Process-level singleton — one engine per MCP server. */
|
|
146
|
-
export declare const hiveConsensusRuntime: HiveConsensusRuntime;
|
|
147
|
-
/** Re-export the singleton's type for tests / advanced consumers. */
|
|
148
|
-
export type { HiveConsensusRuntime };
|
|
149
|
-
//# sourceMappingURL=hive-consensus-runtime.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"hive-consensus-runtime.d.ts","sourceRoot":"","sources":["../../../src/mcp-tools/hive-consensus-runtime.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAEH,OAAO,KAAK,EACV,eAAe,IAAI,mBAAmB,EACtC,kBAAkB,IAAI,sBAAsB,EAC5C,aAAa,EACb,iBAAiB,EACjB,eAAe,EACf,kBAAkB,EACnB,MAAM,oBAAoB,CAAC;AAE5B,MAAM,MAAM,iBAAiB,GAAG,OAAO,GAAG,YAAY,GAAG,MAAM,CAAC;AAChE,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,WAAW,GAAG,QAAQ,CAAC;AAE5D,MAAM,WAAW,cAAc;IAC7B,4DAA4D;IAC5D,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB;;;OAGG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;OAIG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,SAAS,CAAC,EAAE,aAAa,CAAC;IACnC,QAAQ,CAAC,SAAS,CAAC,EAAE,iBAAiB,CAAC;IACvC,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,cAAc,EAAE,CAAC;IAC3C,+CAA+C;IAC/C,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,+DAA+D;IAC/D,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,WAAW,EAAE,IAAI,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,SAAS,EAAE,aAAa,CAAC;IAClC,+EAA+E;IAC/E,QAAQ,CAAC,SAAS,EAAE,OAAO,GAAG,YAAY,CAAC;IAC3C,2EAA2E;IAC3E,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,iDAAiD;IACjD,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC;CAC3B;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAC9B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,CAAC,EAAE,aAAa,CAAC;IACnC,QAAQ,CAAC,SAAS,EAAE,OAAO,GAAG,YAAY,GAAG,IAAI,CAAC;IAClD,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,QAAQ,CAAC,MAAM,EAAE;QACf,QAAQ,CAAC,SAAS,EAAE,kBAAkB,CAAC;QACvC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;QAChC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;QAClC,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;QACnC,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;QACnC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;KACnC,GAAG,IAAI,CAAC;CACV;AAQD,cAAM,oBAAoB;IACxB,OAAO,CAAC,MAAM,CAAoC;IAClD,OAAO,CAAC,SAAS,CAAuC;IACxD,OAAO,CAAC,IAAI,CAAyC;IACrD,OAAO,CAAC,aAAa,CAAuC;IAC5D,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,SAAS,CAAyB;IAC1C,OAAO,CAAC,KAAK,CAAwB;IACrC,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,cAAc,CAAqB;IAE3C,aAAa,IAAI,OAAO;IAIxB;;;;OAIG;IACG,IAAI,CAAC,IAAI,EAAE,sBAAsB,GAAG,OAAO,CAAC,qBAAqB,CAAC;IAiGxE;;;;OAIG;YACW,qBAAqB;IAoCnC,wDAAwD;IAClD,OAAO,CAAC,KAAK,EAAE,OAAO,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAK9E,gDAAgD;IAC1C,IAAI,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAKlE;;;;OAIG;IACG,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;IAKlE;;;;OAIG;IACG,SAAS,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,GAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,UAAqB,GAAG,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,OAAO,GAAG,YAAY,CAAA;KAAE,CAAC;IAUjK,MAAM,IAAI,iBAAiB;IAqBrB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAuB/B,wEAAwE;IACxE,YAAY,CAAC,MAAM,EAAE,mBAAmB,EAAE,SAAS,EAAE,sBAAsB,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE,OAAO,GAAG,YAAsB,GAAG,IAAI;IAO1I,OAAO,CAAC,YAAY;CAYrB;AAED,2DAA2D;AAC3D,eAAO,MAAM,oBAAoB,sBAA6B,CAAC;AAE/D,qEAAqE;AACrE,YAAY,EAAE,oBAAoB,EAAE,CAAC"}
|
|
@@ -1,296 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Hive-Mind Consensus Runtime — ADR-095 G2.2.
|
|
3
|
-
*
|
|
4
|
-
* Before this module, `hive-mind_*` MCP tools were a JSON-file state machine
|
|
5
|
-
* that hand-rolled raft/byzantine/quorum voting on top of `state.consensus`
|
|
6
|
-
* and never touched `@claude-flow/swarm`'s real `ConsensusEngine`. That worked
|
|
7
|
-
* for a single MCP server but ignored every cross-host machinery G2 was meant
|
|
8
|
-
* to unlock: real RequestVote/AppendEntries RPCs, Ed25519-signed PBFT
|
|
9
|
-
* messages, FederationTransport over ADR-104 WS, BFT quorum derived from
|
|
10
|
-
* actual cluster size.
|
|
11
|
-
*
|
|
12
|
-
* This module owns a process-level `ConsensusEngine` plus a pluggable
|
|
13
|
-
* `ConsensusTransport`. `hive-mind_init` calls `init()` here; the consensus /
|
|
14
|
-
* broadcast / shutdown MCP tools delegate to it.
|
|
15
|
-
*
|
|
16
|
-
* Transport selection:
|
|
17
|
-
* - `transport: 'local'` → LocalTransport (in-process registry).
|
|
18
|
-
* Matches the legacy single-process path;
|
|
19
|
-
* real engine, just no WS.
|
|
20
|
-
* - `transport: 'federation'` → FederationTransport over an
|
|
21
|
-
* agentic-flow/transport/loader wire.
|
|
22
|
-
* Real cross-host messaging. Requires
|
|
23
|
-
* `agentic-flow` to be resolvable; if
|
|
24
|
-
* it's not, init returns
|
|
25
|
-
* `transport: 'local'` with `degraded:
|
|
26
|
-
* true` and a fallbackReason — the
|
|
27
|
-
* engine still works locally, the caller
|
|
28
|
-
* just knows the cross-host wire didn't
|
|
29
|
-
* come up.
|
|
30
|
-
* - `transport: 'auto'` (default)→ Probe for `agentic-flow`; if loadable
|
|
31
|
-
* AND `peers` were supplied with
|
|
32
|
-
* addresses, use federation; else local.
|
|
33
|
-
*
|
|
34
|
-
* Why peers are passed in (not auto-discovered): the federation plugin's
|
|
35
|
-
* DiscoveryService is the canonical source of peers, but wiring it into the
|
|
36
|
-
* MCP runtime is a separate concern (it has its own lifecycle / consent
|
|
37
|
-
* gates). Until that lands as G2.3, callers explicitly supply the peer
|
|
38
|
-
* list; the runtime is honest about what it received.
|
|
39
|
-
*/
|
|
40
|
-
class HiveConsensusRuntime {
|
|
41
|
-
engine = null;
|
|
42
|
-
transport = null;
|
|
43
|
-
wire = null;
|
|
44
|
-
transportKind = null;
|
|
45
|
-
nodeId = null;
|
|
46
|
-
algorithm = 'raft';
|
|
47
|
-
peers = [];
|
|
48
|
-
degraded = false;
|
|
49
|
-
fallbackReason;
|
|
50
|
-
isInitialized() {
|
|
51
|
-
return this.engine !== null;
|
|
52
|
-
}
|
|
53
|
-
/**
|
|
54
|
-
* Lazy-initialize the consensus engine + transport. Idempotent on the
|
|
55
|
-
* same nodeId/algorithm/transport tuple — subsequent calls return the
|
|
56
|
-
* existing state. Different parameters trigger a clean shutdown + reinit.
|
|
57
|
-
*/
|
|
58
|
-
async init(opts) {
|
|
59
|
-
const requestedAlgorithm = opts.algorithm ?? 'raft';
|
|
60
|
-
const requestedTransport = opts.transport ?? 'auto';
|
|
61
|
-
const peers = [...(opts.peers ?? [])];
|
|
62
|
-
// If already initialized with the same shape, return existing state.
|
|
63
|
-
if (this.engine && this.nodeId === opts.nodeId && this.algorithm === requestedAlgorithm) {
|
|
64
|
-
return this.toInitResult();
|
|
65
|
-
}
|
|
66
|
-
// Different shape — tear down before re-instantiating.
|
|
67
|
-
if (this.engine) {
|
|
68
|
-
await this.shutdown();
|
|
69
|
-
}
|
|
70
|
-
const swarm = await import('@claude-flow/swarm');
|
|
71
|
-
// Resolve transport. 'auto' prefers federation when the loader is
|
|
72
|
-
// available AND we have peer addresses; otherwise local.
|
|
73
|
-
let resolvedKind;
|
|
74
|
-
let resolvedTransport;
|
|
75
|
-
let degraded = false;
|
|
76
|
-
let fallbackReason;
|
|
77
|
-
if (requestedTransport === 'local') {
|
|
78
|
-
resolvedKind = 'local';
|
|
79
|
-
resolvedTransport = new swarm.LocalTransport(opts.nodeId, {
|
|
80
|
-
defaultTimeoutMs: opts.timeoutMs,
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
|
-
else {
|
|
84
|
-
// 'federation' or 'auto' → probe agentic-flow loader.
|
|
85
|
-
const probe = await this.tryLoadFederationWire(opts);
|
|
86
|
-
if (probe.wire) {
|
|
87
|
-
// Build the addressOf map from peers config.
|
|
88
|
-
const addressMap = new Map();
|
|
89
|
-
const pubkeyMap = new Map();
|
|
90
|
-
for (const p of peers) {
|
|
91
|
-
if (p.address)
|
|
92
|
-
addressMap.set(p.nodeId, p.address);
|
|
93
|
-
if (p.publicKeyPem)
|
|
94
|
-
pubkeyMap.set(p.nodeId, p.publicKeyPem);
|
|
95
|
-
}
|
|
96
|
-
this.wire = probe.wire;
|
|
97
|
-
resolvedKind = 'federation';
|
|
98
|
-
resolvedTransport = new swarm.FederationTransport(probe.wire, {
|
|
99
|
-
nodeId: opts.nodeId,
|
|
100
|
-
addressOf: (id) => addressMap.get(id),
|
|
101
|
-
peerIds: () => peers.map(p => p.nodeId),
|
|
102
|
-
defaultTimeoutMs: opts.timeoutMs,
|
|
103
|
-
resolvePeerPublicKey: pubkeyMap.size > 0 ? (id) => pubkeyMap.get(id) : undefined,
|
|
104
|
-
});
|
|
105
|
-
}
|
|
106
|
-
else {
|
|
107
|
-
// Couldn't load federation wire. 'federation' requested → degrade
|
|
108
|
-
// honestly. 'auto' → silently fall back to local.
|
|
109
|
-
if (requestedTransport === 'federation') {
|
|
110
|
-
degraded = true;
|
|
111
|
-
fallbackReason = probe.reason ?? 'agentic-flow loader unavailable';
|
|
112
|
-
}
|
|
113
|
-
resolvedKind = 'local';
|
|
114
|
-
resolvedTransport = new swarm.LocalTransport(opts.nodeId, {
|
|
115
|
-
defaultTimeoutMs: opts.timeoutMs,
|
|
116
|
-
});
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
// Build the engine with the resolved transport. We pass `transport`
|
|
120
|
-
// through `config.transport` (typed `unknown` on `ConsensusConfig` in
|
|
121
|
-
// swarm's types.ts — the engine narrows it via a structural check).
|
|
122
|
-
const engine = new swarm.ConsensusEngine(opts.nodeId, {
|
|
123
|
-
algorithm: requestedAlgorithm,
|
|
124
|
-
threshold: opts.threshold ?? 0.66,
|
|
125
|
-
timeoutMs: opts.timeoutMs ?? 30_000,
|
|
126
|
-
maxRounds: 10,
|
|
127
|
-
requireQuorum: true,
|
|
128
|
-
transport: resolvedTransport,
|
|
129
|
-
});
|
|
130
|
-
await engine.initialize();
|
|
131
|
-
// Register peers with the consensus engine so its protocol-internal
|
|
132
|
-
// bookkeeping (Raft's `peers` map, BFT's node set, gossip neighbors)
|
|
133
|
-
// matches the transport's peer list.
|
|
134
|
-
for (const p of peers) {
|
|
135
|
-
if (p.nodeId === opts.nodeId)
|
|
136
|
-
continue;
|
|
137
|
-
engine.addNode(p.nodeId);
|
|
138
|
-
}
|
|
139
|
-
this.engine = engine;
|
|
140
|
-
this.transport = resolvedTransport;
|
|
141
|
-
this.transportKind = resolvedKind;
|
|
142
|
-
this.nodeId = opts.nodeId;
|
|
143
|
-
this.algorithm = requestedAlgorithm;
|
|
144
|
-
this.peers = peers;
|
|
145
|
-
this.degraded = degraded;
|
|
146
|
-
this.fallbackReason = fallbackReason;
|
|
147
|
-
return this.toInitResult();
|
|
148
|
-
}
|
|
149
|
-
/**
|
|
150
|
-
* Probe for the agentic-flow QUIC/WS transport loader. Returns the wire
|
|
151
|
-
* when loadable; an explanatory reason when not. Never throws — failure
|
|
152
|
-
* is data, not control flow, so the runtime can degrade cleanly.
|
|
153
|
-
*/
|
|
154
|
-
async tryLoadFederationWire(_opts) {
|
|
155
|
-
// agentic-flow is an *optional* peer dep — when it isn't installed,
|
|
156
|
-
// dynamic import throws and we degrade. The bare-string specifier
|
|
157
|
-
// is wrapped in a `new Function(...)` so the TS compiler doesn't try
|
|
158
|
-
// to resolve types at build time (the same pattern the federation
|
|
159
|
-
// plugin's loader uses, see ADR-120 step 2 comments).
|
|
160
|
-
const importDynamic = new Function('s', 'return import(s)');
|
|
161
|
-
let mod;
|
|
162
|
-
try {
|
|
163
|
-
mod = await importDynamic('agentic-flow/transport/loader');
|
|
164
|
-
}
|
|
165
|
-
catch (err) {
|
|
166
|
-
return { wire: null, reason: `agentic-flow not installed (${err.message ?? 'unknown'})` };
|
|
167
|
-
}
|
|
168
|
-
const m = mod;
|
|
169
|
-
const fn = typeof m.loadQuicTransport === 'function'
|
|
170
|
-
? m.loadQuicTransport
|
|
171
|
-
: m.default?.loadQuicTransport;
|
|
172
|
-
if (typeof fn !== 'function') {
|
|
173
|
-
return { wire: null, reason: 'agentic-flow loader does not expose loadQuicTransport' };
|
|
174
|
-
}
|
|
175
|
-
try {
|
|
176
|
-
const wire = await fn();
|
|
177
|
-
if (!wire || typeof wire.send !== 'function' || typeof wire.onMessage !== 'function') {
|
|
178
|
-
return { wire: null, reason: 'agentic-flow loader returned a wire without send/onMessage' };
|
|
179
|
-
}
|
|
180
|
-
return { wire };
|
|
181
|
-
}
|
|
182
|
-
catch (err) {
|
|
183
|
-
return { wire: null, reason: `agentic-flow loader threw: ${err.message ?? 'unknown'}` };
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
/** Propose a value through the real ConsensusEngine. */
|
|
187
|
-
async propose(value, proposerId) {
|
|
188
|
-
if (!this.engine)
|
|
189
|
-
throw new Error('hive-consensus-runtime: not initialized');
|
|
190
|
-
return this.engine.propose(value, proposerId ?? this.nodeId ?? 'unknown');
|
|
191
|
-
}
|
|
192
|
-
/** Record a vote against an active proposal. */
|
|
193
|
-
async vote(proposalId, vote) {
|
|
194
|
-
if (!this.engine)
|
|
195
|
-
throw new Error('hive-consensus-runtime: not initialized');
|
|
196
|
-
await this.engine.vote(proposalId, vote);
|
|
197
|
-
}
|
|
198
|
-
/**
|
|
199
|
-
* Block until a proposal resolves (accepted / rejected / expired).
|
|
200
|
-
* Used by the MCP tool when callers want a synchronous result instead
|
|
201
|
-
* of polling `proposal-status`.
|
|
202
|
-
*/
|
|
203
|
-
async awaitConsensus(proposalId) {
|
|
204
|
-
if (!this.engine)
|
|
205
|
-
throw new Error('hive-consensus-runtime: not initialized');
|
|
206
|
-
return this.engine.awaitConsensus(proposalId);
|
|
207
|
-
}
|
|
208
|
-
/**
|
|
209
|
-
* Broadcast a free-form payload to all known peers via the transport.
|
|
210
|
-
* Gossip-style, no reply expected. Wraps the payload so peers don't
|
|
211
|
-
* confuse it with protocol messages — `type: 'hive-broadcast'`.
|
|
212
|
-
*/
|
|
213
|
-
async broadcast(payload, priority = 'normal') {
|
|
214
|
-
if (!this.transport)
|
|
215
|
-
throw new Error('hive-consensus-runtime: not initialized');
|
|
216
|
-
const peers = this.transport.peers();
|
|
217
|
-
await this.transport.broadcast({
|
|
218
|
-
type: 'hive-broadcast',
|
|
219
|
-
payload: { value: payload, priority, sentAt: new Date().toISOString() },
|
|
220
|
-
});
|
|
221
|
-
return { delivered: peers.length, transport: this.transportKind };
|
|
222
|
-
}
|
|
223
|
-
status() {
|
|
224
|
-
if (!this.engine || !this.transport) {
|
|
225
|
-
return {
|
|
226
|
-
initialized: false,
|
|
227
|
-
transport: null,
|
|
228
|
-
degraded: false,
|
|
229
|
-
peers: [],
|
|
230
|
-
engine: null,
|
|
231
|
-
};
|
|
232
|
-
}
|
|
233
|
-
return {
|
|
234
|
-
initialized: true,
|
|
235
|
-
nodeId: this.nodeId,
|
|
236
|
-
algorithm: this.algorithm,
|
|
237
|
-
transport: this.transportKind,
|
|
238
|
-
degraded: this.degraded,
|
|
239
|
-
peers: [...this.transport.peers()],
|
|
240
|
-
engine: this.engine.getStats(),
|
|
241
|
-
};
|
|
242
|
-
}
|
|
243
|
-
async shutdown() {
|
|
244
|
-
const engine = this.engine;
|
|
245
|
-
const transport = this.transport;
|
|
246
|
-
const wire = this.wire;
|
|
247
|
-
this.engine = null;
|
|
248
|
-
this.transport = null;
|
|
249
|
-
this.wire = null;
|
|
250
|
-
this.transportKind = null;
|
|
251
|
-
this.nodeId = null;
|
|
252
|
-
this.peers = [];
|
|
253
|
-
this.degraded = false;
|
|
254
|
-
this.fallbackReason = undefined;
|
|
255
|
-
if (engine) {
|
|
256
|
-
try {
|
|
257
|
-
await engine.shutdown();
|
|
258
|
-
}
|
|
259
|
-
catch { /* best-effort */ }
|
|
260
|
-
}
|
|
261
|
-
if (transport) {
|
|
262
|
-
try {
|
|
263
|
-
await transport.close();
|
|
264
|
-
}
|
|
265
|
-
catch { /* best-effort */ }
|
|
266
|
-
}
|
|
267
|
-
if (wire && typeof wire.close === 'function') {
|
|
268
|
-
try {
|
|
269
|
-
await wire.close();
|
|
270
|
-
}
|
|
271
|
-
catch { /* best-effort */ }
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
/** Test seam: replace the singleton's underlying engine + transport. */
|
|
275
|
-
__setForTest(engine, transport, nodeId, kind = 'local') {
|
|
276
|
-
this.engine = engine;
|
|
277
|
-
this.transport = transport;
|
|
278
|
-
this.nodeId = nodeId;
|
|
279
|
-
this.transportKind = kind;
|
|
280
|
-
}
|
|
281
|
-
toInitResult() {
|
|
282
|
-
return {
|
|
283
|
-
initialized: true,
|
|
284
|
-
nodeId: this.nodeId,
|
|
285
|
-
algorithm: this.algorithm,
|
|
286
|
-
transport: this.transportKind,
|
|
287
|
-
degraded: this.degraded,
|
|
288
|
-
fallbackReason: this.fallbackReason,
|
|
289
|
-
peerCount: this.peers.length,
|
|
290
|
-
source: 'engine',
|
|
291
|
-
};
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
/** Process-level singleton — one engine per MCP server. */
|
|
295
|
-
export const hiveConsensusRuntime = new HiveConsensusRuntime();
|
|
296
|
-
//# sourceMappingURL=hive-consensus-runtime.js.map
|