mioku 1.0.2 → 1.0.4

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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["query: string","hits: NpmPackageHit[]","prefix: string","packageName: string","version","meta: NpmPackageMeta | null","pluginNames: readonly string[]","message: string","items: Array<{ label: string; value: string }>","initial: string[]","name: string","cwd: string","pkgName: string","cmd: string","args: string[]","options: { cwd?: string }","args","dir: string","err: any","packages: string[]","cwd?: string","p: string","fileTree: Record<string, string | Record<string, unknown>>","base: string","version: string","options?: OmitTypeWithRequired<{ initial?: boolean }>","options?: OmitTypeWithRequired<{ default?: string; placeholder?: string }>","cmdArgs: string[]","helpInfo: string","pkgName: string","packages: string[]","cwd: string","prefix: string","name?: string","cmdArgs: string[]","name: string","fileTree: Record<string, string | Record<string, unknown>>","message: string","prefix: string","initial: string[]","options: { exclude?: string[] }","version: string","version","args"],"sources":["../../src/cli/shared.ts","../../src/cli/install.ts","../../src/cli/update.ts","../../src/cli/scaffold.ts","../../src/cli/index.ts"],"sourcesContent":["import fs, { readFileSync } from \"node:fs\";\nimport path from \"node:path\";\nimport consola from \"consola\";\nimport dedent from \"dedent\";\nimport {\n clearCommandCache,\n commandExists,\n resolveCommand,\n runCommandInherit,\n} from \"../internal/exec\";\n\nexport const PLUGIN_PREFIX = \"mioku-plugin-\";\nexport const SERVICE_PREFIX = \"mioku-service-\";\nexport const ADAPTER_PREFIX = \"mioku-adapter-\";\n\nexport const NPM_REGISTRY = \"https://registry.npmjs.org\";\nexport const OFFICIAL_REGISTRY_URL =\n \"https://raw.githubusercontent.com/mioku-lab/mioku/main/official-registry.json\";\n\nexport interface NpmPackageHit {\n name: string;\n description: string;\n version: string;\n keywords: string[];\n}\n\nasync function searchNpm(query: string, size = 250): Promise<NpmPackageHit[]> {\n try {\n const url = `${NPM_REGISTRY}/-/v1/search?text=${encodeURIComponent(query)}&size=${size}`;\n const res = await fetch(url, {\n headers: { Accept: \"application/json\", \"User-Agent\": \"mioku-cli\" },\n });\n if (!res.ok) return [];\n const data = (await res.json()) as {\n objects?: Array<{\n package?: {\n name?: string;\n description?: string;\n version?: string;\n keywords?: string[];\n };\n }>;\n };\n const hits: NpmPackageHit[] = [];\n for (const obj of data.objects ?? []) {\n const pkg = obj.package ?? {};\n const name = String(pkg.name ?? \"\").trim();\n if (!name) continue;\n hits.push({\n name,\n description: String(pkg.description ?? \"\").trim(),\n version: String(pkg.version ?? \"\").trim(),\n keywords: Array.isArray(pkg.keywords) ? pkg.keywords.map(String) : [],\n });\n }\n return hits;\n } catch {\n return [];\n }\n}\n\nexport async function searchMiokuPackages(\n prefix: string,\n): Promise<NpmPackageHit[]> {\n const [broad, targeted] = await Promise.all([\n searchNpm(\"mioku\"),\n searchNpm(prefix.replace(/-$/, \"\")),\n ]);\n const seen = new Set<string>();\n const hits: NpmPackageHit[] = [];\n for (const hit of [...broad, ...targeted]) {\n if (!hit.name.startsWith(prefix)) continue;\n if (!hit.keywords.includes(\"mioku\")) continue;\n if (seen.has(hit.name)) continue;\n seen.add(hit.name);\n hits.push(hit);\n }\n return hits.sort((a, b) => a.name.localeCompare(b.name));\n}\n\nexport interface OfficialRegistryEntry {\n npm?: string;\n builtin?: boolean;\n}\n\nexport interface OfficialRegistry {\n plugins?: Record<string, OfficialRegistryEntry>;\n services?: Record<string, OfficialRegistryEntry>;\n adapters?: Record<string, OfficialRegistryEntry>;\n}\n\nexport async function fetchOfficialRegistry(): Promise<OfficialRegistry | null> {\n try {\n const res = await fetch(OFFICIAL_REGISTRY_URL, {\n headers: { Accept: \"application/json\", \"User-Agent\": \"mioku-cli\" },\n });\n if (!res.ok) return null;\n return (await res.json()) as OfficialRegistry;\n } catch {\n return null;\n }\n}\n\nexport interface NpmPackageMeta {\n version: string;\n description: string;\n keywords: string[];\n mioku?: unknown;\n}\n\nexport async function fetchNpmPackageMeta(\n packageName: string,\n): Promise<NpmPackageMeta | null> {\n try {\n const res = await fetch(\n `${NPM_REGISTRY}/${encodeURIComponent(packageName)}`,\n {\n headers: { Accept: \"application/json\", \"User-Agent\": \"mioku-cli\" },\n },\n );\n if (!res.ok) return null;\n const data = (await res.json()) as any;\n const latest = String(data?.[\"dist-tags\"]?.latest || \"\").trim();\n const version = latest ? (data?.versions?.[latest] ?? {}) : {};\n return {\n version: latest,\n description: String(version?.description || \"\").trim(),\n keywords: Array.isArray(version?.keywords)\n ? version.keywords.map(String)\n : [],\n mioku: version?.mioku,\n };\n } catch {\n return null;\n }\n}\n\nexport function declaredServicesOf(meta: NpmPackageMeta | null): string[] {\n const mioku = meta?.mioku;\n if (Array.isArray(mioku)) {\n return mioku.filter(\n (s): s is string => typeof s === \"string\" && s.length > 0,\n );\n }\n if (mioku && typeof mioku === \"object\") {\n const services = (mioku as { services?: unknown }).services;\n if (Array.isArray(services)) {\n return services.filter(\n (s): s is string => typeof s === \"string\" && s.length > 0,\n );\n }\n }\n return [];\n}\n\nexport async function resolveRequiredServices(\n pluginNames: readonly string[],\n): Promise<string[]> {\n const registry = await fetchOfficialRegistry();\n const serviceMap = new Map<string, string>();\n if (registry) {\n for (const [short, entry] of Object.entries(registry.services ?? {})) {\n if (entry?.npm) serviceMap.set(short, entry.npm);\n }\n }\n\n const required = new Set<string>();\n for (const pluginName of pluginNames) {\n const meta = await fetchNpmPackageMeta(pluginName);\n for (const short of declaredServicesOf(meta)) {\n const npm = serviceMap.get(short) ?? `${SERVICE_PREFIX}${short}`;\n if (serviceMap.has(short)) {\n required.add(npm);\n continue;\n }\n const check = await fetchNpmPackageMeta(npm);\n if (check && check.keywords.includes(\"mioku\")) {\n required.add(npm);\n } else {\n consola.warn(\n `${pluginName} 声明了服务 \"${short}\",但未找到对应的 mioku 服务包,已跳过`,\n );\n }\n }\n }\n return Array.from(required);\n}\n\nexport async function multiSelect(\n message: string,\n items: Array<{ label: string; value: string }>,\n initial: string[] = [],\n): Promise<string[]> {\n if (items.length === 0) return [];\n const result = await consola.prompt(message, {\n type: \"multiselect\",\n options: items,\n initial,\n cancel: \"reject\",\n });\n return (result as Array<string | { value: string }>).map((item) =>\n typeof item === \"string\" ? item : item.value,\n );\n}\n\nexport function runAdapterCli(name: string, cwd: string): void {\n const isWin = process.platform === \"win32\";\n const exts = isWin ? [\"\", \".cmd\", \".ps1\", \".bat\"] : [\"\"];\n for (const ext of exts) {\n const binPath = path.join(\n cwd,\n \"node_modules\",\n \".bin\",\n `mioku-adapter-${name}${ext}`,\n );\n if (fs.existsSync(binPath)) {\n run(binPath, [], { cwd });\n return;\n }\n }\n run(\"bunx\", [`mioku-adapter-${name}`], { cwd });\n}\n\nexport function shortNameOfPackage(pkgName: string): string {\n for (const prefix of [PLUGIN_PREFIX, SERVICE_PREFIX, ADAPTER_PREFIX]) {\n if (pkgName.startsWith(prefix)) return pkgName.slice(prefix.length);\n }\n return pkgName;\n}\n\nexport function run(\n cmd: string,\n args: string[] = [],\n options: { cwd?: string } = {},\n): void {\n runCommandInherit(cmd, args, options);\n}\n\nexport async function rmrf(dir: string, retries = 5): Promise<void> {\n for (let i = 0; i < retries; i++) {\n try {\n fs.rmSync(dir, { recursive: true, force: true });\n return;\n } catch (err: any) {\n if (i === retries - 1) throw err;\n const code = err?.code;\n if (\n code === \"EPERM\" ||\n code === \"EBUSY\" ||\n code === \"ENOTEMPTY\" ||\n code === \"ENOENT\"\n ) {\n await new Promise((resolve) => setTimeout(resolve, 300 * (i + 1)));\n } else {\n throw err;\n }\n }\n }\n}\n\nexport function hasCommand(cmd: string): boolean {\n return commandExists(cmd);\n}\n\nfunction findNpmPath(): string | null {\n const resolved = resolveCommand(\"npm\");\n if (resolved) return resolved;\n if (process.platform !== \"win32\") return null;\n\n const fallbacks = [\n path.join(process.env.ProgramFiles || \"\", \"nodejs\", \"npm.cmd\"),\n path.join(process.env[\"ProgramFiles(x86)\"] || \"\", \"nodejs\", \"npm.cmd\"),\n path.join(process.env.APPDATA || \"\", \"npm\", \"npm.cmd\"),\n ];\n\n return fallbacks.find((candidate) => resolveCommand(candidate)) ?? null;\n}\n\nfunction installBunViaOfficialScript(): void {\n console.log(\"安装 bun...\");\n if (process.platform === \"win32\") {\n const ps =\n process.env.SystemRoot &&\n path.join(\n process.env.SystemRoot,\n \"System32\",\n \"WindowsPowerShell\",\n \"v1.0\",\n \"powershell.exe\",\n );\n const psExe = ps && resolveCommand(ps) ? ps : \"powershell\";\n run(psExe, [\n \"-NoProfile\",\n \"-NonInteractive\",\n \"-ExecutionPolicy\",\n \"Bypass\",\n \"-Command\",\n \"irm bun.sh/install.ps1 | iex\",\n ]);\n } else {\n run(\"bash\", [\"-c\", \"curl -fsSL https://bun.sh/install | bash\"]);\n }\n clearCommandCache();\n}\n\nexport function ensurePackageManager(): void {\n if (hasCommand(\"bun\")) return;\n try {\n installBunViaOfficialScript();\n } catch (err) {\n const npmPath = findNpmPath();\n if (!npmPath) {\n consola.error(\"未找到 npm,请确保 Node.js 已安装并包含 npm\");\n consola.error(\n '自动安装 bun 失败,请手动执行:\\n macOS / Linux: curl -fsSL https://bun.sh/install | bash\\n Windows: powershell -c \"irm bun.sh/install.ps1 | iex\"',\n );\n throw err;\n }\n consola.warn(\"官方安装脚本失败,回退到 npm 全局安装 bun ...\");\n run(npmPath, [\"install\", \"-g\", \"bun\"]);\n clearCommandCache();\n }\n if (!hasCommand(\"bun\")) {\n consola.error(\n \"bun 安装后仍无法在 PATH 中找到,请重启终端或将 bun 的安装目录加入 PATH 后重试\",\n );\n process.exit(1);\n }\n}\n\nexport function getAddCommand(packages: string[]): [string, string[]] {\n return [\"bun\", [\"add\", ...packages]];\n}\n\nexport function normalizePackageName(input: string): string {\n if (input.startsWith(PLUGIN_PREFIX) || input.startsWith(SERVICE_PREFIX)) {\n return input;\n }\n if (input.startsWith(\"mioku-\")) return input;\n return `${PLUGIN_PREFIX}${input}`;\n}\n\nexport function detectType(name: string): \"plugin\" | \"service\" | \"unknown\" {\n if (name.startsWith(PLUGIN_PREFIX)) return \"plugin\";\n if (name.startsWith(SERVICE_PREFIX)) return \"service\";\n return \"unknown\";\n}\n\nexport function execAdd(packages: string[], cwd?: string): void {\n const [cmd, args] = getAddCommand(packages);\n console.log(`执行: ${cmd} ${args.join(\" \")}`);\n run(cmd, args, { cwd });\n}\n\nexport function appendToMiokuPlugins(cwd: string, pkgName: string): boolean {\n if (!pkgName.startsWith(PLUGIN_PREFIX)) return false;\n const shortName = pkgName.slice(PLUGIN_PREFIX.length);\n\n const packageJsonPath = path.join(cwd, \"package.json\");\n if (!fs.existsSync(packageJsonPath)) return false;\n\n const pkg = JSON.parse(readFileSync(packageJsonPath, \"utf-8\"));\n const mioku = pkg.mioku ?? {};\n const plugins = Array.isArray(mioku.plugins) ? [...mioku.plugins] : [];\n if (plugins.includes(shortName)) return false;\n\n plugins.push(shortName);\n pkg.mioku = { ...mioku, plugins };\n fs.writeFileSync(packageJsonPath, `${JSON.stringify(pkg, null, 2)}\\n`);\n return true;\n}\n\nexport async function getInstalledPackages(cwd: string): Promise<string[]> {\n try {\n const pkg = JSON.parse(\n readFileSync(path.join(cwd, \"package.json\"), \"utf-8\"),\n );\n const deps = { ...pkg.dependencies, ...pkg.devDependencies };\n return Object.keys(deps).filter((k) => k.startsWith(\"mioku-\"));\n } catch {\n return [];\n }\n}\n\nexport function withRoot(p: string): string {\n return path.resolve(process.cwd(), p);\n}\n\nexport async function fetchNpmKeywords(\n packageName: string,\n): Promise<string[] | null> {\n try {\n const res = await fetch(\n `${NPM_REGISTRY}/${encodeURIComponent(packageName)}`,\n {\n headers: { Accept: \"application/json\", \"User-Agent\": \"mioku-cli\" },\n },\n );\n if (!res.ok) return null;\n const data = (await res.json()) as any;\n const latestVersion = String(data?.[\"dist-tags\"]?.latest || \"\").trim();\n const keywords = latestVersion\n ? data?.versions?.[latestVersion]?.keywords\n : data?.keywords;\n return Array.isArray(keywords) ? keywords.map(String) : [];\n } catch {\n return null;\n }\n}\n\nexport function gracefullyExit(): void {\n console.log(\"Bye!\");\n process.exit(0);\n}\n\nexport function makeFileTree(\n fileTree: Record<string, string | Record<string, unknown>>,\n base: string,\n): void {\n for (const [name, content] of Object.entries(fileTree)) {\n if (typeof content === \"object\" && content !== null) {\n const subPath = path.join(base, name);\n if (!fs.existsSync(subPath)) fs.mkdirSync(subPath, { recursive: true });\n for (const [subName, subContent] of Object.entries(content)) {\n if (typeof subContent === \"object\") {\n makeFileTree(\n subContent as Record<string, string | Record<string, unknown>>,\n path.join(subPath, subName),\n );\n } else {\n fs.writeFileSync(path.join(subPath, subName), subContent as string);\n }\n }\n } else {\n const filePath = path.join(base, name);\n const dirname = path.dirname(filePath);\n if (!fs.existsSync(dirname)) fs.mkdirSync(dirname, { recursive: true });\n fs.writeFileSync(filePath, content as string);\n }\n }\n}\n\nexport function buildHelpInfo(version: string): string {\n return dedent(`\n mioku 命令行工具 v${version}\n\n 用法: mioku <命令> [选项]\n\n 命令:\n install plugin <名称> 安装插件,自动补全 mioku-plugin- 前缀\n install service <名称> 安装服务,自动补全 mioku-service- 前缀\n update [包名|self|all] 更新插件或服务\n update - 检查可用更新\n update all - 更新所有 mioku- 包\n update self - 更新 mioku 框架\n update xxx - 更新指定包\n\n 选项:\n -h, --help 显示帮助信息\n -v, --version 显示版本号\n --name <name> 指定项目/文件夹名称,默认 mioku-bot\n --protocol <protocol> 指定 NapCat 协议,默认 ws\n --host <host> 指定 NapCat 主机,默认 localhost\n --port <port> 指定 NapCat 端口,默认 3001\n --token <token> 指定 NapCat 连接 Token,默认空\n --prefix <prefix> 指定命令前缀,默认 #\n --owners <owners> 指定主人 QQ,英文逗号分隔,必填\n --admins <admins> 指定管理员 QQ,英文逗号分隔,可空\n --use-npm-mirror 使用 npm 镜像源加速依赖安装,默认否\n `);\n}\n\ntype OmitTypeWithRequired<T> = Omit<T, \"type\" | \"required\"> & {\n required?: boolean;\n};\n\nexport async function confirm(\n message: string,\n options?: OmitTypeWithRequired<{ initial?: boolean }>,\n): Promise<boolean> {\n return consola.prompt(message, {\n type: \"confirm\",\n cancel: \"reject\",\n ...options,\n });\n}\n\nexport async function input(\n message: string,\n options?: OmitTypeWithRequired<{ default?: string; placeholder?: string }>,\n): Promise<string> {\n const result = await consola.prompt(message, {\n type: \"text\",\n cancel: \"reject\",\n ...options,\n });\n if (options?.required && !result) return input(message, options);\n return result;\n}\n","import consola from \"consola\";\nimport {\n ensurePackageManager,\n appendToMiokuPlugins,\n execAdd,\n fetchNpmKeywords,\n PLUGIN_PREFIX,\n SERVICE_PREFIX,\n confirm,\n} from \"./shared\";\n\nexport async function installCommand(\n cmdArgs: string[],\n helpInfo: string,\n): Promise<number> {\n ensurePackageManager();\n const cwd = process.cwd();\n const [type, name] = cmdArgs;\n\n if (!type || !name) {\n consola.error(\n \"请指定类型和名称: mioku install plugin <名称> 或 mioku install service <名称>\",\n );\n console.log(helpInfo);\n return 1;\n }\n\n if (type !== \"plugin\" && type !== \"service\") {\n consola.error(`无效的类型 \"${type}\",请使用 plugin 或 service`);\n console.log(helpInfo);\n return 1;\n }\n\n const prefix = type === \"plugin\" ? PLUGIN_PREFIX : SERVICE_PREFIX;\n const normalized = `${prefix}${name}`;\n\n if (type === \"plugin\") {\n const proceed = await warnIfPrivatePlugin(normalized);\n if (!proceed) {\n consola.info(\"已取消安装\");\n return 1;\n }\n }\n\n try {\n execAdd([normalized], cwd);\n consola.success(`已安装 ${normalized}`);\n\n if (type === \"plugin\") {\n const shortName = normalized.slice(PLUGIN_PREFIX.length);\n if (appendToMiokuPlugins(cwd, normalized)) {\n consola.success(`已在 mioku.plugins 中启用 ${shortName}`);\n } else {\n consola.info(`${shortName} 已在 mioku.plugins 中,跳过`);\n }\n }\n return 0;\n } catch {\n consola.error(`安装失败: ${normalized}`);\n return 1;\n }\n}\n\nasync function warnIfPrivatePlugin(pkgName: string): Promise<boolean> {\n const keywords = await fetchNpmKeywords(pkgName);\n if (keywords === null) return true;\n if (keywords.includes(\"mioku\")) return true;\n\n consola.warn(`${pkgName} 看起来是私有插件\"`);\n consola.warn(\"该插件未上架插件市场,可能存在风险\");\n return confirm(\"仍要继续安装吗?\", { initial: false });\n}\n","import consola from \"consola\";\nimport {\n run,\n ensurePackageManager,\n getInstalledPackages,\n PLUGIN_PREFIX,\n SERVICE_PREFIX,\n} from \"./shared\";\n\nasync function updatePackages(packages: string[], cwd: string): Promise<void> {\n if (packages.length === 0) {\n consola.info(\"未找到 mioku- 相关依赖\");\n return;\n }\n console.log(`执行: bun update ${packages.join(\" \")} --latest`);\n run(\"bun\", [\"update\", ...packages, \"--latest\"], { cwd });\n}\n\nasync function updateByPrefix(\n prefix: string,\n cwd: string,\n name?: string,\n): Promise<void> {\n if (name) {\n const normalized = name.startsWith(prefix) ? name : `${prefix}${name}`;\n console.log(`执行: bun update ${normalized} --latest`);\n run(\"bun\", [\"update\", normalized, \"--latest\"], { cwd });\n return;\n }\n const packages = (await getInstalledPackages(cwd)).filter((p) =>\n p.startsWith(prefix),\n );\n if (packages.length === 0) {\n consola.info(`未找到 ${prefix}* 相关依赖`);\n return;\n }\n await updatePackages(packages, cwd);\n}\n\nexport async function updateCommand(cmdArgs: string[]): Promise<number> {\n ensurePackageManager();\n const cwd = process.cwd();\n const [target, name] = cmdArgs;\n\n if (!target || target === \"check\") {\n run(\"bun\", [\"update\", \"-i\"], { cwd });\n return 0;\n }\n\n if (target === \"all\") {\n await updatePackages(await getInstalledPackages(cwd), cwd);\n return 0;\n }\n\n if (target === \"self\") {\n console.log(\"执行: bun update mioku --latest\");\n run(\"bun\", [\"update\", \"mioku\", \"--latest\"], { cwd });\n return 0;\n }\n\n if (target === \"plugin\" || target === \"service\") {\n const prefix = target === \"plugin\" ? PLUGIN_PREFIX : SERVICE_PREFIX;\n await updateByPrefix(prefix, cwd, name);\n return 0;\n }\n\n console.log(`执行: bun update ${target} --latest`);\n run(\"bun\", [\"update\", target, \"--latest\"], { cwd });\n return 0;\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport dedent from \"dedent\";\nimport consola from \"consola\";\nimport {\n ADAPTER_PREFIX,\n PLUGIN_PREFIX,\n ensurePackageManager,\n getAddCommand,\n multiSelect,\n run,\n runAdapterCli,\n searchMiokuPackages,\n shortNameOfPackage,\n resolveRequiredServices,\n rmrf,\n withRoot,\n gracefullyExit,\n makeFileTree,\n input,\n confirm,\n} from \"./shared\";\n\n/** stdin 会话对应的主人标识,默认追加到 mioku.owners */\nexport const STDIN_OWNER = \"stdin\";\n\n/** 系统自带适配器:必装且不可取消,默认启用 */\nexport const SYSTEM_ADAPTERS = [\"mioku-adapter-stdin\"];\n\n/** 系统自带插件:必装且不可取消 */\nexport const SYSTEM_PLUGINS = [\"mioku-plugin-help\", \"mioku-plugin-chat\"];\n\n/** 系统服务:框架运行所必需,无条件安装 */\nexport const SYSTEM_SERVICES = [\n \"mioku-service-ai\",\n \"mioku-service-config\",\n \"mioku-service-screenshot\",\n \"mioku-service-help\",\n];\n\nasync function createNewProject(\n name: string,\n fileTree: Record<string, string | Record<string, unknown>>,\n): Promise<string> {\n const projectPath = withRoot(`./${name}`);\n\n if (fs.existsSync(projectPath)) {\n const overwrite = await confirm(`项目 ${name} 已存在,是否覆盖?`);\n if (!overwrite) gracefullyExit();\n\n if (projectPath === process.cwd()) {\n if (fs.readdirSync(projectPath).length !== 0) {\n const confirmOver = await confirm(\n \"项目路径与当前路径相同,将删除当前目录下所有内容再创建,是否继续?\",\n );\n if (!confirmOver) gracefullyExit();\n }\n }\n await rmrf(projectPath);\n }\n\n fs.mkdirSync(projectPath, { recursive: true });\n makeFileTree(fileTree, projectPath);\n console.log(`项目 ${name} 创建成功!`);\n\n console.log(\"正在安装基础依赖 (bun i) ...\");\n run(\"bun\", [\"i\"], { cwd: projectPath });\n return projectPath;\n}\n\nasync function selectPackages(\n message: string,\n prefix: string,\n initial: string[] = [],\n options: { exclude?: string[] } = {},\n): Promise<string[]> {\n console.log(`\\n正在从 npm 拉取 ${prefix}* 包...`);\n const hits = await searchMiokuPackages(prefix);\n if (hits.length === 0) {\n consola.warn(`未在 npm 上找到任何 ${prefix}* 包`);\n return [];\n }\n const excludeSet = new Set(options.exclude ?? []);\n const items = hits\n .filter((hit) => !excludeSet.has(hit.name))\n .map((hit) => ({\n label: `${hit.name} (${hit.description || \"暂无介绍\"})`,\n value: hit.name,\n }));\n return multiSelect(message, items, initial);\n}\n\nexport async function scaffoldCommand(version: string): Promise<number> {\n const name = await input(\"请输入项目名称\", {\n default: \"mioku-bot\",\n placeholder: \"mioku-bot\",\n required: true,\n });\n const owners = await input(\"请输入主人 QQ (最高权限,英文逗号分隔,必填)\", {\n placeholder: \"请输入\",\n default: \"\",\n required: true,\n });\n\n ensurePackageManager();\n\n // stdin 会话默认拥有主人权限:自动追加到 owners\n const ownersList = [\n ...String(owners)\n .split(\",\")\n .map((o) => o.trim())\n .filter(Boolean),\n STDIN_OWNER,\n ];\n\n const adapterNames = await selectPackages(\n \"选择要安装的适配器(上下键选择,空格勾选,回车确认,系统适配器 stdin 将自动安装)\",\n ADAPTER_PREFIX,\n [],\n { exclude: SYSTEM_ADAPTERS },\n );\n const allAdapterNames = [...SYSTEM_ADAPTERS, ...adapterNames];\n if (adapterNames.length === 0) {\n consola.warn(\"未选择其他适配器,将仅启用系统适配器 stdin(终端输入)\");\n }\n\n const pkgJsonObj = {\n name,\n private: true,\n type: \"module\" as const,\n dependencies: {\n mioku: \"latest\",\n ...Object.fromEntries(allAdapterNames.map((p) => [p, \"latest\"])),\n },\n mioku: {\n prefix: \".\",\n owners: ownersList,\n admins: [] as string[],\n plugins: [\"demo\"],\n log_level: \"info\",\n online_push: false,\n error_push: false,\n adapters: {\n stdin: {},\n },\n },\n scripts: {\n start: \"bun run app.ts\",\n dev: \"bun run --watch app.ts\",\n },\n };\n const pkgJson = `${JSON.stringify(pkgJsonObj, null, 2)}\\n`;\n\n const pluginCode = dedent(`\n import { definePlugin } from 'mioku'\n\n export default definePlugin({\n name: 'demo',\n version: '${version}',\n async setup(ctx) {\n ctx.logger.info('Demo 插件已加载')\n\n ctx.handle('message', async (e) => {\n if (e.raw_message === 'hello') {\n e.reply('world', true)\n }\n })\n\n return () => {\n ctx.logger.info('Demo 插件已卸载')\n }\n },\n })\n `);\n\n const fileTree: Record<string, string | Record<string, unknown>> = {\n \"app.ts\":\n \"import { start } from 'mioku'\\n\\nstart({ cwd: import.meta.dirname }).then()\\n\",\n \"package.json\": pkgJson,\n plugins: { demo: { \"index.ts\": pluginCode } },\n config: {},\n data: {},\n };\n\n const projectPath = await createNewProject(name, fileTree);\n\n // 仅为用户额外选择的适配器运行配置向导(系统适配器 stdin 免配置)\n for (const adapterPkg of adapterNames) {\n const adapterName = shortNameOfPackage(adapterPkg);\n consola.info(`正在运行 ${adapterPkg} 配置向导...`);\n runAdapterCli(adapterName, projectPath);\n }\n consola.info(\n `已自动安装并启用系统适配器: ${SYSTEM_ADAPTERS.map(shortNameOfPackage).join(\", \")}`,\n );\n\n // 系统插件必装且不可取消:从选择列表中剔除,自动启用\n const pluginNames = await selectPackages(\n \"选择要安装的插件(上下键选择,空格勾选,回车确认)\",\n PLUGIN_PREFIX,\n [],\n { exclude: SYSTEM_PLUGINS },\n );\n consola.info(\n `系统插件将自动安装: ${SYSTEM_PLUGINS.map(shortNameOfPackage).join(\", \")}`,\n );\n\n const enabledPlugins = [\n \"demo\",\n ...SYSTEM_PLUGINS.map(shortNameOfPackage),\n ...pluginNames.map(shortNameOfPackage),\n ];\n const pkgPath = path.join(projectPath, \"package.json\");\n const pkg = JSON.parse(fs.readFileSync(pkgPath, \"utf-8\"));\n pkg.mioku = { ...pkg.mioku, plugins: enabledPlugins };\n fs.writeFileSync(pkgPath, `${JSON.stringify(pkg, null, 2)}\\n`);\n\n const serviceNames = new Set<string>(SYSTEM_SERVICES);\n for (const service of await resolveRequiredServices(pluginNames)) {\n serviceNames.add(service);\n }\n consola.info(\n `将自动安装服务: ${Array.from(serviceNames).map(shortNameOfPackage).join(\", \")}`,\n );\n\n const installWebui = await confirm(\"是否安装 WebUI 管理面板?(建议安装)\", {\n initial: true,\n });\n\n const addPackages = [...pluginNames, ...Array.from(serviceNames)];\n if (installWebui) addPackages.push(\"mioku-service-webui\");\n\n if (addPackages.length > 0) {\n const [cmd, args] = getAddCommand(addPackages);\n console.log(`正在安装插件与服务: ${cmd} ${args.join(\" \")}`);\n run(cmd, args, { cwd: projectPath });\n }\n\n console.log(\"\\n若需启动机器人,请运行:\");\n console.log(\" cd\", name);\n console.log(\" bun run start\");\n return 0;\n}\n","#!/usr/bin/env node\n\nimport mri from \"mri\";\nimport { version } from \"../../package.json\";\nimport { buildHelpInfo } from \"./shared\";\nimport { installCommand } from \"./install\";\nimport { updateCommand } from \"./update\";\nimport { scaffoldCommand } from \"./scaffold\";\n\ninterface CliOptions {\n help?: boolean;\n version?: boolean;\n}\n\nconst args = process.argv.slice(2);\n\n(async () => {\n const cli = mri<CliOptions>(args, { alias: { v: \"version\", h: \"help\" } });\n const helpInfo = buildHelpInfo(version);\n const [cmd, ...cmdArgs] = args;\n\n switch (cmd) {\n case \"install\":\n process.exitCode = await installCommand(cmdArgs, helpInfo);\n return;\n case \"update\":\n process.exitCode = await updateCommand(cmdArgs);\n return;\n default:\n if (cli.version) {\n console.log(`v${version}`);\n return;\n }\n if (cli.help) {\n console.log(helpInfo);\n return;\n }\n process.exitCode = await scaffoldCommand(version);\n return;\n }\n})();\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["query: string","hits: NpmPackageHit[]","prefix: string","packageName: string","version","meta: NpmPackageMeta | null","pluginNames: readonly string[]","message: string","items: Array<{ label: string; value: string }>","initial: string[]","options: { required?: boolean }","name: string","cwd: string","pkgName: string","cmd: string","args: string[]","options: { cwd?: string }","args","dir: string","err: any","packages: string[]","cwd?: string","p: string","fileTree: Record<string, string | Record<string, unknown>>","base: string","version: string","options?: OmitTypeWithRequired<{ initial?: boolean }>","options?: OmitTypeWithRequired<{ default?: string; placeholder?: string }>","cmdArgs: string[]","helpInfo: string","pkgName: string","packages: string[]","cwd: string","prefix: string","name?: string","cmdArgs: string[]","name: string","fileTree: Record<string, string | Record<string, unknown>>","message: string","prefix: string","initial: string[]","options: { exclude?: string[]; typeLabel?: string }","version: string","version","args"],"sources":["../../src/cli/shared.ts","../../src/cli/install.ts","../../src/cli/update.ts","../../src/cli/scaffold.ts","../../src/cli/index.ts"],"sourcesContent":["import fs, { readFileSync } from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport consola from \"consola\";\nimport dedent from \"dedent\";\nimport {\n clearCommandCache,\n commandExists,\n resolveCommand,\n runCommandInherit,\n} from \"../internal/exec\";\n\nexport const PLUGIN_PREFIX = \"mioku-plugin-\";\nexport const SERVICE_PREFIX = \"mioku-service-\";\nexport const ADAPTER_PREFIX = \"mioku-adapter-\";\n\nexport const NPM_REGISTRY = \"https://registry.npmjs.org\";\nexport const OFFICIAL_REGISTRY_URL =\n \"https://raw.githubusercontent.com/mioku-lab/mioku/main/official-registry.json\";\n\nexport interface NpmPackageHit {\n name: string;\n description: string;\n version: string;\n keywords: string[];\n}\n\nasync function searchNpm(query: string, size = 250): Promise<NpmPackageHit[]> {\n try {\n const url = `${NPM_REGISTRY}/-/v1/search?text=${encodeURIComponent(query)}&size=${size}`;\n const res = await fetch(url, {\n headers: { Accept: \"application/json\", \"User-Agent\": \"mioku-cli\" },\n });\n if (!res.ok) return [];\n const data = (await res.json()) as {\n objects?: Array<{\n package?: {\n name?: string;\n description?: string;\n version?: string;\n keywords?: string[];\n };\n }>;\n };\n const hits: NpmPackageHit[] = [];\n for (const obj of data.objects ?? []) {\n const pkg = obj.package ?? {};\n const name = String(pkg.name ?? \"\").trim();\n if (!name) continue;\n hits.push({\n name,\n description: String(pkg.description ?? \"\").trim(),\n version: String(pkg.version ?? \"\").trim(),\n keywords: Array.isArray(pkg.keywords) ? pkg.keywords.map(String) : [],\n });\n }\n return hits;\n } catch {\n return [];\n }\n}\n\nexport async function searchMiokuPackages(\n prefix: string,\n): Promise<NpmPackageHit[]> {\n const [broad, targeted] = await Promise.all([\n searchNpm(\"mioku\"),\n searchNpm(prefix.replace(/-$/, \"\")),\n ]);\n const seen = new Set<string>();\n const hits: NpmPackageHit[] = [];\n for (const hit of [...broad, ...targeted]) {\n if (!hit.name.startsWith(prefix)) continue;\n if (!hit.keywords.includes(\"mioku\")) continue;\n if (seen.has(hit.name)) continue;\n seen.add(hit.name);\n hits.push(hit);\n }\n return hits.sort((a, b) => a.name.localeCompare(b.name));\n}\n\nexport interface OfficialRegistryEntry {\n npm?: string;\n builtin?: boolean;\n}\n\nexport interface OfficialRegistry {\n plugins?: Record<string, OfficialRegistryEntry>;\n services?: Record<string, OfficialRegistryEntry>;\n adapters?: Record<string, OfficialRegistryEntry>;\n}\n\nexport async function fetchOfficialRegistry(): Promise<OfficialRegistry | null> {\n try {\n const res = await fetch(OFFICIAL_REGISTRY_URL, {\n headers: { Accept: \"application/json\", \"User-Agent\": \"mioku-cli\" },\n });\n if (!res.ok) return null;\n return (await res.json()) as OfficialRegistry;\n } catch {\n return null;\n }\n}\n\nexport interface NpmPackageMeta {\n version: string;\n description: string;\n keywords: string[];\n mioku?: unknown;\n}\n\nexport async function fetchNpmPackageMeta(\n packageName: string,\n): Promise<NpmPackageMeta | null> {\n try {\n const res = await fetch(\n `${NPM_REGISTRY}/${encodeURIComponent(packageName)}`,\n {\n headers: { Accept: \"application/json\", \"User-Agent\": \"mioku-cli\" },\n },\n );\n if (!res.ok) return null;\n const data = (await res.json()) as any;\n const latest = String(data?.[\"dist-tags\"]?.latest || \"\").trim();\n const version = latest ? (data?.versions?.[latest] ?? {}) : {};\n return {\n version: latest,\n description: String(version?.description || \"\").trim(),\n keywords: Array.isArray(version?.keywords)\n ? version.keywords.map(String)\n : [],\n mioku: version?.mioku,\n };\n } catch {\n return null;\n }\n}\n\nexport function declaredServicesOf(meta: NpmPackageMeta | null): string[] {\n const mioku = meta?.mioku;\n if (Array.isArray(mioku)) {\n return mioku.filter(\n (s): s is string => typeof s === \"string\" && s.length > 0,\n );\n }\n if (mioku && typeof mioku === \"object\") {\n const services = (mioku as { services?: unknown }).services;\n if (Array.isArray(services)) {\n return services.filter(\n (s): s is string => typeof s === \"string\" && s.length > 0,\n );\n }\n }\n return [];\n}\n\nexport async function resolveRequiredServices(\n pluginNames: readonly string[],\n): Promise<string[]> {\n const registry = await fetchOfficialRegistry();\n const serviceMap = new Map<string, string>();\n if (registry) {\n for (const [short, entry] of Object.entries(registry.services ?? {})) {\n if (entry?.npm) serviceMap.set(short, entry.npm);\n }\n }\n\n const required = new Set<string>();\n for (const pluginName of pluginNames) {\n const meta = await fetchNpmPackageMeta(pluginName);\n for (const short of declaredServicesOf(meta)) {\n const npm = serviceMap.get(short) ?? `${SERVICE_PREFIX}${short}`;\n if (serviceMap.has(short)) {\n required.add(npm);\n continue;\n }\n const check = await fetchNpmPackageMeta(npm);\n if (check && check.keywords.includes(\"mioku\")) {\n required.add(npm);\n } else {\n consola.warn(\n `${pluginName} 声明了服务 \"${short}\",但未找到对应的 mioku 服务包,已跳过`,\n );\n }\n }\n }\n return Array.from(required);\n}\n\nexport async function multiSelect(\n message: string,\n items: Array<{ label: string; value: string }>,\n initial: string[] = [],\n options: { required?: boolean } = {},\n): Promise<string[]> {\n if (items.length === 0) return [];\n const result = await consola.prompt(message, {\n type: \"multiselect\",\n options: items,\n initial,\n cancel: \"reject\",\n required: options.required ?? false,\n });\n return (result as Array<string | { value: string }>).map((item) =>\n typeof item === \"string\" ? item : item.value,\n );\n}\n\nexport function runAdapterCli(name: string, cwd: string): void {\n const isWin = process.platform === \"win32\";\n const exts = isWin ? [\"\", \".cmd\", \".ps1\", \".bat\"] : [\"\"];\n for (const ext of exts) {\n const binPath = path.join(\n cwd,\n \"node_modules\",\n \".bin\",\n `mioku-adapter-${name}${ext}`,\n );\n if (fs.existsSync(binPath)) {\n run(binPath, [], { cwd });\n return;\n }\n }\n run(\"bunx\", [`mioku-adapter-${name}`], { cwd });\n}\n\nexport function shortNameOfPackage(pkgName: string): string {\n for (const prefix of [PLUGIN_PREFIX, SERVICE_PREFIX, ADAPTER_PREFIX]) {\n if (pkgName.startsWith(prefix)) return pkgName.slice(prefix.length);\n }\n return pkgName;\n}\n\nexport function run(\n cmd: string,\n args: string[] = [],\n options: { cwd?: string } = {},\n): void {\n runCommandInherit(cmd, args, options);\n}\n\nexport async function rmrf(dir: string, retries = 5): Promise<void> {\n for (let i = 0; i < retries; i++) {\n try {\n fs.rmSync(dir, { recursive: true, force: true });\n return;\n } catch (err: any) {\n if (i === retries - 1) throw err;\n const code = err?.code;\n if (\n code === \"EPERM\" ||\n code === \"EBUSY\" ||\n code === \"ENOTEMPTY\" ||\n code === \"ENOENT\"\n ) {\n await new Promise((resolve) => setTimeout(resolve, 300 * (i + 1)));\n } else {\n throw err;\n }\n }\n }\n}\n\nexport function hasCommand(cmd: string): boolean {\n return commandExists(cmd);\n}\n\nfunction findNpmPath(): string | null {\n const resolved = resolveCommand(\"npm\");\n if (resolved) return resolved;\n if (process.platform !== \"win32\") return null;\n\n const fallbacks = [\n path.join(process.env.ProgramFiles || \"\", \"nodejs\", \"npm.cmd\"),\n path.join(process.env[\"ProgramFiles(x86)\"] || \"\", \"nodejs\", \"npm.cmd\"),\n path.join(process.env.APPDATA || \"\", \"npm\", \"npm.cmd\"),\n ];\n\n return fallbacks.find((candidate) => resolveCommand(candidate)) ?? null;\n}\n\nfunction installBunViaOfficialScript(): void {\n console.log(\"安装 bun...\");\n if (process.platform === \"win32\") {\n const ps =\n process.env.SystemRoot &&\n path.join(\n process.env.SystemRoot,\n \"System32\",\n \"WindowsPowerShell\",\n \"v1.0\",\n \"powershell.exe\",\n );\n const psExe = ps && resolveCommand(ps) ? ps : \"powershell\";\n run(psExe, [\n \"-NoProfile\",\n \"-NonInteractive\",\n \"-ExecutionPolicy\",\n \"Bypass\",\n \"-Command\",\n \"irm bun.sh/install.ps1 | iex\",\n ]);\n } else {\n run(\"bash\", [\"-c\", \"curl -fsSL https://bun.sh/install | bash\"]);\n }\n clearCommandCache();\n}\n\nexport function ensurePackageManager(): void {\n if (hasCommand(\"bun\")) return;\n try {\n installBunViaOfficialScript();\n } catch (err) {\n const npmPath = findNpmPath();\n if (!npmPath) {\n consola.error(\"未找到 npm,请确保 Node.js 已安装并包含 npm\");\n consola.error(\n '自动安装 bun 失败,请手动执行:\\n macOS / Linux: curl -fsSL https://bun.sh/install | bash\\n Windows: powershell -c \"irm bun.sh/install.ps1 | iex\"',\n );\n throw err;\n }\n consola.warn(\"官方安装脚本失败,回退到 npm 全局安装 bun ...\");\n run(npmPath, [\"install\", \"-g\", \"bun\"]);\n clearCommandCache();\n }\n if (!hasCommand(\"bun\")) {\n const home = os.homedir();\n const candidates =\n process.platform === \"win32\"\n ? [\n path.join(home, \".bun\", \"bin\", \"bun.exe\"),\n path.join(process.env.APPDATA || \"\", \"npm\", \"bun.cmd\"),\n path.join(\n process.env.APPDATA || \"\",\n \"npm\",\n \"node_modules\",\n \".bin\",\n \"bun.cmd\",\n ),\n ]\n : [\n path.join(home, \".bun\", \"bin\", \"bun\"),\n \"/usr/local/bin/bun\",\n \"/opt/homebrew/bin/bun\",\n ];\n for (const c of candidates) {\n try {\n if (fs.existsSync(c)) {\n consola.warn(\n `检测到 bun 已安装在 ${c}。请把该目录加入 PATH 后重新运行本命令。`,\n );\n break;\n }\n } catch {\n // 忽略\n }\n }\n consola.error(\n \"bun 安装后仍无法在 PATH 中找到,请重启终端或将 bun 的安装目录加入 PATH 后重试\",\n );\n process.exit(1);\n }\n}\n\nexport function getAddCommand(packages: string[]): [string, string[]] {\n return [\"bun\", [\"add\", ...packages]];\n}\n\nexport function normalizePackageName(input: string): string {\n if (input.startsWith(PLUGIN_PREFIX) || input.startsWith(SERVICE_PREFIX)) {\n return input;\n }\n if (input.startsWith(\"mioku-\")) return input;\n return `${PLUGIN_PREFIX}${input}`;\n}\n\nexport function detectType(name: string): \"plugin\" | \"service\" | \"unknown\" {\n if (name.startsWith(PLUGIN_PREFIX)) return \"plugin\";\n if (name.startsWith(SERVICE_PREFIX)) return \"service\";\n return \"unknown\";\n}\n\nexport function execAdd(packages: string[], cwd?: string): void {\n const [cmd, args] = getAddCommand(packages);\n console.log(`执行: ${cmd} ${args.join(\" \")}`);\n run(cmd, args, { cwd });\n}\n\nexport function appendToMiokuPlugins(cwd: string, pkgName: string): boolean {\n if (!pkgName.startsWith(PLUGIN_PREFIX)) return false;\n const shortName = pkgName.slice(PLUGIN_PREFIX.length);\n\n const packageJsonPath = path.join(cwd, \"package.json\");\n if (!fs.existsSync(packageJsonPath)) return false;\n\n const pkg = JSON.parse(readFileSync(packageJsonPath, \"utf-8\"));\n const mioku = pkg.mioku ?? {};\n const plugins = Array.isArray(mioku.plugins) ? [...mioku.plugins] : [];\n if (plugins.includes(shortName)) return false;\n\n plugins.push(shortName);\n pkg.mioku = { ...mioku, plugins };\n fs.writeFileSync(packageJsonPath, `${JSON.stringify(pkg, null, 2)}\\n`);\n return true;\n}\n\nexport async function getInstalledPackages(cwd: string): Promise<string[]> {\n try {\n const pkg = JSON.parse(\n readFileSync(path.join(cwd, \"package.json\"), \"utf-8\"),\n );\n const deps = { ...pkg.dependencies, ...pkg.devDependencies };\n return Object.keys(deps).filter((k) => k.startsWith(\"mioku-\"));\n } catch {\n return [];\n }\n}\n\nexport function withRoot(p: string): string {\n return path.resolve(process.cwd(), p);\n}\n\nexport async function fetchNpmKeywords(\n packageName: string,\n): Promise<string[] | null> {\n try {\n const res = await fetch(\n `${NPM_REGISTRY}/${encodeURIComponent(packageName)}`,\n {\n headers: { Accept: \"application/json\", \"User-Agent\": \"mioku-cli\" },\n },\n );\n if (!res.ok) return null;\n const data = (await res.json()) as any;\n const latestVersion = String(data?.[\"dist-tags\"]?.latest || \"\").trim();\n const keywords = latestVersion\n ? data?.versions?.[latestVersion]?.keywords\n : data?.keywords;\n return Array.isArray(keywords) ? keywords.map(String) : [];\n } catch {\n return null;\n }\n}\n\nexport function gracefullyExit(): void {\n console.log(\"Bye!\");\n process.exit(0);\n}\n\nexport function makeFileTree(\n fileTree: Record<string, string | Record<string, unknown>>,\n base: string,\n): void {\n for (const [name, content] of Object.entries(fileTree)) {\n if (typeof content === \"object\" && content !== null) {\n const subPath = path.join(base, name);\n if (!fs.existsSync(subPath)) fs.mkdirSync(subPath, { recursive: true });\n for (const [subName, subContent] of Object.entries(content)) {\n if (typeof subContent === \"object\") {\n makeFileTree(\n subContent as Record<string, string | Record<string, unknown>>,\n path.join(subPath, subName),\n );\n } else {\n fs.writeFileSync(path.join(subPath, subName), subContent as string);\n }\n }\n } else {\n const filePath = path.join(base, name);\n const dirname = path.dirname(filePath);\n if (!fs.existsSync(dirname)) fs.mkdirSync(dirname, { recursive: true });\n fs.writeFileSync(filePath, content as string);\n }\n }\n}\n\nexport function buildHelpInfo(version: string): string {\n return dedent(`\n mioku 命令行工具 v${version}\n\n 用法: mioku <命令> [选项]\n\n 命令:\n install plugin <名称> 安装插件,自动补全 mioku-plugin- 前缀\n install service <名称> 安装服务,自动补全 mioku-service- 前缀\n update [包名|self|all] 更新插件或服务\n update - 检查可用更新\n update all - 更新所有 mioku- 包\n update self - 更新 mioku 框架\n update xxx - 更新指定包\n\n 选项:\n -h, --help 显示帮助信息\n -v, --version 显示版本号\n --name <name> 指定项目/文件夹名称,默认 mioku-bot\n --protocol <protocol> 指定 NapCat 协议,默认 ws\n --host <host> 指定 NapCat 主机,默认 localhost\n --port <port> 指定 NapCat 端口,默认 3001\n --token <token> 指定 NapCat 连接 Token,默认空\n --prefix <prefix> 指定命令前缀,默认 #\n --owners <owners> 指定主人 QQ,英文逗号分隔,必填\n --admins <admins> 指定管理员 QQ,英文逗号分隔,可空\n --use-npm-mirror 使用 npm 镜像源加速依赖安装,默认否\n `);\n}\n\ntype OmitTypeWithRequired<T> = Omit<T, \"type\" | \"required\"> & {\n required?: boolean;\n};\n\nexport async function confirm(\n message: string,\n options?: OmitTypeWithRequired<{ initial?: boolean }>,\n): Promise<boolean> {\n return consola.prompt(message, {\n type: \"confirm\",\n cancel: \"reject\",\n ...options,\n });\n}\n\nexport async function input(\n message: string,\n options?: OmitTypeWithRequired<{ default?: string; placeholder?: string }>,\n): Promise<string> {\n const result = await consola.prompt(message, {\n type: \"text\",\n cancel: \"reject\",\n ...options,\n });\n if (options?.required && !result) return input(message, options);\n return result;\n}\n","import consola from \"consola\";\nimport {\n ensurePackageManager,\n appendToMiokuPlugins,\n execAdd,\n fetchNpmKeywords,\n PLUGIN_PREFIX,\n SERVICE_PREFIX,\n confirm,\n} from \"./shared\";\n\nexport async function installCommand(\n cmdArgs: string[],\n helpInfo: string,\n): Promise<number> {\n ensurePackageManager();\n const cwd = process.cwd();\n const [type, name] = cmdArgs;\n\n if (!type || !name) {\n consola.error(\n \"请指定类型和名称: mioku install plugin <名称> 或 mioku install service <名称>\",\n );\n console.log(helpInfo);\n return 1;\n }\n\n if (type !== \"plugin\" && type !== \"service\") {\n consola.error(`无效的类型 \"${type}\",请使用 plugin 或 service`);\n console.log(helpInfo);\n return 1;\n }\n\n const prefix = type === \"plugin\" ? PLUGIN_PREFIX : SERVICE_PREFIX;\n const normalized = `${prefix}${name}`;\n\n if (type === \"plugin\") {\n const proceed = await warnIfPrivatePlugin(normalized);\n if (!proceed) {\n consola.info(\"已取消安装\");\n return 1;\n }\n }\n\n try {\n execAdd([normalized], cwd);\n consola.success(`已安装 ${normalized}`);\n\n if (type === \"plugin\") {\n const shortName = normalized.slice(PLUGIN_PREFIX.length);\n if (appendToMiokuPlugins(cwd, normalized)) {\n consola.success(`已在 mioku.plugins 中启用 ${shortName}`);\n } else {\n consola.info(`${shortName} 已在 mioku.plugins 中,跳过`);\n }\n }\n return 0;\n } catch {\n consola.error(`安装失败: ${normalized}`);\n return 1;\n }\n}\n\nasync function warnIfPrivatePlugin(pkgName: string): Promise<boolean> {\n const keywords = await fetchNpmKeywords(pkgName);\n if (keywords === null) return true;\n if (keywords.includes(\"mioku\")) return true;\n\n consola.warn(`${pkgName} 看起来是私有插件\"`);\n consola.warn(\"该插件未上架插件市场,可能存在风险\");\n return confirm(\"仍要继续安装吗?\", { initial: false });\n}\n","import consola from \"consola\";\nimport {\n run,\n ensurePackageManager,\n getInstalledPackages,\n PLUGIN_PREFIX,\n SERVICE_PREFIX,\n} from \"./shared\";\n\nasync function updatePackages(packages: string[], cwd: string): Promise<void> {\n if (packages.length === 0) {\n consola.info(\"未找到 mioku- 相关依赖\");\n return;\n }\n console.log(`执行: bun update ${packages.join(\" \")} --latest`);\n run(\"bun\", [\"update\", ...packages, \"--latest\"], { cwd });\n}\n\nasync function updateByPrefix(\n prefix: string,\n cwd: string,\n name?: string,\n): Promise<void> {\n if (name) {\n const normalized = name.startsWith(prefix) ? name : `${prefix}${name}`;\n console.log(`执行: bun update ${normalized} --latest`);\n run(\"bun\", [\"update\", normalized, \"--latest\"], { cwd });\n return;\n }\n const packages = (await getInstalledPackages(cwd)).filter((p) =>\n p.startsWith(prefix),\n );\n if (packages.length === 0) {\n consola.info(`未找到 ${prefix}* 相关依赖`);\n return;\n }\n await updatePackages(packages, cwd);\n}\n\nexport async function updateCommand(cmdArgs: string[]): Promise<number> {\n ensurePackageManager();\n const cwd = process.cwd();\n const [target, name] = cmdArgs;\n\n if (!target || target === \"check\") {\n run(\"bun\", [\"update\", \"-i\"], { cwd });\n return 0;\n }\n\n if (target === \"all\") {\n await updatePackages(await getInstalledPackages(cwd), cwd);\n return 0;\n }\n\n if (target === \"self\") {\n console.log(\"执行: bun update mioku --latest\");\n run(\"bun\", [\"update\", \"mioku\", \"--latest\"], { cwd });\n return 0;\n }\n\n if (target === \"plugin\" || target === \"service\") {\n const prefix = target === \"plugin\" ? PLUGIN_PREFIX : SERVICE_PREFIX;\n await updateByPrefix(prefix, cwd, name);\n return 0;\n }\n\n console.log(`执行: bun update ${target} --latest`);\n run(\"bun\", [\"update\", target, \"--latest\"], { cwd });\n return 0;\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport dedent from \"dedent\";\nimport consola from \"consola\";\nimport {\n ADAPTER_PREFIX,\n PLUGIN_PREFIX,\n ensurePackageManager,\n getAddCommand,\n multiSelect,\n run,\n runAdapterCli,\n searchMiokuPackages,\n shortNameOfPackage,\n resolveRequiredServices,\n rmrf,\n withRoot,\n gracefullyExit,\n makeFileTree,\n input,\n confirm,\n} from \"./shared\";\n\n/** stdin 会话对应的主人标识,默认追加到 mioku.owners */\nexport const STDIN_OWNER = \"stdin\";\n\n/** 系统自带适配器:必装且不可取消,默认启用 */\nexport const SYSTEM_ADAPTERS = [\"mioku-adapter-stdin\"];\n\n/** 系统自带插件:必装且不可取消 */\nexport const SYSTEM_PLUGINS = [\"mioku-plugin-help\", \"mioku-plugin-chat\"];\n\n/** 系统服务:框架运行所必需,无条件安装 */\nexport const SYSTEM_SERVICES = [\n \"mioku-service-ai\",\n \"mioku-service-config\",\n \"mioku-service-screenshot\",\n \"mioku-service-help\",\n];\n\nasync function createNewProject(\n name: string,\n fileTree: Record<string, string | Record<string, unknown>>,\n): Promise<string> {\n const projectPath = withRoot(`./${name}`);\n\n if (fs.existsSync(projectPath)) {\n const overwrite = await confirm(`项目 ${name} 已存在,是否覆盖?`);\n if (!overwrite) gracefullyExit();\n\n if (projectPath === process.cwd()) {\n if (fs.readdirSync(projectPath).length !== 0) {\n const confirmOver = await confirm(\n \"项目路径与当前路径相同,将删除当前目录下所有内容再创建,是否继续?\",\n );\n if (!confirmOver) gracefullyExit();\n }\n }\n await rmrf(projectPath);\n }\n\n fs.mkdirSync(projectPath, { recursive: true });\n makeFileTree(fileTree, projectPath);\n console.log(`项目 ${name} 创建成功!`);\n\n console.log(\"正在安装基础依赖 (bun i) ...\");\n run(\"bun\", [\"i\"], { cwd: projectPath });\n return projectPath;\n}\n\nasync function selectPackages(\n message: string,\n prefix: string,\n initial: string[] = [],\n options: { exclude?: string[]; typeLabel?: string } = {},\n): Promise<string[]> {\n console.log(`\\n正在从 npm 拉取 ${prefix}* 包...`);\n const hits = await searchMiokuPackages(prefix);\n if (hits.length === 0) {\n consola.warn(`未在 npm 上找到任何 ${prefix}* 包`);\n return [];\n }\n const excludeSet = new Set(options.exclude ?? []);\n const typeLabel = options.typeLabel ?? \"\";\n const items = hits\n .filter((hit) => !excludeSet.has(hit.name))\n .map((hit) => {\n const shortName = shortNameOfPackage(hit.name);\n const desc = hit.description || \"暂无介绍\";\n const label = typeLabel\n ? `${shortName} (${typeLabel} · ${desc})`\n : `${shortName} (${desc})`;\n return { label, value: hit.name };\n });\n return multiSelect(message, items, initial, { required: false });\n}\n\nexport async function scaffoldCommand(version: string): Promise<number> {\n const name = await input(\"请输入项目名称\", {\n default: \"mioku-bot\",\n placeholder: \"mioku-bot\",\n required: true,\n });\n const owners = await input(\"请输入主人 QQ (最高权限,英文逗号分隔,必填)\", {\n placeholder: \"请输入\",\n default: \"\",\n required: true,\n });\n\n ensurePackageManager();\n\n // stdin 会话默认拥有主人权限:自动追加到 owners\n const ownersList = [\n ...String(owners)\n .split(\",\")\n .map((o) => o.trim())\n .filter(Boolean),\n STDIN_OWNER,\n ];\n\n const adapterNames = await selectPackages(\n \"选择要安装的适配器(上下键选择,空格勾选,回车确认)\",\n ADAPTER_PREFIX,\n [],\n { exclude: SYSTEM_ADAPTERS, typeLabel: \"mioku 适配器\" },\n );\n const allAdapterNames = [...SYSTEM_ADAPTERS, ...adapterNames];\n if (adapterNames.length === 0) {\n consola.info(\"未选择其他适配器,仅启用标准输入\");\n }\n\n const pkgJsonObj = {\n name,\n private: true,\n type: \"module\" as const,\n dependencies: {\n mioku: \"latest\",\n ...Object.fromEntries(allAdapterNames.map((p) => [p, \"latest\"])),\n },\n mioku: {\n prefix: \".\",\n owners: ownersList,\n admins: [] as string[],\n plugins: [\"demo\"],\n log_level: \"info\",\n online_push: false,\n error_push: false,\n adapters: {\n stdin: {},\n },\n },\n scripts: {\n start: \"bun run app.ts\",\n dev: \"bun run --watch app.ts\",\n },\n };\n const pkgJson = `${JSON.stringify(pkgJsonObj, null, 2)}\\n`;\n\n const pluginCode = dedent(`\n import { definePlugin } from 'mioku'\n\n export default definePlugin({\n name: 'demo',\n version: '${version}',\n async setup(ctx) {\n ctx.logger.info('Demo 插件已加载')\n\n ctx.handle('message', async (e) => {\n if (e.raw_message === 'hello') {\n e.reply('world', true)\n }\n })\n\n return () => {\n ctx.logger.info('Demo 插件已卸载')\n }\n },\n })\n `);\n\n const fileTree: Record<string, string | Record<string, unknown>> = {\n \"app.ts\":\n \"import { start } from 'mioku'\\n\\nstart({ cwd: import.meta.dirname }).then()\\n\",\n \"package.json\": pkgJson,\n plugins: { demo: { \"index.ts\": pluginCode } },\n config: {},\n data: {},\n };\n\n const projectPath = await createNewProject(name, fileTree);\n\n // 仅为用户额外选择的适配器运行配置向导(系统适配器 stdin 免配置)\n for (const adapterPkg of adapterNames) {\n const adapterName = shortNameOfPackage(adapterPkg);\n consola.info(`正在运行 ${adapterPkg} 配置向导...`);\n runAdapterCli(adapterName, projectPath);\n }\n consola.info(\n `已自动安装并启用系统适配器: ${SYSTEM_ADAPTERS.map(shortNameOfPackage).join(\", \")}`,\n );\n\n // 系统插件必装且不可取消:从选择列表中剔除,自动启用\n const pluginNames = await selectPackages(\n \"选择要安装的插件(上下键选择,空格勾选,回车确认)\",\n PLUGIN_PREFIX,\n [],\n { exclude: SYSTEM_PLUGINS, typeLabel: \"mioku 插件\" },\n );\n consola.info(\n `系统插件将自动安装: ${SYSTEM_PLUGINS.map(shortNameOfPackage).join(\", \")}`,\n );\n\n const enabledPlugins = [\n \"demo\",\n ...SYSTEM_PLUGINS.map(shortNameOfPackage),\n ...pluginNames.map(shortNameOfPackage),\n ];\n const pkgPath = path.join(projectPath, \"package.json\");\n const pkg = JSON.parse(fs.readFileSync(pkgPath, \"utf-8\"));\n pkg.mioku = { ...pkg.mioku, plugins: enabledPlugins };\n fs.writeFileSync(pkgPath, `${JSON.stringify(pkg, null, 2)}\\n`);\n\n const serviceNames = new Set<string>(SYSTEM_SERVICES);\n for (const service of await resolveRequiredServices(pluginNames)) {\n serviceNames.add(service);\n }\n consola.info(\n `将自动安装服务: ${Array.from(serviceNames).map(shortNameOfPackage).join(\", \")}`,\n );\n\n const installWebui = await confirm(\"是否安装 WebUI 管理面板?(建议安装)\", {\n initial: true,\n });\n\n const addPackages = [...pluginNames, ...Array.from(serviceNames)];\n if (installWebui) addPackages.push(\"mioku-service-webui\");\n\n if (addPackages.length > 0) {\n const [cmd, args] = getAddCommand(addPackages);\n console.log(`正在安装插件与服务: ${cmd} ${args.join(\" \")}`);\n run(cmd, args, { cwd: projectPath });\n }\n\n console.log(\"\\n若需启动机器人,请运行:\");\n console.log(\" cd\", name);\n console.log(\" bun run start\");\n return 0;\n}\n","#!/usr/bin/env node\n\nimport mri from \"mri\";\nimport { version } from \"../../package.json\";\nimport { buildHelpInfo } from \"./shared\";\nimport { installCommand } from \"./install\";\nimport { updateCommand } from \"./update\";\nimport { scaffoldCommand } from \"./scaffold\";\n\ninterface CliOptions {\n help?: boolean;\n version?: boolean;\n}\n\nconst args = process.argv.slice(2);\n\n(async () => {\n const cli = mri<CliOptions>(args, { alias: { v: \"version\", h: \"help\" } });\n const helpInfo = buildHelpInfo(version);\n const [cmd, ...cmdArgs] = args;\n\n switch (cmd) {\n case \"install\":\n process.exitCode = await installCommand(cmdArgs, helpInfo);\n return;\n case \"update\":\n process.exitCode = await updateCommand(cmdArgs);\n return;\n default:\n if (cli.version) {\n console.log(`v${version}`);\n return;\n }\n if (cli.help) {\n console.log(helpInfo);\n return;\n }\n process.exitCode = await scaffoldCommand(version);\n return;\n }\n})();\n"],"mappings":"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"}
@@ -4,7 +4,7 @@ import * as os$1 from "node:os";
4
4
  import { spawn, spawnSync } from "node:child_process";
5
5
 
6
6
  //#region package.json
7
- var version = "1.0.2";
7
+ var version = "1.0.4";
8
8
 
9
9
  //#endregion
10
10
  //#region src/internal/exec.ts
@@ -12,16 +12,27 @@ const isWindows = process.platform === "win32";
12
12
  const resolveCache = new Map();
13
13
  function windowsExtensions() {
14
14
  const raw = process.env.PATHEXT || ".COM;.EXE;.BAT;.CMD";
15
- return raw.split(");").map((ext) => ext.trim()).filter(Boolean);
15
+ return raw.split(";").map((ext) => ext.trim()).filter(Boolean);
16
16
  }
17
17
  function searchDirs() {
18
18
  const raw = process.env.PATH || process.env.Path || "";
19
19
  const dirs = raw.split(path$1.delimiter).map((d) => d.trim()).filter(Boolean);
20
20
  const home = os$1.homedir();
21
+ const appData = process.env.APPDATA || path$1.join(home, "AppData", "Roaming");
22
+ const localAppData = process.env.LOCALAPPDATA || path$1.join(home, "AppData", "Local");
23
+ const programFiles = process.env.ProgramFiles || "C:\\Program Files";
24
+ const programFilesX86 = process.env["ProgramFiles(x86)"] || "C:\\Program Files (x86)";
21
25
  const extra = isWindows ? [
22
26
  path$1.join(home, ".bun", "bin"),
23
- path$1.join(process.env.APPDATA || "", "npm"),
24
- path$1.join(process.env.ProgramFiles || "", "nodejs")
27
+ path$1.join(appData, "npm"),
28
+ path$1.join(appData, "npm", "node_modules", ".bin"),
29
+ path$1.join(localAppData, "bun", "bin"),
30
+ path$1.join(programFiles, "bun", "bin"),
31
+ path$1.join(programFilesX86, "bun", "bin"),
32
+ path$1.join(home, "scoop", "shims"),
33
+ "C:\\ProgramData\\chocolatey\\bin",
34
+ path$1.join(programFiles, "nodejs"),
35
+ path$1.join(programFilesX86, "nodejs")
25
36
  ] : [
26
37
  path$1.join(home, ".bun", "bin"),
27
38
  "/usr/local/bin",
@@ -37,6 +48,27 @@ function isExecutableFile(candidate) {
37
48
  return false;
38
49
  }
39
50
  }
51
+ function searchCommandViaShell(command) {
52
+ if (command.includes("/") || command.includes(path$1.sep)) return null;
53
+ const shellCmd = isWindows ? "where" : "which";
54
+ try {
55
+ const result = spawnSync(shellCmd, [command], {
56
+ encoding: "utf-8",
57
+ windowsHide: true,
58
+ stdio: [
59
+ "ignore",
60
+ "pipe",
61
+ "pipe"
62
+ ],
63
+ timeout: 5e3
64
+ });
65
+ if (result.status === 0 && result.stdout) {
66
+ const first = result.stdout.split(/\r?\n/).map((s) => s.trim()).find(Boolean);
67
+ if (first && isExecutableFile(first)) return first;
68
+ }
69
+ } catch {}
70
+ return null;
71
+ }
40
72
  /** 在 PATH 及常见安装目录中解析命令的完整路径,结果带缓存 */
41
73
  function resolveCommand(command) {
42
74
  if (resolveCache.has(command)) return resolveCache.get(command) ?? null;
@@ -62,6 +94,7 @@ function resolveCommand(command) {
62
94
  }
63
95
  }
64
96
  }
97
+ if (!resolved) resolved = searchCommandViaShell(command);
65
98
  }
66
99
  resolveCache.set(command, resolved);
67
100
  return resolved;
@@ -147,4 +180,4 @@ function commandExists(command) {
147
180
 
148
181
  //#endregion
149
182
  export { buildSpawnPlan, clearCommandCache, commandExists, resolveCommand, runCommand, runCommandInherit, version };
150
- //# sourceMappingURL=exec-DmpZrf3S.js.map
183
+ //# sourceMappingURL=exec-B6AHNNhG.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exec-B6AHNNhG.js","names":["path","candidate: string","command: string","resolved: string | null","resolved: string","args: string[]","options: { cwd?: string; env?: NodeJS.ProcessEnv }","options: { cwd?: string }"],"sources":["../package.json","../src/internal/exec.ts"],"sourcesContent":["{\n \"name\": \"mioku\",\n \"type\": \"module\",\n \"version\": \"1.0.4\",\n \"packageManager\": \"bun@1.2.0\",\n \"description\": \"Mioku - A plugin-based QQ bot framework\",\n \"keywords\": [\n \"onebot\",\n \"framework\",\n \"bot\",\n \"mioku\"\n ],\n \"bin\": {\n \"mioku\": \"./dist/cli/index.js\"\n },\n \"engines\": {\n \"node\": \">= 22.18.0\"\n },\n \"homepage\": \"https://github.com/mioku-lab/mioku#readme\",\n \"files\": [\n \"dist\"\n ],\n \"bugs\": {\n \"url\": \"https://github.com/mioku-lab/mioku/issues\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/mioku-lab/mioku.git\",\n \"directory\": \"packages/mioku\"\n },\n \"scripts\": {\n \"dev\": \"tsdown -w\",\n \"build\": \"tsdown\",\n \"typecheck\": \"tsc --noEmit\"\n },\n \"exports\": {\n \".\": {\n \"require\": \"./dist/index.cjs\",\n \"import\": \"./dist/index.js\"\n },\n \"./package.json\": \"./package.json\"\n },\n \"author\": \"Jerryplusy <jerryplusy@outlook.com>\",\n \"license\": \"MIT\",\n \"dependencies\": {\n \"napcat-sdk\": \"^0.16.0\",\n \"consola\": \"^3.4.2\",\n \"dayjs\": \"^1.11.19\",\n \"dedent\": \"^1.7.1\",\n \"filesize\": \"^11.0.13\",\n \"inquirer\": \"^10.0.0\",\n \"jiti\": \"^2.6.1\",\n \"lowdb\": \"^7.0.1\",\n \"mri\": \"^1.2.0\",\n \"node-cron\": \"^4.2.1\",\n \"pretty-ms\": \"^9.3.0\",\n \"string2argv\": \"^1.0.2\",\n \"lodash\": \"^4.17.21\"\n },\n \"devDependencies\": {\n \"@types/lodash\": \"^4.17.0\",\n \"@types/node\": \"^22.0.0\",\n \"tsdown\": \"^0.11.0\",\n \"typescript\": \"^5.8.0\"\n }\n}\n","import { spawn, spawnSync } from \"node:child_process\";\nimport * as fs from \"node:fs\";\nimport * as os from \"node:os\";\nimport * as path from \"node:path\";\n\nconst isWindows = process.platform === \"win32\";\n\nconst resolveCache = new Map<string, string | null>();\n\nfunction windowsExtensions(): string[] {\n const raw = process.env.PATHEXT || \".COM;.EXE;.BAT;.CMD\";\n return raw\n .split(\";\")\n .map((ext) => ext.trim())\n .filter(Boolean);\n}\n\n// PATH is a snapshot taken at process start, so a package manager installed\n// mid-run won't be on it. We enumerate every plausible install prefix for\n// bun / npm / scoop / chocolatey so the CLI can find bun in one shot.\nfunction searchDirs(): string[] {\n const raw = process.env.PATH || process.env.Path || \"\";\n const dirs = raw\n .split(path.delimiter)\n .map((d) => d.trim())\n .filter(Boolean);\n const home = os.homedir();\n const appData = process.env.APPDATA || path.join(home, \"AppData\", \"Roaming\");\n const localAppData =\n process.env.LOCALAPPDATA || path.join(home, \"AppData\", \"Local\");\n const programFiles = process.env.ProgramFiles || \"C:\\\\Program Files\";\n const programFilesX86 =\n process.env[\"ProgramFiles(x86)\"] || \"C:\\\\Program Files (x86)\";\n\n const extra = isWindows\n ? [\n // 官方安装器\n path.join(home, \".bun\", \"bin\"),\n // npm 全局(带 .cmd shim)\n path.join(appData, \"npm\"),\n path.join(appData, \"npm\", \"node_modules\", \".bin\"),\n // 备用 bun 位置\n path.join(localAppData, \"bun\", \"bin\"),\n path.join(programFiles, \"bun\", \"bin\"),\n path.join(programFilesX86, \"bun\", \"bin\"),\n // scoop\n path.join(home, \"scoop\", \"shims\"),\n // chocolatey\n \"C:\\\\ProgramData\\\\chocolatey\\\\bin\",\n // node 自带(很多用户 npm i -g 装到 node 目录)\n path.join(programFiles, \"nodejs\"),\n path.join(programFilesX86, \"nodejs\"),\n ]\n : [\n path.join(home, \".bun\", \"bin\"),\n \"/usr/local/bin\",\n \"/opt/homebrew/bin\",\n path.join(home, \".npm-global\", \"bin\"),\n ];\n\n return [...dirs, ...extra.filter((dir) => dir && !dir.endsWith(path.sep))];\n}\n\nfunction isExecutableFile(candidate: string): boolean {\n try {\n return fs.statSync(candidate).isFile();\n } catch {\n return false;\n }\n}\n\nfunction searchCommandViaShell(command: string): string | null {\n if (command.includes(\"/\") || command.includes(path.sep)) return null;\n const shellCmd = isWindows ? \"where\" : \"which\";\n try {\n const result = spawnSync(shellCmd, [command], {\n encoding: \"utf-8\",\n windowsHide: true,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n timeout: 5000,\n });\n if (result.status === 0 && result.stdout) {\n const first = result.stdout\n .split(/\\r?\\n/)\n .map((s) => s.trim())\n .find(Boolean);\n if (first && isExecutableFile(first)) return first;\n }\n } catch {}\n return null;\n}\n\n/** 在 PATH 及常见安装目录中解析命令的完整路径,结果带缓存 */\nexport function resolveCommand(command: string): string | null {\n if (resolveCache.has(command)) return resolveCache.get(command) ?? null;\n\n let resolved: string | null = null;\n\n if (command.includes(\"/\") || command.includes(path.sep)) {\n resolved = isExecutableFile(command) ? path.resolve(command) : null;\n } else {\n const exts = isWindows ? windowsExtensions() : [\"\"];\n const hasKnownExt =\n isWindows &&\n exts.some((ext) => command.toLowerCase().endsWith(ext.toLowerCase()));\n\n outer: for (const dir of searchDirs()) {\n if (hasKnownExt) {\n const direct = path.join(dir, command);\n if (isExecutableFile(direct)) {\n resolved = direct;\n break;\n }\n continue;\n }\n for (const ext of exts) {\n const candidate = path.join(dir, command + ext);\n if (isExecutableFile(candidate)) {\n resolved = candidate;\n break outer;\n }\n }\n }\n\n if (!resolved) resolved = searchCommandViaShell(command);\n }\n\n resolveCache.set(command, resolved);\n return resolved;\n}\n\nexport function clearCommandCache(): void {\n resolveCache.clear();\n}\n\nfunction needsCmdShell(resolved: string): boolean {\n if (!isWindows) return false;\n const ext = path.extname(resolved).toLowerCase();\n return ext === \".cmd\" || ext === \".bat\";\n}\n\nexport interface SpawnPlan {\n file: string;\n args: string[];\n windowsVerbatimArguments?: boolean;\n shell?: boolean | string;\n}\n\n// Windows can't CreateProcess a .cmd/.bat shim directly (npm installs bun as\n// bun.cmd), so those get routed through cmd.exe via shell: true. Previously\n// we hand-rolled a cmd.exe invocation with windowsVerbatimArguments: true,\n// but that combination misbehaves with spawnSync + stdio:\"inherit\" on\n// Node.js >= 20 (manifests as the spawned process printing \"undefined\" or\n// a spurious EINVAL), so we let Node's shell wrapper do the quoting.\n/** 生成跨平台的 spawn 参数,Windows 下 .cmd/.bat 会改经 cmd.exe 执行 */\nexport function buildSpawnPlan(command: string, args: string[]): SpawnPlan {\n const resolved = resolveCommand(command);\n\n if (!resolved) {\n return { file: command, args };\n }\n\n if (!needsCmdShell(resolved)) {\n return { file: resolved, args };\n }\n\n return {\n file: resolved,\n args,\n shell: true,\n };\n}\n\nexport interface RunCommandResult {\n stdout: string;\n stderr: string;\n code: number;\n}\n\n/** 执行命令并收集 stdout/stderr 与退出码,失败不抛异常 */\nexport function runCommand(\n command: string,\n args: string[],\n options: { cwd?: string; env?: NodeJS.ProcessEnv } = {},\n): Promise<RunCommandResult> {\n const plan = buildSpawnPlan(command, args);\n\n return new Promise((resolve) => {\n const child = spawn(plan.file, plan.args, {\n cwd: options.cwd,\n env: options.env,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n shell: plan.shell,\n });\n\n let stdout = \"\";\n let stderr = \"\";\n\n child.stdout?.on(\"data\", (chunk) => {\n stdout += String(chunk);\n });\n child.stderr?.on(\"data\", (chunk) => {\n stderr += String(chunk);\n });\n\n child.on(\"close\", (code) => {\n resolve({ stdout, stderr, code: code ?? 1 });\n });\n child.on(\"error\", (error) => {\n resolve({\n stdout,\n stderr: `${stderr}\\n${error.message}`.trim(),\n code: 1,\n });\n });\n });\n}\n\n/** 同步执行命令并继承当前终端的输入输出,非零退出码时抛错 */\nexport function runCommandInherit(\n command: string,\n args: string[],\n options: { cwd?: string } = {},\n): void {\n const plan = buildSpawnPlan(command, args);\n const result = spawnSync(plan.file, plan.args, {\n cwd: options.cwd,\n stdio: \"inherit\",\n shell: plan.shell,\n });\n\n if (result.error) throw result.error;\n if (result.status !== 0) {\n throw new Error(`${command} 退出码 ${result.status}`);\n }\n}\n\n/** 判断命令是否可用 */\nexport function commandExists(command: string): boolean {\n return resolveCommand(command) !== null;\n}\n"],"mappings":"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"}
@@ -27,7 +27,7 @@ const node_os = __toESM(require("node:os"));
27
27
  const node_child_process = __toESM(require("node:child_process"));
28
28
 
29
29
  //#region package.json
30
- var version = "1.0.2";
30
+ var version = "1.0.4";
31
31
 
32
32
  //#endregion
33
33
  //#region src/internal/exec.ts
@@ -35,16 +35,27 @@ const isWindows = process.platform === "win32";
35
35
  const resolveCache = new Map();
36
36
  function windowsExtensions() {
37
37
  const raw = process.env.PATHEXT || ".COM;.EXE;.BAT;.CMD";
38
- return raw.split(");").map((ext) => ext.trim()).filter(Boolean);
38
+ return raw.split(";").map((ext) => ext.trim()).filter(Boolean);
39
39
  }
40
40
  function searchDirs() {
41
41
  const raw = process.env.PATH || process.env.Path || "";
42
42
  const dirs = raw.split(node_path.delimiter).map((d) => d.trim()).filter(Boolean);
43
43
  const home = node_os.homedir();
44
+ const appData = process.env.APPDATA || node_path.join(home, "AppData", "Roaming");
45
+ const localAppData = process.env.LOCALAPPDATA || node_path.join(home, "AppData", "Local");
46
+ const programFiles = process.env.ProgramFiles || "C:\\Program Files";
47
+ const programFilesX86 = process.env["ProgramFiles(x86)"] || "C:\\Program Files (x86)";
44
48
  const extra = isWindows ? [
45
49
  node_path.join(home, ".bun", "bin"),
46
- node_path.join(process.env.APPDATA || "", "npm"),
47
- node_path.join(process.env.ProgramFiles || "", "nodejs")
50
+ node_path.join(appData, "npm"),
51
+ node_path.join(appData, "npm", "node_modules", ".bin"),
52
+ node_path.join(localAppData, "bun", "bin"),
53
+ node_path.join(programFiles, "bun", "bin"),
54
+ node_path.join(programFilesX86, "bun", "bin"),
55
+ node_path.join(home, "scoop", "shims"),
56
+ "C:\\ProgramData\\chocolatey\\bin",
57
+ node_path.join(programFiles, "nodejs"),
58
+ node_path.join(programFilesX86, "nodejs")
48
59
  ] : [
49
60
  node_path.join(home, ".bun", "bin"),
50
61
  "/usr/local/bin",
@@ -60,6 +71,27 @@ function isExecutableFile(candidate) {
60
71
  return false;
61
72
  }
62
73
  }
74
+ function searchCommandViaShell(command) {
75
+ if (command.includes("/") || command.includes(node_path.sep)) return null;
76
+ const shellCmd = isWindows ? "where" : "which";
77
+ try {
78
+ const result = (0, node_child_process.spawnSync)(shellCmd, [command], {
79
+ encoding: "utf-8",
80
+ windowsHide: true,
81
+ stdio: [
82
+ "ignore",
83
+ "pipe",
84
+ "pipe"
85
+ ],
86
+ timeout: 5e3
87
+ });
88
+ if (result.status === 0 && result.stdout) {
89
+ const first = result.stdout.split(/\r?\n/).map((s) => s.trim()).find(Boolean);
90
+ if (first && isExecutableFile(first)) return first;
91
+ }
92
+ } catch {}
93
+ return null;
94
+ }
63
95
  /** 在 PATH 及常见安装目录中解析命令的完整路径,结果带缓存 */
64
96
  function resolveCommand(command) {
65
97
  if (resolveCache.has(command)) return resolveCache.get(command) ?? null;
@@ -85,6 +117,7 @@ function resolveCommand(command) {
85
117
  }
86
118
  }
87
119
  }
120
+ if (!resolved) resolved = searchCommandViaShell(command);
88
121
  }
89
122
  resolveCache.set(command, resolved);
90
123
  return resolved;
@@ -217,4 +250,4 @@ Object.defineProperty(exports, 'version', {
217
250
  return version;
218
251
  }
219
252
  });
220
- //# sourceMappingURL=exec-B4lXl4No.cjs.map
253
+ //# sourceMappingURL=exec-Bwnfv-TQ.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exec-Bwnfv-TQ.cjs","names":["path","candidate: string","command: string","resolved: string | null","resolved: string","args: string[]","options: { cwd?: string; env?: NodeJS.ProcessEnv }","options: { cwd?: string }"],"sources":["../package.json","../src/internal/exec.ts"],"sourcesContent":["{\n \"name\": \"mioku\",\n \"type\": \"module\",\n \"version\": \"1.0.4\",\n \"packageManager\": \"bun@1.2.0\",\n \"description\": \"Mioku - A plugin-based QQ bot framework\",\n \"keywords\": [\n \"onebot\",\n \"framework\",\n \"bot\",\n \"mioku\"\n ],\n \"bin\": {\n \"mioku\": \"./dist/cli/index.js\"\n },\n \"engines\": {\n \"node\": \">= 22.18.0\"\n },\n \"homepage\": \"https://github.com/mioku-lab/mioku#readme\",\n \"files\": [\n \"dist\"\n ],\n \"bugs\": {\n \"url\": \"https://github.com/mioku-lab/mioku/issues\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/mioku-lab/mioku.git\",\n \"directory\": \"packages/mioku\"\n },\n \"scripts\": {\n \"dev\": \"tsdown -w\",\n \"build\": \"tsdown\",\n \"typecheck\": \"tsc --noEmit\"\n },\n \"exports\": {\n \".\": {\n \"require\": \"./dist/index.cjs\",\n \"import\": \"./dist/index.js\"\n },\n \"./package.json\": \"./package.json\"\n },\n \"author\": \"Jerryplusy <jerryplusy@outlook.com>\",\n \"license\": \"MIT\",\n \"dependencies\": {\n \"napcat-sdk\": \"^0.16.0\",\n \"consola\": \"^3.4.2\",\n \"dayjs\": \"^1.11.19\",\n \"dedent\": \"^1.7.1\",\n \"filesize\": \"^11.0.13\",\n \"inquirer\": \"^10.0.0\",\n \"jiti\": \"^2.6.1\",\n \"lowdb\": \"^7.0.1\",\n \"mri\": \"^1.2.0\",\n \"node-cron\": \"^4.2.1\",\n \"pretty-ms\": \"^9.3.0\",\n \"string2argv\": \"^1.0.2\",\n \"lodash\": \"^4.17.21\"\n },\n \"devDependencies\": {\n \"@types/lodash\": \"^4.17.0\",\n \"@types/node\": \"^22.0.0\",\n \"tsdown\": \"^0.11.0\",\n \"typescript\": \"^5.8.0\"\n }\n}\n","import { spawn, spawnSync } from \"node:child_process\";\nimport * as fs from \"node:fs\";\nimport * as os from \"node:os\";\nimport * as path from \"node:path\";\n\nconst isWindows = process.platform === \"win32\";\n\nconst resolveCache = new Map<string, string | null>();\n\nfunction windowsExtensions(): string[] {\n const raw = process.env.PATHEXT || \".COM;.EXE;.BAT;.CMD\";\n return raw\n .split(\";\")\n .map((ext) => ext.trim())\n .filter(Boolean);\n}\n\n// PATH is a snapshot taken at process start, so a package manager installed\n// mid-run won't be on it. We enumerate every plausible install prefix for\n// bun / npm / scoop / chocolatey so the CLI can find bun in one shot.\nfunction searchDirs(): string[] {\n const raw = process.env.PATH || process.env.Path || \"\";\n const dirs = raw\n .split(path.delimiter)\n .map((d) => d.trim())\n .filter(Boolean);\n const home = os.homedir();\n const appData = process.env.APPDATA || path.join(home, \"AppData\", \"Roaming\");\n const localAppData =\n process.env.LOCALAPPDATA || path.join(home, \"AppData\", \"Local\");\n const programFiles = process.env.ProgramFiles || \"C:\\\\Program Files\";\n const programFilesX86 =\n process.env[\"ProgramFiles(x86)\"] || \"C:\\\\Program Files (x86)\";\n\n const extra = isWindows\n ? [\n // 官方安装器\n path.join(home, \".bun\", \"bin\"),\n // npm 全局(带 .cmd shim)\n path.join(appData, \"npm\"),\n path.join(appData, \"npm\", \"node_modules\", \".bin\"),\n // 备用 bun 位置\n path.join(localAppData, \"bun\", \"bin\"),\n path.join(programFiles, \"bun\", \"bin\"),\n path.join(programFilesX86, \"bun\", \"bin\"),\n // scoop\n path.join(home, \"scoop\", \"shims\"),\n // chocolatey\n \"C:\\\\ProgramData\\\\chocolatey\\\\bin\",\n // node 自带(很多用户 npm i -g 装到 node 目录)\n path.join(programFiles, \"nodejs\"),\n path.join(programFilesX86, \"nodejs\"),\n ]\n : [\n path.join(home, \".bun\", \"bin\"),\n \"/usr/local/bin\",\n \"/opt/homebrew/bin\",\n path.join(home, \".npm-global\", \"bin\"),\n ];\n\n return [...dirs, ...extra.filter((dir) => dir && !dir.endsWith(path.sep))];\n}\n\nfunction isExecutableFile(candidate: string): boolean {\n try {\n return fs.statSync(candidate).isFile();\n } catch {\n return false;\n }\n}\n\nfunction searchCommandViaShell(command: string): string | null {\n if (command.includes(\"/\") || command.includes(path.sep)) return null;\n const shellCmd = isWindows ? \"where\" : \"which\";\n try {\n const result = spawnSync(shellCmd, [command], {\n encoding: \"utf-8\",\n windowsHide: true,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n timeout: 5000,\n });\n if (result.status === 0 && result.stdout) {\n const first = result.stdout\n .split(/\\r?\\n/)\n .map((s) => s.trim())\n .find(Boolean);\n if (first && isExecutableFile(first)) return first;\n }\n } catch {}\n return null;\n}\n\n/** 在 PATH 及常见安装目录中解析命令的完整路径,结果带缓存 */\nexport function resolveCommand(command: string): string | null {\n if (resolveCache.has(command)) return resolveCache.get(command) ?? null;\n\n let resolved: string | null = null;\n\n if (command.includes(\"/\") || command.includes(path.sep)) {\n resolved = isExecutableFile(command) ? path.resolve(command) : null;\n } else {\n const exts = isWindows ? windowsExtensions() : [\"\"];\n const hasKnownExt =\n isWindows &&\n exts.some((ext) => command.toLowerCase().endsWith(ext.toLowerCase()));\n\n outer: for (const dir of searchDirs()) {\n if (hasKnownExt) {\n const direct = path.join(dir, command);\n if (isExecutableFile(direct)) {\n resolved = direct;\n break;\n }\n continue;\n }\n for (const ext of exts) {\n const candidate = path.join(dir, command + ext);\n if (isExecutableFile(candidate)) {\n resolved = candidate;\n break outer;\n }\n }\n }\n\n if (!resolved) resolved = searchCommandViaShell(command);\n }\n\n resolveCache.set(command, resolved);\n return resolved;\n}\n\nexport function clearCommandCache(): void {\n resolveCache.clear();\n}\n\nfunction needsCmdShell(resolved: string): boolean {\n if (!isWindows) return false;\n const ext = path.extname(resolved).toLowerCase();\n return ext === \".cmd\" || ext === \".bat\";\n}\n\nexport interface SpawnPlan {\n file: string;\n args: string[];\n windowsVerbatimArguments?: boolean;\n shell?: boolean | string;\n}\n\n// Windows can't CreateProcess a .cmd/.bat shim directly (npm installs bun as\n// bun.cmd), so those get routed through cmd.exe via shell: true. Previously\n// we hand-rolled a cmd.exe invocation with windowsVerbatimArguments: true,\n// but that combination misbehaves with spawnSync + stdio:\"inherit\" on\n// Node.js >= 20 (manifests as the spawned process printing \"undefined\" or\n// a spurious EINVAL), so we let Node's shell wrapper do the quoting.\n/** 生成跨平台的 spawn 参数,Windows 下 .cmd/.bat 会改经 cmd.exe 执行 */\nexport function buildSpawnPlan(command: string, args: string[]): SpawnPlan {\n const resolved = resolveCommand(command);\n\n if (!resolved) {\n return { file: command, args };\n }\n\n if (!needsCmdShell(resolved)) {\n return { file: resolved, args };\n }\n\n return {\n file: resolved,\n args,\n shell: true,\n };\n}\n\nexport interface RunCommandResult {\n stdout: string;\n stderr: string;\n code: number;\n}\n\n/** 执行命令并收集 stdout/stderr 与退出码,失败不抛异常 */\nexport function runCommand(\n command: string,\n args: string[],\n options: { cwd?: string; env?: NodeJS.ProcessEnv } = {},\n): Promise<RunCommandResult> {\n const plan = buildSpawnPlan(command, args);\n\n return new Promise((resolve) => {\n const child = spawn(plan.file, plan.args, {\n cwd: options.cwd,\n env: options.env,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n shell: plan.shell,\n });\n\n let stdout = \"\";\n let stderr = \"\";\n\n child.stdout?.on(\"data\", (chunk) => {\n stdout += String(chunk);\n });\n child.stderr?.on(\"data\", (chunk) => {\n stderr += String(chunk);\n });\n\n child.on(\"close\", (code) => {\n resolve({ stdout, stderr, code: code ?? 1 });\n });\n child.on(\"error\", (error) => {\n resolve({\n stdout,\n stderr: `${stderr}\\n${error.message}`.trim(),\n code: 1,\n });\n });\n });\n}\n\n/** 同步执行命令并继承当前终端的输入输出,非零退出码时抛错 */\nexport function runCommandInherit(\n command: string,\n args: string[],\n options: { cwd?: string } = {},\n): void {\n const plan = buildSpawnPlan(command, args);\n const result = spawnSync(plan.file, plan.args, {\n cwd: options.cwd,\n stdio: \"inherit\",\n shell: plan.shell,\n });\n\n if (result.error) throw result.error;\n if (result.status !== 0) {\n throw new Error(`${command} 退出码 ${result.status}`);\n }\n}\n\n/** 判断命令是否可用 */\nexport function commandExists(command: string): boolean {\n return resolveCommand(command) !== null;\n}\n"],"mappings":"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"}
package/dist/index.cjs CHANGED
@@ -1,4 +1,4 @@
1
- const require_exec = require('./exec-B4lXl4No.cjs');
1
+ const require_exec = require('./exec-Bwnfv-TQ.cjs');
2
2
  const node_fs = require_exec.__toESM(require("node:fs"));
3
3
  const node_path = require_exec.__toESM(require("node:path"));
4
4
  const node_url = require_exec.__toESM(require("node:url"));
@@ -1357,6 +1357,15 @@ const filter = (source, type) => {
1357
1357
  const message = getMessage(source);
1358
1358
  return message.filter((seg) => seg.type === type);
1359
1359
  };
1360
+ const ADAPTER_DISPLAY_NAMES = {
1361
+ stdin: "标准输入",
1362
+ onebotv11: "OneBot v11",
1363
+ icqq: "ICQQ"
1364
+ };
1365
+ const displayAdapterId = (id) => {
1366
+ if (id == null) return "";
1367
+ return ADAPTER_DISPLAY_NAMES[String(id)] ?? String(id);
1368
+ };
1360
1369
  const getMessage = (source) => {
1361
1370
  if (Array.isArray(source) && typeof source.text === "function") return source;
1362
1371
  return source.message;
@@ -2348,7 +2357,7 @@ const formatMiokuStatus = async (status) => {
2348
2357
  const botLines = bots.map((bot) => {
2349
2358
  const hasStats = bot.friends != null || bot.groups != null || bot.send != null || bot.receive != null;
2350
2359
  const statsLine$1 = hasStats ? `\n📋 ${localNum(bot.friends ?? 0)} 好友 / ${localNum(bot.groups ?? 0)} 群 / 📮 收 ${localNum(bot.receive ?? 0)} 发 ${localNum(bot.send ?? 0)}` : "";
2351
- return `👤 ${bot.nickname || "(未命名)"} (${bot.bot_id})${statsLine$1}`;
2360
+ return `👤 ${bot.nickname || "(未命名)"} (${displayAdapterId(bot.bot_id)})${statsLine$1}`;
2352
2361
  }).join("\n");
2353
2362
  const totalSend = bots.reduce((sum, bot) => sum + (bot.send ?? 0), 0);
2354
2363
  const totalReceive = bots.reduce((sum, bot) => sum + (bot.receive ?? 0), 0);
@@ -2480,7 +2489,7 @@ const formatInstance = (instance) => {
2480
2489
  instance.platform ? `${instance.platform}${instance.platformVersion ? ` v${instance.platformVersion}` : ""}` : "",
2481
2490
  instance.online ? "" : "🔴 离线"
2482
2491
  ].filter(Boolean);
2483
- const lines = [`👤 ${instance.nickname || "(未命名)"} (${instance.bot_id})${tags.length ? ` · ${tags.join(" · ")}` : ""}`];
2492
+ const lines = [`👤 ${instance.nickname || "(未命名)"} (${displayAdapterId(instance.bot_id)})${tags.length ? ` · ${tags.join(" · ")}` : ""}`];
2484
2493
  const uptime = instance.online && instance.connected_at != null ? `⏳ 已连接 ${(0, pretty_ms.default)(Date.now() - instance.connected_at, {
2485
2494
  hideYear: true,
2486
2495
  secondsDecimalDigits: 0
@@ -2496,9 +2505,9 @@ const summarize = (entry) => {
2496
2505
  if (online === total) return `🟢 ${localNum(total)} 实例`;
2497
2506
  return `${online === 0 ? "🔴" : "🟡"} ${localNum(online)}/${localNum(total)} 实例在线`;
2498
2507
  };
2499
- /** `名称@包版本[/实现库 v版本]` */
2508
+ /** `名称@包版本[/实现库 v版本]`,名称走人类可读映射 */
2500
2509
  const formatAdapterName = (entry) => {
2501
- const base = `${entry.name}${entry.version ? `@${entry.version}` : ""}`;
2510
+ const base = `${displayAdapterId(entry.name)}${entry.version ? `@${entry.version}` : ""}`;
2502
2511
  if (!entry.impl) return base;
2503
2512
  const impl = `${entry.impl.name}${entry.impl.version ? ` v${entry.impl.version}` : ""}`;
2504
2513
  return `${base}/${impl}`;
@@ -5539,6 +5548,7 @@ exports.defineState = defineState;
5539
5548
  exports.deleteServiceConfig = deleteServiceConfig;
5540
5549
  exports.discoverAdapterCandidates = discoverAdapterCandidates;
5541
5550
  exports.discoverPluginCandidates = discoverPluginCandidates;
5551
+ exports.displayAdapterId = displayAdapterId;
5542
5552
  exports.ensureDataDir = ensureDataDir;
5543
5553
  Object.defineProperty(exports, 'filesize', {
5544
5554
  enumerable: true,