@sfmc-bds/cli 0.2.5 → 0.3.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 (41) hide show
  1. package/dist/command-surface.d.ts.map +1 -1
  2. package/dist/command-surface.js +5 -1
  3. package/dist/command-surface.js.map +2 -2
  4. package/dist/commands.d.ts.map +1 -1
  5. package/dist/commands.js +20 -79
  6. package/dist/commands.js.map +2 -2
  7. package/dist/help-text.d.ts.map +1 -1
  8. package/dist/help-text.js +2 -0
  9. package/dist/help-text.js.map +2 -2
  10. package/dist/i18n/locales/en.d.ts +33 -0
  11. package/dist/i18n/locales/en.d.ts.map +1 -1
  12. package/dist/i18n/locales/en.js +33 -0
  13. package/dist/i18n/locales/en.js.map +2 -2
  14. package/dist/i18n/locales/zh-CN.d.ts.map +1 -1
  15. package/dist/i18n/locales/zh-CN.js +33 -0
  16. package/dist/i18n/locales/zh-CN.js.map +2 -2
  17. package/dist/module-commands.d.ts.map +1 -1
  18. package/dist/module-commands.js +8 -0
  19. package/dist/module-commands.js.map +2 -2
  20. package/dist/module-update/index.d.ts +18 -0
  21. package/dist/module-update/index.d.ts.map +1 -0
  22. package/dist/module-update/index.js +223 -0
  23. package/dist/module-update/index.js.map +7 -0
  24. package/dist/repl.d.ts.map +1 -1
  25. package/dist/repl.js +11 -0
  26. package/dist/repl.js.map +2 -2
  27. package/dist/services.d.ts +29 -1
  28. package/dist/services.d.ts.map +1 -1
  29. package/dist/services.js +79 -1
  30. package/dist/services.js.map +2 -2
  31. package/dist/wizard.d.ts.map +1 -1
  32. package/dist/wizard.js +2 -0
  33. package/dist/wizard.js.map +2 -2
  34. package/package.json +1 -1
  35. package/scripts/module-install/fetch-module.mjs +164 -76
  36. package/scripts/module-install/lib/module-update-config.mjs +83 -0
  37. package/scripts/module-install/lib/module-update.mjs +507 -0
  38. package/scripts/module-install/lib/pins.mjs +436 -0
  39. package/scripts/module-install/lib/registry-cache.mjs +83 -0
  40. package/scripts/module-install/lib/semver.mjs +124 -0
  41. package/scripts/module-install/test/module-update.test.mjs +182 -0
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/services.ts"],
4
- "sourcesContent": ["/**\n * services.ts \u2014 CLI \u8FDB\u7A0B\u7F16\u6392\u4E0E\u670D\u52A1\u751F\u547D\u5468\u671F\u7BA1\u7406\n *\n * \u6838\u5FC3\u7BA1\u7406\u5BF9\u8C61\uFF08ServiceName\uFF09\uFF1A\n * - `bds`\uFF1AMinecraft \u57FA\u5CA9\u7248\u670D\u52A1\u7AEF\uFF08\u652F\u6301 stdin \u7BA1\u9053\u6307\u4EE4\u4EA4\u4E92\u4E0E\u4F18\u96C5\u505C\u670D\uFF09\n * - `db`\uFF1Adb-server SQLite HTTP \u670D\u52A1\uFF08\u7AEF\u53E3\u5065\u5EB7\u68C0\u67E5\u4E0E loopback \u63A2\u6D3B\uFF09\n * - `tunnel`\uFF1A\u4E91\u7AEF QQ Webhook \u5230\u672C\u673A db-server \u7684 SSH \u53CD\u5411\u96A7\u9053\n * - `qq`\uFF1Aqq-bridge \u6D88\u606F\u7F51\u6865\u670D\u52A1\uFF08\u652F\u6301\u5B98\u65B9 Bot \u4E0E LLBot \u53CC\u540E\u7AEF\uFF09\n * - `llbot`\uFF1ALLBot \u72EC\u7ACB\u673A\u5668\u4EBA\u8FDB\u7A0B\uFF08\u6761\u4EF6\u542F\u52A8\uFF09\n *\n * \u6838\u5FC3\u80FD\u529B\uFF1A\n * - \u8FDB\u7A0B\u751F\u547D\u5468\u671F\uFF1A\u6309\u4F9D\u8D56\u6B21\u5E8F\u7F16\u6392\u670D\u52A1\u542F\u52A8\uFF08db \u2192 qq \u2192 bds\uFF09\u3001\u4F18\u96C5\u505C\u6B62\u4E0E\u5F02\u5E38\u81EA\u52A8\u62C9\u8D77\n * - \u591A\u6E90\u63A2\u6D3B\u611F\u77E5\uFF1A\u81EA\u52A8\u63A2\u6D4B\u6258\u7BA1\u8FDB\u7A0B\u4E0E\u5916\u90E8\u72EC\u7ACB\u8FDB\u7A0B\u72B6\u6001\n * - \u65E5\u5FD7\u6D41\u7EDF\u4E00\u805A\u5408\uFF1A\u6355\u83B7\u5E76\u5F52\u4E00\u5316\u5404\u670D\u52A1\u7684 stdout / stderr \u6570\u636E\u6D41\n */\n\nimport type { BdsUpdaterConfig, DBConfig, QQBackend, QQBridgeConfig } from \"@sfmc-bds/sdk/node/config\";\nimport {\n DEFAULT_BDS_UPDATER_CONFIG,\n DEFAULT_DB_CONFIG,\n DEFAULT_QQ_CONFIG,\n ensureCoreConfigs,\n loadEnsuredConfig,\n qqRuntimeStatusPath,\n readJson,\n type QqRuntimeStatus,\n} from \"@sfmc-bds/sdk/node/config\";\n\nimport { bdsExePath, bdsSpawnEnvExtra, ensureBdsExecutable } from \"@sfmc-bds/bds-tools/host-platform\";\nimport {\n clearBdsPidFile,\n isProcessAlive,\n probeBdsStatus,\n readBdsPidFile,\n writeBdsPidFile,\n} from \"@sfmc-bds/bds-tools/process-probe\";\nimport { postBdsLifecycleEvent } from \"@sfmc-bds/bds-tools/qq-events-notify\";\nimport { spawn, type ChildProcess } from \"node:child_process\";\nimport { EventEmitter } from \"node:events\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { isDaemonServer } from \"./daemon/role.js\";\nimport { onRemoteServiceStateChange } from \"./daemon/client.js\";\nimport { t } from \"./i18n/index.js\";\nimport { resolveLlbotLaunch } from \"./llbot-launch.js\";\nimport { inferLevel, pushLog as pushUnifiedLog } from \"./logs.js\";\nimport { findNodeServicePids } from \"./node-service-probe.js\";\nimport { ensurePackUpdateConfigFile } from \"./pack-update/index.js\";\nimport { recordBdsVersion } from \"./bds-runtime-version.js\";\nimport { reportBdsPlayerSession } from \"./player-session.js\";\nimport { startModuleSidecars, stopModuleSidecars } from \"./module-sidecars.js\";\nimport { ROOT, spawnService, type ServiceId } from \"./runtime.js\";\n\nexport { ROOT } from \"./runtime.js\";\n\nexport interface LogLine {\n time: Date;\n text: string;\n stream: \"stdout\" | \"stderr\";\n}\n\n/** \u5B50\u8FDB\u7A0B\u8F93\u51FA\u5206\u884C\uFF1A\u8FC7\u6EE4\u7A7A\u4E32\u4EE5\u53CA Windows CRLF \u62C6\u5206\u540E\u6B8B\u7559\u7684\u7EAF\u7A7A\u767D\u884C\u3002 */\nexport function nonBlankOutputLines(text: string): string[] {\n return text.split(/\\r?\\n/).filter((line) => line.trim().length > 0);\n}\n\nexport type ServiceName = \"bds\" | \"db\" | \"tunnel\" | \"qq\" | \"llbot\";\nexport const SERVICE_NAMES: ServiceName[] = [\"bds\", \"db\", \"tunnel\", \"qq\", \"llbot\"];\n\n/** \u5355\u670D\u52A1 start \u7ED3\u679C\uFF1Aoptional \u670D\u52A1 validate \u5931\u8D25\u8BB0\u4E3A skipped\uFF0C\u4E0D\u629B\u9519 */\nexport type StartOutcome = { status: \"started\" } | { status: \"already\" } | { status: \"skipped\"; reason: string };\n\nexport interface StartAllResult {\n started: ServiceName[];\n skipped: Array<{ name: ServiceName; reason: string }>;\n failed: Array<{ name: ServiceName; reason: string }>;\n}\n\nexport interface ServiceStatus {\n name: ServiceName;\n title: string;\n running: boolean;\n pid: number;\n uptime: string;\n ownership?: \"managed\" | \"external\";\n}\n\n/** \u5F53\u524D db \u5065\u5EB7\u63A2\u6D4B\u7AEF\u53E3\uFF08\u4E0E createServices \u540C\u6B65\uFF09 */\nlet dbHealthPort = 3001;\n/** \u5F53\u524D QQ \u540E\u7AEF\uFF08\u4E0E createServices \u540C\u6B65\uFF0C\u4F9B Tab/\u7A97\u6807\u9898\uFF09 */\nlet qqBackendMode: QQBackend = \"official\";\n\nexport function getQqBackendMode(): QQBackend {\n return qqBackendMode;\n}\n\nasync function probeDbHealth(port: number): Promise<boolean> {\n try {\n const res = await fetch(`http://127.0.0.1:${port}/api/health`, { signal: AbortSignal.timeout(2000) });\n return res.ok;\n } catch {\n return false;\n }\n}\n\n/** \u8BFB `.sfmc/qq.runtime.json` + pid \u5B58\u6D3B\uFF0C\u63A2\u6D4B\u5916\u90E8/\u672C\u673A qq-bridge */\nasync function probeQqRuntime(): Promise<{ alive: boolean; pid: number }> {\n const status = readJson<QqRuntimeStatus>(qqRuntimeStatusPath(ROOT));\n if (!status?.pid || status.pid <= 0) return { alive: false, pid: 0 };\n if (!(await isProcessAlive(status.pid))) return { alive: false, pid: 0 };\n return { alive: true, pid: status.pid };\n}\n\nconst tunnelRuntimePath = path.join(ROOT, \".sfmc\", \"tunnel.runtime.json\");\n\nasync function probeTunnelRuntime(): Promise<number> {\n const pid = readJson<{ pid?: number }>(tunnelRuntimePath)?.pid;\n return typeof pid === \"number\" && pid > 0 && (await isProcessAlive(pid)) ? pid : 0;\n}\n\nfunction writeTunnelRuntime(pid: number): void {\n fs.mkdirSync(path.dirname(tunnelRuntimePath), { recursive: true });\n fs.writeFileSync(tunnelRuntimePath, JSON.stringify({ pid, startedAt: Date.now() }) + \"\\n\");\n}\n\nfunction clearTunnelRuntime(pid: number): void {\n if (readJson<{ pid?: number }>(tunnelRuntimePath)?.pid !== pid) return;\n try {\n fs.unlinkSync(tunnelRuntimePath);\n } catch {\n /* \u8FDB\u7A0B\u9000\u51FA\u65F6\u5141\u8BB8\u6587\u4EF6\u5DF2\u88AB\u79FB\u9664 */\n }\n}\n\ninterface ServiceDef {\n name: ServiceName;\n title: string;\n service?: ServiceId;\n cmd?: string;\n args?: string[];\n cwd: string;\n env?: Record<string, string>;\n stopCommand?: string;\n stopTimeout: number;\n autoRestart: boolean;\n restartDelay: number;\n /**\n * \u53EF\u9009\u670D\u52A1\uFF1Avalidate \u5931\u8D25\u65F6 start \u8FD4\u56DE skipped\uFF08startAll \u4E0D\u5F53\u4F5C\u5931\u8D25\uFF09\u3002\n * \u7528\u4E8E official \u4E0B\u8DF3\u8FC7 llbot\u3001\u4EE5\u53CA qq_enabled=false\u3002\n */\n optional?: boolean;\n validate?: () => string | null;\n /** \u542F\u52A8\u524D\u94A9\u5B50(\u5982 BDS \u88C5\u8F7D\u4E00\u81F4\u6027\u6821\u9A8C);\u5931\u8D25\u5219\u7981\u6B62 spawn */\n beforeStart?: () => Promise<void>;\n /** \u539F\u59CB\u65E5\u5FD7\u884C\u89C2\u5BDF\u5668\uFF0C\u4E0D\u5F97\u963B\u585E\u5B50\u8FDB\u7A0B\u8F93\u51FA\u3002 */\n onLogLine?: (line: string) => void;\n}\n\nclass Service {\n name: ServiceName;\n title: string;\n proc: ChildProcess | null = null;\n running = false;\n pid = 0;\n startTime: Date | null = null;\n logs: LogLine[] = [];\n events = new EventEmitter();\n\n private def: ServiceDef;\n private manualStop = false;\n private updateInProgress = false;\n private restartTimer: ReturnType<typeof setTimeout> | null = null;\n\n constructor(def: ServiceDef) {\n this.name = def.name;\n this.title = def.title;\n this.def = def;\n if (def.name === \"tunnel\") {\n this.events.on(\"output\", (text: string, level: \"info\" | \"error\") => {\n pushUnifiedLog(text, \"tunnel\", level);\n });\n }\n }\n\n get uptime(): string {\n if (!this.startTime || !this.running) return \"\u2014\";\n const ms = Date.now() - this.startTime.getTime();\n const m = Math.floor(ms / 60000);\n const h = Math.floor(m / 60);\n if (h > 0) return `${h}h ${m % 60}m`;\n if (m > 0) return `${m}m`;\n return `${Math.floor(ms / 1000)}s`;\n }\n\n pushLog(text: string, stream: \"stdout\" | \"stderr\"): void {\n const line: LogLine = { time: new Date(), text, stream };\n this.logs.push(line);\n if (this.logs.length > 2000) this.logs.splice(0, this.logs.length - 2000);\n this.events.emit(\"log\", line);\n // stderr \u89C6\u4E3A error; stdout \u7528 inferLevel \u63A8\u65AD (bare \u5B50\u8FDB\u7A0B\u7EAF text \u65F6\u9ED8\u8BA4 info,\n // BDS \u7B49\u81EA\u5E26 [LEVEL] \u6807\u7B7E\u7684\u4ECD\u53EF\u6B63\u786E\u63A8\u65AD)\n const level = stream === \"stderr\" ? \"error\" : inferLevel(text);\n pushUnifiedLog(text, this.name, level);\n this.def.onLogLine?.(text);\n }\n\n async start(): Promise<StartOutcome> {\n if (this.updateInProgress) throw new Error(\"BDS \u6B63\u5728\u66F4\u65B0\uFF0C\u6682\u4E0D\u53EF\u542F\u52A8\");\n if (this.running) return { status: \"already\" };\n if (this.name === \"bds\") {\n const probe = await probeBdsStatus({ rootDir: ROOT });\n if (probe.state !== \"stopped\") {\n throw new Error(\n t(\"svc.bdsAlreadyRunning\", {\n pid: String(probe.pid),\n kind: t(probe.state === \"managed\" ? \"svc.running\" : \"svc.runningExternal\"),\n })\n );\n }\n }\n if (this.name === \"db\" || this.name === \"qq\") {\n const external = await findNodeServicePids(this.name);\n if (external.length > 0) {\n return { status: \"already\" };\n }\n }\n if (this.name === \"tunnel\" && (await probeTunnelRuntime())) return { status: \"already\" };\n if (this.def.validate) {\n const v = this.def.validate();\n if (v) {\n // optional\uFF1A\u914D\u7F6E\u5C42\u9762\u8DF3\u8FC7\uFF08\u5982 official \u4E0B llbot\uFF09\uFF0C\u4E0D\u5F53\u5931\u8D25\u3001\u4E5F\u4E0D spawn\n if (this.def.optional) return { status: \"skipped\", reason: v };\n throw new Error(v);\n }\n }\n if (this.def.beforeStart) {\n await this.def.beforeStart();\n }\n if (this.name === \"bds\") {\n await startModuleSidecars(ROOT, (line, stream) => this.pushLog(line, stream));\n }\n // beforeStart \u542B\u5F02\u6B65\u68C0\u67E5\uFF1B\u66F4\u65B0\u53EF\u80FD\u5728\u7B49\u5F85\u671F\u95F4\u5F00\u59CB\u3002\n if (this.updateInProgress) throw new Error(\"BDS \u6B63\u5728\u66F4\u65B0\uFF0C\u6682\u4E0D\u53EF\u542F\u52A8\");\n this.manualStop = false;\n /* \u5B50\u8FDB\u7A0B\u59CB\u7EC8\u7531\u5B88\u62A4\u8FDB\u7A0B\u7528\u7BA1\u9053\u6301\u6709\uFF08stdin \u53D1 stop\u3001stdout \u65E5\u5FD7\u3001autoRestart\uFF09\uFF1B\n * \u4E0D\u518D\u5BF9\u5B50\u670D\u52A1\u505A detached/unref\u2014\u2014\u8131\u79BB\u7EC8\u7AEF\u7531 daemon \u8FDB\u7A0B\u81EA\u8EAB\u8D1F\u8D23\u3002\n * windowsHide\uFF1AWindows \u4E0A\u907F\u514D\u4E3A\u6BCF\u4E2A\u670D\u52A1\u5F39\u51FA\u7A7A\u767D\u63A7\u5236\u53F0\uFF08stdout \u5DF2 pipe\uFF0C\u7A97\u5185\u65E0\u8F93\u51FA\uFF09\u3002 */\n const spawnOpts = {\n cwd: this.def.cwd,\n stdio: [\"pipe\", \"pipe\", \"pipe\"] as Array<\"pipe\">,\n env: this.def.env ? { ...process.env, ...this.def.env } : process.env,\n windowsHide: true,\n };\n const child = this.def.service\n ? spawnService(this.def.service, this.def.args ?? [], spawnOpts)\n : spawn(this.def.cmd as string, this.def.args ?? [], spawnOpts);\n this.proc = child;\n this.pid = child.pid ?? 0;\n this.running = true;\n this.startTime = new Date();\n if (this.name === \"bds\" && this.pid > 0) {\n writeBdsPidFile(this.pid, ROOT);\n }\n if (this.name === \"tunnel\" && this.pid > 0) writeTunnelRuntime(this.pid);\n this.events.emit(\"output\", `started (PID ${this.pid})`, \"info\");\n this.events.emit(\"state\", { name: this.name, running: true, pid: this.pid });\n\n let lifecycleReported = false;\n const reportExit = (code?: number | null) => {\n if (this.name !== \"bds\" || lifecycleReported) return;\n lifecycleReported = true;\n const planned = this.manualStop || this.updateInProgress;\n void postBdsLifecycleEvent(planned ? \"stop\" : \"crash\", planned ? undefined : `code=${code ?? \"?\"}`, {\n port: dbHealthPort,\n });\n };\n if (this.name === \"bds\") {\n child.once(\"spawn\", () => {\n void postBdsLifecycleEvent(\"start\", undefined, { port: dbHealthPort });\n });\n }\n\n child.on(\"error\", (e) => {\n this.events.emit(\"output\", `process error: ${e.message}`, \"error\");\n reportExit();\n this.cleanup();\n this.scheduleRestart();\n });\n\n let versionLineBuffer = \"\";\n child.stdout?.on(\"data\", (d: Buffer) => {\n if (this.name === \"bds\" && this.startTime) {\n versionLineBuffer += d.toString();\n const versionLines = versionLineBuffer.split(/\\r?\\n/);\n versionLineBuffer = (versionLines.pop() ?? \"\").slice(-4096);\n for (const versionLine of versionLines) recordBdsVersion(ROOT, versionLine, this.pid, this.startTime.getTime());\n }\n for (const line of nonBlankOutputLines(d.toString())) {\n this.pushLog(line, \"stdout\");\n }\n });\n child.stderr?.on(\"data\", (d: Buffer) => {\n for (const line of nonBlankOutputLines(d.toString())) {\n this.pushLog(line, \"stderr\");\n }\n });\n\n child.on(\"exit\", (code) => {\n if (this.proc && this.proc !== child) return;\n this.events.emit(\"output\", `exited (code: ${code})`, \"info\");\n reportExit(code);\n this.cleanup();\n this.scheduleRestart();\n });\n return { status: \"started\" };\n }\n\n private scheduleRestart(): void {\n if (this.manualStop || this.updateInProgress || !this.def.autoRestart || this.restartTimer) return;\n this.restartTimer = setTimeout(() => {\n this.restartTimer = null;\n if (!this.updateInProgress && !this.manualStop && !this.running) {\n void this.start().catch((e: Error) => {\n this.events.emit(\"output\", `restart failed: ${e.message}`, \"error\");\n });\n }\n }, this.def.restartDelay);\n }\n\n /** \u66F4\u65B0\u5668\u72EC\u7ACB\u8FDB\u7A0B\u505C\u670D\u65F6\uFF0C\u7981\u6B62\u5C06\u8BA1\u5212\u5185\u9000\u51FA\u5F53\u4F5C\u5D29\u6E83\u5E76\u81EA\u52A8\u62C9\u8D77\u3002 */\n beginUpdate(): void {\n if (this.name !== \"bds\") return;\n if (this.updateInProgress) throw new Error(\"BDS \u66F4\u65B0\u5DF2\u5728\u8FDB\u884C\u4E2D\");\n this.updateInProgress = true;\n if (this.restartTimer) {\n clearTimeout(this.restartTimer);\n this.restartTimer = null;\n }\n }\n\n endUpdate(): void {\n this.updateInProgress = false;\n }\n\n async stop(): Promise<void> {\n this.manualStop = true;\n if (this.restartTimer) {\n clearTimeout(this.restartTimer);\n this.restartTimer = null;\n }\n if (!this.proc || !this.running) return;\n this.events.emit(\"output\", \"stopping...\", \"info\");\n\n if (this.def.stopCommand && this.proc.stdin) {\n this.proc.stdin.write(this.def.stopCommand + \"\\n\");\n } else {\n this.proc.kill(\"SIGTERM\");\n }\n\n return new Promise((resolve) => {\n const timeout = setTimeout(() => {\n if (this.proc) {\n this.events.emit(\"output\", \"force kill\", \"error\");\n try {\n this.proc.kill(\"SIGKILL\");\n } catch {\n /* ignore */\n }\n }\n resolve();\n }, this.def.stopTimeout);\n\n this.proc?.on(\"exit\", () => {\n clearTimeout(timeout);\n resolve();\n });\n });\n }\n\n forceStop(): void {\n const child = this.proc;\n this.manualStop = true;\n if (this.restartTimer) {\n clearTimeout(this.restartTimer);\n this.restartTimer = null;\n }\n this.cleanup();\n if (!child) return;\n try {\n child.kill(\"SIGKILL\");\n } catch {\n /* ignore */\n }\n }\n\n async restart(): Promise<StartOutcome> {\n await this.stop();\n return this.start();\n }\n\n getRecentLogs(n: number): LogLine[] {\n return this.logs.slice(-n);\n }\n\n /**\n * \u63A2\u6D4B\u53D1\u73B0\u8FDB\u7A0B\u5DF2\u6B7B\u540E\u56DE\u5199\u672C\u5730\u72B6\u6001\uFF08\u4E0D\u8BBE manualStop\uFF0C\u4EE5\u4FBF exit \u56DE\u8C03\u4ECD\u53EF\u6309\u9700 autoRestart\uFF09\u3002\n */\n markStoppedFromProbe(): void {\n if (!this.running && !this.proc) return;\n this.cleanup();\n }\n\n private cleanup(): void {\n const wasRunning = this.running || this.proc !== null;\n const exitingPid = this.pid;\n this.proc = null;\n this.running = false;\n this.pid = 0;\n this.startTime = null;\n if (this.name === \"bds\" && exitingPid > 0) {\n const filePid = readBdsPidFile(ROOT);\n if (filePid === exitingPid) {\n clearBdsPidFile(ROOT);\n }\n stopModuleSidecars();\n }\n if (this.name === \"tunnel\" && exitingPid > 0) clearTunnelRuntime(exitingPid);\n if (wasRunning) {\n this.events.emit(\"state\", { name: this.name, running: false, pid: 0 });\n }\n }\n}\n\nfunction createServices(): Record<ServiceName, Service> {\n /* \u5404\u670D\u52A1/CLI \u7528 SDK ensureCoreConfigs \u64AD\u79CD\uFF08\u542B $schema\uFF09\uFF0C\u4E0D\u518D\u4ECE configs-default \u62F7\u8D1D\u3002 */\n ensureCoreConfigs(ROOT, [\"bds_updater\", \"qq_config\", \"db_config\"]);\n ensurePackUpdateConfigFile();\n const bdsCfg = loadEnsuredConfig(ROOT, \"bds_updater.json\", \"bds_updater\", { ...DEFAULT_BDS_UPDATER_CONFIG } as Record<\n string,\n unknown\n >) as BdsUpdaterConfig;\n const qqCfg = loadEnsuredConfig(ROOT, \"qq_config.json\", \"qq_config\", { ...DEFAULT_QQ_CONFIG } as Record<\n string,\n unknown\n >) as QQBridgeConfig;\n const dbCfg = loadEnsuredConfig(ROOT, \"db_config.json\", \"db_config\", { ...DEFAULT_DB_CONFIG } as Record<\n string,\n unknown\n >) as DBConfig;\n const rawBdsPath = String(bdsCfg.bds_path ?? \"\").trim();\n if (process.platform !== \"win32\" && /^[A-Za-z]:[\\\\/]/.test(rawBdsPath)) {\n throw new Error(\n `configs/bds_updater.json \u7684 bds_path \u662F Windows \u8DEF\u5F84\uFF08${rawBdsPath}\uFF09\u3002` +\n `\u8BF7\u6539\u6210\u76F8\u5BF9 SFMC_ROOT \u7684\u8DEF\u5F84\uFF0C\u4F8B\u5982 \"BDS\"\u3002`\n );\n }\n const bdsPath = path.resolve(ROOT, rawBdsPath || \".\");\n const useLlbotBackend = qqCfg.qq_backend === \"llbot\";\n const qqEnabled = qqCfg.qq_enabled !== false;\n // \u5B98\u65B9 Webhook \u7531\u4E91\u7AEF\u63A5\u6536\uFF1B\u4EC5\u5207\u6362\u4F20\u8F93\u65B9\u5F0F\u5373\u53EF\u907F\u514D\u672C\u673A\u518D\u542F\u52A8\u4E00\u4E2A\u6865\u3002\n const qqExternal = !useLlbotBackend && qqCfg.official?.transport === \"webhook\";\n const tunnelCfg = qqCfg.official?.tunnel;\n const tunnelEnabled = qqEnabled && qqExternal && tunnelCfg?.enabled === true;\n const tunnelHost = String(tunnelCfg?.host ?? \"\").trim();\n const tunnelRemotePort = tunnelCfg?.remotePort ?? 13001;\n const llbotEnabled = qqCfg.llbot?.enabled !== false;\n const llbotLaunch = resolveLlbotLaunch(qqCfg.llbot?.path, qqCfg.llbot?.cwd);\n const llbotPath = llbotLaunch.exe;\n const llbotCwd = llbotLaunch.cwd;\n const dbPort = dbCfg.db_port ?? 3001;\n dbHealthPort = dbPort;\n qqBackendMode = useLlbotBackend ? \"llbot\" : \"official\";\n const bdsExe = bdsExePath(bdsPath);\n const qqTitle = useLlbotBackend ? \"QQ (llbot)\" : \"QQ (official)\";\n\n return {\n bds: new Service({\n name: \"bds\",\n title: \"BDS\",\n cmd: bdsExe,\n args: [],\n cwd: bdsPath,\n env: bdsSpawnEnvExtra(bdsPath),\n stopCommand: \"stop\",\n stopTimeout: 30000,\n /* \u5D29\u6E83\u62C9\u8D77\u7531 sfmc daemon \u56FA\u5B9A\u5F00\u542F\uFF1B\u4E0D\u518D\u8BFB bds_updater.crash_restart */\n autoRestart: true,\n restartDelay: 5000,\n validate: () => {\n if (!fs.existsSync(bdsExe)) return `not found: ${bdsExe}`;\n return null;\n },\n beforeStart: async () => {\n ensureBdsExecutable(bdsExe);\n /* \u5148\u88C5\u6536\u4EF6\u7BB1\u7B2C\u4E09\u65B9\u5305\uFF0C\u518D\u68C0\u67E5 CF \u66F4\u65B0\uFF0C\u518D\u8DD1\u6A21\u5757\u805A\u5408\u95F8\u95E8 */\n const { scanAndInstallInbox } = await import(\"./world-packs.js\");\n await scanAndInstallInbox({ interactive: false });\n const { runPackUpdatesOnBdsStart } = await import(\"./pack-update/index.js\");\n await runPackUpdatesOnBdsStart();\n const { ensurePacksReady } = await import(\"./pack-lifecycle.js\");\n await ensurePacksReady();\n },\n onLogLine: (line) =>\n reportBdsPlayerSession(line, {\n port: dbPort,\n ...(dbCfg.http_auth ? { authToken: dbCfg.http_auth } : {}),\n }),\n }),\n\n db: new Service({\n name: \"db\",\n title: \"DB Server\",\n service: \"db\",\n cwd: ROOT,\n stopTimeout: 10000,\n autoRestart: true,\n restartDelay: 3000,\n env: { DB_PORT: String(dbPort) },\n }),\n\n tunnel: new Service({\n name: \"tunnel\",\n title: \"QQ SSH Tunnel\",\n cmd: \"ssh\",\n args: [\n \"-N\", \"-T\", \"-o\", \"BatchMode=yes\", \"-o\", \"ConnectTimeout=10\",\n \"-o\", \"ExitOnForwardFailure=yes\", \"-o\", \"ServerAliveInterval=30\",\n \"-o\", \"ServerAliveCountMax=3\",\n \"-R\", `127.0.0.1:${tunnelRemotePort}:127.0.0.1:${dbPort}`,\n tunnelHost,\n ],\n cwd: ROOT,\n stopTimeout: 10000,\n autoRestart: true,\n restartDelay: 5000,\n optional: !tunnelEnabled,\n validate: () => {\n if (!tunnelEnabled) return \"QQ tunnel disabled (official webhook tunnel.enabled=false)\";\n if (!/^[A-Za-z0-9_][A-Za-z0-9_.-]*$/.test(tunnelHost)) return \"invalid official.tunnel.host\";\n if (!Number.isInteger(tunnelRemotePort) || tunnelRemotePort < 1 || tunnelRemotePort > 65535) {\n return \"invalid official.tunnel.remotePort\";\n }\n return null;\n },\n }),\n\n qq: new Service({\n name: \"qq\",\n title: qqTitle,\n service: \"qq\",\n cwd: ROOT,\n stopTimeout: 10000,\n // \u7F3A\u51ED\u636E\u65F6 validate \u62E6\u4E0B\uFF0C\u4E0D\u4F1A spawn\u2192exit(1)\u2192autoRestart \u6B7B\u5FAA\u73AF\n autoRestart: true,\n restartDelay: 3000,\n optional: !qqEnabled || qqExternal,\n validate: () => {\n if (!qqEnabled) return \"QQ bridge disabled (qq_enabled=false)\";\n if (qqExternal) return \"QQ bridge runs externally (official.transport=webhook)\";\n if (!useLlbotBackend) {\n if (!String(qqCfg.official?.app_id ?? \"\").trim() || !String(qqCfg.official?.app_secret ?? \"\").trim()) {\n return \"missing official.app_id / official.app_secret\";\n }\n }\n return null;\n },\n }),\n\n llbot: new Service({\n name: \"llbot\",\n title: \"LLBot\",\n cmd: llbotPath,\n args: [],\n cwd: llbotCwd,\n stopTimeout: 10000,\n autoRestart: false,\n restartDelay: 5000,\n // official \u6216\u672A\u542F\u7528\u65F6\u771F\u6B63 skip\uFF0C\u4E0D throw\n optional: !useLlbotBackend || !llbotEnabled,\n validate: () => {\n if (!useLlbotBackend) return \"LLBot skipped (qq_backend!=llbot)\";\n if (!llbotEnabled) return \"LLBot disabled (llbot.enabled=false)\";\n if (!fs.existsSync(llbotPath)) return `not found: ${llbotPath}`;\n return null;\n },\n }),\n };\n}\n\nexport let services: Record<ServiceName, Service> = createServices();\n\nexport function refreshServices(): void {\n forceStopAll();\n services = createServices();\n}\n\nexport const START_ORDER: ServiceName[] = [\"db\", \"tunnel\", \"qq\", \"llbot\", \"bds\"];\n\nexport async function startAll(): Promise<StartAllResult> {\n const result: StartAllResult = { started: [], skipped: [], failed: [] };\n for (const name of START_ORDER) {\n const svc = services[name];\n if (!svc) continue;\n try {\n const outcome = await svc.start();\n if (outcome.status === \"skipped\") {\n result.skipped.push({ name, reason: outcome.reason });\n svc.events.emit(\"output\", `skipped: ${outcome.reason}`, \"info\");\n } else {\n result.started.push(name);\n }\n } catch (e) {\n const reason = (e as Error).message;\n result.failed.push({ name, reason });\n svc.events.emit(\"output\", `start error: ${reason}`, \"error\");\n }\n }\n return result;\n}\n\nexport async function stopAll(): Promise<void> {\n const pending = [...START_ORDER]\n .reverse()\n .map((name) => services[name])\n .filter((service): service is Service => Boolean(service))\n .map((service) => service.stop());\n await Promise.allSettled(pending);\n}\n\nexport function forceStopAll(): void {\n for (const service of Object.values(services)) service.forceStop();\n}\n\nexport type ServiceStateEvent = { name: ServiceName; running: boolean; pid: number };\n\n/** \u8BA2\u9605\u4EFB\u610F\u670D\u52A1\u542F\u505C\uFF08\u542B\u63A2\u6D4B\u56DE\u5199\uFF09\uFF1B\u8FD4\u56DE\u53D6\u6D88\u51FD\u6570 */\nexport function onServiceStateChange(fn: (ev: ServiceStateEvent) => void): () => void {\n /* CLI \u8FDB\u7A0B\u4E0D\u6301\u6709 Service \u5B50\u8FDB\u7A0B\uFF1A\u6539\u8BA2\u5B88\u62A4\u8FDB\u7A0B\u63A8\u9001\u7684\u8FDC\u7A0B\u72B6\u6001\u4E8B\u4EF6 */\n if (!isDaemonServer()) {\n return onRemoteServiceStateChange(fn);\n }\n const handler = (ev: ServiceStateEvent): void => {\n fn(ev);\n };\n for (const service of Object.values(services)) {\n service.events.on(\"state\", handler);\n }\n return () => {\n for (const service of Object.values(services)) {\n service.events.off(\"state\", handler);\n }\n };\n}\n\n/** \u82E5\u672C\u5730\u6807\u8BB0 running \u4F46 OS \u8FDB\u7A0B\u5DF2\u6B7B\uFF0C\u56DE\u6536\u5185\u5B58\u6807\u5FD7 */\nasync function reconcileManagedAlive(service: Service): Promise<boolean> {\n if (!service.running) return false;\n if (service.pid > 0 && !(await isProcessAlive(service.pid))) {\n service.markStoppedFromProbe();\n return false;\n }\n return service.running;\n}\n\n/**\n * \u7EDF\u4E00\u8FD0\u884C\u6001\u67E5\u8BE2\uFF08\u6743\u5A01\u5165\u53E3\uFF09\uFF1AOS/\u5065\u5EB7\u63A2\u6D4B + \u56DE\u5199 Service \u5185\u5B58\u6807\u5FD7\u3002\n * status / Tab \u53D1\u9001\u76EE\u6807 / reload \u7B49\u5747\u5E94\u8D70\u6B64\u63A5\u53E3\uFF0C\u52FF\u76F4\u63A5\u8BFB `service.running`\u3002\n * CLI \u8FDB\u7A0B\u7ECF\u5B88\u62A4\u8FDB\u7A0B RPC \u83B7\u53D6\uFF1B\u5B88\u62A4\u8FDB\u7A0B\u5185\u8D70\u672C\u5730\u63A2\u6D3B\u3002\n */\nexport async function queryServicesRuntime(): Promise<ServiceStatus[]> {\n if (!isDaemonServer()) {\n const { queryRuntimeViaDaemon } = await import(\"./daemon/client.js\");\n return queryRuntimeViaDaemon();\n }\n return queryServicesRuntimeLocal();\n}\n\n/** \u5B88\u62A4\u8FDB\u7A0B\u5185\u672C\u5730\u63A2\u6D3B\u5B9E\u73B0\uFF08\u4EA6\u4F9B server status \u7EC4\u88C5 rows\uFF09 */\nexport async function queryServicesRuntimeLocal(): Promise<ServiceStatus[]> {\n return Promise.all(\n SERVICE_NAMES.map(async (name) => {\n const service = services[name];\n let running = false;\n let pid = 0;\n let uptime = \"\u2014\";\n let ownership: \"managed\" | \"external\" | undefined;\n\n if (name === \"bds\") {\n const probe = await probeBdsStatus({\n managedPid: service.pid,\n hasStdin: Boolean(service.proc?.stdin),\n rootDir: ROOT,\n });\n if (probe.state === \"managed\") {\n running = true;\n pid = probe.pid;\n uptime = service.uptime;\n ownership = \"managed\";\n /* \u63A2\u6D4B\u4E3A managed \u4F46\u672C\u5730\u5DF2\u6807\u505C\uFF1A\u4FDD\u6301\u63A2\u6D4B\u7ED3\u679C\uFF0C\u4E0D\u5F3A\u5236\u6539\u5185\u5B58\uFF08stdin \u4ECD\u53EF\u7528\uFF09 */\n } else if (probe.state === \"external\") {\n running = true;\n pid = probe.pid;\n ownership = \"external\";\n /* \u5916\u90E8\u8FDB\u7A0B\uFF1A\u672C\u5730 managed \u53E5\u67C4\u5DF2\u5931\u6548\u5219\u56DE\u6536 */\n if (service.running && service.pid !== probe.pid) {\n service.markStoppedFromProbe();\n } else if (service.running && !(await isProcessAlive(service.pid))) {\n service.markStoppedFromProbe();\n }\n } else {\n running = false;\n if (service.running || service.proc) {\n service.markStoppedFromProbe();\n }\n }\n } else if (name === \"db\") {\n const managed = await reconcileManagedAlive(service);\n if (managed) {\n running = true;\n pid = service.pid;\n uptime = service.uptime;\n ownership = \"managed\";\n } else if (await probeDbHealth(dbHealthPort)) {\n running = true;\n ownership = \"external\";\n const pids = await findNodeServicePids(\"db\");\n pid = pids[0] ?? 0;\n }\n } else if (name === \"qq\") {\n const managed = await reconcileManagedAlive(service);\n if (managed) {\n running = true;\n pid = service.pid;\n uptime = service.uptime;\n ownership = \"managed\";\n } else {\n const probe = await probeQqRuntime();\n if (probe.alive) {\n running = true;\n pid = probe.pid;\n ownership = \"external\";\n } else {\n const pids = await findNodeServicePids(\"qq\");\n if (pids.length > 0) {\n running = true;\n pid = pids[0]!;\n ownership = \"external\";\n }\n }\n }\n } else if (name === \"tunnel\") {\n const managed = await reconcileManagedAlive(service);\n if (managed) {\n running = true;\n pid = service.pid;\n uptime = service.uptime;\n ownership = \"managed\";\n } else {\n pid = await probeTunnelRuntime();\n running = pid > 0;\n if (running) ownership = \"external\";\n }\n } else {\n const managed = await reconcileManagedAlive(service);\n if (managed) {\n running = true;\n pid = service.pid;\n uptime = service.uptime;\n ownership = \"managed\";\n }\n }\n\n return {\n name,\n title: service.title,\n running,\n pid,\n uptime,\n ...(ownership ? { ownership } : {}),\n };\n })\n );\n}\n\n/** \u5355\u670D\u52A1\u662F\u5426\u5728\u8DD1\uFF08\u542B\u5916\u90E8\u5B9E\u4F8B\uFF09 */\nexport async function isServiceRunning(name: ServiceName): Promise<boolean> {\n const rows = await queryServicesRuntime();\n return rows.some((r) => r.name === name && r.running);\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * services.ts \u2014 CLI \u8FDB\u7A0B\u7F16\u6392\u4E0E\u670D\u52A1\u751F\u547D\u5468\u671F\u7BA1\u7406\n *\n * \u6838\u5FC3\u7BA1\u7406\u5BF9\u8C61\uFF08ServiceName\uFF09\uFF1A\n * - `bds`\uFF1AMinecraft \u57FA\u5CA9\u7248\u670D\u52A1\u7AEF\uFF08\u652F\u6301 stdin \u7BA1\u9053\u6307\u4EE4\u4EA4\u4E92\u4E0E\u4F18\u96C5\u505C\u670D\uFF09\n * - `db`\uFF1Adb-server SQLite HTTP \u670D\u52A1\uFF08\u7AEF\u53E3\u5065\u5EB7\u68C0\u67E5\u4E0E loopback \u63A2\u6D3B\uFF09\n * - `tunnel`\uFF1A\u4E91\u7AEF QQ Webhook \u5230\u672C\u673A db-server \u7684 SSH \u53CD\u5411\u96A7\u9053\n * - `qq`\uFF1Aqq-bridge \u6D88\u606F\u7F51\u6865\u670D\u52A1\uFF08\u652F\u6301\u5B98\u65B9 Bot \u4E0E LLBot \u53CC\u540E\u7AEF\uFF09\n * - `llbot`\uFF1ALLBot \u72EC\u7ACB\u673A\u5668\u4EBA\u8FDB\u7A0B\uFF08\u6761\u4EF6\u542F\u52A8\uFF09\n *\n * \u6838\u5FC3\u80FD\u529B\uFF1A\n * - \u8FDB\u7A0B\u751F\u547D\u5468\u671F\uFF1A\u6309\u4F9D\u8D56\u6B21\u5E8F\u7F16\u6392\u670D\u52A1\u542F\u52A8\uFF08db \u2192 qq \u2192 bds\uFF09\u3001\u4F18\u96C5\u505C\u6B62\u4E0E\u5F02\u5E38\u81EA\u52A8\u62C9\u8D77\n * - \u591A\u6E90\u63A2\u6D3B\u611F\u77E5\uFF1A\u81EA\u52A8\u63A2\u6D4B\u6258\u7BA1\u8FDB\u7A0B\u4E0E\u5916\u90E8\u72EC\u7ACB\u8FDB\u7A0B\u72B6\u6001\n * - \u65E5\u5FD7\u6D41\u7EDF\u4E00\u805A\u5408\uFF1A\u6355\u83B7\u5E76\u5F52\u4E00\u5316\u5404\u670D\u52A1\u7684 stdout / stderr \u6570\u636E\u6D41\n */\n\nimport type { BdsUpdaterConfig, DBConfig, QQBackend, QQBridgeConfig } from \"@sfmc-bds/sdk/node/config\";\nimport {\n DEFAULT_BDS_UPDATER_CONFIG,\n DEFAULT_DB_CONFIG,\n DEFAULT_QQ_CONFIG,\n ensureCoreConfigs,\n loadEnsuredConfig,\n qqRuntimeStatusPath,\n readJson,\n type QqRuntimeStatus,\n} from \"@sfmc-bds/sdk/node/config\";\n\nimport { bdsExePath, bdsSpawnEnvExtra, ensureBdsExecutable } from \"@sfmc-bds/bds-tools/host-platform\";\nimport {\n clearBdsPidFile,\n findBedrockServerPids,\n isProcessAlive,\n killBedrockServerByImage,\n probeBdsStatus,\n readBdsPidFile,\n writeBdsPidFile,\n} from \"@sfmc-bds/bds-tools/process-probe\";\nimport { postBdsLifecycleEvent } from \"@sfmc-bds/bds-tools/qq-events-notify\";\nimport { spawn, type ChildProcess } from \"node:child_process\";\nimport { EventEmitter } from \"node:events\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { isDaemonServer } from \"./daemon/role.js\";\nimport { onRemoteServiceStateChange } from \"./daemon/client.js\";\nimport { t } from \"./i18n/index.js\";\nimport { resolveLlbotLaunch } from \"./llbot-launch.js\";\nimport { inferLevel, pushLog as pushUnifiedLog } from \"./logs.js\";\nimport { findNodeServicePids, killNodeServiceByScript } from \"./node-service-probe.js\";\nimport { ensurePackUpdateConfigFile } from \"./pack-update/index.js\";\nimport { recordBdsVersion } from \"./bds-runtime-version.js\";\nimport { reportBdsPlayerSession } from \"./player-session.js\";\nimport { startModuleSidecars, stopModuleSidecars } from \"./module-sidecars.js\";\nimport { ROOT, spawnService, type ServiceId } from \"./runtime.js\";\n\nexport { ROOT } from \"./runtime.js\";\n\nexport interface LogLine {\n time: Date;\n text: string;\n stream: \"stdout\" | \"stderr\";\n}\n\n/** \u5B50\u8FDB\u7A0B\u8F93\u51FA\u5206\u884C\uFF1A\u8FC7\u6EE4\u7A7A\u4E32\u4EE5\u53CA Windows CRLF \u62C6\u5206\u540E\u6B8B\u7559\u7684\u7EAF\u7A7A\u767D\u884C\u3002 */\nexport function nonBlankOutputLines(text: string): string[] {\n return text.split(/\\r?\\n/).filter((line) => line.trim().length > 0);\n}\n\nexport type ServiceName = \"bds\" | \"db\" | \"tunnel\" | \"qq\" | \"llbot\";\nexport const SERVICE_NAMES: ServiceName[] = [\"bds\", \"db\", \"tunnel\", \"qq\", \"llbot\"];\n\n/** \u5355\u670D\u52A1 start \u7ED3\u679C\uFF1Aoptional \u670D\u52A1 validate \u5931\u8D25\u8BB0\u4E3A skipped\uFF0C\u4E0D\u629B\u9519 */\nexport type StartOutcome = { status: \"started\" } | { status: \"already\" } | { status: \"skipped\"; reason: string };\n\n/**\n * \u5355\u670D\u52A1 stop \u7ED3\u679C\uFF0C\u4F9B CLI \u533A\u5206\u6587\u6848\u3002\n * \u4F7F\u7528\u573A\u666F\uFF1A`stop` / `restart` / `stop all` \u5171\u7528 Service.stop\u3002\n * - managed\uFF1A\u505C\u7684\u662F\u672C\u8FDB\u7A0B\u62C9\u8D77\u7684\u5B50\u8FDB\u7A0B\n * - external\uFF1A\u6CA1\u6709\u6258\u7BA1\u53E5\u67C4\uFF0C\u4F46\u6E05\u6389\u4E86\u5916\u90E8\u5B9E\u4F8B\n * - idle\uFF1A\u672C\u6765\u5C31\u6CA1\u5728\u8DD1\n */\nexport type StopKind = \"managed\" | \"external\" | \"idle\";\n\nexport interface StartAllResult {\n started: ServiceName[];\n skipped: Array<{ name: ServiceName; reason: string }>;\n failed: Array<{ name: ServiceName; reason: string }>;\n}\n\nexport interface ServiceStatus {\n name: ServiceName;\n title: string;\n running: boolean;\n pid: number;\n uptime: string;\n ownership?: \"managed\" | \"external\";\n}\n\n/** \u5F53\u524D db \u5065\u5EB7\u63A2\u6D4B\u7AEF\u53E3\uFF08\u4E0E createServices \u540C\u6B65\uFF09 */\nlet dbHealthPort = 3001;\n/** \u5F53\u524D QQ \u540E\u7AEF\uFF08\u4E0E createServices \u540C\u6B65\uFF0C\u4F9B Tab/\u7A97\u6807\u9898\uFF09 */\nlet qqBackendMode: QQBackend = \"official\";\n\nexport function getQqBackendMode(): QQBackend {\n return qqBackendMode;\n}\n\nasync function probeDbHealth(port: number): Promise<boolean> {\n try {\n const res = await fetch(`http://127.0.0.1:${port}/api/health`, { signal: AbortSignal.timeout(2000) });\n return res.ok;\n } catch {\n return false;\n }\n}\n\n/** \u8BFB `.sfmc/qq.runtime.json` + pid \u5B58\u6D3B\uFF0C\u63A2\u6D4B\u5916\u90E8/\u672C\u673A qq-bridge */\nasync function probeQqRuntime(): Promise<{ alive: boolean; pid: number }> {\n const status = readJson<QqRuntimeStatus>(qqRuntimeStatusPath(ROOT));\n if (!status?.pid || status.pid <= 0) return { alive: false, pid: 0 };\n if (!(await isProcessAlive(status.pid))) return { alive: false, pid: 0 };\n return { alive: true, pid: status.pid };\n}\n\nconst tunnelRuntimePath = path.join(ROOT, \".sfmc\", \"tunnel.runtime.json\");\n\nasync function probeTunnelRuntime(): Promise<number> {\n const pid = readJson<{ pid?: number }>(tunnelRuntimePath)?.pid;\n return typeof pid === \"number\" && pid > 0 && (await isProcessAlive(pid)) ? pid : 0;\n}\n\nfunction writeTunnelRuntime(pid: number): void {\n fs.mkdirSync(path.dirname(tunnelRuntimePath), { recursive: true });\n fs.writeFileSync(tunnelRuntimePath, JSON.stringify({ pid, startedAt: Date.now() }) + \"\\n\");\n}\n\nfunction clearTunnelRuntime(pid: number): void {\n if (readJson<{ pid?: number }>(tunnelRuntimePath)?.pid !== pid) return;\n try {\n fs.unlinkSync(tunnelRuntimePath);\n } catch {\n /* \u8FDB\u7A0B\u9000\u51FA\u65F6\u5141\u8BB8\u6587\u4EF6\u5DF2\u88AB\u79FB\u9664 */\n }\n}\n\n/** \u6E05\u6389 qq-bridge \u8FD0\u884C\u65F6\u6587\u4EF6\uFF0C\u907F\u514D status \u4ECD\u628A\u5DF2\u9000\u51FA\u7684\u5916\u90E8\u8FDB\u7A0B\u5F53\u6210\u5B58\u6D3B\u3002 */\nfunction clearQqRuntimeFile(): void {\n try {\n const file = qqRuntimeStatusPath(ROOT);\n if (fs.existsSync(file)) fs.unlinkSync(file);\n } catch {\n /* \u8FD0\u884C\u65F6\u6587\u4EF6\u53EF\u80FD\u5DF2\u88AB\u8FDB\u7A0B\u81EA\u5DF1\u5220\u6389 */\n }\n}\n\n/**\n * \u6309\u955C\u50CF\u540D\u7ED3\u675F\u5916\u90E8 BDS\uFF0C\u5E76\u7B49\u5230\u8FDB\u7A0B\u4ECE\u8FDB\u7A0B\u8868\u6D88\u5931\u3002\n * \u4F7F\u7528\u573A\u666F\uFF1A\u5355\u670D\u52A1 stop\u3001restart\u3001stop all \u90FD\u8981\u80FD\u505C\u6389\u975E\u672C\u8FDB\u7A0B\u62C9\u8D77\u7684 bedrock\u3002\n * taskkill \u8FD4\u56DE\u540E\u8FDB\u7A0B\u8868\u53EF\u80FD\u4ECD\u77ED\u6682\u53EF\u89C1\uFF0Crestart \u4F1A\u7ACB\u523B\u63A2\u6D3B\uFF0C\u56E0\u6B64\u8FD9\u91CC\u7B49\u5230\u6D88\u5931\u518D\u8FD4\u56DE\u3002\n */\nasync function killExternalBedrock(): Promise<void> {\n await killBedrockServerByImage();\n clearBdsPidFile(ROOT);\n const deadline = Date.now() + 8000;\n while (Date.now() < deadline) {\n if ((await findBedrockServerPids()).length === 0) return;\n await new Promise((r) => setTimeout(r, 200));\n }\n await killBedrockServerByImage();\n clearBdsPidFile(ROOT);\n}\n\ninterface ServiceDef {\n name: ServiceName;\n title: string;\n service?: ServiceId;\n cmd?: string;\n args?: string[];\n cwd: string;\n env?: Record<string, string>;\n stopCommand?: string;\n stopTimeout: number;\n autoRestart: boolean;\n restartDelay: number;\n /**\n * \u53EF\u9009\u670D\u52A1\uFF1Avalidate \u5931\u8D25\u65F6 start \u8FD4\u56DE skipped\uFF08startAll \u4E0D\u5F53\u4F5C\u5931\u8D25\uFF09\u3002\n * \u7528\u4E8E official \u4E0B\u8DF3\u8FC7 llbot\u3001\u4EE5\u53CA qq_enabled=false\u3002\n */\n optional?: boolean;\n validate?: () => string | null;\n /** \u542F\u52A8\u524D\u94A9\u5B50(\u5982 BDS \u88C5\u8F7D\u4E00\u81F4\u6027\u6821\u9A8C);\u5931\u8D25\u5219\u7981\u6B62 spawn */\n beforeStart?: () => Promise<void>;\n /** \u539F\u59CB\u65E5\u5FD7\u884C\u89C2\u5BDF\u5668\uFF0C\u4E0D\u5F97\u963B\u585E\u5B50\u8FDB\u7A0B\u8F93\u51FA\u3002 */\n onLogLine?: (line: string) => void;\n}\n\nclass Service {\n name: ServiceName;\n title: string;\n proc: ChildProcess | null = null;\n running = false;\n pid = 0;\n startTime: Date | null = null;\n logs: LogLine[] = [];\n events = new EventEmitter();\n\n private def: ServiceDef;\n private manualStop = false;\n private updateInProgress = false;\n private restartTimer: ReturnType<typeof setTimeout> | null = null;\n\n constructor(def: ServiceDef) {\n this.name = def.name;\n this.title = def.title;\n this.def = def;\n if (def.name === \"tunnel\") {\n this.events.on(\"output\", (text: string, level: \"info\" | \"error\") => {\n pushUnifiedLog(text, \"tunnel\", level);\n });\n }\n }\n\n get uptime(): string {\n if (!this.startTime || !this.running) return \"\u2014\";\n const ms = Date.now() - this.startTime.getTime();\n const m = Math.floor(ms / 60000);\n const h = Math.floor(m / 60);\n if (h > 0) return `${h}h ${m % 60}m`;\n if (m > 0) return `${m}m`;\n return `${Math.floor(ms / 1000)}s`;\n }\n\n pushLog(text: string, stream: \"stdout\" | \"stderr\"): void {\n const line: LogLine = { time: new Date(), text, stream };\n this.logs.push(line);\n if (this.logs.length > 2000) this.logs.splice(0, this.logs.length - 2000);\n this.events.emit(\"log\", line);\n // stderr \u89C6\u4E3A error; stdout \u7528 inferLevel \u63A8\u65AD (bare \u5B50\u8FDB\u7A0B\u7EAF text \u65F6\u9ED8\u8BA4 info,\n // BDS \u7B49\u81EA\u5E26 [LEVEL] \u6807\u7B7E\u7684\u4ECD\u53EF\u6B63\u786E\u63A8\u65AD)\n const level = stream === \"stderr\" ? \"error\" : inferLevel(text);\n pushUnifiedLog(text, this.name, level);\n this.def.onLogLine?.(text);\n }\n\n async start(): Promise<StartOutcome> {\n if (this.updateInProgress) throw new Error(\"BDS \u6B63\u5728\u66F4\u65B0\uFF0C\u6682\u4E0D\u53EF\u542F\u52A8\");\n if (this.running) return { status: \"already\" };\n if (this.name === \"bds\") {\n const probe = await probeBdsStatus({ rootDir: ROOT });\n if (probe.state !== \"stopped\") {\n throw new Error(\n t(\"svc.bdsAlreadyRunning\", {\n pid: String(probe.pid),\n kind: t(probe.state === \"managed\" ? \"svc.running\" : \"svc.runningExternal\"),\n })\n );\n }\n }\n if (this.name === \"db\" || this.name === \"qq\") {\n const external = await findNodeServicePids(this.name);\n if (external.length > 0) {\n return { status: \"already\" };\n }\n }\n if (this.name === \"tunnel\" && (await probeTunnelRuntime())) return { status: \"already\" };\n if (this.def.validate) {\n const v = this.def.validate();\n if (v) {\n // optional\uFF1A\u914D\u7F6E\u5C42\u9762\u8DF3\u8FC7\uFF08\u5982 official \u4E0B llbot\uFF09\uFF0C\u4E0D\u5F53\u5931\u8D25\u3001\u4E5F\u4E0D spawn\n if (this.def.optional) return { status: \"skipped\", reason: v };\n throw new Error(v);\n }\n }\n if (this.def.beforeStart) {\n await this.def.beforeStart();\n }\n if (this.name === \"bds\") {\n await startModuleSidecars(ROOT, (line, stream) => this.pushLog(line, stream));\n }\n // beforeStart \u542B\u5F02\u6B65\u68C0\u67E5\uFF1B\u66F4\u65B0\u53EF\u80FD\u5728\u7B49\u5F85\u671F\u95F4\u5F00\u59CB\u3002\n if (this.updateInProgress) throw new Error(\"BDS \u6B63\u5728\u66F4\u65B0\uFF0C\u6682\u4E0D\u53EF\u542F\u52A8\");\n this.manualStop = false;\n /* \u5B50\u8FDB\u7A0B\u59CB\u7EC8\u7531\u5B88\u62A4\u8FDB\u7A0B\u7528\u7BA1\u9053\u6301\u6709\uFF08stdin \u53D1 stop\u3001stdout \u65E5\u5FD7\u3001autoRestart\uFF09\uFF1B\n * \u4E0D\u518D\u5BF9\u5B50\u670D\u52A1\u505A detached/unref\u2014\u2014\u8131\u79BB\u7EC8\u7AEF\u7531 daemon \u8FDB\u7A0B\u81EA\u8EAB\u8D1F\u8D23\u3002\n * windowsHide\uFF1AWindows \u4E0A\u907F\u514D\u4E3A\u6BCF\u4E2A\u670D\u52A1\u5F39\u51FA\u7A7A\u767D\u63A7\u5236\u53F0\uFF08stdout \u5DF2 pipe\uFF0C\u7A97\u5185\u65E0\u8F93\u51FA\uFF09\u3002 */\n const spawnOpts = {\n cwd: this.def.cwd,\n stdio: [\"pipe\", \"pipe\", \"pipe\"] as Array<\"pipe\">,\n env: this.def.env ? { ...process.env, ...this.def.env } : process.env,\n windowsHide: true,\n };\n const child = this.def.service\n ? spawnService(this.def.service, this.def.args ?? [], spawnOpts)\n : spawn(this.def.cmd as string, this.def.args ?? [], spawnOpts);\n this.proc = child;\n this.pid = child.pid ?? 0;\n this.running = true;\n this.startTime = new Date();\n if (this.name === \"bds\" && this.pid > 0) {\n writeBdsPidFile(this.pid, ROOT);\n }\n if (this.name === \"tunnel\" && this.pid > 0) writeTunnelRuntime(this.pid);\n this.events.emit(\"output\", `started (PID ${this.pid})`, \"info\");\n this.events.emit(\"state\", { name: this.name, running: true, pid: this.pid });\n\n let lifecycleReported = false;\n const reportExit = (code?: number | null) => {\n if (this.name !== \"bds\" || lifecycleReported) return;\n lifecycleReported = true;\n const planned = this.manualStop || this.updateInProgress;\n void postBdsLifecycleEvent(planned ? \"stop\" : \"crash\", planned ? undefined : `code=${code ?? \"?\"}`, {\n port: dbHealthPort,\n });\n };\n if (this.name === \"bds\") {\n child.once(\"spawn\", () => {\n void postBdsLifecycleEvent(\"start\", undefined, { port: dbHealthPort });\n });\n }\n\n child.on(\"error\", (e) => {\n this.events.emit(\"output\", `process error: ${e.message}`, \"error\");\n reportExit();\n this.cleanup();\n this.scheduleRestart();\n });\n\n let versionLineBuffer = \"\";\n child.stdout?.on(\"data\", (d: Buffer) => {\n if (this.name === \"bds\" && this.startTime) {\n versionLineBuffer += d.toString();\n const versionLines = versionLineBuffer.split(/\\r?\\n/);\n versionLineBuffer = (versionLines.pop() ?? \"\").slice(-4096);\n for (const versionLine of versionLines) recordBdsVersion(ROOT, versionLine, this.pid, this.startTime.getTime());\n }\n for (const line of nonBlankOutputLines(d.toString())) {\n this.pushLog(line, \"stdout\");\n }\n });\n child.stderr?.on(\"data\", (d: Buffer) => {\n for (const line of nonBlankOutputLines(d.toString())) {\n this.pushLog(line, \"stderr\");\n }\n });\n\n child.on(\"exit\", (code) => {\n if (this.proc && this.proc !== child) return;\n this.events.emit(\"output\", `exited (code: ${code})`, \"info\");\n reportExit(code);\n this.cleanup();\n this.scheduleRestart();\n });\n return { status: \"started\" };\n }\n\n private scheduleRestart(): void {\n if (this.manualStop || this.updateInProgress || !this.def.autoRestart || this.restartTimer) return;\n this.restartTimer = setTimeout(() => {\n this.restartTimer = null;\n if (!this.updateInProgress && !this.manualStop && !this.running) {\n void this.start().catch((e: Error) => {\n this.events.emit(\"output\", `restart failed: ${e.message}`, \"error\");\n });\n }\n }, this.def.restartDelay);\n }\n\n /** \u66F4\u65B0\u5668\u72EC\u7ACB\u8FDB\u7A0B\u505C\u670D\u65F6\uFF0C\u7981\u6B62\u5C06\u8BA1\u5212\u5185\u9000\u51FA\u5F53\u4F5C\u5D29\u6E83\u5E76\u81EA\u52A8\u62C9\u8D77\u3002 */\n beginUpdate(): void {\n if (this.name !== \"bds\") return;\n if (this.updateInProgress) throw new Error(\"BDS \u66F4\u65B0\u5DF2\u5728\u8FDB\u884C\u4E2D\");\n this.updateInProgress = true;\n if (this.restartTimer) {\n clearTimeout(this.restartTimer);\n this.restartTimer = null;\n }\n }\n\n endUpdate(): void {\n this.updateInProgress = false;\n }\n\n /**\n * \u505C\u6B62\u672C\u670D\u52A1\u3002\u6258\u7BA1\u5B50\u8FDB\u7A0B\u4ECD\u8D70\u539F\u6765\u7684\u4F18\u96C5\u505C\u6B62\uFF1B\u6CA1\u6709\u53EF\u7BA1\u53E5\u67C4\u65F6\u6E05\u6389\u5916\u90E8\u5B9E\u4F8B\u3002\n * \u4F7F\u7528\u573A\u666F\uFF1A`stop <name>`\u3001`restart`\u3001`stop all` \u548C\u5B88\u62A4\u8FDB\u7A0B\u9000\u51FA\u90FD\u8D70\u8FD9\u91CC\uFF0C\n * \u907F\u514D\u53EA\u6709\u5355\u670D\u52A1 stop \u80FD\u505C\u5916\u90E8\u6765\u6E90\u7684\u8FDB\u7A0B\u3002\n */\n async stop(): Promise<StopKind> {\n this.manualStop = true;\n if (this.restartTimer) {\n clearTimeout(this.restartTimer);\n this.restartTimer = null;\n }\n\n /* \u4E0E\u539F\u5148 cmdStop \u4E00\u81F4\uFF1ABDS \u88AB\u5224\u5B9A\u4E3A\u5916\u90E8\u65F6\u76F4\u63A5\u6309\u955C\u50CF\u7ED3\u675F\uFF0C\u4E0D\u8D70 stdin stop */\n if (this.name === \"bds\") {\n const probe = await probeBdsStatus({\n managedPid: this.pid,\n hasStdin: Boolean(this.proc?.stdin),\n rootDir: ROOT,\n });\n if (probe.state === \"external\") {\n await killExternalBedrock();\n this.dropStaleHandle();\n return \"external\";\n }\n }\n\n const managed = Boolean(this.proc && this.running);\n if (managed) await this.stopManagedChild();\n\n /* db / qq\uFF1A\u6258\u7BA1\u505C\u5B8C\u540E\u4ECD\u6309\u811A\u672C\u518D\u626B\u4E00\u904D\uFF0C\u6E05\u6389\u540C\u673A\u4E0A\u7684\u5916\u90E8\u5B9E\u4F8B\uFF08\u4E0E\u539F stop \u76F8\u540C\uFF09 */\n if (this.name === \"db\" || this.name === \"qq\") {\n const killed = await killNodeServiceByScript(this.name);\n if (this.name === \"qq\") clearQqRuntimeFile();\n if (managed) return \"managed\";\n return killed.length > 0 ? \"external\" : \"idle\";\n }\n\n if (managed) return \"managed\";\n return \"idle\";\n }\n\n /**\n * \u4F18\u96C5\u505C\u6B62\u5F53\u524D\u6258\u7BA1\u5B50\u8FDB\u7A0B\uFF08stdin stop \u6216 SIGTERM\uFF0C\u8D85\u65F6\u540E SIGKILL\uFF09\u3002\n * \u4F7F\u7528\u573A\u666F\uFF1AService.stop \u786E\u8BA4\u672C\u8FDB\u7A0B\u4ECD\u6301\u6709\u5B50\u8FDB\u7A0B\u65F6\u8C03\u7528\uFF1B\u903B\u8F91\u4E0E\u539F\u5148 stop \u4E3B\u4F53\u76F8\u540C\u3002\n */\n private async stopManagedChild(): Promise<void> {\n if (!this.proc || !this.running) return;\n this.events.emit(\"output\", \"stopping...\", \"info\");\n\n if (this.def.stopCommand && this.proc.stdin) {\n this.proc.stdin.write(this.def.stopCommand + \"\\n\");\n } else {\n this.proc.kill(\"SIGTERM\");\n }\n\n return new Promise((resolve) => {\n const timeout = setTimeout(() => {\n if (this.proc) {\n this.events.emit(\"output\", \"force kill\", \"error\");\n try {\n this.proc.kill(\"SIGKILL\");\n } catch {\n /* ignore */\n }\n }\n resolve();\n }, this.def.stopTimeout);\n\n this.proc?.on(\"exit\", () => {\n clearTimeout(timeout);\n resolve();\n });\n });\n }\n\n /**\n * \u5916\u90E8\u505C\u670D\u540E\u4E22\u6389\u5931\u6548\u7684\u6258\u7BA1\u53E5\u67C4\uFF0C\u907F\u514D\u7D27\u63A5\u7740\u7684 start/restart \u8BEF\u5224\u300C\u5DF2\u5728\u8FD0\u884C\u300D\u3002\n * \u4E0D\u8D70 cleanup\uFF1A\u90A3\u4F1A\u8FDE\u5E26\u505C\u6389\u6A21\u5757\u9644\u5C5E\u8FDB\u7A0B\uFF0C\u800C\u539F\u5148\u7684\u5916\u90E8 BDS stop \u5E76\u4E0D\u8FD9\u4E48\u505A\u3002\n */\n private dropStaleHandle(): void {\n if (!this.running && !this.proc) return;\n const stale = this.proc;\n this.proc = null;\n this.running = false;\n this.pid = 0;\n this.startTime = null;\n this.events.emit(\"state\", { name: this.name, running: false, pid: 0 });\n if (stale && stale.exitCode === null) {\n try {\n stale.kill(\"SIGKILL\");\n } catch {\n /* \u5916\u90E8\u955C\u50CF\u7ED3\u675F\u65F6\u8FD9\u4E2A\u53E5\u67C4\u53EF\u80FD\u5DF2\u7ECF\u9000\u51FA */\n }\n }\n }\n\n forceStop(): void {\n const child = this.proc;\n this.manualStop = true;\n if (this.restartTimer) {\n clearTimeout(this.restartTimer);\n this.restartTimer = null;\n }\n this.cleanup();\n if (!child) return;\n try {\n child.kill(\"SIGKILL\");\n } catch {\n /* ignore */\n }\n }\n\n async restart(): Promise<StartOutcome> {\n await this.stop();\n return this.start();\n }\n\n getRecentLogs(n: number): LogLine[] {\n return this.logs.slice(-n);\n }\n\n /**\n * \u63A2\u6D4B\u53D1\u73B0\u8FDB\u7A0B\u5DF2\u6B7B\u540E\u56DE\u5199\u672C\u5730\u72B6\u6001\uFF08\u4E0D\u8BBE manualStop\uFF0C\u4EE5\u4FBF exit \u56DE\u8C03\u4ECD\u53EF\u6309\u9700 autoRestart\uFF09\u3002\n */\n markStoppedFromProbe(): void {\n if (!this.running && !this.proc) return;\n this.cleanup();\n }\n\n private cleanup(): void {\n const wasRunning = this.running || this.proc !== null;\n const exitingPid = this.pid;\n this.proc = null;\n this.running = false;\n this.pid = 0;\n this.startTime = null;\n if (this.name === \"bds\" && exitingPid > 0) {\n const filePid = readBdsPidFile(ROOT);\n if (filePid === exitingPid) {\n clearBdsPidFile(ROOT);\n }\n stopModuleSidecars();\n }\n if (this.name === \"tunnel\" && exitingPid > 0) clearTunnelRuntime(exitingPid);\n if (wasRunning) {\n this.events.emit(\"state\", { name: this.name, running: false, pid: 0 });\n }\n }\n}\n\nfunction createServices(): Record<ServiceName, Service> {\n /* \u5404\u670D\u52A1/CLI \u7528 SDK ensureCoreConfigs \u64AD\u79CD\uFF08\u542B $schema\uFF09\uFF0C\u4E0D\u518D\u4ECE configs-default \u62F7\u8D1D\u3002 */\n ensureCoreConfigs(ROOT, [\"bds_updater\", \"qq_config\", \"db_config\"]);\n ensurePackUpdateConfigFile();\n void import(\"./module-update/index.js\")\n .then((mod) => mod.ensureModuleUpdateConfigFile())\n .catch((error: unknown) => {\n const message = error instanceof Error ? error.message : String(error);\n pushUnifiedLog(message, \"module\", \"warn\");\n });\n const bdsCfg = loadEnsuredConfig(ROOT, \"bds_updater.json\", \"bds_updater\", { ...DEFAULT_BDS_UPDATER_CONFIG } as Record<\n string,\n unknown\n >) as BdsUpdaterConfig;\n const qqCfg = loadEnsuredConfig(ROOT, \"qq_config.json\", \"qq_config\", { ...DEFAULT_QQ_CONFIG } as Record<\n string,\n unknown\n >) as QQBridgeConfig;\n const dbCfg = loadEnsuredConfig(ROOT, \"db_config.json\", \"db_config\", { ...DEFAULT_DB_CONFIG } as Record<\n string,\n unknown\n >) as DBConfig;\n const rawBdsPath = String(bdsCfg.bds_path ?? \"\").trim();\n if (process.platform !== \"win32\" && /^[A-Za-z]:[\\\\/]/.test(rawBdsPath)) {\n throw new Error(\n `configs/bds_updater.json \u7684 bds_path \u662F Windows \u8DEF\u5F84\uFF08${rawBdsPath}\uFF09\u3002` +\n `\u8BF7\u6539\u6210\u76F8\u5BF9 SFMC_ROOT \u7684\u8DEF\u5F84\uFF0C\u4F8B\u5982 \"BDS\"\u3002`\n );\n }\n const bdsPath = path.resolve(ROOT, rawBdsPath || \".\");\n const useLlbotBackend = qqCfg.qq_backend === \"llbot\";\n const qqEnabled = qqCfg.qq_enabled !== false;\n // \u5B98\u65B9 Webhook \u7531\u4E91\u7AEF\u63A5\u6536\uFF1B\u4EC5\u5207\u6362\u4F20\u8F93\u65B9\u5F0F\u5373\u53EF\u907F\u514D\u672C\u673A\u518D\u542F\u52A8\u4E00\u4E2A\u6865\u3002\n const qqExternal = !useLlbotBackend && qqCfg.official?.transport === \"webhook\";\n const tunnelCfg = qqCfg.official?.tunnel;\n const tunnelEnabled = qqEnabled && qqExternal && tunnelCfg?.enabled === true;\n const tunnelHost = String(tunnelCfg?.host ?? \"\").trim();\n const tunnelRemotePort = tunnelCfg?.remotePort ?? 13001;\n const llbotEnabled = qqCfg.llbot?.enabled !== false;\n const llbotLaunch = resolveLlbotLaunch(qqCfg.llbot?.path, qqCfg.llbot?.cwd);\n const llbotPath = llbotLaunch.exe;\n const llbotCwd = llbotLaunch.cwd;\n const dbPort = dbCfg.db_port ?? 3001;\n dbHealthPort = dbPort;\n qqBackendMode = useLlbotBackend ? \"llbot\" : \"official\";\n const bdsExe = bdsExePath(bdsPath);\n const qqTitle = useLlbotBackend ? \"QQ (llbot)\" : \"QQ (official)\";\n\n return {\n bds: new Service({\n name: \"bds\",\n title: \"BDS\",\n cmd: bdsExe,\n args: [],\n cwd: bdsPath,\n env: bdsSpawnEnvExtra(bdsPath),\n stopCommand: \"stop\",\n stopTimeout: 30000,\n /* \u5D29\u6E83\u62C9\u8D77\u7531 sfmc daemon \u56FA\u5B9A\u5F00\u542F\uFF1B\u4E0D\u518D\u8BFB bds_updater.crash_restart */\n autoRestart: true,\n restartDelay: 5000,\n validate: () => {\n if (!fs.existsSync(bdsExe)) return `not found: ${bdsExe}`;\n return null;\n },\n beforeStart: async () => {\n ensureBdsExecutable(bdsExe);\n /* \u5148\u88C5\u6536\u4EF6\u7BB1\u7B2C\u4E09\u65B9\u5305\uFF0C\u518D\u68C0\u67E5 CF \u66F4\u65B0\uFF0C\u518D\u5347\u7EA7\u4E1A\u52A1\u6A21\u5757\uFF0C\u518D\u8DD1\u6A21\u5757\u805A\u5408\u95F8\u95E8 */\n const { scanAndInstallInbox } = await import(\"./world-packs.js\");\n await scanAndInstallInbox({ interactive: false });\n const { runPackUpdatesOnBdsStart } = await import(\"./pack-update/index.js\");\n await runPackUpdatesOnBdsStart();\n const { runModuleUpdatesOnBdsStart } = await import(\"./module-update/index.js\");\n await runModuleUpdatesOnBdsStart();\n const { ensurePacksReady } = await import(\"./pack-lifecycle.js\");\n await ensurePacksReady();\n },\n onLogLine: (line) =>\n reportBdsPlayerSession(line, {\n port: dbPort,\n ...(dbCfg.http_auth ? { authToken: dbCfg.http_auth } : {}),\n }),\n }),\n\n db: new Service({\n name: \"db\",\n title: \"DB Server\",\n service: \"db\",\n cwd: ROOT,\n stopTimeout: 10000,\n autoRestart: true,\n restartDelay: 3000,\n env: { DB_PORT: String(dbPort) },\n }),\n\n tunnel: new Service({\n name: \"tunnel\",\n title: \"QQ SSH Tunnel\",\n cmd: \"ssh\",\n args: [\n \"-N\", \"-T\", \"-o\", \"BatchMode=yes\", \"-o\", \"ConnectTimeout=10\",\n \"-o\", \"ExitOnForwardFailure=yes\", \"-o\", \"ServerAliveInterval=30\",\n \"-o\", \"ServerAliveCountMax=3\",\n \"-R\", `127.0.0.1:${tunnelRemotePort}:127.0.0.1:${dbPort}`,\n tunnelHost,\n ],\n cwd: ROOT,\n stopTimeout: 10000,\n autoRestart: true,\n restartDelay: 5000,\n optional: !tunnelEnabled,\n validate: () => {\n if (!tunnelEnabled) return \"QQ tunnel disabled (official webhook tunnel.enabled=false)\";\n if (!/^[A-Za-z0-9_][A-Za-z0-9_.-]*$/.test(tunnelHost)) return \"invalid official.tunnel.host\";\n if (!Number.isInteger(tunnelRemotePort) || tunnelRemotePort < 1 || tunnelRemotePort > 65535) {\n return \"invalid official.tunnel.remotePort\";\n }\n return null;\n },\n }),\n\n qq: new Service({\n name: \"qq\",\n title: qqTitle,\n service: \"qq\",\n cwd: ROOT,\n stopTimeout: 10000,\n // \u7F3A\u51ED\u636E\u65F6 validate \u62E6\u4E0B\uFF0C\u4E0D\u4F1A spawn\u2192exit(1)\u2192autoRestart \u6B7B\u5FAA\u73AF\n autoRestart: true,\n restartDelay: 3000,\n optional: !qqEnabled || qqExternal,\n validate: () => {\n if (!qqEnabled) return \"QQ bridge disabled (qq_enabled=false)\";\n if (qqExternal) return \"QQ bridge runs externally (official.transport=webhook)\";\n if (!useLlbotBackend) {\n if (!String(qqCfg.official?.app_id ?? \"\").trim() || !String(qqCfg.official?.app_secret ?? \"\").trim()) {\n return \"missing official.app_id / official.app_secret\";\n }\n }\n return null;\n },\n }),\n\n llbot: new Service({\n name: \"llbot\",\n title: \"LLBot\",\n cmd: llbotPath,\n args: [],\n cwd: llbotCwd,\n stopTimeout: 10000,\n autoRestart: false,\n restartDelay: 5000,\n // official \u6216\u672A\u542F\u7528\u65F6\u771F\u6B63 skip\uFF0C\u4E0D throw\n optional: !useLlbotBackend || !llbotEnabled,\n validate: () => {\n if (!useLlbotBackend) return \"LLBot skipped (qq_backend!=llbot)\";\n if (!llbotEnabled) return \"LLBot disabled (llbot.enabled=false)\";\n if (!fs.existsSync(llbotPath)) return `not found: ${llbotPath}`;\n return null;\n },\n }),\n };\n}\n\nexport let services: Record<ServiceName, Service> = createServices();\n\nexport function refreshServices(): void {\n forceStopAll();\n services = createServices();\n}\n\nexport const START_ORDER: ServiceName[] = [\"db\", \"tunnel\", \"qq\", \"llbot\", \"bds\"];\n\nexport async function startAll(): Promise<StartAllResult> {\n const result: StartAllResult = { started: [], skipped: [], failed: [] };\n for (const name of START_ORDER) {\n const svc = services[name];\n if (!svc) continue;\n try {\n const outcome = await svc.start();\n if (outcome.status === \"skipped\") {\n result.skipped.push({ name, reason: outcome.reason });\n svc.events.emit(\"output\", `skipped: ${outcome.reason}`, \"info\");\n } else {\n result.started.push(name);\n }\n } catch (e) {\n const reason = (e as Error).message;\n result.failed.push({ name, reason });\n svc.events.emit(\"output\", `start error: ${reason}`, \"error\");\n }\n }\n return result;\n}\n\n/**\n * \u6309\u542F\u52A8\u9006\u5E8F\u505C\u6B62\u5168\u90E8\u670D\u52A1\uFF0C\u5305\u542B status \u91CC\u6807\u6210\u300C\u5916\u90E8\u300D\u7684\u5B9E\u4F8B\u3002\n * \u4F7F\u7528\u573A\u666F\uFF1A`stop all`\u3001`restart -all`\u3001\u5B88\u62A4\u8FDB\u7A0B shutdown\u3002\n * \u5177\u4F53\u505C\u5916\u90E8\u8FDB\u7A0B\u7684\u89C4\u5219\u5728 Service.stop\uFF0C\u4E0E\u5355\u670D\u52A1 `stop` \u76F8\u540C\u3002\n */\nexport async function stopAll(): Promise<void> {\n const pending = [...START_ORDER]\n .reverse()\n .map((name) => services[name])\n .filter((service): service is Service => Boolean(service))\n .map((service) => service.stop());\n await Promise.allSettled(pending);\n}\n\nexport function forceStopAll(): void {\n for (const service of Object.values(services)) service.forceStop();\n}\n\nexport type ServiceStateEvent = { name: ServiceName; running: boolean; pid: number };\n\n/** \u8BA2\u9605\u4EFB\u610F\u670D\u52A1\u542F\u505C\uFF08\u542B\u63A2\u6D4B\u56DE\u5199\uFF09\uFF1B\u8FD4\u56DE\u53D6\u6D88\u51FD\u6570 */\nexport function onServiceStateChange(fn: (ev: ServiceStateEvent) => void): () => void {\n /* CLI \u8FDB\u7A0B\u4E0D\u6301\u6709 Service \u5B50\u8FDB\u7A0B\uFF1A\u6539\u8BA2\u5B88\u62A4\u8FDB\u7A0B\u63A8\u9001\u7684\u8FDC\u7A0B\u72B6\u6001\u4E8B\u4EF6 */\n if (!isDaemonServer()) {\n return onRemoteServiceStateChange(fn);\n }\n const handler = (ev: ServiceStateEvent): void => {\n fn(ev);\n };\n for (const service of Object.values(services)) {\n service.events.on(\"state\", handler);\n }\n return () => {\n for (const service of Object.values(services)) {\n service.events.off(\"state\", handler);\n }\n };\n}\n\n/** \u82E5\u672C\u5730\u6807\u8BB0 running \u4F46 OS \u8FDB\u7A0B\u5DF2\u6B7B\uFF0C\u56DE\u6536\u5185\u5B58\u6807\u5FD7 */\nasync function reconcileManagedAlive(service: Service): Promise<boolean> {\n if (!service.running) return false;\n if (service.pid > 0 && !(await isProcessAlive(service.pid))) {\n service.markStoppedFromProbe();\n return false;\n }\n return service.running;\n}\n\n/**\n * \u7EDF\u4E00\u8FD0\u884C\u6001\u67E5\u8BE2\uFF08\u6743\u5A01\u5165\u53E3\uFF09\uFF1AOS/\u5065\u5EB7\u63A2\u6D4B + \u56DE\u5199 Service \u5185\u5B58\u6807\u5FD7\u3002\n * status / Tab \u53D1\u9001\u76EE\u6807 / reload \u7B49\u5747\u5E94\u8D70\u6B64\u63A5\u53E3\uFF0C\u52FF\u76F4\u63A5\u8BFB `service.running`\u3002\n * CLI \u8FDB\u7A0B\u7ECF\u5B88\u62A4\u8FDB\u7A0B RPC \u83B7\u53D6\uFF1B\u5B88\u62A4\u8FDB\u7A0B\u5185\u8D70\u672C\u5730\u63A2\u6D3B\u3002\n */\nexport async function queryServicesRuntime(): Promise<ServiceStatus[]> {\n if (!isDaemonServer()) {\n const { queryRuntimeViaDaemon } = await import(\"./daemon/client.js\");\n return queryRuntimeViaDaemon();\n }\n return queryServicesRuntimeLocal();\n}\n\n/** \u5B88\u62A4\u8FDB\u7A0B\u5185\u672C\u5730\u63A2\u6D3B\u5B9E\u73B0\uFF08\u4EA6\u4F9B server status \u7EC4\u88C5 rows\uFF09 */\nexport async function queryServicesRuntimeLocal(): Promise<ServiceStatus[]> {\n return Promise.all(\n SERVICE_NAMES.map(async (name) => {\n const service = services[name];\n let running = false;\n let pid = 0;\n let uptime = \"\u2014\";\n let ownership: \"managed\" | \"external\" | undefined;\n\n if (name === \"bds\") {\n const probe = await probeBdsStatus({\n managedPid: service.pid,\n hasStdin: Boolean(service.proc?.stdin),\n rootDir: ROOT,\n });\n if (probe.state === \"managed\") {\n running = true;\n pid = probe.pid;\n uptime = service.uptime;\n ownership = \"managed\";\n /* \u63A2\u6D4B\u4E3A managed \u4F46\u672C\u5730\u5DF2\u6807\u505C\uFF1A\u4FDD\u6301\u63A2\u6D4B\u7ED3\u679C\uFF0C\u4E0D\u5F3A\u5236\u6539\u5185\u5B58\uFF08stdin \u4ECD\u53EF\u7528\uFF09 */\n } else if (probe.state === \"external\") {\n running = true;\n pid = probe.pid;\n ownership = \"external\";\n /* \u5916\u90E8\u8FDB\u7A0B\uFF1A\u672C\u5730 managed \u53E5\u67C4\u5DF2\u5931\u6548\u5219\u56DE\u6536 */\n if (service.running && service.pid !== probe.pid) {\n service.markStoppedFromProbe();\n } else if (service.running && !(await isProcessAlive(service.pid))) {\n service.markStoppedFromProbe();\n }\n } else {\n running = false;\n if (service.running || service.proc) {\n service.markStoppedFromProbe();\n }\n }\n } else if (name === \"db\") {\n const managed = await reconcileManagedAlive(service);\n if (managed) {\n running = true;\n pid = service.pid;\n uptime = service.uptime;\n ownership = \"managed\";\n } else if (await probeDbHealth(dbHealthPort)) {\n running = true;\n ownership = \"external\";\n const pids = await findNodeServicePids(\"db\");\n pid = pids[0] ?? 0;\n }\n } else if (name === \"qq\") {\n const managed = await reconcileManagedAlive(service);\n if (managed) {\n running = true;\n pid = service.pid;\n uptime = service.uptime;\n ownership = \"managed\";\n } else {\n const probe = await probeQqRuntime();\n if (probe.alive) {\n running = true;\n pid = probe.pid;\n ownership = \"external\";\n } else {\n const pids = await findNodeServicePids(\"qq\");\n if (pids.length > 0) {\n running = true;\n pid = pids[0]!;\n ownership = \"external\";\n }\n }\n }\n } else if (name === \"tunnel\") {\n const managed = await reconcileManagedAlive(service);\n if (managed) {\n running = true;\n pid = service.pid;\n uptime = service.uptime;\n ownership = \"managed\";\n } else {\n pid = await probeTunnelRuntime();\n running = pid > 0;\n if (running) ownership = \"external\";\n }\n } else {\n const managed = await reconcileManagedAlive(service);\n if (managed) {\n running = true;\n pid = service.pid;\n uptime = service.uptime;\n ownership = \"managed\";\n }\n }\n\n return {\n name,\n title: service.title,\n running,\n pid,\n uptime,\n ...(ownership ? { ownership } : {}),\n };\n })\n );\n}\n\n/** \u5355\u670D\u52A1\u662F\u5426\u5728\u8DD1\uFF08\u542B\u5916\u90E8\u5B9E\u4F8B\uFF09 */\nexport async function isServiceRunning(name: ServiceName): Promise<boolean> {\n const rows = await queryServicesRuntime();\n return rows.some((r) => r.name === name && r.running);\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["ROOT"]
7
7
  }
@@ -1 +1 @@
1
- {"version":3,"file":"wizard.d.ts","sourceRoot":"","sources":["../src/wizard.ts"],"names":[],"mappings":"AAiHA,wBAAsB,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,CAyV/C"}
1
+ {"version":3,"file":"wizard.d.ts","sourceRoot":"","sources":["../src/wizard.ts"],"names":[],"mappings":"AAsHA,wBAAsB,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,CAyV/C"}
package/dist/wizard.js CHANGED
@@ -73,6 +73,8 @@ function seedNpmRuntimeLayout(rootDir) {
73
73
  ensureCoreConfigs(rootDir, ["db_config", "qq_config", "bds_updater", "permissions"]);
74
74
  if (path.resolve(rootDir) === path.resolve(ROOT)) {
75
75
  ensurePackUpdateConfigFile();
76
+ void import("./module-update/index.js").then((mod) => mod.ensureModuleUpdateConfigFile()).catch(() => {
77
+ });
76
78
  }
77
79
  const modulesRoot = path.join(rootDir, "modules");
78
80
  const packagesDir = path.join(modulesRoot, "packages");
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/wizard.ts"],
4
- "sourcesContent": ["import { confirm, intro, isCancel, multiselect, note, outro, password, select, tasks, text } from \"@clack/prompts\";\nimport {\n configPath,\n ensureCoreConfigs,\n modulePath,\n patchJson as patchConfig,\n readJson,\n withConfigSchema,\n writeJson,\n type Catalog,\n type ConfigName,\n type ModuleLock,\n type QQBridgeConfig,\n} from \"@sfmc-bds/sdk/node/config\";\nimport { bdsExePath } from \"@sfmc-bds/bds-tools/host-platform\";\nimport { execFileSync } from \"node:child_process\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { ensureDirectory, pickDirectory } from \"./interactive-prompts.js\";\nimport { persistLocale, t, type Locale } from \"./i18n/index.js\";\nimport { llbotExeName } from \"./llbot-launch.js\";\nimport { ROOT, isMonorepoLayout, isRuntimeInitialized, resolveFetchModule, spawnService } from \"./runtime.js\";\nimport { ensurePackUpdateConfigFile } from \"./pack-update/index.js\";\nimport { c } from \"./theme.js\";\n\n/** Shallow-merge write for top-level configs. Delegates to SDK; do not mkdir+writeFileSync here. */\nfunction patchJson<T extends object>(rootDir: string, name: ConfigName, updates: Partial<T>): void {\n patchConfig<T>(configPath(rootDir, name), updates);\n}\n\nasync function waitForHealth(port: number, ms = 15000): Promise<boolean> {\n const t = Date.now();\n while (Date.now() - t < ms) {\n try {\n if ((await fetch(`http://127.0.0.1:${port}/api/health`)).ok) return true;\n } catch {\n /* retry */\n }\n await new Promise((r) => setTimeout(r, 300));\n }\n return false;\n}\n\n/** \u8FD0\u884C\u65F6\u5FC5\u9700\u76EE\u5F55\u63A2\u6D4B(configs / modules) */\nconst RUNTIME_DIRS = [\n { target: \"configs\", npmTarget: \"configs\" },\n { target: \"modules\", npmTarget: \"modules\" },\n] as const;\n\nfunction missingRuntimeAssets(rootDir: string): string[] {\n return RUNTIME_DIRS.flatMap(({ target, npmTarget }) => {\n const directory = path.join(rootDir, npmTarget);\n try {\n return fs.statSync(directory).isDirectory() && fs.readdirSync(directory).length > 0 ? [] : [target];\n } catch {\n return [target];\n }\n });\n}\n\nasync function runBdsUpdate(rootDir: string, channel: string): Promise<{ code: number | null; output: string }> {\n const child = spawnService(\"update\", [`--channel=${channel}`, \"--force\", \"--no-start\"], {\n cwd: rootDir,\n stdio: \"pipe\",\n });\n const output: string[] = [];\n child.stdout?.on(\"data\", (data: Buffer) => output.push(data.toString()));\n child.stderr?.on(\"data\", (data: Buffer) => output.push(data.toString()));\n\n return new Promise((resolve) => {\n child.once(\"error\", (error) => resolve({ code: null, output: `${output.join(\"\")}${error.message}` }));\n child.once(\"close\", (code) => resolve({ code, output: output.join(\"\") }));\n });\n}\n\nasync function prepareRuntimeAssets(rootDir: string): Promise<void> {\n /* monorepo \u5E03\u5C40\uFF1Aconfigs/ modules/ \u5E94\u7531 pnpm workspace \u63D0\u4F9B */\n if (isMonorepoLayout(rootDir)) {\n const missing = missingRuntimeAssets(rootDir);\n if (missing.length > 0) {\n throw new Error(t(\"wizard.runtimeMissingAssets\", { list: missing.join(\", \") }));\n }\n return;\n }\n\n seedNpmRuntimeLayout(rootDir);\n}\n\n/** \u975E monorepo \u7684 npm \u5B89\u88C5\u5E03\u5C40\uFF1Aensure \u914D\u7F6E\u9AA8\u67B6 + \u7A7A modules */\nfunction seedNpmRuntimeLayout(rootDir: string): void {\n ensureCoreConfigs(rootDir, [\"db_config\", \"qq_config\", \"bds_updater\", \"permissions\"]);\n /* pack-update \u7684 ensure \u4F7F\u7528 runtime ROOT\uFF1Bnpm \u5E03\u5C40\u4E0B\u5E94\u4E0E rootDir \u4E00\u81F4 */\n if (path.resolve(rootDir) === path.resolve(ROOT)) {\n ensurePackUpdateConfigFile();\n }\n\n const modulesRoot = path.join(rootDir, \"modules\");\n const packagesDir = path.join(modulesRoot, \"packages\");\n fs.mkdirSync(packagesDir, { recursive: true });\n\n const catalogPath = path.join(modulesRoot, \"catalog.json\");\n if (!fs.existsSync(catalogPath)) {\n writeJson(\n catalogPath,\n withConfigSchema({ version: 1, modules: [] }, \"module_catalog\", \"modules\")\n );\n }\n const lockPath = path.join(modulesRoot, \"module-lock.json\");\n if (!fs.existsSync(lockPath)) {\n writeJson(lockPath, { version: 1, modules: {} });\n }\n}\n\nexport async function runWizard(): Promise<void> {\n intro(c.bold(t(\"wizard.intro\")));\n\n const langPick = await select({\n message: t(\"locale.wizard\"),\n options: [\n { value: \"zh-CN\", label: t(\"locale.opt.zh\") },\n { value: \"en\", label: t(\"locale.opt.en\") },\n ],\n initialValue: \"zh-CN\",\n });\n if (!isCancel(langPick)) {\n persistLocale(ROOT, langPick as Locale);\n }\n\n // Already initialized only when runtime.json#initialized_at is set (empty db_config skeleton does not count).\n if (isRuntimeInitialized()) {\n const r = await confirm({ message: t(\"wizard.rerun\"), initialValue: false });\n if (isCancel(r) || !r) {\n outro(c.dim(t(\"wizard.skipped\")));\n return;\n }\n }\n // Step 1: Runtime Environment\uFF08\u53EA\u64AD\u79CD configs/modules\uFF0C\u4E0D\u5199 initialized_at\u3001\u4E0D\u5EFA data/\uFF09\n const rootDir = ROOT;\n note(c.text(t(\"wizard.runtimeRoot\", { root: rootDir })), t(\"wizard.step1\"));\n\n try {\n await prepareRuntimeAssets(rootDir);\n } catch (error) {\n outro(c.red(t(\"wizard.prepFailed\", { message: (error as Error).message })));\n return;\n }\n\n // Step 2: External runtime paths\n note(c.text(t(\"wizard.step2Note\")), t(\"wizard.step2\"));\n\n const bdsResolved = await pickDirectory(t(\"wizard.bdsDir\"), path.join(rootDir, \"BDS\"));\n if (!ensureDirectory(bdsResolved)) {\n outro(c.red(t(\"wizard.cannotCreateBds\", { dir: bdsResolved })));\n return;\n }\n\n /* QQ \u6865\uFF1A\u9009\u540E\u7AEF \u2192 official \u51ED\u636E / llbot \u8DEF\u5F84\uFF1B\u7981\u7528\u5219 qq_enabled=false */\n const qqBackendPick = await select({\n message: t(\"wizard.qqBackend\"),\n options: [\n { value: \"official\", label: t(\"wizard.qqBackend.official\"), hint: t(\"wizard.qqBackend.officialHint\") },\n { value: \"llbot\", label: t(\"wizard.qqBackend.llbot\"), hint: t(\"wizard.qqBackend.llbotHint\") },\n { value: \"disabled\", label: t(\"wizard.qqBackend.disabled\"), hint: t(\"wizard.qqBackend.disabledHint\") },\n ],\n initialValue: \"official\",\n });\n const qqBackendChoice =\n isCancel(qqBackendPick) || !qqBackendPick ? \"official\" : String(qqBackendPick);\n\n let qqEnabled = true;\n let qqBackend: \"official\" | \"llbot\" = \"official\";\n let qqAppId = \"\";\n let qqAppSecret = \"\";\n let qqSandbox = false;\n let qqGroupOpenid = \"\";\n let llbotPath: string | undefined;\n let llbotEnabled = false;\n\n if (qqBackendChoice === \"disabled\") {\n qqEnabled = false;\n } else if (qqBackendChoice === \"llbot\") {\n qqBackend = \"llbot\";\n llbotEnabled = true;\n const picked = await pickDirectory(t(\"wizard.llbotDir\"), path.join(rootDir, \"LLBOT\"));\n if (ensureDirectory(picked)) {\n llbotPath = picked;\n } else {\n llbotPath = path.join(rootDir, \"LLBOT\");\n note(c.text(t(\"wizard.usingDefault\", { path: llbotPath })), t(\"common.tips\"));\n }\n } else {\n qqBackend = \"official\";\n const appIdRaw = await text({\n message: t(\"wizard.qqAppId\"),\n placeholder: \"102xxxxx\",\n validate: (v: any): any => {\n if (!String(v ?? \"\").trim()) return t(\"wizard.valueRequired\");\n },\n });\n if (!isCancel(appIdRaw)) qqAppId = String(appIdRaw).trim();\n\n const secretRaw = await password({\n message: t(\"wizard.qqAppSecret\"),\n validate: (v: any): any => {\n if (!String(v ?? \"\").trim()) return t(\"wizard.valueRequired\");\n },\n });\n if (!isCancel(secretRaw)) qqAppSecret = String(secretRaw).trim();\n\n const sandboxPick = await confirm({\n message: t(\"wizard.qqSandbox\"),\n initialValue: false,\n });\n if (!isCancel(sandboxPick)) qqSandbox = !!sandboxPick;\n\n const openidRaw = await text({\n message: t(\"wizard.qqGroupOpenid\"),\n placeholder: t(\"wizard.qqGroupOpenidHint\"),\n });\n if (!isCancel(openidRaw)) qqGroupOpenid = String(openidRaw).trim();\n }\n\n const dbDirInput = await pickDirectory(t(\"wizard.dbDir\"), path.join(rootDir, \"data\"));\n const dbDir = ensureDirectory(dbDirInput) ? dbDirInput : path.join(rootDir, \"data\");\n if (dbDir !== dbDirInput) {\n note(c.text(t(\"wizard.usingDefault\", { path: dbDir })), t(\"common.tips\"));\n }\n const dbPortRaw = await text({\n message: t(\"wizard.dbPort\"),\n initialValue: \"3001\",\n validate: (v: any): any => {\n const n = parseInt(v, 10);\n if (isNaN(n) || n < 1024 || n > 65535) return t(\"wizard.portRange\");\n if (v.length === 0) return t(\"wizard.valueRequired\");\n },\n });\n const dbPort = isCancel(dbPortRaw) ? 3001 : parseInt(dbPortRaw as string, 10);\n\n // Step 3: BDS environment\n const bdsExe = bdsExePath(bdsResolved);\n const bdsExists = fs.existsSync(bdsExe);\n\n note(\n bdsExists\n ? c.green(t(\"wizard.bdsFound\", { path: bdsResolved }))\n : c.yellow(t(\"wizard.bdsNotFound\", { path: bdsResolved })),\n t(\"wizard.step3\")\n );\n\n const EULA = await confirm({\n message: t(\"wizard.eula\"),\n initialValue: false,\n });\n if (isCancel(EULA) || !EULA) {\n outro(c.yellow(t(\"wizard.disagreed\")));\n return;\n }\n\n let downloadBds = false;\n let bdsChannel = \"release\";\n let backupDir = path.join(path.dirname(bdsResolved), \"backups\");\n let preserve: string[] = [];\n\n if (!bdsExists) {\n const d = await confirm({ message: t(\"wizard.downloadBds\"), initialValue: true });\n if (!isCancel(d) && d) {\n const ch = await select({\n message: t(\"wizard.selectChannel\"),\n options: [\n { value: \"release\", label: t(\"wizard.channel.release\"), hint: t(\"wizard.channel.releaseHint\") },\n { value: \"preview\", label: t(\"wizard.channel.preview\"), hint: t(\"wizard.channel.previewHint\") },\n ],\n });\n if (!isCancel(ch)) {\n bdsChannel = ch as string;\n downloadBds = true;\n }\n if (!ensureDirectory(backupDir)) {\n outro(c.red(t(\"wizard.cannotCreateBackup\", { dir: backupDir })));\n return;\n }\n }\n }\n\n backupDir = await pickDirectory(t(\"wizard.backupDir\"), backupDir);\n const preserveOptions = [\n { value: \"server.properties\", label: \"server.properties\", hint: t(\"wizard.preserve.serverProps\") },\n { value: \"whitelist.json\", label: \"whitelist.json\" },\n { value: \"permissions.json\", label: \"permissions.json\" },\n { value: \"allowlist.json\", label: \"allowlist.json\" },\n { value: \"worlds\", label: \"worlds/\", hint: t(\"wizard.preserve.worlds\") },\n { value: \"config\", label: \"config/\", hint: t(\"wizard.preserve.config\") },\n ] as const;\n const pr = await multiselect({\n message: t(\"wizard.preserve\"),\n options: [...preserveOptions],\n initialValues: preserveOptions.map((o) => o.value),\n required: false,\n });\n if (!isCancel(pr)) preserve = pr as string[];\n note(c.yellow(t(\"wizard.updaterTip\")), t(\"common.tips\"));\n\n // Step 4: Module initialization\n const catalog = readJson<Catalog>(modulePath(rootDir, \"catalog.json\")) ?? {\n version: 1,\n modules: [],\n };\n const catalogModules: Array<{ id: string; name?: string; description?: string; canDisable?: boolean }> = [];\n if (Array.isArray(catalog.modules)) {\n for (const m of catalog.modules) {\n catalogModules.push({\n id: String(m.id ?? \"\"),\n name: String(m.name ?? m.id ?? \"\"),\n description: String(m.description ?? \"\"),\n canDisable: m.canDisable !== false,\n });\n }\n }\n\n note(\n c.text(\n catalogModules.length > 0\n ? t(\"wizard.modulesFound\", { count: catalogModules.length })\n : t(\"wizard.modulesNone\")\n ),\n t(\"wizard.step4\")\n );\n\n let selectedModules: string[] = [];\n const lockedMd: any[] = [];\n const optionalMd: any[] = [];\n catalogModules.forEach((k) => {\n const option = {\n value: k.id,\n label: String(k.name),\n hint: String(k.description ?? t(\"wizard.emptyHint\")),\n };\n if (k.canDisable === false) {\n lockedMd.push({ ...option, disabled: true });\n } else {\n optionalMd.push(option);\n }\n });\n if (catalogModules.length > 0) {\n const r = await multiselect({\n message: t(\"wizard.enableModules\"),\n options: [...lockedMd, ...optionalMd],\n required: false,\n });\n if (!isCancel(r)) selectedModules = r as string[];\n }\n\n const wizardTasks = [\n {\n title: t(\"wizard.updatingConfigs\"),\n task: () => {\n const slashPath = (value: string) => value.replace(/\\\\/g, \"/\");\n patchJson(rootDir, \"db_config.json\", {\n db_port: dbPort,\n dbDir: slashPath(path.relative(rootDir, path.join(dbDir, \"sfmc_data.db\"))),\n modulesDir: \"modules\",\n });\n\n const llbotOn = qqBackend === \"llbot\" && !!llbotEnabled && !!llbotPath;\n const qqNotify = qqEnabled && (qqBackend === \"official\" || llbotOn);\n const exeName = llbotExeName();\n const currentQq = readJson<QQBridgeConfig>(configPath(rootDir, \"qq_config.json\")) ?? {};\n patchJson(rootDir, \"qq_config.json\", {\n qq_enabled: qqEnabled,\n qq_backend: qqBackend,\n official: {\n ...currentQq.official,\n app_id: qqAppId,\n app_secret: qqAppSecret,\n sandbox: qqSandbox,\n group_openid: qqGroupOpenid,\n },\n llbot: {\n ...currentQq.llbot,\n enabled: llbotOn,\n // path = \u53EF\u6267\u884C\u6587\u4EF6\uFF1Bcwd = \u8FD0\u884C\u76EE\u5F55\uFF08\u5411\u5BFC\u9009\u7684\u662F\u76EE\u5F55\uFF09\n path: llbotPath ? slashPath(path.join(llbotPath, exeName)) : \"\",\n cwd: llbotPath ? slashPath(llbotPath) : \"\",\n },\n });\n patchJson(rootDir, \"bds_updater.json\", {\n bds_path: slashPath(bdsResolved),\n channel: bdsChannel,\n backup_dir: slashPath(backupDir),\n preserve,\n qq_notify: qqNotify,\n });\n /* \u8DEF\u5F84\u9009\u5B9A\u540E\u518D\u6807\u8BB0\u5DF2\u521D\u59CB\u5316\uFF0C\u907F\u514D\u534A\u9014\u53D6\u6D88\u4ECD\u7559\u4E0B data/ \u8BED\u4E49 */\n patchJson(rootDir, \"runtime.json\", {\n runtime_root: rootDir,\n initialized_at: new Date().toISOString(),\n locale: isCancel(langPick) ? undefined : (langPick as string),\n });\n return t(\"wizard.configsUpdated\");\n },\n },\n {\n title: t(\"wizard.updatingModules\"),\n task: async (): Promise<string> => {\n const lock = readJson<ModuleLock>(modulePath(rootDir, \"module-lock.json\")) ?? {\n version: 1,\n modules: {},\n };\n if (!lock.modules) lock.modules = {};\n const now = Date.now();\n for (const id of selectedModules) lock.modules[id] = { enabled: true, updatedAt: now };\n writeJson(modulePath(rootDir, \"module-lock.json\"), lock);\n return t(\"wizard.modulesUpdated\");\n },\n },\n {\n title: t(\"wizard.initDb\"),\n task: async (): Promise<string> => {\n const child = spawnService(\"db\", [], {\n cwd: rootDir,\n stdio: \"ignore\",\n env: { ...process.env, DB_PORT: String(dbPort) },\n });\n if (!(await waitForHealth(dbPort))) {\n child.kill(\"SIGTERM\");\n return t(\"wizard.dbTimeout\");\n }\n\n await new Promise((resolve) => setTimeout(resolve, 1000));\n child.kill(\"SIGTERM\");\n setTimeout(() => child.kill(\"SIGKILL\"), 3000).unref();\n return t(\"wizard.dbOk\");\n },\n },\n ];\n if (downloadBds) {\n wizardTasks.push({\n title: t(\"wizard.downloadingBds\"),\n task: async (): Promise<string> => {\n const result = await runBdsUpdate(rootDir, bdsChannel);\n if (result.code !== 0) {\n return t(\"wizard.downloadFail\");\n }\n return t(\"wizard.bdsDownloaded\");\n },\n });\n }\n try {\n await tasks(wizardTasks);\n } catch (e) {\n outro(c.red(t(\"common.error\", { message: (e as Error).message })));\n return;\n }\n\n /* install \u2192 build \u2192 deploy chain */\n await runInstallBuildDeploy(rootDir, selectedModules, bdsResolved);\n\n outro(c.green(t(\"wizard.done\")));\n}\n\nasync function runInstallBuildDeploy(rootDir: string, selectedModules: string[], bdsResolved: string): Promise<void> {\n if (selectedModules.length > 0) {\n const fetchScript = resolveFetchModule();\n if (fetchScript) {\n const installT = [\n {\n title: t(\"wizard.installing\", { count: selectedModules.length }),\n task: async (): Promise<string> => {\n execFileSync(process.execPath, [fetchScript, \"install\", ...selectedModules], {\n cwd: rootDir,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n env: { ...process.env, SFMC_ROOT: rootDir },\n });\n return t(\"wizard.installed\", { count: selectedModules.length });\n },\n },\n ];\n try {\n await tasks(installT);\n } catch (e) {\n note(c.yellow(t(\"wizard.installFailed\", { message: (e as Error).message })));\n }\n } else {\n note(c.yellow(t(\"wizard.fetchMissing\", { list: selectedModules.join(\", \") })));\n }\n } else {\n note(c.dim(t(\"wizard.noModulesSelected\")));\n }\n\n const { cmdBehaviorPackBuild, cmdBehaviorPackDeploy } = await import(\"./commands-behavior-pack.js\");\n const buildT = [\n {\n title: t(\"wizard.buildingBp\"),\n task: async (): Promise<string> => {\n const r = await cmdBehaviorPackBuild([]);\n if (!r.ok) throw new Error(r.message);\n return r.message;\n },\n },\n ];\n try {\n await tasks(buildT);\n } catch (e) {\n note(c.yellow(t(\"wizard.buildFailed\", { message: (e as Error).message })));\n return;\n }\n\n const deployT = [\n {\n title: t(\"wizard.deploying\", { path: bdsResolved }),\n task: async (): Promise<string> => {\n const r = await cmdBehaviorPackDeploy([]);\n if (!r.ok) throw new Error(r.message);\n return r.message;\n },\n },\n ];\n try {\n await tasks(deployT);\n note(c.green(t(\"wizard.restartBds\")));\n } catch (e) {\n note(c.yellow(t(\"wizard.deployFailed\", { message: (e as Error).message })));\n }\n void rootDir;\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { confirm, intro, isCancel, multiselect, note, outro, password, select, tasks, text } from \"@clack/prompts\";\nimport {\n configPath,\n ensureCoreConfigs,\n modulePath,\n patchJson as patchConfig,\n readJson,\n withConfigSchema,\n writeJson,\n type Catalog,\n type ConfigName,\n type ModuleLock,\n type QQBridgeConfig,\n} from \"@sfmc-bds/sdk/node/config\";\nimport { bdsExePath } from \"@sfmc-bds/bds-tools/host-platform\";\nimport { execFileSync } from \"node:child_process\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { ensureDirectory, pickDirectory } from \"./interactive-prompts.js\";\nimport { persistLocale, t, type Locale } from \"./i18n/index.js\";\nimport { llbotExeName } from \"./llbot-launch.js\";\nimport { ROOT, isMonorepoLayout, isRuntimeInitialized, resolveFetchModule, spawnService } from \"./runtime.js\";\nimport { ensurePackUpdateConfigFile } from \"./pack-update/index.js\";\nimport { c } from \"./theme.js\";\n\n/** Shallow-merge write for top-level configs. Delegates to SDK; do not mkdir+writeFileSync here. */\nfunction patchJson<T extends object>(rootDir: string, name: ConfigName, updates: Partial<T>): void {\n patchConfig<T>(configPath(rootDir, name), updates);\n}\n\nasync function waitForHealth(port: number, ms = 15000): Promise<boolean> {\n const t = Date.now();\n while (Date.now() - t < ms) {\n try {\n if ((await fetch(`http://127.0.0.1:${port}/api/health`)).ok) return true;\n } catch {\n /* retry */\n }\n await new Promise((r) => setTimeout(r, 300));\n }\n return false;\n}\n\n/** \u8FD0\u884C\u65F6\u5FC5\u9700\u76EE\u5F55\u63A2\u6D4B(configs / modules) */\nconst RUNTIME_DIRS = [\n { target: \"configs\", npmTarget: \"configs\" },\n { target: \"modules\", npmTarget: \"modules\" },\n] as const;\n\nfunction missingRuntimeAssets(rootDir: string): string[] {\n return RUNTIME_DIRS.flatMap(({ target, npmTarget }) => {\n const directory = path.join(rootDir, npmTarget);\n try {\n return fs.statSync(directory).isDirectory() && fs.readdirSync(directory).length > 0 ? [] : [target];\n } catch {\n return [target];\n }\n });\n}\n\nasync function runBdsUpdate(rootDir: string, channel: string): Promise<{ code: number | null; output: string }> {\n const child = spawnService(\"update\", [`--channel=${channel}`, \"--force\", \"--no-start\"], {\n cwd: rootDir,\n stdio: \"pipe\",\n });\n const output: string[] = [];\n child.stdout?.on(\"data\", (data: Buffer) => output.push(data.toString()));\n child.stderr?.on(\"data\", (data: Buffer) => output.push(data.toString()));\n\n return new Promise((resolve) => {\n child.once(\"error\", (error) => resolve({ code: null, output: `${output.join(\"\")}${error.message}` }));\n child.once(\"close\", (code) => resolve({ code, output: output.join(\"\") }));\n });\n}\n\nasync function prepareRuntimeAssets(rootDir: string): Promise<void> {\n /* monorepo \u5E03\u5C40\uFF1Aconfigs/ modules/ \u5E94\u7531 pnpm workspace \u63D0\u4F9B */\n if (isMonorepoLayout(rootDir)) {\n const missing = missingRuntimeAssets(rootDir);\n if (missing.length > 0) {\n throw new Error(t(\"wizard.runtimeMissingAssets\", { list: missing.join(\", \") }));\n }\n return;\n }\n\n seedNpmRuntimeLayout(rootDir);\n}\n\n/** \u975E monorepo \u7684 npm \u5B89\u88C5\u5E03\u5C40\uFF1Aensure \u914D\u7F6E\u9AA8\u67B6 + \u7A7A modules */\nfunction seedNpmRuntimeLayout(rootDir: string): void {\n ensureCoreConfigs(rootDir, [\"db_config\", \"qq_config\", \"bds_updater\", \"permissions\"]);\n /* pack-update \u7684 ensure \u4F7F\u7528 runtime ROOT\uFF1Bnpm \u5E03\u5C40\u4E0B\u5E94\u4E0E rootDir \u4E00\u81F4 */\n if (path.resolve(rootDir) === path.resolve(ROOT)) {\n ensurePackUpdateConfigFile();\n void import(\"./module-update/index.js\")\n .then((mod) => mod.ensureModuleUpdateConfigFile())\n .catch(() => {\n /* \u7B56\u7565\u6587\u4EF6\u7A0D\u540E\u5728 mod update / \u5F00\u670D\u65F6\u8FD8\u4F1A\u518D\u786E\u4FDD\u4E00\u6B21 */\n });\n }\n\n const modulesRoot = path.join(rootDir, \"modules\");\n const packagesDir = path.join(modulesRoot, \"packages\");\n fs.mkdirSync(packagesDir, { recursive: true });\n\n const catalogPath = path.join(modulesRoot, \"catalog.json\");\n if (!fs.existsSync(catalogPath)) {\n writeJson(\n catalogPath,\n withConfigSchema({ version: 1, modules: [] }, \"module_catalog\", \"modules\")\n );\n }\n const lockPath = path.join(modulesRoot, \"module-lock.json\");\n if (!fs.existsSync(lockPath)) {\n writeJson(lockPath, { version: 1, modules: {} });\n }\n}\n\nexport async function runWizard(): Promise<void> {\n intro(c.bold(t(\"wizard.intro\")));\n\n const langPick = await select({\n message: t(\"locale.wizard\"),\n options: [\n { value: \"zh-CN\", label: t(\"locale.opt.zh\") },\n { value: \"en\", label: t(\"locale.opt.en\") },\n ],\n initialValue: \"zh-CN\",\n });\n if (!isCancel(langPick)) {\n persistLocale(ROOT, langPick as Locale);\n }\n\n // Already initialized only when runtime.json#initialized_at is set (empty db_config skeleton does not count).\n if (isRuntimeInitialized()) {\n const r = await confirm({ message: t(\"wizard.rerun\"), initialValue: false });\n if (isCancel(r) || !r) {\n outro(c.dim(t(\"wizard.skipped\")));\n return;\n }\n }\n // Step 1: Runtime Environment\uFF08\u53EA\u64AD\u79CD configs/modules\uFF0C\u4E0D\u5199 initialized_at\u3001\u4E0D\u5EFA data/\uFF09\n const rootDir = ROOT;\n note(c.text(t(\"wizard.runtimeRoot\", { root: rootDir })), t(\"wizard.step1\"));\n\n try {\n await prepareRuntimeAssets(rootDir);\n } catch (error) {\n outro(c.red(t(\"wizard.prepFailed\", { message: (error as Error).message })));\n return;\n }\n\n // Step 2: External runtime paths\n note(c.text(t(\"wizard.step2Note\")), t(\"wizard.step2\"));\n\n const bdsResolved = await pickDirectory(t(\"wizard.bdsDir\"), path.join(rootDir, \"BDS\"));\n if (!ensureDirectory(bdsResolved)) {\n outro(c.red(t(\"wizard.cannotCreateBds\", { dir: bdsResolved })));\n return;\n }\n\n /* QQ \u6865\uFF1A\u9009\u540E\u7AEF \u2192 official \u51ED\u636E / llbot \u8DEF\u5F84\uFF1B\u7981\u7528\u5219 qq_enabled=false */\n const qqBackendPick = await select({\n message: t(\"wizard.qqBackend\"),\n options: [\n { value: \"official\", label: t(\"wizard.qqBackend.official\"), hint: t(\"wizard.qqBackend.officialHint\") },\n { value: \"llbot\", label: t(\"wizard.qqBackend.llbot\"), hint: t(\"wizard.qqBackend.llbotHint\") },\n { value: \"disabled\", label: t(\"wizard.qqBackend.disabled\"), hint: t(\"wizard.qqBackend.disabledHint\") },\n ],\n initialValue: \"official\",\n });\n const qqBackendChoice =\n isCancel(qqBackendPick) || !qqBackendPick ? \"official\" : String(qqBackendPick);\n\n let qqEnabled = true;\n let qqBackend: \"official\" | \"llbot\" = \"official\";\n let qqAppId = \"\";\n let qqAppSecret = \"\";\n let qqSandbox = false;\n let qqGroupOpenid = \"\";\n let llbotPath: string | undefined;\n let llbotEnabled = false;\n\n if (qqBackendChoice === \"disabled\") {\n qqEnabled = false;\n } else if (qqBackendChoice === \"llbot\") {\n qqBackend = \"llbot\";\n llbotEnabled = true;\n const picked = await pickDirectory(t(\"wizard.llbotDir\"), path.join(rootDir, \"LLBOT\"));\n if (ensureDirectory(picked)) {\n llbotPath = picked;\n } else {\n llbotPath = path.join(rootDir, \"LLBOT\");\n note(c.text(t(\"wizard.usingDefault\", { path: llbotPath })), t(\"common.tips\"));\n }\n } else {\n qqBackend = \"official\";\n const appIdRaw = await text({\n message: t(\"wizard.qqAppId\"),\n placeholder: \"102xxxxx\",\n validate: (v: any): any => {\n if (!String(v ?? \"\").trim()) return t(\"wizard.valueRequired\");\n },\n });\n if (!isCancel(appIdRaw)) qqAppId = String(appIdRaw).trim();\n\n const secretRaw = await password({\n message: t(\"wizard.qqAppSecret\"),\n validate: (v: any): any => {\n if (!String(v ?? \"\").trim()) return t(\"wizard.valueRequired\");\n },\n });\n if (!isCancel(secretRaw)) qqAppSecret = String(secretRaw).trim();\n\n const sandboxPick = await confirm({\n message: t(\"wizard.qqSandbox\"),\n initialValue: false,\n });\n if (!isCancel(sandboxPick)) qqSandbox = !!sandboxPick;\n\n const openidRaw = await text({\n message: t(\"wizard.qqGroupOpenid\"),\n placeholder: t(\"wizard.qqGroupOpenidHint\"),\n });\n if (!isCancel(openidRaw)) qqGroupOpenid = String(openidRaw).trim();\n }\n\n const dbDirInput = await pickDirectory(t(\"wizard.dbDir\"), path.join(rootDir, \"data\"));\n const dbDir = ensureDirectory(dbDirInput) ? dbDirInput : path.join(rootDir, \"data\");\n if (dbDir !== dbDirInput) {\n note(c.text(t(\"wizard.usingDefault\", { path: dbDir })), t(\"common.tips\"));\n }\n const dbPortRaw = await text({\n message: t(\"wizard.dbPort\"),\n initialValue: \"3001\",\n validate: (v: any): any => {\n const n = parseInt(v, 10);\n if (isNaN(n) || n < 1024 || n > 65535) return t(\"wizard.portRange\");\n if (v.length === 0) return t(\"wizard.valueRequired\");\n },\n });\n const dbPort = isCancel(dbPortRaw) ? 3001 : parseInt(dbPortRaw as string, 10);\n\n // Step 3: BDS environment\n const bdsExe = bdsExePath(bdsResolved);\n const bdsExists = fs.existsSync(bdsExe);\n\n note(\n bdsExists\n ? c.green(t(\"wizard.bdsFound\", { path: bdsResolved }))\n : c.yellow(t(\"wizard.bdsNotFound\", { path: bdsResolved })),\n t(\"wizard.step3\")\n );\n\n const EULA = await confirm({\n message: t(\"wizard.eula\"),\n initialValue: false,\n });\n if (isCancel(EULA) || !EULA) {\n outro(c.yellow(t(\"wizard.disagreed\")));\n return;\n }\n\n let downloadBds = false;\n let bdsChannel = \"release\";\n let backupDir = path.join(path.dirname(bdsResolved), \"backups\");\n let preserve: string[] = [];\n\n if (!bdsExists) {\n const d = await confirm({ message: t(\"wizard.downloadBds\"), initialValue: true });\n if (!isCancel(d) && d) {\n const ch = await select({\n message: t(\"wizard.selectChannel\"),\n options: [\n { value: \"release\", label: t(\"wizard.channel.release\"), hint: t(\"wizard.channel.releaseHint\") },\n { value: \"preview\", label: t(\"wizard.channel.preview\"), hint: t(\"wizard.channel.previewHint\") },\n ],\n });\n if (!isCancel(ch)) {\n bdsChannel = ch as string;\n downloadBds = true;\n }\n if (!ensureDirectory(backupDir)) {\n outro(c.red(t(\"wizard.cannotCreateBackup\", { dir: backupDir })));\n return;\n }\n }\n }\n\n backupDir = await pickDirectory(t(\"wizard.backupDir\"), backupDir);\n const preserveOptions = [\n { value: \"server.properties\", label: \"server.properties\", hint: t(\"wizard.preserve.serverProps\") },\n { value: \"whitelist.json\", label: \"whitelist.json\" },\n { value: \"permissions.json\", label: \"permissions.json\" },\n { value: \"allowlist.json\", label: \"allowlist.json\" },\n { value: \"worlds\", label: \"worlds/\", hint: t(\"wizard.preserve.worlds\") },\n { value: \"config\", label: \"config/\", hint: t(\"wizard.preserve.config\") },\n ] as const;\n const pr = await multiselect({\n message: t(\"wizard.preserve\"),\n options: [...preserveOptions],\n initialValues: preserveOptions.map((o) => o.value),\n required: false,\n });\n if (!isCancel(pr)) preserve = pr as string[];\n note(c.yellow(t(\"wizard.updaterTip\")), t(\"common.tips\"));\n\n // Step 4: Module initialization\n const catalog = readJson<Catalog>(modulePath(rootDir, \"catalog.json\")) ?? {\n version: 1,\n modules: [],\n };\n const catalogModules: Array<{ id: string; name?: string; description?: string; canDisable?: boolean }> = [];\n if (Array.isArray(catalog.modules)) {\n for (const m of catalog.modules) {\n catalogModules.push({\n id: String(m.id ?? \"\"),\n name: String(m.name ?? m.id ?? \"\"),\n description: String(m.description ?? \"\"),\n canDisable: m.canDisable !== false,\n });\n }\n }\n\n note(\n c.text(\n catalogModules.length > 0\n ? t(\"wizard.modulesFound\", { count: catalogModules.length })\n : t(\"wizard.modulesNone\")\n ),\n t(\"wizard.step4\")\n );\n\n let selectedModules: string[] = [];\n const lockedMd: any[] = [];\n const optionalMd: any[] = [];\n catalogModules.forEach((k) => {\n const option = {\n value: k.id,\n label: String(k.name),\n hint: String(k.description ?? t(\"wizard.emptyHint\")),\n };\n if (k.canDisable === false) {\n lockedMd.push({ ...option, disabled: true });\n } else {\n optionalMd.push(option);\n }\n });\n if (catalogModules.length > 0) {\n const r = await multiselect({\n message: t(\"wizard.enableModules\"),\n options: [...lockedMd, ...optionalMd],\n required: false,\n });\n if (!isCancel(r)) selectedModules = r as string[];\n }\n\n const wizardTasks = [\n {\n title: t(\"wizard.updatingConfigs\"),\n task: () => {\n const slashPath = (value: string) => value.replace(/\\\\/g, \"/\");\n patchJson(rootDir, \"db_config.json\", {\n db_port: dbPort,\n dbDir: slashPath(path.relative(rootDir, path.join(dbDir, \"sfmc_data.db\"))),\n modulesDir: \"modules\",\n });\n\n const llbotOn = qqBackend === \"llbot\" && !!llbotEnabled && !!llbotPath;\n const qqNotify = qqEnabled && (qqBackend === \"official\" || llbotOn);\n const exeName = llbotExeName();\n const currentQq = readJson<QQBridgeConfig>(configPath(rootDir, \"qq_config.json\")) ?? {};\n patchJson(rootDir, \"qq_config.json\", {\n qq_enabled: qqEnabled,\n qq_backend: qqBackend,\n official: {\n ...currentQq.official,\n app_id: qqAppId,\n app_secret: qqAppSecret,\n sandbox: qqSandbox,\n group_openid: qqGroupOpenid,\n },\n llbot: {\n ...currentQq.llbot,\n enabled: llbotOn,\n // path = \u53EF\u6267\u884C\u6587\u4EF6\uFF1Bcwd = \u8FD0\u884C\u76EE\u5F55\uFF08\u5411\u5BFC\u9009\u7684\u662F\u76EE\u5F55\uFF09\n path: llbotPath ? slashPath(path.join(llbotPath, exeName)) : \"\",\n cwd: llbotPath ? slashPath(llbotPath) : \"\",\n },\n });\n patchJson(rootDir, \"bds_updater.json\", {\n bds_path: slashPath(bdsResolved),\n channel: bdsChannel,\n backup_dir: slashPath(backupDir),\n preserve,\n qq_notify: qqNotify,\n });\n /* \u8DEF\u5F84\u9009\u5B9A\u540E\u518D\u6807\u8BB0\u5DF2\u521D\u59CB\u5316\uFF0C\u907F\u514D\u534A\u9014\u53D6\u6D88\u4ECD\u7559\u4E0B data/ \u8BED\u4E49 */\n patchJson(rootDir, \"runtime.json\", {\n runtime_root: rootDir,\n initialized_at: new Date().toISOString(),\n locale: isCancel(langPick) ? undefined : (langPick as string),\n });\n return t(\"wizard.configsUpdated\");\n },\n },\n {\n title: t(\"wizard.updatingModules\"),\n task: async (): Promise<string> => {\n const lock = readJson<ModuleLock>(modulePath(rootDir, \"module-lock.json\")) ?? {\n version: 1,\n modules: {},\n };\n if (!lock.modules) lock.modules = {};\n const now = Date.now();\n for (const id of selectedModules) lock.modules[id] = { enabled: true, updatedAt: now };\n writeJson(modulePath(rootDir, \"module-lock.json\"), lock);\n return t(\"wizard.modulesUpdated\");\n },\n },\n {\n title: t(\"wizard.initDb\"),\n task: async (): Promise<string> => {\n const child = spawnService(\"db\", [], {\n cwd: rootDir,\n stdio: \"ignore\",\n env: { ...process.env, DB_PORT: String(dbPort) },\n });\n if (!(await waitForHealth(dbPort))) {\n child.kill(\"SIGTERM\");\n return t(\"wizard.dbTimeout\");\n }\n\n await new Promise((resolve) => setTimeout(resolve, 1000));\n child.kill(\"SIGTERM\");\n setTimeout(() => child.kill(\"SIGKILL\"), 3000).unref();\n return t(\"wizard.dbOk\");\n },\n },\n ];\n if (downloadBds) {\n wizardTasks.push({\n title: t(\"wizard.downloadingBds\"),\n task: async (): Promise<string> => {\n const result = await runBdsUpdate(rootDir, bdsChannel);\n if (result.code !== 0) {\n return t(\"wizard.downloadFail\");\n }\n return t(\"wizard.bdsDownloaded\");\n },\n });\n }\n try {\n await tasks(wizardTasks);\n } catch (e) {\n outro(c.red(t(\"common.error\", { message: (e as Error).message })));\n return;\n }\n\n /* install \u2192 build \u2192 deploy chain */\n await runInstallBuildDeploy(rootDir, selectedModules, bdsResolved);\n\n outro(c.green(t(\"wizard.done\")));\n}\n\nasync function runInstallBuildDeploy(rootDir: string, selectedModules: string[], bdsResolved: string): Promise<void> {\n if (selectedModules.length > 0) {\n const fetchScript = resolveFetchModule();\n if (fetchScript) {\n const installT = [\n {\n title: t(\"wizard.installing\", { count: selectedModules.length }),\n task: async (): Promise<string> => {\n execFileSync(process.execPath, [fetchScript, \"install\", ...selectedModules], {\n cwd: rootDir,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n env: { ...process.env, SFMC_ROOT: rootDir },\n });\n return t(\"wizard.installed\", { count: selectedModules.length });\n },\n },\n ];\n try {\n await tasks(installT);\n } catch (e) {\n note(c.yellow(t(\"wizard.installFailed\", { message: (e as Error).message })));\n }\n } else {\n note(c.yellow(t(\"wizard.fetchMissing\", { list: selectedModules.join(\", \") })));\n }\n } else {\n note(c.dim(t(\"wizard.noModulesSelected\")));\n }\n\n const { cmdBehaviorPackBuild, cmdBehaviorPackDeploy } = await import(\"./commands-behavior-pack.js\");\n const buildT = [\n {\n title: t(\"wizard.buildingBp\"),\n task: async (): Promise<string> => {\n const r = await cmdBehaviorPackBuild([]);\n if (!r.ok) throw new Error(r.message);\n return r.message;\n },\n },\n ];\n try {\n await tasks(buildT);\n } catch (e) {\n note(c.yellow(t(\"wizard.buildFailed\", { message: (e as Error).message })));\n return;\n }\n\n const deployT = [\n {\n title: t(\"wizard.deploying\", { path: bdsResolved }),\n task: async (): Promise<string> => {\n const r = await cmdBehaviorPackDeploy([]);\n if (!r.ok) throw new Error(r.message);\n return r.message;\n },\n },\n ];\n try {\n await tasks(deployT);\n note(c.green(t(\"wizard.restartBds\")));\n } catch (e) {\n note(c.yellow(t(\"wizard.deployFailed\", { message: (e as Error).message })));\n }\n void rootDir;\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["t"]
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sfmc-bds/cli",
3
- "version": "0.2.5",
3
+ "version": "0.3.0",
4
4
  "description": "SFMC management CLI — REPL, service supervisor, module install, behavior-pack build/deploy",
5
5
  "author": "Shiroha7z",
6
6
  "license": "AGPL-3.0-only",