@sfmc-bds/cli 0.2.0-beta.15 → 0.2.0-beta.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/i18n/locales/en.d.ts +10 -5
- package/dist/i18n/locales/en.d.ts.map +1 -1
- package/dist/i18n/locales/en.js +5 -0
- package/dist/i18n/locales/en.js.map +2 -2
- package/dist/i18n/locales/zh-CN.d.ts.map +1 -1
- package/dist/i18n/locales/zh-CN.js +5 -0
- package/dist/i18n/locales/zh-CN.js.map +2 -2
- package/dist/logs-blank-line.test.js +16 -0
- package/dist/logs-blank-line.test.js.map +7 -0
- package/dist/logs.d.ts +2 -0
- package/dist/logs.d.ts.map +1 -1
- package/dist/logs.js +8 -1
- package/dist/logs.js.map +2 -2
- package/dist/pack-bundle.test.js +6 -0
- package/dist/pack-bundle.test.js.map +2 -2
- package/dist/pack-lifecycle.d.ts.map +1 -1
- package/dist/pack-lifecycle.js +1 -1
- package/dist/pack-lifecycle.js.map +2 -2
- package/dist/services-output.test.js +9 -0
- package/dist/services-output.test.js.map +7 -0
- package/dist/services.d.ts +2 -0
- package/dist/services.d.ts.map +1 -1
- package/dist/services.js +6 -2
- package/dist/services.js.map +2 -2
- package/dist/world-packs-list.test.js +11 -0
- package/dist/world-packs-list.test.js.map +7 -0
- package/dist/world-packs.d.ts +2 -0
- package/dist/world-packs.d.ts.map +1 -1
- package/dist/world-packs.js +90 -18
- package/dist/world-packs.js.map +3 -3
- package/package.json +4 -4
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/pack-lifecycle.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * pack-lifecycle.ts \u2014 \u884C\u4E3A\u5305/\u8D44\u6E90\u5305\u88C5\u8F7D\u751F\u547D\u5468\u671F\n *\n * \u804C\u8D23:\n * - \u8BA1\u7B97\u672C\u673A desired deploy-catalog(\u542F\u7528\u6A21\u5757 + fingerprint)\n * - \u4E0E\u4E16\u754C BP \u5185 sfmc-deploy-catalog.json \u6BD4\u5BF9\n * - \u4E0D\u4E00\u81F4\u5219\u6574\u5305 build + deploy + \u5199\u4E16\u754C\u6E05\u5355 + Script API permission\n * - \u542F\u52A8\u524D ensurePacksReady;\u65E5\u5FD7\u4E00\u5F8B\u8D70 source=`pack`\n */\n\nimport {\n configPath,\n modulePath,\n readJson,\n writeJson,\n type BdsUpdaterConfig,\n type Catalog,\n type ModuleLock,\n} from \"@sfmc-bds/sdk/node/config\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { pushLog } from \"./logs.js\";\nimport { dirFingerprint } from \"./module-fingerprint.js\";\nimport { failResult, okResult, type CliResult } from \"./cli-result.js\";\nimport { t } from \"./i18n/index.js\";\nimport {\n assembleBehaviorPack,\n assembleResourcePack,\n bdsWorldLevelDir,\n bdsWorldsDir,\n configPermissionPath,\n deployToBDS,\n disablePackInWorld,\n enablePackInWorld,\n ensureConfigPermission,\n hasConfigPermission,\n readLevelNameSync,\n readPackManifestHeader,\n readWorldPackList,\n worldPackListHas as pmWorldPackListHas,\n BASELINE_BEDROCK_DEPENDENCIES,\n negotiateBedrockDependencies,\n NATIVE_BEDROCK_SCRIPT_MODULES,\n type PackManifestDependency,\n} from \"@sfmc-bds/bds-tools/pack-manager-lib\";\nimport { ROOT, PACKAGES_DIR, resolveSdkPackageRoot, getRoot } from \"./runtime.js\";\nimport { c } from \"./theme.js\";\n\nexport const BP_NAME = \"sfmc-modules\";\nexport const RP_NAME = \"sfmc-modules-rp\";\nexport const DEPLOY_CATALOG_NAME = \"sfmc-deploy-catalog.json\";\nexport const DEFAULT_PACK_VERSION: [number, number, number] = [1, 0, 0];\n\n/** \u5C06 @sfmc/sdk \u4E0E @sfmc-bds/sdk \u5B50\u8DEF\u5F84\u89E3\u6790\u5230 SDK \u5305\u5185\u771F\u5B9E\u6587\u4EF6\uFF0C\u5E76\u6CE8\u5165 sfmc:host \u5F15\u5BFC\u5165\u53E3 */\nexport function createSdkResolvePlugin(sdkRoot: string): import(\"esbuild\").Plugin {\n const pkg = JSON.parse(readFileSync(path.join(sdkRoot, \"package.json\"), \"utf8\")) as {\n exports?: Record<string, string | { import?: string; default?: string; types?: string }>;\n };\n const exportsMap = pkg.exports ?? {};\n\n function resolveExportSubpath(subpath: string): string | null {\n const key = subpath === \"\" ? \".\" : `./${subpath}`;\n const entry = exportsMap[key];\n if (!entry) return null;\n const rel = typeof entry === \"string\" ? entry : (entry.import ?? entry.default);\n if (!rel || typeof rel !== \"string\") return null;\n const abs = path.join(sdkRoot, rel);\n return existsSync(abs) ? abs : null;\n }\n\n return {\n name: \"sfmc-sdk-resolve\",\n setup(build) {\n build.onResolve({ filter: /^sfmc:host$/ }, () => ({\n path: \"sfmc:host\",\n namespace: \"sfmc-host\",\n }));\n build.onLoad({ filter: /.*/, namespace: \"sfmc-host\" }, () => ({\n contents: [\n 'import { installHostBootstrap } from \"@sfmc-bds/sdk/module-loader/install\";',\n \"installHostBootstrap();\",\n ].join(\"\\n\"),\n loader: \"ts\",\n }));\n\n build.onResolve({ filter: /^@sfmc(?:-bds)?\\/sdk(?:\\/|$)/ }, (args) => {\n const normalized = args.path.replace(/^@sfmc\\/sdk/, \"@sfmc-bds/sdk\");\n const sub = normalized === \"@sfmc-bds/sdk\" ? \"\" : normalized.slice(\"@sfmc-bds/sdk/\".length);\n\n const importerNorm = (args.importer || \"\").replace(/\\\\/g, \"/\");\n const sapiIdx = importerNorm.indexOf(\"/sapi/\");\n if (sapiIdx !== -1 && !importerNorm.includes(\"@sfmc-sdk\") && !importerNorm.includes(\"@sfmc/sdk\")) {\n const sapiDir = importerNorm.slice(0, sapiIdx + \"/sapi\".length);\n const manifestFile = path.join(sapiDir, \"manifest.json\");\n let logicalId = \"\";\n let configKey = \"\";\n if (existsSync(manifestFile)) {\n try {\n const man = JSON.parse(readFileSync(manifestFile, \"utf8\")) as { id?: string; configKey?: string };\n if (man.id) logicalId = man.id;\n if (man.configKey) configKey = man.configKey;\n } catch {}\n }\n if (!logicalId) {\n const rootDir = importerNorm.slice(0, sapiIdx);\n logicalId = path.basename(rootDir).replace(/^sfmc-module-/, \"\");\n configKey = logicalId;\n }\n if (sub === \"sapi/db\") {\n return {\n path: `sfmc-scoped:db?mod=${encodeURIComponent(logicalId)}`,\n namespace: \"sfmc-scoped-db\",\n };\n }\n if (sub === \"sapi/config\") {\n return {\n path: `sfmc-scoped:config?cfg=${encodeURIComponent(configKey)}`,\n namespace: \"sfmc-scoped-config\",\n };\n }\n if (sub === \"sapi/service\") {\n return {\n path: `sfmc-scoped:service?mod=${encodeURIComponent(logicalId)}`,\n namespace: \"sfmc-scoped-service\",\n };\n }\n }\n\n const resolved = resolveExportSubpath(sub);\n if (!resolved) {\n return {\n errors: [\n {\n text: `Cannot resolve ${args.path} under SDK at ${sdkRoot} (export \"./${sub || \".\"}\" missing or file absent; run sdk:build?)`,\n },\n ],\n };\n }\n return { path: resolved };\n });\n\n build.onLoad({ filter: /.*/, namespace: \"sfmc-scoped-db\" }, (args) => {\n const u = new URL(args.path);\n const mod = u.searchParams.get(\"mod\") || \"\";\n return {\n contents: [\n 'import { getDbClient } from \"@sfmc-bds/sdk/sapi/db\";',\n 'export * from \"@sfmc-bds/sdk/sapi/db\";',\n 'export const db = new Proxy({}, {',\n ' get(_t, prop) {',\n ` const c = getDbClient(${JSON.stringify(mod)});`,\n ' const val = (c as any)[prop];',\n ' return typeof val === \"function\" ? val.bind(c) : val;',\n ' }',\n '});',\n ].join(\"\\n\"),\n loader: \"ts\",\n resolveDir: sdkRoot,\n };\n });\n\n build.onLoad({ filter: /.*/, namespace: \"sfmc-scoped-config\" }, (args) => {\n const u = new URL(args.path);\n const cfg = u.searchParams.get(\"cfg\") || \"\";\n return {\n contents: [\n 'import { getConfigClient } from \"@sfmc-bds/sdk/sapi/config\";',\n 'export * from \"@sfmc-bds/sdk/sapi/config\";',\n 'export const config = new Proxy({}, {',\n ' get(_t, prop) {',\n ` const c = getConfigClient(${JSON.stringify(cfg)});`,\n ' const val = (c as any)[prop];',\n ' return typeof val === \"function\" ? val.bind(c) : val;',\n ' }',\n '});',\n ].join(\"\\n\"),\n loader: \"ts\",\n resolveDir: sdkRoot,\n };\n });\n\n build.onLoad({ filter: /.*/, namespace: \"sfmc-scoped-service\" }, (args) => {\n const u = new URL(args.path);\n const mod = u.searchParams.get(\"mod\") || \"\";\n return {\n contents: [\n 'import { getServiceClient } from \"@sfmc-bds/sdk/sapi/service\";',\n 'export * from \"@sfmc-bds/sdk/sapi/service\";',\n 'export const service = new Proxy({}, {',\n ' get(_t, prop) {',\n ` const c = getServiceClient(${JSON.stringify(mod)});`,\n ' const val = (c as any)[prop];',\n ' return typeof val === \"function\" ? val.bind(c) : val;',\n ' }',\n '});',\n ].join(\"\\n\"),\n loader: \"ts\",\n resolveDir: sdkRoot,\n };\n });\n },\n };\n}\n\nexport function buildRoot(): string {\n /* \u4E0E\u6536\u4EF6\u7BB1\u540C\u6811\uFF1Apacks/_build\uFF08_ \u524D\u7F00\u4E0D\u4F1A\u88AB inbox \u626B\u63CF\uFF09 */\n return path.join(ROOT, \"packs\", \"_build\");\n}\nexport function bpSrc(): string {\n return path.join(buildRoot(), `${BP_NAME}-bp`);\n}\nexport function bpOut(): string {\n return path.join(buildRoot(), BP_NAME);\n}\nexport function rpOut(): string {\n return path.join(buildRoot(), RP_NAME);\n}\n\nexport interface DeployCatalogModule {\n logicalId: string;\n enabled: boolean;\n version: string;\n fingerprint: string;\n hasResourcePack: boolean;\n}\n\nexport interface DeployCatalog {\n schemaVersion: 1;\n bpUuid: string;\n rpUuid: string | null;\n bpVersion: [number, number, number];\n rpVersion: [number, number, number] | null;\n bpModuleUuid?: string;\n rpModuleUuid?: string;\n generatedAt: number;\n sdkVersion?: string;\n dependencies?: PackManifestDependency[];\n modules: Record<string, DeployCatalogModule>;\n}\n\nexport interface PackEnsureResult {\n rebuilt: boolean;\n skipped: boolean;\n catalog: DeployCatalog;\n bdsRoot: string;\n levelName: string;\n summary: string;\n}\n\ninterface PackManifestLite {\n id?: string;\n version?: string;\n schemaVersion?: number;\n enabledByDefault?: boolean;\n name?: string;\n}\n\nfunction packLog(text: string, level: \"info\" | \"success\" | \"warn\" | \"error\" = \"info\"): void {\n pushLog(text, \"pack\", level);\n}\n\nfunction packagesDir(): string {\n return PACKAGES_DIR || path.join(ROOT, \"modules\", \"packages\");\n}\n\nfunction lockPath(): string {\n return modulePath(path.join(ROOT, \"modules\"), \"module-lock.json\");\n}\n\nfunction catalogPath(): string {\n return modulePath(path.join(ROOT, \"modules\"), \"catalog.json\");\n}\n\n/** \u8BFB BDS \u8DEF\u5F84\u4E0E level-name\uFF08level \u6743\u5A01\uFF1Apack-manager-lib.readLevelNameSync\uFF0CDIP\uFF09 */\nexport function resolveBdsContext(root: string = getRoot()): { bdsRoot: string; levelName: string } {\n const cfg = (readJson<BdsUpdaterConfig>(configPath(root, \"bds_updater.json\")) ?? {}) as BdsUpdaterConfig;\n const rawBds = cfg.bds_path;\n if (!rawBds) {\n throw new Error(\"bds_path not configured. Run `sfmc init` first.\");\n }\n const bdsRoot = path.isAbsolute(rawBds) ? rawBds : path.resolve(root, rawBds);\n return { bdsRoot, levelName: readLevelNameSync(bdsRoot) };\n}\n\nexport function deployedBpDir(bdsRoot: string, levelName: string): string {\n return path.join(bdsWorldLevelDir(bdsRoot, levelName), \"behavior_packs\", BP_NAME);\n}\n\nexport function deployedRpDir(bdsRoot: string, levelName: string): string {\n return path.join(bdsWorldLevelDir(bdsRoot, levelName), \"resource_packs\", RP_NAME);\n}\n\nexport function deployedCatalogPath(bdsRoot: string, levelName: string): string {\n return path.join(deployedBpDir(bdsRoot, levelName), DEPLOY_CATALOG_NAME);\n}\n\n/** \u89E3\u6790\u542F\u7528\u72B6\u6001:lock \u4F18\u5148,\u5426\u5219 catalog.enabledByDefault(\u7F3A\u7701 true\u2194!==false),\u672A\u6536\u5F55\u6A21\u5757 false */\nfunction isModuleEnabled(logicalId: string, lock: ModuleLock, catalogDefaults: Map<string, boolean>): boolean {\n const st = lock.modules?.[logicalId];\n if (st && typeof st.enabled === \"boolean\") return st.enabled;\n return catalogDefaults.get(logicalId) ?? false;\n}\n\n/**\n * \u90E8\u7F72\u524D\u6536\u96C6\u4E16\u754C\u5185\u5DF2\u51FA\u73B0\u7684 BP/RP uuid\u3002\n * \u540C\u65F6\u8BFB deploy-catalog \u4E0E\u78C1\u76D8 manifest \u2014 catalog \u7F3A\u5931\u65F6\u4ECD\u80FD\u5378\u8FC7\u671F\u6E05\u5355\u9879(Demeter/\u5B8C\u6574\u5951\u7EA6)\u3002\n */\nfunction collectDeployedPackUuids(\n bdsRoot: string,\n levelName: string\n): { bp: Set<string>; rp: Set<string> } {\n const bp = new Set<string>();\n const rp = new Set<string>();\n const cat = readDeployedCatalog(bdsRoot, levelName);\n if (cat?.bpUuid) bp.add(cat.bpUuid);\n if (cat?.rpUuid) rp.add(cat.rpUuid);\n const liveBp = readPackManifestHeader(deployedBpDir(bdsRoot, levelName));\n const liveRp = readPackManifestHeader(deployedRpDir(bdsRoot, levelName));\n if (liveBp?.uuid) bp.add(liveBp.uuid);\n if (liveRp?.uuid) rp.add(liveRp.uuid);\n return { bp, rp };\n}\n\n/**\n * \u4ECE\u6A21\u5757\u76EE\u5F55\u63D0\u53D6\u58F0\u660E\u7684 @minecraft/* \u539F\u751F\u4F9D\u8D56\u3002\n * \u4F18\u5148\u7EA7\uFF1A\n * 1. sapi/manifest.json \u7684 dependencies\uFF08\u6807\u51C6\u57FA\u5CA9\u6570\u7EC4\u6216\u952E\u503C\u5BF9\u6620\u5C04\uFF09\u4E0E minecraft \u5B57\u6BB5\uFF1B\n * 2. package.json \u7684 peerDependencies \u4E0E dependencies\uFF08\u4E0D\u542B devDependencies\uFF0C\u907F\u514D\u7C7B\u578B\u5305\u8BEF\u4F24\uFF09\u3002\n */\nexport async function extractModuleBedrockDependencies(modPath: string): Promise<PackManifestDependency[]> {\n const deps: PackManifestDependency[] = [];\n const seen = new Set<string>();\n\n const manifestPath = path.join(modPath, \"sapi\", \"manifest.json\");\n if (existsSync(manifestPath)) {\n try {\n const raw = JSON.parse(await fs.readFile(manifestPath, \"utf8\")) as Record<string, unknown>;\n if (Array.isArray(raw.dependencies)) {\n for (const d of raw.dependencies) {\n if (\n d &&\n typeof d === \"object\" &&\n typeof (d as { module_name?: unknown }).module_name === \"string\" &&\n (d as { module_name: string }).module_name.startsWith(\"@minecraft/\") &&\n NATIVE_BEDROCK_SCRIPT_MODULES.has((d as { module_name: string }).module_name)\n ) {\n const modName = (d as { module_name: string }).module_name;\n const ver = String((d as { version?: unknown }).version ?? \"1.0.0\");\n const uuid = typeof (d as { uuid?: unknown }).uuid === \"string\" ? (d as { uuid: string }).uuid : undefined;\n deps.push({ module_name: modName, version: ver, ...(uuid ? { uuid } : {}) });\n seen.add(modName);\n }\n }\n } else if (raw.dependencies && typeof raw.dependencies === \"object\") {\n for (const [modName, ver] of Object.entries(raw.dependencies as Record<string, unknown>)) {\n if (modName.startsWith(\"@minecraft/\") && !seen.has(modName) && NATIVE_BEDROCK_SCRIPT_MODULES.has(modName)) {\n deps.push({ module_name: modName, version: String(ver ?? \"1.0.0\") });\n seen.add(modName);\n }\n }\n }\n\n if (raw.minecraft && typeof raw.minecraft === \"object\") {\n const mc = raw.minecraft as Record<string, unknown>;\n const mcDeps = (Array.isArray(mc.dependencies) ? mc.dependencies : mc) as Record<string, unknown>;\n if (typeof mcDeps === \"object\" && !Array.isArray(mcDeps)) {\n for (const [modName, ver] of Object.entries(mcDeps)) {\n if (modName.startsWith(\"@minecraft/\") && !seen.has(modName) && NATIVE_BEDROCK_SCRIPT_MODULES.has(modName)) {\n deps.push({ module_name: modName, version: String(ver ?? \"1.0.0\") });\n seen.add(modName);\n }\n }\n }\n }\n } catch {\n /* ignore parse error */\n }\n }\n\n const pkgPath = path.join(modPath, \"package.json\");\n if (existsSync(pkgPath)) {\n try {\n const pkg = JSON.parse(await fs.readFile(pkgPath, \"utf8\")) as {\n peerDependencies?: Record<string, string>;\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n };\n const candidateMap = {\n ...(pkg.devDependencies ?? {}),\n ...(pkg.dependencies ?? {}),\n ...(pkg.peerDependencies ?? {}),\n };\n for (const [modName, ver] of Object.entries(candidateMap)) {\n if (modName.startsWith(\"@minecraft/\") && !seen.has(modName) && NATIVE_BEDROCK_SCRIPT_MODULES.has(modName)) {\n deps.push({ module_name: modName, version: ver });\n seen.add(modName);\n }\n }\n } catch {\n /* ignore */\n }\n }\n\n return deps;\n}\n\n/**\n * \u679A\u4E3E\u672C\u673A packages,\u8FD4\u56DE folderId \u2192 \u5143\u6570\u636E\u3002\n * \u4EC5\u542B\u6709 sapi/src/index.ts \u7684\u6A21\u5757\u4F1A\u8FDB\u5165 BP bundle \u5019\u9009\u3002\n */\nexport async function scanLocalModules(): Promise<\n Array<{\n folderId: string;\n logicalId: string;\n version: string;\n enabled: boolean;\n hasSapi: boolean;\n hasResourcePack: boolean;\n fingerprint: string;\n entryPath: string | null;\n declaredDependencies: PackManifestDependency[];\n }>\n> {\n const dir = packagesDir();\n if (!existsSync(dir)) return [];\n const lock = (readJson<ModuleLock>(lockPath()) ?? { version: 1, modules: {} }) as ModuleLock;\n const cat = (readJson<Catalog>(catalogPath()) ?? { version: 1, modules: [] }) as Catalog;\n const defaults = new Map<string, boolean>();\n if (Array.isArray(cat.modules)) {\n for (const m of cat.modules) {\n const id = typeof m.id === \"string\" ? m.id : \"\";\n if (!id) continue;\n /* \u4E0E db-server \u5951\u7EA6\u4E00\u81F4:enabledByDefault !== false(\u7F3A\u7701 true) \u2014 LSP */\n defaults.set(id, m.enabledByDefault !== false);\n }\n }\n\n const entries = await fs.readdir(dir, { withFileTypes: true });\n const out: Array<{\n folderId: string;\n logicalId: string;\n version: string;\n enabled: boolean;\n hasSapi: boolean;\n hasResourcePack: boolean;\n fingerprint: string;\n entryPath: string | null;\n declaredDependencies: PackManifestDependency[];\n }> = [];\n\n for (const e of entries) {\n if (e.name.startsWith(\".\")) continue;\n const folderId = e.name;\n const modPath = path.join(dir, folderId);\n // Dirent.isDirectory() \u5BF9\u300C\u6307\u5411\u76EE\u5F55\u7684 symlink\u300D\u5728 Linux \u4E3A false\uFF1B\u7528 stat \u8DDF\u968F\u94FE\u63A5\n try {\n const st = await fs.stat(modPath);\n if (!st.isDirectory()) continue;\n } catch {\n continue;\n }\n const manifestPath = path.join(modPath, \"sapi\", \"manifest.json\");\n const entryPath = path.join(modPath, \"sapi\", \"src\", \"index.ts\");\n let logicalId = folderId;\n let version = \"0.0.0\";\n if (existsSync(manifestPath)) {\n try {\n const man = JSON.parse(await fs.readFile(manifestPath, \"utf8\")) as PackManifestLite;\n if (typeof man.id === \"string\" && man.id) logicalId = man.id;\n if (typeof man.version === \"string\" && man.version) version = man.version;\n else if (typeof man.schemaVersion === \"number\") version = `schema-${man.schemaVersion}`;\n } catch {\n /* keep defaults */\n }\n }\n const hasSapi = existsSync(entryPath);\n const hasResourcePack = existsSync(path.join(modPath, \"resource_pack\"));\n const fingerprint = await dirFingerprint(modPath);\n const enabled = isModuleEnabled(logicalId, lock, defaults);\n const declaredDependencies = await extractModuleBedrockDependencies(modPath);\n out.push({\n folderId,\n logicalId,\n version,\n enabled,\n hasSapi,\n hasResourcePack,\n fingerprint,\n entryPath: hasSapi ? entryPath : null,\n declaredDependencies,\n });\n }\n out.sort((a, b) => a.folderId.localeCompare(b.folderId));\n return out;\n}\n\n/** \u4ECE\u672C\u673A\u72B6\u6001 + \u5DF2\u6709 UUID \u5408\u6210 desired catalog\u3002\n * UUID \u4F18\u5148:deployed catalog \u2192 \u672C\u5730 build manifest \u2192 \u65B0\u5EFA\u968F\u673A\u3002\n */\nexport async function computeDesiredCatalog(opts?: {\n bpUuid?: string;\n rpUuid?: string | null;\n bpVersion?: [number, number, number];\n rpVersion?: [number, number, number] | null;\n bpModuleUuid?: string;\n rpModuleUuid?: string;\n}): Promise<DeployCatalog> {\n const mods = await scanLocalModules();\n const modules: Record<string, DeployCatalogModule> = {};\n let anyRp = false;\n for (const m of mods) {\n /* catalog \u8BB0\u5F55\u5168\u90E8\u5DF2\u5B89\u88C5\u6A21\u5757\u7684\u542F\u505C\u4E0E\u6307\u7EB9,\u4FBF\u4E8E diff \u88C5\u5378/\u7981\u7528 */\n modules[m.folderId] = {\n logicalId: m.logicalId,\n enabled: m.enabled,\n version: m.version,\n fingerprint: m.fingerprint,\n hasResourcePack: m.hasResourcePack,\n };\n if (m.enabled && m.hasResourcePack) anyRp = true;\n }\n\n const localBp = readPackManifestHeader(bpOut());\n const localRp = readPackManifestHeader(rpOut());\n const bpUuid = opts?.bpUuid ?? localBp?.uuid ?? crypto.randomUUID();\n const bpVersion = opts?.bpVersion ?? localBp?.version ?? DEFAULT_PACK_VERSION;\n const bpModuleUuid = opts?.bpModuleUuid ?? localBp?.moduleUuid;\n let rpUuid: string | null = null;\n let rpVersion: [number, number, number] | null = null;\n let rpModuleUuid: string | undefined;\n if (anyRp) {\n rpUuid = opts?.rpUuid ?? localRp?.uuid ?? crypto.randomUUID();\n rpVersion = opts?.rpVersion ?? localRp?.version ?? DEFAULT_PACK_VERSION;\n rpModuleUuid = opts?.rpModuleUuid ?? localRp?.moduleUuid;\n }\n\n let sdkVersion: string | undefined;\n try {\n const sdkRoot = resolveSdkPackageRoot();\n const pkg = JSON.parse(readFileSync(path.join(sdkRoot, \"package.json\"), \"utf8\")) as { version?: string };\n sdkVersion = pkg.version;\n } catch {\n /* ignore */\n }\n\n // \u4F9D\u8D56\u52A8\u6001\u534F\u5546\uFF1A\u6536\u96C6\u6240\u6709\u5DF2\u542F\u7528\u6A21\u5757\u7684 Minecraft \u4F9D\u8D56\u58F0\u660E\u5E76\u6309\u7248\u672C\u89C4\u5219\u63D0\u5347\n const enabledModuleReqs = mods\n .filter((m) => m.enabled && m.declaredDependencies.length > 0)\n .map((m) => ({ folderId: m.folderId, dependencies: m.declaredDependencies }));\n const negotiated = negotiateBedrockDependencies(BASELINE_BEDROCK_DEPENDENCIES, enabledModuleReqs);\n\n if (negotiated.promotions.length > 0) {\n for (const p of negotiated.promotions) {\n packLog(\n `promoted ${p.moduleName} ${p.from} -> ${p.to} (requested by: ${p.requestedBy.join(\", \")})`,\n \"info\"\n );\n }\n }\n\n return {\n schemaVersion: 1,\n bpUuid,\n rpUuid,\n bpVersion,\n rpVersion,\n ...(bpModuleUuid ? { bpModuleUuid } : {}),\n ...(rpModuleUuid ? { rpModuleUuid } : {}),\n generatedAt: Date.now(),\n ...(sdkVersion ? { sdkVersion } : {}),\n dependencies: negotiated.dependencies,\n modules,\n };\n}\n\nexport function readDeployedCatalog(bdsRoot: string, levelName: string): DeployCatalog | null {\n const file = deployedCatalogPath(bdsRoot, levelName);\n if (!existsSync(file)) return null;\n try {\n return JSON.parse(readFileSync(file, \"utf8\")) as DeployCatalog;\n } catch {\n return null;\n }\n}\n\n/** \u6BD4\u8F83\u952E:\u6A21\u5757\u96C6\u5408 + enabled/version/fingerprint/hasRP + bp/rp uuid + sdkVersion + dependencies */\nexport function catalogsEqual(a: DeployCatalog, b: DeployCatalog): boolean {\n if (a.bpUuid !== b.bpUuid) return false;\n if ((a.rpUuid ?? null) !== (b.rpUuid ?? null)) return false;\n if ((a.sdkVersion ?? null) !== (b.sdkVersion ?? null)) return false;\n\n const depsA = a.dependencies ?? [];\n const depsB = b.dependencies ?? [];\n if (depsA.length !== depsB.length) return false;\n for (let i = 0; i < depsA.length; i++) {\n const da = depsA[i];\n const db = depsB[i];\n if (!da || !db || da.module_name !== db.module_name || da.version !== db.version) {\n return false;\n }\n }\n const aKeys = Object.keys(a.modules).sort();\n const bKeys = Object.keys(b.modules).sort();\n if (aKeys.length !== bKeys.length) return false;\n for (let i = 0; i < aKeys.length; i++) {\n if (aKeys[i] !== bKeys[i]) return false;\n }\n for (const k of aKeys) {\n const x = a.modules[k]!;\n const y = b.modules[k]!;\n if (\n x.logicalId !== y.logicalId ||\n x.enabled !== y.enabled ||\n x.version !== y.version ||\n x.fingerprint !== y.fingerprint ||\n x.hasResourcePack !== y.hasResourcePack\n ) {\n return false;\n }\n }\n /* \u4E16\u754C\u6E05\u5355\u662F\u5426\u4ECD\u542B uuid \u2014 \u8C03\u7528\u65B9\u989D\u5916\u68C0\u67E5 */\n return true;\n}\n\n/** \u4E16\u754C enable-list \u67E5\u8BE2 \u2014 \u76F4\u8FDE pack-manager-lib\uFF08DRY/DIP\uFF0C\u4E0E CLI has-pack \u540C\u5951\u7EA6\uFF09 */\nfunction worldPackListHas(bdsRoot: string, levelName: string, kind: \"behavior\" | \"resource\", uuid: string): boolean {\n return pmWorldPackListHas(bdsWorldsDir(bdsRoot), levelName, kind, uuid);\n}\n\n/** esbuild \u805A\u5408\u542F\u7528\u6A21\u5757 \u2192 assemble BP + RP(\u82E5\u6709) */\nexport async function buildPacks(desired?: DeployCatalog): Promise<DeployCatalog> {\n await fs.mkdir(buildRoot(), { recursive: true });\n const catalog = desired ?? (await computeDesiredCatalog());\n packLog(`building BP/RP (modules=${Object.keys(catalog.modules).length})\u2026`);\n\n /* \u5355\u6B21\u626B\u63CF:SAPI \u5165\u53E3 + RP \u76EE\u5F55(DRY,\u907F\u514D listEnabled* \u91CD\u590D fingerprint) */\n const mods = await scanLocalModules();\n const entries = mods.filter((m) => m.enabled && m.entryPath).map((m) => m.entryPath!);\n const rpDirs: Record<string, string> = {};\n for (const m of mods) {\n if (!m.enabled || !m.hasResourcePack) continue;\n rpDirs[m.folderId] = path.join(packagesDir(), m.folderId, \"resource_pack\");\n }\n\n const { build } = await import(\"esbuild\");\n const outFile = path.join(bpSrc(), \"scripts\", \"main.js\");\n await fs.mkdir(path.dirname(outFile), { recursive: true });\n if (entries.length === 0) {\n await fs.writeFile(outFile, \"/* no modules enabled */\\n\", \"utf8\");\n packLog(\"no enabled SAPI modules \u2014 empty main.js\", \"warn\");\n } else {\n const sdkRoot = resolveSdkPackageRoot();\n packLog(`SDK root: ${sdkRoot}`);\n await build({\n stdin: {\n contents: [\n 'import \"sfmc:host\";',\n ...entries.map((e) => `import ${JSON.stringify(path.resolve(e).replace(/\\\\/g, \"/\"))};`),\n ].join(\"\\n\"),\n resolveDir: ROOT,\n sourcefile: \"bootstrap.ts\",\n loader: \"ts\",\n },\n outfile: outFile,\n bundle: true,\n platform: \"neutral\",\n format: \"esm\",\n target: \"es2022\",\n logLevel: \"warning\",\n sourcemap: true,\n external: [\"@minecraft/*\"],\n // \u907F\u514D\u8BFB\u53D6\u6A21\u5757\u5185\u6B8B\u7F3A\u7684 extends\uFF08\u5982 ../../../sdk/@sfmc-sdk/tsconfig.json\uFF09\n tsconfigRaw: JSON.stringify({\n compilerOptions: {\n module: \"ESNext\",\n moduleResolution: \"bundler\",\n target: \"ES2022\",\n strict: true,\n skipLibCheck: true,\n },\n }),\n plugins: [createSdkResolvePlugin(sdkRoot)],\n });\n packLog(`esbuild bundled ${entries.length} entr(y/ies)`, \"success\");\n }\n\n try {\n await assembleBehaviorPack({\n srcDir: bpSrc(),\n outDir: bpOut(),\n projectName: BP_NAME,\n version: catalog.bpVersion,\n description: \"ScriptsForMinecraftServer aggregated behavior pack\",\n uuid: catalog.bpUuid,\n ...(catalog.bpModuleUuid ? { moduleUuid: catalog.bpModuleUuid } : {}),\n ...(catalog.dependencies ? { dependencies: catalog.dependencies } : {}),\n });\n } catch (e) {\n throw new Error(`assemble-bp failed: ${(e as Error).message}`);\n }\n packLog(`assembled BP uuid=${catalog.bpUuid}`, \"success\");\n\n if (Object.keys(rpDirs).length > 0 && catalog.rpUuid) {\n /* OCP:\u663E\u5F0F module\u2192rpDir map \u76F4\u4F20\u5E93\uFF0C\u4E0D\u518D\u4E34\u65F6\u955C\u50CF\u6574\u6811 / \u843D\u76D8 JSON */\n try {\n await assembleResourcePack({\n moduleResourceDirs: rpDirs,\n outDir: rpOut(),\n projectName: RP_NAME,\n version: catalog.rpVersion ?? DEFAULT_PACK_VERSION,\n description: \"ScriptsForMinecraftServer aggregated resource pack\",\n uuid: catalog.rpUuid,\n ...(catalog.rpModuleUuid ? { moduleUuid: catalog.rpModuleUuid } : {}),\n });\n } catch (e) {\n throw new Error(`assemble-rp failed: ${(e as Error).message}`);\n }\n packLog(`assembled RP uuid=${catalog.rpUuid} (${Object.keys(rpDirs).length} modules)`, \"success\");\n } else {\n /* \u65E0 RP:\u6E05\u7406\u65E7\u4EA7\u7269,catalog.rpUuid \u7F6E\u7A7A */\n await fs.rm(rpOut(), { recursive: true, force: true });\n catalog.rpUuid = null;\n catalog.rpVersion = null;\n packLog(\"no enabled resource packs \u2014 RP skipped\");\n }\n\n /* \u628A catalog \u5199\u5230\u672C\u5730 BP \u4EA7\u7269,deploy \u65F6\u4E00\u5E76\u62F7\u8D70 */\n catalog.generatedAt = Date.now();\n writeJson(path.join(bpOut(), DEPLOY_CATALOG_NAME), catalog);\n return catalog;\n}\n\n/** \u90E8\u7F72\u5230\u4E16\u754C + enable \u6E05\u5355 + Script API permission */\nexport async function deployPacks(catalog: DeployCatalog): Promise<void> {\n const { bdsRoot, levelName } = resolveBdsContext();\n if (!existsSync(bpOut())) {\n throw new Error(`BP not built at ${bpOut()}. Run build first.`);\n }\n\n /* \u5FC5\u987B\u5728 deploy/clear-rp \u4E4B\u524D\u91C7\u96C6 \u2014 \u6E05\u76EE\u5F55\u540E\u65E0\u6CD5\u518D\u8BFB manifest */\n const previous = collectDeployedPackUuids(bdsRoot, levelName);\n try {\n await deployToBDS({\n bdsRoot,\n levelName,\n behaviorPackSrc: bpOut(),\n bpName: BP_NAME,\n rpName: RP_NAME,\n ...(catalog.rpUuid && existsSync(rpOut())\n ? { resourcePackSrc: rpOut() }\n : { clearResourcePack: true }),\n });\n } catch (e) {\n throw new Error(`deploy failed: ${(e as Error).message}`);\n }\n packLog(`deployed to worlds/${levelName}`, \"success\");\n\n /* \u786E\u4FDD catalog \u5728\u90E8\u7F72\u540E\u7684 BP \u5185(deploy \u4F1A\u62F7\u8D1D\u6574\u4E2A\u76EE\u5F55) */\n writeJson(path.join(deployedBpDir(bdsRoot, levelName), DEPLOY_CATALOG_NAME), catalog);\n\n const worldsDir = bdsWorldsDir(bdsRoot);\n try {\n await enablePackInWorld({\n worldsDir,\n levelName,\n kind: \"behavior\",\n packUuid: catalog.bpUuid,\n version: catalog.bpVersion,\n });\n } catch (e) {\n throw new Error(`enable BP failed: ${(e as Error).message}`);\n }\n packLog(`enabled behavior pack ${catalog.bpUuid} in world list`, \"success\");\n\n if (catalog.rpUuid && catalog.rpVersion) {\n try {\n await enablePackInWorld({\n worldsDir,\n levelName,\n kind: \"resource\",\n packUuid: catalog.rpUuid,\n version: catalog.rpVersion,\n });\n } catch (e) {\n throw new Error(`enable RP failed: ${(e as Error).message}`);\n }\n packLog(`enabled resource pack ${catalog.rpUuid} in world list`, \"success\");\n }\n\n /* \u5378\u6389\u8FC7\u671F RP:UUID \u8F6E\u6362 / \u4E0D\u518D\u63D0\u4F9B RP / catalog \u7F3A\u5931\u4F46\u78C1\u76D8\u4ECD\u6709\u65E7\u5305 */\n for (const staleRp of previous.rp) {\n if (staleRp === (catalog.rpUuid ?? null)) continue;\n try {\n await disablePackInWorld({\n worldsDir,\n levelName,\n kind: \"resource\",\n packUuid: staleRp,\n version: DEFAULT_PACK_VERSION,\n });\n packLog(`disabled stale resource pack ${staleRp}`, \"success\");\n } catch (e) {\n packLog(`disable stale RP ${staleRp} failed: ${(e as Error).message}`, \"warn\");\n }\n }\n\n /* \u5378\u6389\u8FC7\u671F BP(uuid \u8F6E\u6362) */\n for (const staleBp of previous.bp) {\n if (staleBp === catalog.bpUuid) continue;\n try {\n await disablePackInWorld({\n worldsDir,\n levelName,\n kind: \"behavior\",\n packUuid: staleBp,\n version: DEFAULT_PACK_VERSION,\n });\n packLog(`disabled stale behavior pack ${staleBp}`, \"success\");\n } catch (e) {\n packLog(`disable stale BP ${staleBp} failed: ${(e as Error).message}`, \"warn\");\n }\n }\n\n try {\n const wrote = await ensureConfigPermission(bdsRoot, catalog.bpUuid);\n const permRel = path.relative(bdsRoot, configPermissionPath(bdsRoot, catalog.bpUuid));\n packLog(wrote ? `wrote ${permRel}` : `${permRel} already exists \u2014 skipped`);\n } catch (e) {\n throw new Error(`ensure-permission failed: ${(e as Error).message}`);\n }\n}\n\nexport function formatPackLoadInfo(catalog: DeployCatalog, rebuilt: boolean): string {\n const mods = Object.entries(catalog.modules);\n const enabled = mods.filter(([, m]) => m.enabled);\n const disabled = mods.filter(([, m]) => !m.enabled);\n const lines = [\n `pack load ${rebuilt ? \"(rebuilt)\" : \"(catalog match \u2014 skip rebuild)\"}`,\n ` BP ${catalog.bpUuid} v${catalog.bpVersion.join(\".\")}`,\n catalog.rpUuid\n ? ` RP ${catalog.rpUuid} v${(catalog.rpVersion ?? DEFAULT_PACK_VERSION).join(\".\")}`\n : ` RP (none)`,\n ` modules: ${enabled.length} enabled / ${disabled.length} disabled / ${mods.length} installed`,\n ];\n if (catalog.dependencies && catalog.dependencies.length > 0) {\n const depStr = catalog.dependencies.map((d) => `${d.module_name}@${d.version}`).join(\" \");\n lines.push(` dependencies: ${depStr}`);\n }\n for (const [folderId, m] of enabled.sort((a, b) => a[0].localeCompare(b[0]))) {\n lines.push(` \u25CF ${folderId} (${m.logicalId}) ${m.version}${m.hasResourcePack ? \" +rp\" : \"\"}`);\n }\n for (const [folderId, m] of disabled.sort((a, b) => a[0].localeCompare(b[0]))) {\n lines.push(` \u25CB ${folderId} (${m.logicalId}) disabled`);\n }\n return lines.join(\"\\n\");\n}\n\nfunction reusePackIds(deployed: DeployCatalog): {\n bpUuid?: string;\n rpUuid?: string | null;\n bpVersion?: [number, number, number];\n rpVersion?: [number, number, number] | null;\n bpModuleUuid?: string;\n rpModuleUuid?: string;\n} {\n return {\n bpUuid: deployed.bpUuid,\n rpUuid: deployed.rpUuid,\n bpVersion: deployed.bpVersion,\n rpVersion: deployed.rpVersion,\n ...(deployed.bpModuleUuid ? { bpModuleUuid: deployed.bpModuleUuid } : {}),\n ...(deployed.rpModuleUuid ? { rpModuleUuid: deployed.rpModuleUuid } : {}),\n };\n}\n\n/**\n * BDS \u542F\u52A8\u524D\u95F8\u95E8:catalog \u4E0D\u4E00\u81F4\u5219\u6574\u5305\u91CD\u7F16\u90E8\u7F72;\u5931\u8D25\u629B\u9519,\u7981\u6B62\u542F\u52A8\u3002\n */\nexport async function ensurePacksReady(): Promise<PackEnsureResult> {\n const { bdsRoot, levelName } = resolveBdsContext();\n packLog(`preflight: checking packs for ${bdsRoot} / ${levelName}`);\n\n const deployed = readDeployedCatalog(bdsRoot, levelName);\n /* \u590D\u7528\u5DF2\u90E8\u7F72 UUID,\u907F\u514D\u65E0\u8C13\u8F6E\u6362 */\n let desired = await computeDesiredCatalog(deployed ? reusePackIds(deployed) : undefined);\n\n /* \u82E5 desired \u9700\u8981 RP \u4F46\u590D\u7528\u4E86\u65E7 null rpUuid,\u8865\u4E00\u4E2A */\n const needsRp = Object.values(desired.modules).some((m) => m.enabled && m.hasResourcePack);\n if (needsRp && !desired.rpUuid) {\n desired = await computeDesiredCatalog({\n bpUuid: desired.bpUuid,\n bpVersion: desired.bpVersion,\n ...(desired.bpModuleUuid ? { bpModuleUuid: desired.bpModuleUuid } : {}),\n rpUuid: crypto.randomUUID(),\n rpVersion: DEFAULT_PACK_VERSION,\n });\n }\n if (!needsRp) {\n desired.rpUuid = null;\n desired.rpVersion = null;\n }\n\n let needRebuild = !deployed || !catalogsEqual(desired, deployed);\n if (!needRebuild && deployed) {\n if (!worldPackListHas(bdsRoot, levelName, \"behavior\", deployed.bpUuid)) needRebuild = true;\n if (deployed.rpUuid && !worldPackListHas(bdsRoot, levelName, \"resource\", deployed.rpUuid)) {\n needRebuild = true;\n }\n const deployedMainJs = path.join(deployedBpDir(bdsRoot, levelName), \"scripts\", \"main.js\");\n if (!existsSync(deployedMainJs)) needRebuild = true;\n if (!hasConfigPermission(bdsRoot, deployed.bpUuid)) {\n /* permission \u7F3A\u5931\u53EA\u8865\u5199,\u4E0D\u5F3A\u5236\u6574\u5305\u91CD\u7F16 */\n try {\n const wrote = await ensureConfigPermission(bdsRoot, deployed.bpUuid);\n const permRel = path.relative(bdsRoot, configPermissionPath(bdsRoot, deployed.bpUuid));\n packLog(wrote ? `wrote ${permRel}` : `${permRel} already exists \u2014 skipped`);\n } catch (e) {\n throw new Error(`ensure-permission failed: ${(e as Error).message}`);\n }\n }\n }\n\n let rebuilt = false;\n if (needRebuild) {\n packLog(\"catalog mismatch \u2014 rebuilding packs\u2026\", \"warn\");\n desired = await buildPacks(desired);\n await deployPacks(desired);\n rebuilt = true;\n } else {\n packLog(\"catalog match \u2014 skip rebuild\", \"success\");\n }\n\n const summary = formatPackLoadInfo(desired, rebuilt);\n for (const line of summary.split(\"\\n\")) packLog(line, rebuilt ? \"success\" : \"info\");\n\n return {\n rebuilt,\n skipped: !rebuilt,\n catalog: desired,\n bdsRoot,\n levelName,\n summary,\n };\n}\n\n/* \u2500\u2500 CLI \u547D\u4EE4\u5B9E\u73B0 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\nexport async function cmdPackBuild(_args: string[]): Promise<CliResult> {\n try {\n const cat = await buildPacks();\n return okResult(c.green(t(\"pack.built\", { path: bpOut() })) + `\\n` + formatPackLoadInfo(cat, true) + \"\\n\");\n } catch (e) {\n packLog((e as Error).message, \"error\");\n return failResult(c.red(t(\"pack.buildFailed\", { message: (e as Error).message })));\n }\n}\n\nexport async function cmdPackDeploy(_args: string[]): Promise<CliResult> {\n try {\n const localCatFile = path.join(bpOut(), DEPLOY_CATALOG_NAME);\n let cat: DeployCatalog;\n if (existsSync(localCatFile)) {\n cat = JSON.parse(await fs.readFile(localCatFile, \"utf8\")) as DeployCatalog;\n } else {\n cat = await buildPacks();\n }\n await deployPacks(cat);\n return okResult(c.green(t(\"pack.deployed\")) + \"\\n\" + formatPackLoadInfo(cat, true) + \"\\n\");\n } catch (e) {\n packLog((e as Error).message, \"error\");\n return failResult(c.red(t(\"pack.deployFailed\", { message: (e as Error).message })));\n }\n}\n\nexport async function cmdPackStatus(_args: string[]): Promise<string> {\n try {\n const { bdsRoot, levelName } = resolveBdsContext();\n const deployed = readDeployedCatalog(bdsRoot, levelName);\n const desired = await computeDesiredCatalog(deployed ? reusePackIds(deployed) : undefined);\n const match = deployed ? catalogsEqual(desired, deployed) : false;\n const permPath = deployed ? configPermissionPath(bdsRoot, deployed.bpUuid) : null;\n const lines = [\n c.bold(\"\\nPack status\"),\n ` bds : ${bdsRoot}`,\n ` level : ${levelName}`,\n ` catalog : ${match ? c.green(\"in sync\") : c.yellow(deployed ? \"mismatch \u2014 will rebuild on start\" : \"missing\")}`,\n ` BP dir : ${deployedBpDir(bdsRoot, levelName)} ${existsSync(deployedBpDir(bdsRoot, levelName)) ? c.green(\"\u2713\") : c.red(\"\u2717\")}`,\n ` RP dir : ${deployedRpDir(bdsRoot, levelName)} ${existsSync(deployedRpDir(bdsRoot, levelName)) ? c.green(\"\u2713\") : c.dim(\"\u2014\")}`,\n ` permission : ${permPath ? (existsSync(permPath) ? c.green(permPath) : c.yellow(\"missing\")) : c.dim(\"n/a\")}`,\n ];\n if (deployed) {\n lines.push(` BP uuid : ${deployed.bpUuid}`);\n if (deployed.rpUuid) lines.push(` RP uuid : ${deployed.rpUuid}`);\n lines.push(\n ` world BP : ${worldPackListHas(bdsRoot, levelName, \"behavior\", deployed.bpUuid) ? c.green(\"listed\") : c.red(\"not listed\")}`\n );\n if (deployed.rpUuid) {\n lines.push(\n ` world RP : ${worldPackListHas(bdsRoot, levelName, \"resource\", deployed.rpUuid) ? c.green(\"listed\") : c.red(\"not listed\")}`\n );\n }\n }\n lines.push(formatPackLoadInfo(desired, false));\n return lines.join(\"\\n\") + \"\\n\";\n } catch (e) {\n return c.red(t(\"pack.statusFailed\", { message: (e as Error).message }));\n }\n}\n\nexport async function cmdPackList(_args: string[]): Promise<string> {\n try {\n const { bdsRoot, levelName } = resolveBdsContext();\n const mods = await scanLocalModules();\n const lines = [c.bold(\"\\nModules / resource packs\"), c.dim(` ${packagesDir()}`)];\n for (const m of mods) {\n const mark = m.enabled ? c.green(\"\u25CF\") : c.dim(\"\u25CB\");\n lines.push(\n ` ${mark} ${m.folderId.padEnd(24)} ${m.logicalId.padEnd(24)} ${m.enabled ? \"on \" : \"off\"} ${m.hasResourcePack ? \"+rp\" : \" \"} ${m.version}`\n );\n }\n const worldsDir = bdsWorldsDir(bdsRoot);\n lines.push(c.bold(\"\\nWorld enable lists\"));\n for (const kind of [\"behavior\", \"resource\"] as const) {\n const arr = readWorldPackList(worldsDir, levelName, kind);\n if (!arr.length) lines.push(c.dim(` ${kind}: (empty)`));\n for (const e of arr) {\n lines.push(` ${kind}: ${e.pack_id} v${(e.version ?? []).join(\".\")}`);\n }\n }\n return lines.join(\"\\n\") + \"\\n\";\n } catch (e) {\n return c.red(t(\"pack.listFailed\", { message: (e as Error).message }));\n }\n}\n\nexport async function cmdPackEnableDisable(action: \"enable\" | \"disable\", args: string[]): Promise<string> {\n try {\n const kind = (args[0] === \"resource\" || args[0] === \"rp\" ? \"resource\" : \"behavior\") as \"behavior\" | \"resource\";\n const { bdsRoot, levelName } = resolveBdsContext();\n const deployed = readDeployedCatalog(bdsRoot, levelName);\n if (!deployed) return c.red(t(\"pack.noCatalog\"));\n const uuid = kind === \"behavior\" ? deployed.bpUuid : deployed.rpUuid;\n const version = kind === \"behavior\" ? deployed.bpVersion : deployed.rpVersion;\n if (!uuid || !version) return c.red(t(\"pack.noUuid\", { kind }));\n const worldsDir = bdsWorldsDir(bdsRoot);\n try {\n const opts = { worldsDir, levelName, kind, packUuid: uuid, version };\n if (action === \"enable\") await enablePackInWorld(opts);\n else await disablePackInWorld(opts);\n } catch (e) {\n return c.red(t(\"pack.actionFailed\", { action, detail: (e as Error).message }));\n }\n packLog(`${action}d ${kind} pack ${uuid}`, \"success\");\n return c.green(\n action === \"enable\"\n ? t(\"pack.enabledOk\", { kind, uuid })\n : t(\"pack.disabledOk\", { kind, uuid })\n );\n } catch (e) {\n return c.red(t(\"pack.actionErr\", { action, message: (e as Error).message }));\n }\n}\n\n/* CLI \u8868\u9762\u5DF2\u6536\u655B\uFF1A\u6A21\u5757\u7528 mod build/reload\uFF1B\u7B2C\u4E09\u65B9\u5305\u542F\u505C\u7528 addon/packs\u3002\n * \u6B64\u5904\u4FDD\u7559 cmdPackBuild / cmdPackDeploy \u4F9B ensurePacksReady \u4E0E mod reload \u8C03\u7528\u3002 */\n\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["/**\n * pack-lifecycle.ts \u2014 \u884C\u4E3A\u5305/\u8D44\u6E90\u5305\u88C5\u8F7D\u751F\u547D\u5468\u671F\n *\n * \u804C\u8D23:\n * - \u8BA1\u7B97\u672C\u673A desired deploy-catalog(\u542F\u7528\u6A21\u5757 + fingerprint)\n * - \u4E0E\u4E16\u754C BP \u5185 sfmc-deploy-catalog.json \u6BD4\u5BF9\n * - \u4E0D\u4E00\u81F4\u5219\u6574\u5305 build + deploy + \u5199\u4E16\u754C\u6E05\u5355 + Script API permission\n * - \u542F\u52A8\u524D ensurePacksReady;\u65E5\u5FD7\u4E00\u5F8B\u8D70 source=`pack`\n */\n\nimport {\n configPath,\n modulePath,\n readJson,\n writeJson,\n type BdsUpdaterConfig,\n type Catalog,\n type ModuleLock,\n} from \"@sfmc-bds/sdk/node/config\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { pushLog } from \"./logs.js\";\nimport { dirFingerprint } from \"./module-fingerprint.js\";\nimport { failResult, okResult, type CliResult } from \"./cli-result.js\";\nimport { t } from \"./i18n/index.js\";\nimport {\n assembleBehaviorPack,\n assembleResourcePack,\n bdsWorldLevelDir,\n bdsWorldsDir,\n configPermissionPath,\n deployToBDS,\n disablePackInWorld,\n enablePackInWorld,\n ensureConfigPermission,\n hasConfigPermission,\n readLevelNameSync,\n readPackManifestHeader,\n readWorldPackList,\n worldPackListHas as pmWorldPackListHas,\n BASELINE_BEDROCK_DEPENDENCIES,\n negotiateBedrockDependencies,\n NATIVE_BEDROCK_SCRIPT_MODULES,\n type PackManifestDependency,\n} from \"@sfmc-bds/bds-tools/pack-manager-lib\";\nimport { ROOT, PACKAGES_DIR, resolveSdkPackageRoot, getRoot } from \"./runtime.js\";\nimport { c } from \"./theme.js\";\n\nexport const BP_NAME = \"sfmc-modules\";\nexport const RP_NAME = \"sfmc-modules-rp\";\nexport const DEPLOY_CATALOG_NAME = \"sfmc-deploy-catalog.json\";\nexport const DEFAULT_PACK_VERSION: [number, number, number] = [1, 0, 0];\n\n/** \u5C06 @sfmc/sdk \u4E0E @sfmc-bds/sdk \u5B50\u8DEF\u5F84\u89E3\u6790\u5230 SDK \u5305\u5185\u771F\u5B9E\u6587\u4EF6\uFF0C\u5E76\u6CE8\u5165 sfmc:host \u5F15\u5BFC\u5165\u53E3 */\nexport function createSdkResolvePlugin(sdkRoot: string): import(\"esbuild\").Plugin {\n const pkg = JSON.parse(readFileSync(path.join(sdkRoot, \"package.json\"), \"utf8\")) as {\n exports?: Record<string, string | { import?: string; default?: string; types?: string }>;\n };\n const exportsMap = pkg.exports ?? {};\n\n function resolveExportSubpath(subpath: string): string | null {\n const key = subpath === \"\" ? \".\" : `./${subpath}`;\n const entry = exportsMap[key];\n if (!entry) return null;\n const rel = typeof entry === \"string\" ? entry : (entry.import ?? entry.default);\n if (!rel || typeof rel !== \"string\") return null;\n const abs = path.join(sdkRoot, rel);\n return existsSync(abs) ? abs : null;\n }\n\n return {\n name: \"sfmc-sdk-resolve\",\n setup(build) {\n build.onResolve({ filter: /^sfmc:host$/ }, () => ({\n path: \"sfmc:host\",\n namespace: \"sfmc-host\",\n }));\n build.onLoad({ filter: /.*/, namespace: \"sfmc-host\" }, () => ({\n contents: [\n 'import { installHostBootstrap } from \"@sfmc-bds/sdk/module-loader/install\";',\n \"installHostBootstrap();\",\n ].join(\"\\n\"),\n loader: \"ts\",\n }));\n\n build.onResolve({ filter: /^@sfmc(?:-bds)?\\/sdk(?:\\/|$)/ }, (args) => {\n const normalized = args.path.replace(/^@sfmc\\/sdk/, \"@sfmc-bds/sdk\");\n const sub = normalized === \"@sfmc-bds/sdk\" ? \"\" : normalized.slice(\"@sfmc-bds/sdk/\".length);\n\n const importerNorm = (args.importer || \"\").replace(/\\\\/g, \"/\");\n const sapiIdx = importerNorm.indexOf(\"/sapi/\");\n if (sapiIdx !== -1 && !importerNorm.includes(\"@sfmc-sdk\") && !importerNorm.includes(\"@sfmc/sdk\")) {\n const sapiDir = importerNorm.slice(0, sapiIdx + \"/sapi\".length);\n const manifestFile = path.join(sapiDir, \"manifest.json\");\n let logicalId = \"\";\n let configKey = \"\";\n if (existsSync(manifestFile)) {\n try {\n const man = JSON.parse(readFileSync(manifestFile, \"utf8\")) as { id?: string; configKey?: string };\n if (man.id) logicalId = man.id;\n if (man.configKey) configKey = man.configKey;\n } catch {}\n }\n if (!logicalId) {\n const rootDir = importerNorm.slice(0, sapiIdx);\n logicalId = path.basename(rootDir).replace(/^sfmc-module-/, \"\");\n configKey = logicalId;\n }\n if (sub === \"sapi/db\") {\n return {\n path: `sfmc-scoped:db?mod=${encodeURIComponent(logicalId)}`,\n namespace: \"sfmc-scoped-db\",\n };\n }\n if (sub === \"sapi/config\") {\n return {\n path: `sfmc-scoped:config?cfg=${encodeURIComponent(configKey)}`,\n namespace: \"sfmc-scoped-config\",\n };\n }\n if (sub === \"sapi/service\") {\n return {\n path: `sfmc-scoped:service?mod=${encodeURIComponent(logicalId)}`,\n namespace: \"sfmc-scoped-service\",\n };\n }\n }\n\n const resolved = resolveExportSubpath(sub);\n if (!resolved) {\n return {\n errors: [\n {\n text: `Cannot resolve ${args.path} under SDK at ${sdkRoot} (export \"./${sub || \".\"}\" missing or file absent; run sdk:build?)`,\n },\n ],\n };\n }\n // \u865A\u62DF\u5BBF\u4E3B\u4E2D\u7684 SDK \u5BFC\u5165\u4E5F\u6536\u655B\u5230\u6807\u51C6\u6587\u4EF6\u547D\u540D\u7A7A\u95F4\u3002\n return { path: resolved, namespace: \"file\" };\n });\n\n build.onLoad({ filter: /.*/, namespace: \"sfmc-scoped-db\" }, (args) => {\n const u = new URL(args.path);\n const mod = u.searchParams.get(\"mod\") || \"\";\n return {\n contents: [\n 'import { getDbClient } from \"@sfmc-bds/sdk/sapi/db\";',\n 'export * from \"@sfmc-bds/sdk/sapi/db\";',\n 'export const db = new Proxy({}, {',\n ' get(_t, prop) {',\n ` const c = getDbClient(${JSON.stringify(mod)});`,\n ' const val = (c as any)[prop];',\n ' return typeof val === \"function\" ? val.bind(c) : val;',\n ' }',\n '});',\n ].join(\"\\n\"),\n loader: \"ts\",\n resolveDir: sdkRoot,\n };\n });\n\n build.onLoad({ filter: /.*/, namespace: \"sfmc-scoped-config\" }, (args) => {\n const u = new URL(args.path);\n const cfg = u.searchParams.get(\"cfg\") || \"\";\n return {\n contents: [\n 'import { getConfigClient } from \"@sfmc-bds/sdk/sapi/config\";',\n 'export * from \"@sfmc-bds/sdk/sapi/config\";',\n 'export const config = new Proxy({}, {',\n ' get(_t, prop) {',\n ` const c = getConfigClient(${JSON.stringify(cfg)});`,\n ' const val = (c as any)[prop];',\n ' return typeof val === \"function\" ? val.bind(c) : val;',\n ' }',\n '});',\n ].join(\"\\n\"),\n loader: \"ts\",\n resolveDir: sdkRoot,\n };\n });\n\n build.onLoad({ filter: /.*/, namespace: \"sfmc-scoped-service\" }, (args) => {\n const u = new URL(args.path);\n const mod = u.searchParams.get(\"mod\") || \"\";\n return {\n contents: [\n 'import { getServiceClient } from \"@sfmc-bds/sdk/sapi/service\";',\n 'export * from \"@sfmc-bds/sdk/sapi/service\";',\n 'export const service = new Proxy({}, {',\n ' get(_t, prop) {',\n ` const c = getServiceClient(${JSON.stringify(mod)});`,\n ' const val = (c as any)[prop];',\n ' return typeof val === \"function\" ? val.bind(c) : val;',\n ' }',\n '});',\n ].join(\"\\n\"),\n loader: \"ts\",\n resolveDir: sdkRoot,\n };\n });\n },\n };\n}\n\nexport function buildRoot(): string {\n /* \u4E0E\u6536\u4EF6\u7BB1\u540C\u6811\uFF1Apacks/_build\uFF08_ \u524D\u7F00\u4E0D\u4F1A\u88AB inbox \u626B\u63CF\uFF09 */\n return path.join(ROOT, \"packs\", \"_build\");\n}\nexport function bpSrc(): string {\n return path.join(buildRoot(), `${BP_NAME}-bp`);\n}\nexport function bpOut(): string {\n return path.join(buildRoot(), BP_NAME);\n}\nexport function rpOut(): string {\n return path.join(buildRoot(), RP_NAME);\n}\n\nexport interface DeployCatalogModule {\n logicalId: string;\n enabled: boolean;\n version: string;\n fingerprint: string;\n hasResourcePack: boolean;\n}\n\nexport interface DeployCatalog {\n schemaVersion: 1;\n bpUuid: string;\n rpUuid: string | null;\n bpVersion: [number, number, number];\n rpVersion: [number, number, number] | null;\n bpModuleUuid?: string;\n rpModuleUuid?: string;\n generatedAt: number;\n sdkVersion?: string;\n dependencies?: PackManifestDependency[];\n modules: Record<string, DeployCatalogModule>;\n}\n\nexport interface PackEnsureResult {\n rebuilt: boolean;\n skipped: boolean;\n catalog: DeployCatalog;\n bdsRoot: string;\n levelName: string;\n summary: string;\n}\n\ninterface PackManifestLite {\n id?: string;\n version?: string;\n schemaVersion?: number;\n enabledByDefault?: boolean;\n name?: string;\n}\n\nfunction packLog(text: string, level: \"info\" | \"success\" | \"warn\" | \"error\" = \"info\"): void {\n pushLog(text, \"pack\", level);\n}\n\nfunction packagesDir(): string {\n return PACKAGES_DIR || path.join(ROOT, \"modules\", \"packages\");\n}\n\nfunction lockPath(): string {\n return modulePath(path.join(ROOT, \"modules\"), \"module-lock.json\");\n}\n\nfunction catalogPath(): string {\n return modulePath(path.join(ROOT, \"modules\"), \"catalog.json\");\n}\n\n/** \u8BFB BDS \u8DEF\u5F84\u4E0E level-name\uFF08level \u6743\u5A01\uFF1Apack-manager-lib.readLevelNameSync\uFF0CDIP\uFF09 */\nexport function resolveBdsContext(root: string = getRoot()): { bdsRoot: string; levelName: string } {\n const cfg = (readJson<BdsUpdaterConfig>(configPath(root, \"bds_updater.json\")) ?? {}) as BdsUpdaterConfig;\n const rawBds = cfg.bds_path;\n if (!rawBds) {\n throw new Error(\"bds_path not configured. Run `sfmc init` first.\");\n }\n const bdsRoot = path.isAbsolute(rawBds) ? rawBds : path.resolve(root, rawBds);\n return { bdsRoot, levelName: readLevelNameSync(bdsRoot) };\n}\n\nexport function deployedBpDir(bdsRoot: string, levelName: string): string {\n return path.join(bdsWorldLevelDir(bdsRoot, levelName), \"behavior_packs\", BP_NAME);\n}\n\nexport function deployedRpDir(bdsRoot: string, levelName: string): string {\n return path.join(bdsWorldLevelDir(bdsRoot, levelName), \"resource_packs\", RP_NAME);\n}\n\nexport function deployedCatalogPath(bdsRoot: string, levelName: string): string {\n return path.join(deployedBpDir(bdsRoot, levelName), DEPLOY_CATALOG_NAME);\n}\n\n/** \u89E3\u6790\u542F\u7528\u72B6\u6001:lock \u4F18\u5148,\u5426\u5219 catalog.enabledByDefault(\u7F3A\u7701 true\u2194!==false),\u672A\u6536\u5F55\u6A21\u5757 false */\nfunction isModuleEnabled(logicalId: string, lock: ModuleLock, catalogDefaults: Map<string, boolean>): boolean {\n const st = lock.modules?.[logicalId];\n if (st && typeof st.enabled === \"boolean\") return st.enabled;\n return catalogDefaults.get(logicalId) ?? false;\n}\n\n/**\n * \u90E8\u7F72\u524D\u6536\u96C6\u4E16\u754C\u5185\u5DF2\u51FA\u73B0\u7684 BP/RP uuid\u3002\n * \u540C\u65F6\u8BFB deploy-catalog \u4E0E\u78C1\u76D8 manifest \u2014 catalog \u7F3A\u5931\u65F6\u4ECD\u80FD\u5378\u8FC7\u671F\u6E05\u5355\u9879(Demeter/\u5B8C\u6574\u5951\u7EA6)\u3002\n */\nfunction collectDeployedPackUuids(\n bdsRoot: string,\n levelName: string\n): { bp: Set<string>; rp: Set<string> } {\n const bp = new Set<string>();\n const rp = new Set<string>();\n const cat = readDeployedCatalog(bdsRoot, levelName);\n if (cat?.bpUuid) bp.add(cat.bpUuid);\n if (cat?.rpUuid) rp.add(cat.rpUuid);\n const liveBp = readPackManifestHeader(deployedBpDir(bdsRoot, levelName));\n const liveRp = readPackManifestHeader(deployedRpDir(bdsRoot, levelName));\n if (liveBp?.uuid) bp.add(liveBp.uuid);\n if (liveRp?.uuid) rp.add(liveRp.uuid);\n return { bp, rp };\n}\n\n/**\n * \u4ECE\u6A21\u5757\u76EE\u5F55\u63D0\u53D6\u58F0\u660E\u7684 @minecraft/* \u539F\u751F\u4F9D\u8D56\u3002\n * \u4F18\u5148\u7EA7\uFF1A\n * 1. sapi/manifest.json \u7684 dependencies\uFF08\u6807\u51C6\u57FA\u5CA9\u6570\u7EC4\u6216\u952E\u503C\u5BF9\u6620\u5C04\uFF09\u4E0E minecraft \u5B57\u6BB5\uFF1B\n * 2. package.json \u7684 peerDependencies \u4E0E dependencies\uFF08\u4E0D\u542B devDependencies\uFF0C\u907F\u514D\u7C7B\u578B\u5305\u8BEF\u4F24\uFF09\u3002\n */\nexport async function extractModuleBedrockDependencies(modPath: string): Promise<PackManifestDependency[]> {\n const deps: PackManifestDependency[] = [];\n const seen = new Set<string>();\n\n const manifestPath = path.join(modPath, \"sapi\", \"manifest.json\");\n if (existsSync(manifestPath)) {\n try {\n const raw = JSON.parse(await fs.readFile(manifestPath, \"utf8\")) as Record<string, unknown>;\n if (Array.isArray(raw.dependencies)) {\n for (const d of raw.dependencies) {\n if (\n d &&\n typeof d === \"object\" &&\n typeof (d as { module_name?: unknown }).module_name === \"string\" &&\n (d as { module_name: string }).module_name.startsWith(\"@minecraft/\") &&\n NATIVE_BEDROCK_SCRIPT_MODULES.has((d as { module_name: string }).module_name)\n ) {\n const modName = (d as { module_name: string }).module_name;\n const ver = String((d as { version?: unknown }).version ?? \"1.0.0\");\n const uuid = typeof (d as { uuid?: unknown }).uuid === \"string\" ? (d as { uuid: string }).uuid : undefined;\n deps.push({ module_name: modName, version: ver, ...(uuid ? { uuid } : {}) });\n seen.add(modName);\n }\n }\n } else if (raw.dependencies && typeof raw.dependencies === \"object\") {\n for (const [modName, ver] of Object.entries(raw.dependencies as Record<string, unknown>)) {\n if (modName.startsWith(\"@minecraft/\") && !seen.has(modName) && NATIVE_BEDROCK_SCRIPT_MODULES.has(modName)) {\n deps.push({ module_name: modName, version: String(ver ?? \"1.0.0\") });\n seen.add(modName);\n }\n }\n }\n\n if (raw.minecraft && typeof raw.minecraft === \"object\") {\n const mc = raw.minecraft as Record<string, unknown>;\n const mcDeps = (Array.isArray(mc.dependencies) ? mc.dependencies : mc) as Record<string, unknown>;\n if (typeof mcDeps === \"object\" && !Array.isArray(mcDeps)) {\n for (const [modName, ver] of Object.entries(mcDeps)) {\n if (modName.startsWith(\"@minecraft/\") && !seen.has(modName) && NATIVE_BEDROCK_SCRIPT_MODULES.has(modName)) {\n deps.push({ module_name: modName, version: String(ver ?? \"1.0.0\") });\n seen.add(modName);\n }\n }\n }\n }\n } catch {\n /* ignore parse error */\n }\n }\n\n const pkgPath = path.join(modPath, \"package.json\");\n if (existsSync(pkgPath)) {\n try {\n const pkg = JSON.parse(await fs.readFile(pkgPath, \"utf8\")) as {\n peerDependencies?: Record<string, string>;\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n };\n const candidateMap = {\n ...(pkg.devDependencies ?? {}),\n ...(pkg.dependencies ?? {}),\n ...(pkg.peerDependencies ?? {}),\n };\n for (const [modName, ver] of Object.entries(candidateMap)) {\n if (modName.startsWith(\"@minecraft/\") && !seen.has(modName) && NATIVE_BEDROCK_SCRIPT_MODULES.has(modName)) {\n deps.push({ module_name: modName, version: ver });\n seen.add(modName);\n }\n }\n } catch {\n /* ignore */\n }\n }\n\n return deps;\n}\n\n/**\n * \u679A\u4E3E\u672C\u673A packages,\u8FD4\u56DE folderId \u2192 \u5143\u6570\u636E\u3002\n * \u4EC5\u542B\u6709 sapi/src/index.ts \u7684\u6A21\u5757\u4F1A\u8FDB\u5165 BP bundle \u5019\u9009\u3002\n */\nexport async function scanLocalModules(): Promise<\n Array<{\n folderId: string;\n logicalId: string;\n version: string;\n enabled: boolean;\n hasSapi: boolean;\n hasResourcePack: boolean;\n fingerprint: string;\n entryPath: string | null;\n declaredDependencies: PackManifestDependency[];\n }>\n> {\n const dir = packagesDir();\n if (!existsSync(dir)) return [];\n const lock = (readJson<ModuleLock>(lockPath()) ?? { version: 1, modules: {} }) as ModuleLock;\n const cat = (readJson<Catalog>(catalogPath()) ?? { version: 1, modules: [] }) as Catalog;\n const defaults = new Map<string, boolean>();\n if (Array.isArray(cat.modules)) {\n for (const m of cat.modules) {\n const id = typeof m.id === \"string\" ? m.id : \"\";\n if (!id) continue;\n /* \u4E0E db-server \u5951\u7EA6\u4E00\u81F4:enabledByDefault !== false(\u7F3A\u7701 true) \u2014 LSP */\n defaults.set(id, m.enabledByDefault !== false);\n }\n }\n\n const entries = await fs.readdir(dir, { withFileTypes: true });\n const out: Array<{\n folderId: string;\n logicalId: string;\n version: string;\n enabled: boolean;\n hasSapi: boolean;\n hasResourcePack: boolean;\n fingerprint: string;\n entryPath: string | null;\n declaredDependencies: PackManifestDependency[];\n }> = [];\n\n for (const e of entries) {\n if (e.name.startsWith(\".\")) continue;\n const folderId = e.name;\n const modPath = path.join(dir, folderId);\n // Dirent.isDirectory() \u5BF9\u300C\u6307\u5411\u76EE\u5F55\u7684 symlink\u300D\u5728 Linux \u4E3A false\uFF1B\u7528 stat \u8DDF\u968F\u94FE\u63A5\n try {\n const st = await fs.stat(modPath);\n if (!st.isDirectory()) continue;\n } catch {\n continue;\n }\n const manifestPath = path.join(modPath, \"sapi\", \"manifest.json\");\n const entryPath = path.join(modPath, \"sapi\", \"src\", \"index.ts\");\n let logicalId = folderId;\n let version = \"0.0.0\";\n if (existsSync(manifestPath)) {\n try {\n const man = JSON.parse(await fs.readFile(manifestPath, \"utf8\")) as PackManifestLite;\n if (typeof man.id === \"string\" && man.id) logicalId = man.id;\n if (typeof man.version === \"string\" && man.version) version = man.version;\n else if (typeof man.schemaVersion === \"number\") version = `schema-${man.schemaVersion}`;\n } catch {\n /* keep defaults */\n }\n }\n const hasSapi = existsSync(entryPath);\n const hasResourcePack = existsSync(path.join(modPath, \"resource_pack\"));\n const fingerprint = await dirFingerprint(modPath);\n const enabled = isModuleEnabled(logicalId, lock, defaults);\n const declaredDependencies = await extractModuleBedrockDependencies(modPath);\n out.push({\n folderId,\n logicalId,\n version,\n enabled,\n hasSapi,\n hasResourcePack,\n fingerprint,\n entryPath: hasSapi ? entryPath : null,\n declaredDependencies,\n });\n }\n out.sort((a, b) => a.folderId.localeCompare(b.folderId));\n return out;\n}\n\n/** \u4ECE\u672C\u673A\u72B6\u6001 + \u5DF2\u6709 UUID \u5408\u6210 desired catalog\u3002\n * UUID \u4F18\u5148:deployed catalog \u2192 \u672C\u5730 build manifest \u2192 \u65B0\u5EFA\u968F\u673A\u3002\n */\nexport async function computeDesiredCatalog(opts?: {\n bpUuid?: string;\n rpUuid?: string | null;\n bpVersion?: [number, number, number];\n rpVersion?: [number, number, number] | null;\n bpModuleUuid?: string;\n rpModuleUuid?: string;\n}): Promise<DeployCatalog> {\n const mods = await scanLocalModules();\n const modules: Record<string, DeployCatalogModule> = {};\n let anyRp = false;\n for (const m of mods) {\n /* catalog \u8BB0\u5F55\u5168\u90E8\u5DF2\u5B89\u88C5\u6A21\u5757\u7684\u542F\u505C\u4E0E\u6307\u7EB9,\u4FBF\u4E8E diff \u88C5\u5378/\u7981\u7528 */\n modules[m.folderId] = {\n logicalId: m.logicalId,\n enabled: m.enabled,\n version: m.version,\n fingerprint: m.fingerprint,\n hasResourcePack: m.hasResourcePack,\n };\n if (m.enabled && m.hasResourcePack) anyRp = true;\n }\n\n const localBp = readPackManifestHeader(bpOut());\n const localRp = readPackManifestHeader(rpOut());\n const bpUuid = opts?.bpUuid ?? localBp?.uuid ?? crypto.randomUUID();\n const bpVersion = opts?.bpVersion ?? localBp?.version ?? DEFAULT_PACK_VERSION;\n const bpModuleUuid = opts?.bpModuleUuid ?? localBp?.moduleUuid;\n let rpUuid: string | null = null;\n let rpVersion: [number, number, number] | null = null;\n let rpModuleUuid: string | undefined;\n if (anyRp) {\n rpUuid = opts?.rpUuid ?? localRp?.uuid ?? crypto.randomUUID();\n rpVersion = opts?.rpVersion ?? localRp?.version ?? DEFAULT_PACK_VERSION;\n rpModuleUuid = opts?.rpModuleUuid ?? localRp?.moduleUuid;\n }\n\n let sdkVersion: string | undefined;\n try {\n const sdkRoot = resolveSdkPackageRoot();\n const pkg = JSON.parse(readFileSync(path.join(sdkRoot, \"package.json\"), \"utf8\")) as { version?: string };\n sdkVersion = pkg.version;\n } catch {\n /* ignore */\n }\n\n // \u4F9D\u8D56\u52A8\u6001\u534F\u5546\uFF1A\u6536\u96C6\u6240\u6709\u5DF2\u542F\u7528\u6A21\u5757\u7684 Minecraft \u4F9D\u8D56\u58F0\u660E\u5E76\u6309\u7248\u672C\u89C4\u5219\u63D0\u5347\n const enabledModuleReqs = mods\n .filter((m) => m.enabled && m.declaredDependencies.length > 0)\n .map((m) => ({ folderId: m.folderId, dependencies: m.declaredDependencies }));\n const negotiated = negotiateBedrockDependencies(BASELINE_BEDROCK_DEPENDENCIES, enabledModuleReqs);\n\n if (negotiated.promotions.length > 0) {\n for (const p of negotiated.promotions) {\n packLog(\n `promoted ${p.moduleName} ${p.from} -> ${p.to} (requested by: ${p.requestedBy.join(\", \")})`,\n \"info\"\n );\n }\n }\n\n return {\n schemaVersion: 1,\n bpUuid,\n rpUuid,\n bpVersion,\n rpVersion,\n ...(bpModuleUuid ? { bpModuleUuid } : {}),\n ...(rpModuleUuid ? { rpModuleUuid } : {}),\n generatedAt: Date.now(),\n ...(sdkVersion ? { sdkVersion } : {}),\n dependencies: negotiated.dependencies,\n modules,\n };\n}\n\nexport function readDeployedCatalog(bdsRoot: string, levelName: string): DeployCatalog | null {\n const file = deployedCatalogPath(bdsRoot, levelName);\n if (!existsSync(file)) return null;\n try {\n return JSON.parse(readFileSync(file, \"utf8\")) as DeployCatalog;\n } catch {\n return null;\n }\n}\n\n/** \u6BD4\u8F83\u952E:\u6A21\u5757\u96C6\u5408 + enabled/version/fingerprint/hasRP + bp/rp uuid + sdkVersion + dependencies */\nexport function catalogsEqual(a: DeployCatalog, b: DeployCatalog): boolean {\n if (a.bpUuid !== b.bpUuid) return false;\n if ((a.rpUuid ?? null) !== (b.rpUuid ?? null)) return false;\n if ((a.sdkVersion ?? null) !== (b.sdkVersion ?? null)) return false;\n\n const depsA = a.dependencies ?? [];\n const depsB = b.dependencies ?? [];\n if (depsA.length !== depsB.length) return false;\n for (let i = 0; i < depsA.length; i++) {\n const da = depsA[i];\n const db = depsB[i];\n if (!da || !db || da.module_name !== db.module_name || da.version !== db.version) {\n return false;\n }\n }\n const aKeys = Object.keys(a.modules).sort();\n const bKeys = Object.keys(b.modules).sort();\n if (aKeys.length !== bKeys.length) return false;\n for (let i = 0; i < aKeys.length; i++) {\n if (aKeys[i] !== bKeys[i]) return false;\n }\n for (const k of aKeys) {\n const x = a.modules[k]!;\n const y = b.modules[k]!;\n if (\n x.logicalId !== y.logicalId ||\n x.enabled !== y.enabled ||\n x.version !== y.version ||\n x.fingerprint !== y.fingerprint ||\n x.hasResourcePack !== y.hasResourcePack\n ) {\n return false;\n }\n }\n /* \u4E16\u754C\u6E05\u5355\u662F\u5426\u4ECD\u542B uuid \u2014 \u8C03\u7528\u65B9\u989D\u5916\u68C0\u67E5 */\n return true;\n}\n\n/** \u4E16\u754C enable-list \u67E5\u8BE2 \u2014 \u76F4\u8FDE pack-manager-lib\uFF08DRY/DIP\uFF0C\u4E0E CLI has-pack \u540C\u5951\u7EA6\uFF09 */\nfunction worldPackListHas(bdsRoot: string, levelName: string, kind: \"behavior\" | \"resource\", uuid: string): boolean {\n return pmWorldPackListHas(bdsWorldsDir(bdsRoot), levelName, kind, uuid);\n}\n\n/** esbuild \u805A\u5408\u542F\u7528\u6A21\u5757 \u2192 assemble BP + RP(\u82E5\u6709) */\nexport async function buildPacks(desired?: DeployCatalog): Promise<DeployCatalog> {\n await fs.mkdir(buildRoot(), { recursive: true });\n const catalog = desired ?? (await computeDesiredCatalog());\n packLog(`building BP/RP (modules=${Object.keys(catalog.modules).length})\u2026`);\n\n /* \u5355\u6B21\u626B\u63CF:SAPI \u5165\u53E3 + RP \u76EE\u5F55(DRY,\u907F\u514D listEnabled* \u91CD\u590D fingerprint) */\n const mods = await scanLocalModules();\n const entries = mods.filter((m) => m.enabled && m.entryPath).map((m) => m.entryPath!);\n const rpDirs: Record<string, string> = {};\n for (const m of mods) {\n if (!m.enabled || !m.hasResourcePack) continue;\n rpDirs[m.folderId] = path.join(packagesDir(), m.folderId, \"resource_pack\");\n }\n\n const { build } = await import(\"esbuild\");\n const outFile = path.join(bpSrc(), \"scripts\", \"main.js\");\n await fs.mkdir(path.dirname(outFile), { recursive: true });\n if (entries.length === 0) {\n await fs.writeFile(outFile, \"/* no modules enabled */\\n\", \"utf8\");\n packLog(\"no enabled SAPI modules \u2014 empty main.js\", \"warn\");\n } else {\n const sdkRoot = resolveSdkPackageRoot();\n packLog(`SDK root: ${sdkRoot}`);\n await build({\n stdin: {\n contents: [\n 'import \"sfmc:host\";',\n ...entries.map((e) => `import ${JSON.stringify(path.resolve(e).replace(/\\\\/g, \"/\"))};`),\n ].join(\"\\n\"),\n resolveDir: ROOT,\n sourcefile: \"bootstrap.ts\",\n loader: \"ts\",\n },\n outfile: outFile,\n bundle: true,\n platform: \"neutral\",\n format: \"esm\",\n target: \"es2022\",\n logLevel: \"warning\",\n sourcemap: true,\n external: [\"@minecraft/*\"],\n // \u907F\u514D\u8BFB\u53D6\u6A21\u5757\u5185\u6B8B\u7F3A\u7684 extends\uFF08\u5982 ../../../sdk/@sfmc-sdk/tsconfig.json\uFF09\n tsconfigRaw: JSON.stringify({\n compilerOptions: {\n module: \"ESNext\",\n moduleResolution: \"bundler\",\n target: \"ES2022\",\n strict: true,\n skipLibCheck: true,\n },\n }),\n plugins: [createSdkResolvePlugin(sdkRoot)],\n });\n packLog(`esbuild bundled ${entries.length} entr(y/ies)`, \"success\");\n }\n\n try {\n await assembleBehaviorPack({\n srcDir: bpSrc(),\n outDir: bpOut(),\n projectName: BP_NAME,\n version: catalog.bpVersion,\n description: \"ScriptsForMinecraftServer aggregated behavior pack\",\n uuid: catalog.bpUuid,\n ...(catalog.bpModuleUuid ? { moduleUuid: catalog.bpModuleUuid } : {}),\n ...(catalog.dependencies ? { dependencies: catalog.dependencies } : {}),\n });\n } catch (e) {\n throw new Error(`assemble-bp failed: ${(e as Error).message}`);\n }\n packLog(`assembled BP uuid=${catalog.bpUuid}`, \"success\");\n\n if (Object.keys(rpDirs).length > 0 && catalog.rpUuid) {\n /* OCP:\u663E\u5F0F module\u2192rpDir map \u76F4\u4F20\u5E93\uFF0C\u4E0D\u518D\u4E34\u65F6\u955C\u50CF\u6574\u6811 / \u843D\u76D8 JSON */\n try {\n await assembleResourcePack({\n moduleResourceDirs: rpDirs,\n outDir: rpOut(),\n projectName: RP_NAME,\n version: catalog.rpVersion ?? DEFAULT_PACK_VERSION,\n description: \"ScriptsForMinecraftServer aggregated resource pack\",\n uuid: catalog.rpUuid,\n ...(catalog.rpModuleUuid ? { moduleUuid: catalog.rpModuleUuid } : {}),\n });\n } catch (e) {\n throw new Error(`assemble-rp failed: ${(e as Error).message}`);\n }\n packLog(`assembled RP uuid=${catalog.rpUuid} (${Object.keys(rpDirs).length} modules)`, \"success\");\n } else {\n /* \u65E0 RP:\u6E05\u7406\u65E7\u4EA7\u7269,catalog.rpUuid \u7F6E\u7A7A */\n await fs.rm(rpOut(), { recursive: true, force: true });\n catalog.rpUuid = null;\n catalog.rpVersion = null;\n packLog(\"no enabled resource packs \u2014 RP skipped\");\n }\n\n /* \u628A catalog \u5199\u5230\u672C\u5730 BP \u4EA7\u7269,deploy \u65F6\u4E00\u5E76\u62F7\u8D70 */\n catalog.generatedAt = Date.now();\n writeJson(path.join(bpOut(), DEPLOY_CATALOG_NAME), catalog);\n return catalog;\n}\n\n/** \u90E8\u7F72\u5230\u4E16\u754C + enable \u6E05\u5355 + Script API permission */\nexport async function deployPacks(catalog: DeployCatalog): Promise<void> {\n const { bdsRoot, levelName } = resolveBdsContext();\n if (!existsSync(bpOut())) {\n throw new Error(`BP not built at ${bpOut()}. Run build first.`);\n }\n\n /* \u5FC5\u987B\u5728 deploy/clear-rp \u4E4B\u524D\u91C7\u96C6 \u2014 \u6E05\u76EE\u5F55\u540E\u65E0\u6CD5\u518D\u8BFB manifest */\n const previous = collectDeployedPackUuids(bdsRoot, levelName);\n try {\n await deployToBDS({\n bdsRoot,\n levelName,\n behaviorPackSrc: bpOut(),\n bpName: BP_NAME,\n rpName: RP_NAME,\n ...(catalog.rpUuid && existsSync(rpOut())\n ? { resourcePackSrc: rpOut() }\n : { clearResourcePack: true }),\n });\n } catch (e) {\n throw new Error(`deploy failed: ${(e as Error).message}`);\n }\n packLog(`deployed to worlds/${levelName}`, \"success\");\n\n /* \u786E\u4FDD catalog \u5728\u90E8\u7F72\u540E\u7684 BP \u5185(deploy \u4F1A\u62F7\u8D1D\u6574\u4E2A\u76EE\u5F55) */\n writeJson(path.join(deployedBpDir(bdsRoot, levelName), DEPLOY_CATALOG_NAME), catalog);\n\n const worldsDir = bdsWorldsDir(bdsRoot);\n try {\n await enablePackInWorld({\n worldsDir,\n levelName,\n kind: \"behavior\",\n packUuid: catalog.bpUuid,\n version: catalog.bpVersion,\n });\n } catch (e) {\n throw new Error(`enable BP failed: ${(e as Error).message}`);\n }\n packLog(`enabled behavior pack ${catalog.bpUuid} in world list`, \"success\");\n\n if (catalog.rpUuid && catalog.rpVersion) {\n try {\n await enablePackInWorld({\n worldsDir,\n levelName,\n kind: \"resource\",\n packUuid: catalog.rpUuid,\n version: catalog.rpVersion,\n });\n } catch (e) {\n throw new Error(`enable RP failed: ${(e as Error).message}`);\n }\n packLog(`enabled resource pack ${catalog.rpUuid} in world list`, \"success\");\n }\n\n /* \u5378\u6389\u8FC7\u671F RP:UUID \u8F6E\u6362 / \u4E0D\u518D\u63D0\u4F9B RP / catalog \u7F3A\u5931\u4F46\u78C1\u76D8\u4ECD\u6709\u65E7\u5305 */\n for (const staleRp of previous.rp) {\n if (staleRp === (catalog.rpUuid ?? null)) continue;\n try {\n await disablePackInWorld({\n worldsDir,\n levelName,\n kind: \"resource\",\n packUuid: staleRp,\n version: DEFAULT_PACK_VERSION,\n });\n packLog(`disabled stale resource pack ${staleRp}`, \"success\");\n } catch (e) {\n packLog(`disable stale RP ${staleRp} failed: ${(e as Error).message}`, \"warn\");\n }\n }\n\n /* \u5378\u6389\u8FC7\u671F BP(uuid \u8F6E\u6362) */\n for (const staleBp of previous.bp) {\n if (staleBp === catalog.bpUuid) continue;\n try {\n await disablePackInWorld({\n worldsDir,\n levelName,\n kind: \"behavior\",\n packUuid: staleBp,\n version: DEFAULT_PACK_VERSION,\n });\n packLog(`disabled stale behavior pack ${staleBp}`, \"success\");\n } catch (e) {\n packLog(`disable stale BP ${staleBp} failed: ${(e as Error).message}`, \"warn\");\n }\n }\n\n try {\n const wrote = await ensureConfigPermission(bdsRoot, catalog.bpUuid);\n const permRel = path.relative(bdsRoot, configPermissionPath(bdsRoot, catalog.bpUuid));\n packLog(wrote ? `wrote ${permRel}` : `${permRel} already exists \u2014 skipped`);\n } catch (e) {\n throw new Error(`ensure-permission failed: ${(e as Error).message}`);\n }\n}\n\nexport function formatPackLoadInfo(catalog: DeployCatalog, rebuilt: boolean): string {\n const mods = Object.entries(catalog.modules);\n const enabled = mods.filter(([, m]) => m.enabled);\n const disabled = mods.filter(([, m]) => !m.enabled);\n const lines = [\n `pack load ${rebuilt ? \"(rebuilt)\" : \"(catalog match \u2014 skip rebuild)\"}`,\n ` BP ${catalog.bpUuid} v${catalog.bpVersion.join(\".\")}`,\n catalog.rpUuid\n ? ` RP ${catalog.rpUuid} v${(catalog.rpVersion ?? DEFAULT_PACK_VERSION).join(\".\")}`\n : ` RP (none)`,\n ` modules: ${enabled.length} enabled / ${disabled.length} disabled / ${mods.length} installed`,\n ];\n if (catalog.dependencies && catalog.dependencies.length > 0) {\n const depStr = catalog.dependencies.map((d) => `${d.module_name}@${d.version}`).join(\" \");\n lines.push(` dependencies: ${depStr}`);\n }\n for (const [folderId, m] of enabled.sort((a, b) => a[0].localeCompare(b[0]))) {\n lines.push(` \u25CF ${folderId} (${m.logicalId}) ${m.version}${m.hasResourcePack ? \" +rp\" : \"\"}`);\n }\n for (const [folderId, m] of disabled.sort((a, b) => a[0].localeCompare(b[0]))) {\n lines.push(` \u25CB ${folderId} (${m.logicalId}) disabled`);\n }\n return lines.join(\"\\n\");\n}\n\nfunction reusePackIds(deployed: DeployCatalog): {\n bpUuid?: string;\n rpUuid?: string | null;\n bpVersion?: [number, number, number];\n rpVersion?: [number, number, number] | null;\n bpModuleUuid?: string;\n rpModuleUuid?: string;\n} {\n return {\n bpUuid: deployed.bpUuid,\n rpUuid: deployed.rpUuid,\n bpVersion: deployed.bpVersion,\n rpVersion: deployed.rpVersion,\n ...(deployed.bpModuleUuid ? { bpModuleUuid: deployed.bpModuleUuid } : {}),\n ...(deployed.rpModuleUuid ? { rpModuleUuid: deployed.rpModuleUuid } : {}),\n };\n}\n\n/**\n * BDS \u542F\u52A8\u524D\u95F8\u95E8:catalog \u4E0D\u4E00\u81F4\u5219\u6574\u5305\u91CD\u7F16\u90E8\u7F72;\u5931\u8D25\u629B\u9519,\u7981\u6B62\u542F\u52A8\u3002\n */\nexport async function ensurePacksReady(): Promise<PackEnsureResult> {\n const { bdsRoot, levelName } = resolveBdsContext();\n packLog(`preflight: checking packs for ${bdsRoot} / ${levelName}`);\n\n const deployed = readDeployedCatalog(bdsRoot, levelName);\n /* \u590D\u7528\u5DF2\u90E8\u7F72 UUID,\u907F\u514D\u65E0\u8C13\u8F6E\u6362 */\n let desired = await computeDesiredCatalog(deployed ? reusePackIds(deployed) : undefined);\n\n /* \u82E5 desired \u9700\u8981 RP \u4F46\u590D\u7528\u4E86\u65E7 null rpUuid,\u8865\u4E00\u4E2A */\n const needsRp = Object.values(desired.modules).some((m) => m.enabled && m.hasResourcePack);\n if (needsRp && !desired.rpUuid) {\n desired = await computeDesiredCatalog({\n bpUuid: desired.bpUuid,\n bpVersion: desired.bpVersion,\n ...(desired.bpModuleUuid ? { bpModuleUuid: desired.bpModuleUuid } : {}),\n rpUuid: crypto.randomUUID(),\n rpVersion: DEFAULT_PACK_VERSION,\n });\n }\n if (!needsRp) {\n desired.rpUuid = null;\n desired.rpVersion = null;\n }\n\n let needRebuild = !deployed || !catalogsEqual(desired, deployed);\n if (!needRebuild && deployed) {\n if (!worldPackListHas(bdsRoot, levelName, \"behavior\", deployed.bpUuid)) needRebuild = true;\n if (deployed.rpUuid && !worldPackListHas(bdsRoot, levelName, \"resource\", deployed.rpUuid)) {\n needRebuild = true;\n }\n const deployedMainJs = path.join(deployedBpDir(bdsRoot, levelName), \"scripts\", \"main.js\");\n if (!existsSync(deployedMainJs)) needRebuild = true;\n if (!hasConfigPermission(bdsRoot, deployed.bpUuid)) {\n /* permission \u7F3A\u5931\u53EA\u8865\u5199,\u4E0D\u5F3A\u5236\u6574\u5305\u91CD\u7F16 */\n try {\n const wrote = await ensureConfigPermission(bdsRoot, deployed.bpUuid);\n const permRel = path.relative(bdsRoot, configPermissionPath(bdsRoot, deployed.bpUuid));\n packLog(wrote ? `wrote ${permRel}` : `${permRel} already exists \u2014 skipped`);\n } catch (e) {\n throw new Error(`ensure-permission failed: ${(e as Error).message}`);\n }\n }\n }\n\n let rebuilt = false;\n if (needRebuild) {\n packLog(\"catalog mismatch \u2014 rebuilding packs\u2026\", \"warn\");\n desired = await buildPacks(desired);\n await deployPacks(desired);\n rebuilt = true;\n } else {\n packLog(\"catalog match \u2014 skip rebuild\", \"success\");\n }\n\n const summary = formatPackLoadInfo(desired, rebuilt);\n for (const line of summary.split(\"\\n\")) packLog(line, rebuilt ? \"success\" : \"info\");\n\n return {\n rebuilt,\n skipped: !rebuilt,\n catalog: desired,\n bdsRoot,\n levelName,\n summary,\n };\n}\n\n/* \u2500\u2500 CLI \u547D\u4EE4\u5B9E\u73B0 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\nexport async function cmdPackBuild(_args: string[]): Promise<CliResult> {\n try {\n const cat = await buildPacks();\n return okResult(c.green(t(\"pack.built\", { path: bpOut() })) + `\\n` + formatPackLoadInfo(cat, true) + \"\\n\");\n } catch (e) {\n packLog((e as Error).message, \"error\");\n return failResult(c.red(t(\"pack.buildFailed\", { message: (e as Error).message })));\n }\n}\n\nexport async function cmdPackDeploy(_args: string[]): Promise<CliResult> {\n try {\n const localCatFile = path.join(bpOut(), DEPLOY_CATALOG_NAME);\n let cat: DeployCatalog;\n if (existsSync(localCatFile)) {\n cat = JSON.parse(await fs.readFile(localCatFile, \"utf8\")) as DeployCatalog;\n } else {\n cat = await buildPacks();\n }\n await deployPacks(cat);\n return okResult(c.green(t(\"pack.deployed\")) + \"\\n\" + formatPackLoadInfo(cat, true) + \"\\n\");\n } catch (e) {\n packLog((e as Error).message, \"error\");\n return failResult(c.red(t(\"pack.deployFailed\", { message: (e as Error).message })));\n }\n}\n\nexport async function cmdPackStatus(_args: string[]): Promise<string> {\n try {\n const { bdsRoot, levelName } = resolveBdsContext();\n const deployed = readDeployedCatalog(bdsRoot, levelName);\n const desired = await computeDesiredCatalog(deployed ? reusePackIds(deployed) : undefined);\n const match = deployed ? catalogsEqual(desired, deployed) : false;\n const permPath = deployed ? configPermissionPath(bdsRoot, deployed.bpUuid) : null;\n const lines = [\n c.bold(\"\\nPack status\"),\n ` bds : ${bdsRoot}`,\n ` level : ${levelName}`,\n ` catalog : ${match ? c.green(\"in sync\") : c.yellow(deployed ? \"mismatch \u2014 will rebuild on start\" : \"missing\")}`,\n ` BP dir : ${deployedBpDir(bdsRoot, levelName)} ${existsSync(deployedBpDir(bdsRoot, levelName)) ? c.green(\"\u2713\") : c.red(\"\u2717\")}`,\n ` RP dir : ${deployedRpDir(bdsRoot, levelName)} ${existsSync(deployedRpDir(bdsRoot, levelName)) ? c.green(\"\u2713\") : c.dim(\"\u2014\")}`,\n ` permission : ${permPath ? (existsSync(permPath) ? c.green(permPath) : c.yellow(\"missing\")) : c.dim(\"n/a\")}`,\n ];\n if (deployed) {\n lines.push(` BP uuid : ${deployed.bpUuid}`);\n if (deployed.rpUuid) lines.push(` RP uuid : ${deployed.rpUuid}`);\n lines.push(\n ` world BP : ${worldPackListHas(bdsRoot, levelName, \"behavior\", deployed.bpUuid) ? c.green(\"listed\") : c.red(\"not listed\")}`\n );\n if (deployed.rpUuid) {\n lines.push(\n ` world RP : ${worldPackListHas(bdsRoot, levelName, \"resource\", deployed.rpUuid) ? c.green(\"listed\") : c.red(\"not listed\")}`\n );\n }\n }\n lines.push(formatPackLoadInfo(desired, false));\n return lines.join(\"\\n\") + \"\\n\";\n } catch (e) {\n return c.red(t(\"pack.statusFailed\", { message: (e as Error).message }));\n }\n}\n\nexport async function cmdPackList(_args: string[]): Promise<string> {\n try {\n const { bdsRoot, levelName } = resolveBdsContext();\n const mods = await scanLocalModules();\n const lines = [c.bold(\"\\nModules / resource packs\"), c.dim(` ${packagesDir()}`)];\n for (const m of mods) {\n const mark = m.enabled ? c.green(\"\u25CF\") : c.dim(\"\u25CB\");\n lines.push(\n ` ${mark} ${m.folderId.padEnd(24)} ${m.logicalId.padEnd(24)} ${m.enabled ? \"on \" : \"off\"} ${m.hasResourcePack ? \"+rp\" : \" \"} ${m.version}`\n );\n }\n const worldsDir = bdsWorldsDir(bdsRoot);\n lines.push(c.bold(\"\\nWorld enable lists\"));\n for (const kind of [\"behavior\", \"resource\"] as const) {\n const arr = readWorldPackList(worldsDir, levelName, kind);\n if (!arr.length) lines.push(c.dim(` ${kind}: (empty)`));\n for (const e of arr) {\n lines.push(` ${kind}: ${e.pack_id} v${(e.version ?? []).join(\".\")}`);\n }\n }\n return lines.join(\"\\n\") + \"\\n\";\n } catch (e) {\n return c.red(t(\"pack.listFailed\", { message: (e as Error).message }));\n }\n}\n\nexport async function cmdPackEnableDisable(action: \"enable\" | \"disable\", args: string[]): Promise<string> {\n try {\n const kind = (args[0] === \"resource\" || args[0] === \"rp\" ? \"resource\" : \"behavior\") as \"behavior\" | \"resource\";\n const { bdsRoot, levelName } = resolveBdsContext();\n const deployed = readDeployedCatalog(bdsRoot, levelName);\n if (!deployed) return c.red(t(\"pack.noCatalog\"));\n const uuid = kind === \"behavior\" ? deployed.bpUuid : deployed.rpUuid;\n const version = kind === \"behavior\" ? deployed.bpVersion : deployed.rpVersion;\n if (!uuid || !version) return c.red(t(\"pack.noUuid\", { kind }));\n const worldsDir = bdsWorldsDir(bdsRoot);\n try {\n const opts = { worldsDir, levelName, kind, packUuid: uuid, version };\n if (action === \"enable\") await enablePackInWorld(opts);\n else await disablePackInWorld(opts);\n } catch (e) {\n return c.red(t(\"pack.actionFailed\", { action, detail: (e as Error).message }));\n }\n packLog(`${action}d ${kind} pack ${uuid}`, \"success\");\n return c.green(\n action === \"enable\"\n ? t(\"pack.enabledOk\", { kind, uuid })\n : t(\"pack.disabledOk\", { kind, uuid })\n );\n } catch (e) {\n return c.red(t(\"pack.actionErr\", { action, message: (e as Error).message }));\n }\n}\n\n/* CLI \u8868\u9762\u5DF2\u6536\u655B\uFF1A\u6A21\u5757\u7528 mod build/reload\uFF1B\u7B2C\u4E09\u65B9\u5305\u542F\u505C\u7528 addon/packs\u3002\n * \u6B64\u5904\u4FDD\u7559 cmdPackBuild / cmdPackDeploy \u4F9B ensurePacksReady \u4E0E mod reload \u8C03\u7528\u3002 */\n\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { describe, it } from "node:test";
|
|
3
|
+
import { nonBlankOutputLines } from "./services.js";
|
|
4
|
+
describe("\u5B50\u8FDB\u7A0B\u8F93\u51FA\u5206\u884C", () => {
|
|
5
|
+
it("\u8FC7\u6EE4 LF\u3001CRLF \u4E0E\u7EAF\u7A7A\u767D\u884C\uFF0C\u4FDD\u7559\u771F\u5B9E\u65E5\u5FD7\u5185\u5BB9", () => {
|
|
6
|
+
assert.deepEqual(nonBlankOutputLines("first\r\n\r\n \r\nsecond\r\n"), ["first", "second"]);
|
|
7
|
+
});
|
|
8
|
+
});
|
|
9
|
+
//# sourceMappingURL=services-output.test.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/services-output.test.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * \u5B50\u8FDB\u7A0B\u65E5\u5FD7\u5165\u53E3\u5951\u7EA6\uFF1A\u7EAF\u7A7A\u767D\u884C\u4E0D\u80FD\u8FDB\u5165\u7EDF\u4E00\u65E5\u5FD7\u5E76\u88AB\u5305\u88C5\u6210 [INF]\u3002\n */\nimport assert from \"node:assert/strict\";\nimport { describe, it } from \"node:test\";\nimport { nonBlankOutputLines } from \"./services.js\";\n\ndescribe(\"\u5B50\u8FDB\u7A0B\u8F93\u51FA\u5206\u884C\", () => {\n it(\"\u8FC7\u6EE4 LF\u3001CRLF \u4E0E\u7EAF\u7A7A\u767D\u884C\uFF0C\u4FDD\u7559\u771F\u5B9E\u65E5\u5FD7\u5185\u5BB9\", () => {\n assert.deepEqual(nonBlankOutputLines(\"first\\r\\n\\r\\n \\r\\nsecond\\r\\n\"), [\"first\", \"second\"]);\n });\n});\n"],
|
|
5
|
+
"mappings": "AAGA,OAAO,YAAY;AACnB,SAAS,UAAU,UAAU;AAC7B,SAAS,2BAA2B;AAEpC,SAAS,8CAAW,MAAM;AACxB,KAAG,kHAA6B,MAAM;AACpC,WAAO,UAAU,oBAAoB,+BAA+B,GAAG,CAAC,SAAS,QAAQ,CAAC;AAAA,EAC5F,CAAC;AACH,CAAC;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/dist/services.d.ts
CHANGED
|
@@ -22,6 +22,8 @@ export interface LogLine {
|
|
|
22
22
|
text: string;
|
|
23
23
|
stream: "stdout" | "stderr";
|
|
24
24
|
}
|
|
25
|
+
/** 子进程输出分行:过滤空串以及 Windows CRLF 拆分后残留的纯空白行。 */
|
|
26
|
+
export declare function nonBlankOutputLines(text: string): string[];
|
|
25
27
|
export type ServiceName = "bds" | "db" | "qq" | "llbot";
|
|
26
28
|
export declare const SERVICE_NAMES: ServiceName[];
|
|
27
29
|
export declare function setArgvDaemonize(on: boolean): void;
|
package/dist/services.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"services.d.ts","sourceRoot":"","sources":["../src/services.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"services.d.ts","sourceRoot":"","sources":["../src/services.ts"],"names":[],"mappings":"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"}
|
package/dist/services.js
CHANGED
|
@@ -26,6 +26,9 @@ import { ROOT, spawnService } from "./runtime.js";
|
|
|
26
26
|
import { ensurePackUpdateConfigFile } from "./pack-update/index.js";
|
|
27
27
|
import { t } from "./i18n/index.js";
|
|
28
28
|
import { ROOT as ROOT2 } from "./runtime.js";
|
|
29
|
+
function nonBlankOutputLines(text) {
|
|
30
|
+
return text.split(/\r?\n/).filter((line) => line.trim().length > 0);
|
|
31
|
+
}
|
|
29
32
|
const SERVICE_NAMES = ["bds", "db", "qq", "llbot"];
|
|
30
33
|
let argvDaemonize = false;
|
|
31
34
|
function setArgvDaemonize(on) {
|
|
@@ -133,12 +136,12 @@ class Service {
|
|
|
133
136
|
this.cleanup();
|
|
134
137
|
});
|
|
135
138
|
child.stdout?.on("data", (d) => {
|
|
136
|
-
for (const line of d.toString()
|
|
139
|
+
for (const line of nonBlankOutputLines(d.toString())) {
|
|
137
140
|
this.pushLog(line, "stdout");
|
|
138
141
|
}
|
|
139
142
|
});
|
|
140
143
|
child.stderr?.on("data", (d) => {
|
|
141
|
-
for (const line of d.toString()
|
|
144
|
+
for (const line of nonBlankOutputLines(d.toString())) {
|
|
142
145
|
this.pushLog(line, "stderr");
|
|
143
146
|
}
|
|
144
147
|
});
|
|
@@ -485,6 +488,7 @@ export {
|
|
|
485
488
|
forceStopAll,
|
|
486
489
|
getQqBackendMode,
|
|
487
490
|
isServiceRunning,
|
|
491
|
+
nonBlankOutputLines,
|
|
488
492
|
onServiceStateChange,
|
|
489
493
|
queryServicesRuntime,
|
|
490
494
|
refreshServices,
|
package/dist/services.js.map
CHANGED
|
@@ -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 * - `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 ensureCoreConfigs,\n loadEnsuredConfig,\n qqRuntimeStatusPath,\n readJson,\n DEFAULT_BDS_UPDATER_CONFIG,\n DEFAULT_DB_CONFIG,\n DEFAULT_QQ_CONFIG,\n type QqRuntimeStatus,\n} from \"@sfmc-bds/sdk/node/config\";\n\nimport {\n clearBdsPidFile,\n isProcessAlive,\n probeBdsStatus,\n readBdsPidFile,\n writeBdsPidFile,\n} from \"@sfmc-bds/bds-tools/process-probe\";\nimport { bdsExePath, bdsSpawnEnvExtra, ensureBdsExecutable } from \"@sfmc-bds/bds-tools/host-platform\";\nimport { spawn, type ChildProcess, type IOType } from \"node:child_process\";\nimport { EventEmitter } from \"node:events\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { inferLevel, pushLog as pushUnifiedLog } from \"./logs.js\";\nimport { resolveLlbotLaunch } from \"./llbot-launch.js\";\nimport { findNodeServicePids } from \"./node-service-probe.js\";\nimport { ROOT, spawnService, type ServiceId } from \"./runtime.js\";\nimport { ensurePackUpdateConfigFile } from \"./pack-update/index.js\";\nimport { t } from \"./i18n/index.js\";\n\nexport { ROOT } from \"./runtime.js\";\n\nexport interface LogLine {\n time: Date;\n text: string;\n stream: \"stdout\" | \"stderr\";\n}\n\nexport type ServiceName = \"bds\" | \"db\" | \"qq\" | \"llbot\";\nexport const SERVICE_NAMES: ServiceName[] = [\"bds\", \"db\", \"qq\", \"llbot\"];\n\n/** argv \u4E00\u6B21\u6027 start \u5728 POSIX \u4E0A\u987B daemonize\uFF0C\u5426\u5219\u7236\u8FDB\u7A0B\u9000\u51FA\u4F1A\u5E26\u8D70\u5B50\u8FDB\u7A0B\uFF08Windows \u4E0D\u9700\u8981\uFF09 */\nlet argvDaemonize = false;\nexport function setArgvDaemonize(on: boolean): void {\n argvDaemonize = on;\n}\n\n/** \u5355\u670D\u52A1 start \u7ED3\u679C\uFF1Aoptional \u670D\u52A1 validate \u5931\u8D25\u8BB0\u4E3A skipped\uFF0C\u4E0D\u629B\u9519 */\nexport type StartOutcome =\n | { status: \"started\" }\n | { status: \"already\" }\n | { 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\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}\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\n constructor(def: ServiceDef) {\n this.name = def.name;\n this.title = def.title;\n this.def = def;\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 }\n\n async start(): Promise<StartOutcome> {\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\", { pid: String(probe.pid), kind: t(probe.state === \"managed\" ? \"svc.running\" : \"svc.runningExternal\") })\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.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 this.manualStop = false;\n const daemonize = argvDaemonize && process.platform !== \"win32\";\n const spawnOpts = {\n cwd: this.def.cwd,\n stdio: (daemonize ? \"ignore\" : [\"pipe\", \"pipe\", \"pipe\"]) as \"ignore\" | Array<IOType>,\n env: this.def.env ? { ...process.env, ...this.def.env } : process.env,\n detached: daemonize,\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 if (daemonize) child.unref();\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 this.events.emit(\"output\", `started (PID ${this.pid})`, \"info\");\n this.events.emit(\"state\", { name: this.name, running: true, pid: this.pid });\n\n child.on(\"error\", (e) => {\n this.events.emit(\"output\", `process error: ${e.message}`, \"error\");\n this.cleanup();\n });\n\n child.stdout?.on(\"data\", (d: Buffer) => {\n for (const line of d.toString().split(\"\\n\").filter(Boolean)) {\n this.pushLog(line, \"stdout\");\n }\n });\n child.stderr?.on(\"data\", (d: Buffer) => {\n for (const line of d.toString().split(\"\\n\").filter(Boolean)) {\n this.pushLog(line, \"stderr\");\n }\n });\n\n child.on(\"exit\", (code) => {\n this.events.emit(\"output\", `exited (code: ${code})`, \"info\");\n this.cleanup();\n if (!this.manualStop && this.def.autoRestart) {\n setTimeout(() => {\n void this.start();\n }, this.def.restartDelay);\n }\n });\n return { status: \"started\" };\n }\n\n async stop(): Promise<void> {\n if (!this.proc || !this.running) return;\n this.manualStop = true;\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 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 }\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(\n ROOT,\n \"bds_updater.json\",\n \"bds_updater\",\n { ...DEFAULT_BDS_UPDATER_CONFIG } as Record<string, unknown>\n ) as BdsUpdaterConfig;\n const qqCfg = loadEnsuredConfig(\n ROOT,\n \"qq_config.json\",\n \"qq_config\",\n { ...DEFAULT_QQ_CONFIG } as Record<string, unknown>\n ) as QQBridgeConfig;\n const dbCfg = loadEnsuredConfig(\n ROOT,\n \"db_config.json\",\n \"db_config\",\n { ...DEFAULT_DB_CONFIG } as Record<string, unknown>\n ) as DBConfig;\n const bdsPath = bdsCfg.bds_path ?? ROOT;\n const useLlbotBackend = qqCfg.qq_backend === \"llbot\";\n const qqEnabled = qqCfg.qq_enabled !== false;\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(path.resolve(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 autoRestart: bdsCfg.crash_restart !== false,\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 }),\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 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,\n validate: () => {\n if (!qqEnabled) return \"QQ bridge disabled (qq_enabled=false)\";\n if (!useLlbotBackend) {\n if (!String(qqCfg.qq_app_id ?? \"\").trim() || !String(qqCfg.qq_app_secret ?? \"\").trim()) {\n return \"missing qq_app_id / qq_app_secret (official backend)\";\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\", \"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?.running))\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 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 */\nexport async function queryServicesRuntime(): 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 {\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 * - `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 ensureCoreConfigs,\n loadEnsuredConfig,\n qqRuntimeStatusPath,\n readJson,\n DEFAULT_BDS_UPDATER_CONFIG,\n DEFAULT_DB_CONFIG,\n DEFAULT_QQ_CONFIG,\n type QqRuntimeStatus,\n} from \"@sfmc-bds/sdk/node/config\";\n\nimport {\n clearBdsPidFile,\n isProcessAlive,\n probeBdsStatus,\n readBdsPidFile,\n writeBdsPidFile,\n} from \"@sfmc-bds/bds-tools/process-probe\";\nimport { bdsExePath, bdsSpawnEnvExtra, ensureBdsExecutable } from \"@sfmc-bds/bds-tools/host-platform\";\nimport { spawn, type ChildProcess, type IOType } from \"node:child_process\";\nimport { EventEmitter } from \"node:events\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { inferLevel, pushLog as pushUnifiedLog } from \"./logs.js\";\nimport { resolveLlbotLaunch } from \"./llbot-launch.js\";\nimport { findNodeServicePids } from \"./node-service-probe.js\";\nimport { ROOT, spawnService, type ServiceId } from \"./runtime.js\";\nimport { ensurePackUpdateConfigFile } from \"./pack-update/index.js\";\nimport { t } from \"./i18n/index.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\" | \"qq\" | \"llbot\";\nexport const SERVICE_NAMES: ServiceName[] = [\"bds\", \"db\", \"qq\", \"llbot\"];\n\n/** argv \u4E00\u6B21\u6027 start \u5728 POSIX \u4E0A\u987B daemonize\uFF0C\u5426\u5219\u7236\u8FDB\u7A0B\u9000\u51FA\u4F1A\u5E26\u8D70\u5B50\u8FDB\u7A0B\uFF08Windows \u4E0D\u9700\u8981\uFF09 */\nlet argvDaemonize = false;\nexport function setArgvDaemonize(on: boolean): void {\n argvDaemonize = on;\n}\n\n/** \u5355\u670D\u52A1 start \u7ED3\u679C\uFF1Aoptional \u670D\u52A1 validate \u5931\u8D25\u8BB0\u4E3A skipped\uFF0C\u4E0D\u629B\u9519 */\nexport type StartOutcome =\n | { status: \"started\" }\n | { status: \"already\" }\n | { 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\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}\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\n constructor(def: ServiceDef) {\n this.name = def.name;\n this.title = def.title;\n this.def = def;\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 }\n\n async start(): Promise<StartOutcome> {\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\", { pid: String(probe.pid), kind: t(probe.state === \"managed\" ? \"svc.running\" : \"svc.runningExternal\") })\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.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 this.manualStop = false;\n const daemonize = argvDaemonize && process.platform !== \"win32\";\n const spawnOpts = {\n cwd: this.def.cwd,\n stdio: (daemonize ? \"ignore\" : [\"pipe\", \"pipe\", \"pipe\"]) as \"ignore\" | Array<IOType>,\n env: this.def.env ? { ...process.env, ...this.def.env } : process.env,\n detached: daemonize,\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 if (daemonize) child.unref();\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 this.events.emit(\"output\", `started (PID ${this.pid})`, \"info\");\n this.events.emit(\"state\", { name: this.name, running: true, pid: this.pid });\n\n child.on(\"error\", (e) => {\n this.events.emit(\"output\", `process error: ${e.message}`, \"error\");\n this.cleanup();\n });\n\n child.stdout?.on(\"data\", (d: Buffer) => {\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 this.events.emit(\"output\", `exited (code: ${code})`, \"info\");\n this.cleanup();\n if (!this.manualStop && this.def.autoRestart) {\n setTimeout(() => {\n void this.start();\n }, this.def.restartDelay);\n }\n });\n return { status: \"started\" };\n }\n\n async stop(): Promise<void> {\n if (!this.proc || !this.running) return;\n this.manualStop = true;\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 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 }\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(\n ROOT,\n \"bds_updater.json\",\n \"bds_updater\",\n { ...DEFAULT_BDS_UPDATER_CONFIG } as Record<string, unknown>\n ) as BdsUpdaterConfig;\n const qqCfg = loadEnsuredConfig(\n ROOT,\n \"qq_config.json\",\n \"qq_config\",\n { ...DEFAULT_QQ_CONFIG } as Record<string, unknown>\n ) as QQBridgeConfig;\n const dbCfg = loadEnsuredConfig(\n ROOT,\n \"db_config.json\",\n \"db_config\",\n { ...DEFAULT_DB_CONFIG } as Record<string, unknown>\n ) as DBConfig;\n const bdsPath = bdsCfg.bds_path ?? ROOT;\n const useLlbotBackend = qqCfg.qq_backend === \"llbot\";\n const qqEnabled = qqCfg.qq_enabled !== false;\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(path.resolve(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 autoRestart: bdsCfg.crash_restart !== false,\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 }),\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 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,\n validate: () => {\n if (!qqEnabled) return \"QQ bridge disabled (qq_enabled=false)\";\n if (!useLlbotBackend) {\n if (!String(qqCfg.qq_app_id ?? \"\").trim() || !String(qqCfg.qq_app_secret ?? \"\").trim()) {\n return \"missing qq_app_id / qq_app_secret (official backend)\";\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\", \"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?.running))\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 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 */\nexport async function queryServicesRuntime(): 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 {\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
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { describe, it } from "node:test";
|
|
3
|
+
import { shouldDisplayPackSourceLabel } from "./world-packs.js";
|
|
4
|
+
describe("packs list \u66F4\u65B0\u6E90\u5217", () => {
|
|
5
|
+
it("\u9690\u85CF\u672A\u7ED1\u5B9A\u5360\u4F4D\u7B26\uFF0C\u4FDD\u7559\u5DF2\u7ED1\u5B9A\u4E0E\u5DF2\u505C\u7528\u6765\u6E90", () => {
|
|
6
|
+
assert.equal(shouldDisplayPackSourceLabel("src=-"), false);
|
|
7
|
+
assert.equal(shouldDisplayPackSourceLabel("src=CF:farmers-delight"), true);
|
|
8
|
+
assert.equal(shouldDisplayPackSourceLabel("src=CF:farmers-delight:off"), true);
|
|
9
|
+
});
|
|
10
|
+
});
|
|
11
|
+
//# sourceMappingURL=world-packs-list.test.js.map
|