opencode-supertask 0.1.40 → 0.1.41

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.
@@ -0,0 +1,2 @@
1
+
2
+ export { }
@@ -0,0 +1,461 @@
1
+ // src/daemon/pm2.ts
2
+ import { execSync, spawnSync } from "child_process";
3
+ import {
4
+ accessSync,
5
+ chmodSync,
6
+ constants,
7
+ existsSync,
8
+ mkdirSync,
9
+ readFileSync,
10
+ rmSync,
11
+ statSync,
12
+ writeFileSync
13
+ } from "fs";
14
+ import { homedir as homedir2, userInfo } from "os";
15
+ import { delimiter, dirname, isAbsolute, join as join2, resolve } from "path";
16
+ import { fileURLToPath } from "url";
17
+ import { Database as Database2 } from "bun:sqlite";
18
+
19
+ // src/gateway/config.ts
20
+ import { homedir } from "os";
21
+ import { join } from "path";
22
+ var DEFAULT_CONFIG_PATH = join(homedir(), ".config/opencode/supertask.json");
23
+
24
+ // src/daemon/management-lock.ts
25
+ import { Database } from "bun:sqlite";
26
+
27
+ // src/daemon/pm2.ts
28
+ var __dirname = dirname(fileURLToPath(import.meta.url));
29
+ var PROCESS_NAME = "supertask-gateway";
30
+ var MAC_LAUNCH_AGENT_LABEL = "com.supertask.pm2-resurrect";
31
+ var GATEWAY_LOCK_STALE_MS = 3e4;
32
+ function runtimeHome(env) {
33
+ return resolve(env.HOME || homedir2());
34
+ }
35
+ function runtimePath(value, cwd) {
36
+ return resolve(cwd, value);
37
+ }
38
+ function versionFile(env = process.env, cwd = process.cwd()) {
39
+ return env.SUPERTASK_VERSION_FILE ? runtimePath(env.SUPERTASK_VERSION_FILE, cwd) : join2(runtimeHome(env), ".local/share/opencode/supertask-gateway-version");
40
+ }
41
+ function getRunningVersion(env = process.env, cwd = process.cwd()) {
42
+ try {
43
+ const path = versionFile(env, cwd);
44
+ if (!existsSync(path)) return null;
45
+ return readFileSync(path, "utf-8").trim() || null;
46
+ } catch {
47
+ return null;
48
+ }
49
+ }
50
+ function packageVersionFromGatewayEntry(gatewayEntry) {
51
+ if (gatewayEntry === null) return null;
52
+ let directory = dirname(gatewayEntry);
53
+ for (let depth = 0; depth < 6; depth += 1) {
54
+ const packagePath = join2(directory, "package.json");
55
+ if (existsSync(packagePath)) {
56
+ try {
57
+ const pkg = JSON.parse(readFileSync(packagePath, "utf8"));
58
+ if (pkg.name === "opencode-supertask" && typeof pkg.version === "string") {
59
+ return pkg.version;
60
+ }
61
+ } catch {
62
+ }
63
+ }
64
+ const parent = dirname(directory);
65
+ if (parent === directory) break;
66
+ directory = parent;
67
+ }
68
+ return null;
69
+ }
70
+ function resolveRuntimeExecutable(command, env, cwd) {
71
+ if (isAbsolute(command) || command.includes("/")) return runtimePath(command, cwd);
72
+ for (const entry of (env.PATH ?? "").split(delimiter)) {
73
+ if (!entry) continue;
74
+ const candidate = resolve(cwd, entry, command);
75
+ try {
76
+ accessSync(candidate, constants.X_OK);
77
+ return candidate;
78
+ } catch {
79
+ }
80
+ }
81
+ return command;
82
+ }
83
+ function runtimeScope(runtime) {
84
+ const { cwd, env } = runtime;
85
+ const home = runtimeHome(env);
86
+ return {
87
+ cwd: resolve(cwd),
88
+ databasePath: env.SUPERTASK_DB_PATH ? runtimePath(env.SUPERTASK_DB_PATH, cwd) : join2(home, ".local/share/opencode/tasks.db"),
89
+ configPath: env.SUPERTASK_CONFIG_PATH ? runtimePath(env.SUPERTASK_CONFIG_PATH, cwd) : join2(home, ".config/opencode/supertask.json"),
90
+ opencodePath: resolveRuntimeExecutable(env.SUPERTASK_OPENCODE_BIN ?? "opencode", env, cwd),
91
+ home,
92
+ pm2Home: env.PM2_HOME ? runtimePath(env.PM2_HOME, cwd) : join2(home, ".pm2"),
93
+ managementLockPath: canonicalManagementLockPath(env, cwd)
94
+ };
95
+ }
96
+ function scopesMatch(left, right) {
97
+ return left.databasePath === right.databasePath && left.configPath === right.configPath && left.opencodePath === right.opencodePath && left.home === right.home && left.pm2Home === right.pm2Home && left.managementLockPath === right.managementLockPath;
98
+ }
99
+ function currentScope() {
100
+ return runtimeScope({ cwd: process.cwd(), env: process.env });
101
+ }
102
+ function diagnoseOpenCodeRuntime(runtime = {
103
+ cwd: process.cwd(),
104
+ env: process.env
105
+ }) {
106
+ const executable = runtimeScope(runtime).opencodePath;
107
+ const result = spawnSync(executable, ["--version"], {
108
+ cwd: runtime.cwd,
109
+ env: runtime.env,
110
+ encoding: "utf8",
111
+ timeout: 1e4,
112
+ killSignal: "SIGKILL"
113
+ });
114
+ const ok = result.status === 0 && result.error === void 0;
115
+ return {
116
+ ok,
117
+ executable,
118
+ version: ok ? result.stdout.trim() || result.stderr.trim() || null : null,
119
+ error: ok ? null : result.error?.message || result.stderr.trim() || result.stdout.trim() || `exit code ${result.status}`
120
+ };
121
+ }
122
+ function getGatewayDiagnostic(options = {}) {
123
+ const producerScope = currentScope();
124
+ if (!isPm2Installed()) {
125
+ return {
126
+ pm2Installed: false,
127
+ processFound: false,
128
+ status: null,
129
+ pid: null,
130
+ ready: false,
131
+ runningVersion: getRunningVersion(),
132
+ gatewayEntry: null,
133
+ gatewayPackageVersion: null,
134
+ logRotationInstalled: false,
135
+ startupConfigured: process.platform === "darwin" || process.platform === "linux" ? false : null,
136
+ currentScope: producerScope,
137
+ gatewayScope: null,
138
+ scopeMatches: false,
139
+ gatewayOpenCode: null
140
+ };
141
+ }
142
+ const processes = pm2JsonList();
143
+ const gateway = processes.find((item) => item.name === PROCESS_NAME);
144
+ const runtime = gatewayRuntimeFromProcess(gateway);
145
+ const gatewayEnv = runtime?.env ?? process.env;
146
+ const managedScope = runtime ? runtimeScope(runtime) : null;
147
+ const pid = typeof gateway?.pid === "number" ? gateway.pid : null;
148
+ const readyPath = managedScope?.databasePath ?? databasePath();
149
+ const lockedVersion = pid == null ? void 0 : gatewayVersionFromLock(pid, readyPath);
150
+ const gatewayEntry = runtime?.gatewayEntry ?? null;
151
+ return {
152
+ pm2Installed: true,
153
+ processFound: gateway != null,
154
+ status: gateway?.pm2_env?.status ?? null,
155
+ pid,
156
+ ready: pid != null && isGatewayReady(pid, readyPath),
157
+ runningVersion: lockedVersion === void 0 ? getRunningVersion(gatewayEnv, runtime?.cwd) : lockedVersion,
158
+ gatewayEntry,
159
+ gatewayPackageVersion: packageVersionFromGatewayEntry(gatewayEntry),
160
+ logRotationInstalled: processes.some((item) => item.name === "pm2-logrotate" && item.pm2_env?.status === "online"),
161
+ startupConfigured: process.platform === "darwin" ? isMacLaunchAgentConfigured(
162
+ gatewayEnv.PM2_HOME ?? join2(runtimeHome(gatewayEnv), ".pm2"),
163
+ runtime ?? void 0
164
+ ) : process.platform === "linux" ? isLinuxStartupConfigured(gatewayEnv, runtime?.cwd, runtime ?? void 0) : null,
165
+ currentScope: producerScope,
166
+ gatewayScope: managedScope,
167
+ scopeMatches: managedScope != null && scopesMatch(producerScope, managedScope),
168
+ gatewayOpenCode: runtime === null || !options.probeOpenCode ? null : diagnoseOpenCodeRuntime(runtime)
169
+ };
170
+ }
171
+ function pm2Bin(env = process.env) {
172
+ return env.SUPERTASK_PM2_BIN ?? (process.platform === "win32" ? "pm2.cmd" : "pm2");
173
+ }
174
+ function pm2CommandTimeoutMs(env = process.env) {
175
+ const configured = Number(env.SUPERTASK_PM2_COMMAND_TIMEOUT_MS ?? 15e3);
176
+ return Number.isFinite(configured) && configured > 0 ? configured : 15e3;
177
+ }
178
+ function resolvePm2Bin() {
179
+ const configured = pm2Bin();
180
+ if (isAbsolute(configured)) return configured;
181
+ const result = spawnSync("which", [configured], { encoding: "utf8" });
182
+ const resolved = result.status === 0 ? result.stdout.trim().split("\n")[0] : "";
183
+ if (!resolved) throw new Error(`[supertask] \u65E0\u6CD5\u89E3\u6790 pm2 \u53EF\u6267\u884C\u6587\u4EF6: ${configured}`);
184
+ return resolved;
185
+ }
186
+ function launchAgentPath() {
187
+ return process.env.SUPERTASK_LAUNCH_AGENT_PATH ?? join2(runtimeHome(process.env), "Library/LaunchAgents", `${MAC_LAUNCH_AGENT_LABEL}.plist`);
188
+ }
189
+ function launchctlBin() {
190
+ return process.env.SUPERTASK_LAUNCHCTL_BIN ?? "launchctl";
191
+ }
192
+ function xmlUnescape(value) {
193
+ return value.replaceAll("&apos;", "'").replaceAll("&quot;", '"').replaceAll("&gt;", ">").replaceAll("&lt;", "<").replaceAll("&amp;", "&");
194
+ }
195
+ function plistValue(contents, key) {
196
+ const escapedKey = key.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
197
+ const match = contents.match(new RegExp(`<key>\\s*${escapedKey}\\s*</key>\\s*<string>([^<]*)</string>`));
198
+ return match?.[1] ? xmlUnescape(match[1]) : null;
199
+ }
200
+ function isMacLaunchAgentConfigured(expectedPm2Home, expectedRuntime) {
201
+ if (typeof process.getuid !== "function") return false;
202
+ const plistPath = launchAgentPath();
203
+ if (!existsSync(plistPath)) return false;
204
+ try {
205
+ const contents = readFileSync(plistPath, "utf8");
206
+ const argumentsBlock = contents.match(
207
+ /<key>\s*ProgramArguments\s*<\/key>\s*<array>([\s\S]*?)<\/array>/
208
+ )?.[1];
209
+ const programArguments = argumentsBlock ? [...argumentsBlock.matchAll(/<string>([^<]*)<\/string>/g)].map((match) => xmlUnescape(match[1])) : [];
210
+ const bunPath = programArguments[0];
211
+ const supervisorEntry = programArguments[1];
212
+ const pm2Path = programArguments[2];
213
+ const pm2Home = plistValue(contents, "PM2_HOME");
214
+ const managementLock = plistValue(contents, "SUPERTASK_PM2_MANAGEMENT_LOCK");
215
+ if (!bunPath || !supervisorEntry || !pm2Path || !pm2Home || !managementLock) return false;
216
+ if (expectedPm2Home && pm2Home !== expectedPm2Home) return false;
217
+ const expectedManagementLock = expectedRuntime ? managementLockPath(expectedRuntime.env, expectedRuntime.cwd) : process.env.SUPERTASK_PM2_MANAGEMENT_LOCK ? managementLockPath() : join2(expectedPm2Home ?? currentScope().pm2Home, "supertask-gateway.manage.sqlite");
218
+ if (managementLock !== expectedManagementLock) return false;
219
+ accessSync(bunPath, constants.X_OK);
220
+ accessSync(supervisorEntry, constants.R_OK);
221
+ accessSync(pm2Path, constants.X_OK);
222
+ if (spawnSync(bunPath, ["--version"], {
223
+ stdio: "ignore",
224
+ timeout: pm2CommandTimeoutMs(),
225
+ killSignal: "SIGKILL"
226
+ }).status !== 0) return false;
227
+ if (spawnSync(pm2Path, ["--version"], {
228
+ stdio: "ignore",
229
+ env: { ...process.env, PM2_HOME: pm2Home },
230
+ timeout: pm2CommandTimeoutMs(),
231
+ killSignal: "SIGKILL"
232
+ }).status !== 0) return false;
233
+ const loaded = spawnSync(
234
+ launchctlBin(),
235
+ ["print", `gui/${process.getuid()}/${MAC_LAUNCH_AGENT_LABEL}`],
236
+ {
237
+ encoding: "utf8",
238
+ stdio: ["ignore", "pipe", "ignore"],
239
+ timeout: pm2CommandTimeoutMs(),
240
+ killSignal: "SIGKILL"
241
+ }
242
+ );
243
+ if (loaded.status !== 0) return false;
244
+ if (!loaded.stdout.includes("state = running")) return false;
245
+ if (!loaded.stdout.includes(`path = ${plistPath}`)) return false;
246
+ if (!loaded.stdout.includes(`program = ${bunPath}`)) return false;
247
+ const dumpPath = join2(pm2Home, "dump.pm2");
248
+ const dump = JSON.parse(readFileSync(dumpPath, "utf8"));
249
+ if (!Array.isArray(dump)) return false;
250
+ const gateway = dump.find((item) => item.name === PROCESS_NAME);
251
+ const dumpRuntime = gatewayRuntimeFromProcess(gateway);
252
+ if (!dumpRuntime || !hasRestorableSavedGatewayRuntime(gateway)) return false;
253
+ return expectedRuntime === void 0 || dumpRuntime.gatewayEntry === expectedRuntime.gatewayEntry && dumpRuntime.bunPath === expectedRuntime.bunPath && dumpRuntime.cwd === expectedRuntime.cwd && scopesMatch(runtimeScope(dumpRuntime), runtimeScope(expectedRuntime));
254
+ } catch {
255
+ return false;
256
+ }
257
+ }
258
+ function systemctlBin(env = process.env) {
259
+ return env.SUPERTASK_SYSTEMCTL_BIN ?? "systemctl";
260
+ }
261
+ function isLinuxStartupConfigured(env = process.env, cwd = process.cwd(), expectedRuntime) {
262
+ const unit = env.SUPERTASK_PM2_SYSTEMD_UNIT ?? `pm2-${userInfo().username}.service`;
263
+ const enabled = spawnSync(systemctlBin(env), ["is-enabled", unit], {
264
+ encoding: "utf8",
265
+ env,
266
+ stdio: ["ignore", "pipe", "ignore"],
267
+ timeout: pm2CommandTimeoutMs(env),
268
+ killSignal: "SIGKILL"
269
+ });
270
+ if (enabled.status !== 0 || enabled.stdout.trim() !== "enabled") return false;
271
+ const contents = spawnSync(systemctlBin(env), ["cat", unit], {
272
+ encoding: "utf8",
273
+ env,
274
+ stdio: ["ignore", "pipe", "ignore"],
275
+ timeout: pm2CommandTimeoutMs(env),
276
+ killSignal: "SIGKILL"
277
+ });
278
+ if (contents.status !== 0) return false;
279
+ const expectedPm2Home = env.PM2_HOME ?? join2(runtimeHome(env), ".pm2");
280
+ if (!contents.stdout.includes("resurrect") || !contents.stdout.includes(expectedPm2Home)) {
281
+ return false;
282
+ }
283
+ try {
284
+ const dump = JSON.parse(readFileSync(join2(expectedPm2Home, "dump.pm2"), "utf8"));
285
+ if (!Array.isArray(dump)) return false;
286
+ const gateway = dump.find((item) => item.name === PROCESS_NAME);
287
+ const runtime = gatewayRuntimeFromProcess(gateway);
288
+ if (!runtime || !hasRestorableSavedGatewayRuntime(gateway)) return false;
289
+ return runtime.cwd === resolve(cwd) && scopesMatch(runtimeScope(runtime), runtimeScope({ cwd, env })) && (expectedRuntime === void 0 || runtime.gatewayEntry === expectedRuntime.gatewayEntry && runtime.bunPath === expectedRuntime.bunPath);
290
+ } catch {
291
+ return false;
292
+ }
293
+ }
294
+ function isPm2Installed(env = process.env) {
295
+ const result = spawnSync(pm2Bin(env), ["--version"], {
296
+ stdio: "ignore",
297
+ env,
298
+ shell: process.platform === "win32",
299
+ timeout: pm2CommandTimeoutMs(env),
300
+ killSignal: "SIGKILL"
301
+ });
302
+ return result.status === 0;
303
+ }
304
+ function resolveCommand(command) {
305
+ const lookup = process.platform === "win32" ? "where" : "which";
306
+ const result = spawnSync(lookup, [command], { encoding: "utf8" });
307
+ return result.status === 0 ? result.stdout.trim().split("\n")[0] || null : null;
308
+ }
309
+ function npmPreferredEnvironment() {
310
+ if (process.platform === "win32") return null;
311
+ const npm = resolveCommand("npm");
312
+ const node = resolveCommand("node");
313
+ if (!npm || !node) return null;
314
+ const command = resolvePm2Bin();
315
+ const path = [.../* @__PURE__ */ new Set([
316
+ dirname(command),
317
+ dirname(npm),
318
+ dirname(node),
319
+ "/usr/local/bin",
320
+ "/usr/bin",
321
+ "/bin"
322
+ ])].join(delimiter);
323
+ return { command, env: { ...process.env, PATH: path } };
324
+ }
325
+ function pm2Exec(args, options = {}) {
326
+ const npmEnvironment = options.preferNpm ? npmPreferredEnvironment() : null;
327
+ const effectiveEnv = options.env ?? npmEnvironment?.env ?? process.env;
328
+ const result = spawnSync(npmEnvironment?.command ?? pm2Bin(effectiveEnv), args, {
329
+ stdio: ["pipe", "pipe", "pipe"],
330
+ encoding: "utf-8",
331
+ env: effectiveEnv,
332
+ shell: process.platform === "win32",
333
+ timeout: options.timeoutMs ?? pm2CommandTimeoutMs(effectiveEnv),
334
+ killSignal: "SIGKILL"
335
+ });
336
+ const output = `${result.stdout ?? ""}${result.stderr ?? ""}`.trim();
337
+ if (result.error) return { ok: false, output: result.error.message };
338
+ return { ok: result.status === 0, output };
339
+ }
340
+ function requirePm2(args, action, options = {}) {
341
+ const result = pm2Exec(args, options);
342
+ if (!result.ok) throw new Error(`[supertask] ${action} failed: ${result.output || "unknown pm2 error"}`);
343
+ return result.output;
344
+ }
345
+ function pm2JsonList(env = process.env) {
346
+ const output = requirePm2(["jlist"], "pm2 jlist", { env });
347
+ try {
348
+ const parsed = JSON.parse(output);
349
+ if (!Array.isArray(parsed)) throw new Error("result is not an array");
350
+ return parsed;
351
+ } catch (error) {
352
+ const message = error instanceof Error ? error.message : String(error);
353
+ throw new Error(`[supertask] Invalid pm2 jlist output: ${message}`);
354
+ }
355
+ }
356
+ function gatewayEntryFromProcess(processInfo) {
357
+ const args = processInfo?.pm2_env?.args ?? processInfo?.args;
358
+ const candidates = Array.isArray(args) ? [...args].reverse() : typeof args === "string" ? [args] : [];
359
+ const savedCwd = processInfo?.pm2_env?.pm_cwd ?? processInfo?.pm_cwd;
360
+ for (const candidate of candidates) {
361
+ const path = typeof savedCwd === "string" ? runtimePath(candidate, savedCwd) : candidate;
362
+ if (existsSync(path)) return resolve(path);
363
+ }
364
+ return null;
365
+ }
366
+ function gatewayEnvironmentFromProcess(processInfo) {
367
+ const saved = processInfo?.pm2_env?.env ?? processInfo?.env;
368
+ if (!saved) return { ...process.env };
369
+ const env = {};
370
+ for (const [key, value] of Object.entries(saved)) {
371
+ if (typeof value === "string") env[key] = value;
372
+ }
373
+ return env;
374
+ }
375
+ function gatewayRuntimeFromProcess(processInfo) {
376
+ const gatewayEntry = gatewayEntryFromProcess(processInfo);
377
+ if (!gatewayEntry) return null;
378
+ const savedBunPath = processInfo?.pm2_env?.pm_exec_path ?? processInfo?.pm_exec_path;
379
+ const savedCwd = processInfo?.pm2_env?.pm_cwd ?? processInfo?.pm_cwd;
380
+ const savedEnv = gatewayEnvironmentFromProcess(processInfo);
381
+ if (typeof savedBunPath !== "string" || typeof savedCwd !== "string") return null;
382
+ try {
383
+ accessSync(savedBunPath, constants.X_OK);
384
+ if (!statSync(savedCwd).isDirectory()) return null;
385
+ if (spawnSync(savedBunPath, ["--version"], {
386
+ stdio: "ignore",
387
+ env: savedEnv,
388
+ timeout: pm2CommandTimeoutMs(savedEnv),
389
+ killSignal: "SIGKILL"
390
+ }).status !== 0) return null;
391
+ } catch {
392
+ return null;
393
+ }
394
+ const killTimeout = processInfo?.pm2_env?.kill_timeout ?? processInfo?.kill_timeout;
395
+ return {
396
+ gatewayEntry,
397
+ bunPath: savedBunPath,
398
+ cwd: resolve(savedCwd),
399
+ env: savedEnv,
400
+ killTimeoutMs: Number.isInteger(killTimeout) && killTimeout >= 5e3 ? killTimeout : void 0
401
+ };
402
+ }
403
+ function hasRestorableSavedGatewayRuntime(processInfo) {
404
+ return gatewayRuntimeFromProcess(processInfo) !== null;
405
+ }
406
+ function databasePath(env = process.env, cwd = process.cwd()) {
407
+ return env.SUPERTASK_DB_PATH ? runtimePath(env.SUPERTASK_DB_PATH, cwd) : join2(runtimeHome(env), ".local/share/opencode/tasks.db");
408
+ }
409
+ function isGatewayReady(expectedPid, path = databasePath()) {
410
+ if (!existsSync(path)) return false;
411
+ let database = null;
412
+ try {
413
+ database = new Database2(path, { readonly: true });
414
+ const row = database.query(
415
+ "SELECT pid, heartbeat_at, ready_at FROM gateway_lock WHERE id = 1"
416
+ ).get();
417
+ if (!row || row.ready_at == null) return false;
418
+ if (expectedPid !== void 0 && row.pid !== expectedPid) return false;
419
+ const ageMs = Date.now() - row.heartbeat_at;
420
+ return ageMs >= -5e3 && ageMs < GATEWAY_LOCK_STALE_MS;
421
+ } catch {
422
+ return false;
423
+ } finally {
424
+ database?.close();
425
+ }
426
+ }
427
+ function gatewayVersionFromLock(expectedPid, path) {
428
+ if (!existsSync(path)) return void 0;
429
+ let database = null;
430
+ try {
431
+ database = new Database2(path, { readonly: true });
432
+ const row = database.query(
433
+ "SELECT pid, version FROM gateway_lock WHERE id = 1"
434
+ ).get();
435
+ if (!row || row.pid !== expectedPid) return void 0;
436
+ return row.version;
437
+ } catch {
438
+ return void 0;
439
+ } finally {
440
+ database?.close();
441
+ }
442
+ }
443
+ function managementLockPath(env = process.env, cwd = process.cwd()) {
444
+ const override = env.SUPERTASK_PM2_MANAGEMENT_LOCK;
445
+ if (override) return runtimePath(override, cwd);
446
+ return join2(runtimeScope({ env, cwd }).pm2Home, "supertask-gateway.manage.sqlite");
447
+ }
448
+ function canonicalManagementLockPath(env = process.env, cwd = process.cwd()) {
449
+ const home = runtimeHome(env);
450
+ const pm2Home = env.PM2_HOME ? runtimePath(env.PM2_HOME, cwd) : join2(home, ".pm2");
451
+ return join2(pm2Home, "supertask-gateway.manage.sqlite");
452
+ }
453
+
454
+ // src/daemon/gateway-diagnostic-runner.ts
455
+ try {
456
+ console.log(JSON.stringify(getGatewayDiagnostic()));
457
+ } catch (error) {
458
+ console.error(error instanceof Error ? error.message : String(error));
459
+ process.exitCode = 1;
460
+ }
461
+ //# sourceMappingURL=gateway-diagnostic-runner.js.map