mioku 0.8.18 → 0.8.20

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/cli.cjs CHANGED
@@ -8,7 +8,7 @@ const dedent = require_chunk.__toESM(require("dedent"));
8
8
  const consola = require_chunk.__toESM(require("consola"));
9
9
 
10
10
  //#region package.json
11
- var version = "0.8.18";
11
+ var version = "0.8.19";
12
12
 
13
13
  //#endregion
14
14
  //#region src/cli.ts
@@ -133,41 +133,6 @@ async function installPackage(name, cwd) {
133
133
  return false;
134
134
  }
135
135
  }
136
- async function updatePackage(name, cwd) {
137
- try {
138
- console.log(`执行: bun update ${name}`);
139
- run("bun", ["update", name], { cwd });
140
- consola.default.success(`已更新 ${name}`);
141
- return true;
142
- } catch {
143
- consola.default.error(`更新失败: ${name}`);
144
- return false;
145
- }
146
- }
147
- async function checkUpdates(packages, cwd) {
148
- try {
149
- const output = (0, node_child_process.execFileSync)("bun", [
150
- "pm",
151
- "outdated",
152
- "--json"
153
- ], {
154
- cwd,
155
- encoding: "utf-8",
156
- stdio: "pipe",
157
- shell: process.platform === "win32"
158
- });
159
- if (!output.trim()) {
160
- consola.default.info("所有依赖已是最新版本");
161
- return [];
162
- }
163
- const outdated = JSON.parse(output);
164
- const updates = [];
165
- for (const pkg of packages) if (outdated[pkg]) updates.push(`${pkg}: ${outdated[pkg].current} → ${outdated[pkg].latest}`);
166
- return updates;
167
- } catch {
168
- return [];
169
- }
170
- }
171
136
  async function getInstalledPackages(cwd) {
172
137
  try {
173
138
  const pkgPath = node_path.default.join(cwd, "package.json");
@@ -242,71 +207,64 @@ async function getInstalledPackages(cwd) {
242
207
  case "update": {
243
208
  ensurePackageManager();
244
209
  const cwd = process.cwd();
245
- if (!cmdArgs.length || cmdArgs[0] === "check") {
246
- const packages$1 = await getInstalledPackages(cwd);
247
- const updates = await checkUpdates(packages$1, cwd);
248
- if (updates.length === 0) consola.default.info("所有 mioku 依赖已是最新版本");
249
- else {
250
- console.log("\n可用更新:");
251
- updates.forEach((u) => consola.default.warn(` ${u}`));
252
- console.log("\n运行 npx mioku update all 更新所有包");
253
- }
210
+ const target = cmdArgs[0];
211
+ if (!target || target === "check") {
212
+ run("bun", ["update", "-i"], { cwd });
254
213
  process.exitCode = 0;
255
214
  return;
256
215
  }
257
- const target = cmdArgs[0];
258
216
  if (target === "all") {
259
- const packages$1 = await getInstalledPackages(cwd);
260
- if (packages$1.length === 0) {
261
- consola.default.info("未找到 mioku 相关依赖");
262
- process.exitCode = 0;
263
- return;
264
- }
265
- const updates = await checkUpdates(packages$1, cwd);
266
- if (updates.length === 0) {
267
- consola.default.info("所有 mioku 依赖已是最新版本");
268
- process.exitCode = 0;
269
- return;
270
- }
271
- console.log("\n可用更新:");
272
- updates.forEach((u) => consola.default.warn(` ${u}`));
273
- const confirm$1 = await confirm$1(`确认更新以上 ${updates.length} 个包?`);
274
- if (!confirm$1) gracefullyExit();
275
- await Promise.all(packages$1.map((pkg) => updatePackage(pkg, cwd)));
217
+ console.log("执行: bun update --latest");
218
+ run("bun", ["update", "--latest"], { cwd });
276
219
  process.exitCode = 0;
277
220
  return;
278
221
  }
279
222
  if (target === "self") {
280
- await updatePackage("mioku", cwd);
223
+ console.log("执行: bun update mioku --latest");
224
+ run("bun", [
225
+ "update",
226
+ "mioku",
227
+ "--latest"
228
+ ], { cwd });
281
229
  process.exitCode = 0;
282
230
  return;
283
231
  }
284
232
  if (target === "plugin" || target === "service") {
285
233
  const name = cmdArgs[1];
286
234
  if (!name) {
287
- const packages$1 = await getInstalledPackages(cwd);
235
+ const packages = await getInstalledPackages(cwd);
288
236
  const prefix = target === "plugin" ? PLUGIN_PREFIX : SERVICE_PREFIX;
289
- const filtered = packages$1.filter((p) => p.startsWith(prefix));
237
+ const filtered = packages.filter((p) => p.startsWith(prefix));
290
238
  if (filtered.length === 0) {
291
239
  consola.default.info(`未找到 ${prefix}* 相关依赖`);
292
240
  process.exitCode = 0;
293
241
  return;
294
242
  }
295
- for (const pkg of filtered) await updatePackage(pkg, cwd);
243
+ console.log(`执行: bun update ${filtered.join(" ")} --latest`);
244
+ run("bun", [
245
+ "update",
246
+ ...filtered,
247
+ "--latest"
248
+ ], { cwd });
296
249
  } else {
297
250
  const prefix = target === "plugin" ? PLUGIN_PREFIX : SERVICE_PREFIX;
298
251
  const normalized = name.startsWith(prefix) ? name : `${prefix}${name}`;
299
- await updatePackage(normalized, cwd);
252
+ console.log(`执行: bun update ${normalized} --latest`);
253
+ run("bun", [
254
+ "update",
255
+ normalized,
256
+ "--latest"
257
+ ], { cwd });
300
258
  }
301
259
  process.exitCode = 0;
302
260
  return;
303
261
  }
304
- const packages = await getInstalledPackages(cwd);
305
- if (packages.includes(target)) await updatePackage(target, cwd);
306
- else {
307
- const normalized = normalizePackageName(target);
308
- await updatePackage(normalized, cwd);
309
- }
262
+ console.log(`执行: bun update ${target} --latest`);
263
+ run("bun", [
264
+ "update",
265
+ target,
266
+ "--latest"
267
+ ], { cwd });
310
268
  process.exitCode = 0;
311
269
  return;
312
270
  }
package/dist/cli.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.cjs","names":["cmd: string","args: string[]","options: Parameters<typeof execFileSync>[2]","args","dir: string","err: any","packages: string[]","input: string","input","name: string","cwd?: string","updates: string[]","cwd: string","packages","confirm","cli","fileTree: Record<string, any>","_path: string","message: string","options?: OmitTypeWithRequired<{ initial?: boolean }>","options?: OmitTypeWithRequired<{ default?: string; placeholder?: string }>","fileTree: Record<\n string,\n string | Record<string, string | Record<string, string>>\n >","base: string"],"sources":["../package.json","../src/cli.ts"],"sourcesContent":["{\n \"name\": \"mioku\",\n \"type\": \"module\",\n \"version\": \"0.8.18\",\n \"packageManager\": \"bun@1.2.0\",\n \"description\": \"Mioku - Plugin framework extended from mioki for NapCat OneBot v11\",\n \"keywords\": [\n \"onebot\",\n \"framework\",\n \"bot\",\n \"mioki\",\n \"mioku\"\n ],\n \"bin\": {\n \"mioku\": \"./dist/cli.js\"\n },\n \"engines\": {\n \"node\": \">= 22.18.0\"\n },\n \"homepage\": \"https://github.com/jerryplusy/mioku#readme\",\n \"files\": [\n \"dist\"\n ],\n \"bugs\": {\n \"url\": \"https://github.com/jerryplusy/mioku/issues\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/jerryplusy/mioku.git\",\n \"directory\": \"src/packages/mioku\"\n },\n \"scripts\": {\n \"dev\": \"tsdown -w\",\n \"build\": \"tsdown\"\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 \"mioki\": \"^0.16.0\",\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 \"openai\": \"^4.0.0\",\n \"puppeteer\": \"^23.10.0\",\n \"pretty-ms\": \"^9.3.0\",\n \"string2argv\": \"^1.0.2\",\n \"systeminformation\": \"^5.30.7\",\n \"lodash\": \"^4.17.21\"\n },\n \"devDependencies\": {\n \"@types/lodash\": \"^4.17.0\",\n \"@types/node\": \"^22.0.0\",\n \"@types/puppeteer\": \"^7.0.4\",\n \"tsdown\": \"^0.11.0\",\n \"typescript\": \"^5.8.0\"\n }\n}\n","#!/usr/bin/env node\n\nimport fs, { readFileSync } from \"node:fs\";\nimport { execFileSync } from \"node:child_process\";\nimport mri from \"mri\";\nimport path from \"node:path\";\nimport dedent from \"dedent\";\nimport consola from \"consola\";\nimport { version } from \"../package.json\";\nconst DEFAULT_PACKAGES = [\n \"mioku\",\n \"mioku-plugin-boot\",\n \"mioku-plugin-help\",\n \"mioku-plugin-chat\",\n \"mioku-service-config\",\n \"mioku-service-ai\",\n \"mioku-service-screenshot\",\n \"mioku-service-help\",\n];\n\nconst PLUGIN_PREFIX = \"mioku-plugin-\";\nconst SERVICE_PREFIX = \"mioku-service-\";\n\nconst args = process.argv.slice(2);\n\nfunction run(\n cmd: string,\n args: string[] = [],\n options: Parameters<typeof execFileSync>[2] = {},\n) {\n return execFileSync(cmd, args, {\n stdio: \"inherit\",\n shell: process.platform === \"win32\",\n ...options,\n });\n}\n\nasync 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\ninterface CliOptions {\n name?: string;\n protocol?: string;\n host?: string;\n port?: number;\n token?: string;\n prefix?: string;\n owners?: string;\n admins?: string;\n help?: boolean;\n version?: boolean;\n \"use-npm-mirror\"?: boolean;\n}\n\nfunction hasCommand(cmd: string): boolean {\n try {\n execFileSync(cmd, [\"--version\"], {\n stdio: \"ignore\",\n shell: process.platform === \"win32\",\n });\n return true;\n } catch {\n return false;\n }\n}\n\nfunction findNpmPath(): string | null {\n if (process.platform !== \"win32\") {\n return \"npm\";\n }\n\n const candidates = [\n \"npm.cmd\",\n \"npm.exe\",\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 for (const candidate of candidates) {\n try {\n execFileSync(candidate, [\"--version\"], {\n stdio: \"ignore\",\n shell: true,\n });\n return candidate;\n } catch {}\n }\n\n try {\n const result = execFileSync(\"where\", [\"npm\"], {\n encoding: \"utf-8\",\n shell: true,\n });\n\n const lines = result\n .split(/\\r?\\n/)\n .map((line) => line.trim())\n .filter(Boolean);\n\n const cmdPath = lines.find((line) => line.endsWith(\".cmd\"));\n return cmdPath || lines[0] || null;\n } catch {\n return null;\n }\n}\n\nfunction ensurePackageManager() {\n if (hasCommand(\"bun\")) return;\n\n console.log(\"安装 bun...\");\n\n const npmPath = findNpmPath();\n if (!npmPath) {\n consola.error(\"未找到 npm,请确保 Node.js 已安装并包含 npm\");\n process.exit(1);\n }\n\n run(npmPath, [\"install\", \"-g\", \"bun\"]);\n}\n\nfunction getAddCommand(packages: string[]): [string, string[]] {\n return [\"bun\", [\"add\", ...packages]];\n}\n\nfunction normalizePackageName(input: string): string {\n if (input.startsWith(PLUGIN_PREFIX) || input.startsWith(SERVICE_PREFIX)) {\n return input;\n }\n if (input.startsWith(\"mioku-\")) {\n // 已经是完整名称,如 mioku-plugin-xxx\n return input;\n }\n // 默认当作 plugin 处理\n return `${PLUGIN_PREFIX}${input}`;\n}\n\nfunction 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\nfunction execAdd(packages: string[], cwd?: string) {\n const [cmd, args] = getAddCommand(packages);\n\n console.log(`执行: ${cmd} ${args.join(\" \")}`);\n\n run(cmd, args, {\n cwd,\n });\n}\n\nasync function installPackage(name: string, cwd?: string) {\n const normalized = normalizePackageName(name);\n const type = detectType(normalized);\n if (type === \"unknown\") {\n consola.error(`无法识别的包类型: ${name}`);\n return false;\n }\n try {\n execAdd([normalized], cwd);\n consola.success(`已安装 ${normalized}`);\n return true;\n } catch {\n consola.error(`安装失败: ${normalized}`);\n return false;\n }\n}\n\nasync function updatePackage(name: string, cwd?: string) {\n try {\n console.log(`执行: bun update ${name}`);\n\n run(\"bun\", [\"update\", name], {\n cwd,\n });\n consola.success(`已更新 ${name}`);\n return true;\n } catch {\n consola.error(`更新失败: ${name}`);\n return false;\n }\n}\n\nasync function checkUpdates(packages: string[], cwd?: string) {\n try {\n const output = execFileSync(\"bun\", [\"pm\", \"outdated\", \"--json\"], {\n cwd,\n encoding: \"utf-8\",\n stdio: \"pipe\",\n shell: process.platform === \"win32\",\n });\n if (!output.trim()) {\n consola.info(\"所有依赖已是最新版本\");\n return [];\n }\n const outdated = JSON.parse(output);\n const updates: string[] = [];\n for (const pkg of packages) {\n if (outdated[pkg]) {\n updates.push(\n `${pkg}: ${outdated[pkg].current} → ${outdated[pkg].latest}`,\n );\n }\n }\n return updates;\n } catch {\n return [];\n }\n}\n\nasync function getInstalledPackages(cwd: string): Promise<string[]> {\n try {\n const pkgPath = path.join(cwd, \"package.json\");\n const content = readFileSync(pkgPath, \"utf-8\");\n const pkg = JSON.parse(content);\n const deps = {\n ...pkg.dependencies,\n ...pkg.devDependencies,\n };\n return Object.keys(deps).filter((k) => k.startsWith(\"mioku-\"));\n } catch {\n return [];\n }\n}\n\n(async () => {\n const cli = mri<CliOptions>(args, {\n alias: {\n v: \"version\",\n h: \"help\",\n },\n });\n\n const helpInfo = 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 const [cmd, ...cmdArgs] = args;\n\n switch (cmd) {\n case \"install\": {\n ensurePackageManager();\n const cwd = process.cwd();\n const type = cmdArgs[0];\n const name = cmdArgs[1];\n\n if (!type || !name) {\n consola.error(\n \"请指定类型和名称: mioku install plugin <名称> 或 mioku install service <名称>\",\n );\n console.log(helpInfo);\n process.exitCode = 1;\n return;\n }\n\n if (type !== \"plugin\" && type !== \"service\") {\n consola.error(`无效的类型 \"${type}\",请使用 plugin 或 service`);\n console.log(helpInfo);\n process.exitCode = 1;\n return;\n }\n\n const prefix = type === \"plugin\" ? PLUGIN_PREFIX : SERVICE_PREFIX;\n const normalized = `${prefix}${name}`;\n const success = await installPackage(normalized, cwd);\n process.exitCode = success ? 0 : 1;\n return;\n }\n\n case \"update\": {\n ensurePackageManager();\n const cwd = process.cwd();\n\n if (!cmdArgs.length || cmdArgs[0] === \"check\") {\n // 检查更新\n const packages = await getInstalledPackages(cwd);\n const updates = await checkUpdates(packages, cwd);\n if (updates.length === 0) {\n consola.info(\"所有 mioku 依赖已是最新版本\");\n } else {\n console.log(\"\\n可用更新:\");\n updates.forEach((u) => consola.warn(` ${u}`));\n console.log(\"\\n运行 npx mioku update all 更新所有包\");\n }\n process.exitCode = 0;\n return;\n }\n\n const target = cmdArgs[0];\n\n if (target === \"all\") {\n // 先并发检查所有包的更新\n const packages = await getInstalledPackages(cwd);\n if (packages.length === 0) {\n consola.info(\"未找到 mioku 相关依赖\");\n process.exitCode = 0;\n return;\n }\n\n const updates = await checkUpdates(packages, cwd);\n if (updates.length === 0) {\n consola.info(\"所有 mioku 依赖已是最新版本\");\n process.exitCode = 0;\n return;\n }\n\n console.log(\"\\n可用更新:\");\n updates.forEach((u) => consola.warn(` ${u}`));\n\n const confirm = await confirm(`确认更新以上 ${updates.length} 个包?`);\n if (!confirm) {\n gracefullyExit();\n }\n\n // 并发更新所有包\n await Promise.all(\n packages.map((pkg) => updatePackage(pkg, cwd)),\n );\n process.exitCode = 0;\n return;\n }\n\n if (target === \"self\") {\n await updatePackage(\"mioku\", cwd);\n process.exitCode = 0;\n return;\n }\n\n if (target === \"plugin\" || target === \"service\") {\n // update plugin/service [name]\n const name = cmdArgs[1];\n if (!name) {\n // 更新所有指定类型的包\n const packages = await getInstalledPackages(cwd);\n const prefix = target === \"plugin\" ? PLUGIN_PREFIX : SERVICE_PREFIX;\n const filtered = packages.filter((p) => p.startsWith(prefix));\n if (filtered.length === 0) {\n consola.info(`未找到 ${prefix}* 相关依赖`);\n process.exitCode = 0;\n return;\n }\n for (const pkg of filtered) {\n await updatePackage(pkg, cwd);\n }\n } else {\n const prefix = target === \"plugin\" ? PLUGIN_PREFIX : SERVICE_PREFIX;\n const normalized = name.startsWith(prefix)\n ? name\n : `${prefix}${name}`;\n await updatePackage(normalized, cwd);\n }\n process.exitCode = 0;\n return;\n }\n\n // update xxx - 更新指定包,自动识别前缀\n const packages = await getInstalledPackages(cwd);\n if (packages.includes(target)) {\n await updatePackage(target, cwd);\n } else {\n const normalized = normalizePackageName(target);\n await updatePackage(normalized, cwd);\n }\n process.exitCode = 0;\n return;\n }\n\n default: {\n // 原始交互式项目创建\n const cli = mri<CliOptions>(args, {\n alias: {\n v: \"version\",\n h: \"help\",\n },\n });\n\n switch (true) {\n case cli.version:\n console.log(`v${version}`);\n process.exitCode = 0;\n return;\n // fall through\n\n case cli.help:\n console.log(helpInfo);\n process.exitCode = 0;\n return;\n // fall through\n\n default:\n break;\n }\n\n const name = await input(\"请输入项目名称\", {\n default: \"mioku-bot\",\n placeholder: \"mioku-bot\",\n required: true,\n });\n\n const owners = await input(\n \"请输入主人 QQ (最高权限,英文逗号分隔,必填)\",\n {\n placeholder: \"请输入\",\n default: \"\",\n required: true,\n },\n );\n\n const host = await input(\"请输入 NapCat WS 主机\", {\n default: \"localhost\",\n placeholder: \"localhost\",\n required: true,\n });\n\n const port = parseInt(\n await input(\"请输入 NapCat WS 端口\", {\n default: \"3001\",\n placeholder: \"3001\",\n required: true,\n }),\n );\n\n const token = await input(\"请输入 NapCat WS Token(如无则留空)\", {\n placeholder: \"请输入\",\n });\n\n ensurePackageManager();\n\n const pkgJson = dedent(`\n {\n \"name\": \"${name}\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {},\n \"mioki\": {\n \"prefix\": \"#\",\n \"owners\": [${String(owners)\n .split(\",\")\n .map((o) => o.trim())\n .join(\", \")}],\n \"admins\": [],\n \"plugins\": [\"boot\", \"help\", \"chat\", \"demo\"],\n \"log_level\": \"info\",\n \"online_push\": false,\n \"error_push\": false,\n \"napcat\": [\n {\n \"protocol\": \"ws\",\n \"port\": ${port},\n \"host\": \"${host}\",\n \"token\": \"${token}\"\n }\n ]\n },\n \"scripts\": {\n \"start\": \"bun run app.ts\",\n \"dev\": \"bun run --watch app.ts\"\n }\n }\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, any> = {\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 installWebui = await confirm(\"是否安装 WebUI 管理面板?(建议安装)\", {\n initial: true,\n });\n\n await createNewProject(name, fileTree, installWebui);\n\n console.log(\"\\n若需启动机器人,请运行:\");\n console.log(\" cd\", name);\n console.log(\" bun run start\");\n }\n }\n})();\n\nasync function createNewProject(name: string, fileTree: Record<string, any>, installWebui = false) {\n const projectName = name;\n const projectPath = withRoot(`./${projectName}`);\n\n if (fs.existsSync(projectPath)) {\n const overwrite = await confirm(`项目 ${projectName} 已存在,是否覆盖?`);\n\n if (!overwrite) {\n gracefullyExit();\n }\n\n if (projectPath === process.cwd()) {\n if (fs.readdirSync(projectPath).length !== 0) {\n const confirmOver = await confirm(\n \"项目路径与当前路径相同,将删除当前目录下所有内容再创建,是否继续?\",\n );\n if (!confirmOver) {\n gracefullyExit();\n }\n }\n }\n\n await rmrf(projectPath);\n }\n\n fs.mkdirSync(projectPath, { recursive: true });\n\n makeFileTree(fileTree, projectPath);\n\n console.log(`项目 ${projectName} 创建成功!`);\n\n const packages = installWebui ? DEFAULT_PACKAGES : DEFAULT_PACKAGES.filter(p => p !== \"mioku-service-webui\");\n const [cmd, args] = getAddCommand(packages);\n console.log(`正在安装 Mioku 依赖: ${cmd} ${args.join(\" \")}`);\n run(cmd, args, {\n cwd: projectPath,\n });\n}\n\nfunction gracefullyExit() {\n console.log(\"Bye!\");\n process.exit(0);\n}\n\nfunction withRoot(_path: string) {\n return path.resolve(process.cwd(), _path);\n}\n\ntype OmitTypeWithRequired<T> = Omit<T, \"type\" | \"required\"> & {\n required?: boolean;\n};\n\nasync function confirm(\n message: string,\n options?: OmitTypeWithRequired<{ initial?: boolean }>,\n) {\n return consola.prompt(message, {\n type: \"confirm\",\n cancel: \"reject\",\n ...options,\n });\n}\n\nasync function input(\n message: string,\n options?: OmitTypeWithRequired<{ default?: string; placeholder?: string }>,\n) {\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\nfunction makeFileTree(\n fileTree: Record<\n string,\n string | Record<string, string | Record<string, string>>\n >,\n base: string,\n) {\n for (const [name, content] of Object.entries(fileTree)) {\n if (typeof content === \"object\" && content !== null) {\n const subPath = `${base}/${name}`;\n if (!fs.existsSync(subPath)) {\n fs.mkdirSync(subPath, { recursive: true });\n }\n for (const [subName, subContent] of Object.entries(content)) {\n if (typeof subContent === \"object\") {\n makeFileTree(\n subContent as typeof fileTree,\n path.join(subPath, subName),\n );\n } else {\n fs.writeFileSync(`${subPath}/${subName}`, subContent);\n }\n }\n } else {\n const filePath = `${base}/${name}`;\n const dirname = path.dirname(filePath);\n if (!fs.existsSync(dirname)) {\n fs.mkdirSync(dirname, { recursive: true });\n }\n fs.writeFileSync(filePath, content);\n }\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"cli.cjs","names":["cmd: string","args: string[]","options: Parameters<typeof execFileSync>[2]","args","dir: string","err: any","packages: string[]","input: string","input","name: string","cwd?: string","cwd: string","cli","fileTree: Record<string, any>","_path: string","message: string","options?: OmitTypeWithRequired<{ initial?: boolean }>","options?: OmitTypeWithRequired<{ default?: string; placeholder?: string }>","fileTree: Record<\n string,\n string | Record<string, string | Record<string, string>>\n >","base: string"],"sources":["../package.json","../src/cli.ts"],"sourcesContent":["{\n \"name\": \"mioku\",\n \"type\": \"module\",\n \"version\": \"0.8.19\",\n \"packageManager\": \"bun@1.2.0\",\n \"description\": \"Mioku - Plugin framework extended from mioki for NapCat OneBot v11\",\n \"keywords\": [\n \"onebot\",\n \"framework\",\n \"bot\",\n \"mioki\",\n \"mioku\"\n ],\n \"bin\": {\n \"mioku\": \"./dist/cli.js\"\n },\n \"engines\": {\n \"node\": \">= 22.18.0\"\n },\n \"homepage\": \"https://github.com/jerryplusy/mioku#readme\",\n \"files\": [\n \"dist\"\n ],\n \"bugs\": {\n \"url\": \"https://github.com/jerryplusy/mioku/issues\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/jerryplusy/mioku.git\",\n \"directory\": \"src/packages/mioku\"\n },\n \"scripts\": {\n \"dev\": \"tsdown -w\",\n \"build\": \"tsdown\"\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 \"mioki\": \"^0.16.0\",\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 \"openai\": \"^4.0.0\",\n \"puppeteer\": \"^23.10.0\",\n \"pretty-ms\": \"^9.3.0\",\n \"string2argv\": \"^1.0.2\",\n \"systeminformation\": \"^5.30.7\",\n \"lodash\": \"^4.17.21\"\n },\n \"devDependencies\": {\n \"@types/lodash\": \"^4.17.0\",\n \"@types/node\": \"^22.0.0\",\n \"@types/puppeteer\": \"^7.0.4\",\n \"tsdown\": \"^0.11.0\",\n \"typescript\": \"^5.8.0\"\n }\n}\n","#!/usr/bin/env node\n\nimport fs, { readFileSync } from \"node:fs\";\nimport { execFileSync } from \"node:child_process\";\nimport mri from \"mri\";\nimport path from \"node:path\";\nimport dedent from \"dedent\";\nimport consola from \"consola\";\nimport { version } from \"../package.json\";\nconst DEFAULT_PACKAGES = [\n \"mioku\",\n \"mioku-plugin-boot\",\n \"mioku-plugin-help\",\n \"mioku-plugin-chat\",\n \"mioku-service-config\",\n \"mioku-service-ai\",\n \"mioku-service-screenshot\",\n \"mioku-service-help\",\n];\n\nconst PLUGIN_PREFIX = \"mioku-plugin-\";\nconst SERVICE_PREFIX = \"mioku-service-\";\n\nconst args = process.argv.slice(2);\n\nfunction run(\n cmd: string,\n args: string[] = [],\n options: Parameters<typeof execFileSync>[2] = {},\n) {\n return execFileSync(cmd, args, {\n stdio: \"inherit\",\n shell: process.platform === \"win32\",\n ...options,\n });\n}\n\nasync 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\ninterface CliOptions {\n name?: string;\n protocol?: string;\n host?: string;\n port?: number;\n token?: string;\n prefix?: string;\n owners?: string;\n admins?: string;\n help?: boolean;\n version?: boolean;\n \"use-npm-mirror\"?: boolean;\n}\n\nfunction hasCommand(cmd: string): boolean {\n try {\n execFileSync(cmd, [\"--version\"], {\n stdio: \"ignore\",\n shell: process.platform === \"win32\",\n });\n return true;\n } catch {\n return false;\n }\n}\n\nfunction findNpmPath(): string | null {\n if (process.platform !== \"win32\") {\n return \"npm\";\n }\n\n const candidates = [\n \"npm.cmd\",\n \"npm.exe\",\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 for (const candidate of candidates) {\n try {\n execFileSync(candidate, [\"--version\"], {\n stdio: \"ignore\",\n shell: true,\n });\n return candidate;\n } catch {}\n }\n\n try {\n const result = execFileSync(\"where\", [\"npm\"], {\n encoding: \"utf-8\",\n shell: true,\n });\n\n const lines = result\n .split(/\\r?\\n/)\n .map((line) => line.trim())\n .filter(Boolean);\n\n const cmdPath = lines.find((line) => line.endsWith(\".cmd\"));\n return cmdPath || lines[0] || null;\n } catch {\n return null;\n }\n}\n\nfunction ensurePackageManager() {\n if (hasCommand(\"bun\")) return;\n\n console.log(\"安装 bun...\");\n\n const npmPath = findNpmPath();\n if (!npmPath) {\n consola.error(\"未找到 npm,请确保 Node.js 已安装并包含 npm\");\n process.exit(1);\n }\n\n run(npmPath, [\"install\", \"-g\", \"bun\"]);\n}\n\nfunction getAddCommand(packages: string[]): [string, string[]] {\n return [\"bun\", [\"add\", ...packages]];\n}\n\nfunction normalizePackageName(input: string): string {\n if (input.startsWith(PLUGIN_PREFIX) || input.startsWith(SERVICE_PREFIX)) {\n return input;\n }\n if (input.startsWith(\"mioku-\")) {\n // 已经是完整名称,如 mioku-plugin-xxx\n return input;\n }\n // 默认当作 plugin 处理\n return `${PLUGIN_PREFIX}${input}`;\n}\n\nfunction 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\nfunction execAdd(packages: string[], cwd?: string) {\n const [cmd, args] = getAddCommand(packages);\n\n console.log(`执行: ${cmd} ${args.join(\" \")}`);\n\n run(cmd, args, {\n cwd,\n });\n}\n\nasync function installPackage(name: string, cwd?: string) {\n const normalized = normalizePackageName(name);\n const type = detectType(normalized);\n if (type === \"unknown\") {\n consola.error(`无法识别的包类型: ${name}`);\n return false;\n }\n try {\n execAdd([normalized], cwd);\n consola.success(`已安装 ${normalized}`);\n return true;\n } catch {\n consola.error(`安装失败: ${normalized}`);\n return false;\n }\n}\n\nasync function updatePackage(name: string, cwd?: string) {\n try {\n console.log(`执行: bun update ${name}`);\n\n run(\"bun\", [\"update\", name], {\n cwd,\n });\n consola.success(`已更新 ${name}`);\n return true;\n } catch {\n consola.error(`更新失败: ${name}`);\n return false;\n }\n}\n\nasync function checkUpdates(packages: string[], cwd?: string) {\n const updates: string[] = [];\n for (const pkg of packages) {\n try {\n const latest = execFileSync(\"bun\", [\"info\", pkg, \"version\"], {\n cwd,\n encoding: \"utf-8\",\n stdio: \"pipe\",\n shell: process.platform === \"win32\",\n }).trim();\n if (!latest) continue;\n\n const current = execFileSync(\"bun\", [\"info\", pkg, \"json\"], {\n cwd,\n encoding: \"utf-8\",\n stdio: \"pipe\",\n shell: process.platform === \"win32\",\n }).trim();\n let currentVersion = \"unknown\";\n try {\n const parsed = JSON.parse(current);\n currentVersion = parsed.version || \"unknown\";\n } catch {\n currentVersion = current || \"unknown\";\n }\n\n if (currentVersion !== latest) {\n updates.push(`${pkg}: ${currentVersion} → ${latest}`);\n }\n } catch {\n // skip packages that can't be looked up\n }\n }\n if (updates.length === 0) {\n consola.info(\"所有依赖已是最新版本\");\n }\n return updates;\n}\n\nasync function getInstalledPackages(cwd: string): Promise<string[]> {\n try {\n const pkgPath = path.join(cwd, \"package.json\");\n const content = readFileSync(pkgPath, \"utf-8\");\n const pkg = JSON.parse(content);\n const deps = {\n ...pkg.dependencies,\n ...pkg.devDependencies,\n };\n return Object.keys(deps).filter((k) => k.startsWith(\"mioku-\"));\n } catch {\n return [];\n }\n}\n\n(async () => {\n const cli = mri<CliOptions>(args, {\n alias: {\n v: \"version\",\n h: \"help\",\n },\n });\n\n const helpInfo = 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 const [cmd, ...cmdArgs] = args;\n\n switch (cmd) {\n case \"install\": {\n ensurePackageManager();\n const cwd = process.cwd();\n const type = cmdArgs[0];\n const name = cmdArgs[1];\n\n if (!type || !name) {\n consola.error(\n \"请指定类型和名称: mioku install plugin <名称> 或 mioku install service <名称>\",\n );\n console.log(helpInfo);\n process.exitCode = 1;\n return;\n }\n\n if (type !== \"plugin\" && type !== \"service\") {\n consola.error(`无效的类型 \"${type}\",请使用 plugin 或 service`);\n console.log(helpInfo);\n process.exitCode = 1;\n return;\n }\n\n const prefix = type === \"plugin\" ? PLUGIN_PREFIX : SERVICE_PREFIX;\n const normalized = `${prefix}${name}`;\n const success = await installPackage(normalized, cwd);\n process.exitCode = success ? 0 : 1;\n return;\n }\n\n case \"update\": {\n ensurePackageManager();\n const cwd = process.cwd();\n const target = cmdArgs[0];\n\n if (!target || target === \"check\") {\n // mioku update / mioku update check — 交互式更新\n run(\"bun\", [\"update\", \"-i\"], { cwd });\n process.exitCode = 0;\n return;\n }\n\n if (target === \"all\") {\n // mioku update all — 强制更新所有包到最新\n console.log(\"执行: bun update --latest\");\n run(\"bun\", [\"update\", \"--latest\"], { cwd });\n process.exitCode = 0;\n return;\n }\n\n if (target === \"self\") {\n // mioku update self — 更新 mioku 自身\n console.log(\"执行: bun update mioku --latest\");\n run(\"bun\", [\"update\", \"mioku\", \"--latest\"], { cwd });\n process.exitCode = 0;\n return;\n }\n\n if (target === \"plugin\" || target === \"service\") {\n // update plugin/service [name]\n const name = cmdArgs[1];\n if (!name) {\n // 更新所有指定类型的包\n const packages = await getInstalledPackages(cwd);\n const prefix = target === \"plugin\" ? PLUGIN_PREFIX : SERVICE_PREFIX;\n const filtered = packages.filter((p) => p.startsWith(prefix));\n if (filtered.length === 0) {\n consola.info(`未找到 ${prefix}* 相关依赖`);\n process.exitCode = 0;\n return;\n }\n console.log(`执行: bun update ${filtered.join(\" \")} --latest`);\n run(\"bun\", [\"update\", ...filtered, \"--latest\"], { cwd });\n } else {\n const prefix = target === \"plugin\" ? PLUGIN_PREFIX : SERVICE_PREFIX;\n const normalized = name.startsWith(prefix)\n ? name\n : `${prefix}${name}`;\n console.log(`执行: bun update ${normalized} --latest`);\n run(\"bun\", [\"update\", normalized, \"--latest\"], { cwd });\n }\n process.exitCode = 0;\n return;\n }\n\n // update xxx - 更新指定包\n console.log(`执行: bun update ${target} --latest`);\n run(\"bun\", [\"update\", target, \"--latest\"], { cwd });\n process.exitCode = 0;\n return;\n }\n\n default: {\n // 原始交互式项目创建\n const cli = mri<CliOptions>(args, {\n alias: {\n v: \"version\",\n h: \"help\",\n },\n });\n\n switch (true) {\n case cli.version:\n console.log(`v${version}`);\n process.exitCode = 0;\n return;\n // fall through\n\n case cli.help:\n console.log(helpInfo);\n process.exitCode = 0;\n return;\n // fall through\n\n default:\n break;\n }\n\n const name = await input(\"请输入项目名称\", {\n default: \"mioku-bot\",\n placeholder: \"mioku-bot\",\n required: true,\n });\n\n const owners = await input(\n \"请输入主人 QQ (最高权限,英文逗号分隔,必填)\",\n {\n placeholder: \"请输入\",\n default: \"\",\n required: true,\n },\n );\n\n const host = await input(\"请输入 NapCat WS 主机\", {\n default: \"localhost\",\n placeholder: \"localhost\",\n required: true,\n });\n\n const port = parseInt(\n await input(\"请输入 NapCat WS 端口\", {\n default: \"3001\",\n placeholder: \"3001\",\n required: true,\n }),\n );\n\n const token = await input(\"请输入 NapCat WS Token(如无则留空)\", {\n placeholder: \"请输入\",\n });\n\n ensurePackageManager();\n\n const pkgJson = dedent(`\n {\n \"name\": \"${name}\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {},\n \"mioki\": {\n \"prefix\": \"#\",\n \"owners\": [${String(owners)\n .split(\",\")\n .map((o) => o.trim())\n .join(\", \")}],\n \"admins\": [],\n \"plugins\": [\"boot\", \"help\", \"chat\", \"demo\"],\n \"log_level\": \"info\",\n \"online_push\": false,\n \"error_push\": false,\n \"napcat\": [\n {\n \"protocol\": \"ws\",\n \"port\": ${port},\n \"host\": \"${host}\",\n \"token\": \"${token}\"\n }\n ]\n },\n \"scripts\": {\n \"start\": \"bun run app.ts\",\n \"dev\": \"bun run --watch app.ts\"\n }\n }\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, any> = {\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 installWebui = await confirm(\"是否安装 WebUI 管理面板?(建议安装)\", {\n initial: true,\n });\n\n await createNewProject(name, fileTree, installWebui);\n\n console.log(\"\\n若需启动机器人,请运行:\");\n console.log(\" cd\", name);\n console.log(\" bun run start\");\n }\n }\n})();\n\nasync function createNewProject(name: string, fileTree: Record<string, any>, installWebui = false) {\n const projectName = name;\n const projectPath = withRoot(`./${projectName}`);\n\n if (fs.existsSync(projectPath)) {\n const overwrite = await confirm(`项目 ${projectName} 已存在,是否覆盖?`);\n\n if (!overwrite) {\n gracefullyExit();\n }\n\n if (projectPath === process.cwd()) {\n if (fs.readdirSync(projectPath).length !== 0) {\n const confirmOver = await confirm(\n \"项目路径与当前路径相同,将删除当前目录下所有内容再创建,是否继续?\",\n );\n if (!confirmOver) {\n gracefullyExit();\n }\n }\n }\n\n await rmrf(projectPath);\n }\n\n fs.mkdirSync(projectPath, { recursive: true });\n\n makeFileTree(fileTree, projectPath);\n\n console.log(`项目 ${projectName} 创建成功!`);\n\n const packages = installWebui ? DEFAULT_PACKAGES : DEFAULT_PACKAGES.filter(p => p !== \"mioku-service-webui\");\n const [cmd, args] = getAddCommand(packages);\n console.log(`正在安装 Mioku 依赖: ${cmd} ${args.join(\" \")}`);\n run(cmd, args, {\n cwd: projectPath,\n });\n}\n\nfunction gracefullyExit() {\n console.log(\"Bye!\");\n process.exit(0);\n}\n\nfunction withRoot(_path: string) {\n return path.resolve(process.cwd(), _path);\n}\n\ntype OmitTypeWithRequired<T> = Omit<T, \"type\" | \"required\"> & {\n required?: boolean;\n};\n\nasync 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\nasync 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\nfunction makeFileTree(\n fileTree: Record<\n string,\n string | Record<string, string | Record<string, string>>\n >,\n base: string,\n) {\n for (const [name, content] of Object.entries(fileTree)) {\n if (typeof content === \"object\" && content !== null) {\n const subPath = `${base}/${name}`;\n if (!fs.existsSync(subPath)) {\n fs.mkdirSync(subPath, { recursive: true });\n }\n for (const [subName, subContent] of Object.entries(content)) {\n if (typeof subContent === \"object\") {\n makeFileTree(\n subContent as typeof fileTree,\n path.join(subPath, subName),\n );\n } else {\n fs.writeFileSync(`${subPath}/${subName}`, subContent);\n }\n }\n } else {\n const filePath = `${base}/${name}`;\n const dirname = path.dirname(filePath);\n if (!fs.existsSync(dirname)) {\n fs.mkdirSync(dirname, { recursive: true });\n }\n fs.writeFileSync(filePath, content);\n }\n }\n}\n"],"mappings":"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"}
package/dist/cli.js CHANGED
@@ -7,7 +7,7 @@ import dedent from "dedent";
7
7
  import consola from "consola";
8
8
 
9
9
  //#region package.json
10
- var version = "0.8.18";
10
+ var version = "0.8.19";
11
11
 
12
12
  //#endregion
13
13
  //#region src/cli.ts
@@ -132,41 +132,6 @@ async function installPackage(name, cwd) {
132
132
  return false;
133
133
  }
134
134
  }
135
- async function updatePackage(name, cwd) {
136
- try {
137
- console.log(`执行: bun update ${name}`);
138
- run("bun", ["update", name], { cwd });
139
- consola.success(`已更新 ${name}`);
140
- return true;
141
- } catch {
142
- consola.error(`更新失败: ${name}`);
143
- return false;
144
- }
145
- }
146
- async function checkUpdates(packages, cwd) {
147
- try {
148
- const output = execFileSync("bun", [
149
- "pm",
150
- "outdated",
151
- "--json"
152
- ], {
153
- cwd,
154
- encoding: "utf-8",
155
- stdio: "pipe",
156
- shell: process.platform === "win32"
157
- });
158
- if (!output.trim()) {
159
- consola.info("所有依赖已是最新版本");
160
- return [];
161
- }
162
- const outdated = JSON.parse(output);
163
- const updates = [];
164
- for (const pkg of packages) if (outdated[pkg]) updates.push(`${pkg}: ${outdated[pkg].current} → ${outdated[pkg].latest}`);
165
- return updates;
166
- } catch {
167
- return [];
168
- }
169
- }
170
135
  async function getInstalledPackages(cwd) {
171
136
  try {
172
137
  const pkgPath = path.join(cwd, "package.json");
@@ -241,71 +206,64 @@ async function getInstalledPackages(cwd) {
241
206
  case "update": {
242
207
  ensurePackageManager();
243
208
  const cwd = process.cwd();
244
- if (!cmdArgs.length || cmdArgs[0] === "check") {
245
- const packages$1 = await getInstalledPackages(cwd);
246
- const updates = await checkUpdates(packages$1, cwd);
247
- if (updates.length === 0) consola.info("所有 mioku 依赖已是最新版本");
248
- else {
249
- console.log("\n可用更新:");
250
- updates.forEach((u) => consola.warn(` ${u}`));
251
- console.log("\n运行 npx mioku update all 更新所有包");
252
- }
209
+ const target = cmdArgs[0];
210
+ if (!target || target === "check") {
211
+ run("bun", ["update", "-i"], { cwd });
253
212
  process.exitCode = 0;
254
213
  return;
255
214
  }
256
- const target = cmdArgs[0];
257
215
  if (target === "all") {
258
- const packages$1 = await getInstalledPackages(cwd);
259
- if (packages$1.length === 0) {
260
- consola.info("未找到 mioku 相关依赖");
261
- process.exitCode = 0;
262
- return;
263
- }
264
- const updates = await checkUpdates(packages$1, cwd);
265
- if (updates.length === 0) {
266
- consola.info("所有 mioku 依赖已是最新版本");
267
- process.exitCode = 0;
268
- return;
269
- }
270
- console.log("\n可用更新:");
271
- updates.forEach((u) => consola.warn(` ${u}`));
272
- const confirm$1 = await confirm$1(`确认更新以上 ${updates.length} 个包?`);
273
- if (!confirm$1) gracefullyExit();
274
- await Promise.all(packages$1.map((pkg) => updatePackage(pkg, cwd)));
216
+ console.log("执行: bun update --latest");
217
+ run("bun", ["update", "--latest"], { cwd });
275
218
  process.exitCode = 0;
276
219
  return;
277
220
  }
278
221
  if (target === "self") {
279
- await updatePackage("mioku", cwd);
222
+ console.log("执行: bun update mioku --latest");
223
+ run("bun", [
224
+ "update",
225
+ "mioku",
226
+ "--latest"
227
+ ], { cwd });
280
228
  process.exitCode = 0;
281
229
  return;
282
230
  }
283
231
  if (target === "plugin" || target === "service") {
284
232
  const name = cmdArgs[1];
285
233
  if (!name) {
286
- const packages$1 = await getInstalledPackages(cwd);
234
+ const packages = await getInstalledPackages(cwd);
287
235
  const prefix = target === "plugin" ? PLUGIN_PREFIX : SERVICE_PREFIX;
288
- const filtered = packages$1.filter((p) => p.startsWith(prefix));
236
+ const filtered = packages.filter((p) => p.startsWith(prefix));
289
237
  if (filtered.length === 0) {
290
238
  consola.info(`未找到 ${prefix}* 相关依赖`);
291
239
  process.exitCode = 0;
292
240
  return;
293
241
  }
294
- for (const pkg of filtered) await updatePackage(pkg, cwd);
242
+ console.log(`执行: bun update ${filtered.join(" ")} --latest`);
243
+ run("bun", [
244
+ "update",
245
+ ...filtered,
246
+ "--latest"
247
+ ], { cwd });
295
248
  } else {
296
249
  const prefix = target === "plugin" ? PLUGIN_PREFIX : SERVICE_PREFIX;
297
250
  const normalized = name.startsWith(prefix) ? name : `${prefix}${name}`;
298
- await updatePackage(normalized, cwd);
251
+ console.log(`执行: bun update ${normalized} --latest`);
252
+ run("bun", [
253
+ "update",
254
+ normalized,
255
+ "--latest"
256
+ ], { cwd });
299
257
  }
300
258
  process.exitCode = 0;
301
259
  return;
302
260
  }
303
- const packages = await getInstalledPackages(cwd);
304
- if (packages.includes(target)) await updatePackage(target, cwd);
305
- else {
306
- const normalized = normalizePackageName(target);
307
- await updatePackage(normalized, cwd);
308
- }
261
+ console.log(`执行: bun update ${target} --latest`);
262
+ run("bun", [
263
+ "update",
264
+ target,
265
+ "--latest"
266
+ ], { cwd });
309
267
  process.exitCode = 0;
310
268
  return;
311
269
  }
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","names":["cmd: string","args: string[]","options: Parameters<typeof execFileSync>[2]","args","dir: string","err: any","packages: string[]","input: string","input","name: string","cwd?: string","updates: string[]","cwd: string","packages","confirm","cli","fileTree: Record<string, any>","_path: string","message: string","options?: OmitTypeWithRequired<{ initial?: boolean }>","options?: OmitTypeWithRequired<{ default?: string; placeholder?: string }>","fileTree: Record<\n string,\n string | Record<string, string | Record<string, string>>\n >","base: string"],"sources":["../package.json","../src/cli.ts"],"sourcesContent":["{\n \"name\": \"mioku\",\n \"type\": \"module\",\n \"version\": \"0.8.18\",\n \"packageManager\": \"bun@1.2.0\",\n \"description\": \"Mioku - Plugin framework extended from mioki for NapCat OneBot v11\",\n \"keywords\": [\n \"onebot\",\n \"framework\",\n \"bot\",\n \"mioki\",\n \"mioku\"\n ],\n \"bin\": {\n \"mioku\": \"./dist/cli.js\"\n },\n \"engines\": {\n \"node\": \">= 22.18.0\"\n },\n \"homepage\": \"https://github.com/jerryplusy/mioku#readme\",\n \"files\": [\n \"dist\"\n ],\n \"bugs\": {\n \"url\": \"https://github.com/jerryplusy/mioku/issues\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/jerryplusy/mioku.git\",\n \"directory\": \"src/packages/mioku\"\n },\n \"scripts\": {\n \"dev\": \"tsdown -w\",\n \"build\": \"tsdown\"\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 \"mioki\": \"^0.16.0\",\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 \"openai\": \"^4.0.0\",\n \"puppeteer\": \"^23.10.0\",\n \"pretty-ms\": \"^9.3.0\",\n \"string2argv\": \"^1.0.2\",\n \"systeminformation\": \"^5.30.7\",\n \"lodash\": \"^4.17.21\"\n },\n \"devDependencies\": {\n \"@types/lodash\": \"^4.17.0\",\n \"@types/node\": \"^22.0.0\",\n \"@types/puppeteer\": \"^7.0.4\",\n \"tsdown\": \"^0.11.0\",\n \"typescript\": \"^5.8.0\"\n }\n}\n","#!/usr/bin/env node\n\nimport fs, { readFileSync } from \"node:fs\";\nimport { execFileSync } from \"node:child_process\";\nimport mri from \"mri\";\nimport path from \"node:path\";\nimport dedent from \"dedent\";\nimport consola from \"consola\";\nimport { version } from \"../package.json\";\nconst DEFAULT_PACKAGES = [\n \"mioku\",\n \"mioku-plugin-boot\",\n \"mioku-plugin-help\",\n \"mioku-plugin-chat\",\n \"mioku-service-config\",\n \"mioku-service-ai\",\n \"mioku-service-screenshot\",\n \"mioku-service-help\",\n];\n\nconst PLUGIN_PREFIX = \"mioku-plugin-\";\nconst SERVICE_PREFIX = \"mioku-service-\";\n\nconst args = process.argv.slice(2);\n\nfunction run(\n cmd: string,\n args: string[] = [],\n options: Parameters<typeof execFileSync>[2] = {},\n) {\n return execFileSync(cmd, args, {\n stdio: \"inherit\",\n shell: process.platform === \"win32\",\n ...options,\n });\n}\n\nasync 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\ninterface CliOptions {\n name?: string;\n protocol?: string;\n host?: string;\n port?: number;\n token?: string;\n prefix?: string;\n owners?: string;\n admins?: string;\n help?: boolean;\n version?: boolean;\n \"use-npm-mirror\"?: boolean;\n}\n\nfunction hasCommand(cmd: string): boolean {\n try {\n execFileSync(cmd, [\"--version\"], {\n stdio: \"ignore\",\n shell: process.platform === \"win32\",\n });\n return true;\n } catch {\n return false;\n }\n}\n\nfunction findNpmPath(): string | null {\n if (process.platform !== \"win32\") {\n return \"npm\";\n }\n\n const candidates = [\n \"npm.cmd\",\n \"npm.exe\",\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 for (const candidate of candidates) {\n try {\n execFileSync(candidate, [\"--version\"], {\n stdio: \"ignore\",\n shell: true,\n });\n return candidate;\n } catch {}\n }\n\n try {\n const result = execFileSync(\"where\", [\"npm\"], {\n encoding: \"utf-8\",\n shell: true,\n });\n\n const lines = result\n .split(/\\r?\\n/)\n .map((line) => line.trim())\n .filter(Boolean);\n\n const cmdPath = lines.find((line) => line.endsWith(\".cmd\"));\n return cmdPath || lines[0] || null;\n } catch {\n return null;\n }\n}\n\nfunction ensurePackageManager() {\n if (hasCommand(\"bun\")) return;\n\n console.log(\"安装 bun...\");\n\n const npmPath = findNpmPath();\n if (!npmPath) {\n consola.error(\"未找到 npm,请确保 Node.js 已安装并包含 npm\");\n process.exit(1);\n }\n\n run(npmPath, [\"install\", \"-g\", \"bun\"]);\n}\n\nfunction getAddCommand(packages: string[]): [string, string[]] {\n return [\"bun\", [\"add\", ...packages]];\n}\n\nfunction normalizePackageName(input: string): string {\n if (input.startsWith(PLUGIN_PREFIX) || input.startsWith(SERVICE_PREFIX)) {\n return input;\n }\n if (input.startsWith(\"mioku-\")) {\n // 已经是完整名称,如 mioku-plugin-xxx\n return input;\n }\n // 默认当作 plugin 处理\n return `${PLUGIN_PREFIX}${input}`;\n}\n\nfunction 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\nfunction execAdd(packages: string[], cwd?: string) {\n const [cmd, args] = getAddCommand(packages);\n\n console.log(`执行: ${cmd} ${args.join(\" \")}`);\n\n run(cmd, args, {\n cwd,\n });\n}\n\nasync function installPackage(name: string, cwd?: string) {\n const normalized = normalizePackageName(name);\n const type = detectType(normalized);\n if (type === \"unknown\") {\n consola.error(`无法识别的包类型: ${name}`);\n return false;\n }\n try {\n execAdd([normalized], cwd);\n consola.success(`已安装 ${normalized}`);\n return true;\n } catch {\n consola.error(`安装失败: ${normalized}`);\n return false;\n }\n}\n\nasync function updatePackage(name: string, cwd?: string) {\n try {\n console.log(`执行: bun update ${name}`);\n\n run(\"bun\", [\"update\", name], {\n cwd,\n });\n consola.success(`已更新 ${name}`);\n return true;\n } catch {\n consola.error(`更新失败: ${name}`);\n return false;\n }\n}\n\nasync function checkUpdates(packages: string[], cwd?: string) {\n try {\n const output = execFileSync(\"bun\", [\"pm\", \"outdated\", \"--json\"], {\n cwd,\n encoding: \"utf-8\",\n stdio: \"pipe\",\n shell: process.platform === \"win32\",\n });\n if (!output.trim()) {\n consola.info(\"所有依赖已是最新版本\");\n return [];\n }\n const outdated = JSON.parse(output);\n const updates: string[] = [];\n for (const pkg of packages) {\n if (outdated[pkg]) {\n updates.push(\n `${pkg}: ${outdated[pkg].current} → ${outdated[pkg].latest}`,\n );\n }\n }\n return updates;\n } catch {\n return [];\n }\n}\n\nasync function getInstalledPackages(cwd: string): Promise<string[]> {\n try {\n const pkgPath = path.join(cwd, \"package.json\");\n const content = readFileSync(pkgPath, \"utf-8\");\n const pkg = JSON.parse(content);\n const deps = {\n ...pkg.dependencies,\n ...pkg.devDependencies,\n };\n return Object.keys(deps).filter((k) => k.startsWith(\"mioku-\"));\n } catch {\n return [];\n }\n}\n\n(async () => {\n const cli = mri<CliOptions>(args, {\n alias: {\n v: \"version\",\n h: \"help\",\n },\n });\n\n const helpInfo = 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 const [cmd, ...cmdArgs] = args;\n\n switch (cmd) {\n case \"install\": {\n ensurePackageManager();\n const cwd = process.cwd();\n const type = cmdArgs[0];\n const name = cmdArgs[1];\n\n if (!type || !name) {\n consola.error(\n \"请指定类型和名称: mioku install plugin <名称> 或 mioku install service <名称>\",\n );\n console.log(helpInfo);\n process.exitCode = 1;\n return;\n }\n\n if (type !== \"plugin\" && type !== \"service\") {\n consola.error(`无效的类型 \"${type}\",请使用 plugin 或 service`);\n console.log(helpInfo);\n process.exitCode = 1;\n return;\n }\n\n const prefix = type === \"plugin\" ? PLUGIN_PREFIX : SERVICE_PREFIX;\n const normalized = `${prefix}${name}`;\n const success = await installPackage(normalized, cwd);\n process.exitCode = success ? 0 : 1;\n return;\n }\n\n case \"update\": {\n ensurePackageManager();\n const cwd = process.cwd();\n\n if (!cmdArgs.length || cmdArgs[0] === \"check\") {\n // 检查更新\n const packages = await getInstalledPackages(cwd);\n const updates = await checkUpdates(packages, cwd);\n if (updates.length === 0) {\n consola.info(\"所有 mioku 依赖已是最新版本\");\n } else {\n console.log(\"\\n可用更新:\");\n updates.forEach((u) => consola.warn(` ${u}`));\n console.log(\"\\n运行 npx mioku update all 更新所有包\");\n }\n process.exitCode = 0;\n return;\n }\n\n const target = cmdArgs[0];\n\n if (target === \"all\") {\n // 先并发检查所有包的更新\n const packages = await getInstalledPackages(cwd);\n if (packages.length === 0) {\n consola.info(\"未找到 mioku 相关依赖\");\n process.exitCode = 0;\n return;\n }\n\n const updates = await checkUpdates(packages, cwd);\n if (updates.length === 0) {\n consola.info(\"所有 mioku 依赖已是最新版本\");\n process.exitCode = 0;\n return;\n }\n\n console.log(\"\\n可用更新:\");\n updates.forEach((u) => consola.warn(` ${u}`));\n\n const confirm = await confirm(`确认更新以上 ${updates.length} 个包?`);\n if (!confirm) {\n gracefullyExit();\n }\n\n // 并发更新所有包\n await Promise.all(\n packages.map((pkg) => updatePackage(pkg, cwd)),\n );\n process.exitCode = 0;\n return;\n }\n\n if (target === \"self\") {\n await updatePackage(\"mioku\", cwd);\n process.exitCode = 0;\n return;\n }\n\n if (target === \"plugin\" || target === \"service\") {\n // update plugin/service [name]\n const name = cmdArgs[1];\n if (!name) {\n // 更新所有指定类型的包\n const packages = await getInstalledPackages(cwd);\n const prefix = target === \"plugin\" ? PLUGIN_PREFIX : SERVICE_PREFIX;\n const filtered = packages.filter((p) => p.startsWith(prefix));\n if (filtered.length === 0) {\n consola.info(`未找到 ${prefix}* 相关依赖`);\n process.exitCode = 0;\n return;\n }\n for (const pkg of filtered) {\n await updatePackage(pkg, cwd);\n }\n } else {\n const prefix = target === \"plugin\" ? PLUGIN_PREFIX : SERVICE_PREFIX;\n const normalized = name.startsWith(prefix)\n ? name\n : `${prefix}${name}`;\n await updatePackage(normalized, cwd);\n }\n process.exitCode = 0;\n return;\n }\n\n // update xxx - 更新指定包,自动识别前缀\n const packages = await getInstalledPackages(cwd);\n if (packages.includes(target)) {\n await updatePackage(target, cwd);\n } else {\n const normalized = normalizePackageName(target);\n await updatePackage(normalized, cwd);\n }\n process.exitCode = 0;\n return;\n }\n\n default: {\n // 原始交互式项目创建\n const cli = mri<CliOptions>(args, {\n alias: {\n v: \"version\",\n h: \"help\",\n },\n });\n\n switch (true) {\n case cli.version:\n console.log(`v${version}`);\n process.exitCode = 0;\n return;\n // fall through\n\n case cli.help:\n console.log(helpInfo);\n process.exitCode = 0;\n return;\n // fall through\n\n default:\n break;\n }\n\n const name = await input(\"请输入项目名称\", {\n default: \"mioku-bot\",\n placeholder: \"mioku-bot\",\n required: true,\n });\n\n const owners = await input(\n \"请输入主人 QQ (最高权限,英文逗号分隔,必填)\",\n {\n placeholder: \"请输入\",\n default: \"\",\n required: true,\n },\n );\n\n const host = await input(\"请输入 NapCat WS 主机\", {\n default: \"localhost\",\n placeholder: \"localhost\",\n required: true,\n });\n\n const port = parseInt(\n await input(\"请输入 NapCat WS 端口\", {\n default: \"3001\",\n placeholder: \"3001\",\n required: true,\n }),\n );\n\n const token = await input(\"请输入 NapCat WS Token(如无则留空)\", {\n placeholder: \"请输入\",\n });\n\n ensurePackageManager();\n\n const pkgJson = dedent(`\n {\n \"name\": \"${name}\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {},\n \"mioki\": {\n \"prefix\": \"#\",\n \"owners\": [${String(owners)\n .split(\",\")\n .map((o) => o.trim())\n .join(\", \")}],\n \"admins\": [],\n \"plugins\": [\"boot\", \"help\", \"chat\", \"demo\"],\n \"log_level\": \"info\",\n \"online_push\": false,\n \"error_push\": false,\n \"napcat\": [\n {\n \"protocol\": \"ws\",\n \"port\": ${port},\n \"host\": \"${host}\",\n \"token\": \"${token}\"\n }\n ]\n },\n \"scripts\": {\n \"start\": \"bun run app.ts\",\n \"dev\": \"bun run --watch app.ts\"\n }\n }\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, any> = {\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 installWebui = await confirm(\"是否安装 WebUI 管理面板?(建议安装)\", {\n initial: true,\n });\n\n await createNewProject(name, fileTree, installWebui);\n\n console.log(\"\\n若需启动机器人,请运行:\");\n console.log(\" cd\", name);\n console.log(\" bun run start\");\n }\n }\n})();\n\nasync function createNewProject(name: string, fileTree: Record<string, any>, installWebui = false) {\n const projectName = name;\n const projectPath = withRoot(`./${projectName}`);\n\n if (fs.existsSync(projectPath)) {\n const overwrite = await confirm(`项目 ${projectName} 已存在,是否覆盖?`);\n\n if (!overwrite) {\n gracefullyExit();\n }\n\n if (projectPath === process.cwd()) {\n if (fs.readdirSync(projectPath).length !== 0) {\n const confirmOver = await confirm(\n \"项目路径与当前路径相同,将删除当前目录下所有内容再创建,是否继续?\",\n );\n if (!confirmOver) {\n gracefullyExit();\n }\n }\n }\n\n await rmrf(projectPath);\n }\n\n fs.mkdirSync(projectPath, { recursive: true });\n\n makeFileTree(fileTree, projectPath);\n\n console.log(`项目 ${projectName} 创建成功!`);\n\n const packages = installWebui ? DEFAULT_PACKAGES : DEFAULT_PACKAGES.filter(p => p !== \"mioku-service-webui\");\n const [cmd, args] = getAddCommand(packages);\n console.log(`正在安装 Mioku 依赖: ${cmd} ${args.join(\" \")}`);\n run(cmd, args, {\n cwd: projectPath,\n });\n}\n\nfunction gracefullyExit() {\n console.log(\"Bye!\");\n process.exit(0);\n}\n\nfunction withRoot(_path: string) {\n return path.resolve(process.cwd(), _path);\n}\n\ntype OmitTypeWithRequired<T> = Omit<T, \"type\" | \"required\"> & {\n required?: boolean;\n};\n\nasync function confirm(\n message: string,\n options?: OmitTypeWithRequired<{ initial?: boolean }>,\n) {\n return consola.prompt(message, {\n type: \"confirm\",\n cancel: \"reject\",\n ...options,\n });\n}\n\nasync function input(\n message: string,\n options?: OmitTypeWithRequired<{ default?: string; placeholder?: string }>,\n) {\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\nfunction makeFileTree(\n fileTree: Record<\n string,\n string | Record<string, string | Record<string, string>>\n >,\n base: string,\n) {\n for (const [name, content] of Object.entries(fileTree)) {\n if (typeof content === \"object\" && content !== null) {\n const subPath = `${base}/${name}`;\n if (!fs.existsSync(subPath)) {\n fs.mkdirSync(subPath, { recursive: true });\n }\n for (const [subName, subContent] of Object.entries(content)) {\n if (typeof subContent === \"object\") {\n makeFileTree(\n subContent as typeof fileTree,\n path.join(subPath, subName),\n );\n } else {\n fs.writeFileSync(`${subPath}/${subName}`, subContent);\n }\n }\n } else {\n const filePath = `${base}/${name}`;\n const dirname = path.dirname(filePath);\n if (!fs.existsSync(dirname)) {\n fs.mkdirSync(dirname, { recursive: true });\n }\n fs.writeFileSync(filePath, content);\n }\n }\n}\n"],"mappings":";;;;;;;;;cAGa;;;;ACMb,MAAM,mBAAmB;CACvB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACD;AAED,MAAM,gBAAgB;AACtB,MAAM,iBAAiB;AAEvB,MAAM,OAAO,QAAQ,KAAK,MAAM,EAAE;AAElC,SAAS,IACPA,KACAC,SAAiB,CAAE,GACnBC,UAA8C,CAAE,GAChD;AACA,QAAO,aAAa,KAAKC,QAAM;EAC7B,OAAO;EACP,OAAO,QAAQ,aAAa;EAC5B,GAAG;CACJ,EAAC;AACH;AAED,eAAe,KAAKC,KAAa,UAAU,GAAkB;AAC3D,MAAK,IAAI,IAAI,GAAG,IAAI,SAAS,IAC3B,KAAI;AACF,KAAG,OAAO,KAAK;GAAE,WAAW;GAAM,OAAO;EAAM,EAAC;AAChD;CACD,SAAQC,KAAU;AACjB,MAAI,MAAM,UAAU,EAAG,OAAM;EAC7B,MAAM,OAAO,KAAK;AAClB,MACE,SAAS,WACT,SAAS,WACT,SAAS,eACT,SAAS,SAET,OAAM,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,OAAO,IAAI,GAAG;MAEjE,OAAM;CAET;AAEJ;AAgBD,SAAS,WAAWL,KAAsB;AACxC,KAAI;AACF,eAAa,KAAK,CAAC,WAAY,GAAE;GAC/B,OAAO;GACP,OAAO,QAAQ,aAAa;EAC7B,EAAC;AACF,SAAO;CACR,QAAO;AACN,SAAO;CACR;AACF;AAED,SAAS,cAA6B;AACpC,KAAI,QAAQ,aAAa,QACvB,QAAO;CAGT,MAAM,aAAa;EACjB;EACA;EACA,KAAK,KAAK,QAAQ,IAAI,gBAAgB,IAAI,UAAU,UAAU;EAC9D,KAAK,KAAK,QAAQ,IAAI,wBAAwB,IAAI,UAAU,UAAU;EACtE,KAAK,KAAK,QAAQ,IAAI,WAAW,IAAI,OAAO,UAAU;CACvD;AAED,MAAK,MAAM,aAAa,WACtB,KAAI;AACF,eAAa,WAAW,CAAC,WAAY,GAAE;GACrC,OAAO;GACP,OAAO;EACR,EAAC;AACF,SAAO;CACR,QAAO,CAAE;AAGZ,KAAI;EACF,MAAM,SAAS,aAAa,SAAS,CAAC,KAAM,GAAE;GAC5C,UAAU;GACV,OAAO;EACR,EAAC;EAEF,MAAM,QAAQ,OACX,MAAM,QAAQ,CACd,IAAI,CAAC,SAAS,KAAK,MAAM,CAAC,CAC1B,OAAO,QAAQ;EAElB,MAAM,UAAU,MAAM,KAAK,CAAC,SAAS,KAAK,SAAS,OAAO,CAAC;AAC3D,SAAO,WAAW,MAAM,MAAM;CAC/B,QAAO;AACN,SAAO;CACR;AACF;AAED,SAAS,uBAAuB;AAC9B,KAAI,WAAW,MAAM,CAAE;AAEvB,SAAQ,IAAI,YAAY;CAExB,MAAM,UAAU,aAAa;AAC7B,MAAK,SAAS;AACZ,UAAQ,MAAM,iCAAiC;AAC/C,UAAQ,KAAK,EAAE;CAChB;AAED,KAAI,SAAS;EAAC;EAAW;EAAM;CAAM,EAAC;AACvC;AAED,SAAS,cAAcM,UAAwC;AAC7D,QAAO,CAAC,OAAO,CAAC,OAAO,GAAG,QAAS,CAAC;AACrC;AAED,SAAS,qBAAqBC,SAAuB;AACnD,KAAI,QAAM,WAAW,cAAc,IAAI,QAAM,WAAW,eAAe,CACrE,QAAOC;AAET,KAAI,QAAM,WAAW,SAAS,CAE5B,QAAOA;AAGT,SAAQ,EAAE,cAAc,EAAEA,QAAM;AACjC;AAED,SAAS,WAAWC,MAAgD;AAClE,KAAI,KAAK,WAAW,cAAc,CAAE,QAAO;AAC3C,KAAI,KAAK,WAAW,eAAe,CAAE,QAAO;AAC5C,QAAO;AACR;AAED,SAAS,QAAQH,UAAoBI,KAAc;CACjD,MAAM,CAAC,KAAKP,OAAK,GAAG,cAAc,SAAS;AAE3C,SAAQ,KAAK,MAAM,IAAI,GAAG,OAAK,KAAK,IAAI,CAAC,EAAE;AAE3C,KAAI,KAAKA,QAAM,EACb,IACD,EAAC;AACH;AAED,eAAe,eAAeM,MAAcC,KAAc;CACxD,MAAM,aAAa,qBAAqB,KAAK;CAC7C,MAAM,OAAO,WAAW,WAAW;AACnC,KAAI,SAAS,WAAW;AACtB,UAAQ,OAAO,YAAY,KAAK,EAAE;AAClC,SAAO;CACR;AACD,KAAI;AACF,UAAQ,CAAC,UAAW,GAAE,IAAI;AAC1B,UAAQ,SAAS,MAAM,WAAW,EAAE;AACpC,SAAO;CACR,QAAO;AACN,UAAQ,OAAO,QAAQ,WAAW,EAAE;AACpC,SAAO;CACR;AACF;AAED,eAAe,cAAcD,MAAcC,KAAc;AACvD,KAAI;AACF,UAAQ,KAAK,iBAAiB,KAAK,EAAE;AAErC,MAAI,OAAO,CAAC,UAAU,IAAK,GAAE,EAC3B,IACD,EAAC;AACF,UAAQ,SAAS,MAAM,KAAK,EAAE;AAC9B,SAAO;CACR,QAAO;AACN,UAAQ,OAAO,QAAQ,KAAK,EAAE;AAC9B,SAAO;CACR;AACF;AAED,eAAe,aAAaJ,UAAoBI,KAAc;AAC5D,KAAI;EACF,MAAM,SAAS,aAAa,OAAO;GAAC;GAAM;GAAY;EAAS,GAAE;GAC/D;GACA,UAAU;GACV,OAAO;GACP,OAAO,QAAQ,aAAa;EAC7B,EAAC;AACF,OAAK,OAAO,MAAM,EAAE;AAClB,WAAQ,KAAK,aAAa;AAC1B,UAAO,CAAE;EACV;EACD,MAAM,WAAW,KAAK,MAAM,OAAO;EACnC,MAAMC,UAAoB,CAAE;AAC5B,OAAK,MAAM,OAAO,SAChB,KAAI,SAAS,KACX,SAAQ,MACL,EAAE,IAAI,IAAI,SAAS,KAAK,QAAQ,KAAK,SAAS,KAAK,OAAO,EAC5D;AAGL,SAAO;CACR,QAAO;AACN,SAAO,CAAE;CACV;AACF;AAED,eAAe,qBAAqBC,KAAgC;AAClE,KAAI;EACF,MAAM,UAAU,KAAK,KAAK,KAAK,eAAe;EAC9C,MAAM,UAAU,aAAa,SAAS,QAAQ;EAC9C,MAAM,MAAM,KAAK,MAAM,QAAQ;EAC/B,MAAM,OAAO;GACX,GAAG,IAAI;GACP,GAAG,IAAI;EACR;AACD,SAAO,OAAO,KAAK,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,WAAW,SAAS,CAAC;CAC/D,QAAO;AACN,SAAO,CAAE;CACV;AACF;AAED,CAAC,YAAY;CACX,MAAM,MAAM,IAAgB,MAAM,EAChC,OAAO;EACL,GAAG;EACH,GAAG;CACJ,EACF,EAAC;CAEF,MAAM,WAAW,QAAQ;iBACV,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;IAyBrB;CAEF,MAAM,CAAC,KAAK,GAAG,QAAQ,GAAG;AAE1B,SAAQ,KAAR;EACE,KAAK,WAAW;AACd,yBAAsB;GACtB,MAAM,MAAM,QAAQ,KAAK;GACzB,MAAM,OAAO,QAAQ;GACrB,MAAM,OAAO,QAAQ;AAErB,QAAK,SAAS,MAAM;AAClB,YAAQ,MACN,mEACD;AACD,YAAQ,IAAI,SAAS;AACrB,YAAQ,WAAW;AACnB;GACD;AAED,OAAI,SAAS,YAAY,SAAS,WAAW;AAC3C,YAAQ,OAAO,SAAS,KAAK,wBAAwB;AACrD,YAAQ,IAAI,SAAS;AACrB,YAAQ,WAAW;AACnB;GACD;GAED,MAAM,SAAS,SAAS,WAAW,gBAAgB;GACnD,MAAM,cAAc,EAAE,OAAO,EAAE,KAAK;GACpC,MAAM,UAAU,MAAM,eAAe,YAAY,IAAI;AACrD,WAAQ,WAAW,UAAU,IAAI;AACjC;EACD;EAED,KAAK,UAAU;AACb,yBAAsB;GACtB,MAAM,MAAM,QAAQ,KAAK;AAEzB,QAAK,QAAQ,UAAU,QAAQ,OAAO,SAAS;IAE7C,MAAMC,aAAW,MAAM,qBAAqB,IAAI;IAChD,MAAM,UAAU,MAAM,aAAaA,YAAU,IAAI;AACjD,QAAI,QAAQ,WAAW,EACrB,SAAQ,KAAK,oBAAoB;SAC5B;AACL,aAAQ,IAAI,UAAU;AACtB,aAAQ,QAAQ,CAAC,MAAM,QAAQ,MAAM,IAAI,EAAE,EAAE,CAAC;AAC9C,aAAQ,IAAI,kCAAkC;IAC/C;AACD,YAAQ,WAAW;AACnB;GACD;GAED,MAAM,SAAS,QAAQ;AAEvB,OAAI,WAAW,OAAO;IAEpB,MAAMA,aAAW,MAAM,qBAAqB,IAAI;AAChD,QAAIA,WAAS,WAAW,GAAG;AACzB,aAAQ,KAAK,iBAAiB;AAC9B,aAAQ,WAAW;AACnB;IACD;IAED,MAAM,UAAU,MAAM,aAAaA,YAAU,IAAI;AACjD,QAAI,QAAQ,WAAW,GAAG;AACxB,aAAQ,KAAK,oBAAoB;AACjC,aAAQ,WAAW;AACnB;IACD;AAED,YAAQ,IAAI,UAAU;AACtB,YAAQ,QAAQ,CAAC,MAAM,QAAQ,MAAM,IAAI,EAAE,EAAE,CAAC;IAE9C,MAAMC,YAAU,MAAM,WAAS,SAAS,QAAQ,OAAO,MAAM;AAC7D,SAAKA,UACH,iBAAgB;AAIlB,UAAM,QAAQ,IACZ,WAAS,IAAI,CAAC,QAAQ,cAAc,KAAK,IAAI,CAAC,CAC/C;AACD,YAAQ,WAAW;AACnB;GACD;AAED,OAAI,WAAW,QAAQ;AACrB,UAAM,cAAc,SAAS,IAAI;AACjC,YAAQ,WAAW;AACnB;GACD;AAED,OAAI,WAAW,YAAY,WAAW,WAAW;IAE/C,MAAM,OAAO,QAAQ;AACrB,SAAK,MAAM;KAET,MAAMD,aAAW,MAAM,qBAAqB,IAAI;KAChD,MAAM,SAAS,WAAW,WAAW,gBAAgB;KACrD,MAAM,WAAW,WAAS,OAAO,CAAC,MAAM,EAAE,WAAW,OAAO,CAAC;AAC7D,SAAI,SAAS,WAAW,GAAG;AACzB,cAAQ,MAAM,MAAM,OAAO,QAAQ;AACnC,cAAQ,WAAW;AACnB;KACD;AACD,UAAK,MAAM,OAAO,SAChB,OAAM,cAAc,KAAK,IAAI;IAEhC,OAAM;KACL,MAAM,SAAS,WAAW,WAAW,gBAAgB;KACrD,MAAM,aAAa,KAAK,WAAW,OAAO,GACtC,QACC,EAAE,OAAO,EAAE,KAAK;AACrB,WAAM,cAAc,YAAY,IAAI;IACrC;AACD,YAAQ,WAAW;AACnB;GACD;GAGD,MAAM,WAAW,MAAM,qBAAqB,IAAI;AAChD,OAAI,SAAS,SAAS,OAAO,CAC3B,OAAM,cAAc,QAAQ,IAAI;QAC3B;IACL,MAAM,aAAa,qBAAqB,OAAO;AAC/C,UAAM,cAAc,YAAY,IAAI;GACrC;AACD,WAAQ,WAAW;AACnB;EACD;EAED,SAAS;GAEP,MAAME,QAAM,IAAgB,MAAM,EAChC,OAAO;IACL,GAAG;IACH,GAAG;GACJ,EACF,EAAC;AAEF,WAAQ,MAAR;IACE,KAAKA,MAAI;AACP,aAAQ,KAAK,GAAG,QAAQ,EAAE;AAC1B,aAAQ,WAAW;AACnB;IAGF,KAAKA,MAAI;AACP,aAAQ,IAAI,SAAS;AACrB,aAAQ,WAAW;AACnB;IAGF,QACE;GACH;GAED,MAAM,OAAO,MAAM,MAAM,WAAW;IAClC,SAAS;IACT,aAAa;IACb,UAAU;GACX,EAAC;GAEF,MAAM,SAAS,MAAM,MACnB,6BACA;IACE,aAAa;IACb,SAAS;IACT,UAAU;GACX,EACF;GAED,MAAM,OAAO,MAAM,MAAM,oBAAoB;IAC3C,SAAS;IACT,aAAa;IACb,UAAU;GACX,EAAC;GAEF,MAAM,OAAO,SACX,MAAM,MAAM,oBAAoB;IAC9B,SAAS;IACT,aAAa;IACb,UAAU;GACX,EAAC,CACH;GAED,MAAM,QAAQ,MAAM,MAAM,8BAA8B,EACtD,aAAa,MACd,EAAC;AAEF,yBAAsB;GAEtB,MAAM,UAAU,QAAQ;;mBAEX,KAAK;;;;;;uBAMD,OAAO,OAAO,CACxB,MAAM,IAAI,CACV,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,CACpB,KAAK,KAAK,CAAC;;;;;;;;;wBASA,KAAK;yBACJ,KAAK;0BACJ,MAAM;;;;;;;;;EAS9B;GAEI,MAAM,aAAa,QAAQ;;;;;oBAKb,QAAQ;;;;;;;;;;;;;;;EAe1B;GAEI,MAAMC,WAAgC;IACpC,UACE;IACF,gBAAgB;IAChB,SAAS,EAAE,MAAM,EAAE,YAAY,WAAY,EAAE;IAC7C,QAAQ,CAAE;IACV,MAAM,CAAE;GACT;GAED,MAAM,eAAe,MAAM,QAAQ,0BAA0B,EAC3D,SAAS,KACV,EAAC;AAEF,SAAM,iBAAiB,MAAM,UAAU,aAAa;AAEpD,WAAQ,IAAI,iBAAiB;AAC7B,WAAQ,IAAI,QAAQ,KAAK;AACzB,WAAQ,IAAI,kBAAkB;EAC/B;CACF;AACF,IAAG;AAEJ,eAAe,iBAAiBP,MAAcO,UAA+B,eAAe,OAAO;CACjG,MAAM,cAAc;CACpB,MAAM,cAAc,UAAU,IAAI,YAAY,EAAE;AAEhD,KAAI,GAAG,WAAW,YAAY,EAAE;EAC9B,MAAM,YAAY,MAAM,SAAS,KAAK,YAAY,YAAY;AAE9D,OAAK,UACH,iBAAgB;AAGlB,MAAI,gBAAgB,QAAQ,KAAK,EAC/B;OAAI,GAAG,YAAY,YAAY,CAAC,WAAW,GAAG;IAC5C,MAAM,cAAc,MAAM,QACxB,oCACD;AACD,SAAK,YACH,iBAAgB;GAEnB;;AAGH,QAAM,KAAK,YAAY;CACxB;AAED,IAAG,UAAU,aAAa,EAAE,WAAW,KAAM,EAAC;AAE9C,cAAa,UAAU,YAAY;AAEnC,SAAQ,KAAK,KAAK,YAAY,QAAQ;CAEtC,MAAM,WAAW,eAAe,mBAAmB,iBAAiB,OAAO,OAAK,MAAM,sBAAsB;CAC5G,MAAM,CAAC,KAAKb,OAAK,GAAG,cAAc,SAAS;AAC3C,SAAQ,KAAK,iBAAiB,IAAI,GAAG,OAAK,KAAK,IAAI,CAAC,EAAE;AACtD,KAAI,KAAKA,QAAM,EACb,KAAK,YACN,EAAC;AACH;AAED,SAAS,iBAAiB;AACxB,SAAQ,IAAI,OAAO;AACnB,SAAQ,KAAK,EAAE;AAChB;AAED,SAAS,SAASc,OAAe;AAC/B,QAAO,KAAK,QAAQ,QAAQ,KAAK,EAAE,MAAM;AAC1C;AAMD,eAAe,QACbC,SACAC,SACA;AACA,QAAO,QAAQ,OAAO,SAAS;EAC7B,MAAM;EACN,QAAQ;EACR,GAAG;CACJ,EAAC;AACH;AAED,eAAe,MACbD,SACAE,SACA;CACA,MAAM,SAAS,MAAM,QAAQ,OAAO,SAAS;EAC3C,MAAM;EACN,QAAQ;EACR,GAAG;CACJ,EAAC;AACF,KAAI,SAAS,aAAa,OAAQ,QAAO,MAAM,SAAS,QAAQ;AAChE,QAAO;AACR;AAED,SAAS,aACPC,UAIAC,MACA;AACA,MAAK,MAAM,CAAC,MAAM,QAAQ,IAAI,OAAO,QAAQ,SAAS,CACpD,YAAW,YAAY,YAAY,YAAY,MAAM;EACnD,MAAM,WAAW,EAAE,KAAK,GAAG,KAAK;AAChC,OAAK,GAAG,WAAW,QAAQ,CACzB,IAAG,UAAU,SAAS,EAAE,WAAW,KAAM,EAAC;AAE5C,OAAK,MAAM,CAAC,SAAS,WAAW,IAAI,OAAO,QAAQ,QAAQ,CACzD,YAAW,eAAe,SACxB,cACE,YACA,KAAK,KAAK,SAAS,QAAQ,CAC5B;MAED,IAAG,eAAe,EAAE,QAAQ,GAAG,QAAQ,GAAG,WAAW;CAG1D,OAAM;EACL,MAAM,YAAY,EAAE,KAAK,GAAG,KAAK;EACjC,MAAM,UAAU,KAAK,QAAQ,SAAS;AACtC,OAAK,GAAG,WAAW,QAAQ,CACzB,IAAG,UAAU,SAAS,EAAE,WAAW,KAAM,EAAC;AAE5C,KAAG,cAAc,UAAU,QAAQ;CACpC;AAEJ"}
1
+ {"version":3,"file":"cli.js","names":["cmd: string","args: string[]","options: Parameters<typeof execFileSync>[2]","args","dir: string","err: any","packages: string[]","input: string","input","name: string","cwd?: string","cwd: string","cli","fileTree: Record<string, any>","_path: string","message: string","options?: OmitTypeWithRequired<{ initial?: boolean }>","options?: OmitTypeWithRequired<{ default?: string; placeholder?: string }>","fileTree: Record<\n string,\n string | Record<string, string | Record<string, string>>\n >","base: string"],"sources":["../package.json","../src/cli.ts"],"sourcesContent":["{\n \"name\": \"mioku\",\n \"type\": \"module\",\n \"version\": \"0.8.19\",\n \"packageManager\": \"bun@1.2.0\",\n \"description\": \"Mioku - Plugin framework extended from mioki for NapCat OneBot v11\",\n \"keywords\": [\n \"onebot\",\n \"framework\",\n \"bot\",\n \"mioki\",\n \"mioku\"\n ],\n \"bin\": {\n \"mioku\": \"./dist/cli.js\"\n },\n \"engines\": {\n \"node\": \">= 22.18.0\"\n },\n \"homepage\": \"https://github.com/jerryplusy/mioku#readme\",\n \"files\": [\n \"dist\"\n ],\n \"bugs\": {\n \"url\": \"https://github.com/jerryplusy/mioku/issues\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/jerryplusy/mioku.git\",\n \"directory\": \"src/packages/mioku\"\n },\n \"scripts\": {\n \"dev\": \"tsdown -w\",\n \"build\": \"tsdown\"\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 \"mioki\": \"^0.16.0\",\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 \"openai\": \"^4.0.0\",\n \"puppeteer\": \"^23.10.0\",\n \"pretty-ms\": \"^9.3.0\",\n \"string2argv\": \"^1.0.2\",\n \"systeminformation\": \"^5.30.7\",\n \"lodash\": \"^4.17.21\"\n },\n \"devDependencies\": {\n \"@types/lodash\": \"^4.17.0\",\n \"@types/node\": \"^22.0.0\",\n \"@types/puppeteer\": \"^7.0.4\",\n \"tsdown\": \"^0.11.0\",\n \"typescript\": \"^5.8.0\"\n }\n}\n","#!/usr/bin/env node\n\nimport fs, { readFileSync } from \"node:fs\";\nimport { execFileSync } from \"node:child_process\";\nimport mri from \"mri\";\nimport path from \"node:path\";\nimport dedent from \"dedent\";\nimport consola from \"consola\";\nimport { version } from \"../package.json\";\nconst DEFAULT_PACKAGES = [\n \"mioku\",\n \"mioku-plugin-boot\",\n \"mioku-plugin-help\",\n \"mioku-plugin-chat\",\n \"mioku-service-config\",\n \"mioku-service-ai\",\n \"mioku-service-screenshot\",\n \"mioku-service-help\",\n];\n\nconst PLUGIN_PREFIX = \"mioku-plugin-\";\nconst SERVICE_PREFIX = \"mioku-service-\";\n\nconst args = process.argv.slice(2);\n\nfunction run(\n cmd: string,\n args: string[] = [],\n options: Parameters<typeof execFileSync>[2] = {},\n) {\n return execFileSync(cmd, args, {\n stdio: \"inherit\",\n shell: process.platform === \"win32\",\n ...options,\n });\n}\n\nasync 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\ninterface CliOptions {\n name?: string;\n protocol?: string;\n host?: string;\n port?: number;\n token?: string;\n prefix?: string;\n owners?: string;\n admins?: string;\n help?: boolean;\n version?: boolean;\n \"use-npm-mirror\"?: boolean;\n}\n\nfunction hasCommand(cmd: string): boolean {\n try {\n execFileSync(cmd, [\"--version\"], {\n stdio: \"ignore\",\n shell: process.platform === \"win32\",\n });\n return true;\n } catch {\n return false;\n }\n}\n\nfunction findNpmPath(): string | null {\n if (process.platform !== \"win32\") {\n return \"npm\";\n }\n\n const candidates = [\n \"npm.cmd\",\n \"npm.exe\",\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 for (const candidate of candidates) {\n try {\n execFileSync(candidate, [\"--version\"], {\n stdio: \"ignore\",\n shell: true,\n });\n return candidate;\n } catch {}\n }\n\n try {\n const result = execFileSync(\"where\", [\"npm\"], {\n encoding: \"utf-8\",\n shell: true,\n });\n\n const lines = result\n .split(/\\r?\\n/)\n .map((line) => line.trim())\n .filter(Boolean);\n\n const cmdPath = lines.find((line) => line.endsWith(\".cmd\"));\n return cmdPath || lines[0] || null;\n } catch {\n return null;\n }\n}\n\nfunction ensurePackageManager() {\n if (hasCommand(\"bun\")) return;\n\n console.log(\"安装 bun...\");\n\n const npmPath = findNpmPath();\n if (!npmPath) {\n consola.error(\"未找到 npm,请确保 Node.js 已安装并包含 npm\");\n process.exit(1);\n }\n\n run(npmPath, [\"install\", \"-g\", \"bun\"]);\n}\n\nfunction getAddCommand(packages: string[]): [string, string[]] {\n return [\"bun\", [\"add\", ...packages]];\n}\n\nfunction normalizePackageName(input: string): string {\n if (input.startsWith(PLUGIN_PREFIX) || input.startsWith(SERVICE_PREFIX)) {\n return input;\n }\n if (input.startsWith(\"mioku-\")) {\n // 已经是完整名称,如 mioku-plugin-xxx\n return input;\n }\n // 默认当作 plugin 处理\n return `${PLUGIN_PREFIX}${input}`;\n}\n\nfunction 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\nfunction execAdd(packages: string[], cwd?: string) {\n const [cmd, args] = getAddCommand(packages);\n\n console.log(`执行: ${cmd} ${args.join(\" \")}`);\n\n run(cmd, args, {\n cwd,\n });\n}\n\nasync function installPackage(name: string, cwd?: string) {\n const normalized = normalizePackageName(name);\n const type = detectType(normalized);\n if (type === \"unknown\") {\n consola.error(`无法识别的包类型: ${name}`);\n return false;\n }\n try {\n execAdd([normalized], cwd);\n consola.success(`已安装 ${normalized}`);\n return true;\n } catch {\n consola.error(`安装失败: ${normalized}`);\n return false;\n }\n}\n\nasync function updatePackage(name: string, cwd?: string) {\n try {\n console.log(`执行: bun update ${name}`);\n\n run(\"bun\", [\"update\", name], {\n cwd,\n });\n consola.success(`已更新 ${name}`);\n return true;\n } catch {\n consola.error(`更新失败: ${name}`);\n return false;\n }\n}\n\nasync function checkUpdates(packages: string[], cwd?: string) {\n const updates: string[] = [];\n for (const pkg of packages) {\n try {\n const latest = execFileSync(\"bun\", [\"info\", pkg, \"version\"], {\n cwd,\n encoding: \"utf-8\",\n stdio: \"pipe\",\n shell: process.platform === \"win32\",\n }).trim();\n if (!latest) continue;\n\n const current = execFileSync(\"bun\", [\"info\", pkg, \"json\"], {\n cwd,\n encoding: \"utf-8\",\n stdio: \"pipe\",\n shell: process.platform === \"win32\",\n }).trim();\n let currentVersion = \"unknown\";\n try {\n const parsed = JSON.parse(current);\n currentVersion = parsed.version || \"unknown\";\n } catch {\n currentVersion = current || \"unknown\";\n }\n\n if (currentVersion !== latest) {\n updates.push(`${pkg}: ${currentVersion} → ${latest}`);\n }\n } catch {\n // skip packages that can't be looked up\n }\n }\n if (updates.length === 0) {\n consola.info(\"所有依赖已是最新版本\");\n }\n return updates;\n}\n\nasync function getInstalledPackages(cwd: string): Promise<string[]> {\n try {\n const pkgPath = path.join(cwd, \"package.json\");\n const content = readFileSync(pkgPath, \"utf-8\");\n const pkg = JSON.parse(content);\n const deps = {\n ...pkg.dependencies,\n ...pkg.devDependencies,\n };\n return Object.keys(deps).filter((k) => k.startsWith(\"mioku-\"));\n } catch {\n return [];\n }\n}\n\n(async () => {\n const cli = mri<CliOptions>(args, {\n alias: {\n v: \"version\",\n h: \"help\",\n },\n });\n\n const helpInfo = 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 const [cmd, ...cmdArgs] = args;\n\n switch (cmd) {\n case \"install\": {\n ensurePackageManager();\n const cwd = process.cwd();\n const type = cmdArgs[0];\n const name = cmdArgs[1];\n\n if (!type || !name) {\n consola.error(\n \"请指定类型和名称: mioku install plugin <名称> 或 mioku install service <名称>\",\n );\n console.log(helpInfo);\n process.exitCode = 1;\n return;\n }\n\n if (type !== \"plugin\" && type !== \"service\") {\n consola.error(`无效的类型 \"${type}\",请使用 plugin 或 service`);\n console.log(helpInfo);\n process.exitCode = 1;\n return;\n }\n\n const prefix = type === \"plugin\" ? PLUGIN_PREFIX : SERVICE_PREFIX;\n const normalized = `${prefix}${name}`;\n const success = await installPackage(normalized, cwd);\n process.exitCode = success ? 0 : 1;\n return;\n }\n\n case \"update\": {\n ensurePackageManager();\n const cwd = process.cwd();\n const target = cmdArgs[0];\n\n if (!target || target === \"check\") {\n // mioku update / mioku update check — 交互式更新\n run(\"bun\", [\"update\", \"-i\"], { cwd });\n process.exitCode = 0;\n return;\n }\n\n if (target === \"all\") {\n // mioku update all — 强制更新所有包到最新\n console.log(\"执行: bun update --latest\");\n run(\"bun\", [\"update\", \"--latest\"], { cwd });\n process.exitCode = 0;\n return;\n }\n\n if (target === \"self\") {\n // mioku update self — 更新 mioku 自身\n console.log(\"执行: bun update mioku --latest\");\n run(\"bun\", [\"update\", \"mioku\", \"--latest\"], { cwd });\n process.exitCode = 0;\n return;\n }\n\n if (target === \"plugin\" || target === \"service\") {\n // update plugin/service [name]\n const name = cmdArgs[1];\n if (!name) {\n // 更新所有指定类型的包\n const packages = await getInstalledPackages(cwd);\n const prefix = target === \"plugin\" ? PLUGIN_PREFIX : SERVICE_PREFIX;\n const filtered = packages.filter((p) => p.startsWith(prefix));\n if (filtered.length === 0) {\n consola.info(`未找到 ${prefix}* 相关依赖`);\n process.exitCode = 0;\n return;\n }\n console.log(`执行: bun update ${filtered.join(\" \")} --latest`);\n run(\"bun\", [\"update\", ...filtered, \"--latest\"], { cwd });\n } else {\n const prefix = target === \"plugin\" ? PLUGIN_PREFIX : SERVICE_PREFIX;\n const normalized = name.startsWith(prefix)\n ? name\n : `${prefix}${name}`;\n console.log(`执行: bun update ${normalized} --latest`);\n run(\"bun\", [\"update\", normalized, \"--latest\"], { cwd });\n }\n process.exitCode = 0;\n return;\n }\n\n // update xxx - 更新指定包\n console.log(`执行: bun update ${target} --latest`);\n run(\"bun\", [\"update\", target, \"--latest\"], { cwd });\n process.exitCode = 0;\n return;\n }\n\n default: {\n // 原始交互式项目创建\n const cli = mri<CliOptions>(args, {\n alias: {\n v: \"version\",\n h: \"help\",\n },\n });\n\n switch (true) {\n case cli.version:\n console.log(`v${version}`);\n process.exitCode = 0;\n return;\n // fall through\n\n case cli.help:\n console.log(helpInfo);\n process.exitCode = 0;\n return;\n // fall through\n\n default:\n break;\n }\n\n const name = await input(\"请输入项目名称\", {\n default: \"mioku-bot\",\n placeholder: \"mioku-bot\",\n required: true,\n });\n\n const owners = await input(\n \"请输入主人 QQ (最高权限,英文逗号分隔,必填)\",\n {\n placeholder: \"请输入\",\n default: \"\",\n required: true,\n },\n );\n\n const host = await input(\"请输入 NapCat WS 主机\", {\n default: \"localhost\",\n placeholder: \"localhost\",\n required: true,\n });\n\n const port = parseInt(\n await input(\"请输入 NapCat WS 端口\", {\n default: \"3001\",\n placeholder: \"3001\",\n required: true,\n }),\n );\n\n const token = await input(\"请输入 NapCat WS Token(如无则留空)\", {\n placeholder: \"请输入\",\n });\n\n ensurePackageManager();\n\n const pkgJson = dedent(`\n {\n \"name\": \"${name}\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {},\n \"mioki\": {\n \"prefix\": \"#\",\n \"owners\": [${String(owners)\n .split(\",\")\n .map((o) => o.trim())\n .join(\", \")}],\n \"admins\": [],\n \"plugins\": [\"boot\", \"help\", \"chat\", \"demo\"],\n \"log_level\": \"info\",\n \"online_push\": false,\n \"error_push\": false,\n \"napcat\": [\n {\n \"protocol\": \"ws\",\n \"port\": ${port},\n \"host\": \"${host}\",\n \"token\": \"${token}\"\n }\n ]\n },\n \"scripts\": {\n \"start\": \"bun run app.ts\",\n \"dev\": \"bun run --watch app.ts\"\n }\n }\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, any> = {\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 installWebui = await confirm(\"是否安装 WebUI 管理面板?(建议安装)\", {\n initial: true,\n });\n\n await createNewProject(name, fileTree, installWebui);\n\n console.log(\"\\n若需启动机器人,请运行:\");\n console.log(\" cd\", name);\n console.log(\" bun run start\");\n }\n }\n})();\n\nasync function createNewProject(name: string, fileTree: Record<string, any>, installWebui = false) {\n const projectName = name;\n const projectPath = withRoot(`./${projectName}`);\n\n if (fs.existsSync(projectPath)) {\n const overwrite = await confirm(`项目 ${projectName} 已存在,是否覆盖?`);\n\n if (!overwrite) {\n gracefullyExit();\n }\n\n if (projectPath === process.cwd()) {\n if (fs.readdirSync(projectPath).length !== 0) {\n const confirmOver = await confirm(\n \"项目路径与当前路径相同,将删除当前目录下所有内容再创建,是否继续?\",\n );\n if (!confirmOver) {\n gracefullyExit();\n }\n }\n }\n\n await rmrf(projectPath);\n }\n\n fs.mkdirSync(projectPath, { recursive: true });\n\n makeFileTree(fileTree, projectPath);\n\n console.log(`项目 ${projectName} 创建成功!`);\n\n const packages = installWebui ? DEFAULT_PACKAGES : DEFAULT_PACKAGES.filter(p => p !== \"mioku-service-webui\");\n const [cmd, args] = getAddCommand(packages);\n console.log(`正在安装 Mioku 依赖: ${cmd} ${args.join(\" \")}`);\n run(cmd, args, {\n cwd: projectPath,\n });\n}\n\nfunction gracefullyExit() {\n console.log(\"Bye!\");\n process.exit(0);\n}\n\nfunction withRoot(_path: string) {\n return path.resolve(process.cwd(), _path);\n}\n\ntype OmitTypeWithRequired<T> = Omit<T, \"type\" | \"required\"> & {\n required?: boolean;\n};\n\nasync 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\nasync 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\nfunction makeFileTree(\n fileTree: Record<\n string,\n string | Record<string, string | Record<string, string>>\n >,\n base: string,\n) {\n for (const [name, content] of Object.entries(fileTree)) {\n if (typeof content === \"object\" && content !== null) {\n const subPath = `${base}/${name}`;\n if (!fs.existsSync(subPath)) {\n fs.mkdirSync(subPath, { recursive: true });\n }\n for (const [subName, subContent] of Object.entries(content)) {\n if (typeof subContent === \"object\") {\n makeFileTree(\n subContent as typeof fileTree,\n path.join(subPath, subName),\n );\n } else {\n fs.writeFileSync(`${subPath}/${subName}`, subContent);\n }\n }\n } else {\n const filePath = `${base}/${name}`;\n const dirname = path.dirname(filePath);\n if (!fs.existsSync(dirname)) {\n fs.mkdirSync(dirname, { recursive: true });\n }\n fs.writeFileSync(filePath, content);\n }\n }\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "mioku",
3
3
  "type": "module",
4
- "version": "0.8.18",
4
+ "version": "0.8.20",
5
5
  "packageManager": "bun@1.2.0",
6
6
  "description": "Mioku - Plugin framework extended from mioki for NapCat OneBot v11",
7
7
  "keywords": [