mioku 0.8.1 → 0.8.3
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 +70 -36
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +71 -37
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -9,7 +9,7 @@ const dedent = require_chunk.__toESM(require("dedent"));
|
|
|
9
9
|
const consola = require_chunk.__toESM(require("consola"));
|
|
10
10
|
|
|
11
11
|
//#region package.json
|
|
12
|
-
var version = "0.8.
|
|
12
|
+
var version = "0.8.2";
|
|
13
13
|
|
|
14
14
|
//#endregion
|
|
15
15
|
//#region src/cli.ts
|
|
@@ -26,9 +26,15 @@ const DEFAULT_PACKAGES = [
|
|
|
26
26
|
const PLUGIN_PREFIX = "mioku-plugin-";
|
|
27
27
|
const SERVICE_PREFIX = "mioku-service-";
|
|
28
28
|
const args = process.argv.slice(2);
|
|
29
|
+
function run(cmd, args$1 = [], options = {}) {
|
|
30
|
+
return (0, node_child_process.execFileSync)(cmd, args$1, {
|
|
31
|
+
stdio: "inherit",
|
|
32
|
+
...options
|
|
33
|
+
});
|
|
34
|
+
}
|
|
29
35
|
function commandExists(cmd) {
|
|
30
36
|
try {
|
|
31
|
-
(0, node_child_process.
|
|
37
|
+
(0, node_child_process.execFileSync)("which", [cmd], { stdio: "ignore" });
|
|
32
38
|
return true;
|
|
33
39
|
} catch {
|
|
34
40
|
return false;
|
|
@@ -37,10 +43,14 @@ function commandExists(cmd) {
|
|
|
37
43
|
function ensurePackageManager() {
|
|
38
44
|
if (commandExists("bun")) return;
|
|
39
45
|
console.log("安装 bun...");
|
|
40
|
-
(
|
|
46
|
+
run("npm", [
|
|
47
|
+
"install",
|
|
48
|
+
"-g",
|
|
49
|
+
"bun"
|
|
50
|
+
]);
|
|
41
51
|
}
|
|
42
52
|
function getAddCommand(packages) {
|
|
43
|
-
return
|
|
53
|
+
return ["bun", ["add", ...packages]];
|
|
44
54
|
}
|
|
45
55
|
function normalizePackageName(input$1) {
|
|
46
56
|
if (input$1.startsWith(PLUGIN_PREFIX) || input$1.startsWith(SERVICE_PREFIX)) return input$1;
|
|
@@ -54,10 +64,14 @@ function detectType(name) {
|
|
|
54
64
|
}
|
|
55
65
|
async function installWebUIDist(projectPath) {
|
|
56
66
|
consola.default.info("正在安装 WebUI...");
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
67
|
+
try {
|
|
68
|
+
run("bun", ["add", "mioku-service-webui"], {
|
|
69
|
+
cwd: projectPath,
|
|
70
|
+
stdio: "ignore"
|
|
71
|
+
});
|
|
72
|
+
} catch {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
61
75
|
const nodeModulesWebui = node_path.default.join(projectPath, "node_modules", "mioku-service-webui");
|
|
62
76
|
const targetDist = node_path.default.join(nodeModulesWebui, "dist");
|
|
63
77
|
try {
|
|
@@ -76,7 +90,15 @@ async function installWebUIDist(projectPath) {
|
|
|
76
90
|
const tmpZip = node_path.default.join(node_os.default.tmpdir(), `mioku-webui-${Date.now()}.zip`);
|
|
77
91
|
node_fs.default.writeFileSync(tmpZip, buffer);
|
|
78
92
|
const tmpUnpack = node_path.default.join(node_os.default.tmpdir(), `mioku-webui-unpack-${Date.now()}`);
|
|
79
|
-
|
|
93
|
+
node_fs.default.mkdirSync(tmpUnpack, { recursive: true });
|
|
94
|
+
try {
|
|
95
|
+
run("unzip", [
|
|
96
|
+
"-oq",
|
|
97
|
+
tmpZip,
|
|
98
|
+
"-d",
|
|
99
|
+
tmpUnpack
|
|
100
|
+
], { stdio: "ignore" });
|
|
101
|
+
} catch {}
|
|
80
102
|
const sourceDir = findDistSourceDir(tmpUnpack);
|
|
81
103
|
if (sourceDir) {
|
|
82
104
|
node_fs.default.mkdirSync(targetDist, { recursive: true });
|
|
@@ -106,12 +128,9 @@ function findDistSourceDir(unpackDir) {
|
|
|
106
128
|
return null;
|
|
107
129
|
}
|
|
108
130
|
function execAdd(packages, cwd) {
|
|
109
|
-
const cmd = getAddCommand(packages);
|
|
110
|
-
console.log(`执行: ${cmd}`);
|
|
111
|
-
(
|
|
112
|
-
cwd,
|
|
113
|
-
stdio: "inherit"
|
|
114
|
-
});
|
|
131
|
+
const [cmd, args$1] = getAddCommand(packages);
|
|
132
|
+
console.log(`执行: ${cmd} ${args$1.join(" ")}`);
|
|
133
|
+
run(cmd, args$1, { cwd });
|
|
115
134
|
}
|
|
116
135
|
async function installPackage(name, cwd) {
|
|
117
136
|
const normalized = normalizePackageName(name);
|
|
@@ -131,12 +150,8 @@ async function installPackage(name, cwd) {
|
|
|
131
150
|
}
|
|
132
151
|
async function updatePackage(name, cwd) {
|
|
133
152
|
try {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
(0, node_child_process.execSync)(cmd, {
|
|
137
|
-
cwd,
|
|
138
|
-
stdio: "inherit"
|
|
139
|
-
});
|
|
153
|
+
console.log(`执行: bun update ${name}`);
|
|
154
|
+
run("bun", ["update", name], { cwd });
|
|
140
155
|
consola.default.success(`已更新 ${name}`);
|
|
141
156
|
return true;
|
|
142
157
|
} catch {
|
|
@@ -145,9 +160,12 @@ async function updatePackage(name, cwd) {
|
|
|
145
160
|
}
|
|
146
161
|
}
|
|
147
162
|
async function checkUpdates(packages, cwd) {
|
|
148
|
-
const cmd = `bun pm outdated --json`;
|
|
149
163
|
try {
|
|
150
|
-
const output = (0, node_child_process.
|
|
164
|
+
const output = (0, node_child_process.execFileSync)("bun", [
|
|
165
|
+
"pm",
|
|
166
|
+
"outdated",
|
|
167
|
+
"--json"
|
|
168
|
+
], {
|
|
151
169
|
cwd,
|
|
152
170
|
encoding: "utf-8",
|
|
153
171
|
stdio: "pipe"
|
|
@@ -310,13 +328,32 @@ async function getInstalledPackages(cwd) {
|
|
|
310
328
|
required: true
|
|
311
329
|
}), token, protocol, host, port, prefix, admins, "use-npm-mirror": useNpmMirror } = cli$1;
|
|
312
330
|
if (name && owners) {
|
|
313
|
-
protocol ||= "ws";
|
|
314
|
-
host ||= "localhost";
|
|
315
|
-
port ||= 3001;
|
|
316
|
-
token ||= "";
|
|
317
|
-
prefix ||= "#";
|
|
318
|
-
admins ||= "";
|
|
319
331
|
useNpmMirror ??= false;
|
|
332
|
+
if (!protocol) protocol = await input("请输入 NapCat WS 协议", {
|
|
333
|
+
default: "ws",
|
|
334
|
+
placeholder: "ws",
|
|
335
|
+
required: true
|
|
336
|
+
});
|
|
337
|
+
if (!host) host = await input("请输入 NapCat WS 主机", {
|
|
338
|
+
default: "127.0.0.1",
|
|
339
|
+
placeholder: "127.0.0.1",
|
|
340
|
+
required: true
|
|
341
|
+
});
|
|
342
|
+
if (!port) port = parseInt(await input("请输入 NapCat WS 端口", {
|
|
343
|
+
default: "3001",
|
|
344
|
+
placeholder: "3001",
|
|
345
|
+
required: true
|
|
346
|
+
}));
|
|
347
|
+
if (!token) token = await input("请输入 NapCat WS Token(如无则留空)", {
|
|
348
|
+
default: "",
|
|
349
|
+
placeholder: "请输入"
|
|
350
|
+
});
|
|
351
|
+
if (!prefix) prefix = await input("请输入消息命令前缀", {
|
|
352
|
+
default: "#",
|
|
353
|
+
placeholder: "#",
|
|
354
|
+
required: true
|
|
355
|
+
});
|
|
356
|
+
if (!admins) admins = await input("请输入管理员 QQ (插件权限,英文逗号分隔,可空)", { placeholder: "可空" }) || "";
|
|
320
357
|
} else {
|
|
321
358
|
token ||= await input("请输入 NapCat WS Token", {
|
|
322
359
|
default: "",
|
|
@@ -346,7 +383,6 @@ async function getInstalledPackages(cwd) {
|
|
|
346
383
|
useNpmMirror ??= await confirm("是否使用 npm 镜像源加速依赖安装?", { initial: false });
|
|
347
384
|
}
|
|
348
385
|
const installWebui = await confirm("是否安装 WebUI?(建议安装)", { initial: true });
|
|
349
|
-
if (installWebui) await installWebUIDist(node_path.default.join(process.cwd(), name));
|
|
350
386
|
ensurePackageManager();
|
|
351
387
|
const pkgJson = (0, dedent.default)(`
|
|
352
388
|
{
|
|
@@ -411,6 +447,7 @@ async function getInstalledPackages(cwd) {
|
|
|
411
447
|
...useNpmMirror ? { ".npmrc": npmrc } : {}
|
|
412
448
|
};
|
|
413
449
|
await createNewProject(name, fileTree);
|
|
450
|
+
if (installWebui) await installWebUIDist(node_path.default.join(process.cwd(), name));
|
|
414
451
|
}
|
|
415
452
|
}
|
|
416
453
|
})();
|
|
@@ -431,12 +468,9 @@ async function createNewProject(name, fileTree) {
|
|
|
431
468
|
node_fs.default.mkdirSync(projectPath);
|
|
432
469
|
makeFileTree(fileTree, projectPath);
|
|
433
470
|
console.log(`项目 ${projectName} 创建成功!`);
|
|
434
|
-
const
|
|
435
|
-
console.log(`正在安装 Mioku 依赖: ${
|
|
436
|
-
(
|
|
437
|
-
cwd: projectPath,
|
|
438
|
-
stdio: "inherit"
|
|
439
|
-
});
|
|
471
|
+
const [cmd, args$1] = getAddCommand(DEFAULT_PACKAGES);
|
|
472
|
+
console.log(`正在安装 Mioku 依赖: ${cmd} ${args$1.join(" ")}`);
|
|
473
|
+
run(cmd, args$1, { cwd: projectPath });
|
|
440
474
|
console.log(`\ncd ${projectPath} && bun run start\n`);
|
|
441
475
|
}
|
|
442
476
|
function gracefullyExit() {
|
package/dist/cli.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.cjs","names":["cmd: string","packages: string[]","input: string","input","name: string","projectPath: string","a: any","unpackDir: string","cwd?: string","updates: string[]","cwd: string","packages","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.0\",\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 from \"node:fs\";\nimport { execSync } from \"node:child_process\";\nimport mri from \"mri\";\nimport path from \"node:path\";\nimport os from \"node:os\";\nimport dedent from \"dedent\";\nimport consola from \"consola\";\nimport { version } from \"../package.json\";\nimport { readFileSync } from \"node:fs\";\n\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\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 commandExists(cmd: string): boolean {\n try {\n execSync(`command -v ${cmd} > /dev/null 2>&1`, { stdio: \"ignore\" });\n return true;\n } catch {\n return false;\n }\n}\n\nfunction ensurePackageManager() {\n if (commandExists(\"bun\")) return;\n console.log(\"安装 bun...\");\n execSync(\"npm install -g bun\", { stdio: \"inherit\" });\n}\n\nfunction getAddCommand(packages: string[]): string {\n return `bun add ${packages.join(\" \")}`;\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\nasync function getPackageManager(): Promise<string> {\n return \"bun\";\n}\n\nasync function installWebUIDist(projectPath: string) {\n consola.info(\"正在安装 WebUI...\");\n execSync(\"bun add mioku-service-webui\", {\n cwd: projectPath,\n stdio: \"ignore\",\n });\n\n const nodeModulesWebui = path.join(projectPath, \"node_modules\", \"mioku-service-webui\");\n const targetDist = path.join(nodeModulesWebui, \"dist\");\n\n try {\n const releaseRes = await fetch(\n \"https://api.github.com/repos/mioku-lab/mioku-webui/releases/latest\",\n {\n headers: {\n Accept: \"application/vnd.github+json\",\n \"User-Agent\": \"mioku-cli\",\n },\n },\n );\n\n if (!releaseRes.ok) return;\n\n const release = await releaseRes.json();\n const assets = release.assets || [];\n const distAsset = assets.find(\n (a: any) => /dist/i.test(a.name) || a.name.endsWith(\".zip\"),\n );\n if (!distAsset?.browser_download_url) return;\n\n const zipRes = await fetch(distAsset.browser_download_url, {\n headers: { \"User-Agent\": \"mioku-cli\" },\n });\n if (!zipRes.ok) return;\n\n const buffer = Buffer.from(await zipRes.arrayBuffer());\n const tmpZip = path.join(os.tmpdir(), `mioku-webui-${Date.now()}.zip`);\n fs.writeFileSync(tmpZip, buffer);\n\n const tmpUnpack = path.join(os.tmpdir(), `mioku-webui-unpack-${Date.now()}`);\n execSync(`unzip -oq \"${tmpZip}\" -d \"${tmpUnpack}\"`, { stdio: \"ignore\" });\n\n const sourceDir = findDistSourceDir(tmpUnpack);\n if (sourceDir) {\n fs.mkdirSync(targetDist, { recursive: true });\n fs.cpSync(sourceDir, targetDist, { recursive: true, force: true });\n }\n\n fs.rmSync(tmpZip, { force: true });\n fs.rmSync(tmpUnpack, { recursive: true, force: true });\n } catch {\n // ignore download failure\n }\n}\n\nfunction findDistSourceDir(unpackDir: string): string | null {\n const directCandidates = [path.join(unpackDir, \"dist\"), unpackDir];\n for (const candidate of directCandidates) {\n if (fs.existsSync(path.join(candidate, \"index.html\"))) {\n return candidate;\n }\n }\n const children = fs.readdirSync(unpackDir);\n for (const child of children) {\n const childPath = path.join(unpackDir, child);\n if (fs.statSync(childPath).isDirectory()) {\n const subCandidate = path.join(childPath, \"dist\");\n if (fs.existsSync(path.join(subCandidate, \"index.html\"))) {\n return subCandidate;\n }\n }\n }\n return null;\n}\n\nfunction execAdd(packages: string[], cwd?: string) {\n const cmd = getAddCommand(packages);\n console.log(`执行: ${cmd}`);\n execSync(cmd, { cwd, stdio: \"inherit\" });\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 const cmd = `bun update ${name}`;\n console.log(`执行: ${cmd}`);\n execSync(cmd, { cwd, stdio: \"inherit\" });\n consola.success(`已更新 ${name}`);\n return true;\n } catch {\n consola.error(`更新失败: ${name}`);\n return false;\n }\n}\n\nasync function checkUpdates(\n packages: string[],\n cwd?: string,\n) {\n const cmd = `bun pm outdated --json`;\n\n try {\n const output = execSync(cmd, { cwd, encoding: \"utf-8\", stdio: \"pipe\" });\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(\"请指定类型和名称: mioku install plugin <名称> 或 mioku install service <名称>\");\n console.log(helpInfo);\n process.exit(1);\n }\n\n if (type !== \"plugin\" && type !== \"service\") {\n consola.error(`无效的类型 \"${type}\",请使用 plugin 或 service`);\n console.log(helpInfo);\n process.exit(1);\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.exit(success ? 0 : 1);\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.exit(0);\n }\n\n const target = cmdArgs[0];\n\n if (target === \"all\") {\n // 更新所有 mioku- 包\n const packages = await getInstalledPackages(cwd);\n if (packages.length === 0) {\n consola.info(\"未找到 mioku 相关依赖\");\n process.exit(0);\n }\n for (const pkg of packages) {\n await updatePackage(pkg, cwd);\n }\n process.exit(0);\n }\n\n if (target === \"self\") {\n await updatePackage(\"mioku\", cwd);\n process.exit(0);\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.exit(0);\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.exit(0);\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.exit(0);\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.exit(0);\n // fall through\n\n case cli.help:\n console.log(helpInfo);\n process.exit(0);\n // fall through\n\n default:\n break;\n }\n\n let {\n name = await input(\"请输入项目名称\", {\n default: \"mioku-bot\",\n placeholder: \"mioku-bot\",\n required: true,\n }),\n owners = await input(\"请输入主人 QQ (最高权限,英文逗号分隔,必填)\", {\n placeholder: \"请输入\",\n default: \"\",\n required: true,\n }),\n token,\n protocol,\n host,\n port,\n prefix,\n admins,\n \"use-npm-mirror\": useNpmMirror,\n } = cli;\n\n if (name && owners) {\n protocol ||= \"ws\";\n host ||= \"localhost\";\n port ||= 3001;\n token ||= \"\";\n prefix ||= \"#\";\n admins ||= \"\";\n useNpmMirror ??= false;\n } else {\n token ||= await input(\"请输入 NapCat WS Token\", {\n default: \"\",\n placeholder: \"请输入\",\n });\n protocol ||= await input(\"请输入 NapCat WS 协议\", {\n default: \"ws\",\n placeholder: \"ws\",\n required: true,\n });\n host ||= await input(\"请输入 NapCat WS 主机\", {\n default: \"localhost\",\n placeholder: \"localhost\",\n required: true,\n });\n port ||= parseInt(\n await input(\"请输入 NapCat WS 端口\", {\n default: \"3001\",\n placeholder: \"3001\",\n required: true,\n }),\n );\n prefix ||= await input(\"请输入消息命令前缀\", {\n default: \"#\",\n placeholder: \"#\",\n required: true,\n });\n admins ||=\n (await input(\"请输入管理员 QQ (插件权限,英文逗号分隔,可空)\", {\n placeholder: \"可空\",\n })) || \"\";\n useNpmMirror ??= await confirm(\"是否使用 npm 镜像源加速依赖安装?\", {\n initial: false,\n });\n }\n\n const installWebui = await confirm(\"是否安装 WebUI?(建议安装)\", {\n initial: true,\n });\n\n if (installWebui) {\n await installWebUIDist(path.join(process.cwd(), name));\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\": \"${prefix}\",\n \"owners\": [${String(owners)\n .split(\",\")\n .map((o) => o.trim())\n .join(\", \")}],\n \"admins\": [${\n admins\n ? String(admins)\n .split(\",\")\n .map((o) => `\"${o.trim()}\"`)\n .join(\", \")\n : \"\"\n }],\n \"plugins\": [\"boot\", \"help\", \"chat\", \"demo\"],\n \"log_level\": \"info\",\n \"online_push\": true,\n \"error_push\": true,\n \"napcat\": [\n {\n \"protocol\": \"${protocol}\",\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 npmrc = dedent(`\n registry=https://registry.npmmirror.com\n fund=false\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 ...(useNpmMirror ? { \".npmrc\": npmrc } : {}),\n };\n\n await createNewProject(name, fileTree);\n }\n }\n})();\n\nasync function createNewProject(\n name: string,\n fileTree: Record<string, any>,\n) {\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 fs.rmSync(projectPath, { recursive: true });\n }\n\n fs.mkdirSync(projectPath);\n\n makeFileTree(fileTree, projectPath);\n\n console.log(`项目 ${projectName} 创建成功!`);\n\n const addCommand = getAddCommand(DEFAULT_PACKAGES);\n console.log(`正在安装 Mioku 依赖: ${addCommand}`);\n execSync(addCommand, { cwd: projectPath, stdio: \"inherit\" });\n\n console.log(`\\ncd ${projectPath} && bun run start\\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(content as typeof fileTree, subPath);\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","packages: string[]","input: string","input","name: string","projectPath: string","a: any","unpackDir: string","cwd?: string","updates: string[]","cwd: string","packages","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.2\",\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 from \"node:fs\";\nimport { execFileSync } from \"node:child_process\";\nimport mri from \"mri\";\nimport path from \"node:path\";\nimport os from \"node:os\";\nimport dedent from \"dedent\";\nimport consola from \"consola\";\nimport { version } from \"../package.json\";\nimport { readFileSync } from \"node:fs\";\n\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 ...options,\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 commandExists(cmd: string): boolean {\n try {\n execFileSync(\"which\", [cmd], {\n stdio: \"ignore\",\n });\n return true;\n } catch {\n return false;\n }\n}\n\nfunction ensurePackageManager() {\n if (commandExists(\"bun\")) return;\n\n console.log(\"安装 bun...\");\n\n run(\"npm\", [\"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\nasync function getPackageManager(): Promise<string> {\n return \"bun\";\n}\n\nasync function installWebUIDist(projectPath: string) {\n consola.info(\"正在安装 WebUI...\");\n try {\n run(\"bun\", [\"add\", \"mioku-service-webui\"], {\n cwd: projectPath,\n stdio: \"ignore\",\n });\n } catch {\n return;\n }\n\n const nodeModulesWebui = path.join(projectPath, \"node_modules\", \"mioku-service-webui\");\n const targetDist = path.join(nodeModulesWebui, \"dist\");\n\n try {\n const releaseRes = await fetch(\n \"https://api.github.com/repos/mioku-lab/mioku-webui/releases/latest\",\n {\n headers: {\n Accept: \"application/vnd.github+json\",\n \"User-Agent\": \"mioku-cli\",\n },\n },\n );\n\n if (!releaseRes.ok) return;\n\n const release = await releaseRes.json();\n const assets = release.assets || [];\n const distAsset = assets.find(\n (a: any) => /dist/i.test(a.name) || a.name.endsWith(\".zip\"),\n );\n if (!distAsset?.browser_download_url) return;\n\n const zipRes = await fetch(distAsset.browser_download_url, {\n headers: { \"User-Agent\": \"mioku-cli\" },\n });\n if (!zipRes.ok) return;\n\n const buffer = Buffer.from(await zipRes.arrayBuffer());\n const tmpZip = path.join(os.tmpdir(), `mioku-webui-${Date.now()}.zip`);\n fs.writeFileSync(tmpZip, buffer);\n\n const tmpUnpack = path.join(os.tmpdir(), `mioku-webui-unpack-${Date.now()}`);\n fs.mkdirSync(tmpUnpack, { recursive: true });\n try {\n run(\"unzip\", [\"-oq\", tmpZip, \"-d\", tmpUnpack], {\n stdio: \"ignore\",\n });\n } catch {\n // ignore unzip failure\n }\n\n const sourceDir = findDistSourceDir(tmpUnpack);\n if (sourceDir) {\n fs.mkdirSync(targetDist, { recursive: true });\n fs.cpSync(sourceDir, targetDist, { recursive: true, force: true });\n }\n\n fs.rmSync(tmpZip, { force: true });\n fs.rmSync(tmpUnpack, { recursive: true, force: true });\n } catch {\n // ignore download failure\n }\n}\n\nfunction findDistSourceDir(unpackDir: string): string | null {\n const directCandidates = [path.join(unpackDir, \"dist\"), unpackDir];\n for (const candidate of directCandidates) {\n if (fs.existsSync(path.join(candidate, \"index.html\"))) {\n return candidate;\n }\n }\n const children = fs.readdirSync(unpackDir);\n for (const child of children) {\n const childPath = path.join(unpackDir, child);\n if (fs.statSync(childPath).isDirectory()) {\n const subCandidate = path.join(childPath, \"dist\");\n if (fs.existsSync(path.join(subCandidate, \"index.html\"))) {\n return subCandidate;\n }\n }\n }\n return null;\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(\n packages: string[],\n cwd?: string,\n) {\n try {\n const output = execFileSync(\n \"bun\",\n [\"pm\", \"outdated\", \"--json\"],\n {\n cwd,\n encoding: \"utf-8\",\n stdio: \"pipe\",\n },\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(\"请指定类型和名称: mioku install plugin <名称> 或 mioku install service <名称>\");\n console.log(helpInfo);\n process.exit(1);\n }\n\n if (type !== \"plugin\" && type !== \"service\") {\n consola.error(`无效的类型 \"${type}\",请使用 plugin 或 service`);\n console.log(helpInfo);\n process.exit(1);\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.exit(success ? 0 : 1);\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.exit(0);\n }\n\n const target = cmdArgs[0];\n\n if (target === \"all\") {\n // 更新所有 mioku- 包\n const packages = await getInstalledPackages(cwd);\n if (packages.length === 0) {\n consola.info(\"未找到 mioku 相关依赖\");\n process.exit(0);\n }\n for (const pkg of packages) {\n await updatePackage(pkg, cwd);\n }\n process.exit(0);\n }\n\n if (target === \"self\") {\n await updatePackage(\"mioku\", cwd);\n process.exit(0);\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.exit(0);\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.exit(0);\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.exit(0);\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.exit(0);\n // fall through\n\n case cli.help:\n console.log(helpInfo);\n process.exit(0);\n // fall through\n\n default:\n break;\n }\n\n let {\n name = await input(\"请输入项目名称\", {\n default: \"mioku-bot\",\n placeholder: \"mioku-bot\",\n required: true,\n }),\n owners = await input(\"请输入主人 QQ (最高权限,英文逗号分隔,必填)\", {\n placeholder: \"请输入\",\n default: \"\",\n required: true,\n }),\n token,\n protocol,\n host,\n port,\n prefix,\n admins,\n \"use-npm-mirror\": useNpmMirror,\n } = cli;\n\n if (name && owners) {\n useNpmMirror ??= false;\n if (!protocol) {\n protocol = await input(\"请输入 NapCat WS 协议\", {\n default: \"ws\",\n placeholder: \"ws\",\n required: true,\n });\n }\n if (!host) {\n host = await input(\"请输入 NapCat WS 主机\", {\n default: \"127.0.0.1\",\n placeholder: \"127.0.0.1\",\n required: true,\n });\n }\n if (!port) {\n port = parseInt(\n await input(\"请输入 NapCat WS 端口\", {\n default: \"3001\",\n placeholder: \"3001\",\n required: true,\n }),\n );\n }\n if (!token) {\n token = await input(\"请输入 NapCat WS Token(如无则留空)\", {\n default: \"\",\n placeholder: \"请输入\",\n });\n }\n if (!prefix) {\n prefix = await input(\"请输入消息命令前缀\", {\n default: \"#\",\n placeholder: \"#\",\n required: true,\n });\n }\n if (!admins) {\n admins =\n (await input(\"请输入管理员 QQ (插件权限,英文逗号分隔,可空)\", {\n placeholder: \"可空\",\n })) || \"\";\n }\n } else {\n token ||= await input(\"请输入 NapCat WS Token\", {\n default: \"\",\n placeholder: \"请输入\",\n });\n protocol ||= await input(\"请输入 NapCat WS 协议\", {\n default: \"ws\",\n placeholder: \"ws\",\n required: true,\n });\n host ||= await input(\"请输入 NapCat WS 主机\", {\n default: \"localhost\",\n placeholder: \"localhost\",\n required: true,\n });\n port ||= parseInt(\n await input(\"请输入 NapCat WS 端口\", {\n default: \"3001\",\n placeholder: \"3001\",\n required: true,\n }),\n );\n prefix ||= await input(\"请输入消息命令前缀\", {\n default: \"#\",\n placeholder: \"#\",\n required: true,\n });\n admins ||=\n (await input(\"请输入管理员 QQ (插件权限,英文逗号分隔,可空)\", {\n placeholder: \"可空\",\n })) || \"\";\n useNpmMirror ??= await confirm(\"是否使用 npm 镜像源加速依赖安装?\", {\n initial: false,\n });\n }\n\n const installWebui = await confirm(\"是否安装 WebUI?(建议安装)\", {\n initial: true,\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\": \"${prefix}\",\n \"owners\": [${String(owners)\n .split(\",\")\n .map((o) => o.trim())\n .join(\", \")}],\n \"admins\": [${\n admins\n ? String(admins)\n .split(\",\")\n .map((o) => `\"${o.trim()}\"`)\n .join(\", \")\n : \"\"\n }],\n \"plugins\": [\"boot\", \"help\", \"chat\", \"demo\"],\n \"log_level\": \"info\",\n \"online_push\": true,\n \"error_push\": true,\n \"napcat\": [\n {\n \"protocol\": \"${protocol}\",\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 npmrc = dedent(`\n registry=https://registry.npmmirror.com\n fund=false\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 ...(useNpmMirror ? { \".npmrc\": npmrc } : {}),\n };\n\n await createNewProject(name, fileTree);\n\n if (installWebui) {\n await installWebUIDist(path.join(process.cwd(), name));\n }\n }\n }\n})();\n\nasync function createNewProject(\n name: string,\n fileTree: Record<string, any>,\n) {\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 fs.rmSync(projectPath, { recursive: true });\n }\n\n fs.mkdirSync(projectPath);\n\n makeFileTree(fileTree, projectPath);\n\n console.log(`项目 ${projectName} 创建成功!`);\n\n const [cmd, args] = getAddCommand(DEFAULT_PACKAGES);\n console.log(`正在安装 Mioku 依赖: ${cmd} ${args.join(\" \")}`);\n run(cmd, args, {\n cwd: projectPath,\n });\n\n console.log(`\\ncd ${projectPath} && bun run start\\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(content as typeof fileTree, subPath);\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
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import fs, { readFileSync } from "node:fs";
|
|
3
|
-
import {
|
|
3
|
+
import { execFileSync } from "node:child_process";
|
|
4
4
|
import mri from "mri";
|
|
5
5
|
import path from "node:path";
|
|
6
6
|
import os from "node:os";
|
|
@@ -8,7 +8,7 @@ import dedent from "dedent";
|
|
|
8
8
|
import consola from "consola";
|
|
9
9
|
|
|
10
10
|
//#region package.json
|
|
11
|
-
var version = "0.8.
|
|
11
|
+
var version = "0.8.2";
|
|
12
12
|
|
|
13
13
|
//#endregion
|
|
14
14
|
//#region src/cli.ts
|
|
@@ -25,9 +25,15 @@ const DEFAULT_PACKAGES = [
|
|
|
25
25
|
const PLUGIN_PREFIX = "mioku-plugin-";
|
|
26
26
|
const SERVICE_PREFIX = "mioku-service-";
|
|
27
27
|
const args = process.argv.slice(2);
|
|
28
|
+
function run(cmd, args$1 = [], options = {}) {
|
|
29
|
+
return execFileSync(cmd, args$1, {
|
|
30
|
+
stdio: "inherit",
|
|
31
|
+
...options
|
|
32
|
+
});
|
|
33
|
+
}
|
|
28
34
|
function commandExists(cmd) {
|
|
29
35
|
try {
|
|
30
|
-
|
|
36
|
+
execFileSync("which", [cmd], { stdio: "ignore" });
|
|
31
37
|
return true;
|
|
32
38
|
} catch {
|
|
33
39
|
return false;
|
|
@@ -36,10 +42,14 @@ function commandExists(cmd) {
|
|
|
36
42
|
function ensurePackageManager() {
|
|
37
43
|
if (commandExists("bun")) return;
|
|
38
44
|
console.log("安装 bun...");
|
|
39
|
-
|
|
45
|
+
run("npm", [
|
|
46
|
+
"install",
|
|
47
|
+
"-g",
|
|
48
|
+
"bun"
|
|
49
|
+
]);
|
|
40
50
|
}
|
|
41
51
|
function getAddCommand(packages) {
|
|
42
|
-
return
|
|
52
|
+
return ["bun", ["add", ...packages]];
|
|
43
53
|
}
|
|
44
54
|
function normalizePackageName(input$1) {
|
|
45
55
|
if (input$1.startsWith(PLUGIN_PREFIX) || input$1.startsWith(SERVICE_PREFIX)) return input$1;
|
|
@@ -53,10 +63,14 @@ function detectType(name) {
|
|
|
53
63
|
}
|
|
54
64
|
async function installWebUIDist(projectPath) {
|
|
55
65
|
consola.info("正在安装 WebUI...");
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
66
|
+
try {
|
|
67
|
+
run("bun", ["add", "mioku-service-webui"], {
|
|
68
|
+
cwd: projectPath,
|
|
69
|
+
stdio: "ignore"
|
|
70
|
+
});
|
|
71
|
+
} catch {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
60
74
|
const nodeModulesWebui = path.join(projectPath, "node_modules", "mioku-service-webui");
|
|
61
75
|
const targetDist = path.join(nodeModulesWebui, "dist");
|
|
62
76
|
try {
|
|
@@ -75,7 +89,15 @@ async function installWebUIDist(projectPath) {
|
|
|
75
89
|
const tmpZip = path.join(os.tmpdir(), `mioku-webui-${Date.now()}.zip`);
|
|
76
90
|
fs.writeFileSync(tmpZip, buffer);
|
|
77
91
|
const tmpUnpack = path.join(os.tmpdir(), `mioku-webui-unpack-${Date.now()}`);
|
|
78
|
-
|
|
92
|
+
fs.mkdirSync(tmpUnpack, { recursive: true });
|
|
93
|
+
try {
|
|
94
|
+
run("unzip", [
|
|
95
|
+
"-oq",
|
|
96
|
+
tmpZip,
|
|
97
|
+
"-d",
|
|
98
|
+
tmpUnpack
|
|
99
|
+
], { stdio: "ignore" });
|
|
100
|
+
} catch {}
|
|
79
101
|
const sourceDir = findDistSourceDir(tmpUnpack);
|
|
80
102
|
if (sourceDir) {
|
|
81
103
|
fs.mkdirSync(targetDist, { recursive: true });
|
|
@@ -105,12 +127,9 @@ function findDistSourceDir(unpackDir) {
|
|
|
105
127
|
return null;
|
|
106
128
|
}
|
|
107
129
|
function execAdd(packages, cwd) {
|
|
108
|
-
const cmd = getAddCommand(packages);
|
|
109
|
-
console.log(`执行: ${cmd}`);
|
|
110
|
-
|
|
111
|
-
cwd,
|
|
112
|
-
stdio: "inherit"
|
|
113
|
-
});
|
|
130
|
+
const [cmd, args$1] = getAddCommand(packages);
|
|
131
|
+
console.log(`执行: ${cmd} ${args$1.join(" ")}`);
|
|
132
|
+
run(cmd, args$1, { cwd });
|
|
114
133
|
}
|
|
115
134
|
async function installPackage(name, cwd) {
|
|
116
135
|
const normalized = normalizePackageName(name);
|
|
@@ -130,12 +149,8 @@ async function installPackage(name, cwd) {
|
|
|
130
149
|
}
|
|
131
150
|
async function updatePackage(name, cwd) {
|
|
132
151
|
try {
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
execSync(cmd, {
|
|
136
|
-
cwd,
|
|
137
|
-
stdio: "inherit"
|
|
138
|
-
});
|
|
152
|
+
console.log(`执行: bun update ${name}`);
|
|
153
|
+
run("bun", ["update", name], { cwd });
|
|
139
154
|
consola.success(`已更新 ${name}`);
|
|
140
155
|
return true;
|
|
141
156
|
} catch {
|
|
@@ -144,9 +159,12 @@ async function updatePackage(name, cwd) {
|
|
|
144
159
|
}
|
|
145
160
|
}
|
|
146
161
|
async function checkUpdates(packages, cwd) {
|
|
147
|
-
const cmd = `bun pm outdated --json`;
|
|
148
162
|
try {
|
|
149
|
-
const output =
|
|
163
|
+
const output = execFileSync("bun", [
|
|
164
|
+
"pm",
|
|
165
|
+
"outdated",
|
|
166
|
+
"--json"
|
|
167
|
+
], {
|
|
150
168
|
cwd,
|
|
151
169
|
encoding: "utf-8",
|
|
152
170
|
stdio: "pipe"
|
|
@@ -309,13 +327,32 @@ async function getInstalledPackages(cwd) {
|
|
|
309
327
|
required: true
|
|
310
328
|
}), token, protocol, host, port, prefix, admins, "use-npm-mirror": useNpmMirror } = cli$1;
|
|
311
329
|
if (name && owners) {
|
|
312
|
-
protocol ||= "ws";
|
|
313
|
-
host ||= "localhost";
|
|
314
|
-
port ||= 3001;
|
|
315
|
-
token ||= "";
|
|
316
|
-
prefix ||= "#";
|
|
317
|
-
admins ||= "";
|
|
318
330
|
useNpmMirror ??= false;
|
|
331
|
+
if (!protocol) protocol = await input("请输入 NapCat WS 协议", {
|
|
332
|
+
default: "ws",
|
|
333
|
+
placeholder: "ws",
|
|
334
|
+
required: true
|
|
335
|
+
});
|
|
336
|
+
if (!host) host = await input("请输入 NapCat WS 主机", {
|
|
337
|
+
default: "127.0.0.1",
|
|
338
|
+
placeholder: "127.0.0.1",
|
|
339
|
+
required: true
|
|
340
|
+
});
|
|
341
|
+
if (!port) port = parseInt(await input("请输入 NapCat WS 端口", {
|
|
342
|
+
default: "3001",
|
|
343
|
+
placeholder: "3001",
|
|
344
|
+
required: true
|
|
345
|
+
}));
|
|
346
|
+
if (!token) token = await input("请输入 NapCat WS Token(如无则留空)", {
|
|
347
|
+
default: "",
|
|
348
|
+
placeholder: "请输入"
|
|
349
|
+
});
|
|
350
|
+
if (!prefix) prefix = await input("请输入消息命令前缀", {
|
|
351
|
+
default: "#",
|
|
352
|
+
placeholder: "#",
|
|
353
|
+
required: true
|
|
354
|
+
});
|
|
355
|
+
if (!admins) admins = await input("请输入管理员 QQ (插件权限,英文逗号分隔,可空)", { placeholder: "可空" }) || "";
|
|
319
356
|
} else {
|
|
320
357
|
token ||= await input("请输入 NapCat WS Token", {
|
|
321
358
|
default: "",
|
|
@@ -345,7 +382,6 @@ async function getInstalledPackages(cwd) {
|
|
|
345
382
|
useNpmMirror ??= await confirm("是否使用 npm 镜像源加速依赖安装?", { initial: false });
|
|
346
383
|
}
|
|
347
384
|
const installWebui = await confirm("是否安装 WebUI?(建议安装)", { initial: true });
|
|
348
|
-
if (installWebui) await installWebUIDist(path.join(process.cwd(), name));
|
|
349
385
|
ensurePackageManager();
|
|
350
386
|
const pkgJson = dedent(`
|
|
351
387
|
{
|
|
@@ -410,6 +446,7 @@ async function getInstalledPackages(cwd) {
|
|
|
410
446
|
...useNpmMirror ? { ".npmrc": npmrc } : {}
|
|
411
447
|
};
|
|
412
448
|
await createNewProject(name, fileTree);
|
|
449
|
+
if (installWebui) await installWebUIDist(path.join(process.cwd(), name));
|
|
413
450
|
}
|
|
414
451
|
}
|
|
415
452
|
})();
|
|
@@ -430,12 +467,9 @@ async function createNewProject(name, fileTree) {
|
|
|
430
467
|
fs.mkdirSync(projectPath);
|
|
431
468
|
makeFileTree(fileTree, projectPath);
|
|
432
469
|
console.log(`项目 ${projectName} 创建成功!`);
|
|
433
|
-
const
|
|
434
|
-
console.log(`正在安装 Mioku 依赖: ${
|
|
435
|
-
|
|
436
|
-
cwd: projectPath,
|
|
437
|
-
stdio: "inherit"
|
|
438
|
-
});
|
|
470
|
+
const [cmd, args$1] = getAddCommand(DEFAULT_PACKAGES);
|
|
471
|
+
console.log(`正在安装 Mioku 依赖: ${cmd} ${args$1.join(" ")}`);
|
|
472
|
+
run(cmd, args$1, { cwd: projectPath });
|
|
439
473
|
console.log(`\ncd ${projectPath} && bun run start\n`);
|
|
440
474
|
}
|
|
441
475
|
function gracefullyExit() {
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","names":["cmd: string","packages: string[]","input: string","input","name: string","projectPath: string","a: any","unpackDir: string","cwd?: string","updates: string[]","cwd: string","packages","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.0\",\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 from \"node:fs\";\nimport { execSync } from \"node:child_process\";\nimport mri from \"mri\";\nimport path from \"node:path\";\nimport os from \"node:os\";\nimport dedent from \"dedent\";\nimport consola from \"consola\";\nimport { version } from \"../package.json\";\nimport { readFileSync } from \"node:fs\";\n\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\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 commandExists(cmd: string): boolean {\n try {\n execSync(`command -v ${cmd} > /dev/null 2>&1`, { stdio: \"ignore\" });\n return true;\n } catch {\n return false;\n }\n}\n\nfunction ensurePackageManager() {\n if (commandExists(\"bun\")) return;\n console.log(\"安装 bun...\");\n execSync(\"npm install -g bun\", { stdio: \"inherit\" });\n}\n\nfunction getAddCommand(packages: string[]): string {\n return `bun add ${packages.join(\" \")}`;\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\nasync function getPackageManager(): Promise<string> {\n return \"bun\";\n}\n\nasync function installWebUIDist(projectPath: string) {\n consola.info(\"正在安装 WebUI...\");\n execSync(\"bun add mioku-service-webui\", {\n cwd: projectPath,\n stdio: \"ignore\",\n });\n\n const nodeModulesWebui = path.join(projectPath, \"node_modules\", \"mioku-service-webui\");\n const targetDist = path.join(nodeModulesWebui, \"dist\");\n\n try {\n const releaseRes = await fetch(\n \"https://api.github.com/repos/mioku-lab/mioku-webui/releases/latest\",\n {\n headers: {\n Accept: \"application/vnd.github+json\",\n \"User-Agent\": \"mioku-cli\",\n },\n },\n );\n\n if (!releaseRes.ok) return;\n\n const release = await releaseRes.json();\n const assets = release.assets || [];\n const distAsset = assets.find(\n (a: any) => /dist/i.test(a.name) || a.name.endsWith(\".zip\"),\n );\n if (!distAsset?.browser_download_url) return;\n\n const zipRes = await fetch(distAsset.browser_download_url, {\n headers: { \"User-Agent\": \"mioku-cli\" },\n });\n if (!zipRes.ok) return;\n\n const buffer = Buffer.from(await zipRes.arrayBuffer());\n const tmpZip = path.join(os.tmpdir(), `mioku-webui-${Date.now()}.zip`);\n fs.writeFileSync(tmpZip, buffer);\n\n const tmpUnpack = path.join(os.tmpdir(), `mioku-webui-unpack-${Date.now()}`);\n execSync(`unzip -oq \"${tmpZip}\" -d \"${tmpUnpack}\"`, { stdio: \"ignore\" });\n\n const sourceDir = findDistSourceDir(tmpUnpack);\n if (sourceDir) {\n fs.mkdirSync(targetDist, { recursive: true });\n fs.cpSync(sourceDir, targetDist, { recursive: true, force: true });\n }\n\n fs.rmSync(tmpZip, { force: true });\n fs.rmSync(tmpUnpack, { recursive: true, force: true });\n } catch {\n // ignore download failure\n }\n}\n\nfunction findDistSourceDir(unpackDir: string): string | null {\n const directCandidates = [path.join(unpackDir, \"dist\"), unpackDir];\n for (const candidate of directCandidates) {\n if (fs.existsSync(path.join(candidate, \"index.html\"))) {\n return candidate;\n }\n }\n const children = fs.readdirSync(unpackDir);\n for (const child of children) {\n const childPath = path.join(unpackDir, child);\n if (fs.statSync(childPath).isDirectory()) {\n const subCandidate = path.join(childPath, \"dist\");\n if (fs.existsSync(path.join(subCandidate, \"index.html\"))) {\n return subCandidate;\n }\n }\n }\n return null;\n}\n\nfunction execAdd(packages: string[], cwd?: string) {\n const cmd = getAddCommand(packages);\n console.log(`执行: ${cmd}`);\n execSync(cmd, { cwd, stdio: \"inherit\" });\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 const cmd = `bun update ${name}`;\n console.log(`执行: ${cmd}`);\n execSync(cmd, { cwd, stdio: \"inherit\" });\n consola.success(`已更新 ${name}`);\n return true;\n } catch {\n consola.error(`更新失败: ${name}`);\n return false;\n }\n}\n\nasync function checkUpdates(\n packages: string[],\n cwd?: string,\n) {\n const cmd = `bun pm outdated --json`;\n\n try {\n const output = execSync(cmd, { cwd, encoding: \"utf-8\", stdio: \"pipe\" });\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(\"请指定类型和名称: mioku install plugin <名称> 或 mioku install service <名称>\");\n console.log(helpInfo);\n process.exit(1);\n }\n\n if (type !== \"plugin\" && type !== \"service\") {\n consola.error(`无效的类型 \"${type}\",请使用 plugin 或 service`);\n console.log(helpInfo);\n process.exit(1);\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.exit(success ? 0 : 1);\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.exit(0);\n }\n\n const target = cmdArgs[0];\n\n if (target === \"all\") {\n // 更新所有 mioku- 包\n const packages = await getInstalledPackages(cwd);\n if (packages.length === 0) {\n consola.info(\"未找到 mioku 相关依赖\");\n process.exit(0);\n }\n for (const pkg of packages) {\n await updatePackage(pkg, cwd);\n }\n process.exit(0);\n }\n\n if (target === \"self\") {\n await updatePackage(\"mioku\", cwd);\n process.exit(0);\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.exit(0);\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.exit(0);\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.exit(0);\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.exit(0);\n // fall through\n\n case cli.help:\n console.log(helpInfo);\n process.exit(0);\n // fall through\n\n default:\n break;\n }\n\n let {\n name = await input(\"请输入项目名称\", {\n default: \"mioku-bot\",\n placeholder: \"mioku-bot\",\n required: true,\n }),\n owners = await input(\"请输入主人 QQ (最高权限,英文逗号分隔,必填)\", {\n placeholder: \"请输入\",\n default: \"\",\n required: true,\n }),\n token,\n protocol,\n host,\n port,\n prefix,\n admins,\n \"use-npm-mirror\": useNpmMirror,\n } = cli;\n\n if (name && owners) {\n protocol ||= \"ws\";\n host ||= \"localhost\";\n port ||= 3001;\n token ||= \"\";\n prefix ||= \"#\";\n admins ||= \"\";\n useNpmMirror ??= false;\n } else {\n token ||= await input(\"请输入 NapCat WS Token\", {\n default: \"\",\n placeholder: \"请输入\",\n });\n protocol ||= await input(\"请输入 NapCat WS 协议\", {\n default: \"ws\",\n placeholder: \"ws\",\n required: true,\n });\n host ||= await input(\"请输入 NapCat WS 主机\", {\n default: \"localhost\",\n placeholder: \"localhost\",\n required: true,\n });\n port ||= parseInt(\n await input(\"请输入 NapCat WS 端口\", {\n default: \"3001\",\n placeholder: \"3001\",\n required: true,\n }),\n );\n prefix ||= await input(\"请输入消息命令前缀\", {\n default: \"#\",\n placeholder: \"#\",\n required: true,\n });\n admins ||=\n (await input(\"请输入管理员 QQ (插件权限,英文逗号分隔,可空)\", {\n placeholder: \"可空\",\n })) || \"\";\n useNpmMirror ??= await confirm(\"是否使用 npm 镜像源加速依赖安装?\", {\n initial: false,\n });\n }\n\n const installWebui = await confirm(\"是否安装 WebUI?(建议安装)\", {\n initial: true,\n });\n\n if (installWebui) {\n await installWebUIDist(path.join(process.cwd(), name));\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\": \"${prefix}\",\n \"owners\": [${String(owners)\n .split(\",\")\n .map((o) => o.trim())\n .join(\", \")}],\n \"admins\": [${\n admins\n ? String(admins)\n .split(\",\")\n .map((o) => `\"${o.trim()}\"`)\n .join(\", \")\n : \"\"\n }],\n \"plugins\": [\"boot\", \"help\", \"chat\", \"demo\"],\n \"log_level\": \"info\",\n \"online_push\": true,\n \"error_push\": true,\n \"napcat\": [\n {\n \"protocol\": \"${protocol}\",\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 npmrc = dedent(`\n registry=https://registry.npmmirror.com\n fund=false\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 ...(useNpmMirror ? { \".npmrc\": npmrc } : {}),\n };\n\n await createNewProject(name, fileTree);\n }\n }\n})();\n\nasync function createNewProject(\n name: string,\n fileTree: Record<string, any>,\n) {\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 fs.rmSync(projectPath, { recursive: true });\n }\n\n fs.mkdirSync(projectPath);\n\n makeFileTree(fileTree, projectPath);\n\n console.log(`项目 ${projectName} 创建成功!`);\n\n const addCommand = getAddCommand(DEFAULT_PACKAGES);\n console.log(`正在安装 Mioku 依赖: ${addCommand}`);\n execSync(addCommand, { cwd: projectPath, stdio: \"inherit\" });\n\n console.log(`\\ncd ${projectPath} && bun run start\\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(content as typeof fileTree, subPath);\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.js","names":["cmd: string","args: string[]","options: Parameters<typeof execFileSync>[2]","args","packages: string[]","input: string","input","name: string","projectPath: string","a: any","unpackDir: string","cwd?: string","updates: string[]","cwd: string","packages","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.2\",\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 from \"node:fs\";\nimport { execFileSync } from \"node:child_process\";\nimport mri from \"mri\";\nimport path from \"node:path\";\nimport os from \"node:os\";\nimport dedent from \"dedent\";\nimport consola from \"consola\";\nimport { version } from \"../package.json\";\nimport { readFileSync } from \"node:fs\";\n\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 ...options,\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 commandExists(cmd: string): boolean {\n try {\n execFileSync(\"which\", [cmd], {\n stdio: \"ignore\",\n });\n return true;\n } catch {\n return false;\n }\n}\n\nfunction ensurePackageManager() {\n if (commandExists(\"bun\")) return;\n\n console.log(\"安装 bun...\");\n\n run(\"npm\", [\"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\nasync function getPackageManager(): Promise<string> {\n return \"bun\";\n}\n\nasync function installWebUIDist(projectPath: string) {\n consola.info(\"正在安装 WebUI...\");\n try {\n run(\"bun\", [\"add\", \"mioku-service-webui\"], {\n cwd: projectPath,\n stdio: \"ignore\",\n });\n } catch {\n return;\n }\n\n const nodeModulesWebui = path.join(projectPath, \"node_modules\", \"mioku-service-webui\");\n const targetDist = path.join(nodeModulesWebui, \"dist\");\n\n try {\n const releaseRes = await fetch(\n \"https://api.github.com/repos/mioku-lab/mioku-webui/releases/latest\",\n {\n headers: {\n Accept: \"application/vnd.github+json\",\n \"User-Agent\": \"mioku-cli\",\n },\n },\n );\n\n if (!releaseRes.ok) return;\n\n const release = await releaseRes.json();\n const assets = release.assets || [];\n const distAsset = assets.find(\n (a: any) => /dist/i.test(a.name) || a.name.endsWith(\".zip\"),\n );\n if (!distAsset?.browser_download_url) return;\n\n const zipRes = await fetch(distAsset.browser_download_url, {\n headers: { \"User-Agent\": \"mioku-cli\" },\n });\n if (!zipRes.ok) return;\n\n const buffer = Buffer.from(await zipRes.arrayBuffer());\n const tmpZip = path.join(os.tmpdir(), `mioku-webui-${Date.now()}.zip`);\n fs.writeFileSync(tmpZip, buffer);\n\n const tmpUnpack = path.join(os.tmpdir(), `mioku-webui-unpack-${Date.now()}`);\n fs.mkdirSync(tmpUnpack, { recursive: true });\n try {\n run(\"unzip\", [\"-oq\", tmpZip, \"-d\", tmpUnpack], {\n stdio: \"ignore\",\n });\n } catch {\n // ignore unzip failure\n }\n\n const sourceDir = findDistSourceDir(tmpUnpack);\n if (sourceDir) {\n fs.mkdirSync(targetDist, { recursive: true });\n fs.cpSync(sourceDir, targetDist, { recursive: true, force: true });\n }\n\n fs.rmSync(tmpZip, { force: true });\n fs.rmSync(tmpUnpack, { recursive: true, force: true });\n } catch {\n // ignore download failure\n }\n}\n\nfunction findDistSourceDir(unpackDir: string): string | null {\n const directCandidates = [path.join(unpackDir, \"dist\"), unpackDir];\n for (const candidate of directCandidates) {\n if (fs.existsSync(path.join(candidate, \"index.html\"))) {\n return candidate;\n }\n }\n const children = fs.readdirSync(unpackDir);\n for (const child of children) {\n const childPath = path.join(unpackDir, child);\n if (fs.statSync(childPath).isDirectory()) {\n const subCandidate = path.join(childPath, \"dist\");\n if (fs.existsSync(path.join(subCandidate, \"index.html\"))) {\n return subCandidate;\n }\n }\n }\n return null;\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(\n packages: string[],\n cwd?: string,\n) {\n try {\n const output = execFileSync(\n \"bun\",\n [\"pm\", \"outdated\", \"--json\"],\n {\n cwd,\n encoding: \"utf-8\",\n stdio: \"pipe\",\n },\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(\"请指定类型和名称: mioku install plugin <名称> 或 mioku install service <名称>\");\n console.log(helpInfo);\n process.exit(1);\n }\n\n if (type !== \"plugin\" && type !== \"service\") {\n consola.error(`无效的类型 \"${type}\",请使用 plugin 或 service`);\n console.log(helpInfo);\n process.exit(1);\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.exit(success ? 0 : 1);\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.exit(0);\n }\n\n const target = cmdArgs[0];\n\n if (target === \"all\") {\n // 更新所有 mioku- 包\n const packages = await getInstalledPackages(cwd);\n if (packages.length === 0) {\n consola.info(\"未找到 mioku 相关依赖\");\n process.exit(0);\n }\n for (const pkg of packages) {\n await updatePackage(pkg, cwd);\n }\n process.exit(0);\n }\n\n if (target === \"self\") {\n await updatePackage(\"mioku\", cwd);\n process.exit(0);\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.exit(0);\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.exit(0);\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.exit(0);\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.exit(0);\n // fall through\n\n case cli.help:\n console.log(helpInfo);\n process.exit(0);\n // fall through\n\n default:\n break;\n }\n\n let {\n name = await input(\"请输入项目名称\", {\n default: \"mioku-bot\",\n placeholder: \"mioku-bot\",\n required: true,\n }),\n owners = await input(\"请输入主人 QQ (最高权限,英文逗号分隔,必填)\", {\n placeholder: \"请输入\",\n default: \"\",\n required: true,\n }),\n token,\n protocol,\n host,\n port,\n prefix,\n admins,\n \"use-npm-mirror\": useNpmMirror,\n } = cli;\n\n if (name && owners) {\n useNpmMirror ??= false;\n if (!protocol) {\n protocol = await input(\"请输入 NapCat WS 协议\", {\n default: \"ws\",\n placeholder: \"ws\",\n required: true,\n });\n }\n if (!host) {\n host = await input(\"请输入 NapCat WS 主机\", {\n default: \"127.0.0.1\",\n placeholder: \"127.0.0.1\",\n required: true,\n });\n }\n if (!port) {\n port = parseInt(\n await input(\"请输入 NapCat WS 端口\", {\n default: \"3001\",\n placeholder: \"3001\",\n required: true,\n }),\n );\n }\n if (!token) {\n token = await input(\"请输入 NapCat WS Token(如无则留空)\", {\n default: \"\",\n placeholder: \"请输入\",\n });\n }\n if (!prefix) {\n prefix = await input(\"请输入消息命令前缀\", {\n default: \"#\",\n placeholder: \"#\",\n required: true,\n });\n }\n if (!admins) {\n admins =\n (await input(\"请输入管理员 QQ (插件权限,英文逗号分隔,可空)\", {\n placeholder: \"可空\",\n })) || \"\";\n }\n } else {\n token ||= await input(\"请输入 NapCat WS Token\", {\n default: \"\",\n placeholder: \"请输入\",\n });\n protocol ||= await input(\"请输入 NapCat WS 协议\", {\n default: \"ws\",\n placeholder: \"ws\",\n required: true,\n });\n host ||= await input(\"请输入 NapCat WS 主机\", {\n default: \"localhost\",\n placeholder: \"localhost\",\n required: true,\n });\n port ||= parseInt(\n await input(\"请输入 NapCat WS 端口\", {\n default: \"3001\",\n placeholder: \"3001\",\n required: true,\n }),\n );\n prefix ||= await input(\"请输入消息命令前缀\", {\n default: \"#\",\n placeholder: \"#\",\n required: true,\n });\n admins ||=\n (await input(\"请输入管理员 QQ (插件权限,英文逗号分隔,可空)\", {\n placeholder: \"可空\",\n })) || \"\";\n useNpmMirror ??= await confirm(\"是否使用 npm 镜像源加速依赖安装?\", {\n initial: false,\n });\n }\n\n const installWebui = await confirm(\"是否安装 WebUI?(建议安装)\", {\n initial: true,\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\": \"${prefix}\",\n \"owners\": [${String(owners)\n .split(\",\")\n .map((o) => o.trim())\n .join(\", \")}],\n \"admins\": [${\n admins\n ? String(admins)\n .split(\",\")\n .map((o) => `\"${o.trim()}\"`)\n .join(\", \")\n : \"\"\n }],\n \"plugins\": [\"boot\", \"help\", \"chat\", \"demo\"],\n \"log_level\": \"info\",\n \"online_push\": true,\n \"error_push\": true,\n \"napcat\": [\n {\n \"protocol\": \"${protocol}\",\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 npmrc = dedent(`\n registry=https://registry.npmmirror.com\n fund=false\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 ...(useNpmMirror ? { \".npmrc\": npmrc } : {}),\n };\n\n await createNewProject(name, fileTree);\n\n if (installWebui) {\n await installWebUIDist(path.join(process.cwd(), name));\n }\n }\n }\n})();\n\nasync function createNewProject(\n name: string,\n fileTree: Record<string, any>,\n) {\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 fs.rmSync(projectPath, { recursive: true });\n }\n\n fs.mkdirSync(projectPath);\n\n makeFileTree(fileTree, projectPath);\n\n console.log(`项目 ${projectName} 创建成功!`);\n\n const [cmd, args] = getAddCommand(DEFAULT_PACKAGES);\n console.log(`正在安装 Mioku 依赖: ${cmd} ${args.join(\" \")}`);\n run(cmd, args, {\n cwd: projectPath,\n });\n\n console.log(`\\ncd ${projectPath} && bun run start\\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(content as typeof fileTree, subPath);\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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"}
|