@mcsherrylabs/pi-meerkat 0.7.0 → 0.10.1
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 +109 -33
- package/dist/installer/committee-init.sh +117 -0
- package/dist/installer/committee.conf +102 -0
- package/dist/installer/genesis.devnet.conf +92 -0
- package/dist/installer/node-join.sh +235 -0
- package/dist/installer/node.conf +238 -0
- package/dist/installer/node.devnet.conf +238 -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 +552 -0
- package/dist/installer-runtime/dist/src/chainfetch.js +87 -0
- package/dist/installer-runtime/dist/src/env.js +437 -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 +61 -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 +225 -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 +192 -0
- package/dist/installer-runtime/dist/src/store.js +138 -0
- package/dist/installer-runtime/package.json +1 -0
- package/dist/installer.d.ts +401 -0
- package/dist/installer.d.ts.map +1 -0
- package/dist/installer.js +446 -0
- package/dist/installer.js.map +1 -0
- package/dist/mcp-announce.d.ts +18 -0
- package/dist/mcp-announce.d.ts.map +1 -1
- package/dist/mcp-announce.js +18 -4
- package/dist/mcp-announce.js.map +1 -1
- package/dist/mcp-cli.d.ts.map +1 -1
- package/dist/mcp-cli.js +41 -5
- package/dist/mcp-cli.js.map +1 -1
- package/dist/mcp-config.d.ts +1 -0
- package/dist/mcp-config.d.ts.map +1 -1
- package/dist/mcp-config.js +2 -1
- package/dist/mcp-config.js.map +1 -1
- package/dist/mcp-upstream.d.ts +1 -1
- package/dist/mcp-upstream.d.ts.map +1 -1
- package/dist/mcp-upstream.js +7 -2
- package/dist/mcp-upstream.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/dist/tools.js +4 -4
- package/dist/tools.js.map +1 -1
- package/installer/Committee.Dockerfile +6 -0
- package/installer/Node.Dockerfile +10 -0
- package/installer/Registry.Dockerfile +13 -0
- package/installer/runtime-control.mjs +335 -0
- package/installer/session-files.mjs +16 -0
- package/package.json +8 -7
- package/skills/channel-subscription/SKILL.md +3 -3
|
@@ -0,0 +1,446 @@
|
|
|
1
|
+
// Operator-only deployment orchestration. Key generation/read/signing remains in the released
|
|
2
|
+
// Evolver bootstrap/child. All services/data are owned Docker resources, never host bind mounts.
|
|
3
|
+
//
|
|
4
|
+
// Two modes, each in its own private state directory so installs coexist and 0.8.0 state is never
|
|
5
|
+
// read/adopted/removed:
|
|
6
|
+
// devnet (default) — install against the public DevNet; one follower node + one read-only
|
|
7
|
+
// registry draining the shared channel `ce.meerkat.announcements`.
|
|
8
|
+
// local (--local) — 0.8.0's private chain (committee + follower), now with a read-only
|
|
9
|
+
// registry and an agent-owned private channel.
|
|
10
|
+
import { spawn } from 'node:child_process';
|
|
11
|
+
import { randomBytes } from 'node:crypto';
|
|
12
|
+
import { constants } from 'node:fs';
|
|
13
|
+
import { cp, lstat, mkdir, open, readFile, rename, rm, writeFile } from 'node:fs/promises';
|
|
14
|
+
import { homedir } from 'node:os';
|
|
15
|
+
import { dirname, isAbsolute, join, resolve } from 'node:path';
|
|
16
|
+
import { fileURLToPath } from 'node:url';
|
|
17
|
+
const PACKAGE = '@mcsherrylabs/pi-meerkat';
|
|
18
|
+
const packageDir = resolve(dirname(fileURLToPath(import.meta.url)), '..');
|
|
19
|
+
// Public manifest rechecked anonymously 2026-11-06; coordinated with released SDK 0.23.0.
|
|
20
|
+
// This digest pins tag v0.27.0 (anonymously pullable); keep the tag named here when re-pinning.
|
|
21
|
+
const NODE_IMAGE = 'nexus.mcsherrylabs.com/evolver-node@sha256:f78974686dcdfacfd49a6a02166d393485aeb5db33ac83d4d72393c6bcd3b006';
|
|
22
|
+
// The pinned node image runs as uid=10001(evolver) gid=999(evolver) (Config.User=evolver). The node
|
|
23
|
+
// control listener REQUIRES /node-control to be owned by exactly that uid:gid with mode 0750, or it
|
|
24
|
+
// fails startup. These are image facts tied to NODE_IMAGE — re-check against the new image on re-pin.
|
|
25
|
+
const NODE_CONTROL_UID = '10001';
|
|
26
|
+
const NODE_CONTROL_GID = '999';
|
|
27
|
+
const OWNER = 'io.meerkat.installation';
|
|
28
|
+
const installed = '/opt/meerkat/node_modules/@mcsherrylabs/pi-meerkat';
|
|
29
|
+
const runtime = `${installed}/dist/installer-runtime`;
|
|
30
|
+
const control = `${installed}/installer/runtime-control.mjs`;
|
|
31
|
+
// DevNet facts (verified by the coordinator, pinned exactly). See the task brief.
|
|
32
|
+
const DEVNET_ORIGIN = 'https://devnet.mcsherrylabs.com';
|
|
33
|
+
const DEVNET_CHAIN_ID = 'c8925985ae7948d2e608efcf863928d15476c4b561ad773fdca6f0d53d4fea05';
|
|
34
|
+
const DEVNET_CHANNEL = 'ce.meerkat.announcements';
|
|
35
|
+
const DEVNET_OPERATOR = 'evolvermeerkatA483344';
|
|
36
|
+
const DEVNET_UPSTREAM_NODE_ID = 'evolvermeerkatnode920080';
|
|
37
|
+
const DEVNET_DA_PEERS = 'schednode2';
|
|
38
|
+
const DEVNET_ALLOWED_OUTBOUND = '2';
|
|
39
|
+
export function managedDirectory(env = process.env) {
|
|
40
|
+
const base = env.XDG_STATE_HOME || join(env.HOME || homedir(), '.local', 'state');
|
|
41
|
+
if (!isAbsolute(base))
|
|
42
|
+
throw new Error('HOME/XDG_STATE_HOME must resolve to an absolute operator state directory');
|
|
43
|
+
return join(base, 'meerkat');
|
|
44
|
+
}
|
|
45
|
+
/** Per-mode state directory. The 0.8.0 path `<state>/meerkat/` (installation.json) is never used. */
|
|
46
|
+
export function modeDirectory(mode, env = process.env) {
|
|
47
|
+
return join(managedDirectory(env), mode);
|
|
48
|
+
}
|
|
49
|
+
export const managedConfigPath = (mode = 'devnet', env = process.env) => join(modeDirectory(mode, env), 'installation.json');
|
|
50
|
+
export function pinnedRegistration(version, mode = 'devnet') {
|
|
51
|
+
if (!/^\d+\.\d+\.\d+$/.test(version))
|
|
52
|
+
throw new Error('installer requires a released semantic package version');
|
|
53
|
+
return { mcpServers: { meerkat: { command: 'npx', args: ['--yes', `${PACKAGE}@${version}`, 'serve', ...(mode === 'local' ? ['--local'] : [])] } } };
|
|
54
|
+
}
|
|
55
|
+
const registryEnvironment = (state, committee) => ({
|
|
56
|
+
EVOLVER_TARGET: state.mode === 'devnet' ? 'devnet' : 'local',
|
|
57
|
+
EVOLVER_NODE: 'http://node:8440',
|
|
58
|
+
// The devnet target reads EVOLVER_DEVNET_URL (default: the PUBLIC devnet) and ignores EVOLVER_NODE.
|
|
59
|
+
// The chain is devnet; the ENDPOINT must be this install's own processing node, or the processor
|
|
60
|
+
// observes/pulls the public node (no processor-state for us: HTTP 404) and never becomes ready.
|
|
61
|
+
...(state.mode === 'devnet' ? { EVOLVER_DEVNET_URL: 'http://node:8440' } : {}),
|
|
62
|
+
EVOLVER_FAUCET_URL: committee ? 'http://committee:8440' : DEVNET_ORIGIN,
|
|
63
|
+
EVOLVER_CHAIN_ID: state.mode === 'devnet' ? DEVNET_CHAIN_ID : state.binding?.chainId ?? '',
|
|
64
|
+
APP_NODE_ID: state.nodeId,
|
|
65
|
+
EVOLVER_SUBSCRIPTIONS_FILE: '/subscriptions/channels.conf',
|
|
66
|
+
REGISTRY_CHANNEL: state.channel,
|
|
67
|
+
REGISTRY_CHANNEL_OPERATOR: state.registryOperator,
|
|
68
|
+
REGISTRY_READ_ONLY: '1',
|
|
69
|
+
REGISTRY_CONTENT_URL: 'http://node:8450',
|
|
70
|
+
PROCESSOR_HTTP_PORT: '8090',
|
|
71
|
+
PROCESSOR_READ_HOST: '0.0.0.0',
|
|
72
|
+
EVOLVER_PROCESSOR_CONTROL_SOCKET: '/control/control.sock',
|
|
73
|
+
});
|
|
74
|
+
export function renderDeployment(state) {
|
|
75
|
+
const labels = { [OWNER]: state.id };
|
|
76
|
+
const volume = (name) => ({ name: `${state.project}-${name}`, labels });
|
|
77
|
+
const registryEnv = registryEnvironment(state, state.mode === 'local');
|
|
78
|
+
if (state.mode === 'devnet') {
|
|
79
|
+
return {
|
|
80
|
+
name: state.project,
|
|
81
|
+
services: {
|
|
82
|
+
node: { image: `${state.project}-node:${state.packageVersion}`, labels, container_name: `${state.project}-node`, entrypoint: ['sh', '/config/node-join.sh'],
|
|
83
|
+
build: { context: './package', dockerfile: 'installer/Node.Dockerfile', labels, args: { EVOLVER_NODE_IMAGE: NODE_IMAGE } },
|
|
84
|
+
environment: { APP_NODE_ID: state.nodeId, DEVNET_API: DEVNET_ORIGIN, EVOLVER_UPSTREAM_NODE_ID: DEVNET_UPSTREAM_NODE_ID,
|
|
85
|
+
EVOLVER_DA_PEERS: DEVNET_DA_PEERS, EVOLVER_ALLOWED_OUTBOUND: DEVNET_ALLOWED_OUTBOUND,
|
|
86
|
+
EVOLVER_EXECUTION_ENABLED: 'true', EVOLVER_NODE_PORT: '7100', EVOLVER_NODE_CONFIG: '/config/node.devnet.conf' },
|
|
87
|
+
group_add: ['1000'], volumes: ['node-data:/data', 'subscriptions:/subscriptions:ro', 'node-control:/node-control'],
|
|
88
|
+
restart: 'unless-stopped' },
|
|
89
|
+
registry: { image: `${state.project}-registry:${state.packageVersion}`, labels, container_name: `${state.project}-registry`,
|
|
90
|
+
build: { context: './package', dockerfile: 'installer/Registry.Dockerfile', labels },
|
|
91
|
+
user: '1000:1000', group_add: [NODE_CONTROL_GID], environment: registryEnv,
|
|
92
|
+
volumes: [`app-state:${runtime}/state`, 'subscriptions:/subscriptions', 'agent-state:/meerkat/agent',
|
|
93
|
+
'node-control:/node-control:ro', 'control:/control'],
|
|
94
|
+
restart: 'unless-stopped' },
|
|
95
|
+
'subscriptions-init': { image: `${state.project}-registry:${state.packageVersion}`, labels, profiles: ['initialize-only'],
|
|
96
|
+
user: '0:0', environment: { ...registryEnv, EVOLVER_INITIAL_CHANNELS: JSON.stringify([state.channel]),
|
|
97
|
+
EVOLVER_OPERATOR_UID: '1000', EVOLVER_OPERATOR_GID: '1000' },
|
|
98
|
+
entrypoint: ['sh', '-ec'], command: [`chown 1000:1000 ${runtime}/state /meerkat/agent /control; chown ${NODE_CONTROL_UID}:${NODE_CONTROL_GID} /node-control; chmod 700 /meerkat/agent; chmod 750 /node-control /control; exec node ${runtime}/dist/scripts/subscriptions-init.js`],
|
|
99
|
+
volumes: [`app-state:${runtime}/state`, 'subscriptions:/subscriptions', 'agent-state:/meerkat/agent',
|
|
100
|
+
'node-control:/node-control', 'control:/control'] },
|
|
101
|
+
},
|
|
102
|
+
volumes: { 'node-data': volume('node-data'), 'app-state': volume('app-state'),
|
|
103
|
+
subscriptions: volume('subscriptions'), 'agent-state': volume('agent-state'),
|
|
104
|
+
'node-control': volume('node-control'), control: volume('control') },
|
|
105
|
+
networks: { default: { name: `${state.project}-network`, labels } },
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
// LOCAL: 0.8.0's private chain, with a read-only registry and an agent-owned private channel.
|
|
109
|
+
const environment = registryEnv;
|
|
110
|
+
return {
|
|
111
|
+
name: state.project,
|
|
112
|
+
services: {
|
|
113
|
+
committee: { image: `${state.project}-committee:${state.packageVersion}`, labels, container_name: `${state.project}-committee`,
|
|
114
|
+
build: { context: './package', dockerfile: 'installer/Committee.Dockerfile', labels, args: { EVOLVER_NODE_IMAGE: NODE_IMAGE } },
|
|
115
|
+
entrypoint: ['sh', '/config/node-init.sh'], environment: { NODE_ID: state.committeeId, PUBLIC_HOST: 'committee' },
|
|
116
|
+
group_add: ['1000'], volumes: ['committee-data:/data', 'genesis:/public-genesis'], restart: 'unless-stopped' },
|
|
117
|
+
node: { image: `${state.project}-node:${state.packageVersion}`, labels, container_name: `${state.project}-node`, entrypoint: ['sh', '/config/node-join.sh'],
|
|
118
|
+
build: { context: './package', dockerfile: 'installer/Node.Dockerfile', labels, args: { EVOLVER_NODE_IMAGE: NODE_IMAGE } },
|
|
119
|
+
environment: { APP_NODE_ID: state.nodeId, DEVNET_API: 'http://committee:8440', EVOLVER_UPSTREAM_NODE_ID: state.committeeId,
|
|
120
|
+
EVOLVER_ALLOWED_OUTBOUND: '1', EVOLVER_EXECUTION_ENABLED: 'true', EVOLVER_NODE_PORT: '7100', CLAIM_TIMEOUT: '90', CLAIM_WATCH_SECS: '30' },
|
|
121
|
+
group_add: ['1000'], volumes: ['node-data:/data', 'subscriptions:/subscriptions:ro', 'genesis:/public-genesis:ro', 'node-control:/node-control'],
|
|
122
|
+
restart: 'unless-stopped' },
|
|
123
|
+
registry: { image: `${state.project}-registry:${state.packageVersion}`, labels, container_name: `${state.project}-registry`,
|
|
124
|
+
build: { context: './package', dockerfile: 'installer/Registry.Dockerfile', labels },
|
|
125
|
+
user: '1000:1000', group_add: [NODE_CONTROL_GID], environment,
|
|
126
|
+
volumes: [`app-state:${runtime}/state`, 'subscriptions:/subscriptions', 'agent-state:/meerkat/agent',
|
|
127
|
+
'node-control:/node-control:ro', 'control:/control'],
|
|
128
|
+
restart: 'unless-stopped' },
|
|
129
|
+
'subscriptions-init': { image: `${state.project}-registry:${state.packageVersion}`, labels, profiles: ['initialize-only'],
|
|
130
|
+
user: '0:0', environment: { ...environment, EVOLVER_INITIAL_CHANNELS: JSON.stringify([state.channel]),
|
|
131
|
+
EVOLVER_OPERATOR_UID: '1000', EVOLVER_OPERATOR_GID: '1000' },
|
|
132
|
+
entrypoint: ['sh', '-ec'], command: [`chown 1000:1000 ${runtime}/state /meerkat/agent /public-genesis /control; chown ${NODE_CONTROL_UID}:${NODE_CONTROL_GID} /node-control; chmod 700 /meerkat/agent; chmod 2770 /public-genesis; chmod 750 /node-control /control; exec node ${runtime}/dist/scripts/subscriptions-init.js`],
|
|
133
|
+
volumes: [`app-state:${runtime}/state`, 'subscriptions:/subscriptions', 'agent-state:/meerkat/agent', 'genesis:/public-genesis',
|
|
134
|
+
'node-control:/node-control', 'control:/control'] },
|
|
135
|
+
},
|
|
136
|
+
volumes: { 'committee-data': volume('committee-data'), genesis: volume('genesis'), 'node-data': volume('node-data'),
|
|
137
|
+
'app-state': volume('app-state'), subscriptions: volume('subscriptions'), 'agent-state': volume('agent-state'),
|
|
138
|
+
'node-control': volume('node-control'), control: volume('control') },
|
|
139
|
+
networks: { default: { name: `${state.project}-network`, internal: true, labels } },
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
async function command(command, args, env = process.env, cwd, timeoutMs = 600_000) {
|
|
143
|
+
return new Promise((resolve, reject) => {
|
|
144
|
+
const child = spawn(command, args, { env, cwd, stdio: ['ignore', 'pipe', 'pipe'] });
|
|
145
|
+
let stdout = '', stderr = '', timedOut = false;
|
|
146
|
+
const timer = setTimeout(() => { timedOut = true; child.kill('SIGTERM'); }, timeoutMs);
|
|
147
|
+
const hard = setTimeout(() => child.kill('SIGKILL'), timeoutMs + 5_000);
|
|
148
|
+
child.stdout.on('data', data => { stdout = (stdout + String(data)).slice(-2 * 1024 * 1024); });
|
|
149
|
+
child.stderr.on('data', data => { stderr = (stderr + String(data)).slice(-8192); });
|
|
150
|
+
child.on('error', error => { clearTimeout(timer); clearTimeout(hard); reject(error); });
|
|
151
|
+
child.on('close', code => {
|
|
152
|
+
clearTimeout(timer);
|
|
153
|
+
clearTimeout(hard);
|
|
154
|
+
if (code !== 0 || timedOut)
|
|
155
|
+
reject(new Error(`${command} ${args[0] ?? ''} failed${timedOut ? ' (deadline)' : ''}: ${stderr}`));
|
|
156
|
+
else
|
|
157
|
+
resolve(stdout);
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
const composeArgs = (state) => ['compose', '--project-name', state.project, '--file', join(state.dir, 'compose.json')];
|
|
162
|
+
const request = (state) => JSON.stringify({ mode: state.mode, nodeId: state.nodeId, committeeId: state.committeeId ?? '', identity: state.identity, channel: state.channel, binding: state.binding });
|
|
163
|
+
const defaults = {
|
|
164
|
+
command,
|
|
165
|
+
committeeReady: async (state, env) => {
|
|
166
|
+
await command('docker', [...composeArgs(state), 'run', '--rm', '--no-deps',
|
|
167
|
+
'--entrypoint', 'node', 'registry', control, 'committee-ready', request(state)], env, state.dir);
|
|
168
|
+
},
|
|
169
|
+
nodeBinding: async (state, env) => JSON.parse(await command('docker', [...composeArgs(state), 'run', '--rm', '--no-deps',
|
|
170
|
+
'--entrypoint', 'node', 'registry', control, 'node-binding', request(state)], env, state.dir)),
|
|
171
|
+
// runtime-control 'ready' owns a progress-aware wait (DevNet: 45 min budget, 10 min stall); a fresh
|
|
172
|
+
// DevNet follower needs well over 10 min to sync, so the outer deadline must sit above that budget.
|
|
173
|
+
registryReady: async (state, env) => { await command('docker', ['exec', `${state.project}-registry`, 'node', control, 'ready', request(state)], env, undefined, 50 * 60_000); },
|
|
174
|
+
bootstrap: async (state, env) => { await command('docker', ['exec', '--workdir', '/meerkat/agent', `${state.project}-registry`, 'node', control, 'bootstrap', request(state)], env); },
|
|
175
|
+
claimChannel: async (state, env) => { await command('docker', ['exec', '--workdir', '/meerkat/agent', `${state.project}-registry`, 'node', control, 'claim-channel', request(state)], env); },
|
|
176
|
+
};
|
|
177
|
+
export function operatorEnvironment(env) {
|
|
178
|
+
const result = {};
|
|
179
|
+
for (const key of ['HOME', 'PATH', 'USER', 'XDG_STATE_HOME', 'TMPDIR', 'DOCKER_HOST', 'DOCKER_CONTEXT', 'DOCKER_TLS_VERIFY', 'DOCKER_CERT_PATH', 'DOCKER_CONFIG'])
|
|
180
|
+
if (env[key] !== undefined)
|
|
181
|
+
result[key] = env[key];
|
|
182
|
+
return result;
|
|
183
|
+
}
|
|
184
|
+
async function privateDirectory(path) {
|
|
185
|
+
await mkdir(path, { recursive: true, mode: 0o700 });
|
|
186
|
+
const s = await lstat(path);
|
|
187
|
+
if (!s.isDirectory() || s.isSymbolicLink() || s.uid !== process.getuid?.() || (s.mode & 0o077))
|
|
188
|
+
throw new Error('managed state must be a private operator-owned directory, not a symlink');
|
|
189
|
+
}
|
|
190
|
+
async function readState(path) {
|
|
191
|
+
let handle;
|
|
192
|
+
try {
|
|
193
|
+
handle = await open(path, constants.O_RDONLY | constants.O_NOFOLLOW);
|
|
194
|
+
}
|
|
195
|
+
catch (e) {
|
|
196
|
+
if (e.code === 'ENOENT')
|
|
197
|
+
return undefined;
|
|
198
|
+
throw e;
|
|
199
|
+
}
|
|
200
|
+
try {
|
|
201
|
+
const info = await handle.stat();
|
|
202
|
+
if (!info.isFile() || info.size > 65536 || info.uid !== process.getuid?.() || (info.mode & 0o077))
|
|
203
|
+
throw new Error('invalid managed installation ownership');
|
|
204
|
+
const parsed = JSON.parse(await handle.readFile('utf8'));
|
|
205
|
+
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed))
|
|
206
|
+
throw new Error('invalid saved installation object; refusing adoption');
|
|
207
|
+
return parsed;
|
|
208
|
+
}
|
|
209
|
+
finally {
|
|
210
|
+
await handle.close();
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
async function saveState(state) {
|
|
214
|
+
const temporary = join(state.dir, `installation.${randomBytes(8).toString('hex')}.tmp`);
|
|
215
|
+
const handle = await open(temporary, 'wx', 0o600);
|
|
216
|
+
try {
|
|
217
|
+
await handle.writeFile(JSON.stringify(state, null, 2) + '\n');
|
|
218
|
+
await handle.sync();
|
|
219
|
+
}
|
|
220
|
+
finally {
|
|
221
|
+
await handle.close();
|
|
222
|
+
}
|
|
223
|
+
await rename(temporary, join(state.dir, 'installation.json'));
|
|
224
|
+
}
|
|
225
|
+
async function ownership(state, deps, env, fresh) {
|
|
226
|
+
const daemonId = (await deps.command('docker', ['info', '--format', '{{.ID}}'], env)).trim();
|
|
227
|
+
if (daemonId !== state.daemonId)
|
|
228
|
+
throw new Error('Docker daemon identity differs; refusing resource adoption');
|
|
229
|
+
const devnet = state.mode === 'devnet';
|
|
230
|
+
const services = devnet ? ['node', 'registry'] : ['committee', 'node', 'registry'];
|
|
231
|
+
const volumes = devnet ? ['node-data', 'app-state', 'subscriptions', 'agent-state', 'node-control', 'control'] : ['committee-data', 'genesis', 'node-data', 'app-state', 'subscriptions', 'agent-state', 'node-control', 'control'];
|
|
232
|
+
for (const [args, name] of [
|
|
233
|
+
[['ps', '-a'], `^/${state.project}-(${services.join('|')})$`],
|
|
234
|
+
[['volume', 'ls'], `^${state.project}-(${volumes.join('|')})$`],
|
|
235
|
+
[['network', 'ls'], `^${state.project}-network$`],
|
|
236
|
+
]) {
|
|
237
|
+
const output = await deps.command('docker', [...args, '--filter', `name=${name}`, '--format', 'json'], env);
|
|
238
|
+
const rows = output.trim() ? output.trim().startsWith('[') ? JSON.parse(output) : output.trim().split('\n').map(line => JSON.parse(line)) : [];
|
|
239
|
+
if (fresh && rows.length)
|
|
240
|
+
throw new Error('foreign project resources exist; refusing adoption');
|
|
241
|
+
if (state.binding && ((args[0] === 'volume' && rows.length !== volumes.length) || (args[0] === 'network' && rows.length !== 1) || (args[0] === 'ps' && rows.length < (state.ready ? services.length : services.length - 1))))
|
|
242
|
+
throw new Error('saved owned deployment resources are missing; refusing regeneration/re-genesis');
|
|
243
|
+
for (const row of rows) {
|
|
244
|
+
const labels = row.Labels;
|
|
245
|
+
if (!(typeof labels === 'string' ? labels.split(',').includes(`${OWNER}=${state.id}`) : labels?.[OWNER] === state.id))
|
|
246
|
+
throw new Error('unrelated resource ownership; refusing start/replacement');
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
function validateState(state, dir, version) {
|
|
251
|
+
const id = state.id, nodeId = state.nodeId, identity = state.identity;
|
|
252
|
+
const portsOk = Array.isArray(state.ports) && state.ports.length === 3 &&
|
|
253
|
+
new Set(state.ports).size === 3 &&
|
|
254
|
+
state.ports.every(p => Number.isSafeInteger(p) && p >= 1024 && p <= 65535);
|
|
255
|
+
const baseline = state.version === 1 && state.uid === process.getuid?.() && state.dir === dir &&
|
|
256
|
+
/^[0-9a-f]{24}$/.test(id) && state.project === `meerkat-${id}` &&
|
|
257
|
+
nodeId === `meerkatnode${id}` && identity === `meerkatuser${id}` &&
|
|
258
|
+
typeof state.daemonId === 'string' && /^[A-Za-z0-9:._-]{8,200}$/.test(state.daemonId) &&
|
|
259
|
+
/^[A-Za-z0-9]{1,50}$/.test(state.registryOperator) && state.packageVersion === version &&
|
|
260
|
+
['pending', 'attempted', 'complete'].includes(state.initialization) && portsOk &&
|
|
261
|
+
!(state.binding && (state.binding.nodeId !== state.nodeId || !/^[0-9a-f]{64}$/.test(state.binding.chainId)));
|
|
262
|
+
if (!baseline)
|
|
263
|
+
throw new Error('invalid saved installation or package version differs; refusing automatic migration/adoption');
|
|
264
|
+
if (state.mode === 'devnet') {
|
|
265
|
+
if (state.committeeId !== undefined || state.channel !== DEVNET_CHANNEL || state.registryOperator !== DEVNET_OPERATOR)
|
|
266
|
+
throw new Error('invalid saved installation mode/resources; refusing automatic migration/adoption');
|
|
267
|
+
}
|
|
268
|
+
else if (state.mode === 'local') {
|
|
269
|
+
if (state.committeeId !== `meerkatquorum${id}` || state.channel !== `meerkat.${id}.announcements` || state.registryOperator !== identity)
|
|
270
|
+
throw new Error('invalid saved installation mode/resources; refusing automatic migration/adoption');
|
|
271
|
+
}
|
|
272
|
+
else {
|
|
273
|
+
throw new Error('invalid saved installation mode; refusing automatic migration/adoption');
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
export async function managedInstallation(mode = 'devnet', env = process.env) {
|
|
277
|
+
const state = await readState(managedConfigPath(mode, env));
|
|
278
|
+
if (state) {
|
|
279
|
+
const version = JSON.parse(await readFile(join(packageDir, 'package.json'), 'utf8')).version;
|
|
280
|
+
validateState(state, modeDirectory(mode, env), version);
|
|
281
|
+
}
|
|
282
|
+
return state;
|
|
283
|
+
}
|
|
284
|
+
/** Protocol-only stdio bridge, one new facade/private child/session per harness connection.
|
|
285
|
+
* Docker exec works even when daemon and harness share neither filesystem nor loopback. */
|
|
286
|
+
export async function serveManaged(state, env = process.env) {
|
|
287
|
+
await ownership(state, defaults, operatorEnvironment(env), false);
|
|
288
|
+
if (state.initialization !== 'complete' || !state.binding || !state.ready)
|
|
289
|
+
throw new Error('managed install is incomplete; rerun install');
|
|
290
|
+
const cleanEnv = operatorEnvironment(env);
|
|
291
|
+
const observed = JSON.parse(await command('docker', ['exec', `${state.project}-registry`, 'node', control, 'node-binding', request(state)], cleanEnv));
|
|
292
|
+
if (observed.chainId !== state.binding.chainId || observed.nodeId !== state.binding.nodeId)
|
|
293
|
+
throw new Error('saved managed binding changed');
|
|
294
|
+
const token = randomBytes(16).toString('hex');
|
|
295
|
+
const sessionCommand = (mode) => command('docker', ['exec', `${state.project}-registry`, 'node', control, mode, token], cleanEnv).then(() => { });
|
|
296
|
+
let remoteStop, requestedStop = false, started = false;
|
|
297
|
+
const stopRemote = () => remoteStop ??= sessionCommand('stop-session');
|
|
298
|
+
let onFailure = () => { };
|
|
299
|
+
const stop = () => { requestedStop = true; if (started)
|
|
300
|
+
void stopRemote().catch(error => onFailure(error)); };
|
|
301
|
+
process.once('SIGINT', stop);
|
|
302
|
+
process.once('SIGTERM', stop);
|
|
303
|
+
try {
|
|
304
|
+
await sessionCommand('prepare-session');
|
|
305
|
+
if (requestedStop) {
|
|
306
|
+
await sessionCommand('discard-session');
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
309
|
+
await new Promise((resolve, reject) => {
|
|
310
|
+
onFailure = reject;
|
|
311
|
+
// The remote helper knows this exact preallocated token before docker exec can start.
|
|
312
|
+
// A signal before its PID is recorded sets cancellation, never signals an arbitrary PID.
|
|
313
|
+
started = true;
|
|
314
|
+
const child = spawn('docker', ['exec', '-i', `${state.project}-registry`, 'node', control, 'serve-session', token], { env: cleanEnv, stdio: 'inherit' });
|
|
315
|
+
child.once('error', error => { void sessionCommand('discard-session').then(() => reject(error), reject); });
|
|
316
|
+
child.once('close', code => {
|
|
317
|
+
void stopRemote().then(() => code === 0 || requestedStop ? resolve() : reject(new Error('owned Meerkat stdio process exited')), reject);
|
|
318
|
+
});
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
finally {
|
|
322
|
+
process.off('SIGINT', stop);
|
|
323
|
+
process.off('SIGTERM', stop);
|
|
324
|
+
if (started)
|
|
325
|
+
await stopRemote();
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
export async function installMeerkat(mode = 'devnet', env = process.env, deps = defaults) {
|
|
329
|
+
if (Number(process.versions.node.split('.')[0]) < 22)
|
|
330
|
+
throw new Error('Meerkat install requires Node.js 22 or newer, npm/npx, and Docker Engine with Compose v2');
|
|
331
|
+
const packageVersion = JSON.parse(await readFile(join(packageDir, 'package.json'), 'utf8')).version;
|
|
332
|
+
const dir = modeDirectory(mode, env), configPath = managedConfigPath(mode, env), cleanEnv = operatorEnvironment(env);
|
|
333
|
+
await deps.command('docker', ['version', '--format', 'json'], cleanEnv);
|
|
334
|
+
await deps.command('docker', ['compose', 'version'], cleanEnv);
|
|
335
|
+
await deps.command('npm', ['--version'], cleanEnv);
|
|
336
|
+
await deps.command('npx', ['--version'], cleanEnv);
|
|
337
|
+
const daemonId = (await deps.command('docker', ['info', '--format', '{{.ID}}'], cleanEnv)).trim();
|
|
338
|
+
if (!/^[A-Za-z0-9:._-]{8,200}$/.test(daemonId))
|
|
339
|
+
throw new Error('cannot establish Docker daemon identity');
|
|
340
|
+
await privateDirectory(dir);
|
|
341
|
+
const lock = join(dir, 'install.lock');
|
|
342
|
+
// Do not kill a Docker CLI and abandon its remote operation. An interrupt finishes the
|
|
343
|
+
// current bounded operation, persists its known checkpoint, then releases only this lock.
|
|
344
|
+
let interrupted = false, locked = false;
|
|
345
|
+
const interrupt = () => { interrupted = true; };
|
|
346
|
+
const checkpoint = () => { if (interrupted)
|
|
347
|
+
throw new Error('installation interrupted; owned state retained at its last known checkpoint, rerun the same install command'); };
|
|
348
|
+
process.once('SIGINT', interrupt);
|
|
349
|
+
process.once('SIGTERM', interrupt);
|
|
350
|
+
try {
|
|
351
|
+
await mkdir(lock, { mode: 0o700 }).catch(() => { throw new Error(`another installation owns ${lock}; no automatic lock recovery`); });
|
|
352
|
+
locked = true;
|
|
353
|
+
checkpoint();
|
|
354
|
+
let state = await readState(configPath);
|
|
355
|
+
const fresh = !state;
|
|
356
|
+
if (!state) {
|
|
357
|
+
// A previous explicit facade configuration is not ours to replace or adopt.
|
|
358
|
+
try {
|
|
359
|
+
await lstat(join(dir, 'config.json'));
|
|
360
|
+
throw new Error('unrelated Meerkat config exists; refusing replacement');
|
|
361
|
+
}
|
|
362
|
+
catch (e) {
|
|
363
|
+
if (e.code !== 'ENOENT')
|
|
364
|
+
throw e;
|
|
365
|
+
}
|
|
366
|
+
const id = randomBytes(12).toString('hex');
|
|
367
|
+
const devnet = mode === 'devnet';
|
|
368
|
+
state = { version: 1, uid: process.getuid(), id, dir, project: `meerkat-${id}`, mode,
|
|
369
|
+
nodeId: `meerkatnode${id}`, identity: `meerkatuser${id}`,
|
|
370
|
+
registryOperator: devnet ? DEVNET_OPERATOR : `meerkatuser${id}`,
|
|
371
|
+
channel: devnet ? DEVNET_CHANNEL : `meerkat.${id}.announcements`,
|
|
372
|
+
ports: [8440, 8450, 8090], packageVersion, daemonId, initialization: 'pending',
|
|
373
|
+
...(devnet ? {} : { committeeId: `meerkatquorum${id}` }) };
|
|
374
|
+
}
|
|
375
|
+
validateState(state, dir, packageVersion);
|
|
376
|
+
if (state.initialization === 'attempted')
|
|
377
|
+
throw new Error('fresh initialization was interrupted; retained state requires operator inspection, never automatic reseeding');
|
|
378
|
+
await ownership(state, deps, cleanEnv, fresh);
|
|
379
|
+
checkpoint();
|
|
380
|
+
if (fresh) {
|
|
381
|
+
await cp(join(packageDir, 'dist'), join(dir, 'package', 'dist'), { recursive: true, errorOnExist: true, force: false });
|
|
382
|
+
await cp(join(packageDir, 'installer'), join(dir, 'package', 'installer'), { recursive: true, errorOnExist: true, force: false });
|
|
383
|
+
await cp(join(packageDir, 'package.json'), join(dir, 'package', 'package.json'), { errorOnExist: true, force: false });
|
|
384
|
+
await saveState(state);
|
|
385
|
+
}
|
|
386
|
+
const composePath = join(dir, 'compose.json');
|
|
387
|
+
const compose = async (...args) => deps.command('docker', [...composeArgs(state), ...args], cleanEnv, dir);
|
|
388
|
+
await writeFile(composePath, JSON.stringify(renderDeployment(state), null, 2), { mode: 0o600 });
|
|
389
|
+
await compose('config', '--quiet');
|
|
390
|
+
checkpoint();
|
|
391
|
+
if (state.initialization === 'pending') {
|
|
392
|
+
await compose('build', ...(state.mode === 'devnet' ? ['node', 'registry'] : ['committee', 'node', 'registry']));
|
|
393
|
+
checkpoint();
|
|
394
|
+
state.initialization = 'attempted';
|
|
395
|
+
await saveState(state);
|
|
396
|
+
await compose('--profile', 'initialize-only', 'run', '--rm', '--no-deps', 'subscriptions-init');
|
|
397
|
+
state.initialization = 'complete';
|
|
398
|
+
await saveState(state);
|
|
399
|
+
checkpoint();
|
|
400
|
+
}
|
|
401
|
+
if (state.mode === 'local') {
|
|
402
|
+
await compose('up', '-d', '--no-build', '--no-recreate', 'committee');
|
|
403
|
+
await deps.committeeReady(state, cleanEnv);
|
|
404
|
+
checkpoint();
|
|
405
|
+
}
|
|
406
|
+
await compose('up', '-d', '--no-build', '--no-recreate', 'node');
|
|
407
|
+
checkpoint();
|
|
408
|
+
const observed = await deps.nodeBinding(state, cleanEnv);
|
|
409
|
+
const expectedChain = state.mode === 'devnet' ? DEVNET_CHAIN_ID : null;
|
|
410
|
+
if (observed.nodeId !== state.nodeId || !/^[0-9a-f]{64}$/.test(observed.chainId) ||
|
|
411
|
+
(state.binding && state.binding.chainId !== observed.chainId) ||
|
|
412
|
+
(expectedChain && observed.chainId !== expectedChain))
|
|
413
|
+
throw new Error('owned node returned an invalid or changed saved binding');
|
|
414
|
+
state.binding = observed;
|
|
415
|
+
await saveState(state);
|
|
416
|
+
checkpoint();
|
|
417
|
+
await writeFile(composePath, JSON.stringify(renderDeployment(state), null, 2), { mode: 0o600 });
|
|
418
|
+
await compose('up', '-d', '--no-build', '--no-recreate', 'registry');
|
|
419
|
+
checkpoint();
|
|
420
|
+
await deps.bootstrap(state, cleanEnv);
|
|
421
|
+
if (state.mode === 'local' && !state.ready) {
|
|
422
|
+
// The agent owns the install's private channel; claim it once through the child's own tools,
|
|
423
|
+
// BEFORE the registry's readiness check, so the read-only registry sees its pinned operator.
|
|
424
|
+
// A completed install never repeats the step. An interrupted one retries it: the runtime
|
|
425
|
+
// reads the terms first and never re-claims a channel the agent already owns.
|
|
426
|
+
await deps.claimChannel(state, cleanEnv);
|
|
427
|
+
}
|
|
428
|
+
await deps.registryReady(state, cleanEnv);
|
|
429
|
+
checkpoint();
|
|
430
|
+
state.ready = true;
|
|
431
|
+
await saveState(state);
|
|
432
|
+
checkpoint();
|
|
433
|
+
return { dir, configPath, registration: pinnedRegistration(state.packageVersion, state.mode) };
|
|
434
|
+
}
|
|
435
|
+
finally {
|
|
436
|
+
try {
|
|
437
|
+
if (locked)
|
|
438
|
+
await rm(lock, { recursive: true });
|
|
439
|
+
}
|
|
440
|
+
finally {
|
|
441
|
+
process.off('SIGINT', interrupt);
|
|
442
|
+
process.off('SIGTERM', interrupt);
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
//# sourceMappingURL=installer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"installer.js","sourceRoot":"","sources":["../src/installer.ts"],"names":[],"mappings":"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"}
|
package/dist/mcp-announce.d.ts
CHANGED
|
@@ -36,6 +36,24 @@ export type McpAnnouncementResult = AnnouncementState & ({
|
|
|
36
36
|
readonly kind: "error" | "refused";
|
|
37
37
|
readonly txId?: string;
|
|
38
38
|
});
|
|
39
|
+
/** Strip the child's single terminal warning suffix and return the one text block. Exported for the
|
|
40
|
+
* installer's controlled claim/sign flows (sign_claim_channel) which share this exact released renderer. */
|
|
41
|
+
export declare function resultText(result: CallToolResult): string;
|
|
42
|
+
/** Parse a successful ToolResult into a JSON object, refusing non-ok prose. Exported for the
|
|
43
|
+
* installer's claim flow, which must not hand-roll decoding of the released child's results. */
|
|
44
|
+
export declare function jsonResult(result: CallToolResult): Record<string, unknown>;
|
|
45
|
+
/** Validate the released child's `evolver_sign_claim_channel` acknowledgement and return its txId.
|
|
46
|
+
* Exported for the installer's local-mode channel claim, which must not hand-roll this decoding. */
|
|
47
|
+
export declare function claimTxId(result: CallToolResult, channel: string): string;
|
|
48
|
+
type DecodedSubmit = {
|
|
49
|
+
readonly kind: "committed" | "fined" | "refused" | "already_submitted" | "unknown";
|
|
50
|
+
readonly message: string;
|
|
51
|
+
readonly reason?: string;
|
|
52
|
+
readonly commitIntervalMs?: number;
|
|
53
|
+
};
|
|
54
|
+
/** Decode only complete released ordinary-submit templates. Unrecognized/mismatched data => UNKNOWN.
|
|
55
|
+
* Exported for the installer's local-mode channel claim, which must act on the real outcome. */
|
|
56
|
+
export declare function submissionResult(result: CallToolResult, txId: string): DecodedSubmit;
|
|
39
57
|
/** One same owned session; zero local signing/key/node access; one ordinary submit of its original id. */
|
|
40
58
|
export declare function announceViaMcp(session: McpAnnounceSession, request: AnnounceRequest, options: McpAnnounceOptions): Promise<McpAnnouncementResult>;
|
|
41
59
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-announce.d.ts","sourceRoot":"","sources":["../src/mcp-announce.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACzE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAErD,OAAO,KAAK,EAAiB,SAAS,EAAE,MAAM,eAAe,CAAC;AAE9D,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IACrG,4FAA4F;IAC5F,MAAM,IAAI,OAAO,CAAC;CACnB;AACD,MAAM,WAAW,kBAAkB;IACjC,qFAAqF;IACrF,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;IAC9B,iFAAiF;IACjF,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,mGAAmG;IACnG,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACtD;AACD,MAAM,MAAM,gBAAgB,GAAG,YAAY,GAAG,WAAW,GAAG,SAAS,GAAG,MAAM,GAAG,eAAe,GAAG,QAAQ,CAAC;AAC5G,UAAU,iBAAiB;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAAC;IAClC,4FAA4F;IAC5F,QAAQ,CAAC,MAAM,EAAE,eAAe,GAAG,cAAc,GAAG,SAAS,CAAC;IAC9D,QAAQ,CAAC,KAAK,EAAE,gBAAgB,CAAC;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;CACpC;AACD,MAAM,MAAM,qBAAqB,GAAG,iBAAiB,GAAG,CACpD;IAAE,QAAQ,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,GAAG,SAAS,GAAG,mBAAmB,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACjG;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,SAAS,CAAC;IAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CACjE,CAAC;
|
|
1
|
+
{"version":3,"file":"mcp-announce.d.ts","sourceRoot":"","sources":["../src/mcp-announce.ts"],"names":[],"mappings":"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"}
|
package/dist/mcp-announce.js
CHANGED
|
@@ -17,7 +17,9 @@ function record(v) {
|
|
|
17
17
|
function round(v) {
|
|
18
18
|
return typeof v === "number" && Number.isSafeInteger(v) && v >= 0;
|
|
19
19
|
}
|
|
20
|
-
|
|
20
|
+
/** Strip the child's single terminal warning suffix and return the one text block. Exported for the
|
|
21
|
+
* installer's controlled claim/sign flows (sign_claim_channel) which share this exact released renderer. */
|
|
22
|
+
export function resultText(result) {
|
|
21
23
|
if (!record(result) || result.isError === true ||
|
|
22
24
|
(result.isError !== undefined && result.isError !== false) ||
|
|
23
25
|
!Array.isArray(result.content) || result.content.length !== 1)
|
|
@@ -28,7 +30,9 @@ function resultText(result) {
|
|
|
28
30
|
throw new Error("upstream result is not bounded text with the recognized terminal warning");
|
|
29
31
|
return block.text.slice(0, -UNTRUSTED.length);
|
|
30
32
|
}
|
|
31
|
-
|
|
33
|
+
/** Parse a successful ToolResult into a JSON object, refusing non-ok prose. Exported for the
|
|
34
|
+
* installer's claim flow, which must not hand-roll decoding of the released child's results. */
|
|
35
|
+
export function jsonResult(result) {
|
|
32
36
|
const text = resultText(result);
|
|
33
37
|
// Non-ok ToolResult prose is NOT a JSON success, even with isError:false.
|
|
34
38
|
if (/^(?:misconfigured|partial|wrong_kind|not_found): /.test(text))
|
|
@@ -70,8 +74,18 @@ function signatureResult(result, channel) {
|
|
|
70
74
|
throw new Error("upstream signing acknowledgement is not a valid channel-write intent for the configured channel");
|
|
71
75
|
return s.txId;
|
|
72
76
|
}
|
|
73
|
-
/**
|
|
74
|
-
|
|
77
|
+
/** Validate the released child's `evolver_sign_claim_channel` acknowledgement and return its txId.
|
|
78
|
+
* Exported for the installer's local-mode channel claim, which must not hand-roll this decoding. */
|
|
79
|
+
export function claimTxId(result, channel) {
|
|
80
|
+
const s = jsonResult(result);
|
|
81
|
+
if (typeof s.txId !== "string" || !TX_ID.test(s.txId) || s.verb !== "channel_claim" ||
|
|
82
|
+
!record(s.fields) || s.fields.channel !== channel || !record(s.summary))
|
|
83
|
+
throw new Error("upstream signing acknowledgement is not a valid channel-claim intent for the configured channel");
|
|
84
|
+
return s.txId;
|
|
85
|
+
}
|
|
86
|
+
/** Decode only complete released ordinary-submit templates. Unrecognized/mismatched data => UNKNOWN.
|
|
87
|
+
* Exported for the installer's local-mode channel claim, which must act on the real outcome. */
|
|
88
|
+
export function submissionResult(result, txId) {
|
|
75
89
|
const text = resultText(result);
|
|
76
90
|
const committed = /^committed: the transaction was ordered as ([0-9a-fA-F]{64})(?:, taking (\d+) ms to commit)?\. ⚠️ ORDERED is not the same as PAID — did the payment land is answered by the balance, not by ordering\.(?: `commitIntervalMs` is the submit-to-commit time in milliseconds\.)?$/.exec(text);
|
|
77
91
|
if (committed) {
|