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.
- package/CHANGELOG.md +18 -1
- package/LICENSE +21 -0
- package/README.md +10 -3
- package/README.zh-CN.md +10 -3
- package/dist/cli/index.js +365 -124
- package/dist/cli/index.js.map +1 -1
- package/dist/daemon/gateway-diagnostic-runner.d.ts +2 -0
- package/dist/daemon/gateway-diagnostic-runner.js +461 -0
- package/dist/daemon/gateway-diagnostic-runner.js.map +1 -0
- package/dist/gateway/index.js +348 -572
- package/dist/gateway/index.js.map +1 -1
- package/dist/plugin/supertask.js +53 -24
- package/dist/plugin/supertask.js.map +1 -1
- package/dist/web/index.js +231 -487
- package/dist/web/index.js.map +1 -1
- package/dist/worker/index.d.ts +8 -0
- package/dist/worker/index.js +191 -66
- package/dist/worker/index.js.map +1 -1
- package/dist/worker/launcher.js.map +1 -1
- package/package.json +12 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/daemon/pm2.ts","../../src/gateway/config.ts","../../src/daemon/management-lock.ts","../../src/daemon/gateway-diagnostic-runner.ts"],"sourcesContent":["import { execSync, spawnSync } from \"child_process\";\nimport {\n accessSync,\n chmodSync,\n constants,\n existsSync,\n mkdirSync,\n readFileSync,\n rmSync,\n statSync,\n writeFileSync,\n} from \"fs\";\nimport { homedir, userInfo } from \"os\";\nimport { delimiter, dirname, isAbsolute, join, resolve } from \"path\";\nimport { fileURLToPath } from \"url\";\nimport { Database } from \"bun:sqlite\";\nimport { loadConfig } from \"../gateway/config\";\nimport { getPackageVersion } from \"../core/package-version\";\nimport { ManagementLockBusyError, withExclusiveManagementLock } from \"./management-lock\";\n\nexport { getPackageVersion } from \"../core/package-version\";\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nconst PROCESS_NAME = \"supertask-gateway\";\nconst MAC_LAUNCH_AGENT_LABEL = \"com.supertask.pm2-resurrect\";\n\ninterface Pm2Process {\n name: string;\n pid?: number;\n args?: string[] | string;\n pm_exec_path?: string;\n pm_cwd?: string;\n env?: Record<string, unknown>;\n kill_timeout?: number;\n pm2_env?: {\n status?: string;\n args?: string[] | string;\n pm_exec_path?: string;\n pm_cwd?: string;\n env?: Record<string, unknown>;\n kill_timeout?: number;\n };\n}\n\nexport interface GatewayRuntime {\n gatewayEntry: string;\n bunPath: string;\n cwd: string;\n env: NodeJS.ProcessEnv;\n killTimeoutMs?: number;\n}\n\nexport interface RuntimeScope {\n cwd: string;\n databasePath: string;\n configPath: string;\n opencodePath: string;\n home: string;\n pm2Home: string;\n managementLockPath: string;\n}\n\nexport interface GatewayDiagnostic {\n pm2Installed: boolean;\n processFound: boolean;\n status: string | null;\n pid: number | null;\n ready: boolean;\n runningVersion: string | null;\n gatewayEntry: string | null;\n gatewayPackageVersion: string | null;\n logRotationInstalled: boolean;\n startupConfigured: boolean | null;\n currentScope: RuntimeScope;\n gatewayScope: RuntimeScope | null;\n scopeMatches: boolean;\n gatewayOpenCode: OpenCodeRuntimeDiagnostic | null;\n}\n\nexport interface OpenCodeRuntimeDiagnostic {\n ok: boolean;\n executable: string;\n version: string | null;\n error: string | null;\n}\n\nconst GATEWAY_LOCK_STALE_MS = 30_000;\n\nexport type EnsureGatewayResult =\n | { ok: true; action: \"already-running\" | \"started\" | \"restarted\" }\n | { ok: false; reason: \"pm2-not-installed\" };\n\nexport interface GatewayMaintenanceState {\n wasRunning: boolean;\n env?: NodeJS.ProcessEnv;\n cwd?: string;\n}\n\nexport interface GatewayMaintenanceResult<T> {\n result: T;\n wasRunning: boolean;\n restarted: boolean;\n keptStopped: boolean;\n}\n\nexport function resolveGatewayEntry(): string {\n const override = process.env.SUPERTASK_GATEWAY_ENTRY;\n if (override) {\n if (!existsSync(override)) throw new Error(`[supertask] Gateway entry not found: ${override}`);\n return override;\n }\n\n const candidates = [\n join(__dirname, \"../gateway/index.js\"),\n join(__dirname, \"../gateway/index.ts\"),\n ];\n const entry = candidates.find((candidate) => existsSync(candidate));\n if (!entry) throw new Error(`[supertask] Gateway entry not found. Checked: ${candidates.join(\", \")}`);\n return entry;\n}\n\nfunction runtimeHome(env: NodeJS.ProcessEnv): string {\n return resolve(env.HOME || homedir());\n}\n\nfunction runtimePath(value: string, cwd: string): string {\n return resolve(cwd, value);\n}\n\nfunction versionFile(env: NodeJS.ProcessEnv = process.env, cwd = process.cwd()): string {\n return env.SUPERTASK_VERSION_FILE\n ? runtimePath(env.SUPERTASK_VERSION_FILE, cwd)\n : join(runtimeHome(env), \".local/share/opencode/supertask-gateway-version\");\n}\n\nfunction getRunningVersion(env: NodeJS.ProcessEnv = process.env, cwd = process.cwd()): string | null {\n try {\n const path = versionFile(env, cwd);\n if (!existsSync(path)) return null;\n return readFileSync(path, \"utf-8\").trim() || null;\n } catch {\n return null;\n }\n}\n\nfunction packageVersionFromGatewayEntry(gatewayEntry: string | null): string | null {\n if (gatewayEntry === null) return null;\n let directory = dirname(gatewayEntry);\n for (let depth = 0; depth < 6; depth += 1) {\n const packagePath = join(directory, 'package.json');\n if (existsSync(packagePath)) {\n try {\n const pkg = JSON.parse(readFileSync(packagePath, 'utf8')) as {\n name?: unknown;\n version?: unknown;\n };\n if (pkg.name === 'opencode-supertask' && typeof pkg.version === 'string') {\n return pkg.version;\n }\n } catch {}\n }\n const parent = dirname(directory);\n if (parent === directory) break;\n directory = parent;\n }\n return null;\n}\n\nfunction resolveRuntimeExecutable(command: string, env: NodeJS.ProcessEnv, cwd: string): string {\n if (isAbsolute(command) || command.includes(\"/\")) return runtimePath(command, cwd);\n for (const entry of (env.PATH ?? \"\").split(delimiter)) {\n if (!entry) continue;\n const candidate = resolve(cwd, entry, command);\n try {\n accessSync(candidate, constants.X_OK);\n return candidate;\n } catch {}\n }\n return command;\n}\n\nfunction runtimeScope(runtime: Pick<GatewayRuntime, \"cwd\" | \"env\">): RuntimeScope {\n const { cwd, env } = runtime;\n const home = runtimeHome(env);\n return {\n cwd: resolve(cwd),\n databasePath: env.SUPERTASK_DB_PATH\n ? runtimePath(env.SUPERTASK_DB_PATH, cwd)\n : join(home, \".local/share/opencode/tasks.db\"),\n configPath: env.SUPERTASK_CONFIG_PATH\n ? runtimePath(env.SUPERTASK_CONFIG_PATH, cwd)\n : join(home, \".config/opencode/supertask.json\"),\n opencodePath: resolveRuntimeExecutable(env.SUPERTASK_OPENCODE_BIN ?? \"opencode\", env, cwd),\n home,\n pm2Home: env.PM2_HOME\n ? runtimePath(env.PM2_HOME, cwd)\n : join(home, \".pm2\"),\n managementLockPath: canonicalManagementLockPath(env, cwd),\n };\n}\n\nfunction scopesMatch(left: RuntimeScope, right: RuntimeScope): boolean {\n return left.databasePath === right.databasePath\n && left.configPath === right.configPath\n && left.opencodePath === right.opencodePath\n && left.home === right.home\n && left.pm2Home === right.pm2Home\n && left.managementLockPath === right.managementLockPath;\n}\n\nfunction currentScope(): RuntimeScope {\n return runtimeScope({ cwd: process.cwd(), env: process.env });\n}\n\nexport function diagnoseOpenCodeRuntime(\n runtime: Pick<GatewayRuntime, \"cwd\" | \"env\"> = {\n cwd: process.cwd(),\n env: process.env,\n },\n): OpenCodeRuntimeDiagnostic {\n const executable = runtimeScope(runtime).opencodePath;\n const result = spawnSync(executable, [\"--version\"], {\n cwd: runtime.cwd,\n env: runtime.env,\n encoding: \"utf8\",\n timeout: 10_000,\n killSignal: \"SIGKILL\",\n });\n const ok = result.status === 0 && result.error === undefined;\n return {\n ok,\n executable,\n version: ok ? result.stdout.trim() || result.stderr.trim() || null : null,\n error: ok\n ? null\n : result.error?.message\n || result.stderr.trim()\n || result.stdout.trim()\n || `exit code ${result.status}`,\n };\n}\n\nfunction assertOpenCodeRuntime(runtime: GatewayRuntime): void {\n const diagnostic = diagnoseOpenCodeRuntime(runtime);\n if (!diagnostic.ok) {\n throw new Error(\n `[supertask] 目标 Gateway 环境无法执行 OpenCode (${diagnostic.executable}): ${diagnostic.error}`,\n );\n }\n}\n\nexport function getGatewayDiagnostic(options: { probeOpenCode?: boolean } = {}): GatewayDiagnostic {\n const producerScope = currentScope();\n if (!isPm2Installed()) {\n return {\n pm2Installed: false,\n processFound: false,\n status: null,\n pid: null,\n ready: false,\n runningVersion: getRunningVersion(),\n gatewayEntry: null,\n gatewayPackageVersion: null,\n logRotationInstalled: false,\n startupConfigured: process.platform === \"darwin\" || process.platform === \"linux\" ? false : null,\n currentScope: producerScope,\n gatewayScope: null,\n scopeMatches: false,\n gatewayOpenCode: null,\n };\n }\n\n const processes = pm2JsonList();\n const gateway = processes.find((item) => item.name === PROCESS_NAME);\n const runtime = gatewayRuntimeFromProcess(gateway);\n const gatewayEnv = runtime?.env ?? process.env;\n const managedScope = runtime ? runtimeScope(runtime) : null;\n const pid = typeof gateway?.pid === \"number\" ? gateway.pid : null;\n const readyPath = managedScope?.databasePath ?? databasePath();\n const lockedVersion = pid == null ? undefined : gatewayVersionFromLock(pid, readyPath);\n const gatewayEntry = runtime?.gatewayEntry ?? null;\n return {\n pm2Installed: true,\n processFound: gateway != null,\n status: gateway?.pm2_env?.status ?? null,\n pid,\n ready: pid != null && isGatewayReady(pid, readyPath),\n runningVersion: lockedVersion === undefined\n ? getRunningVersion(gatewayEnv, runtime?.cwd)\n : lockedVersion,\n gatewayEntry,\n gatewayPackageVersion: packageVersionFromGatewayEntry(gatewayEntry),\n logRotationInstalled: processes.some((item) => (\n item.name === \"pm2-logrotate\" && item.pm2_env?.status === \"online\"\n )),\n startupConfigured: process.platform === \"darwin\"\n ? isMacLaunchAgentConfigured(\n gatewayEnv.PM2_HOME ?? join(runtimeHome(gatewayEnv), \".pm2\"),\n runtime ?? undefined,\n )\n : process.platform === \"linux\"\n ? isLinuxStartupConfigured(gatewayEnv, runtime?.cwd, runtime ?? undefined)\n : null,\n currentScope: producerScope,\n gatewayScope: managedScope,\n scopeMatches: managedScope != null && scopesMatch(producerScope, managedScope),\n gatewayOpenCode: runtime === null || !options.probeOpenCode\n ? null\n : diagnoseOpenCodeRuntime(runtime),\n };\n}\n\nfunction writeRunningVersion(\n version: string,\n env: NodeJS.ProcessEnv = process.env,\n cwd = process.cwd(),\n): void {\n const path = versionFile(env, cwd);\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, version, \"utf-8\");\n}\n\nfunction pm2Bin(env: NodeJS.ProcessEnv = process.env): string {\n return env.SUPERTASK_PM2_BIN\n ?? (process.platform === \"win32\" ? \"pm2.cmd\" : \"pm2\");\n}\n\nfunction pm2CommandTimeoutMs(env: NodeJS.ProcessEnv = process.env): number {\n const configured = Number(env.SUPERTASK_PM2_COMMAND_TIMEOUT_MS ?? 15_000);\n return Number.isFinite(configured) && configured > 0 ? configured : 15_000;\n}\n\nfunction xmlEscape(value: string): string {\n return value\n .replaceAll(\"&\", \"&\")\n .replaceAll(\"<\", \"<\")\n .replaceAll(\">\", \">\")\n .replaceAll('\"', \""\")\n .replaceAll(\"'\", \"'\");\n}\n\nfunction resolvePm2Bin(): string {\n const configured = pm2Bin();\n if (isAbsolute(configured)) return configured;\n const result = spawnSync(\"which\", [configured], { encoding: \"utf8\" });\n const resolved = result.status === 0 ? result.stdout.trim().split(\"\\n\")[0] : \"\";\n if (!resolved) throw new Error(`[supertask] 无法解析 pm2 可执行文件: ${configured}`);\n return resolved;\n}\n\nfunction launchAgentPath(): string {\n return process.env.SUPERTASK_LAUNCH_AGENT_PATH\n ?? join(runtimeHome(process.env), \"Library/LaunchAgents\", `${MAC_LAUNCH_AGENT_LABEL}.plist`);\n}\n\nfunction launchctlBin(): string {\n return process.env.SUPERTASK_LAUNCHCTL_BIN ?? \"launchctl\";\n}\n\nexport function resolvePm2SupervisorEntry(baseDir = __dirname): string {\n const override = process.env.SUPERTASK_PM2_SUPERVISOR_ENTRY;\n if (override) {\n if (!existsSync(override)) throw new Error(`[supertask] PM2 supervisor entry not found: ${override}`);\n return resolve(override);\n }\n const candidates = [\n join(baseDir, \"pm2-supervisor.js\"),\n join(baseDir, \"pm2-supervisor.ts\"),\n join(baseDir, \"../daemon/pm2-supervisor.js\"),\n join(baseDir, \"../daemon/pm2-supervisor.ts\"),\n ];\n const entry = candidates.find((candidate) => existsSync(candidate));\n if (!entry) throw new Error(`[supertask] PM2 supervisor entry not found. Checked: ${candidates.join(\", \")}`);\n return resolve(entry);\n}\n\nfunction xmlUnescape(value: string): string {\n return value\n .replaceAll(\"'\", \"'\")\n .replaceAll(\""\", '\"')\n .replaceAll(\">\", \">\")\n .replaceAll(\"<\", \"<\")\n .replaceAll(\"&\", \"&\");\n}\n\nfunction plistValue(contents: string, key: string): string | null {\n const escapedKey = key.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n const match = contents.match(new RegExp(`<key>\\\\s*${escapedKey}\\\\s*</key>\\\\s*<string>([^<]*)</string>`));\n return match?.[1] ? xmlUnescape(match[1]) : null;\n}\n\nexport function isMacLaunchAgentConfigured(\n expectedPm2Home?: string,\n expectedRuntime?: GatewayRuntime,\n): boolean {\n if (typeof process.getuid !== \"function\") return false;\n const plistPath = launchAgentPath();\n if (!existsSync(plistPath)) return false;\n\n try {\n const contents = readFileSync(plistPath, \"utf8\");\n const argumentsBlock = contents.match(\n /<key>\\s*ProgramArguments\\s*<\\/key>\\s*<array>([\\s\\S]*?)<\\/array>/,\n )?.[1];\n const programArguments = argumentsBlock\n ? [...argumentsBlock.matchAll(/<string>([^<]*)<\\/string>/g)].map((match) => xmlUnescape(match[1]))\n : [];\n const bunPath = programArguments[0];\n const supervisorEntry = programArguments[1];\n const pm2Path = programArguments[2];\n const pm2Home = plistValue(contents, \"PM2_HOME\");\n const managementLock = plistValue(contents, \"SUPERTASK_PM2_MANAGEMENT_LOCK\");\n if (!bunPath || !supervisorEntry || !pm2Path || !pm2Home || !managementLock) return false;\n if (expectedPm2Home && pm2Home !== expectedPm2Home) return false;\n const expectedManagementLock = expectedRuntime\n ? managementLockPath(expectedRuntime.env, expectedRuntime.cwd)\n : process.env.SUPERTASK_PM2_MANAGEMENT_LOCK\n ? managementLockPath()\n : join(expectedPm2Home ?? currentScope().pm2Home, \"supertask-gateway.manage.sqlite\");\n if (managementLock !== expectedManagementLock) return false;\n\n accessSync(bunPath, constants.X_OK);\n accessSync(supervisorEntry, constants.R_OK);\n accessSync(pm2Path, constants.X_OK);\n if (spawnSync(bunPath, [\"--version\"], {\n stdio: \"ignore\",\n timeout: pm2CommandTimeoutMs(),\n killSignal: \"SIGKILL\",\n }).status !== 0) return false;\n if (spawnSync(pm2Path, [\"--version\"], {\n stdio: \"ignore\",\n env: { ...process.env, PM2_HOME: pm2Home },\n timeout: pm2CommandTimeoutMs(),\n killSignal: \"SIGKILL\",\n }).status !== 0) return false;\n\n const loaded = spawnSync(\n launchctlBin(),\n [\"print\", `gui/${process.getuid()}/${MAC_LAUNCH_AGENT_LABEL}`],\n {\n encoding: \"utf8\",\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n timeout: pm2CommandTimeoutMs(),\n killSignal: \"SIGKILL\",\n },\n );\n if (loaded.status !== 0) return false;\n if (!loaded.stdout.includes(\"state = running\")) return false;\n if (!loaded.stdout.includes(`path = ${plistPath}`)) return false;\n if (!loaded.stdout.includes(`program = ${bunPath}`)) return false;\n\n const dumpPath = join(pm2Home, \"dump.pm2\");\n const dump = JSON.parse(readFileSync(dumpPath, \"utf8\")) as unknown;\n if (!Array.isArray(dump)) return false;\n const gateway = (dump as Pm2Process[]).find((item) => item.name === PROCESS_NAME);\n const dumpRuntime = gatewayRuntimeFromProcess(gateway);\n if (!dumpRuntime || !hasRestorableSavedGatewayRuntime(gateway)) return false;\n return expectedRuntime === undefined || (\n dumpRuntime.gatewayEntry === expectedRuntime.gatewayEntry\n && dumpRuntime.bunPath === expectedRuntime.bunPath\n && dumpRuntime.cwd === expectedRuntime.cwd\n && scopesMatch(runtimeScope(dumpRuntime), runtimeScope(expectedRuntime))\n );\n } catch {\n return false;\n }\n}\n\nfunction bootstrapMacLaunchAgent(domain: string, path: string) {\n const retryDeadline = Date.now() + 2_000;\n const sleeper = new Int32Array(new SharedArrayBuffer(4));\n let result = spawnSync(launchctlBin(), [\"bootstrap\", domain, path], {\n encoding: \"utf8\",\n timeout: pm2CommandTimeoutMs(),\n killSignal: \"SIGKILL\",\n });\n\n while (result.status !== 0 && Date.now() < retryDeadline) {\n const output = `${result.stdout ?? \"\"}${result.stderr ?? \"\"}`;\n if (result.status !== 5 && !output.includes(\"Bootstrap failed: 5:\")) break;\n Atomics.wait(sleeper, 0, 0, 100);\n result = spawnSync(launchctlBin(), [\"bootstrap\", domain, path], {\n encoding: \"utf8\",\n timeout: pm2CommandTimeoutMs(),\n killSignal: \"SIGKILL\",\n });\n }\n\n return result;\n}\n\nexport function installMacLaunchAgent(expectedRuntime = currentGatewayRuntime()): string {\n if (typeof process.getuid !== \"function\") {\n throw new Error(\"[supertask] 当前运行时无法获取 macOS 用户 ID\");\n }\n\n const path = launchAgentPath();\n const home = runtimeHome(expectedRuntime.env);\n const pm2Home = runtimeScope(expectedRuntime).pm2Home;\n const managementLock = managementLockPath(expectedRuntime.env, expectedRuntime.cwd);\n const environmentPath = expectedRuntime.env.PATH\n ?? \"/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin\";\n const bunPath = findBunPath();\n const supervisorEntry = resolvePm2SupervisorEntry();\n const pm2Path = resolvePm2Bin();\n const plist = `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n <dict>\n <key>Label</key>\n <string>${MAC_LAUNCH_AGENT_LABEL}</string>\n <key>ProgramArguments</key>\n <array>\n <string>${xmlEscape(bunPath)}</string>\n <string>${xmlEscape(supervisorEntry)}</string>\n <string>${xmlEscape(pm2Path)}</string>\n </array>\n <key>RunAtLoad</key>\n <true/>\n <key>KeepAlive</key>\n <true/>\n <key>ThrottleInterval</key>\n <integer>10</integer>\n <key>EnvironmentVariables</key>\n <dict>\n <key>HOME</key>\n <string>${xmlEscape(home)}</string>\n <key>PATH</key>\n <string>${xmlEscape(environmentPath)}</string>\n <key>PM2_HOME</key>\n <string>${xmlEscape(pm2Home)}</string>\n <key>SUPERTASK_PM2_MANAGEMENT_LOCK</key>\n <string>${xmlEscape(managementLock)}</string>\n </dict>\n <key>StandardErrorPath</key>\n <string>${xmlEscape(join(pm2Home, \"supertask-launchd-error.log\"))}</string>\n <key>StandardOutPath</key>\n <string>${xmlEscape(join(pm2Home, \"supertask-launchd-output.log\"))}</string>\n </dict>\n</plist>\n`;\n const domain = `gui/${process.getuid()}`;\n const previousPlist = existsSync(path) ? readFileSync(path) : null;\n const wasLoaded = previousPlist != null && spawnSync(\n launchctlBin(),\n [\"print\", `${domain}/${MAC_LAUNCH_AGENT_LABEL}`],\n {\n stdio: \"ignore\",\n timeout: pm2CommandTimeoutMs(),\n killSignal: \"SIGKILL\",\n },\n ).status === 0;\n\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, plist, { mode: 0o600 });\n chmodSync(path, 0o600);\n\n spawnSync(launchctlBin(), [\"bootout\", `${domain}/${MAC_LAUNCH_AGENT_LABEL}`], {\n stdio: \"ignore\",\n timeout: pm2CommandTimeoutMs(),\n killSignal: \"SIGKILL\",\n });\n const loaded = bootstrapMacLaunchAgent(domain, path);\n const configuredVerifyTimeout = Number(process.env.SUPERTASK_LAUNCH_AGENT_VERIFY_TIMEOUT_MS ?? 2_000);\n const verifyTimeoutMs = Number.isFinite(configuredVerifyTimeout) && configuredVerifyTimeout > 0\n ? configuredVerifyTimeout\n : 2_000;\n const verifyDeadline = Date.now() + verifyTimeoutMs;\n const sleeper = new Int32Array(new SharedArrayBuffer(4));\n let verified = loaded.status === 0 && isMacLaunchAgentConfigured(pm2Home, expectedRuntime);\n while (loaded.status === 0 && !verified && Date.now() < verifyDeadline) {\n Atomics.wait(sleeper, 0, 0, 100);\n verified = isMacLaunchAgentConfigured(pm2Home, expectedRuntime);\n }\n if (loaded.status !== 0 || !verified) {\n const output = loaded.status === 0\n ? \"supervisor 未保持 running 或 PM2 dump 不可恢复\"\n : `${loaded.stdout ?? \"\"}${loaded.stderr ?? \"\"}`.trim();\n if (loaded.status === 0) {\n spawnSync(launchctlBin(), [\"bootout\", `${domain}/${MAC_LAUNCH_AGENT_LABEL}`], {\n stdio: \"ignore\",\n timeout: pm2CommandTimeoutMs(),\n killSignal: \"SIGKILL\",\n });\n }\n if (previousPlist == null) rmSync(path, { force: true });\n else {\n writeFileSync(path, previousPlist, { mode: 0o600 });\n chmodSync(path, 0o600);\n }\n\n let rollbackFailure = \"\";\n if (wasLoaded && previousPlist != null) {\n const restored = bootstrapMacLaunchAgent(domain, path);\n if (restored.status !== 0) {\n rollbackFailure = `;旧 LaunchAgent 恢复失败: ${`${restored.stdout ?? \"\"}${restored.stderr ?? \"\"}`.trim() || `退出码 ${restored.status}`}`;\n }\n }\n throw new Error(`[supertask] macOS LaunchAgent 加载失败: ${output || `退出码 ${loaded.status}`}${rollbackFailure}`);\n }\n return path;\n}\n\nfunction systemctlBin(env: NodeJS.ProcessEnv = process.env): string {\n return env.SUPERTASK_SYSTEMCTL_BIN ?? \"systemctl\";\n}\n\nexport function isLinuxStartupConfigured(\n env: NodeJS.ProcessEnv = process.env,\n cwd = process.cwd(),\n expectedRuntime?: GatewayRuntime,\n): boolean {\n const unit = env.SUPERTASK_PM2_SYSTEMD_UNIT ?? `pm2-${userInfo().username}.service`;\n const enabled = spawnSync(systemctlBin(env), [\"is-enabled\", unit], {\n encoding: \"utf8\",\n env,\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n timeout: pm2CommandTimeoutMs(env),\n killSignal: \"SIGKILL\",\n });\n if (enabled.status !== 0 || enabled.stdout.trim() !== \"enabled\") return false;\n\n const contents = spawnSync(systemctlBin(env), [\"cat\", unit], {\n encoding: \"utf8\",\n env,\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n timeout: pm2CommandTimeoutMs(env),\n killSignal: \"SIGKILL\",\n });\n if (contents.status !== 0) return false;\n const expectedPm2Home = env.PM2_HOME ?? join(runtimeHome(env), \".pm2\");\n if (!contents.stdout.includes(\"resurrect\") || !contents.stdout.includes(expectedPm2Home)) {\n return false;\n }\n try {\n const dump = JSON.parse(readFileSync(join(expectedPm2Home, \"dump.pm2\"), \"utf8\")) as unknown;\n if (!Array.isArray(dump)) return false;\n const gateway = (dump as Pm2Process[]).find((item) => item.name === PROCESS_NAME);\n const runtime = gatewayRuntimeFromProcess(gateway);\n if (!runtime || !hasRestorableSavedGatewayRuntime(gateway)) return false;\n return runtime.cwd === resolve(cwd)\n && scopesMatch(runtimeScope(runtime), runtimeScope({ cwd, env }))\n && (expectedRuntime === undefined || (\n runtime.gatewayEntry === expectedRuntime.gatewayEntry\n && runtime.bunPath === expectedRuntime.bunPath\n ));\n } catch {\n return false;\n }\n}\n\nexport function isPm2Installed(env: NodeJS.ProcessEnv = process.env): boolean {\n const result = spawnSync(pm2Bin(env), [\"--version\"], {\n stdio: \"ignore\",\n env,\n shell: process.platform === \"win32\",\n timeout: pm2CommandTimeoutMs(env),\n killSignal: \"SIGKILL\",\n });\n return result.status === 0;\n}\n\nfunction installPm2(): boolean {\n console.log(\"[supertask] Installing pm2...\");\n try {\n execSync(\"npm install -g pm2\", { stdio: \"inherit\" });\n return true;\n } catch {\n try {\n execSync(\"bun install -g pm2\", { stdio: \"inherit\" });\n return true;\n } catch {\n return false;\n }\n }\n}\n\nfunction resolveCommand(command: string): string | null {\n const lookup = process.platform === \"win32\" ? \"where\" : \"which\";\n const result = spawnSync(lookup, [command], { encoding: \"utf8\" });\n return result.status === 0 ? result.stdout.trim().split(\"\\n\")[0] || null : null;\n}\n\nfunction npmPreferredEnvironment(): { command: string; env: NodeJS.ProcessEnv } | null {\n if (process.platform === \"win32\") return null;\n const npm = resolveCommand(\"npm\");\n const node = resolveCommand(\"node\");\n if (!npm || !node) return null;\n const command = resolvePm2Bin();\n const path = [...new Set([\n dirname(command),\n dirname(npm),\n dirname(node),\n \"/usr/local/bin\",\n \"/usr/bin\",\n \"/bin\",\n ])].join(delimiter);\n return { command, env: { ...process.env, PATH: path } };\n}\n\nfunction pm2Exec(\n args: string[],\n options: { preferNpm?: boolean; env?: NodeJS.ProcessEnv; timeoutMs?: number } = {},\n): { ok: boolean; output: string } {\n const npmEnvironment = options.preferNpm ? npmPreferredEnvironment() : null;\n const effectiveEnv = options.env ?? npmEnvironment?.env ?? process.env;\n const result = spawnSync(npmEnvironment?.command ?? pm2Bin(effectiveEnv), args, {\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n encoding: \"utf-8\",\n env: effectiveEnv,\n shell: process.platform === \"win32\",\n timeout: options.timeoutMs ?? pm2CommandTimeoutMs(effectiveEnv),\n killSignal: \"SIGKILL\",\n });\n const output = `${result.stdout ?? \"\"}${result.stderr ?? \"\"}`.trim();\n if (result.error) return { ok: false, output: result.error.message };\n return { ok: result.status === 0, output };\n}\n\nfunction requirePm2(\n args: string[],\n action: string,\n options: { env?: NodeJS.ProcessEnv; timeoutMs?: number } = {},\n): string {\n const result = pm2Exec(args, options);\n if (!result.ok) throw new Error(`[supertask] ${action} failed: ${result.output || \"unknown pm2 error\"}`);\n return result.output;\n}\n\nexport function ensurePm2LogRotation(env: NodeJS.ProcessEnv = process.env): boolean {\n if (!isPm2Installed(env)) return false;\n const installed = pm2JsonList(env).some((item) => item.name === \"pm2-logrotate\");\n if (!installed) {\n const result = pm2Exec([\"install\", \"pm2-logrotate\"], { preferNpm: true, env });\n if (!result.ok) return false;\n }\n\n for (const [key, value] of [\n [\"max_size\", \"10M\"],\n [\"retain\", \"7\"],\n [\"compress\", \"true\"],\n [\"workerInterval\", \"3600\"],\n ] as const) {\n const result = pm2Exec([\"set\", `pm2-logrotate:${key}`, value], { env });\n if (!result.ok) return false;\n }\n return true;\n}\n\nfunction pm2JsonList(env: NodeJS.ProcessEnv = process.env): Pm2Process[] {\n const output = requirePm2([\"jlist\"], \"pm2 jlist\", { env });\n try {\n const parsed = JSON.parse(output) as unknown;\n if (!Array.isArray(parsed)) throw new Error(\"result is not an array\");\n return parsed as Pm2Process[];\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n throw new Error(`[supertask] Invalid pm2 jlist output: ${message}`);\n }\n}\n\nfunction gatewayEntryFromProcess(processInfo: Pm2Process | undefined): string | null {\n const args = processInfo?.pm2_env?.args ?? processInfo?.args;\n const candidates = Array.isArray(args) ? [...args].reverse() : typeof args === \"string\" ? [args] : [];\n const savedCwd = processInfo?.pm2_env?.pm_cwd ?? processInfo?.pm_cwd;\n for (const candidate of candidates) {\n const path = typeof savedCwd === \"string\" ? runtimePath(candidate, savedCwd) : candidate;\n if (existsSync(path)) return resolve(path);\n }\n return null;\n}\n\nfunction gatewayEnvironmentFromProcess(processInfo: Pm2Process | undefined): NodeJS.ProcessEnv {\n const saved = processInfo?.pm2_env?.env ?? processInfo?.env;\n if (!saved) return { ...process.env };\n\n const env: NodeJS.ProcessEnv = {};\n for (const [key, value] of Object.entries(saved)) {\n if (typeof value === \"string\") env[key] = value;\n }\n return env;\n}\n\nfunction gatewayRuntimeFromProcess(processInfo: Pm2Process | undefined): GatewayRuntime | null {\n const gatewayEntry = gatewayEntryFromProcess(processInfo);\n if (!gatewayEntry) return null;\n const savedBunPath = processInfo?.pm2_env?.pm_exec_path ?? processInfo?.pm_exec_path;\n const savedCwd = processInfo?.pm2_env?.pm_cwd ?? processInfo?.pm_cwd;\n const savedEnv = gatewayEnvironmentFromProcess(processInfo);\n if (typeof savedBunPath !== \"string\" || typeof savedCwd !== \"string\") return null;\n try {\n accessSync(savedBunPath, constants.X_OK);\n if (!statSync(savedCwd).isDirectory()) return null;\n if (spawnSync(savedBunPath, [\"--version\"], {\n stdio: \"ignore\",\n env: savedEnv,\n timeout: pm2CommandTimeoutMs(savedEnv),\n killSignal: \"SIGKILL\",\n }).status !== 0) return null;\n } catch {\n return null;\n }\n const killTimeout = processInfo?.pm2_env?.kill_timeout ?? processInfo?.kill_timeout;\n return {\n gatewayEntry,\n bunPath: savedBunPath,\n cwd: resolve(savedCwd),\n env: savedEnv,\n killTimeoutMs: Number.isInteger(killTimeout) && killTimeout! >= 5000\n ? killTimeout\n : undefined,\n };\n}\n\nfunction hasRestorableSavedGatewayRuntime(processInfo: Pm2Process | undefined): boolean {\n return gatewayRuntimeFromProcess(processInfo) !== null;\n}\n\nfunction currentGatewayRuntime(gatewayEntry = resolveGatewayEntry()): GatewayRuntime {\n return {\n gatewayEntry: resolve(gatewayEntry),\n bunPath: resolve(findBunPath()),\n cwd: process.cwd(),\n env: { ...process.env },\n };\n}\n\nfunction refreshGatewayExecutionEnvironment(\n runtime: GatewayRuntime,\n gatewayEntry: string,\n): GatewayRuntime {\n const env = { ...process.env };\n\n // The explicit install/upgrade command is the point where users expect a\n // Gateway to pick up the same OpenCode/provider environment as their shell.\n // Keep daemon identity and SuperTask scope pinned to the proven old runtime;\n // everything else (including OPENCODE_*, XDG_* and provider credentials)\n // comes from the invoking environment.\n for (const key of new Set([\n ...Object.keys(runtime.env).filter((name) => name.startsWith('SUPERTASK_')),\n ...Object.keys(env).filter((name) => name.startsWith('SUPERTASK_')),\n 'HOME',\n 'PATH',\n 'PM2_HOME',\n ])) {\n const value = runtime.env[key];\n if (value === undefined) delete env[key];\n else env[key] = value;\n }\n\n return {\n ...runtime,\n gatewayEntry: resolve(gatewayEntry),\n env,\n };\n}\n\nexport function isGatewayRunning(): boolean {\n if (!isPm2Installed()) return false;\n const proc = pm2JsonList().find((item) => item.name === PROCESS_NAME);\n const runtime = gatewayRuntimeFromProcess(proc);\n return proc?.pm2_env?.status === \"online\"\n && typeof proc.pid === \"number\"\n && runtime !== null\n && isGatewayReady(proc.pid, runtimeScope(runtime).databasePath);\n}\n\nfunction databasePath(env: NodeJS.ProcessEnv = process.env, cwd = process.cwd()): string {\n return env.SUPERTASK_DB_PATH\n ? runtimePath(env.SUPERTASK_DB_PATH, cwd)\n : join(runtimeHome(env), \".local/share/opencode/tasks.db\");\n}\n\nexport function isGatewayReady(expectedPid?: number, path = databasePath()): boolean {\n if (!existsSync(path)) return false;\n\n let database: Database | null = null;\n try {\n database = new Database(path, { readonly: true });\n const row = database.query(\n \"SELECT pid, heartbeat_at, ready_at FROM gateway_lock WHERE id = 1\",\n ).get() as { pid: number; heartbeat_at: number; ready_at: number | null } | null;\n if (!row || row.ready_at == null) return false;\n if (expectedPid !== undefined && row.pid !== expectedPid) return false;\n const ageMs = Date.now() - row.heartbeat_at;\n return ageMs >= -5000 && ageMs < GATEWAY_LOCK_STALE_MS;\n } catch {\n return false;\n } finally {\n database?.close();\n }\n}\n\nfunction gatewayVersionFromLock(expectedPid: number, path: string): string | null | undefined {\n if (!existsSync(path)) return undefined;\n let database: Database | null = null;\n try {\n database = new Database(path, { readonly: true });\n const row = database.query(\n \"SELECT pid, version FROM gateway_lock WHERE id = 1\",\n ).get() as { pid: number; version: string | null } | null;\n if (!row || row.pid !== expectedPid) return undefined;\n return row.version;\n } catch {\n return undefined;\n } finally {\n database?.close();\n }\n}\n\nfunction readyTimeoutMs(env: NodeJS.ProcessEnv = process.env): number {\n const value = Number(env.SUPERTASK_GATEWAY_READY_TIMEOUT_MS ?? 30_000);\n return Number.isFinite(value) && value > 0 ? value : 30_000;\n}\n\nfunction waitForGatewayReady(\n pid: number,\n path = databasePath(),\n env: NodeJS.ProcessEnv = process.env,\n): boolean {\n const deadline = Date.now() + readyTimeoutMs(env);\n const sleeper = new Int32Array(new SharedArrayBuffer(4));\n while (Date.now() < deadline) {\n if (isGatewayReady(pid, path)) return true;\n Atomics.wait(sleeper, 0, 0, 100);\n }\n return isGatewayReady(pid, path);\n}\n\nexport function stopGatewayForMaintenance(): GatewayMaintenanceState {\n if (!isPm2Installed()) return { wasRunning: false };\n\n const proc = pm2JsonList().find((item) => item.name === PROCESS_NAME);\n const runtime = gatewayRuntimeFromProcess(proc);\n const managedCurrentDatabase = proc?.pm2_env?.status === \"online\"\n && typeof proc.pid === \"number\"\n && runtime !== null\n && scopesMatch(currentScope(), runtimeScope(runtime))\n && isGatewayReady(proc.pid, runtimeScope(runtime).databasePath);\n if (!managedCurrentDatabase) return { wasRunning: false };\n\n assertRuntimeCanControlPm2(runtime, proc);\n requirePm2Termination(\"stop\", \"pm2 stop Gateway for database maintenance\", runtime);\n return { wasRunning: true, env: runtime.env, cwd: runtime.cwd };\n}\n\nexport function restartGatewayAfterMaintenance(state: GatewayMaintenanceState): boolean {\n if (!state.wasRunning) return false;\n\n const env = state.env ?? process.env;\n const cwd = state.cwd ?? process.cwd();\n requirePm2([\"start\", PROCESS_NAME], \"pm2 restart Gateway after database maintenance\", { env });\n const started = pm2JsonList(env).find((item) => item.name === PROCESS_NAME);\n if (started?.pm2_env?.status !== \"online\") {\n throw new Error(\n `[supertask] Gateway 数据库维护后未恢复 online(状态:${started?.pm2_env?.status ?? \"missing\"})`,\n );\n }\n if (typeof started.pid !== \"number\" || !waitForGatewayReady(started.pid, databasePath(env, cwd), env)) {\n throw new Error(\"[supertask] Gateway 数据库维护后已 online,但未在限定时间内就绪;请查看 pm2 logs supertask-gateway\");\n }\n return true;\n}\n\nexport function withGatewayMaintenance<T>(\n keepStopped: boolean,\n operation: () => T,\n): GatewayMaintenanceResult<T> {\n return withManagementLock(() => {\n const state = stopGatewayForMaintenance();\n let result: T;\n try {\n result = operation();\n } catch (error) {\n if (state.wasRunning && !keepStopped) {\n try {\n restartGatewayAfterMaintenance(state);\n } catch (restartError) {\n const original = error instanceof Error ? error.message : String(error);\n const restart = restartError instanceof Error ? restartError.message : String(restartError);\n throw new Error(`${original};Gateway 自动恢复也失败:${restart}`);\n }\n }\n throw error;\n }\n\n let restarted = false;\n if (state.wasRunning && !keepStopped) {\n try {\n restarted = restartGatewayAfterMaintenance(state);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n throw new Error(`数据库维护已完成,但 Gateway 自动重启失败:${message}`);\n }\n }\n return {\n result,\n wasRunning: state.wasRunning,\n restarted,\n keptStopped: state.wasRunning && keepStopped,\n };\n });\n}\n\nfunction findBunPath(): string {\n const override = process.env.SUPERTASK_BUN_BIN;\n if (override) return override;\n try {\n const command = process.platform === \"win32\" ? \"where bun\" : \"which bun\";\n return execSync(command, { stdio: \"pipe\" }).toString().trim().split(\"\\n\")[0];\n } catch {\n return process.execPath;\n }\n}\n\nfunction pm2MaxMemoryRestart(env: NodeJS.ProcessEnv = process.env): string {\n const value = env.SUPERTASK_PM2_MAX_MEMORY ?? \"512M\";\n if (!/^\\d+(?:K|M|G)$/i.test(value)) {\n throw new Error(\"[supertask] SUPERTASK_PM2_MAX_MEMORY 必须使用 512M / 1G 这类格式\");\n }\n return value;\n}\n\nfunction gatewayKillTimeoutMs(runtime: GatewayRuntime): number {\n const shutdownGracePeriodMs = loadConfig(runtimeScope(runtime).configPath).worker.shutdownGracePeriodMs;\n const minimumKillTimeoutMs = shutdownGracePeriodMs + 15_000;\n const configuredValue = runtime.env.SUPERTASK_PM2_KILL_TIMEOUT_MS;\n if (configuredValue !== undefined) {\n const configuredKillTimeout = Number(configuredValue);\n if (!Number.isInteger(configuredKillTimeout) || configuredKillTimeout < minimumKillTimeoutMs) {\n throw new Error(\n `[supertask] SUPERTASK_PM2_KILL_TIMEOUT_MS 必须是至少 ${minimumKillTimeoutMs} 的整数`\n + `(worker shutdown grace ${shutdownGracePeriodMs}ms + 15000ms 收尾余量)`,\n );\n }\n return configuredKillTimeout;\n }\n return Math.max(runtime.killTimeoutMs ?? 0, minimumKillTimeoutMs);\n}\n\nfunction gatewayTerminationCommandTimeoutMs(runtime: GatewayRuntime): number {\n const effectiveKillTimeoutMs = Math.max(\n runtime.killTimeoutMs ?? 0,\n gatewayKillTimeoutMs(runtime),\n );\n const minimumCommandTimeoutMs = effectiveKillTimeoutMs + 5_000;\n const configuredValue = runtime.env.SUPERTASK_PM2_COMMAND_TIMEOUT_MS;\n if (configuredValue !== undefined) {\n const configuredTimeoutMs = Number(configuredValue);\n if (!Number.isInteger(configuredTimeoutMs) || configuredTimeoutMs < minimumCommandTimeoutMs) {\n throw new Error(\n `[supertask] SUPERTASK_PM2_COMMAND_TIMEOUT_MS 必须是至少 ${minimumCommandTimeoutMs} 的整数`\n + `(Gateway kill timeout ${effectiveKillTimeoutMs}ms + 5000ms PM2 收尾余量)`,\n );\n }\n return configuredTimeoutMs;\n }\n return Math.max(pm2CommandTimeoutMs(runtime.env), minimumCommandTimeoutMs);\n}\n\nfunction requirePm2Termination(\n command: \"stop\" | \"delete\",\n action: string,\n runtime: GatewayRuntime,\n): string {\n return requirePm2([command, PROCESS_NAME], action, {\n env: runtime.env,\n timeoutMs: gatewayTerminationCommandTimeoutMs(runtime),\n });\n}\n\nfunction pm2StartGateway(runtime = currentGatewayRuntime()): void {\n try {\n accessSync(runtime.bunPath, constants.X_OK);\n accessSync(runtime.gatewayEntry, constants.R_OK);\n if (!statSync(runtime.cwd).isDirectory()) throw new Error(\"cwd is not a directory\");\n } catch (error) {\n throw new Error(`[supertask] Gateway 目标运行时不可用: ${error instanceof Error ? error.message : String(error)}`);\n }\n const killTimeoutMs = gatewayKillTimeoutMs(runtime);\n requirePm2([\n \"start\",\n runtime.bunPath,\n \"--name\",\n PROCESS_NAME,\n \"--interpreter\",\n \"none\",\n \"--restart-delay\",\n \"5000\",\n \"--max-restarts\",\n \"30\",\n \"--max-memory-restart\",\n pm2MaxMemoryRestart(runtime.env),\n \"--kill-timeout\",\n String(killTimeoutMs),\n \"--cwd\",\n runtime.cwd,\n \"--\",\n runtime.gatewayEntry,\n ], \"pm2 start\", { env: runtime.env });\n const started = pm2JsonList(runtime.env).find((item) => item.name === PROCESS_NAME);\n if (started?.pm2_env?.status !== \"online\") {\n throw new Error(`[supertask] Gateway did not become online (status: ${started?.pm2_env?.status ?? \"missing\"})`);\n }\n const observedRuntime = gatewayRuntimeFromProcess(started);\n if (\n !observedRuntime\n || observedRuntime.gatewayEntry !== resolve(runtime.gatewayEntry)\n || observedRuntime.bunPath !== runtime.bunPath\n || observedRuntime.cwd !== resolve(runtime.cwd)\n || !scopesMatch(runtimeScope(observedRuntime), runtimeScope(runtime))\n ) {\n throw new Error(\"[supertask] PM2 online 记录与本次启动目标不一致,已拒绝接管\");\n }\n if (\n typeof started.pid !== \"number\"\n || !waitForGatewayReady(started.pid, runtimeScope(runtime).databasePath, runtime.env)\n ) {\n throw new Error(\"[supertask] Gateway 进程 online,但未在限定时间内就绪;请查看 pm2 logs supertask-gateway\");\n }\n}\n\nfunction assertRuntimeCanControlPm2(runtime: GatewayRuntime | null, existing?: Pm2Process): void {\n if (!existing) return;\n if (!runtime) {\n throw new Error(\n \"[supertask] 无法完整验证已有 Gateway 的入口、Bun 和 cwd,已拒绝删除现有进程\",\n );\n }\n const probe = pm2Exec([\"--version\"], { env: runtime.env });\n if (!probe.ok) {\n throw new Error(\n `[supertask] 保存的 Gateway 运行环境无法执行 pm2,已拒绝删除现有进程;请先修复 PATH 或 SUPERTASK_PM2_BIN: ${probe.output || \"pm2 unavailable\"}`,\n );\n }\n const observed = pm2JsonList(runtime.env).find((item) => item.name === PROCESS_NAME);\n const observedRuntime = gatewayRuntimeFromProcess(observed);\n if (\n !observed\n || observed.pid !== existing.pid\n || !observedRuntime\n || observedRuntime.gatewayEntry !== runtime.gatewayEntry\n || observedRuntime.bunPath !== runtime.bunPath\n || observedRuntime.cwd !== runtime.cwd\n ) {\n throw new Error(\"[supertask] 保存的 PM2 环境无法重现同一 Gateway 记录,已拒绝删除现有进程\");\n }\n}\n\nfunction savePm2State(env: NodeJS.ProcessEnv = process.env): void {\n requirePm2([\"save\"], \"pm2 save\", { env });\n}\n\nfunction managementLockPath(\n env: NodeJS.ProcessEnv = process.env,\n cwd = process.cwd(),\n): string {\n const override = env.SUPERTASK_PM2_MANAGEMENT_LOCK;\n if (override) return runtimePath(override, cwd);\n return join(runtimeScope({ env, cwd }).pm2Home, \"supertask-gateway.manage.sqlite\");\n}\n\nfunction canonicalManagementLockPath(\n env: NodeJS.ProcessEnv = process.env,\n cwd = process.cwd(),\n): string {\n const home = runtimeHome(env);\n const pm2Home = env.PM2_HOME\n ? runtimePath(env.PM2_HOME, cwd)\n : join(home, \".pm2\");\n return join(pm2Home, \"supertask-gateway.manage.sqlite\");\n}\n\nfunction addLegacyManagementLock(\n paths: Set<string>,\n env: Record<string, unknown> | undefined,\n cwd: string,\n): void {\n const value = env?.SUPERTASK_PM2_MANAGEMENT_LOCK;\n if (typeof value === \"string\" && value.length > 0) paths.add(runtimePath(value, cwd));\n}\n\nfunction savedManagementLockPaths(): string[] {\n const canonical = canonicalManagementLockPath();\n const legacy = new Set<string>();\n addLegacyManagementLock(legacy, process.env, process.cwd());\n\n const pm2Home = currentScope().pm2Home;\n try {\n const dump = JSON.parse(readFileSync(join(pm2Home, \"dump.pm2\"), \"utf8\")) as unknown;\n if (Array.isArray(dump)) {\n const gateway = (dump as Pm2Process[]).find((item) => item.name === PROCESS_NAME);\n const cwd = gateway?.pm2_env?.pm_cwd;\n if (typeof cwd === \"string\") {\n addLegacyManagementLock(\n legacy,\n gateway?.pm2_env?.env ?? gateway?.env,\n cwd,\n );\n }\n }\n } catch {}\n\n if (process.platform === \"darwin\") {\n try {\n const configured = plistValue(\n readFileSync(launchAgentPath(), \"utf8\"),\n \"SUPERTASK_PM2_MANAGEMENT_LOCK\",\n );\n if (configured) legacy.add(resolve(configured));\n } catch {}\n }\n\n if (isPm2Installed()) {\n const gateway = pm2JsonList().find((item) => item.name === PROCESS_NAME);\n const cwd = gateway?.pm2_env?.pm_cwd;\n if (typeof cwd === \"string\") {\n addLegacyManagementLock(\n legacy,\n gateway?.pm2_env?.env ?? gateway?.env,\n cwd,\n );\n }\n }\n\n return [\n canonical,\n ...[...legacy].filter((path) => path !== canonical).sort(),\n ];\n}\n\nfunction withManagementLocks<T>(\n paths: string[],\n timeoutMs: number,\n action: () => T,\n index = 0,\n): T {\n const path = paths[index];\n if (!path) return action();\n return withExclusiveManagementLock(\n path,\n timeoutMs,\n () => withManagementLocks(paths, timeoutMs, action, index + 1),\n );\n}\n\nfunction assertMacLaunchAgentPm2HomeMatchesCurrent(): void {\n if (process.platform !== \"darwin\") return;\n try {\n const configuredPm2Home = plistValue(\n readFileSync(launchAgentPath(), \"utf8\"),\n \"PM2_HOME\",\n );\n if (!configuredPm2Home) return;\n const installedPm2Home = resolve(configuredPm2Home);\n const activePm2Home = currentScope().pm2Home;\n if (installedPm2Home !== activePm2Home) {\n throw new Error(\n `[supertask] 已安装的 macOS LaunchAgent 使用 PM2_HOME=${installedPm2Home},`\n + `当前 CLI 使用 ${activePm2Home};为避免两个 PM2 daemon 同时管理 Gateway,已拒绝修改。`\n + `请使用 PM2_HOME=${installedPm2Home} 重新执行命令`,\n );\n }\n } catch (error) {\n if (error instanceof Error && error.message.startsWith(\"[supertask] 已安装的 macOS LaunchAgent\")) {\n throw error;\n }\n if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") throw error;\n }\n}\n\nfunction withManagementLock<T>(action: () => T): T {\n const paths = savedManagementLockPaths();\n const configuredTimeout = Number(process.env.SUPERTASK_PM2_MANAGEMENT_LOCK_TIMEOUT_MS ?? 15_000);\n const timeoutMs = Number.isFinite(configuredTimeout) && configuredTimeout > 0\n ? configuredTimeout\n : 15_000;\n try {\n return withManagementLocks(paths, timeoutMs, () => {\n assertMacLaunchAgentPm2HomeMatchesCurrent();\n return action();\n });\n } catch (error) {\n if (error instanceof ManagementLockBusyError) {\n throw new Error(\"[supertask] 另一个 Gateway 管理操作仍在进行,已拒绝并发修改 PM2 状态\");\n }\n throw error;\n }\n}\n\nexport function install(): void {\n return withManagementLock(installUnlocked);\n}\n\nfunction installUnlocked(): void {\n if (!isPm2Installed() && !installPm2()) {\n throw new Error(\"[supertask] Failed to install pm2. Please install it manually: npm install -g pm2\");\n }\n\n const existing = pm2JsonList().find((item) => item.name === PROCESS_NAME);\n const oldRuntime = gatewayRuntimeFromProcess(existing);\n const targetRuntime = oldRuntime\n ? refreshGatewayExecutionEnvironment(oldRuntime, resolveGatewayEntry())\n : currentGatewayRuntime();\n const before = getRunningVersion(oldRuntime?.env ?? process.env, oldRuntime?.cwd);\n if (oldRuntime && !scopesMatch(currentScope(), runtimeScope(oldRuntime))) {\n throw new Error(\"[supertask] 当前 CLI 与 PM2 Gateway 的数据库/配置/OpenCode 运行作用域不一致,已拒绝覆盖\");\n }\n assertRuntimeCanControlPm2(oldRuntime, existing);\n gatewayKillTimeoutMs(targetRuntime);\n gatewayTerminationCommandTimeoutMs(targetRuntime);\n assertOpenCodeRuntime(targetRuntime);\n if (existing) requirePm2Termination(\"delete\", \"pm2 delete existing Gateway\", oldRuntime!);\n\n const version = getPackageVersion();\n try {\n pm2StartGateway(targetRuntime);\n savePm2State(targetRuntime.env);\n writeRunningVersion(version, targetRuntime.env, targetRuntime.cwd);\n } catch (error) {\n const failed = pm2JsonList(targetRuntime.env).find((item) => item.name === PROCESS_NAME);\n if (failed) {\n requirePm2Termination(\n \"delete\",\n \"pm2 delete failed Gateway\",\n gatewayRuntimeFromProcess(failed) ?? targetRuntime,\n );\n }\n if (oldRuntime) {\n try {\n pm2StartGateway(oldRuntime);\n savePm2State(oldRuntime.env);\n if (before) writeRunningVersion(before, oldRuntime.env, oldRuntime.cwd);\n } catch (rollbackError) {\n const original = error instanceof Error ? error.message : String(error);\n const rollback = rollbackError instanceof Error ? rollbackError.message : String(rollbackError);\n throw new Error(`${original}; 旧 Gateway 回滚也失败: ${rollback}`);\n }\n const message = error instanceof Error ? error.message : String(error);\n throw new Error(`${message}; 已回滚到旧 Gateway`);\n }\n throw error;\n }\n if (!ensurePm2LogRotation(targetRuntime.env)) {\n console.warn(\"[supertask] pm2-logrotate 安装或配置失败;Gateway 已运行,但请执行 `supertask doctor` 检查日志治理。\");\n }\n if (process.platform === \"darwin\") {\n const path = installMacLaunchAgent(targetRuntime);\n console.log(`[supertask] macOS LaunchAgent installed: ${path}`);\n } else {\n const startup = pm2Exec([\"startup\"], { env: targetRuntime.env });\n if (startup.output) console.log(startup.output);\n if (process.platform === \"linux\" && (!startup.ok || !isLinuxStartupConfigured(targetRuntime.env, targetRuntime.cwd, targetRuntime))) {\n throw new Error(\"[supertask] pm2 startup 未完成或 systemd 自启未生效;Gateway 当前已运行,但安装未达到可重启恢复标准\");\n }\n }\n\n console.log(\"[supertask] Gateway installed and running.\");\n console.log(\"[supertask] Manage with: pm2 status / pm2 logs supertask-gateway\");\n}\n\nexport function uninstall(): void {\n return withManagementLock(uninstallUnlocked);\n}\n\nfunction removeMacLaunchAgent(): void {\n if (typeof process.getuid !== \"function\") return;\n const path = launchAgentPath();\n const domain = `gui/${process.getuid()}`;\n const loaded = spawnSync(\n launchctlBin(),\n [\"print\", `${domain}/${MAC_LAUNCH_AGENT_LABEL}`],\n {\n stdio: \"ignore\",\n timeout: pm2CommandTimeoutMs(),\n killSignal: \"SIGKILL\",\n },\n );\n if (loaded.error) {\n throw new Error(`[supertask] 无法确认 macOS LaunchAgent 状态: ${loaded.error.message}`);\n }\n if (loaded.status === 0) {\n const removed = spawnSync(\n launchctlBin(),\n [\"bootout\", `${domain}/${MAC_LAUNCH_AGENT_LABEL}`],\n {\n encoding: \"utf8\",\n timeout: pm2CommandTimeoutMs(),\n killSignal: \"SIGKILL\",\n },\n );\n if (removed.status !== 0 || removed.error) {\n const output = `${removed.stdout ?? \"\"}${removed.stderr ?? \"\"}`.trim();\n throw new Error(\n `[supertask] Gateway 已从 PM2 与 dump 中移除,但 macOS LaunchAgent 停止失败: `\n + (output || removed.error?.message || `退出码 ${removed.status}`),\n );\n }\n }\n rmSync(path, { force: true });\n}\n\nfunction uninstallUnlocked(): void {\n if (!isPm2Installed()) throw new Error(\"[supertask] pm2 is not installed\");\n const existing = pm2JsonList().find((item) => item.name === PROCESS_NAME);\n const runtime = gatewayRuntimeFromProcess(existing);\n assertRuntimeCanControlPm2(runtime, existing);\n if (existing) requirePm2Termination(\"delete\", \"pm2 delete Gateway\", runtime!);\n savePm2State(runtime?.env);\n if (process.platform === \"darwin\") removeMacLaunchAgent();\n console.log(\"[supertask] Gateway removed from pm2. Other pm2 startup entries were preserved.\");\n}\n\nexport function upgrade(target?: {\n gatewayEntry: string;\n version: string;\n}): { before: string | null; after: string; restarted: boolean } {\n return withManagementLock(() => upgradeUnlocked(target));\n}\n\nfunction upgradeUnlocked(target?: {\n gatewayEntry: string;\n version: string;\n}): { before: string | null; after: string; restarted: boolean } {\n if (!isPm2Installed()) {\n throw new Error(\"[supertask] pm2 is not installed. Run `supertask install` first.\");\n }\n\n const existing = pm2JsonList().find((item) => item.name === PROCESS_NAME);\n const oldRuntime = gatewayRuntimeFromProcess(existing)\n ?? (process.env.SUPERTASK_GATEWAY_ENTRY ? currentGatewayRuntime(resolveGatewayEntry()) : null);\n const before = getRunningVersion(oldRuntime?.env ?? process.env, oldRuntime?.cwd);\n const currentVersion = target?.version ?? getPackageVersion();\n const targetRuntime = oldRuntime\n ? refreshGatewayExecutionEnvironment(\n oldRuntime,\n target?.gatewayEntry ?? oldRuntime.gatewayEntry,\n )\n : currentGatewayRuntime(target?.gatewayEntry ?? resolveGatewayEntry());\n assertRuntimeCanControlPm2(oldRuntime, existing);\n gatewayKillTimeoutMs(targetRuntime);\n gatewayTerminationCommandTimeoutMs(targetRuntime);\n assertOpenCodeRuntime(targetRuntime);\n if (existing) requirePm2Termination(\"delete\", \"pm2 delete old Gateway\", oldRuntime!);\n\n try {\n pm2StartGateway(targetRuntime);\n savePm2State(targetRuntime.env);\n writeRunningVersion(currentVersion, targetRuntime.env, targetRuntime.cwd);\n return { before, after: currentVersion, restarted: true };\n } catch (error) {\n const failed = pm2JsonList(targetRuntime.env).find((item) => item.name === PROCESS_NAME);\n if (failed) {\n requirePm2Termination(\n \"delete\",\n \"pm2 delete failed Gateway\",\n gatewayRuntimeFromProcess(failed) ?? targetRuntime,\n );\n }\n if (!oldRuntime) throw error;\n try {\n pm2StartGateway(oldRuntime);\n savePm2State(oldRuntime.env);\n if (before) writeRunningVersion(before, oldRuntime.env, oldRuntime.cwd);\n } catch (rollbackError) {\n const original = error instanceof Error ? error.message : String(error);\n const rollback = rollbackError instanceof Error ? rollbackError.message : String(rollbackError);\n throw new Error(`${original}; 旧 Gateway 回滚也失败: ${rollback}`);\n }\n const message = error instanceof Error ? error.message : String(error);\n throw new Error(`${message}; 已回滚到旧 Gateway`);\n }\n}\n\nexport function ensureGateway(): EnsureGatewayResult {\n return withManagementLock(ensureGatewayUnlocked);\n}\n\nfunction ensureGatewayUnlocked(): EnsureGatewayResult {\n if (!isPm2Installed()) {\n return { ok: false, reason: \"pm2-not-installed\" };\n }\n\n const currentVersion = getPackageVersion();\n const processList = pm2JsonList();\n const existing = processList.find((item) => item.name === PROCESS_NAME);\n const oldRuntime = gatewayRuntimeFromProcess(existing);\n if (oldRuntime && !scopesMatch(currentScope(), runtimeScope(oldRuntime))) {\n throw new Error(\"[supertask] 当前 OpenCode/CLI 与 PM2 Gateway 的数据库、配置或 OpenCode 可执行文件作用域不一致,已拒绝继续写入\");\n }\n assertRuntimeCanControlPm2(oldRuntime, existing);\n const lockedVersion = existing && typeof existing.pid === \"number\" && oldRuntime\n ? gatewayVersionFromLock(existing.pid, runtimeScope(oldRuntime).databasePath)\n : undefined;\n if (\n existing?.pm2_env?.status === \"online\"\n && typeof existing.pid === \"number\"\n && oldRuntime !== null\n && isGatewayReady(existing.pid, runtimeScope(oldRuntime).databasePath)\n && (\n lockedVersion === currentVersion\n || (\n lockedVersion === undefined\n && getRunningVersion(oldRuntime.env, oldRuntime.cwd) === currentVersion\n )\n )\n ) {\n return { ok: true, action: \"already-running\" };\n }\n\n const targetRuntime = oldRuntime\n ? { ...oldRuntime, gatewayEntry: resolve(resolveGatewayEntry()) }\n : currentGatewayRuntime();\n const before = getRunningVersion(oldRuntime?.env ?? process.env, oldRuntime?.cwd);\n\n gatewayKillTimeoutMs(targetRuntime);\n gatewayTerminationCommandTimeoutMs(targetRuntime);\n assertOpenCodeRuntime(targetRuntime);\n if (existing) requirePm2Termination(\"delete\", \"pm2 delete stale Gateway\", oldRuntime!);\n try {\n pm2StartGateway(targetRuntime);\n savePm2State(targetRuntime.env);\n writeRunningVersion(currentVersion, targetRuntime.env, targetRuntime.cwd);\n } catch (error) {\n const failed = pm2JsonList(targetRuntime.env).find((item) => item.name === PROCESS_NAME);\n if (failed) {\n requirePm2Termination(\n \"delete\",\n \"pm2 delete failed Gateway\",\n gatewayRuntimeFromProcess(failed) ?? targetRuntime,\n );\n }\n if (oldRuntime) {\n try {\n pm2StartGateway(oldRuntime);\n savePm2State(oldRuntime.env);\n if (before) writeRunningVersion(before, oldRuntime.env, oldRuntime.cwd);\n } catch (rollbackError) {\n const original = error instanceof Error ? error.message : String(error);\n const rollback = rollbackError instanceof Error ? rollbackError.message : String(rollbackError);\n throw new Error(`${original}; 旧 Gateway 回滚也失败: ${rollback}`);\n }\n const message = error instanceof Error ? error.message : String(error);\n throw new Error(`${message}; 已回滚到旧 Gateway`);\n }\n throw error;\n }\n return { ok: true, action: existing ? \"restarted\" : \"started\" };\n}\n","import { existsSync, readFileSync } from 'fs';\nimport { homedir } from 'os';\nimport { join } from 'path';\n\nexport interface GatewayConfig {\n configVersion: 2;\n worker: {\n maxConcurrency: number;\n pollIntervalMs: number;\n heartbeatIntervalMs: number;\n taskTimeoutMs: number;\n shutdownGracePeriodMs: number;\n };\n scheduler: {\n enabled: boolean;\n checkIntervalMs: number;\n };\n watchdog: {\n heartbeatTimeoutMs: number;\n checkIntervalMs: number;\n cleanupIntervalMs: number;\n retentionDays: number;\n };\n dashboard: {\n enabled: boolean;\n port: number;\n };\n}\n\nconst DEFAULT_CONFIG: GatewayConfig = {\n configVersion: 2,\n worker: {\n maxConcurrency: 2,\n pollIntervalMs: 1000,\n heartbeatIntervalMs: 30_000,\n taskTimeoutMs: 1_800_000,\n shutdownGracePeriodMs: 30_000,\n },\n scheduler: {\n enabled: true,\n checkIntervalMs: 1000,\n },\n watchdog: {\n heartbeatTimeoutMs: 600_000,\n checkIntervalMs: 60_000,\n cleanupIntervalMs: 86_400_000,\n retentionDays: 30,\n },\n dashboard: {\n enabled: true,\n port: 4680,\n },\n};\n\nconst DEFAULT_CONFIG_PATH = join(homedir(), '.config/opencode/supertask.json');\n\nexport function getConfigPath(): string {\n return process.env.SUPERTASK_CONFIG_PATH ?? DEFAULT_CONFIG_PATH;\n}\n\nfunction objectAt(value: unknown, path: string): Record<string, unknown> {\n if (value === undefined) return {};\n if (value === null || typeof value !== 'object' || Array.isArray(value)) {\n throw new Error(`${path} 必须是对象`);\n }\n return value as Record<string, unknown>;\n}\n\nfunction integerAt(\n source: Record<string, unknown>,\n key: string,\n fallback: number,\n min: number,\n max: number,\n path: string,\n): number {\n const value = source[key];\n if (value === undefined) return fallback;\n if (typeof value !== 'number' || !Number.isInteger(value) || value < min || value > max) {\n throw new Error(`${path}.${key} 必须是 ${min} 到 ${max} 之间的整数`);\n }\n return value;\n}\n\nfunction booleanAt(\n source: Record<string, unknown>,\n key: string,\n fallback: boolean,\n path: string,\n): boolean {\n const value = source[key];\n if (value === undefined) return fallback;\n if (typeof value !== 'boolean') throw new Error(`${path}.${key} 必须是布尔值`);\n return value;\n}\n\nexport function validateConfig(input: unknown): GatewayConfig {\n const root = objectAt(input, 'config');\n const version = root.configVersion ?? 1;\n if (version !== 1 && version !== 2) {\n throw new Error('config.configVersion 只支持 1 或 2');\n }\n\n const worker = objectAt(root.worker, 'worker');\n const scheduler = objectAt(root.scheduler, 'scheduler');\n const watchdog = objectAt(root.watchdog, 'watchdog');\n const dashboard = objectAt(root.dashboard, 'dashboard');\n\n const heartbeatIntervalMs = integerAt(worker, 'heartbeatIntervalMs', DEFAULT_CONFIG.worker.heartbeatIntervalMs, 1000, 3_600_000, 'worker');\n const heartbeatTimeoutMs = integerAt(watchdog, 'heartbeatTimeoutMs', DEFAULT_CONFIG.watchdog.heartbeatTimeoutMs, 1000, 86_400_000, 'watchdog');\n\n let checkIntervalMs: number;\n let cleanupIntervalMs: number;\n if (version === 1 && watchdog.checkIntervalMs === undefined && watchdog.cleanupIntervalMs !== undefined) {\n checkIntervalMs = integerAt(watchdog, 'cleanupIntervalMs', DEFAULT_CONFIG.watchdog.checkIntervalMs, 1000, 3_600_000, 'watchdog');\n cleanupIntervalMs = DEFAULT_CONFIG.watchdog.cleanupIntervalMs;\n } else {\n checkIntervalMs = integerAt(watchdog, 'checkIntervalMs', DEFAULT_CONFIG.watchdog.checkIntervalMs, 1000, 3_600_000, 'watchdog');\n cleanupIntervalMs = integerAt(watchdog, 'cleanupIntervalMs', DEFAULT_CONFIG.watchdog.cleanupIntervalMs, 60_000, 604_800_000, 'watchdog');\n }\n\n if (heartbeatIntervalMs >= heartbeatTimeoutMs) {\n throw new Error('worker.heartbeatIntervalMs 必须小于 watchdog.heartbeatTimeoutMs');\n }\n if (checkIntervalMs > heartbeatTimeoutMs) {\n throw new Error('watchdog.checkIntervalMs 不能大于 watchdog.heartbeatTimeoutMs');\n }\n\n return {\n configVersion: 2,\n worker: {\n maxConcurrency: integerAt(worker, 'maxConcurrency', DEFAULT_CONFIG.worker.maxConcurrency, 1, 64, 'worker'),\n pollIntervalMs: integerAt(worker, 'pollIntervalMs', DEFAULT_CONFIG.worker.pollIntervalMs, 50, 60_000, 'worker'),\n heartbeatIntervalMs,\n taskTimeoutMs: integerAt(worker, 'taskTimeoutMs', DEFAULT_CONFIG.worker.taskTimeoutMs, 1000, 604_800_000, 'worker'),\n shutdownGracePeriodMs: integerAt(worker, 'shutdownGracePeriodMs', DEFAULT_CONFIG.worker.shutdownGracePeriodMs, 0, 3_600_000, 'worker'),\n },\n scheduler: {\n enabled: booleanAt(scheduler, 'enabled', DEFAULT_CONFIG.scheduler.enabled, 'scheduler'),\n checkIntervalMs: integerAt(scheduler, 'checkIntervalMs', DEFAULT_CONFIG.scheduler.checkIntervalMs, 100, 60_000, 'scheduler'),\n },\n watchdog: {\n heartbeatTimeoutMs,\n checkIntervalMs,\n cleanupIntervalMs,\n retentionDays: integerAt(watchdog, 'retentionDays', DEFAULT_CONFIG.watchdog.retentionDays, 1, 3650, 'watchdog'),\n },\n dashboard: {\n enabled: booleanAt(dashboard, 'enabled', DEFAULT_CONFIG.dashboard.enabled, 'dashboard'),\n port: integerAt(dashboard, 'port', DEFAULT_CONFIG.dashboard.port, 1, 65_535, 'dashboard'),\n },\n };\n}\n\nexport function loadConfig(path = getConfigPath()): GatewayConfig {\n if (!existsSync(path)) return validateConfig({ configVersion: 2 });\n\n try {\n return validateConfig(JSON.parse(readFileSync(path, 'utf-8')) as unknown);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n throw new Error(`无法读取配置 ${path}: ${message}`);\n }\n}\n\nexport { DEFAULT_CONFIG, DEFAULT_CONFIG_PATH };\n","import { Database } from 'bun:sqlite';\nimport { mkdirSync } from 'fs';\nimport { dirname } from 'path';\n\nexport class ManagementLockBusyError extends Error {\n constructor() {\n super('Gateway management lock is busy');\n this.name = 'ManagementLockBusyError';\n }\n}\n\nfunction isBusyError(error: unknown): boolean {\n if (!(error instanceof Error)) return false;\n const code = (error as Error & { code?: string }).code;\n return code === 'SQLITE_BUSY' || /database is locked/i.test(error.message);\n}\n\n/**\n * Serializes PM2 lifecycle changes with an OS-backed SQLite write lock.\n * The transaction is held for the complete action and is released by SQLite\n * automatically if the owning process exits or is killed.\n */\nexport function withExclusiveManagementLock<T>(\n path: string,\n timeoutMs: number,\n action: () => T,\n): T {\n mkdirSync(dirname(path), { recursive: true });\n const database = new Database(path, { create: true });\n const normalizedTimeout = Number.isFinite(timeoutMs) && timeoutMs >= 0\n ? Math.floor(timeoutMs)\n : 0;\n database.exec(`PRAGMA busy_timeout = ${normalizedTimeout}`);\n\n try {\n try {\n database.exec('BEGIN IMMEDIATE');\n } catch (error) {\n if (isBusyError(error)) throw new ManagementLockBusyError();\n throw error;\n }\n\n try {\n const result = action();\n database.exec('COMMIT');\n return result;\n } catch (error) {\n try {\n database.exec('ROLLBACK');\n } catch {}\n throw error;\n }\n } finally {\n database.close();\n }\n}\n","import { getGatewayDiagnostic } from './pm2';\n\ntry {\n console.log(JSON.stringify(getGatewayDiagnostic()));\n} catch (error) {\n console.error(error instanceof Error ? error.message : String(error));\n process.exitCode = 1;\n}\n"],"mappings":"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","names":["homedir","join","Database","homedir","join","join","join","join","join","join","Database","join"]}
|