@amalgm/shell 0.1.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.
Files changed (105) hide show
  1. package/PURPOSE.md +73 -0
  2. package/README.md +33 -0
  3. package/dist/automations-host.d.ts +19 -0
  4. package/dist/automations-host.js +41 -0
  5. package/dist/automations-host.js.map +1 -0
  6. package/dist/boot.d.ts +53 -0
  7. package/dist/boot.js +249 -0
  8. package/dist/boot.js.map +1 -0
  9. package/dist/bundle-apps.d.ts +12 -0
  10. package/dist/bundle-apps.js +71 -0
  11. package/dist/bundle-apps.js.map +1 -0
  12. package/dist/bundle-automations.d.ts +8 -0
  13. package/dist/bundle-automations.js +106 -0
  14. package/dist/bundle-automations.js.map +1 -0
  15. package/dist/bundle-bindings.d.ts +8 -0
  16. package/dist/bundle-bindings.js +101 -0
  17. package/dist/bundle-bindings.js.map +1 -0
  18. package/dist/bundle-port.d.ts +14 -0
  19. package/dist/bundle-port.js +166 -0
  20. package/dist/bundle-port.js.map +1 -0
  21. package/dist/chat-host.d.ts +32 -0
  22. package/dist/chat-host.js +167 -0
  23. package/dist/chat-host.js.map +1 -0
  24. package/dist/chat-payloads-host.d.ts +8 -0
  25. package/dist/chat-payloads-host.js +76 -0
  26. package/dist/chat-payloads-host.js.map +1 -0
  27. package/dist/chat-relay-host.d.ts +24 -0
  28. package/dist/chat-relay-host.js +90 -0
  29. package/dist/chat-relay-host.js.map +1 -0
  30. package/dist/cli.d.ts +1 -0
  31. package/dist/cli.js +157 -0
  32. package/dist/cli.js.map +1 -0
  33. package/dist/compose.d.ts +32 -0
  34. package/dist/compose.js +35 -0
  35. package/dist/compose.js.map +1 -0
  36. package/dist/credentials-host.d.ts +7 -0
  37. package/dist/credentials-host.js +143 -0
  38. package/dist/credentials-host.js.map +1 -0
  39. package/dist/diagnostics-host.d.ts +3 -0
  40. package/dist/diagnostics-host.js +92 -0
  41. package/dist/diagnostics-host.js.map +1 -0
  42. package/dist/drivers/claude-code.d.ts +27 -0
  43. package/dist/drivers/claude-code.js +72 -0
  44. package/dist/drivers/claude-code.js.map +1 -0
  45. package/dist/event-triggers-host.d.ts +4 -0
  46. package/dist/event-triggers-host.js +48 -0
  47. package/dist/event-triggers-host.js.map +1 -0
  48. package/dist/events-host.d.ts +9 -0
  49. package/dist/events-host.js +34 -0
  50. package/dist/events-host.js.map +1 -0
  51. package/dist/external-proxy-host.d.ts +15 -0
  52. package/dist/external-proxy-host.js +166 -0
  53. package/dist/external-proxy-host.js.map +1 -0
  54. package/dist/filesystem.d.ts +7 -0
  55. package/dist/filesystem.js +71 -0
  56. package/dist/filesystem.js.map +1 -0
  57. package/dist/forward.d.ts +11 -0
  58. package/dist/forward.js +36 -0
  59. package/dist/forward.js.map +1 -0
  60. package/dist/gateway.d.ts +33 -0
  61. package/dist/gateway.js +85 -0
  62. package/dist/gateway.js.map +1 -0
  63. package/dist/index.d.ts +23 -0
  64. package/dist/index.js +14 -0
  65. package/dist/index.js.map +1 -0
  66. package/dist/local-host.d.ts +8 -0
  67. package/dist/local-host.js +101 -0
  68. package/dist/local-host.js.map +1 -0
  69. package/dist/machine-host.d.ts +56 -0
  70. package/dist/machine-host.js +340 -0
  71. package/dist/machine-host.js.map +1 -0
  72. package/dist/main.d.ts +2 -0
  73. package/dist/main.js +4 -0
  74. package/dist/main.js.map +1 -0
  75. package/dist/parity.d.ts +40 -0
  76. package/dist/parity.js +108 -0
  77. package/dist/parity.js.map +1 -0
  78. package/dist/ports-host.d.ts +8 -0
  79. package/dist/ports-host.js +26 -0
  80. package/dist/ports-host.js.map +1 -0
  81. package/dist/pty-host.d.ts +14 -0
  82. package/dist/pty-host.js +141 -0
  83. package/dist/pty-host.js.map +1 -0
  84. package/dist/release-catalog.d.ts +5 -0
  85. package/dist/release-catalog.js +23 -0
  86. package/dist/release-catalog.js.map +1 -0
  87. package/dist/state-host.d.ts +4 -0
  88. package/dist/state-host.js +67 -0
  89. package/dist/state-host.js.map +1 -0
  90. package/dist/state-store.d.ts +15 -0
  91. package/dist/state-store.js +63 -0
  92. package/dist/state-store.js.map +1 -0
  93. package/dist/user-ground-host.d.ts +58 -0
  94. package/dist/user-ground-host.js +809 -0
  95. package/dist/user-ground-host.js.map +1 -0
  96. package/dist/wire-client.d.ts +44 -0
  97. package/dist/wire-client.js +235 -0
  98. package/dist/wire-client.js.map +1 -0
  99. package/dist/workspace-host.d.ts +5 -0
  100. package/dist/workspace-host.js +73 -0
  101. package/dist/workspace-host.js.map +1 -0
  102. package/dist/workspace-store.d.ts +10 -0
  103. package/dist/workspace-store.js +47 -0
  104. package/dist/workspace-store.js.map +1 -0
  105. package/package.json +55 -0
@@ -0,0 +1,340 @@
1
+ import { randomBytes, randomUUID } from "node:crypto";
2
+ import { existsSync, readdirSync, rmSync } from "node:fs";
3
+ import { homedir as osHomedir, hostname, platform, release } from "node:os";
4
+ import { join } from "node:path";
5
+ import { buildRootManifest, joinMachine, mergeRecordAuth, resumeMachine, scopedAmalgmDir, userMachineDir, } from "@amalgm/core/identity";
6
+ import { bootShell } from "./boot.js";
7
+ import { atomicJson, atomicJsonSet, ensurePrivateDir, readJson, } from "./filesystem.js";
8
+ import { shellReleaseCatalog, shellReleaseVerifier } from "./release-catalog.js";
9
+ import { UserGroundHost } from "./user-ground-host.js";
10
+ /** The production effects around Core's machine-setup operation. It does not
11
+ * decide ordering, readiness, or installation selection; those remain Core. */
12
+ export class MachineHost {
13
+ options;
14
+ homedir;
15
+ amalgmRoot;
16
+ deviceFile;
17
+ ports;
18
+ selectedUserEmail;
19
+ groundHost = null;
20
+ running = new Set();
21
+ constructor(options) {
22
+ this.options = options;
23
+ this.homedir = options.homedir ?? osHomedir();
24
+ this.amalgmRoot = options.amalgmRoot ?? join(this.homedir, "amalgm");
25
+ this.deviceFile = join(this.amalgmRoot, ".amalgm", "device.json");
26
+ this.selectedUserEmail = normalizeEmail(options.userEmail);
27
+ this.ensureInstallationRoot();
28
+ const deviceStore = {
29
+ load: async () => readJson(this.deviceFile),
30
+ save: async (device) => atomicJson(this.deviceFile, device),
31
+ };
32
+ const machineStore = {
33
+ load: async () => this.loadMachine(),
34
+ save: async (machine) => this.saveMachine(machine),
35
+ markReady: async () => {
36
+ const paths = this.paths();
37
+ atomicJson(paths.status, { ready: true, updatedAt: new Date().toISOString() });
38
+ },
39
+ };
40
+ const controlPlane = {
41
+ start: (body) => postJson(this.options.appUrl, "/api/auth/computer-setup/cli/start", body),
42
+ poll: (body) => postJson(this.options.appUrl, "/api/auth/computer-setup/cli/poll", body),
43
+ redeem: (body) => postJson(this.options.appUrl, "/api/auth/computer-setup/redeem", body),
44
+ register: async (token, body) => {
45
+ const response = await postJson(this.options.appUrl, "/api/computers/register", body, token);
46
+ const email = normalizeEmail(response.user_email);
47
+ if (!email)
48
+ throw Object.assign(new Error("registration did not return a user email"), {
49
+ code: "missing_user_email",
50
+ });
51
+ this.selectedUserEmail = email;
52
+ return response;
53
+ },
54
+ refreshProxy: (token, body) => postJson(this.options.appUrl, "/api/computers/proxy-token", body, token),
55
+ };
56
+ const installer = {
57
+ install: async (plan) => {
58
+ const releaseDir = join(this.amalgmRoot, ".amalgm", "managed", "releases", plan.releaseId);
59
+ ensurePrivateDir(releaseDir);
60
+ atomicJson(join(releaseDir, "services.json"), {
61
+ releaseId: plan.releaseId,
62
+ services: plan.services,
63
+ runtimeVersion: this.options.runtimeVersion,
64
+ });
65
+ return { id: plan.releaseId };
66
+ },
67
+ rollback: async (installed) => {
68
+ const target = join(this.amalgmRoot, ".amalgm", "managed", "releases", installed.id);
69
+ rmSync(target, { recursive: true, force: true });
70
+ },
71
+ };
72
+ const userGround = {
73
+ converge: async (identity) => {
74
+ const machine = await this.loadMachine();
75
+ if (!machine)
76
+ throw Object.assign(new Error("machine state is not durable"), { code: "machine_state_missing" });
77
+ const record = mergeRecordAuth(machine.publicRecord, machine.secretAuth) ?? {};
78
+ const tunnelUrl = text(record.tunnel_url);
79
+ const tunnelToken = text(record.tunnel_token);
80
+ if (!tunnelUrl || !tunnelToken) {
81
+ throw Object.assign(new Error("machine tunnel credentials are missing"), { code: "tunnel_credentials_missing" });
82
+ }
83
+ await this.groundHost?.close();
84
+ this.groundHost = new UserGroundHost({
85
+ amalgmRoot: this.amalgmRoot,
86
+ deviceId: identity.deviceId,
87
+ tunnelUrl,
88
+ tunnelToken,
89
+ runtimeVersion: this.options.runtimeVersion,
90
+ });
91
+ return this.groundHost.port.converge(identity);
92
+ },
93
+ };
94
+ const runtime = {
95
+ start: async (machine) => this.startRuntime(machine),
96
+ };
97
+ this.ports = {
98
+ deviceStore,
99
+ machineStore,
100
+ controlPlane,
101
+ catalog: { load: async () => shellReleaseCatalog, verifier: shellReleaseVerifier },
102
+ installer,
103
+ userGround,
104
+ runtime,
105
+ presentation: {
106
+ showSetup: (input) => this.options.showSetup?.(input),
107
+ },
108
+ diagnostics: {
109
+ write: (event) => this.options.diagnostic?.(event),
110
+ },
111
+ nowIso: () => new Date().toISOString(),
112
+ nowMs: () => Date.now(),
113
+ randomUuid: randomUUID,
114
+ sleep: (milliseconds) => new Promise((resolve) => setTimeout(resolve, milliseconds)),
115
+ };
116
+ }
117
+ join(input) {
118
+ return joinMachine({
119
+ ...input,
120
+ appUrl: this.options.appUrl,
121
+ platform: `${platform()}-${release()}`,
122
+ appVersion: this.options.runtimeVersion,
123
+ runtimeLabel: this.options.runtimeLabel ?? "main",
124
+ branch: this.options.branch ?? "main",
125
+ }, this.ports);
126
+ }
127
+ resume() {
128
+ this.resolveUserForResume();
129
+ return resumeMachine(this.ports);
130
+ }
131
+ selectedPaths() {
132
+ return this.paths();
133
+ }
134
+ async close() {
135
+ const runtimes = [...this.running];
136
+ this.running.clear();
137
+ for (const runtime of runtimes)
138
+ await runtime.stop().catch(() => undefined);
139
+ await this.groundHost?.close();
140
+ this.groundHost = null;
141
+ }
142
+ ensureInstallationRoot() {
143
+ ensurePrivateDir(this.amalgmRoot);
144
+ const manifestFile = join(this.amalgmRoot, ".amalgm-root.json");
145
+ const existing = readJson(manifestFile);
146
+ const manifest = buildRootManifest(existing, {
147
+ nowIso: () => new Date().toISOString(),
148
+ randomHex: (bytes) => randomBytes(bytes).toString("hex"),
149
+ });
150
+ if (!existing?.installationId)
151
+ atomicJson(manifestFile, manifest);
152
+ }
153
+ paths(email = this.requireSelectedUser()) {
154
+ const userRoot = scopedAmalgmDir(this.amalgmRoot, email);
155
+ const device = readJson(this.deviceFile);
156
+ const deviceId = text(device?.device_id);
157
+ if (!deviceId)
158
+ throw Object.assign(new Error("physical device identity is missing"), { code: "device_missing" });
159
+ const machineDir = userMachineDir(userRoot, deviceId);
160
+ return {
161
+ userRoot,
162
+ machineDir,
163
+ publicRecord: join(machineDir, "computer.json"),
164
+ secretAuth: join(machineDir, "auth.json"),
165
+ installation: join(machineDir, "installation.json"),
166
+ status: join(machineDir, "status.json"),
167
+ };
168
+ }
169
+ requireSelectedUser() {
170
+ if (!this.selectedUserEmail) {
171
+ throw Object.assign(new Error("select a user with --user before resuming this machine"), {
172
+ code: "user_selection_required",
173
+ });
174
+ }
175
+ return this.selectedUserEmail;
176
+ }
177
+ resolveUserForResume() {
178
+ if (this.selectedUserEmail)
179
+ return;
180
+ const usersRoot = join(this.amalgmRoot, "users");
181
+ const device = readJson(this.deviceFile);
182
+ const deviceId = text(device?.device_id);
183
+ if (!deviceId || !existsSync(usersRoot))
184
+ return;
185
+ const candidates = [];
186
+ for (const entry of readdirSync(usersRoot, { withFileTypes: true })) {
187
+ if (!entry.isDirectory())
188
+ continue;
189
+ const userRoot = join(usersRoot, entry.name);
190
+ const manifest = readJson(join(userRoot, ".amalgm-user.json"));
191
+ const email = normalizeEmail(manifest?.canonicalEmail || entry.name);
192
+ const status = readJson(join(userMachineDir(userRoot, deviceId), "status.json"));
193
+ if (email && status?.ready === true)
194
+ candidates.push(email);
195
+ }
196
+ if (candidates.length === 1)
197
+ this.selectedUserEmail = candidates[0];
198
+ else if (candidates.length > 1) {
199
+ throw Object.assign(new Error(`multiple users are ready on this machine: ${candidates.join(", ")}`), {
200
+ code: "user_selection_required",
201
+ });
202
+ }
203
+ }
204
+ async loadMachine() {
205
+ if (!this.selectedUserEmail)
206
+ this.resolveUserForResume();
207
+ if (!this.selectedUserEmail)
208
+ return null;
209
+ const paths = this.paths();
210
+ const publicRecord = readJson(paths.publicRecord);
211
+ const secretAuth = readJson(paths.secretAuth);
212
+ const installation = readJson(paths.installation);
213
+ const status = readJson(paths.status);
214
+ if (!publicRecord || !secretAuth || !installation || !status)
215
+ return null;
216
+ return { publicRecord, secretAuth, installation, ready: status.ready === true };
217
+ }
218
+ async saveMachine(machine) {
219
+ const recordEmail = normalizeEmail(machine.publicRecord.user_email);
220
+ if (recordEmail)
221
+ this.selectedUserEmail = recordEmail;
222
+ const paths = this.paths();
223
+ atomicJsonSet([
224
+ [paths.publicRecord, machine.publicRecord],
225
+ [paths.secretAuth, machine.secretAuth],
226
+ [paths.installation, machine.installation],
227
+ [paths.status, { ready: machine.ready, updatedAt: new Date().toISOString() }],
228
+ ]);
229
+ }
230
+ async startRuntime(machine) {
231
+ const record = mergeRecordAuth(machine.publicRecord, machine.secretAuth) ?? {};
232
+ const userId = text(record.user_id);
233
+ const userEmail = normalizeEmail(record.user_email);
234
+ const computerId = text(record.computer_id);
235
+ const deviceId = text(record.device_id);
236
+ const tunnelUrl = text(record.tunnel_url);
237
+ const tunnelToken = text(record.tunnel_token);
238
+ const proxyToken = text(record.proxy_token);
239
+ if (!userId || !userEmail || !computerId || !deviceId || !tunnelUrl || !tunnelToken || !proxyToken) {
240
+ throw Object.assign(new Error("runtime identity or credentials are incomplete"), { code: "runtime_identity_incomplete" });
241
+ }
242
+ const runtimeToken = randomBytes(32).toString("base64url");
243
+ const env = {
244
+ ...process.env,
245
+ AMALGM_ROOT: this.amalgmRoot,
246
+ AMALGM_USER_EMAIL: userEmail,
247
+ AMALGM_USER_ID: userId,
248
+ AMALGM_DEVICE_ID: deviceId,
249
+ AMALGM_COMPUTER_ID: computerId,
250
+ AMALGM_RUNTIME_LABEL: this.options.runtimeLabel ?? "main",
251
+ AMALGM_BRANCH: this.options.branch ?? "main",
252
+ AMALGM_RUNTIME_TOKEN: runtimeToken,
253
+ AMALGM_PROXY_TOKEN: proxyToken,
254
+ AMALGM_PROXY_URL: this.options.proxyUrl ?? "https://amalgm-api-proxy-v2.fly.dev",
255
+ };
256
+ let shell = null;
257
+ try {
258
+ if (!this.groundHost)
259
+ throw new Error("Files must converge before the runtime starts");
260
+ shell = await bootShell({
261
+ env,
262
+ homedir: this.homedir,
263
+ amalgmRoot: this.amalgmRoot,
264
+ userEmail,
265
+ deviceId,
266
+ runtimeToken,
267
+ });
268
+ await new Promise((resolve, reject) => {
269
+ shell?.gateway.once("error", reject);
270
+ shell?.gateway.listen(this.options.runtimePort ?? 0, "127.0.0.1", () => resolve());
271
+ });
272
+ const address = shell.gateway.address();
273
+ if (!address || typeof address === "string")
274
+ throw new Error("runtime gateway did not bind a TCP port");
275
+ await this.groundHost.activateRuntimeTunnel(address.port, runtimeToken);
276
+ const running = {
277
+ evidence: {
278
+ userId,
279
+ computerId,
280
+ deviceId,
281
+ services: machine.installation.services,
282
+ tunnelsAuthenticated: true,
283
+ proxyContext: { userId, computerId },
284
+ },
285
+ stop: async () => {
286
+ this.running.delete(running);
287
+ await this.groundHost?.stopRuntimeTunnel();
288
+ await shell?.close();
289
+ shell = null;
290
+ },
291
+ };
292
+ this.running.add(running);
293
+ return running;
294
+ }
295
+ catch (error) {
296
+ await this.groundHost?.stopRuntimeTunnel().catch(() => undefined);
297
+ await shell?.close().catch(() => undefined);
298
+ throw error;
299
+ }
300
+ }
301
+ }
302
+ function normalizeEmail(value) {
303
+ const email = text(value).toLowerCase();
304
+ return email || null;
305
+ }
306
+ function text(value) {
307
+ return typeof value === "string" ? value.trim() : "";
308
+ }
309
+ async function postJson(baseUrl, path, body, token = "") {
310
+ const response = await fetch(`${baseUrl.replace(/\/$/, "")}${path}`, {
311
+ method: "POST",
312
+ headers: {
313
+ accept: "application/json",
314
+ "content-type": "application/json",
315
+ ...(token ? { authorization: `Bearer ${token}` } : {}),
316
+ },
317
+ body: JSON.stringify(body),
318
+ });
319
+ const content = await response.text();
320
+ let payload = {};
321
+ try {
322
+ payload = content ? JSON.parse(content) : {};
323
+ }
324
+ catch {
325
+ payload = { text: content };
326
+ }
327
+ if (!response.ok) {
328
+ const error = Object.assign(new Error(`${response.status} ${text(payload.error) || response.statusText}`), {
329
+ code: `http_${response.status}`,
330
+ status: response.status,
331
+ payload,
332
+ });
333
+ throw error;
334
+ }
335
+ return payload;
336
+ }
337
+ export function defaultMachineName() {
338
+ return hostname() || "Amalgm machine";
339
+ }
340
+ //# sourceMappingURL=machine-host.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"machine-host.js","sourceRoot":"","sources":["../src/machine-host.ts"],"names":[],"mappings":"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"}
package/dist/main.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/main.js ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env node
2
+ import { runCli } from "./cli.js";
3
+ process.exitCode = await runCli();
4
+ //# sourceMappingURL=main.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAElC,OAAO,CAAC,QAAQ,GAAG,MAAM,MAAM,EAAE,CAAC"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * The parity meter: the decomposed runtime's active target surface, derived
3
+ * from the kernel's own route table and probed over real HTTP against a booted
4
+ * shell. The target begins with the Engine contract and excludes only the
5
+ * owner-approved prefixes in Core's explicit retirement ledger.
6
+ *
7
+ * This measures SURFACE parity (does something answer on this route), not
8
+ * behavior parity. Probes are designed so a mounted surface always answers
9
+ * non-404; a 404 therefore means "nothing is mounted here".
10
+ */
11
+ export interface ParityProbe {
12
+ readonly service: "gateway" | "portMonitor" | "chat" | "mcp";
13
+ /** The active target surface being measured — a route-table prefix or exact path. */
14
+ readonly surface: string;
15
+ readonly method: string;
16
+ readonly path: string;
17
+ readonly body?: string;
18
+ readonly note?: string;
19
+ }
20
+ export interface ParityResult extends ParityProbe {
21
+ readonly served: boolean;
22
+ readonly status: number;
23
+ }
24
+ export interface ParityOptions {
25
+ /** Base URL of a booted shell gateway, e.g. http://127.0.0.1:4123 */
26
+ base: string;
27
+ token: string;
28
+ /** A real turnId (capture it from the injected driver) so /raw-temp can replay. */
29
+ seedTurnId?: string;
30
+ }
31
+ export declare function engineSurfaceProbes(seed?: {
32
+ turnId?: string;
33
+ }): ParityProbe[];
34
+ export declare function measureEngineParity(options: ParityOptions): Promise<ParityResult[]>;
35
+ export interface ParitySummary {
36
+ readonly served: string[];
37
+ readonly dead: string[];
38
+ readonly score: string;
39
+ }
40
+ export declare function paritySummary(results: ParityResult[]): ParitySummary;
package/dist/parity.js ADDED
@@ -0,0 +1,108 @@
1
+ import { shippedRouteTable } from "@amalgm/core/transport";
2
+ /**
3
+ * Representative child paths for prefixes whose mounted server 404s at its
4
+ * own root — the probe must elicit a non-404 from a served surface.
5
+ */
6
+ const MCP_PROBE_PATHS = {
7
+ "/agents": "/agents/sessions",
8
+ "/browser": "/browser/health",
9
+ };
10
+ export function engineSurfaceProbes(seed) {
11
+ const table = shippedRouteTable;
12
+ const probes = [];
13
+ for (const path of table.gatewayExactPaths) {
14
+ probes.push({ service: "gateway", surface: path, method: "GET", path });
15
+ }
16
+ for (const prefix of table.gatewayPrefixes) {
17
+ probes.push({ service: "gateway", surface: prefix, method: "GET", path: prefix });
18
+ }
19
+ for (const prefix of table.portMonitorPrefixes) {
20
+ probes.push({ service: "portMonitor", surface: prefix, method: "GET", path: prefix });
21
+ }
22
+ const chatProbe = (surface) => {
23
+ switch (surface) {
24
+ case "/chat":
25
+ return {
26
+ service: "chat",
27
+ surface,
28
+ method: "POST",
29
+ path: "/chat",
30
+ body: JSON.stringify({ sessionId: "parity-probe", prompt: "ping" }),
31
+ };
32
+ case "/raw-temp":
33
+ return {
34
+ service: "chat",
35
+ surface,
36
+ method: "GET",
37
+ path: `/raw-temp/${seed?.turnId ?? "parity-no-seed"}`,
38
+ note: seed?.turnId ? undefined : "no seed turn — a served mount may still 404",
39
+ };
40
+ case "/active":
41
+ return { service: "chat", surface, method: "GET", path: "/active/parity-probe" };
42
+ case "/stop":
43
+ return { service: "chat", surface, method: "POST", path: "/stop/parity-probe" };
44
+ case "/egress":
45
+ return {
46
+ service: "chat",
47
+ surface,
48
+ method: "POST",
49
+ path: "/egress/parity-relay",
50
+ };
51
+ case "/mcp-relay":
52
+ return {
53
+ service: "chat",
54
+ surface,
55
+ method: "POST",
56
+ path: "/mcp-relay/parity-relay/amalgm",
57
+ };
58
+ default:
59
+ return { service: "chat", surface, method: "POST", path: `${surface}/parity-probe` };
60
+ }
61
+ };
62
+ for (const prefix of table.chatPrefixes)
63
+ probes.push(chatProbe(prefix));
64
+ for (const prefix of table.mcpPrefixes) {
65
+ if (prefix === "/mcp") {
66
+ probes.push({
67
+ service: "mcp",
68
+ surface: prefix,
69
+ method: "POST",
70
+ path: "/mcp/tools",
71
+ body: JSON.stringify({ method: "tools/list" }),
72
+ note: "brick MCP catalogs under /mcp/<brick>",
73
+ });
74
+ continue;
75
+ }
76
+ probes.push({
77
+ service: "mcp",
78
+ surface: prefix,
79
+ method: "GET",
80
+ path: MCP_PROBE_PATHS[prefix] ?? prefix,
81
+ });
82
+ }
83
+ return probes;
84
+ }
85
+ export async function measureEngineParity(options) {
86
+ const probes = engineSurfaceProbes({ turnId: options.seedTurnId });
87
+ const results = [];
88
+ for (const probe of probes) {
89
+ const response = await fetch(`${options.base}${probe.path}`, {
90
+ method: probe.method,
91
+ headers: {
92
+ authorization: `Bearer ${options.token}`,
93
+ ...(probe.body ? { "content-type": "application/json" } : {}),
94
+ },
95
+ body: probe.body,
96
+ });
97
+ // Status is the verdict; drain/cancel so streaming probes free their sockets.
98
+ await response.body?.cancel().catch(() => { });
99
+ results.push({ ...probe, served: response.status !== 404, status: response.status });
100
+ }
101
+ return results;
102
+ }
103
+ export function paritySummary(results) {
104
+ const served = results.filter((r) => r.served).map((r) => r.surface);
105
+ const dead = results.filter((r) => !r.served).map((r) => r.surface);
106
+ return { served, dead, score: `${served.length}/${results.length}` };
107
+ }
108
+ //# sourceMappingURL=parity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parity.js","sourceRoot":"","sources":["../src/parity.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { BrickMount } from "./gateway.js";
2
+ /**
3
+ * The port-monitor and runtime-state surfaces, composed from kernel law.
4
+ * In the shell every service shares the one gateway port; the document
5
+ * shape is core's mirror-write law (`runtimeStatePortsPatch`), so what
6
+ * this serves is byte-shaped exactly like what the tunnels read.
7
+ */
8
+ export declare function portsMounts(currentPort: () => number | null): BrickMount[];
@@ -0,0 +1,26 @@
1
+ import { readRuntimePorts, runtimeStatePortsPatch } from "@amalgm/core/transport";
2
+ /**
3
+ * The port-monitor and runtime-state surfaces, composed from kernel law.
4
+ * In the shell every service shares the one gateway port; the document
5
+ * shape is core's mirror-write law (`runtimeStatePortsPatch`), so what
6
+ * this serves is byte-shaped exactly like what the tunnels read.
7
+ */
8
+ export function portsMounts(currentPort) {
9
+ const handle = async () => {
10
+ const port = currentPort() ?? 0;
11
+ const ports = readRuntimePorts(null, {
12
+ gateway: port,
13
+ portMonitor: port,
14
+ mcp: port,
15
+ chat: port,
16
+ });
17
+ return { ok: true, ...runtimeStatePortsPatch(ports) };
18
+ };
19
+ return [
20
+ { prefix: "/ports", handle },
21
+ { prefix: "/api/ports", handle },
22
+ { prefix: "/port-monitor", handle },
23
+ { prefix: "/runtime-state", handle },
24
+ ];
25
+ }
26
+ //# sourceMappingURL=ports-host.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ports-host.js","sourceRoot":"","sources":["../src/ports-host.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAIlF;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CAAC,WAAgC;IAC1D,MAAM,MAAM,GAAG,KAAK,IAAI,EAAE;QACxB,MAAM,IAAI,GAAG,WAAW,EAAE,IAAI,CAAC,CAAC;QAChC,MAAM,KAAK,GAAG,gBAAgB,CAAC,IAAI,EAAE;YACnC,OAAO,EAAE,IAAI;YACb,WAAW,EAAE,IAAI;YACjB,GAAG,EAAE,IAAI;YACT,IAAI,EAAE,IAAI;SACX,CAAC,CAAC;QACH,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,sBAAsB,CAAC,KAAK,CAAC,EAAE,CAAC;IACxD,CAAC,CAAC;IACF,OAAO;QACL,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE;QAC5B,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE;QAChC,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,EAAE;QACnC,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,EAAE;KACrC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,14 @@
1
+ import { PtySessionManager } from "@amalgm/core/pty";
2
+ import type { BrickMount, BrickUpgradeMount } from "./gateway.js";
3
+ export interface PtyHostConfig {
4
+ readonly env: NodeJS.ProcessEnv;
5
+ readonly defaultCwd: string;
6
+ }
7
+ export interface PtyHost {
8
+ readonly manager: PtySessionManager;
9
+ readonly mount: BrickMount;
10
+ readonly upgrade: BrickUpgradeMount;
11
+ close(): void;
12
+ }
13
+ /** Native effects for Core's PTY law; Engine reference local-gateway.js:33-47,333-346,777-904. */
14
+ export declare function createPtyHost(config: PtyHostConfig): PtyHost;