mioku 0.9.8 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.cjs +219 -57
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.js +216 -54
- package/dist/cli/index.js.map +1 -1
- package/dist/{exec-BzODBZwA.js → exec-CUvS9y6X.js} +16 -7
- package/dist/exec-CUvS9y6X.js.map +1 -0
- package/dist/{exec-BojymP61.cjs → exec-gpip41w9.cjs} +20 -5
- package/dist/exec-gpip41w9.cjs.map +1 -0
- package/dist/index.cjs +5349 -519
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1763 -46
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +1763 -46
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5123 -526
- package/dist/index.js.map +1 -1
- package/package.json +8 -13
- package/dist/exec-BojymP61.cjs.map +0 -1
- package/dist/exec-BzODBZwA.js.map +0 -1
package/dist/cli/index.cjs
CHANGED
|
@@ -1,28 +1,145 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
const require_exec = require('../exec-
|
|
2
|
+
const require_exec = require('../exec-gpip41w9.cjs');
|
|
3
3
|
const node_fs = require_exec.__toESM(require("node:fs"));
|
|
4
4
|
const node_path = require_exec.__toESM(require("node:path"));
|
|
5
5
|
const mri = require_exec.__toESM(require("mri"));
|
|
6
|
-
const consola = require_exec.__toESM(require("consola"));
|
|
7
6
|
const dedent = require_exec.__toESM(require("dedent"));
|
|
7
|
+
const consola = require_exec.__toESM(require("consola"));
|
|
8
8
|
|
|
9
|
-
//#region package.json
|
|
10
|
-
var version = "0.9.8";
|
|
11
|
-
|
|
12
|
-
//#endregion
|
|
13
9
|
//#region src/cli/shared.ts
|
|
14
|
-
const DEFAULT_PACKAGES = [
|
|
15
|
-
"mioku",
|
|
16
|
-
"mioku-plugin-boot",
|
|
17
|
-
"mioku-plugin-help",
|
|
18
|
-
"mioku-plugin-chat",
|
|
19
|
-
"mioku-service-config",
|
|
20
|
-
"mioku-service-ai",
|
|
21
|
-
"mioku-service-screenshot",
|
|
22
|
-
"mioku-service-help"
|
|
23
|
-
];
|
|
24
10
|
const PLUGIN_PREFIX = "mioku-plugin-";
|
|
25
11
|
const SERVICE_PREFIX = "mioku-service-";
|
|
12
|
+
const ADAPTER_PREFIX = "mioku-adapter-";
|
|
13
|
+
const NPM_REGISTRY = "https://registry.npmjs.org";
|
|
14
|
+
const OFFICIAL_REGISTRY_URL = "https://raw.githubusercontent.com/mioku-lab/mioku/main/official-registry.json";
|
|
15
|
+
async function searchNpm(query, size = 250) {
|
|
16
|
+
try {
|
|
17
|
+
const url = `${NPM_REGISTRY}/-/v1/search?text=${encodeURIComponent(query)}&size=${size}`;
|
|
18
|
+
const res = await fetch(url, { headers: {
|
|
19
|
+
Accept: "application/json",
|
|
20
|
+
"User-Agent": "mioku-cli"
|
|
21
|
+
} });
|
|
22
|
+
if (!res.ok) return [];
|
|
23
|
+
const data = await res.json();
|
|
24
|
+
const hits = [];
|
|
25
|
+
for (const obj of data.objects ?? []) {
|
|
26
|
+
const pkg = obj.package ?? {};
|
|
27
|
+
const name = String(pkg.name ?? "").trim();
|
|
28
|
+
if (!name) continue;
|
|
29
|
+
hits.push({
|
|
30
|
+
name,
|
|
31
|
+
description: String(pkg.description ?? "").trim(),
|
|
32
|
+
version: String(pkg.version ?? "").trim(),
|
|
33
|
+
keywords: Array.isArray(pkg.keywords) ? pkg.keywords.map(String) : []
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
return hits;
|
|
37
|
+
} catch {
|
|
38
|
+
return [];
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
async function searchMiokuPackages(prefix) {
|
|
42
|
+
const [broad, targeted] = await Promise.all([searchNpm("mioku"), searchNpm(prefix.replace(/-$/, ""))]);
|
|
43
|
+
const seen = new Set();
|
|
44
|
+
const hits = [];
|
|
45
|
+
for (const hit of [...broad, ...targeted]) {
|
|
46
|
+
if (!hit.name.startsWith(prefix)) continue;
|
|
47
|
+
if (!hit.keywords.includes("mioku")) continue;
|
|
48
|
+
if (seen.has(hit.name)) continue;
|
|
49
|
+
seen.add(hit.name);
|
|
50
|
+
hits.push(hit);
|
|
51
|
+
}
|
|
52
|
+
return hits.sort((a, b) => a.name.localeCompare(b.name));
|
|
53
|
+
}
|
|
54
|
+
async function fetchOfficialRegistry() {
|
|
55
|
+
try {
|
|
56
|
+
const res = await fetch(OFFICIAL_REGISTRY_URL, { headers: {
|
|
57
|
+
Accept: "application/json",
|
|
58
|
+
"User-Agent": "mioku-cli"
|
|
59
|
+
} });
|
|
60
|
+
if (!res.ok) return null;
|
|
61
|
+
return await res.json();
|
|
62
|
+
} catch {
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
async function fetchNpmPackageMeta(packageName) {
|
|
67
|
+
try {
|
|
68
|
+
const res = await fetch(`${NPM_REGISTRY}/${encodeURIComponent(packageName)}`, { headers: {
|
|
69
|
+
Accept: "application/json",
|
|
70
|
+
"User-Agent": "mioku-cli"
|
|
71
|
+
} });
|
|
72
|
+
if (!res.ok) return null;
|
|
73
|
+
const data = await res.json();
|
|
74
|
+
const latest = String(data?.["dist-tags"]?.latest || "").trim();
|
|
75
|
+
const version$1 = latest ? data?.versions?.[latest] ?? {} : {};
|
|
76
|
+
return {
|
|
77
|
+
version: latest,
|
|
78
|
+
description: String(version$1?.description || "").trim(),
|
|
79
|
+
keywords: Array.isArray(version$1?.keywords) ? version$1.keywords.map(String) : [],
|
|
80
|
+
mioku: version$1?.mioku
|
|
81
|
+
};
|
|
82
|
+
} catch {
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
function declaredServicesOf(meta) {
|
|
87
|
+
const mioku = meta?.mioku;
|
|
88
|
+
if (Array.isArray(mioku)) return mioku.filter((s) => typeof s === "string" && s.length > 0);
|
|
89
|
+
if (mioku && typeof mioku === "object") {
|
|
90
|
+
const services = mioku.services;
|
|
91
|
+
if (Array.isArray(services)) return services.filter((s) => typeof s === "string" && s.length > 0);
|
|
92
|
+
}
|
|
93
|
+
return [];
|
|
94
|
+
}
|
|
95
|
+
async function resolveRequiredServices(pluginNames) {
|
|
96
|
+
const registry = await fetchOfficialRegistry();
|
|
97
|
+
const serviceMap = new Map();
|
|
98
|
+
if (registry) {
|
|
99
|
+
for (const [short, entry] of Object.entries(registry.services ?? {})) if (entry?.npm) serviceMap.set(short, entry.npm);
|
|
100
|
+
}
|
|
101
|
+
const required = new Set();
|
|
102
|
+
for (const pluginName of pluginNames) {
|
|
103
|
+
const meta = await fetchNpmPackageMeta(pluginName);
|
|
104
|
+
for (const short of declaredServicesOf(meta)) {
|
|
105
|
+
const npm = serviceMap.get(short) ?? `${SERVICE_PREFIX}${short}`;
|
|
106
|
+
if (serviceMap.has(short)) {
|
|
107
|
+
required.add(npm);
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
const check = await fetchNpmPackageMeta(npm);
|
|
111
|
+
if (check && check.keywords.includes("mioku")) required.add(npm);
|
|
112
|
+
else consola.default.warn(`${pluginName} 声明了服务 "${short}",但未找到对应的 mioku 服务包,已跳过`);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return Array.from(required);
|
|
116
|
+
}
|
|
117
|
+
async function multiSelect(message, items, initial = []) {
|
|
118
|
+
if (items.length === 0) return [];
|
|
119
|
+
const result = await consola.default.prompt(message, {
|
|
120
|
+
type: "multiselect",
|
|
121
|
+
options: items,
|
|
122
|
+
initial,
|
|
123
|
+
cancel: "reject"
|
|
124
|
+
});
|
|
125
|
+
return result.map((item) => typeof item === "string" ? item : item.value);
|
|
126
|
+
}
|
|
127
|
+
function runAdapterCli(name, cwd) {
|
|
128
|
+
const binPath = node_path.default.join(cwd, "node_modules", ".bin", `mioku-adapter-${name}`);
|
|
129
|
+
if (node_fs.default.existsSync(binPath)) {
|
|
130
|
+
run(binPath, [], { cwd });
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
run("bunx", [`mioku-adapter-${name}`], { cwd });
|
|
134
|
+
}
|
|
135
|
+
function shortNameOfPackage(pkgName) {
|
|
136
|
+
for (const prefix of [
|
|
137
|
+
PLUGIN_PREFIX,
|
|
138
|
+
SERVICE_PREFIX,
|
|
139
|
+
ADAPTER_PREFIX
|
|
140
|
+
]) if (pkgName.startsWith(prefix)) return pkgName.slice(prefix.length);
|
|
141
|
+
return pkgName;
|
|
142
|
+
}
|
|
26
143
|
function run(cmd, args$1 = [], options = {}) {
|
|
27
144
|
require_exec.runCommandInherit(cmd, args$1, options);
|
|
28
145
|
}
|
|
@@ -77,18 +194,18 @@ function execAdd(packages, cwd) {
|
|
|
77
194
|
console.log(`执行: ${cmd} ${args$1.join(" ")}`);
|
|
78
195
|
run(cmd, args$1, { cwd });
|
|
79
196
|
}
|
|
80
|
-
function
|
|
197
|
+
function appendToMiokuPlugins(cwd, pkgName) {
|
|
81
198
|
if (!pkgName.startsWith(PLUGIN_PREFIX)) return false;
|
|
82
199
|
const shortName = pkgName.slice(PLUGIN_PREFIX.length);
|
|
83
200
|
const packageJsonPath = node_path.default.join(cwd, "package.json");
|
|
84
201
|
if (!node_fs.default.existsSync(packageJsonPath)) return false;
|
|
85
202
|
const pkg = JSON.parse((0, node_fs.readFileSync)(packageJsonPath, "utf-8"));
|
|
86
|
-
const
|
|
87
|
-
const plugins = Array.isArray(
|
|
203
|
+
const mioku = pkg.mioku ?? {};
|
|
204
|
+
const plugins = Array.isArray(mioku.plugins) ? [...mioku.plugins] : [];
|
|
88
205
|
if (plugins.includes(shortName)) return false;
|
|
89
206
|
plugins.push(shortName);
|
|
90
|
-
pkg.
|
|
91
|
-
...
|
|
207
|
+
pkg.mioku = {
|
|
208
|
+
...mioku,
|
|
92
209
|
plugins
|
|
93
210
|
};
|
|
94
211
|
node_fs.default.writeFileSync(packageJsonPath, `${JSON.stringify(pkg, null, 2)}\n`);
|
|
@@ -109,7 +226,6 @@ async function getInstalledPackages(cwd) {
|
|
|
109
226
|
function withRoot(p) {
|
|
110
227
|
return node_path.default.resolve(process.cwd(), p);
|
|
111
228
|
}
|
|
112
|
-
const NPM_REGISTRY = "https://registry.npmjs.org";
|
|
113
229
|
async function fetchNpmKeywords(packageName) {
|
|
114
230
|
try {
|
|
115
231
|
const res = await fetch(`${NPM_REGISTRY}/${encodeURIComponent(packageName)}`, { headers: {
|
|
@@ -218,8 +334,8 @@ async function installCommand(cmdArgs, helpInfo) {
|
|
|
218
334
|
consola.default.success(`已安装 ${normalized}`);
|
|
219
335
|
if (type === "plugin") {
|
|
220
336
|
const shortName = normalized.slice(PLUGIN_PREFIX.length);
|
|
221
|
-
if (
|
|
222
|
-
else consola.default.info(`${shortName} 已在
|
|
337
|
+
if (appendToMiokuPlugins(cwd, normalized)) consola.default.success(`已在 mioku.plugins 中启用 ${shortName}`);
|
|
338
|
+
else consola.default.info(`${shortName} 已在 mioku.plugins 中,跳过`);
|
|
223
339
|
}
|
|
224
340
|
return 0;
|
|
225
341
|
} catch {
|
|
@@ -305,7 +421,20 @@ async function updateCommand(cmdArgs) {
|
|
|
305
421
|
|
|
306
422
|
//#endregion
|
|
307
423
|
//#region src/cli/scaffold.ts
|
|
308
|
-
|
|
424
|
+
/** stdin 会话对应的主人标识,默认追加到 mioku.owners */
|
|
425
|
+
const STDIN_OWNER = "stdin";
|
|
426
|
+
/** 系统自带适配器:必装且不可取消,默认启用 */
|
|
427
|
+
const SYSTEM_ADAPTERS = ["mioku-adapter-stdin"];
|
|
428
|
+
/** 系统自带插件:必装且不可取消 */
|
|
429
|
+
const SYSTEM_PLUGINS = ["mioku-plugin-help", "mioku-plugin-chat"];
|
|
430
|
+
/** 系统服务:框架运行所必需,无条件安装 */
|
|
431
|
+
const SYSTEM_SERVICES = [
|
|
432
|
+
"mioku-service-ai",
|
|
433
|
+
"mioku-service-config",
|
|
434
|
+
"mioku-service-screenshot",
|
|
435
|
+
"mioku-service-help"
|
|
436
|
+
];
|
|
437
|
+
async function createNewProject(name, fileTree) {
|
|
309
438
|
const projectPath = withRoot(`./${name}`);
|
|
310
439
|
if (node_fs.default.existsSync(projectPath)) {
|
|
311
440
|
const overwrite = await confirm(`项目 ${name} 已存在,是否覆盖?`);
|
|
@@ -321,10 +450,23 @@ async function createNewProject(name, fileTree, installWebui = false) {
|
|
|
321
450
|
node_fs.default.mkdirSync(projectPath, { recursive: true });
|
|
322
451
|
makeFileTree(fileTree, projectPath);
|
|
323
452
|
console.log(`项目 ${name} 创建成功!`);
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
453
|
+
console.log("正在安装基础依赖 (bun i) ...");
|
|
454
|
+
run("bun", ["i"], { cwd: projectPath });
|
|
455
|
+
return projectPath;
|
|
456
|
+
}
|
|
457
|
+
async function selectPackages(message, prefix, initial = [], options = {}) {
|
|
458
|
+
console.log(`\n正在从 npm 拉取 ${prefix}* 包...`);
|
|
459
|
+
const hits = await searchMiokuPackages(prefix);
|
|
460
|
+
if (hits.length === 0) {
|
|
461
|
+
consola.default.warn(`未在 npm 上找到任何 ${prefix}* 包`);
|
|
462
|
+
return [];
|
|
463
|
+
}
|
|
464
|
+
const excludeSet = new Set(options.exclude ?? []);
|
|
465
|
+
const items = hits.filter((hit) => !excludeSet.has(hit.name)).map((hit) => ({
|
|
466
|
+
label: `${hit.name} (${hit.description || "暂无介绍"})`,
|
|
467
|
+
value: hit.name
|
|
468
|
+
}));
|
|
469
|
+
return multiSelect(message, items, initial);
|
|
328
470
|
}
|
|
329
471
|
async function scaffoldCommand(version$1) {
|
|
330
472
|
const name = await input("请输入项目名称", {
|
|
@@ -337,41 +479,31 @@ async function scaffoldCommand(version$1) {
|
|
|
337
479
|
default: "",
|
|
338
480
|
required: true
|
|
339
481
|
});
|
|
340
|
-
const host = await input("请输入 NapCat WS 主机", {
|
|
341
|
-
default: "localhost",
|
|
342
|
-
placeholder: "localhost",
|
|
343
|
-
required: true
|
|
344
|
-
});
|
|
345
|
-
const port = parseInt(await input("请输入 NapCat WS 端口", {
|
|
346
|
-
default: "3001",
|
|
347
|
-
placeholder: "3001",
|
|
348
|
-
required: true
|
|
349
|
-
}), 10);
|
|
350
|
-
const token = await input("请输入 NapCat WS Token(如无则留空)", { placeholder: "请输入" });
|
|
351
482
|
ensurePackageManager();
|
|
352
|
-
const ownersList = String(owners).split(",").map((o) => o.trim()).join(", ");
|
|
483
|
+
const ownersList = [...String(owners).split(",").map((o) => o.trim()).filter(Boolean), STDIN_OWNER].join(", ");
|
|
484
|
+
const adapterNames = await selectPackages("选择要安装的适配器(上下键选择,空格勾选,回车确认,系统适配器 stdin 将自动安装)", ADAPTER_PREFIX, [], { exclude: SYSTEM_ADAPTERS });
|
|
485
|
+
const allAdapterNames = [...SYSTEM_ADAPTERS, ...adapterNames];
|
|
486
|
+
if (adapterNames.length === 0) consola.default.warn("未选择其他适配器,将仅启用系统适配器 stdin(终端输入)");
|
|
353
487
|
const pkgJson = (0, dedent.default)(`
|
|
354
488
|
{
|
|
355
489
|
"name": "${name}",
|
|
356
490
|
"private": true,
|
|
357
491
|
"type": "module",
|
|
358
|
-
"dependencies": {
|
|
359
|
-
|
|
360
|
-
"
|
|
492
|
+
"dependencies": {
|
|
493
|
+
"mioku": "latest"
|
|
494
|
+
${allAdapterNames.map((pkg$1) => `,\n "${pkg$1}": "latest"`).join("")}
|
|
495
|
+
},
|
|
496
|
+
"mioku": {
|
|
497
|
+
"prefix": ".",
|
|
361
498
|
"owners": [${ownersList}],
|
|
362
499
|
"admins": [],
|
|
363
|
-
"plugins": ["
|
|
500
|
+
"plugins": ["demo"],
|
|
364
501
|
"log_level": "info",
|
|
365
502
|
"online_push": false,
|
|
366
503
|
"error_push": false,
|
|
367
|
-
"
|
|
368
|
-
{
|
|
369
|
-
|
|
370
|
-
"port": ${port},
|
|
371
|
-
"host": "${host}",
|
|
372
|
-
"token": "${token}"
|
|
373
|
-
}
|
|
374
|
-
]
|
|
504
|
+
"adapters": {
|
|
505
|
+
"stdin": {}
|
|
506
|
+
}
|
|
375
507
|
},
|
|
376
508
|
"scripts": {
|
|
377
509
|
"start": "bun run app.ts",
|
|
@@ -407,8 +539,38 @@ async function scaffoldCommand(version$1) {
|
|
|
407
539
|
config: {},
|
|
408
540
|
data: {}
|
|
409
541
|
};
|
|
542
|
+
const projectPath = await createNewProject(name, fileTree);
|
|
543
|
+
for (const adapterPkg of adapterNames) {
|
|
544
|
+
const adapterName = shortNameOfPackage(adapterPkg);
|
|
545
|
+
consola.default.info(`正在运行 ${adapterPkg} 配置向导...`);
|
|
546
|
+
runAdapterCli(adapterName, projectPath);
|
|
547
|
+
}
|
|
548
|
+
consola.default.info(`已自动安装并启用系统适配器: ${SYSTEM_ADAPTERS.map(shortNameOfPackage).join(", ")}`);
|
|
549
|
+
const pluginNames = await selectPackages("选择要安装的插件(上下键选择,空格勾选,回车确认)", PLUGIN_PREFIX, [], { exclude: SYSTEM_PLUGINS });
|
|
550
|
+
consola.default.info(`系统插件将自动安装: ${SYSTEM_PLUGINS.map(shortNameOfPackage).join(", ")}`);
|
|
551
|
+
const enabledPlugins = [
|
|
552
|
+
"demo",
|
|
553
|
+
...SYSTEM_PLUGINS.map(shortNameOfPackage),
|
|
554
|
+
...pluginNames.map(shortNameOfPackage)
|
|
555
|
+
];
|
|
556
|
+
const pkgPath = node_path.default.join(projectPath, "package.json");
|
|
557
|
+
const pkg = JSON.parse(node_fs.default.readFileSync(pkgPath, "utf-8"));
|
|
558
|
+
pkg.mioku = {
|
|
559
|
+
...pkg.mioku,
|
|
560
|
+
plugins: enabledPlugins
|
|
561
|
+
};
|
|
562
|
+
node_fs.default.writeFileSync(pkgPath, `${JSON.stringify(pkg, null, 2)}\n`);
|
|
563
|
+
const serviceNames = new Set(SYSTEM_SERVICES);
|
|
564
|
+
for (const service of await resolveRequiredServices(pluginNames)) serviceNames.add(service);
|
|
565
|
+
consola.default.info(`将自动安装服务: ${Array.from(serviceNames).map(shortNameOfPackage).join(", ")}`);
|
|
410
566
|
const installWebui = await confirm("是否安装 WebUI 管理面板?(建议安装)", { initial: true });
|
|
411
|
-
|
|
567
|
+
const addPackages = [...pluginNames, ...Array.from(serviceNames)];
|
|
568
|
+
if (installWebui) addPackages.push("mioku-service-webui");
|
|
569
|
+
if (addPackages.length > 0) {
|
|
570
|
+
const [cmd, args$1] = getAddCommand(addPackages);
|
|
571
|
+
console.log(`正在安装插件与服务: ${cmd} ${args$1.join(" ")}`);
|
|
572
|
+
run(cmd, args$1, { cwd: projectPath });
|
|
573
|
+
}
|
|
412
574
|
console.log("\n若需启动机器人,请运行:");
|
|
413
575
|
console.log(" cd", name);
|
|
414
576
|
console.log(" bun run start");
|
|
@@ -423,7 +585,7 @@ const args = process.argv.slice(2);
|
|
|
423
585
|
v: "version",
|
|
424
586
|
h: "help"
|
|
425
587
|
} });
|
|
426
|
-
const helpInfo = buildHelpInfo(version);
|
|
588
|
+
const helpInfo = buildHelpInfo(require_exec.version);
|
|
427
589
|
const [cmd, ...cmdArgs] = args;
|
|
428
590
|
switch (cmd) {
|
|
429
591
|
case "install":
|
|
@@ -434,14 +596,14 @@ const args = process.argv.slice(2);
|
|
|
434
596
|
return;
|
|
435
597
|
default:
|
|
436
598
|
if (cli.version) {
|
|
437
|
-
console.log(`v${version}`);
|
|
599
|
+
console.log(`v${require_exec.version}`);
|
|
438
600
|
return;
|
|
439
601
|
}
|
|
440
602
|
if (cli.help) {
|
|
441
603
|
console.log(helpInfo);
|
|
442
604
|
return;
|
|
443
605
|
}
|
|
444
|
-
process.exitCode = await scaffoldCommand(version);
|
|
606
|
+
process.exitCode = await scaffoldCommand(require_exec.version);
|
|
445
607
|
return;
|
|
446
608
|
}
|
|
447
609
|
})();
|
package/dist/cli/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["cmd: string","args: string[]","options: { cwd?: string }","args","dir: string","err: any","packages: string[]","cwd?: string","cwd: string","pkgName: string","p: string","packageName: string","fileTree: Record<string, string | Record<string, unknown>>","base: string","version: string","version","message: string","options?: OmitTypeWithRequired<{ initial?: boolean }>","options?: OmitTypeWithRequired<{ default?: string; placeholder?: string }>","cmdArgs: string[]","helpInfo: string","pkgName: string","packages: string[]","cwd: string","prefix: string","name?: string","cmdArgs: string[]","name: string","fileTree: Record<string, string | Record<string, unknown>>","args","version: string","version"],"sources":["../../package.json","../../src/cli/shared.ts","../../src/cli/install.ts","../../src/cli/update.ts","../../src/cli/scaffold.ts","../../src/cli/index.ts"],"sourcesContent":["{\n \"name\": \"mioku\",\n \"type\": \"module\",\n \"version\": \"0.9.8\",\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/index.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","import fs, { readFileSync } from \"node:fs\";\nimport path from \"node:path\";\nimport consola from \"consola\";\nimport dedent from \"dedent\";\nimport {\n clearCommandCache,\n commandExists,\n resolveCommand,\n runCommandInherit,\n} from \"../core/exec\";\n\nexport const 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\nexport const PLUGIN_PREFIX = \"mioku-plugin-\";\nexport const SERVICE_PREFIX = \"mioku-service-\";\n\nexport function run(\n cmd: string,\n args: string[] = [],\n options: { cwd?: string } = {},\n): void {\n runCommandInherit(cmd, args, options);\n}\n\nexport async function rmrf(dir: string, retries = 5): Promise<void> {\n for (let i = 0; i < retries; i++) {\n try {\n fs.rmSync(dir, { recursive: true, force: true });\n return;\n } catch (err: any) {\n if (i === retries - 1) throw err;\n const code = err?.code;\n if (\n code === \"EPERM\" ||\n code === \"EBUSY\" ||\n code === \"ENOTEMPTY\" ||\n code === \"ENOENT\"\n ) {\n await new Promise((resolve) => setTimeout(resolve, 300 * (i + 1)));\n } else {\n throw err;\n }\n }\n }\n}\n\nexport function hasCommand(cmd: string): boolean {\n return commandExists(cmd);\n}\n\nfunction findNpmPath(): string | null {\n const resolved = resolveCommand(\"npm\");\n if (resolved) return resolved;\n if (process.platform !== \"win32\") return null;\n\n const fallbacks = [\n path.join(process.env.ProgramFiles || \"\", \"nodejs\", \"npm.cmd\"),\n path.join(process.env[\"ProgramFiles(x86)\"] || \"\", \"nodejs\", \"npm.cmd\"),\n path.join(process.env.APPDATA || \"\", \"npm\", \"npm.cmd\"),\n ];\n\n return fallbacks.find((candidate) => resolveCommand(candidate)) ?? null;\n}\n\nexport function ensurePackageManager(): void {\n if (hasCommand(\"bun\")) return;\n console.log(\"安装 bun...\");\n const npmPath = findNpmPath();\n if (!npmPath) {\n consola.error(\"未找到 npm,请确保 Node.js 已安装并包含 npm\");\n process.exit(1);\n }\n run(npmPath, [\"install\", \"-g\", \"bun\"]);\n // bun was just put on PATH; drop the cached miss so the next lookup finds it.\n clearCommandCache();\n}\n\nexport function getAddCommand(packages: string[]): [string, string[]] {\n return [\"bun\", [\"add\", ...packages]];\n}\n\nexport function normalizePackageName(input: string): string {\n if (input.startsWith(PLUGIN_PREFIX) || input.startsWith(SERVICE_PREFIX)) {\n return input;\n }\n if (input.startsWith(\"mioku-\")) return input;\n return `${PLUGIN_PREFIX}${input}`;\n}\n\nexport function detectType(name: string): \"plugin\" | \"service\" | \"unknown\" {\n if (name.startsWith(PLUGIN_PREFIX)) return \"plugin\";\n if (name.startsWith(SERVICE_PREFIX)) return \"service\";\n return \"unknown\";\n}\n\nexport function execAdd(packages: string[], cwd?: string): void {\n const [cmd, args] = getAddCommand(packages);\n console.log(`执行: ${cmd} ${args.join(\" \")}`);\n run(cmd, args, { cwd });\n}\n\nexport function appendToMiokiPlugins(cwd: string, pkgName: string): boolean {\n if (!pkgName.startsWith(PLUGIN_PREFIX)) return false;\n const shortName = pkgName.slice(PLUGIN_PREFIX.length);\n\n const packageJsonPath = path.join(cwd, \"package.json\");\n if (!fs.existsSync(packageJsonPath)) return false;\n\n const pkg = JSON.parse(readFileSync(packageJsonPath, \"utf-8\"));\n const mioki = pkg.mioki ?? {};\n const plugins = Array.isArray(mioki.plugins) ? [...mioki.plugins] : [];\n if (plugins.includes(shortName)) return false;\n\n plugins.push(shortName);\n pkg.mioki = { ...mioki, plugins };\n fs.writeFileSync(packageJsonPath, `${JSON.stringify(pkg, null, 2)}\\n`);\n return true;\n}\n\nexport async function getInstalledPackages(cwd: string): Promise<string[]> {\n try {\n const pkg = JSON.parse(readFileSync(path.join(cwd, \"package.json\"), \"utf-8\"));\n const deps = { ...pkg.dependencies, ...pkg.devDependencies };\n return Object.keys(deps).filter((k) => k.startsWith(\"mioku-\"));\n } catch {\n return [];\n }\n}\n\nexport function withRoot(p: string): string {\n return path.resolve(process.cwd(), p);\n}\n\nconst NPM_REGISTRY = \"https://registry.npmjs.org\";\n\nexport async function fetchNpmKeywords(\n packageName: string,\n): Promise<string[] | null> {\n try {\n const res = await fetch(`${NPM_REGISTRY}/${encodeURIComponent(packageName)}`, {\n headers: { Accept: \"application/json\", \"User-Agent\": \"mioku-cli\" },\n });\n if (!res.ok) return null;\n const data = (await res.json()) as any;\n const latestVersion = String(data?.[\"dist-tags\"]?.latest || \"\").trim();\n const keywords = latestVersion\n ? data?.versions?.[latestVersion]?.keywords\n : data?.keywords;\n return Array.isArray(keywords) ? keywords.map(String) : [];\n } catch {\n return null;\n }\n}\n\nexport function gracefullyExit(): void {\n console.log(\"Bye!\");\n process.exit(0);\n}\n\nexport function makeFileTree(\n fileTree: Record<string, string | Record<string, unknown>>,\n base: string,\n): void {\n for (const [name, content] of Object.entries(fileTree)) {\n if (typeof content === \"object\" && content !== null) {\n const subPath = `${base}/${name}`;\n if (!fs.existsSync(subPath)) fs.mkdirSync(subPath, { recursive: true });\n for (const [subName, subContent] of Object.entries(content)) {\n if (typeof subContent === \"object\") {\n makeFileTree(\n subContent as Record<string, string | Record<string, unknown>>,\n path.join(subPath, subName),\n );\n } else {\n fs.writeFileSync(`${subPath}/${subName}`, subContent as string);\n }\n }\n } else {\n const filePath = `${base}/${name}`;\n const dirname = path.dirname(filePath);\n if (!fs.existsSync(dirname)) fs.mkdirSync(dirname, { recursive: true });\n fs.writeFileSync(filePath, content as string);\n }\n }\n}\n\nexport function buildHelpInfo(version: string): string {\n return dedent(`\n mioku 命令行工具 v${version}\n\n 用法: mioku <命令> [选项]\n\n 命令:\n install plugin <名称> 安装插件,自动补全 mioku-plugin- 前缀\n install service <名称> 安装服务,自动补全 mioku-service- 前缀\n update [包名|self|all] 更新插件或服务\n update - 检查可用更新\n update all - 更新所有 mioku- 包\n update self - 更新 mioku 框架\n update xxx - 更新指定包\n\n 选项:\n -h, --help 显示帮助信息\n -v, --version 显示版本号\n --name <name> 指定项目/文件夹名称,默认 mioku-bot\n --protocol <protocol> 指定 NapCat 协议,默认 ws\n --host <host> 指定 NapCat 主机,默认 localhost\n --port <port> 指定 NapCat 端口,默认 3001\n --token <token> 指定 NapCat 连接 Token,默认空\n --prefix <prefix> 指定命令前缀,默认 #\n --owners <owners> 指定主人 QQ,英文逗号分隔,必填\n --admins <admins> 指定管理员 QQ,英文逗号分隔,可空\n --use-npm-mirror 使用 npm 镜像源加速依赖安装,默认否\n `);\n}\n\ntype OmitTypeWithRequired<T> = Omit<T, \"type\" | \"required\"> & {\n required?: boolean;\n};\n\nexport async function confirm(\n message: string,\n options?: OmitTypeWithRequired<{ initial?: boolean }>,\n): Promise<boolean> {\n return consola.prompt(message, {\n type: \"confirm\",\n cancel: \"reject\",\n ...options,\n });\n}\n\nexport async function input(\n message: string,\n options?: OmitTypeWithRequired<{ default?: string; placeholder?: string }>,\n): Promise<string> {\n const result = await consola.prompt(message, {\n type: \"text\",\n cancel: \"reject\",\n ...options,\n });\n if (options?.required && !result) return input(message, options);\n return result;\n}\n","import consola from \"consola\";\nimport {\n ensurePackageManager,\n appendToMiokiPlugins,\n execAdd,\n fetchNpmKeywords,\n PLUGIN_PREFIX,\n SERVICE_PREFIX,\n confirm,\n} from \"./shared\";\n\nexport async function installCommand(\n cmdArgs: string[],\n helpInfo: string,\n): Promise<number> {\n ensurePackageManager();\n const cwd = process.cwd();\n const [type, name] = cmdArgs;\n\n if (!type || !name) {\n consola.error(\n \"请指定类型和名称: mioku install plugin <名称> 或 mioku install service <名称>\",\n );\n console.log(helpInfo);\n return 1;\n }\n\n if (type !== \"plugin\" && type !== \"service\") {\n consola.error(`无效的类型 \"${type}\",请使用 plugin 或 service`);\n console.log(helpInfo);\n return 1;\n }\n\n const prefix = type === \"plugin\" ? PLUGIN_PREFIX : SERVICE_PREFIX;\n const normalized = `${prefix}${name}`;\n\n if (type === \"plugin\") {\n const proceed = await warnIfPrivatePlugin(normalized);\n if (!proceed) {\n consola.info(\"已取消安装\");\n return 1;\n }\n }\n\n try {\n execAdd([normalized], cwd);\n consola.success(`已安装 ${normalized}`);\n\n if (type === \"plugin\") {\n const shortName = normalized.slice(PLUGIN_PREFIX.length);\n if (appendToMiokiPlugins(cwd, normalized)) {\n consola.success(`已在 mioki.plugins 中启用 ${shortName}`);\n } else {\n consola.info(`${shortName} 已在 mioki.plugins 中,跳过`);\n }\n }\n return 0;\n } catch {\n consola.error(`安装失败: ${normalized}`);\n return 1;\n }\n}\n\nasync function warnIfPrivatePlugin(pkgName: string): Promise<boolean> {\n const keywords = await fetchNpmKeywords(pkgName);\n if (keywords === null) return true;\n if (keywords.includes(\"mioku\")) return true;\n\n consola.warn(`${pkgName} 看起来是私有插件\"`);\n consola.warn(\"该插件未上架插件市场,可能存在风险\");\n return confirm(\"仍要继续安装吗?\", { initial: false });\n}\n","import consola from \"consola\";\nimport {\n run,\n ensurePackageManager,\n getInstalledPackages,\n PLUGIN_PREFIX,\n SERVICE_PREFIX,\n} from \"./shared\";\n\nasync function updatePackages(packages: string[], cwd: string): Promise<void> {\n if (packages.length === 0) {\n consola.info(\"未找到 mioku- 相关依赖\");\n return;\n }\n console.log(`执行: bun update ${packages.join(\" \")} --latest`);\n run(\"bun\", [\"update\", ...packages, \"--latest\"], { cwd });\n}\n\nasync function updateByPrefix(\n prefix: string,\n cwd: string,\n name?: string,\n): Promise<void> {\n if (name) {\n const normalized = name.startsWith(prefix) ? name : `${prefix}${name}`;\n console.log(`执行: bun update ${normalized} --latest`);\n run(\"bun\", [\"update\", normalized, \"--latest\"], { cwd });\n return;\n }\n const packages = (await getInstalledPackages(cwd)).filter((p) =>\n p.startsWith(prefix),\n );\n if (packages.length === 0) {\n consola.info(`未找到 ${prefix}* 相关依赖`);\n return;\n }\n await updatePackages(packages, cwd);\n}\n\nexport async function updateCommand(cmdArgs: string[]): Promise<number> {\n ensurePackageManager();\n const cwd = process.cwd();\n const [target, name] = cmdArgs;\n\n if (!target || target === \"check\") {\n run(\"bun\", [\"update\", \"-i\"], { cwd });\n return 0;\n }\n\n if (target === \"all\") {\n await updatePackages(await getInstalledPackages(cwd), cwd);\n return 0;\n }\n\n if (target === \"self\") {\n console.log(\"执行: bun update mioku --latest\");\n run(\"bun\", [\"update\", \"mioku\", \"--latest\"], { cwd });\n return 0;\n }\n\n if (target === \"plugin\" || target === \"service\") {\n const prefix = target === \"plugin\" ? PLUGIN_PREFIX : SERVICE_PREFIX;\n await updateByPrefix(prefix, cwd, name);\n return 0;\n }\n\n console.log(`执行: bun update ${target} --latest`);\n run(\"bun\", [\"update\", target, \"--latest\"], { cwd });\n return 0;\n}\n","import fs from \"node:fs\";\nimport dedent from \"dedent\";\nimport {\n DEFAULT_PACKAGES,\n ensurePackageManager,\n getAddCommand,\n run,\n rmrf,\n withRoot,\n gracefullyExit,\n makeFileTree,\n input,\n confirm,\n} from \"./shared\";\n\nasync function createNewProject(\n name: string,\n fileTree: Record<string, string | Record<string, unknown>>,\n installWebui = false,\n): Promise<void> {\n const projectPath = withRoot(`./${name}`);\n\n if (fs.existsSync(projectPath)) {\n const overwrite = await confirm(`项目 ${name} 已存在,是否覆盖?`);\n if (!overwrite) gracefullyExit();\n\n if (projectPath === process.cwd()) {\n if (fs.readdirSync(projectPath).length !== 0) {\n const confirmOver = await confirm(\n \"项目路径与当前路径相同,将删除当前目录下所有内容再创建,是否继续?\",\n );\n if (!confirmOver) gracefullyExit();\n }\n }\n await rmrf(projectPath);\n }\n\n fs.mkdirSync(projectPath, { recursive: true });\n makeFileTree(fileTree, projectPath);\n console.log(`项目 ${name} 创建成功!`);\n\n const packages = installWebui\n ? [...DEFAULT_PACKAGES, \"mioku-service-webui\"]\n : DEFAULT_PACKAGES;\n const [cmd, args] = getAddCommand(packages);\n console.log(`正在安装 Mioku 依赖: ${cmd} ${args.join(\" \")}`);\n run(cmd, args, { cwd: projectPath });\n}\n\nexport async function scaffoldCommand(version: string): Promise<number> {\n const name = await input(\"请输入项目名称\", {\n default: \"mioku-bot\",\n placeholder: \"mioku-bot\",\n required: true,\n });\n const owners = await input(\"请输入主人 QQ (最高权限,英文逗号分隔,必填)\", {\n placeholder: \"请输入\",\n default: \"\",\n required: true,\n });\n const host = await input(\"请输入 NapCat WS 主机\", {\n default: \"localhost\",\n placeholder: \"localhost\",\n required: true,\n });\n const port = parseInt(\n await input(\"请输入 NapCat WS 端口\", {\n default: \"3001\",\n placeholder: \"3001\",\n required: true,\n }),\n 10,\n );\n const token = await input(\"请输入 NapCat WS Token(如无则留空)\", {\n placeholder: \"请输入\",\n });\n\n ensurePackageManager();\n\n const ownersList = String(owners)\n .split(\",\")\n .map((o) => o.trim())\n .join(\", \");\n\n const pkgJson = dedent(`\n {\n \"name\": \"${name}\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {},\n \"mioki\": {\n \"prefix\": \"#\",\n \"owners\": [${ownersList}],\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, string | Record<string, unknown>> = {\n \"app.ts\":\n \"import { start } from 'mioku'\\n\\nstart({ cwd: import.meta.dirname }).then()\\n\",\n \"package.json\": pkgJson,\n plugins: { demo: { \"index.ts\": pluginCode } },\n config: {},\n data: {},\n };\n\n const 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 return 0;\n}\n","#!/usr/bin/env node\n\nimport mri from \"mri\";\nimport { version } from \"../../package.json\";\nimport { buildHelpInfo } from \"./shared\";\nimport { installCommand } from \"./install\";\nimport { updateCommand } from \"./update\";\nimport { scaffoldCommand } from \"./scaffold\";\n\ninterface CliOptions {\n help?: boolean;\n version?: boolean;\n}\n\nconst args = process.argv.slice(2);\n\n(async () => {\n const cli = mri<CliOptions>(args, { alias: { v: \"version\", h: \"help\" } });\n const helpInfo = buildHelpInfo(version);\n const [cmd, ...cmdArgs] = args;\n\n switch (cmd) {\n case \"install\":\n process.exitCode = await installCommand(cmdArgs, helpInfo);\n return;\n case \"update\":\n process.exitCode = await updateCommand(cmdArgs);\n return;\n default:\n if (cli.version) {\n console.log(`v${version}`);\n return;\n }\n if (cli.help) {\n console.log(helpInfo);\n return;\n }\n process.exitCode = await scaffoldCommand(version);\n return;\n }\n})();\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["query: string","hits: NpmPackageHit[]","prefix: string","packageName: string","version","meta: NpmPackageMeta | null","pluginNames: readonly string[]","message: string","items: Array<{ label: string; value: string }>","initial: string[]","name: string","cwd: string","pkgName: string","cmd: string","args: string[]","options: { cwd?: string }","args","dir: string","err: any","packages: string[]","cwd?: string","p: string","fileTree: Record<string, string | Record<string, unknown>>","base: string","version: string","options?: OmitTypeWithRequired<{ initial?: boolean }>","options?: OmitTypeWithRequired<{ default?: string; placeholder?: string }>","cmdArgs: string[]","helpInfo: string","pkgName: string","packages: string[]","cwd: string","prefix: string","name?: string","cmdArgs: string[]","name: string","fileTree: Record<string, string | Record<string, unknown>>","message: string","prefix: string","initial: string[]","options: { exclude?: string[] }","version: string","pkg","version","args","version"],"sources":["../../src/cli/shared.ts","../../src/cli/install.ts","../../src/cli/update.ts","../../src/cli/scaffold.ts","../../src/cli/index.ts"],"sourcesContent":["import fs, { readFileSync } from \"node:fs\";\nimport path from \"node:path\";\nimport consola from \"consola\";\nimport dedent from \"dedent\";\nimport {\n clearCommandCache,\n commandExists,\n resolveCommand,\n runCommandInherit,\n} from \"../internal/exec\";\n\nexport const PLUGIN_PREFIX = \"mioku-plugin-\";\nexport const SERVICE_PREFIX = \"mioku-service-\";\nexport const ADAPTER_PREFIX = \"mioku-adapter-\";\n\nexport const NPM_REGISTRY = \"https://registry.npmjs.org\";\nexport const OFFICIAL_REGISTRY_URL =\n \"https://raw.githubusercontent.com/mioku-lab/mioku/main/official-registry.json\";\n\nexport interface NpmPackageHit {\n name: string;\n description: string;\n version: string;\n keywords: string[];\n}\n\nasync function searchNpm(query: string, size = 250): Promise<NpmPackageHit[]> {\n try {\n const url = `${NPM_REGISTRY}/-/v1/search?text=${encodeURIComponent(query)}&size=${size}`;\n const res = await fetch(url, {\n headers: { Accept: \"application/json\", \"User-Agent\": \"mioku-cli\" },\n });\n if (!res.ok) return [];\n const data = (await res.json()) as {\n objects?: Array<{\n package?: {\n name?: string;\n description?: string;\n version?: string;\n keywords?: string[];\n };\n }>;\n };\n const hits: NpmPackageHit[] = [];\n for (const obj of data.objects ?? []) {\n const pkg = obj.package ?? {};\n const name = String(pkg.name ?? \"\").trim();\n if (!name) continue;\n hits.push({\n name,\n description: String(pkg.description ?? \"\").trim(),\n version: String(pkg.version ?? \"\").trim(),\n keywords: Array.isArray(pkg.keywords) ? pkg.keywords.map(String) : [],\n });\n }\n return hits;\n } catch {\n return [];\n }\n}\n\nexport async function searchMiokuPackages(\n prefix: string,\n): Promise<NpmPackageHit[]> {\n const [broad, targeted] = await Promise.all([\n searchNpm(\"mioku\"),\n searchNpm(prefix.replace(/-$/, \"\")),\n ]);\n const seen = new Set<string>();\n const hits: NpmPackageHit[] = [];\n for (const hit of [...broad, ...targeted]) {\n if (!hit.name.startsWith(prefix)) continue;\n if (!hit.keywords.includes(\"mioku\")) continue;\n if (seen.has(hit.name)) continue;\n seen.add(hit.name);\n hits.push(hit);\n }\n return hits.sort((a, b) => a.name.localeCompare(b.name));\n}\n\nexport interface OfficialRegistryEntry {\n npm?: string;\n builtin?: boolean;\n}\n\nexport interface OfficialRegistry {\n plugins?: Record<string, OfficialRegistryEntry>;\n services?: Record<string, OfficialRegistryEntry>;\n adapters?: Record<string, OfficialRegistryEntry>;\n}\n\nexport async function fetchOfficialRegistry(): Promise<OfficialRegistry | null> {\n try {\n const res = await fetch(OFFICIAL_REGISTRY_URL, {\n headers: { Accept: \"application/json\", \"User-Agent\": \"mioku-cli\" },\n });\n if (!res.ok) return null;\n return (await res.json()) as OfficialRegistry;\n } catch {\n return null;\n }\n}\n\nexport interface NpmPackageMeta {\n version: string;\n description: string;\n keywords: string[];\n mioku?: unknown;\n}\n\nexport async function fetchNpmPackageMeta(\n packageName: string,\n): Promise<NpmPackageMeta | null> {\n try {\n const res = await fetch(\n `${NPM_REGISTRY}/${encodeURIComponent(packageName)}`,\n {\n headers: { Accept: \"application/json\", \"User-Agent\": \"mioku-cli\" },\n },\n );\n if (!res.ok) return null;\n const data = (await res.json()) as any;\n const latest = String(data?.[\"dist-tags\"]?.latest || \"\").trim();\n const version = latest ? (data?.versions?.[latest] ?? {}) : {};\n return {\n version: latest,\n description: String(version?.description || \"\").trim(),\n keywords: Array.isArray(version?.keywords)\n ? version.keywords.map(String)\n : [],\n mioku: version?.mioku,\n };\n } catch {\n return null;\n }\n}\n\nexport function declaredServicesOf(meta: NpmPackageMeta | null): string[] {\n const mioku = meta?.mioku;\n if (Array.isArray(mioku)) {\n return mioku.filter(\n (s): s is string => typeof s === \"string\" && s.length > 0,\n );\n }\n if (mioku && typeof mioku === \"object\") {\n const services = (mioku as { services?: unknown }).services;\n if (Array.isArray(services)) {\n return services.filter(\n (s): s is string => typeof s === \"string\" && s.length > 0,\n );\n }\n }\n return [];\n}\n\nexport async function resolveRequiredServices(\n pluginNames: readonly string[],\n): Promise<string[]> {\n const registry = await fetchOfficialRegistry();\n const serviceMap = new Map<string, string>();\n if (registry) {\n for (const [short, entry] of Object.entries(registry.services ?? {})) {\n if (entry?.npm) serviceMap.set(short, entry.npm);\n }\n }\n\n const required = new Set<string>();\n for (const pluginName of pluginNames) {\n const meta = await fetchNpmPackageMeta(pluginName);\n for (const short of declaredServicesOf(meta)) {\n const npm = serviceMap.get(short) ?? `${SERVICE_PREFIX}${short}`;\n if (serviceMap.has(short)) {\n required.add(npm);\n continue;\n }\n const check = await fetchNpmPackageMeta(npm);\n if (check && check.keywords.includes(\"mioku\")) {\n required.add(npm);\n } else {\n consola.warn(\n `${pluginName} 声明了服务 \"${short}\",但未找到对应的 mioku 服务包,已跳过`,\n );\n }\n }\n }\n return Array.from(required);\n}\n\nexport async function multiSelect(\n message: string,\n items: Array<{ label: string; value: string }>,\n initial: string[] = [],\n): Promise<string[]> {\n if (items.length === 0) return [];\n const result = await consola.prompt(message, {\n type: \"multiselect\",\n options: items,\n initial,\n cancel: \"reject\",\n });\n return (result as Array<string | { value: string }>).map((item) =>\n typeof item === \"string\" ? item : item.value,\n );\n}\n\nexport function runAdapterCli(name: string, cwd: string): void {\n const binPath = path.join(\n cwd,\n \"node_modules\",\n \".bin\",\n `mioku-adapter-${name}`,\n );\n if (fs.existsSync(binPath)) {\n run(binPath, [], { cwd });\n return;\n }\n run(\"bunx\", [`mioku-adapter-${name}`], { cwd });\n}\n\nexport function shortNameOfPackage(pkgName: string): string {\n for (const prefix of [PLUGIN_PREFIX, SERVICE_PREFIX, ADAPTER_PREFIX]) {\n if (pkgName.startsWith(prefix)) return pkgName.slice(prefix.length);\n }\n return pkgName;\n}\n\nexport function run(\n cmd: string,\n args: string[] = [],\n options: { cwd?: string } = {},\n): void {\n runCommandInherit(cmd, args, options);\n}\n\nexport async function rmrf(dir: string, retries = 5): Promise<void> {\n for (let i = 0; i < retries; i++) {\n try {\n fs.rmSync(dir, { recursive: true, force: true });\n return;\n } catch (err: any) {\n if (i === retries - 1) throw err;\n const code = err?.code;\n if (\n code === \"EPERM\" ||\n code === \"EBUSY\" ||\n code === \"ENOTEMPTY\" ||\n code === \"ENOENT\"\n ) {\n await new Promise((resolve) => setTimeout(resolve, 300 * (i + 1)));\n } else {\n throw err;\n }\n }\n }\n}\n\nexport function hasCommand(cmd: string): boolean {\n return commandExists(cmd);\n}\n\nfunction findNpmPath(): string | null {\n const resolved = resolveCommand(\"npm\");\n if (resolved) return resolved;\n if (process.platform !== \"win32\") return null;\n\n const fallbacks = [\n path.join(process.env.ProgramFiles || \"\", \"nodejs\", \"npm.cmd\"),\n path.join(process.env[\"ProgramFiles(x86)\"] || \"\", \"nodejs\", \"npm.cmd\"),\n path.join(process.env.APPDATA || \"\", \"npm\", \"npm.cmd\"),\n ];\n\n return fallbacks.find((candidate) => resolveCommand(candidate)) ?? null;\n}\n\nexport function ensurePackageManager(): void {\n if (hasCommand(\"bun\")) return;\n console.log(\"安装 bun...\");\n const npmPath = findNpmPath();\n if (!npmPath) {\n consola.error(\"未找到 npm,请确保 Node.js 已安装并包含 npm\");\n process.exit(1);\n }\n run(npmPath, [\"install\", \"-g\", \"bun\"]);\n // bun was just put on PATH; drop the cached miss so the next lookup finds it.\n clearCommandCache();\n}\n\nexport function getAddCommand(packages: string[]): [string, string[]] {\n return [\"bun\", [\"add\", ...packages]];\n}\n\nexport function normalizePackageName(input: string): string {\n if (input.startsWith(PLUGIN_PREFIX) || input.startsWith(SERVICE_PREFIX)) {\n return input;\n }\n if (input.startsWith(\"mioku-\")) return input;\n return `${PLUGIN_PREFIX}${input}`;\n}\n\nexport function detectType(name: string): \"plugin\" | \"service\" | \"unknown\" {\n if (name.startsWith(PLUGIN_PREFIX)) return \"plugin\";\n if (name.startsWith(SERVICE_PREFIX)) return \"service\";\n return \"unknown\";\n}\n\nexport function execAdd(packages: string[], cwd?: string): void {\n const [cmd, args] = getAddCommand(packages);\n console.log(`执行: ${cmd} ${args.join(\" \")}`);\n run(cmd, args, { cwd });\n}\n\nexport function appendToMiokuPlugins(cwd: string, pkgName: string): boolean {\n if (!pkgName.startsWith(PLUGIN_PREFIX)) return false;\n const shortName = pkgName.slice(PLUGIN_PREFIX.length);\n\n const packageJsonPath = path.join(cwd, \"package.json\");\n if (!fs.existsSync(packageJsonPath)) return false;\n\n const pkg = JSON.parse(readFileSync(packageJsonPath, \"utf-8\"));\n const mioku = pkg.mioku ?? {};\n const plugins = Array.isArray(mioku.plugins) ? [...mioku.plugins] : [];\n if (plugins.includes(shortName)) return false;\n\n plugins.push(shortName);\n pkg.mioku = { ...mioku, plugins };\n fs.writeFileSync(packageJsonPath, `${JSON.stringify(pkg, null, 2)}\\n`);\n return true;\n}\n\nexport async function getInstalledPackages(cwd: string): Promise<string[]> {\n try {\n const pkg = JSON.parse(\n readFileSync(path.join(cwd, \"package.json\"), \"utf-8\"),\n );\n const deps = { ...pkg.dependencies, ...pkg.devDependencies };\n return Object.keys(deps).filter((k) => k.startsWith(\"mioku-\"));\n } catch {\n return [];\n }\n}\n\nexport function withRoot(p: string): string {\n return path.resolve(process.cwd(), p);\n}\n\nexport async function fetchNpmKeywords(\n packageName: string,\n): Promise<string[] | null> {\n try {\n const res = await fetch(\n `${NPM_REGISTRY}/${encodeURIComponent(packageName)}`,\n {\n headers: { Accept: \"application/json\", \"User-Agent\": \"mioku-cli\" },\n },\n );\n if (!res.ok) return null;\n const data = (await res.json()) as any;\n const latestVersion = String(data?.[\"dist-tags\"]?.latest || \"\").trim();\n const keywords = latestVersion\n ? data?.versions?.[latestVersion]?.keywords\n : data?.keywords;\n return Array.isArray(keywords) ? keywords.map(String) : [];\n } catch {\n return null;\n }\n}\n\nexport function gracefullyExit(): void {\n console.log(\"Bye!\");\n process.exit(0);\n}\n\nexport function makeFileTree(\n fileTree: Record<string, string | Record<string, unknown>>,\n base: string,\n): void {\n for (const [name, content] of Object.entries(fileTree)) {\n if (typeof content === \"object\" && content !== null) {\n const subPath = `${base}/${name}`;\n if (!fs.existsSync(subPath)) fs.mkdirSync(subPath, { recursive: true });\n for (const [subName, subContent] of Object.entries(content)) {\n if (typeof subContent === \"object\") {\n makeFileTree(\n subContent as Record<string, string | Record<string, unknown>>,\n path.join(subPath, subName),\n );\n } else {\n fs.writeFileSync(`${subPath}/${subName}`, subContent as string);\n }\n }\n } else {\n const filePath = `${base}/${name}`;\n const dirname = path.dirname(filePath);\n if (!fs.existsSync(dirname)) fs.mkdirSync(dirname, { recursive: true });\n fs.writeFileSync(filePath, content as string);\n }\n }\n}\n\nexport function buildHelpInfo(version: string): string {\n return dedent(`\n mioku 命令行工具 v${version}\n\n 用法: mioku <命令> [选项]\n\n 命令:\n install plugin <名称> 安装插件,自动补全 mioku-plugin- 前缀\n install service <名称> 安装服务,自动补全 mioku-service- 前缀\n update [包名|self|all] 更新插件或服务\n update - 检查可用更新\n update all - 更新所有 mioku- 包\n update self - 更新 mioku 框架\n update xxx - 更新指定包\n\n 选项:\n -h, --help 显示帮助信息\n -v, --version 显示版本号\n --name <name> 指定项目/文件夹名称,默认 mioku-bot\n --protocol <protocol> 指定 NapCat 协议,默认 ws\n --host <host> 指定 NapCat 主机,默认 localhost\n --port <port> 指定 NapCat 端口,默认 3001\n --token <token> 指定 NapCat 连接 Token,默认空\n --prefix <prefix> 指定命令前缀,默认 #\n --owners <owners> 指定主人 QQ,英文逗号分隔,必填\n --admins <admins> 指定管理员 QQ,英文逗号分隔,可空\n --use-npm-mirror 使用 npm 镜像源加速依赖安装,默认否\n `);\n}\n\ntype OmitTypeWithRequired<T> = Omit<T, \"type\" | \"required\"> & {\n required?: boolean;\n};\n\nexport async function confirm(\n message: string,\n options?: OmitTypeWithRequired<{ initial?: boolean }>,\n): Promise<boolean> {\n return consola.prompt(message, {\n type: \"confirm\",\n cancel: \"reject\",\n ...options,\n });\n}\n\nexport async function input(\n message: string,\n options?: OmitTypeWithRequired<{ default?: string; placeholder?: string }>,\n): Promise<string> {\n const result = await consola.prompt(message, {\n type: \"text\",\n cancel: \"reject\",\n ...options,\n });\n if (options?.required && !result) return input(message, options);\n return result;\n}\n","import consola from \"consola\";\nimport {\n ensurePackageManager,\n appendToMiokuPlugins,\n execAdd,\n fetchNpmKeywords,\n PLUGIN_PREFIX,\n SERVICE_PREFIX,\n confirm,\n} from \"./shared\";\n\nexport async function installCommand(\n cmdArgs: string[],\n helpInfo: string,\n): Promise<number> {\n ensurePackageManager();\n const cwd = process.cwd();\n const [type, name] = cmdArgs;\n\n if (!type || !name) {\n consola.error(\n \"请指定类型和名称: mioku install plugin <名称> 或 mioku install service <名称>\",\n );\n console.log(helpInfo);\n return 1;\n }\n\n if (type !== \"plugin\" && type !== \"service\") {\n consola.error(`无效的类型 \"${type}\",请使用 plugin 或 service`);\n console.log(helpInfo);\n return 1;\n }\n\n const prefix = type === \"plugin\" ? PLUGIN_PREFIX : SERVICE_PREFIX;\n const normalized = `${prefix}${name}`;\n\n if (type === \"plugin\") {\n const proceed = await warnIfPrivatePlugin(normalized);\n if (!proceed) {\n consola.info(\"已取消安装\");\n return 1;\n }\n }\n\n try {\n execAdd([normalized], cwd);\n consola.success(`已安装 ${normalized}`);\n\n if (type === \"plugin\") {\n const shortName = normalized.slice(PLUGIN_PREFIX.length);\n if (appendToMiokuPlugins(cwd, normalized)) {\n consola.success(`已在 mioku.plugins 中启用 ${shortName}`);\n } else {\n consola.info(`${shortName} 已在 mioku.plugins 中,跳过`);\n }\n }\n return 0;\n } catch {\n consola.error(`安装失败: ${normalized}`);\n return 1;\n }\n}\n\nasync function warnIfPrivatePlugin(pkgName: string): Promise<boolean> {\n const keywords = await fetchNpmKeywords(pkgName);\n if (keywords === null) return true;\n if (keywords.includes(\"mioku\")) return true;\n\n consola.warn(`${pkgName} 看起来是私有插件\"`);\n consola.warn(\"该插件未上架插件市场,可能存在风险\");\n return confirm(\"仍要继续安装吗?\", { initial: false });\n}\n","import consola from \"consola\";\nimport {\n run,\n ensurePackageManager,\n getInstalledPackages,\n PLUGIN_PREFIX,\n SERVICE_PREFIX,\n} from \"./shared\";\n\nasync function updatePackages(packages: string[], cwd: string): Promise<void> {\n if (packages.length === 0) {\n consola.info(\"未找到 mioku- 相关依赖\");\n return;\n }\n console.log(`执行: bun update ${packages.join(\" \")} --latest`);\n run(\"bun\", [\"update\", ...packages, \"--latest\"], { cwd });\n}\n\nasync function updateByPrefix(\n prefix: string,\n cwd: string,\n name?: string,\n): Promise<void> {\n if (name) {\n const normalized = name.startsWith(prefix) ? name : `${prefix}${name}`;\n console.log(`执行: bun update ${normalized} --latest`);\n run(\"bun\", [\"update\", normalized, \"--latest\"], { cwd });\n return;\n }\n const packages = (await getInstalledPackages(cwd)).filter((p) =>\n p.startsWith(prefix),\n );\n if (packages.length === 0) {\n consola.info(`未找到 ${prefix}* 相关依赖`);\n return;\n }\n await updatePackages(packages, cwd);\n}\n\nexport async function updateCommand(cmdArgs: string[]): Promise<number> {\n ensurePackageManager();\n const cwd = process.cwd();\n const [target, name] = cmdArgs;\n\n if (!target || target === \"check\") {\n run(\"bun\", [\"update\", \"-i\"], { cwd });\n return 0;\n }\n\n if (target === \"all\") {\n await updatePackages(await getInstalledPackages(cwd), cwd);\n return 0;\n }\n\n if (target === \"self\") {\n console.log(\"执行: bun update mioku --latest\");\n run(\"bun\", [\"update\", \"mioku\", \"--latest\"], { cwd });\n return 0;\n }\n\n if (target === \"plugin\" || target === \"service\") {\n const prefix = target === \"plugin\" ? PLUGIN_PREFIX : SERVICE_PREFIX;\n await updateByPrefix(prefix, cwd, name);\n return 0;\n }\n\n console.log(`执行: bun update ${target} --latest`);\n run(\"bun\", [\"update\", target, \"--latest\"], { cwd });\n return 0;\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport dedent from \"dedent\";\nimport consola from \"consola\";\nimport {\n ADAPTER_PREFIX,\n PLUGIN_PREFIX,\n ensurePackageManager,\n getAddCommand,\n multiSelect,\n run,\n runAdapterCli,\n searchMiokuPackages,\n shortNameOfPackage,\n resolveRequiredServices,\n rmrf,\n withRoot,\n gracefullyExit,\n makeFileTree,\n input,\n confirm,\n} from \"./shared\";\n\n/** stdin 会话对应的主人标识,默认追加到 mioku.owners */\nexport const STDIN_OWNER = \"stdin\";\n\n/** 系统自带适配器:必装且不可取消,默认启用 */\nexport const SYSTEM_ADAPTERS = [\"mioku-adapter-stdin\"];\n\n/** 系统自带插件:必装且不可取消 */\nexport const SYSTEM_PLUGINS = [\"mioku-plugin-help\", \"mioku-plugin-chat\"];\n\n/** 系统服务:框架运行所必需,无条件安装 */\nexport const SYSTEM_SERVICES = [\n \"mioku-service-ai\",\n \"mioku-service-config\",\n \"mioku-service-screenshot\",\n \"mioku-service-help\",\n];\n\nasync function createNewProject(\n name: string,\n fileTree: Record<string, string | Record<string, unknown>>,\n): Promise<string> {\n const projectPath = withRoot(`./${name}`);\n\n if (fs.existsSync(projectPath)) {\n const overwrite = await confirm(`项目 ${name} 已存在,是否覆盖?`);\n if (!overwrite) gracefullyExit();\n\n if (projectPath === process.cwd()) {\n if (fs.readdirSync(projectPath).length !== 0) {\n const confirmOver = await confirm(\n \"项目路径与当前路径相同,将删除当前目录下所有内容再创建,是否继续?\",\n );\n if (!confirmOver) gracefullyExit();\n }\n }\n await rmrf(projectPath);\n }\n\n fs.mkdirSync(projectPath, { recursive: true });\n makeFileTree(fileTree, projectPath);\n console.log(`项目 ${name} 创建成功!`);\n\n console.log(\"正在安装基础依赖 (bun i) ...\");\n run(\"bun\", [\"i\"], { cwd: projectPath });\n return projectPath;\n}\n\nasync function selectPackages(\n message: string,\n prefix: string,\n initial: string[] = [],\n options: { exclude?: string[] } = {},\n): Promise<string[]> {\n console.log(`\\n正在从 npm 拉取 ${prefix}* 包...`);\n const hits = await searchMiokuPackages(prefix);\n if (hits.length === 0) {\n consola.warn(`未在 npm 上找到任何 ${prefix}* 包`);\n return [];\n }\n const excludeSet = new Set(options.exclude ?? []);\n const items = hits\n .filter((hit) => !excludeSet.has(hit.name))\n .map((hit) => ({\n label: `${hit.name} (${hit.description || \"暂无介绍\"})`,\n value: hit.name,\n }));\n return multiSelect(message, items, initial);\n}\n\nexport async function scaffoldCommand(version: string): Promise<number> {\n const name = await input(\"请输入项目名称\", {\n default: \"mioku-bot\",\n placeholder: \"mioku-bot\",\n required: true,\n });\n const owners = await input(\"请输入主人 QQ (最高权限,英文逗号分隔,必填)\", {\n placeholder: \"请输入\",\n default: \"\",\n required: true,\n });\n\n ensurePackageManager();\n\n // stdin 会话默认拥有主人权限:自动追加到 owners\n const ownersList = [\n ...String(owners)\n .split(\",\")\n .map((o) => o.trim())\n .filter(Boolean),\n STDIN_OWNER,\n ].join(\", \");\n\n const adapterNames = await selectPackages(\n \"选择要安装的适配器(上下键选择,空格勾选,回车确认,系统适配器 stdin 将自动安装)\",\n ADAPTER_PREFIX,\n [],\n { exclude: SYSTEM_ADAPTERS },\n );\n const allAdapterNames = [...SYSTEM_ADAPTERS, ...adapterNames];\n if (adapterNames.length === 0) {\n consola.warn(\"未选择其他适配器,将仅启用系统适配器 stdin(终端输入)\");\n }\n\n const pkgJson = dedent(`\n {\n \"name\": \"${name}\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"mioku\": \"latest\"\n ${allAdapterNames.map((pkg) => `,\\n \"${pkg}\": \"latest\"`).join(\"\")}\n },\n \"mioku\": {\n \"prefix\": \".\",\n \"owners\": [${ownersList}],\n \"admins\": [],\n \"plugins\": [\"demo\"],\n \"log_level\": \"info\",\n \"online_push\": false,\n \"error_push\": false,\n \"adapters\": {\n \"stdin\": {}\n }\n },\n \"scripts\": {\n \"start\": \"bun run app.ts\",\n \"dev\": \"bun run --watch app.ts\"\n }\n }\n `);\n\n const pluginCode = dedent(`\n import { definePlugin } from 'mioku'\n\n export default definePlugin({\n name: 'demo',\n version: '${version}',\n async setup(ctx) {\n ctx.logger.info('Demo 插件已加载')\n\n ctx.handle('message', async (e) => {\n if (e.raw_message === 'hello') {\n e.reply('world', true)\n }\n })\n\n return () => {\n ctx.logger.info('Demo 插件已卸载')\n }\n },\n })\n `);\n\n const fileTree: Record<string, string | Record<string, unknown>> = {\n \"app.ts\":\n \"import { start } from 'mioku'\\n\\nstart({ cwd: import.meta.dirname }).then()\\n\",\n \"package.json\": pkgJson,\n plugins: { demo: { \"index.ts\": pluginCode } },\n config: {},\n data: {},\n };\n\n const projectPath = await createNewProject(name, fileTree);\n\n // 仅为用户额外选择的适配器运行配置向导(系统适配器 stdin 免配置)\n for (const adapterPkg of adapterNames) {\n const adapterName = shortNameOfPackage(adapterPkg);\n consola.info(`正在运行 ${adapterPkg} 配置向导...`);\n runAdapterCli(adapterName, projectPath);\n }\n consola.info(\n `已自动安装并启用系统适配器: ${SYSTEM_ADAPTERS.map(shortNameOfPackage).join(\", \")}`,\n );\n\n // 系统插件必装且不可取消:从选择列表中剔除,自动启用\n const pluginNames = await selectPackages(\n \"选择要安装的插件(上下键选择,空格勾选,回车确认)\",\n PLUGIN_PREFIX,\n [],\n { exclude: SYSTEM_PLUGINS },\n );\n consola.info(\n `系统插件将自动安装: ${SYSTEM_PLUGINS.map(shortNameOfPackage).join(\", \")}`,\n );\n\n const enabledPlugins = [\n \"demo\",\n ...SYSTEM_PLUGINS.map(shortNameOfPackage),\n ...pluginNames.map(shortNameOfPackage),\n ];\n const pkgPath = path.join(projectPath, \"package.json\");\n const pkg = JSON.parse(fs.readFileSync(pkgPath, \"utf-8\"));\n pkg.mioku = { ...pkg.mioku, plugins: enabledPlugins };\n fs.writeFileSync(pkgPath, `${JSON.stringify(pkg, null, 2)}\\n`);\n\n const serviceNames = new Set<string>(SYSTEM_SERVICES);\n for (const service of await resolveRequiredServices(pluginNames)) {\n serviceNames.add(service);\n }\n consola.info(\n `将自动安装服务: ${Array.from(serviceNames).map(shortNameOfPackage).join(\", \")}`,\n );\n\n const installWebui = await confirm(\"是否安装 WebUI 管理面板?(建议安装)\", {\n initial: true,\n });\n\n const addPackages = [...pluginNames, ...Array.from(serviceNames)];\n if (installWebui) addPackages.push(\"mioku-service-webui\");\n\n if (addPackages.length > 0) {\n const [cmd, args] = getAddCommand(addPackages);\n console.log(`正在安装插件与服务: ${cmd} ${args.join(\" \")}`);\n run(cmd, args, { cwd: projectPath });\n }\n\n console.log(\"\\n若需启动机器人,请运行:\");\n console.log(\" cd\", name);\n console.log(\" bun run start\");\n return 0;\n}\n","#!/usr/bin/env node\n\nimport mri from \"mri\";\nimport { version } from \"../../package.json\";\nimport { buildHelpInfo } from \"./shared\";\nimport { installCommand } from \"./install\";\nimport { updateCommand } from \"./update\";\nimport { scaffoldCommand } from \"./scaffold\";\n\ninterface CliOptions {\n help?: boolean;\n version?: boolean;\n}\n\nconst args = process.argv.slice(2);\n\n(async () => {\n const cli = mri<CliOptions>(args, { alias: { v: \"version\", h: \"help\" } });\n const helpInfo = buildHelpInfo(version);\n const [cmd, ...cmdArgs] = args;\n\n switch (cmd) {\n case \"install\":\n process.exitCode = await installCommand(cmdArgs, helpInfo);\n return;\n case \"update\":\n process.exitCode = await updateCommand(cmdArgs);\n return;\n default:\n if (cli.version) {\n console.log(`v${version}`);\n return;\n }\n if (cli.help) {\n console.log(helpInfo);\n return;\n }\n process.exitCode = await scaffoldCommand(version);\n return;\n }\n})();\n"],"mappings":"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"}
|