@mcsherrylabs/pi-meerkat 0.7.0 → 0.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/README.md +85 -33
- package/dist/installer/committee-init.sh +117 -0
- package/dist/installer/committee.conf +102 -0
- package/dist/installer/node-join.sh +228 -0
- package/dist/installer/node.conf +235 -0
- package/dist/installer/runtime.json +1 -0
- package/dist/installer-runtime/dist/scripts/recover-owner.js +15 -0
- package/dist/installer-runtime/dist/scripts/subscriptions-init.js +35 -0
- package/dist/installer-runtime/dist/scripts/versions.mjs +86 -0
- package/dist/installer-runtime/dist/scripts/wait-for-chain.js +90 -0
- package/dist/installer-runtime/dist/src/announcements.js +448 -0
- package/dist/installer-runtime/dist/src/app.js +539 -0
- package/dist/installer-runtime/dist/src/chainfetch.js +87 -0
- package/dist/installer-runtime/dist/src/env.js +425 -0
- package/dist/installer-runtime/dist/src/registry/announce.js +77 -0
- package/dist/installer-runtime/dist/src/registry/announcement.js +141 -0
- package/dist/installer-runtime/dist/src/registry/dependencies.js +28 -0
- package/dist/installer-runtime/dist/src/registry/detail.js +87 -0
- package/dist/installer-runtime/dist/src/registry/drainer.js +131 -0
- package/dist/installer-runtime/dist/src/registry/http.js +194 -0
- package/dist/installer-runtime/dist/src/registry/index.js +52 -0
- package/dist/installer-runtime/dist/src/registry/lease.js +35 -0
- package/dist/installer-runtime/dist/src/registry/ownership.js +31 -0
- package/dist/installer-runtime/dist/src/registry/provision.js +180 -0
- package/dist/installer-runtime/dist/src/registry/store.js +242 -0
- package/dist/installer-runtime/dist/src/registry/sweep.js +9 -0
- package/dist/installer-runtime/dist/src/registry/worker-module.js +87 -0
- package/dist/installer-runtime/dist/src/runtime.js +164 -0
- package/dist/installer-runtime/dist/src/store.js +138 -0
- package/dist/installer-runtime/package.json +1 -0
- package/dist/installer.d.ts +224 -0
- package/dist/installer.d.ts.map +1 -0
- package/dist/installer.js +336 -0
- package/dist/installer.js.map +1 -0
- package/dist/mcp-cli.d.ts.map +1 -1
- package/dist/mcp-cli.js +31 -5
- package/dist/mcp-cli.js.map +1 -1
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +8 -4
- package/dist/registry.js.map +1 -1
- package/installer/Committee.Dockerfile +6 -0
- package/installer/Node.Dockerfile +6 -0
- package/installer/Registry.Dockerfile +13 -0
- package/installer/runtime-control.mjs +172 -0
- package/installer/session-files.mjs +16 -0
- package/package.json +5 -4
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
// Meerkat composition root for the shared processor, not a second collector/runtime.
|
|
2
|
+
// All paths/capabilities are operator-fixed here; requests can supply only a channel id.
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { dockerNodeRestarter, nodeObserver, nodePuller, startControlServer, startProcessor, startReadServer, subscriptionConfig, subscriptionController, } from "@mcsherrylabs/evolver-client/processor";
|
|
5
|
+
import { ensureStateDir } from "./env.js";
|
|
6
|
+
const productionSdk = {
|
|
7
|
+
dockerNodeRestarter, nodeObserver, nodePuller, startControlServer, startProcessor,
|
|
8
|
+
startReadServer, subscriptionConfig, subscriptionController,
|
|
9
|
+
};
|
|
10
|
+
export function processorBinding() {
|
|
11
|
+
return { chainId: process.env.EVOLVER_CHAIN_ID?.trim() ?? "", nodeId: process.env.APP_NODE_ID?.trim() ?? "" };
|
|
12
|
+
}
|
|
13
|
+
export function processorConfigPath(target) {
|
|
14
|
+
return process.env.EVOLVER_SUBSCRIPTIONS_FILE?.trim() || join(target.stateDir, "subscriptions", "channels.conf");
|
|
15
|
+
}
|
|
16
|
+
export function processorStatePath(target) {
|
|
17
|
+
return join(target.stateDir, "registry.db");
|
|
18
|
+
}
|
|
19
|
+
export async function startMeerkatProcessor(args, sdk = productionSdk) {
|
|
20
|
+
const binding = processorBinding();
|
|
21
|
+
// Synchronous SDK validation of fixed expectations, NOT an online-node startup dependency.
|
|
22
|
+
const observe = sdk.nodeObserver({ baseUrl: args.target.nodeUrl, binding });
|
|
23
|
+
const config = sdk.subscriptionConfig(processorConfigPath(args.target));
|
|
24
|
+
await config.read(); // missing/malformed declaration refuses before opening storage; never reseed
|
|
25
|
+
let initialized = false;
|
|
26
|
+
ensureStateDir(args.target);
|
|
27
|
+
const runtime = await sdk.startProcessor({
|
|
28
|
+
store: {
|
|
29
|
+
path: processorStatePath(args.target), binding,
|
|
30
|
+
modules: args.worker ? [args.worker] : [],
|
|
31
|
+
limits: { maxEntriesPerChannel: 1000, maxBodyBytes: 64 * 1024 * 1024 },
|
|
32
|
+
},
|
|
33
|
+
puller: sdk.nodePuller(args.node), config,
|
|
34
|
+
// SDK initialization normally attempts setup (which can pace). Defer that attempt until
|
|
35
|
+
// the caller explicitly paces/runs: service composition binds recovery listeners first.
|
|
36
|
+
// Every subsequent pace still uses the SDK's verified node/chain/ACTIVE gate.
|
|
37
|
+
observe: async () => {
|
|
38
|
+
if (!initialized)
|
|
39
|
+
throw new Error("Meerkat listeners not started; collection deferred");
|
|
40
|
+
return observe();
|
|
41
|
+
},
|
|
42
|
+
tip: async () => String(await args.node.currentRound()),
|
|
43
|
+
modules: args.lifecycle ? [args.lifecycle] : [], say: args.say,
|
|
44
|
+
}).catch(error => {
|
|
45
|
+
if (error?.name === "ProcessorOwnerLockError") {
|
|
46
|
+
args.say(error.message);
|
|
47
|
+
args.say("MANUAL FORCE RECOVERY REQUIRED if the owner has died. Using the SAME Compose project/env/files/volumes: 1) docker compose stop app; stop any other collectors and disable all external automatic restarts. 2) Only when fenced: docker compose run --rm --no-deps app node dist/scripts/recover-owner.js --force. 3) docker compose up -d --no-deps app. For a host-run app, stop it and its supervisor first, then run node dist/scripts/recover-owner.js --force with the SAME target/state environment and restart normally. Ordinary restart or --force-recreate does NOT clear the lock. Never delete database/WAL or reinitialize subscriptions.");
|
|
48
|
+
}
|
|
49
|
+
throw error;
|
|
50
|
+
});
|
|
51
|
+
initialized = true;
|
|
52
|
+
return runtime;
|
|
53
|
+
}
|
|
54
|
+
/** Always attempt every release, including when another close fails. */
|
|
55
|
+
export async function closeMeerkat(actions) {
|
|
56
|
+
const errors = [];
|
|
57
|
+
for (const action of actions) {
|
|
58
|
+
try {
|
|
59
|
+
await action();
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
errors.push(error);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
if (errors.length)
|
|
66
|
+
throw new AggregateError(errors, "Meerkat shutdown failed");
|
|
67
|
+
}
|
|
68
|
+
export async function startMeerkatServers(args, sdk = productionSdk) {
|
|
69
|
+
const servers = [];
|
|
70
|
+
try {
|
|
71
|
+
servers.push(await sdk.startReadServer({
|
|
72
|
+
store: args.runtime.store, port: args.port,
|
|
73
|
+
host: process.env.PROCESSOR_READ_HOST?.trim() || "127.0.0.1", routes: args.routes, say: args.say,
|
|
74
|
+
}));
|
|
75
|
+
const containerName = process.env.EVOLVER_MANAGED_NODE_CONTAINER?.trim();
|
|
76
|
+
const socketPath = process.env.EVOLVER_PROCESSOR_CONTROL_SOCKET?.trim() || (containerName ? "/control/control.sock" : undefined);
|
|
77
|
+
const dockerSocket = containerName ? "/var/run/docker.sock" : undefined;
|
|
78
|
+
if (socketPath || dockerSocket || containerName) {
|
|
79
|
+
if (!socketPath || !dockerSocket || !containerName)
|
|
80
|
+
throw new Error("managed control requires explicit control socket, Docker socket and fixed node container");
|
|
81
|
+
const binding = processorBinding();
|
|
82
|
+
const controller = sdk.subscriptionController({
|
|
83
|
+
binding, runtime: args.runtime, config: sdk.subscriptionConfig(processorConfigPath(args.target)),
|
|
84
|
+
observe: sdk.nodeObserver({ baseUrl: args.target.nodeUrl, binding }),
|
|
85
|
+
restart: sdk.dockerNodeRestarter({ socketPath: dockerSocket, containerName }),
|
|
86
|
+
});
|
|
87
|
+
servers.push(await sdk.startControlServer({ socketPath, mode: 0o660, controller, say: args.say }));
|
|
88
|
+
}
|
|
89
|
+
return { port: servers[0].port, close: () => closeMeerkat([...servers].reverse().map(server => () => server.close())) };
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
try {
|
|
93
|
+
await closeMeerkat(servers.reverse().map(server => () => server.close()));
|
|
94
|
+
}
|
|
95
|
+
catch (cleanup) {
|
|
96
|
+
throw new AggregateError([error, cleanup], "Meerkat listener startup failed");
|
|
97
|
+
}
|
|
98
|
+
throw error;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
/** One service owner: bind listeners before run/setup, and release the worker on partial bind. */
|
|
102
|
+
export async function startMeerkatService(args, sdk = productionSdk) {
|
|
103
|
+
const runtime = await startMeerkatProcessor(args, sdk);
|
|
104
|
+
let servers;
|
|
105
|
+
try {
|
|
106
|
+
servers = await startMeerkatServers({ ...args, runtime, routes: args.routes(runtime) }, sdk);
|
|
107
|
+
runtime.run();
|
|
108
|
+
let stopping;
|
|
109
|
+
return { runtime, port: servers.port, stop() {
|
|
110
|
+
return stopping ??= closeMeerkat([() => servers.close(), () => runtime.stop()]);
|
|
111
|
+
} };
|
|
112
|
+
}
|
|
113
|
+
catch (error) {
|
|
114
|
+
try {
|
|
115
|
+
await closeMeerkat([...(servers ? [() => servers.close()] : []), () => runtime.stop()]);
|
|
116
|
+
}
|
|
117
|
+
catch (cleanup) {
|
|
118
|
+
throw new AggregateError([error, cleanup], "Meerkat service startup failed");
|
|
119
|
+
}
|
|
120
|
+
throw error;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
/** Signals and normal/error completion share one cleanup path, including partial async startup. */
|
|
124
|
+
export function meerkatShutdown(signals = process) {
|
|
125
|
+
let stopping;
|
|
126
|
+
const releases = [];
|
|
127
|
+
const stop = () => stopping ??= closeMeerkat([...releases].reverse());
|
|
128
|
+
const onSignal = () => { void stop().then(() => signals.exit(0), error => { console.error(error); signals.exit(1); }); };
|
|
129
|
+
signals.once("SIGINT", onSignal);
|
|
130
|
+
signals.once("SIGTERM", onSignal);
|
|
131
|
+
return {
|
|
132
|
+
async own(start, release) {
|
|
133
|
+
if (stopping)
|
|
134
|
+
throw new Error("Meerkat stopped during startup");
|
|
135
|
+
const pending = start();
|
|
136
|
+
// Register before awaiting so a signal DURING startup waits for and releases its result.
|
|
137
|
+
releases.push(async () => {
|
|
138
|
+
let resource;
|
|
139
|
+
try {
|
|
140
|
+
resource = await pending;
|
|
141
|
+
}
|
|
142
|
+
catch {
|
|
143
|
+
return;
|
|
144
|
+
} // startup owns its partial cleanup
|
|
145
|
+
await release(resource);
|
|
146
|
+
});
|
|
147
|
+
const resource = await pending;
|
|
148
|
+
if (stopping) {
|
|
149
|
+
await stopping;
|
|
150
|
+
throw new Error("Meerkat stopped during startup");
|
|
151
|
+
}
|
|
152
|
+
return resource;
|
|
153
|
+
},
|
|
154
|
+
async close() {
|
|
155
|
+
try {
|
|
156
|
+
await stop();
|
|
157
|
+
}
|
|
158
|
+
finally {
|
|
159
|
+
signals.removeListener("SIGINT", onSignal);
|
|
160
|
+
signals.removeListener("SIGTERM", onSignal);
|
|
161
|
+
}
|
|
162
|
+
},
|
|
163
|
+
};
|
|
164
|
+
}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
// ── application state: the identities this app owns, per target ─────────────
|
|
2
|
+
//
|
|
3
|
+
// This is the whole of "application state" for the template. A real app's state is bigger
|
|
4
|
+
// (a message log, a cursor, derived balances) but it has the same two properties, and they
|
|
5
|
+
// are the ones that matter:
|
|
6
|
+
//
|
|
7
|
+
// 1. It is PER TARGET. Keys for an identity on the local chain are meaningless on devnet,
|
|
8
|
+
// so they live in separate directories and never mix.
|
|
9
|
+
// 2. It is DISPOSABLE, but not free. Deleting it does not remove anything from a chain —
|
|
10
|
+
// the identities remain committed forever. It only means we no longer hold their keys,
|
|
11
|
+
// i.e. we have ABANDONED them. That is fine on an ephemeral local chain and permanent
|
|
12
|
+
// on devnet, which is why the reset command says so out loud for devnet.
|
|
13
|
+
//
|
|
14
|
+
// Private keys are written here in plain hex, which is correct for a development template
|
|
15
|
+
// and wrong for anything else. A real app keeps them in an OS keychain, or behind the SDK's
|
|
16
|
+
// Signer handle so the scalar never reaches application code at all (see the evolver repo's
|
|
17
|
+
// key-isolation work). Said here rather than in a README because this is the file someone
|
|
18
|
+
// copies.
|
|
19
|
+
import { existsSync, readFileSync, renameSync, writeFileSync } from "node:fs";
|
|
20
|
+
import { join } from "node:path";
|
|
21
|
+
import { newIdentity, edSign } from "@mcsherrylabs/evolver-client";
|
|
22
|
+
import { ensureStateDir } from "./env.js";
|
|
23
|
+
const FILE = "identities.json";
|
|
24
|
+
const VERSION = 1;
|
|
25
|
+
/** State that exists but cannot be trusted: malformed, wrong version, or belonging to another
|
|
26
|
+
* target. A distinct type because the CALLERS want different things from it — the app must
|
|
27
|
+
* refuse and say why, `status` must report it, `state:reset` must delete it anyway — and
|
|
28
|
+
* because the fix is always the same one sentence, which is worth saying instead of a stack
|
|
29
|
+
* trace naming a line of store.ts. */
|
|
30
|
+
export class StateError extends Error {
|
|
31
|
+
}
|
|
32
|
+
const hex = (b) => Buffer.from(b).toString("hex");
|
|
33
|
+
const bin = (s) => new Uint8Array(Buffer.from(s, "hex"));
|
|
34
|
+
// READ path — must NOT create anything. `ensureStateDir` mkdirs, so calling it here made
|
|
35
|
+
// merely LOOKING at state (npm run status, which inspects every target) create both state
|
|
36
|
+
// directories as a side effect. Reads resolve the path; only writes create the directory.
|
|
37
|
+
function pathFor(t) { return join(t.stateDir, FILE); }
|
|
38
|
+
function load(t) {
|
|
39
|
+
try {
|
|
40
|
+
const f = JSON.parse(readFileSync(pathFor(t), "utf8"));
|
|
41
|
+
if (f.v !== VERSION)
|
|
42
|
+
throw new StateError(`state version ${f.v}, expected ${VERSION}`);
|
|
43
|
+
// A state file that names a DIFFERENT target means the directories got crossed — refuse
|
|
44
|
+
// rather than hand the app keys for a chain it is not talking to, which would fail later
|
|
45
|
+
// as an inscrutable `invalid_signature`.
|
|
46
|
+
if (f.target !== t.name) {
|
|
47
|
+
throw new StateError(`state in ${t.stateDir} belongs to target '${f.target}', not '${t.name}'`);
|
|
48
|
+
}
|
|
49
|
+
return f;
|
|
50
|
+
}
|
|
51
|
+
catch (e) {
|
|
52
|
+
if (e.code === "ENOENT") {
|
|
53
|
+
return { v: VERSION, target: t.name, identities: {} };
|
|
54
|
+
}
|
|
55
|
+
if (e instanceof StateError)
|
|
56
|
+
throw e;
|
|
57
|
+
// Anything else reaching here (a truncated file, hand-editing, a JSON syntax error) is the
|
|
58
|
+
// same problem with the same fix, so it arrives at callers as the same type rather than as
|
|
59
|
+
// a raw SyntaxError that surfaces to the user as a stack trace.
|
|
60
|
+
throw new StateError(`${pathFor(t)} is not readable as state — ${e.message}`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
// WRITE path — the only place that creates the directory, and the only place that needs to.
|
|
64
|
+
function save(t, f) {
|
|
65
|
+
const dest = join(ensureStateDir(t), FILE);
|
|
66
|
+
// Write-then-rename, and mode 0600. These keys are the only thing standing between this
|
|
67
|
+
// app and its on-chain identities: a crash or a full disk mid-write would otherwise leave
|
|
68
|
+
// a truncated JSON file that no longer parses, i.e. the keys are gone — and on an
|
|
69
|
+
// ephemeral local chain that is an annoyance, on devnet it is permanent. rename(2) within
|
|
70
|
+
// one directory is atomic, so a reader sees the old file or the new one, never a partial.
|
|
71
|
+
const tmp = `${dest}.tmp`;
|
|
72
|
+
writeFileSync(tmp, JSON.stringify(f, null, 2) + "\n", { mode: 0o600 });
|
|
73
|
+
renameSync(tmp, dest);
|
|
74
|
+
}
|
|
75
|
+
/** Identity for `role` from this target's state, or null if we do not hold one. */
|
|
76
|
+
export function get(t, role) {
|
|
77
|
+
const s = load(t).identities[role];
|
|
78
|
+
if (!s)
|
|
79
|
+
return null;
|
|
80
|
+
return {
|
|
81
|
+
nodeId: s.nodeId,
|
|
82
|
+
bls: { priv: bin(s.blsPriv), pub: bin(s.blsPub) },
|
|
83
|
+
ed: { priv: bin(s.edPriv), pub: bin(s.edPub) },
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
/** Create a fresh identity for `role`, persist it, return it. */
|
|
87
|
+
export function create(t, role, nodeId) {
|
|
88
|
+
const id = newIdentity(nodeId);
|
|
89
|
+
const f = load(t);
|
|
90
|
+
f.identities[role] = {
|
|
91
|
+
nodeId: id.nodeId,
|
|
92
|
+
blsPriv: hex(id.bls.priv), blsPub: hex(id.bls.pub),
|
|
93
|
+
edPriv: hex(id.ed.priv), edPub: hex(id.ed.pub),
|
|
94
|
+
};
|
|
95
|
+
save(t, f);
|
|
96
|
+
return id;
|
|
97
|
+
}
|
|
98
|
+
export function roles(t) {
|
|
99
|
+
return Object.keys(load(t).identities);
|
|
100
|
+
}
|
|
101
|
+
export function summary(t) {
|
|
102
|
+
const f = load(t);
|
|
103
|
+
return Object.entries(f.identities).map(([role, s]) => ({ role, nodeId: s.nodeId }));
|
|
104
|
+
}
|
|
105
|
+
/** What `status` uses. NEVER throws.
|
|
106
|
+
*
|
|
107
|
+
* `load` is deliberately strict — a state file that is malformed, versioned wrong, or
|
|
108
|
+
* belongs to another target must stop the APP rather than let it run with keys it cannot
|
|
109
|
+
* trust. But `status` is the command you are told to run FIRST when something is wrong, and
|
|
110
|
+
* a first-aid command that dies with a stack trace on exactly the state it exists to
|
|
111
|
+
* describe is worse than useless. So the strictness stays where it belongs and `status`
|
|
112
|
+
* reads through this: the problem becomes a line of output, in the place that names the
|
|
113
|
+
* state that has it. */
|
|
114
|
+
export function inspect(t) {
|
|
115
|
+
if (!existsSync(pathFor(t)))
|
|
116
|
+
return { ids: [] };
|
|
117
|
+
try {
|
|
118
|
+
return { ids: summary(t) };
|
|
119
|
+
}
|
|
120
|
+
catch (e) {
|
|
121
|
+
return { ids: [], problem: e.message };
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* A signer over a stored identity's Ed25519 key.
|
|
126
|
+
*
|
|
127
|
+
* HERE because this is where identities live, and because three callers now need one — the
|
|
128
|
+
* app, the registry and the rig's announcer. It was a private function in app.ts, and the
|
|
129
|
+
* third caller reaching for `store.signerFor` (which did not exist) is exactly the moment to
|
|
130
|
+
* stop copying it: two implementations of one rule is one too many, and the second is the one
|
|
131
|
+
* that goes stale.
|
|
132
|
+
*
|
|
133
|
+
* The private half never leaves this module's caller: the signer closes over it and exposes
|
|
134
|
+
* only `sign`, which is the handle discipline the key-isolation audit established.
|
|
135
|
+
*/
|
|
136
|
+
export function signerFor(id) {
|
|
137
|
+
return { keyType: "Ed25519", keyLabel: "", nodeId: "", sign: (d) => edSign(d, id.ed.priv) };
|
|
138
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"name":"evolver-meerkat","type":"module","private":true}
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
export interface Installation {
|
|
2
|
+
version: 1;
|
|
3
|
+
uid: number;
|
|
4
|
+
id: string;
|
|
5
|
+
dir: string;
|
|
6
|
+
project: string;
|
|
7
|
+
nodeId: string;
|
|
8
|
+
committeeId: string;
|
|
9
|
+
identity: string;
|
|
10
|
+
registryOperator: string;
|
|
11
|
+
channel: string;
|
|
12
|
+
ports: [number, number, number];
|
|
13
|
+
packageVersion: string;
|
|
14
|
+
daemonId: string;
|
|
15
|
+
initialization: 'pending' | 'attempted' | 'complete';
|
|
16
|
+
ready?: true;
|
|
17
|
+
binding?: {
|
|
18
|
+
chainId: string;
|
|
19
|
+
nodeId: string;
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
export interface InstallerDeps {
|
|
23
|
+
command(command: string, args: string[], env?: NodeJS.ProcessEnv, cwd?: string): Promise<string>;
|
|
24
|
+
committeeReady(state: Installation, env: NodeJS.ProcessEnv): Promise<void>;
|
|
25
|
+
nodeBinding(state: Installation, env: NodeJS.ProcessEnv): Promise<{
|
|
26
|
+
chainId: string;
|
|
27
|
+
nodeId: string;
|
|
28
|
+
}>;
|
|
29
|
+
registryReady(state: Installation, env: NodeJS.ProcessEnv): Promise<void>;
|
|
30
|
+
bootstrap(state: Installation, env: NodeJS.ProcessEnv): Promise<void>;
|
|
31
|
+
}
|
|
32
|
+
export declare function managedDirectory(env?: NodeJS.ProcessEnv): string;
|
|
33
|
+
export declare const managedConfigPath: (env?: NodeJS.ProcessEnv) => string;
|
|
34
|
+
export declare function pinnedRegistration(version: string): {
|
|
35
|
+
mcpServers: {
|
|
36
|
+
meerkat: {
|
|
37
|
+
command: string;
|
|
38
|
+
args: string[];
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
export declare function renderDeployment(state: Installation): {
|
|
43
|
+
name: string;
|
|
44
|
+
services: {
|
|
45
|
+
committee: {
|
|
46
|
+
image: string;
|
|
47
|
+
labels: {
|
|
48
|
+
"io.meerkat.installation": string;
|
|
49
|
+
};
|
|
50
|
+
container_name: string;
|
|
51
|
+
build: {
|
|
52
|
+
context: string;
|
|
53
|
+
dockerfile: string;
|
|
54
|
+
labels: {
|
|
55
|
+
"io.meerkat.installation": string;
|
|
56
|
+
};
|
|
57
|
+
args: {
|
|
58
|
+
EVOLVER_NODE_IMAGE: string;
|
|
59
|
+
};
|
|
60
|
+
};
|
|
61
|
+
entrypoint: string[];
|
|
62
|
+
environment: {
|
|
63
|
+
NODE_ID: string;
|
|
64
|
+
PUBLIC_HOST: string;
|
|
65
|
+
};
|
|
66
|
+
group_add: string[];
|
|
67
|
+
volumes: string[];
|
|
68
|
+
restart: string;
|
|
69
|
+
};
|
|
70
|
+
node: {
|
|
71
|
+
image: string;
|
|
72
|
+
labels: {
|
|
73
|
+
"io.meerkat.installation": string;
|
|
74
|
+
};
|
|
75
|
+
container_name: string;
|
|
76
|
+
entrypoint: string[];
|
|
77
|
+
build: {
|
|
78
|
+
context: string;
|
|
79
|
+
dockerfile: string;
|
|
80
|
+
labels: {
|
|
81
|
+
"io.meerkat.installation": string;
|
|
82
|
+
};
|
|
83
|
+
args: {
|
|
84
|
+
EVOLVER_NODE_IMAGE: string;
|
|
85
|
+
};
|
|
86
|
+
};
|
|
87
|
+
environment: {
|
|
88
|
+
APP_NODE_ID: string;
|
|
89
|
+
DEVNET_API: string;
|
|
90
|
+
EVOLVER_UPSTREAM_NODE_ID: string;
|
|
91
|
+
EVOLVER_ALLOWED_OUTBOUND: string;
|
|
92
|
+
EVOLVER_EXECUTION_ENABLED: string;
|
|
93
|
+
EVOLVER_NODE_PORT: string;
|
|
94
|
+
CLAIM_TIMEOUT: string;
|
|
95
|
+
CLAIM_WATCH_SECS: string;
|
|
96
|
+
};
|
|
97
|
+
group_add: string[];
|
|
98
|
+
volumes: string[];
|
|
99
|
+
restart: string;
|
|
100
|
+
};
|
|
101
|
+
registry: {
|
|
102
|
+
image: string;
|
|
103
|
+
labels: {
|
|
104
|
+
"io.meerkat.installation": string;
|
|
105
|
+
};
|
|
106
|
+
container_name: string;
|
|
107
|
+
build: {
|
|
108
|
+
context: string;
|
|
109
|
+
dockerfile: string;
|
|
110
|
+
labels: {
|
|
111
|
+
"io.meerkat.installation": string;
|
|
112
|
+
};
|
|
113
|
+
};
|
|
114
|
+
user: string;
|
|
115
|
+
environment: {
|
|
116
|
+
EVOLVER_TARGET: string;
|
|
117
|
+
EVOLVER_NODE: string;
|
|
118
|
+
EVOLVER_FAUCET_URL: string;
|
|
119
|
+
EVOLVER_CHAIN_ID: string;
|
|
120
|
+
APP_NODE_ID: string;
|
|
121
|
+
EVOLVER_SUBSCRIPTIONS_FILE: string;
|
|
122
|
+
REGISTRY_CHANNEL: string;
|
|
123
|
+
REGISTRY_CHANNEL_OPERATOR: string;
|
|
124
|
+
REGISTRY_CONTENT_URL: string;
|
|
125
|
+
PROCESSOR_HTTP_PORT: string;
|
|
126
|
+
PROCESSOR_READ_HOST: string;
|
|
127
|
+
};
|
|
128
|
+
volumes: string[];
|
|
129
|
+
restart: string;
|
|
130
|
+
};
|
|
131
|
+
'subscriptions-init': {
|
|
132
|
+
image: string;
|
|
133
|
+
labels: {
|
|
134
|
+
"io.meerkat.installation": string;
|
|
135
|
+
};
|
|
136
|
+
profiles: string[];
|
|
137
|
+
user: string;
|
|
138
|
+
environment: {
|
|
139
|
+
EVOLVER_INITIAL_CHANNELS: string;
|
|
140
|
+
EVOLVER_OPERATOR_UID: string;
|
|
141
|
+
EVOLVER_OPERATOR_GID: string;
|
|
142
|
+
EVOLVER_TARGET: string;
|
|
143
|
+
EVOLVER_NODE: string;
|
|
144
|
+
EVOLVER_FAUCET_URL: string;
|
|
145
|
+
EVOLVER_CHAIN_ID: string;
|
|
146
|
+
APP_NODE_ID: string;
|
|
147
|
+
EVOLVER_SUBSCRIPTIONS_FILE: string;
|
|
148
|
+
REGISTRY_CHANNEL: string;
|
|
149
|
+
REGISTRY_CHANNEL_OPERATOR: string;
|
|
150
|
+
REGISTRY_CONTENT_URL: string;
|
|
151
|
+
PROCESSOR_HTTP_PORT: string;
|
|
152
|
+
PROCESSOR_READ_HOST: string;
|
|
153
|
+
};
|
|
154
|
+
entrypoint: string[];
|
|
155
|
+
command: string[];
|
|
156
|
+
volumes: string[];
|
|
157
|
+
};
|
|
158
|
+
};
|
|
159
|
+
volumes: {
|
|
160
|
+
'committee-data': {
|
|
161
|
+
name: string;
|
|
162
|
+
labels: {
|
|
163
|
+
"io.meerkat.installation": string;
|
|
164
|
+
};
|
|
165
|
+
};
|
|
166
|
+
genesis: {
|
|
167
|
+
name: string;
|
|
168
|
+
labels: {
|
|
169
|
+
"io.meerkat.installation": string;
|
|
170
|
+
};
|
|
171
|
+
};
|
|
172
|
+
'node-data': {
|
|
173
|
+
name: string;
|
|
174
|
+
labels: {
|
|
175
|
+
"io.meerkat.installation": string;
|
|
176
|
+
};
|
|
177
|
+
};
|
|
178
|
+
'app-state': {
|
|
179
|
+
name: string;
|
|
180
|
+
labels: {
|
|
181
|
+
"io.meerkat.installation": string;
|
|
182
|
+
};
|
|
183
|
+
};
|
|
184
|
+
subscriptions: {
|
|
185
|
+
name: string;
|
|
186
|
+
labels: {
|
|
187
|
+
"io.meerkat.installation": string;
|
|
188
|
+
};
|
|
189
|
+
};
|
|
190
|
+
'agent-state': {
|
|
191
|
+
name: string;
|
|
192
|
+
labels: {
|
|
193
|
+
"io.meerkat.installation": string;
|
|
194
|
+
};
|
|
195
|
+
};
|
|
196
|
+
};
|
|
197
|
+
networks: {
|
|
198
|
+
default: {
|
|
199
|
+
name: string;
|
|
200
|
+
internal: boolean;
|
|
201
|
+
labels: {
|
|
202
|
+
"io.meerkat.installation": string;
|
|
203
|
+
};
|
|
204
|
+
};
|
|
205
|
+
};
|
|
206
|
+
};
|
|
207
|
+
export declare function operatorEnvironment(env: NodeJS.ProcessEnv): NodeJS.ProcessEnv;
|
|
208
|
+
export declare function managedInstallation(env?: NodeJS.ProcessEnv): Promise<Installation | undefined>;
|
|
209
|
+
/** Protocol-only stdio bridge, one new facade/private child/session per harness connection.
|
|
210
|
+
* Docker exec works even when daemon and harness share neither filesystem nor loopback. */
|
|
211
|
+
export declare function serveManaged(state: Installation, env?: NodeJS.ProcessEnv): Promise<void>;
|
|
212
|
+
export declare function installMeerkat(env?: NodeJS.ProcessEnv, deps?: InstallerDeps): Promise<{
|
|
213
|
+
dir: string;
|
|
214
|
+
configPath: string;
|
|
215
|
+
registration: {
|
|
216
|
+
mcpServers: {
|
|
217
|
+
meerkat: {
|
|
218
|
+
command: string;
|
|
219
|
+
args: string[];
|
|
220
|
+
};
|
|
221
|
+
};
|
|
222
|
+
};
|
|
223
|
+
}>;
|
|
224
|
+
//# sourceMappingURL=installer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"installer.d.ts","sourceRoot":"","sources":["../src/installer.ts"],"names":[],"mappings":"AAkBA,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,CAAC,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IACvG,QAAQ,EAAE,MAAM,CAAC;IAAC,gBAAgB,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,cAAc,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IACvI,cAAc,EAAE,SAAS,GAAG,WAAW,GAAG,UAAU,CAAC;IAAC,KAAK,CAAC,EAAE,IAAI,CAAC;IAAC,OAAO,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CACnH;AACD,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACjG,cAAc,CAAC,KAAK,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,CAAC,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3E,WAAW,CAAC,KAAK,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,CAAC,UAAU,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACvG,aAAa,CAAC,KAAK,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,CAAC,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1E,SAAS,CAAC,KAAK,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,CAAC,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACvE;AACD,wBAAgB,gBAAgB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,CAI7E;AACD,eAAO,MAAM,iBAAiB,GAAI,MAAK,MAAM,CAAC,UAAwB,KAAG,MAA0D,CAAC;AACpI,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM;;;;;;;EAGjD;AACD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAsCnD;AA2BD,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,CAK7E;AAwDD,wBAAsB,mBAAmB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC,CAOjH;AACD;2FAC2F;AAC3F,wBAAsB,YAAY,CAAC,KAAK,EAAE,YAAY,EAAE,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,OAAO,CAAC,IAAI,CAAC,CAgC3G;AACD,wBAAsB,cAAc,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,EAAE,IAAI,GAAE,aAAwB;;;;;;;;;;;GAiFxG"}
|