enigma-memory 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/LICENSE +55 -0
  2. package/README.md +379 -0
  3. package/apps/cli/bin/enigma.mjs +1117 -0
  4. package/apps/desktop/src/app.js +1327 -0
  5. package/apps/desktop/src/index.html +1373 -0
  6. package/apps/desktop/src/styles.css +386 -0
  7. package/apps/gateway/bin/enigma-gateway.mjs +52 -0
  8. package/apps/gateway/src/server.mjs +1403 -0
  9. package/apps/native-host/README.md +265 -0
  10. package/apps/native-host/bin/enigma-native-host.mjs +499 -0
  11. package/apps/native-host/manifests/com.enigma.native_host.chrome.json +9 -0
  12. package/apps/native-host/manifests/com.enigma.native_host.edge.json +9 -0
  13. package/apps/native-host/manifests/com.enigma.native_host.firefox.json +9 -0
  14. package/apps/relay/bin/enigma-relay.mjs +52 -0
  15. package/apps/relay/src/server.mjs +1571 -0
  16. package/apps/verifier/bin/enigma-verify.mjs +240 -0
  17. package/deploy/docker-compose.production.example.yml +150 -0
  18. package/deploy/kubernetes/enigma-backend.example.yaml +580 -0
  19. package/package.json +196 -0
  20. package/packages/adapters/PACKAGE_CONTRACT.md +47 -0
  21. package/packages/adapters/src/index.js +183 -0
  22. package/packages/boundary/src/index.js +468 -0
  23. package/packages/connectors/src/index.js +533 -0
  24. package/packages/core/src/index.js +766 -0
  25. package/packages/enterprise/src/index.js +505 -0
  26. package/packages/importers/src/index.js +1083 -0
  27. package/packages/mcp-server/bin/enigma-mcp.mjs +19 -0
  28. package/packages/mcp-server/src/index.js +1185 -0
  29. package/packages/mesh/src/index.js +531 -0
  30. package/packages/metering/PACKAGE_CONTRACT.md +20 -0
  31. package/packages/metering/src/index.js +246 -0
  32. package/packages/optimizer/src/index.js +707 -0
  33. package/packages/passport/src/index.js +651 -0
  34. package/packages/settlement/PACKAGE_CONTRACT.md +28 -0
  35. package/packages/settlement/src/index.js +369 -0
  36. package/packages/storage/PACKAGE_CONTRACT.md +23 -0
  37. package/packages/storage/src/index.js +392 -0
  38. package/packages/vault/src/index.js +904 -0
  39. package/scripts/build-ai-orchestration-plan.mjs +248 -0
  40. package/scripts/build-cloudflare-pages-release-packet.mjs +287 -0
  41. package/scripts/build-cloudflare-token-policy.mjs +239 -0
  42. package/scripts/build-cloudflare-token-request.mjs +314 -0
  43. package/scripts/build-demo-assets.mjs +263 -0
  44. package/scripts/build-edge-backend-workers.mjs +353 -0
  45. package/scripts/build-goal-completion-audit.mjs +398 -0
  46. package/scripts/build-hosted-probe-worker.mjs +191 -0
  47. package/scripts/build-operator-acceptance-packet.mjs +254 -0
  48. package/scripts/build-operator-evidence-starter.mjs +525 -0
  49. package/scripts/build-production-backend-env-kit.mjs +384 -0
  50. package/scripts/build-production-dependency-report.mjs +369 -0
  51. package/scripts/build-production-handoff-packet.mjs +475 -0
  52. package/scripts/build-production-readiness-manifest.mjs +209 -0
  53. package/scripts/build-production-status-board.mjs +297 -0
  54. package/scripts/build-production-storage-migration.mjs +86 -0
  55. package/scripts/build-production-workplan.mjs +371 -0
  56. package/scripts/build-review-packet.mjs +594 -0
  57. package/scripts/check.mjs +419 -0
  58. package/scripts/cloudflare-ops.mjs +1672 -0
  59. package/scripts/cloudflare-secret-env.mjs +128 -0
  60. package/scripts/collect-hosted-backend-live-evidence.mjs +263 -0
  61. package/scripts/infrastructure-readiness.mjs +944 -0
  62. package/scripts/install-enigma-local.mjs +270 -0
  63. package/scripts/memory-optimization-benchmark.mjs +242 -0
  64. package/scripts/monitor-live-endpoints.mjs +358 -0
  65. package/scripts/release-audit.mjs +5588 -0
  66. package/scripts/release-provenance.mjs +250 -0
  67. package/scripts/run-backend-readiness-smoke.mjs +220 -0
  68. package/scripts/validate-backup-restore-drill.mjs +166 -0
  69. package/scripts/validate-cloudflare-credentials.mjs +112 -0
  70. package/scripts/validate-cloudflare-worker-inspect.mjs +179 -0
  71. package/scripts/validate-domain-tls.mjs +248 -0
  72. package/scripts/validate-hosted-backend-live.mjs +319 -0
  73. package/scripts/validate-incident-drill.mjs +221 -0
  74. package/scripts/validate-kms-custody.mjs +235 -0
  75. package/scripts/validate-legal-compliance-approval.mjs +274 -0
  76. package/scripts/validate-monitoring-alerting.mjs +263 -0
  77. package/scripts/validate-network-access-policy.mjs +285 -0
  78. package/scripts/validate-operator-acceptance.mjs +298 -0
  79. package/scripts/validate-production-manifests.mjs +325 -0
  80. package/scripts/validate-public-site-security.mjs +252 -0
  81. package/scripts/validate-security-threat-model.mjs +285 -0
  82. package/scripts/validate-service-settlement.mjs +256 -0
  83. package/scripts/validate-support-sla.mjs +190 -0
  84. package/scripts/validate-tenant-policy-approval.mjs +228 -0
  85. package/scripts/validate-usage-metering.mjs +224 -0
  86. package/scripts/validate-whitepaper-claims.mjs +166 -0
  87. package/specs/boundary-manifest-v1.schema.json +35 -0
  88. package/specs/capsule-v1.schema.json +55 -0
  89. package/specs/claim-boundary-manifest-v1.schema.json +22 -0
  90. package/specs/connector-profile-v1.schema.json +62 -0
  91. package/specs/deletion-tombstone-v1.schema.json +26 -0
  92. package/specs/enterprise-policy-v1.schema.json +59 -0
  93. package/specs/gateway-request-v1.schema.json +32 -0
  94. package/specs/goal-completion-audit-v1.schema.json +70 -0
  95. package/specs/hosted-backend-live-evidence-v1.schema.json +147 -0
  96. package/specs/import-report-v1.schema.json +214 -0
  97. package/specs/infrastructure-readiness-manifest-v1.schema.json +130 -0
  98. package/specs/memory-event-v1.schema.json +42 -0
  99. package/specs/mesh-node-v1.schema.json +126 -0
  100. package/specs/passport-v1.schema.json +50 -0
  101. package/specs/production-handoff-packet-v1.schema.json +149 -0
  102. package/specs/receipt-v1.schema.json +61 -0
  103. package/specs/relay-record-v1.schema.json +43 -0
  104. package/specs/state-checkpoint-v1.schema.json +37 -0
  105. package/specs/trust-bundle-v1.schema.json +56 -0
@@ -0,0 +1,358 @@
1
+ #!/usr/bin/env node
2
+ import { mkdir, readFile, writeFile } from 'node:fs/promises';
3
+ import { dirname, resolve } from 'node:path';
4
+ import { pathToFileURL } from 'node:url';
5
+ import { performance } from 'node:perf_hooks';
6
+
7
+ export const LIVE_ENDPOINT_MONITOR_SCHEMA = 'enigma.live_endpoint_monitor.v1';
8
+
9
+ export const DEFAULT_LIVE_ENDPOINTS = Object.freeze([
10
+ Object.freeze({ name: 'public_site', url: 'https://enigmamemory.com/', expected_status: [200] }),
11
+ Object.freeze({ name: 'relay_readyz', url: 'https://relay.enigmamemory.com/readyz', expected_status: [200] }),
12
+ Object.freeze({ name: 'gateway_readyz', url: 'https://gateway.enigmamemory.com/readyz', expected_status: [200] }),
13
+ ]);
14
+
15
+ const DEFAULT_TIMEOUT_MS = 5000;
16
+ const MAX_TIMEOUT_MS = 60000;
17
+ const SAFE_NAME_RE = /^[a-z][a-z0-9_-]{0,63}$/u;
18
+ const SECRET_VALUE_RE = /(?:Bearer\s+[A-Za-z0-9._~+/=-]{12,}|Basic\s+[A-Za-z0-9+/=-]{12,}|-----BEGIN [A-Z ]*PRIVATE KEY-----|https?:\/\/[^\s/@]+:[^\s/@]+@|sk-[A-Za-z0-9_-]{16,}|AKIA[0-9A-Z]{16}|cf-[A-Za-z0-9_-]{12,})/iu;
19
+
20
+ export class UsageError extends Error {
21
+ constructor(message) {
22
+ super(message);
23
+ this.name = 'UsageError';
24
+ }
25
+ }
26
+
27
+ class TimeoutError extends Error {
28
+ constructor() {
29
+ super('Request timed out');
30
+ this.name = 'TimeoutError';
31
+ }
32
+ }
33
+
34
+ function isPlainObject(value) {
35
+ return value !== null && typeof value === 'object' && !Array.isArray(value);
36
+ }
37
+
38
+ function nonEmptyString(value) {
39
+ return typeof value === 'string' && value.trim().length > 0;
40
+ }
41
+
42
+ function toPositiveInteger(value, name, max = Number.MAX_SAFE_INTEGER) {
43
+ const parsed = Number(value);
44
+ if (!Number.isInteger(parsed) || parsed <= 0 || parsed > max) throw new UsageError(`${name} must be an integer between 1 and ${max}`);
45
+ return parsed;
46
+ }
47
+
48
+ function isPrivateHost(hostname) {
49
+ const host = String(hostname ?? '').toLowerCase();
50
+ return host === 'localhost'
51
+ || host.endsWith('.localhost')
52
+ || host === '127.0.0.1'
53
+ || host === '0.0.0.0'
54
+ || host === '::1'
55
+ || /^10\./u.test(host)
56
+ || /^192\.168\./u.test(host)
57
+ || /^172\.(1[6-9]|2\d|3[0-1])\./u.test(host)
58
+ || /^169\.254\./u.test(host)
59
+ || host === '[::1]';
60
+ }
61
+
62
+ function normalizeExpectedStatus(value, path) {
63
+ const source = value === undefined ? [200] : Array.isArray(value) ? value : [value];
64
+ if (source.length === 0) throw new UsageError(`${path}.expected_status must not be empty`);
65
+ return source.map((entry, index) => {
66
+ const status = Number(entry);
67
+ if (!Number.isInteger(status) || status < 100 || status > 599) throw new UsageError(`${path}.expected_status[${index}] must be an HTTP status code`);
68
+ return status;
69
+ });
70
+ }
71
+
72
+ export function normalizeEndpoint(endpoint, index = 0) {
73
+ const path = `endpoints[${index}]`;
74
+ if (!isPlainObject(endpoint)) throw new UsageError(`${path} must be an object`);
75
+ const name = String(endpoint.name ?? '').trim();
76
+ if (!SAFE_NAME_RE.test(name)) throw new UsageError(`${path}.name must match ${SAFE_NAME_RE.source}`);
77
+ if (!nonEmptyString(endpoint.url)) throw new UsageError(`${path}.url is required`);
78
+ if (SECRET_VALUE_RE.test(endpoint.url)) throw new UsageError(`${path}.url must not contain credentials or token-like values`);
79
+ let parsed;
80
+ try {
81
+ parsed = new URL(endpoint.url.trim());
82
+ } catch {
83
+ throw new UsageError(`${path}.url must be a valid URL`);
84
+ }
85
+ if (parsed.protocol !== 'https:') throw new UsageError(`${path}.url must use https`);
86
+ if (parsed.username || parsed.password) throw new UsageError(`${path}.url must not include credentials`);
87
+ if (parsed.search || parsed.hash) throw new UsageError(`${path}.url must not include query strings or fragments`);
88
+ if (isPrivateHost(parsed.hostname)) throw new UsageError(`${path}.url must not target localhost, link-local, or private network hosts`);
89
+
90
+ const method = String(endpoint.method ?? 'GET').toUpperCase();
91
+ if (method !== 'GET' && method !== 'HEAD') throw new UsageError(`${path}.method must be GET or HEAD`);
92
+
93
+ return {
94
+ name,
95
+ url: parsed.href,
96
+ method,
97
+ expected_status: normalizeExpectedStatus(endpoint.expected_status ?? endpoint.expectedStatus, path),
98
+ };
99
+ }
100
+
101
+ export function normalizeEndpoints(endpoints = DEFAULT_LIVE_ENDPOINTS) {
102
+ if (!Array.isArray(endpoints) || endpoints.length === 0) throw new UsageError('endpoints must be a non-empty array');
103
+ const normalized = endpoints.map((endpoint, index) => normalizeEndpoint(endpoint, index));
104
+ const names = new Set();
105
+ for (const endpoint of normalized) {
106
+ if (names.has(endpoint.name)) throw new UsageError(`duplicate endpoint name ${endpoint.name}`);
107
+ names.add(endpoint.name);
108
+ }
109
+ return normalized;
110
+ }
111
+
112
+ function headerValue(headers, name) {
113
+ if (!headers || typeof headers.get !== 'function') return null;
114
+ const value = headers.get(name);
115
+ return typeof value === 'string' && value.trim().length > 0 ? value.trim().slice(0, 120) : null;
116
+ }
117
+
118
+ function safeJsonSummary(value) {
119
+ if (!isPlainObject(value)) return { payload_kind: Array.isArray(value) ? 'json_array' : 'json_scalar' };
120
+ const summary = { payload_kind: 'json_object' };
121
+ if (typeof value.ok === 'boolean') summary.ok = value.ok;
122
+ if (typeof value.status === 'string' && /^[a-z0-9_.:-]{1,48}$/iu.test(value.status) && !SECRET_VALUE_RE.test(value.status)) summary.status = value.status;
123
+ if (typeof value.service === 'string' && /^[a-z0-9_.:-]{1,80}$/iu.test(value.service) && !SECRET_VALUE_RE.test(value.service)) summary.service = value.service;
124
+ if (Array.isArray(value.checks)) summary.checks_count = value.checks.length;
125
+ if (Array.isArray(value.missing_evidence_refs)) summary.missing_evidence_refs_count = value.missing_evidence_refs.length;
126
+ return summary;
127
+ }
128
+
129
+ async function buildSafeSummary(response) {
130
+ const contentType = headerValue(response.headers, 'content-type');
131
+ const summary = {
132
+ content_type: contentType,
133
+ payload_kind: 'not_read',
134
+ };
135
+ if (!contentType) return summary;
136
+ if (!/\bjson\b/iu.test(contentType)) return { ...summary, payload_kind: 'non_json' };
137
+ const source = typeof response.clone === 'function' ? response.clone() : response;
138
+ if (typeof source.json !== 'function') return { ...summary, payload_kind: 'json_unavailable' };
139
+ try {
140
+ return { ...summary, ...safeJsonSummary(await source.json()) };
141
+ } catch {
142
+ return { ...summary, payload_kind: 'json_unreadable' };
143
+ }
144
+ }
145
+
146
+ function publicSafeError(error) {
147
+ if (error instanceof TimeoutError || error?.name === 'AbortError') {
148
+ return { code: 'TIMEOUT', message: 'Request timed out before the configured deadline.' };
149
+ }
150
+ return { code: 'FETCH_ERROR', message: 'Endpoint fetch failed without exposing upstream payloads.' };
151
+ }
152
+
153
+ async function probeEndpoint(endpoint, options) {
154
+ const fetchImpl = options.fetchImpl;
155
+ const timeoutMs = options.timeoutMs;
156
+ const includeSafeSummary = options.includeSafeSummary === true;
157
+ const nowMs = options.nowMs;
158
+ const started = nowMs();
159
+ const controller = new AbortController();
160
+ let timer;
161
+ try {
162
+ const timeout = new Promise((_, reject) => {
163
+ timer = setTimeout(() => {
164
+ controller.abort();
165
+ reject(new TimeoutError());
166
+ }, timeoutMs);
167
+ });
168
+ const response = await Promise.race([
169
+ fetchImpl(endpoint.url, {
170
+ method: endpoint.method,
171
+ redirect: 'manual',
172
+ signal: controller.signal,
173
+ }),
174
+ timeout,
175
+ ]);
176
+ const latencyMs = Math.max(0, Math.round(nowMs() - started));
177
+ const statusCode = Number(response?.status ?? 0);
178
+ const ok = endpoint.expected_status.includes(statusCode);
179
+ const result = {
180
+ name: endpoint.name,
181
+ url: endpoint.url,
182
+ method: endpoint.method,
183
+ expected_status: endpoint.expected_status,
184
+ ok,
185
+ status: ok ? 'ok' : 'http_error',
186
+ http_status: Number.isInteger(statusCode) ? statusCode : null,
187
+ latency_ms: latencyMs,
188
+ };
189
+ if (includeSafeSummary) result.safe_summary = await buildSafeSummary(response);
190
+ return result;
191
+ } catch (error) {
192
+ return {
193
+ name: endpoint.name,
194
+ url: endpoint.url,
195
+ method: endpoint.method,
196
+ expected_status: endpoint.expected_status,
197
+ ok: false,
198
+ status: error instanceof TimeoutError || error?.name === 'AbortError' ? 'timeout' : 'network_error',
199
+ http_status: null,
200
+ latency_ms: Math.max(0, Math.round(nowMs() - started)),
201
+ error: publicSafeError(error),
202
+ };
203
+ } finally {
204
+ clearTimeout(timer);
205
+ }
206
+ }
207
+
208
+ function summarize(results) {
209
+ const total = results.length;
210
+ const passed = results.filter((result) => result.ok === true && result.status !== 'skipped').length;
211
+ const skipped = results.filter((result) => result.status === 'skipped').length;
212
+ const failed = results.filter((result) => result.ok !== true && result.status !== 'skipped').length;
213
+ return {
214
+ ok: failed === 0,
215
+ total,
216
+ passed,
217
+ failed,
218
+ skipped,
219
+ };
220
+ }
221
+
222
+ export function assertPublicSafeMonitorJson(value) {
223
+ const json = JSON.stringify(value);
224
+ if (SECRET_VALUE_RE.test(json)) throw new Error('live endpoint monitor output appears to contain secret-like data');
225
+ if (/response_body|raw_body|set-cookie|authorization/iu.test(json)) throw new Error('live endpoint monitor output contains disallowed response detail');
226
+ return value;
227
+ }
228
+
229
+ export async function monitorLiveEndpoints(input = {}) {
230
+ const endpoints = normalizeEndpoints(input.endpoints ?? DEFAULT_LIVE_ENDPOINTS);
231
+ const timeoutMs = toPositiveInteger(input.timeout_ms ?? input.timeoutMs ?? DEFAULT_TIMEOUT_MS, 'timeout_ms', MAX_TIMEOUT_MS);
232
+ const generatedAt = input.generated_at ?? input.generatedAt ?? new Date().toISOString();
233
+ const includeSafeSummary = input.include_safe_summary === true || input.includeSafeSummary === true;
234
+ const dryRun = input.dry_run === true || input.dryRun === true;
235
+ const nowMs = typeof input.nowMs === 'function' ? input.nowMs : () => performance.now();
236
+ const fetchImpl = input.fetchImpl ?? globalThis.fetch;
237
+
238
+ let results;
239
+ if (dryRun) {
240
+ results = endpoints.map((endpoint) => ({
241
+ name: endpoint.name,
242
+ url: endpoint.url,
243
+ method: endpoint.method,
244
+ expected_status: endpoint.expected_status,
245
+ ok: true,
246
+ status: 'skipped',
247
+ http_status: null,
248
+ latency_ms: 0,
249
+ }));
250
+ } else {
251
+ if (typeof fetchImpl !== 'function') throw new UsageError('fetch is not available; provide fetchImpl or run on Node with global fetch');
252
+ results = await Promise.all(endpoints.map((endpoint) => probeEndpoint(endpoint, { fetchImpl, timeoutMs, includeSafeSummary, nowMs })));
253
+ }
254
+
255
+ const packet = {
256
+ schema: LIVE_ENDPOINT_MONITOR_SCHEMA,
257
+ generated_at: generatedAt,
258
+ dry_run: dryRun,
259
+ timeout_ms: timeoutMs,
260
+ include_safe_summary: includeSafeSummary,
261
+ summary: summarize(results),
262
+ results,
263
+ claim_boundary: [
264
+ 'This packet is point-in-time synthetic monitoring evidence only.',
265
+ 'It does not prove provider deletion, model forgetting, compliance certification, or future availability.',
266
+ 'It contains no response bodies, account identifiers, credential values, cookies, prompts, memory payloads, or provider payloads.',
267
+ ],
268
+ };
269
+ return assertPublicSafeMonitorJson(packet);
270
+ }
271
+
272
+ function parseEndpointSpec(value) {
273
+ const separator = value.indexOf('=');
274
+ if (separator <= 0 || separator === value.length - 1) throw new UsageError('--endpoint must be name=https://host/path');
275
+ return { name: value.slice(0, separator), url: value.slice(separator + 1) };
276
+ }
277
+
278
+ function parseArgs(argv) {
279
+ const out = {
280
+ endpoints: [],
281
+ config: null,
282
+ out: null,
283
+ timeout_ms: null,
284
+ include_safe_summary: false,
285
+ dry_run: false,
286
+ };
287
+ for (let index = 0; index < argv.length;) {
288
+ const token = argv[index];
289
+ if (token === '--help' || token === '-h') return { help: true };
290
+ if (token === '--dry-run') {
291
+ out.dry_run = true;
292
+ index += 1;
293
+ continue;
294
+ }
295
+ if (token === '--safe-summary') {
296
+ out.include_safe_summary = true;
297
+ index += 1;
298
+ continue;
299
+ }
300
+ const readValue = (name) => {
301
+ if (index + 1 >= argv.length || argv[index + 1].startsWith('--')) throw new UsageError(`${name} requires a value`);
302
+ const value = argv[index + 1];
303
+ index += 2;
304
+ return value;
305
+ };
306
+ if (token === '--endpoint') out.endpoints.push(parseEndpointSpec(readValue(token)));
307
+ else if (token === '--config') out.config = readValue(token);
308
+ else if (token === '--out') out.out = readValue(token);
309
+ else if (token === '--timeout-ms') out.timeout_ms = toPositiveInteger(readValue(token), token, MAX_TIMEOUT_MS);
310
+ else throw new UsageError(`unknown option ${token}`);
311
+ }
312
+ return out;
313
+ }
314
+
315
+ function usage() {
316
+ return `Usage: node scripts/monitor-live-endpoints.mjs [options]\n\nOptions:\n --dry-run Validate the endpoint set and emit skipped results without network probes.\n --endpoint <name=https://url> Override defaults; repeat for multiple endpoints. HTTPS only; no query, fragment, or credentials.\n --config <file> Read JSON with {"endpoints":[...],"timeout_ms":5000}.\n --timeout-ms <ms> Per-endpoint timeout, 1-${MAX_TIMEOUT_MS}. Default: ${DEFAULT_TIMEOUT_MS}.\n --safe-summary Include a sanitized JSON response summary; never includes raw response bodies.\n --out <file> Write the same public-safe JSON packet to a file.\n --help Print this help.\n\nDefaults: public site, relay /readyz, and gateway /readyz. The script performs no mutations.\nUse --dry-run for repository evidence that must not probe live endpoints.\n`;
317
+ }
318
+
319
+ async function loadConfig(path) {
320
+ const parsed = JSON.parse(await readFile(path, 'utf8'));
321
+ if (!isPlainObject(parsed)) throw new UsageError('--config must point to a JSON object');
322
+ return parsed;
323
+ }
324
+
325
+ export async function runCli(argv = process.argv.slice(2), options = {}) {
326
+ const parsed = parseArgs(argv);
327
+ if (parsed.help) return { text: usage() };
328
+ const config = parsed.config ? await loadConfig(parsed.config) : {};
329
+ const endpoints = parsed.endpoints.length > 0 ? parsed.endpoints : config.endpoints;
330
+ const packet = await monitorLiveEndpoints({
331
+ endpoints: endpoints ?? DEFAULT_LIVE_ENDPOINTS,
332
+ timeout_ms: parsed.timeout_ms ?? config.timeout_ms,
333
+ include_safe_summary: parsed.include_safe_summary || config.include_safe_summary === true,
334
+ dry_run: parsed.dry_run || config.dry_run === true,
335
+ generated_at: options.generated_at ?? options.generatedAt,
336
+ fetchImpl: options.fetchImpl,
337
+ nowMs: options.nowMs,
338
+ });
339
+ const json = `${JSON.stringify(packet, null, 2)}\n`;
340
+ if (parsed.out) {
341
+ const outPath = resolve(parsed.out);
342
+ await mkdir(dirname(outPath), { recursive: true });
343
+ await writeFile(outPath, json, 'utf8');
344
+ }
345
+ return { json: packet };
346
+ }
347
+
348
+ if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
349
+ try {
350
+ const result = await runCli();
351
+ if (result.text) process.stdout.write(result.text);
352
+ else process.stdout.write(`${JSON.stringify(result.json, null, 2)}\n`);
353
+ } catch (error) {
354
+ const message = error instanceof UsageError ? error.message : 'Live endpoint monitor failed without exposing upstream payloads.';
355
+ process.stdout.write(`${JSON.stringify({ schema: LIVE_ENDPOINT_MONITOR_SCHEMA, ok: false, error: { code: error instanceof UsageError ? 'USAGE_ERROR' : 'MONITOR_ERROR', message } }, null, 2)}\n`);
356
+ process.exitCode = error instanceof UsageError ? 2 : 1;
357
+ }
358
+ }