mioku 0.8.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/index.js ADDED
@@ -0,0 +1,613 @@
1
+ import { createRequire } from "node:module";
2
+ import * as fs$4 from "fs/promises";
3
+ import * as fs$3 from "fs/promises";
4
+ import * as fs$2 from "fs/promises";
5
+ import * as fs$1 from "fs/promises";
6
+ import * as path$5 from "path";
7
+ import * as path$4 from "path";
8
+ import * as path$3 from "path";
9
+ import * as path$2 from "path";
10
+ import * as path$1 from "path";
11
+ import * as path from "path";
12
+ import * as fs from "fs";
13
+ import { existsSync, mkdirSync } from "fs";
14
+
15
+ //#region rolldown:runtime
16
+ var __require = /* @__PURE__ */ createRequire(import.meta.url);
17
+
18
+ //#endregion
19
+ //#region src/core/logger.ts
20
+ const fallbackLogger = {
21
+ error: (...args) => console.error(...args),
22
+ warn: (...args) => console.warn(...args),
23
+ info: (...args) => console.info(...args),
24
+ debug: (...args) => console.debug(...args),
25
+ trace: (...args) => console.debug(...args)
26
+ };
27
+ let activeLogger = fallbackLogger;
28
+ function setMiokuLogger(logger$1) {
29
+ activeLogger = logger$1 || fallbackLogger;
30
+ }
31
+ const logger = {
32
+ error: (...args) => activeLogger.error(...args),
33
+ warn: (...args) => activeLogger.warn(...args),
34
+ info: (...args) => activeLogger.info(...args),
35
+ debug: (...args) => activeLogger.debug(...args),
36
+ trace: (...args) => activeLogger.trace?.(...args)
37
+ };
38
+
39
+ //#endregion
40
+ //#region src/core/plugin-linker.ts
41
+ const DEFAULT_RUNTIME_PLUGINS_DIR = ".mioku/plugins";
42
+ async function pathExists$3(filePath) {
43
+ try {
44
+ await fs$4.access(filePath);
45
+ return true;
46
+ } catch {
47
+ return false;
48
+ }
49
+ }
50
+ async function removeIfBrokenSymlink(entryPath) {
51
+ let stat;
52
+ try {
53
+ stat = await fs$4.lstat(entryPath);
54
+ } catch {
55
+ return "removed";
56
+ }
57
+ if (!stat.isSymbolicLink()) return "blocked";
58
+ try {
59
+ await fs$4.realpath(entryPath);
60
+ return "ok";
61
+ } catch {
62
+ await fs$4.rm(entryPath, { force: true });
63
+ logger.warn(`[plugin-linker] Removed broken plugin link: ${entryPath}`);
64
+ return "removed";
65
+ }
66
+ }
67
+ function relativeSymlinkTarget(linkPath, targetPath) {
68
+ const relativePath = path$5.relative(path$5.dirname(linkPath), targetPath);
69
+ return relativePath || ".";
70
+ }
71
+ async function ensurePluginLink(runtimePluginsDir, metadata) {
72
+ const linkPath = path$5.join(runtimePluginsDir, metadata.name);
73
+ const targetPath = metadata.path;
74
+ let stat;
75
+ try {
76
+ stat = await fs$4.lstat(linkPath);
77
+ } catch {
78
+ stat = null;
79
+ }
80
+ if (stat?.isSymbolicLink()) try {
81
+ const currentTarget = await fs$4.realpath(linkPath);
82
+ const expectedTarget = await fs$4.realpath(targetPath);
83
+ if (currentTarget === expectedTarget) return true;
84
+ await fs$4.rm(linkPath, { force: true });
85
+ logger.info(`[plugin-linker] Rebuilding plugin link: ${metadata.name}`);
86
+ } catch {
87
+ await fs$4.rm(linkPath, { force: true });
88
+ logger.warn(`[plugin-linker] Removed broken plugin link: ${linkPath}`);
89
+ }
90
+ else if (stat) {
91
+ logger.warn(`[plugin-linker] ${linkPath} exists and is not a symlink, skip linking ${metadata.name}`);
92
+ return false;
93
+ }
94
+ if (!await pathExists$3(targetPath)) {
95
+ logger.warn(`[plugin-linker] Plugin target missing, skip linking ${metadata.name}: ${targetPath}`);
96
+ return false;
97
+ }
98
+ await fs$4.symlink(relativeSymlinkTarget(linkPath, targetPath), linkPath, "dir");
99
+ return true;
100
+ }
101
+ async function prepareRuntimePluginLinks(plugins, runtimePluginsDir = path$5.resolve(process.cwd(), DEFAULT_RUNTIME_PLUGINS_DIR)) {
102
+ await fs$4.mkdir(runtimePluginsDir, { recursive: true });
103
+ const discoveredNames = new Set(plugins.map((plugin) => plugin.name));
104
+ const entries = await fs$4.readdir(runtimePluginsDir, { withFileTypes: true });
105
+ for (const entry of entries) {
106
+ const entryPath = path$5.join(runtimePluginsDir, entry.name);
107
+ const symlinkState = await removeIfBrokenSymlink(entryPath);
108
+ if (symlinkState !== "ok") continue;
109
+ if (entry.isSymbolicLink() && !discoveredNames.has(entry.name)) {
110
+ await fs$4.rm(entryPath, { force: true });
111
+ logger.info(`[plugin-linker] Removed stale plugin link: ${entry.name}`);
112
+ }
113
+ }
114
+ const linkedNames = [];
115
+ for (const metadata of plugins) if (await ensurePluginLink(runtimePluginsDir, metadata)) linkedNames.push(metadata.name);
116
+ return linkedNames;
117
+ }
118
+
119
+ //#endregion
120
+ //#region src/core/plugin-manager.ts
121
+ const PLUGIN_MANAGER_SYMBOL = Symbol.for("mioku.plugin-manager");
122
+ async function pathExists$2(filePath) {
123
+ try {
124
+ await fs$3.access(filePath);
125
+ return true;
126
+ } catch {
127
+ return false;
128
+ }
129
+ }
130
+ /**
131
+ * 插件管理器
132
+ *
133
+ * Discover and manage plugins from both local directories and node_modules.
134
+ */
135
+ var PluginManager = class PluginManager {
136
+ pluginMetadata = new Map();
137
+ static getInstance() {
138
+ const g = global;
139
+ if (!g[PLUGIN_MANAGER_SYMBOL]) g[PLUGIN_MANAGER_SYMBOL] = new PluginManager();
140
+ return g[PLUGIN_MANAGER_SYMBOL];
141
+ }
142
+ async discoverPlugins(miokuConfig = {}) {
143
+ const configuredPluginsDir = miokuConfig.plugins_dir;
144
+ const pluginsDir = configuredPluginsDir && configuredPluginsDir !== DEFAULT_RUNTIME_PLUGINS_DIR ? path$4.resolve(process.cwd(), configuredPluginsDir) : path$4.resolve(process.cwd(), "plugins");
145
+ this.pluginMetadata.clear();
146
+ if (!await pathExists$2(pluginsDir)) mkdirSync(pluginsDir, { recursive: true });
147
+ const discovered = [];
148
+ if (await pathExists$2(pluginsDir)) {
149
+ const localPlugins = await this.discoverFromDir(pluginsDir);
150
+ discovered.push(...localPlugins);
151
+ }
152
+ const nodeModulesPlugins = await this.discoverFromNodeModules();
153
+ discovered.push(...nodeModulesPlugins);
154
+ logger.info(`O.o 发现了 ${this.pluginMetadata.size} 个插件`);
155
+ return Array.from(this.pluginMetadata.values());
156
+ }
157
+ async discoverFromDir(pluginsDir) {
158
+ const discovered = [];
159
+ try {
160
+ const entries = await fs$3.readdir(pluginsDir, { withFileTypes: true });
161
+ for (const entry of entries) {
162
+ const pluginPath = path$4.join(pluginsDir, entry.name);
163
+ const metadataPath = await this.resolveDirectoryPath(pluginPath);
164
+ if (!metadataPath) continue;
165
+ const metadata = await this.loadPluginMetadata(entry.name, pluginPath);
166
+ if (metadata) {
167
+ discovered.push(metadata);
168
+ this.pluginMetadata.set(metadata.name, metadata);
169
+ }
170
+ }
171
+ } catch (error) {
172
+ logger.error(`扫描插件目录失败: ${error}`);
173
+ }
174
+ return discovered;
175
+ }
176
+ async discoverFromNodeModules() {
177
+ const discovered = [];
178
+ const nodeModulesPath = path$4.resolve(process.cwd(), "node_modules");
179
+ if (!await pathExists$2(nodeModulesPath)) return discovered;
180
+ try {
181
+ const entries = await fs$3.readdir(nodeModulesPath, { withFileTypes: true });
182
+ for (const entry of entries) {
183
+ if (!entry.name.startsWith("mioku-plugin-")) continue;
184
+ const pluginName = entry.name.replace(/^mioku-plugin-/, "");
185
+ const pluginPath = path$4.join(nodeModulesPath, entry.name);
186
+ const metadata = await this.loadPluginMetadata(pluginName, pluginPath);
187
+ if (metadata) {
188
+ discovered.push(metadata);
189
+ this.pluginMetadata.set(metadata.name, metadata);
190
+ }
191
+ }
192
+ } catch (error) {
193
+ logger.debug(`扫描 node_modules 插件失败: ${error}`);
194
+ }
195
+ return discovered;
196
+ }
197
+ async resolveDirectoryPath(entryPath) {
198
+ try {
199
+ const stat = await fs$3.stat(entryPath);
200
+ return stat.isDirectory() ? entryPath : null;
201
+ } catch {
202
+ return null;
203
+ }
204
+ }
205
+ async loadPluginMetadata(name, pluginPath) {
206
+ let resolvedPath = pluginPath;
207
+ try {
208
+ resolvedPath = await fs$3.realpath(pluginPath);
209
+ } catch {}
210
+ const packageJsonPath = path$4.join(resolvedPath, "package.json");
211
+ let packageJson = null;
212
+ try {
213
+ const content = await fs$3.readFile(packageJsonPath, "utf-8");
214
+ packageJson = JSON.parse(content);
215
+ } catch {}
216
+ const metadata = {
217
+ name,
218
+ version: packageJson?.version || "0.0.0",
219
+ description: packageJson?.description,
220
+ path: resolvedPath,
221
+ packageJson,
222
+ config: packageJson?.mioku || {}
223
+ };
224
+ return metadata;
225
+ }
226
+ collectRequiredServices() {
227
+ const services = new Set();
228
+ for (const metadata of this.pluginMetadata.values()) if (metadata.config.services) metadata.config.services.forEach((s) => services.add(s));
229
+ return services;
230
+ }
231
+ getPluginMetadata(name) {
232
+ return this.pluginMetadata.get(name);
233
+ }
234
+ getAllMetadata() {
235
+ return Array.from(this.pluginMetadata.values());
236
+ }
237
+ reset() {
238
+ this.pluginMetadata.clear();
239
+ }
240
+ };
241
+ var plugin_manager_default = PluginManager.getInstance();
242
+
243
+ //#endregion
244
+ //#region src/core/service-manager.ts
245
+ const SERVICE_MANAGER_SYMBOL = Symbol.for("mioku.service-manager");
246
+ async function pathExists$1(filePath) {
247
+ try {
248
+ await fs$2.access(filePath);
249
+ return true;
250
+ } catch {
251
+ return false;
252
+ }
253
+ }
254
+ /**
255
+ * 服务管理器
256
+ */
257
+ var ServiceManager = class ServiceManager {
258
+ services = new Map();
259
+ serviceMetadata = new Map();
260
+ servicesDir = "services";
261
+ static getInstance() {
262
+ const g = global;
263
+ if (!g[SERVICE_MANAGER_SYMBOL]) g[SERVICE_MANAGER_SYMBOL] = new ServiceManager();
264
+ return g[SERVICE_MANAGER_SYMBOL];
265
+ }
266
+ async discoverServices(miokuConfig = {}) {
267
+ if (miokuConfig.services_dir) this.servicesDir = path$3.resolve(process.cwd(), miokuConfig.services_dir);
268
+ else this.servicesDir = path$3.resolve(process.cwd(), "services");
269
+ const discovered = [];
270
+ this.serviceMetadata.clear();
271
+ if (existsSync(this.servicesDir)) {
272
+ const localServices = await this.discoverFromDir(this.servicesDir);
273
+ discovered.push(...localServices);
274
+ } else mkdirSync(this.servicesDir, { recursive: true });
275
+ await this.loadBuiltinServices();
276
+ logger.info(`o.O 发现了 ${this.serviceMetadata.size} 个服务`);
277
+ return Array.from(this.serviceMetadata.values());
278
+ }
279
+ async discoverFromDir(servicesDir) {
280
+ const discovered = [];
281
+ try {
282
+ const entries = await fs$2.readdir(servicesDir, { withFileTypes: true });
283
+ for (const entry of entries) {
284
+ if (!entry.isDirectory()) continue;
285
+ const servicePath = path$3.join(servicesDir, entry.name);
286
+ const metadata = await this.loadServiceMetadata(entry.name, servicePath);
287
+ if (metadata) {
288
+ discovered.push(metadata);
289
+ this.serviceMetadata.set(entry.name, metadata);
290
+ }
291
+ }
292
+ } catch (error) {
293
+ logger.error(`扫描服务目录失败: ${error}`);
294
+ }
295
+ return discovered;
296
+ }
297
+ async loadServiceMetadata(name, servicePath) {
298
+ let resolvedPath = servicePath;
299
+ try {
300
+ resolvedPath = await fs$2.realpath(servicePath);
301
+ } catch {}
302
+ const packageJsonPath = path$3.join(resolvedPath, "package.json");
303
+ if (!await pathExists$1(packageJsonPath)) return null;
304
+ try {
305
+ const packageJson = JSON.parse(await fs$2.readFile(packageJsonPath, "utf-8"));
306
+ const metadata = {
307
+ name,
308
+ version: packageJson.version || "0.0.0",
309
+ description: packageJson.description,
310
+ path: resolvedPath,
311
+ packageJson
312
+ };
313
+ return metadata;
314
+ } catch (error) {
315
+ logger.error(`解析服务 ${name} 失败: ${error.message}`);
316
+ return null;
317
+ }
318
+ }
319
+ /**
320
+ * Load built-in services from the package
321
+ */
322
+ async loadBuiltinServices() {
323
+ await this.discoverFromNodeModules();
324
+ }
325
+ async discoverFromNodeModules() {
326
+ const nodeModulesPath = path$3.resolve(process.cwd(), "node_modules");
327
+ if (!await pathExists$1(nodeModulesPath)) return;
328
+ try {
329
+ const entries = await fs$2.readdir(nodeModulesPath, { withFileTypes: true });
330
+ for (const entry of entries) {
331
+ if (!entry.name.startsWith("mioku-service-")) continue;
332
+ const serviceName = entry.name.replace(/^mioku-service-/, "");
333
+ const servicePath = path$3.join(nodeModulesPath, entry.name);
334
+ const metadata = await this.loadServiceMetadata(serviceName, servicePath);
335
+ if (metadata) this.serviceMetadata.set(serviceName, metadata);
336
+ }
337
+ } catch (error) {
338
+ logger.debug(`扫描 node_modules 服务失败: ${error}`);
339
+ }
340
+ }
341
+ async checkMissingServices(requiredServices) {
342
+ const missing = [];
343
+ for (const serviceName of requiredServices) if (!this.serviceMetadata.has(serviceName)) missing.push(serviceName);
344
+ return missing;
345
+ }
346
+ async loadAllServices(ctx) {
347
+ const allMetadata = Array.from(this.serviceMetadata.values());
348
+ logger.info(`O.o 准备加载 ${allMetadata.length} 个服务...`);
349
+ for (const metadata of allMetadata) await this.loadService(metadata, ctx);
350
+ }
351
+ async loadService(metadata, ctx) {
352
+ try {
353
+ const indexPath = path$3.join(metadata.path, "index.ts");
354
+ const indexJsPath = path$3.join(metadata.path, "index.js");
355
+ const indexExists = await pathExists$1(indexPath);
356
+ const indexJsExists = await pathExists$1(indexJsPath);
357
+ const entryPoint = indexExists ? indexPath : indexJsPath;
358
+ if (!entryPoint || !indexExists && !indexJsExists) {
359
+ logger.error(`服务 ${metadata.name} 入口丢失`);
360
+ return false;
361
+ }
362
+ let importPath = entryPoint;
363
+ if (process.platform === "win32") importPath = "file:///" + entryPoint.replace(/\\/g, "/");
364
+ const serviceModule = await import(importPath);
365
+ const service = serviceModule.default || serviceModule;
366
+ if (!service || typeof service.init !== "function") return false;
367
+ await service.init();
368
+ if (service.api) {
369
+ if (!ctx.services) ctx.services = {};
370
+ ctx.services[metadata.name] = service.api;
371
+ }
372
+ this.services.set(metadata.name, service);
373
+ return true;
374
+ } catch (error) {
375
+ logger.error(`加载服务 ${metadata.name} 失败: ${error.message}`);
376
+ return false;
377
+ }
378
+ }
379
+ /**
380
+ * Register a builtin service directly
381
+ */
382
+ registerBuiltinService(name, service) {
383
+ this.services.set(name, service);
384
+ }
385
+ /**
386
+ * Get a loaded service
387
+ */
388
+ getService(name) {
389
+ return this.services.get(name);
390
+ }
391
+ async disposeAll() {
392
+ for (const [name, service] of this.services) if (service.dispose) await service.dispose();
393
+ this.services.clear();
394
+ }
395
+ reset() {
396
+ this.services.clear();
397
+ this.serviceMetadata.clear();
398
+ }
399
+ };
400
+ var service_manager_default = ServiceManager.getInstance();
401
+
402
+ //#endregion
403
+ //#region src/core/plugin-artifact-registry.ts
404
+ async function pathExists(filePath) {
405
+ try {
406
+ await fs$1.access(filePath);
407
+ return true;
408
+ } catch {
409
+ return false;
410
+ }
411
+ }
412
+ function toImportPath(filePath) {
413
+ if (process.platform === "win32") return "file:///" + filePath.replace(/\\/g, "/");
414
+ return filePath;
415
+ }
416
+ function isAISkill(value) {
417
+ return value && typeof value === "object" && typeof value.name === "string" && Array.isArray(value.tools);
418
+ }
419
+ function extractSkills(moduleExports) {
420
+ const candidates = [
421
+ moduleExports?.default,
422
+ moduleExports?.skills,
423
+ moduleExports
424
+ ];
425
+ for (const candidate of candidates) {
426
+ if (Array.isArray(candidate)) return candidate.filter(isAISkill);
427
+ if (isAISkill(candidate)) return [candidate];
428
+ }
429
+ return [];
430
+ }
431
+ async function resolveSkillsEntry(pluginPath) {
432
+ const tsPath = path$2.join(pluginPath, "skills.ts");
433
+ if (await pathExists(tsPath)) return tsPath;
434
+ const jsPath = path$2.join(pluginPath, "skills.js");
435
+ if (await pathExists(jsPath)) return jsPath;
436
+ return null;
437
+ }
438
+ /**
439
+ * Auto-register plugin help manifests and AI skills
440
+ */
441
+ async function registerPluginArtifacts(ctx) {
442
+ const enabledPlugins = new Set(Array.isArray(ctx.botConfig?.plugins) ? ctx.botConfig.plugins : []);
443
+ const pluginMetadata = plugin_manager_default.getAllMetadata().filter((metadata) => enabledPlugins.size > 0 ? enabledPlugins.has(metadata.name) : true);
444
+ const helpService = ctx.services?.help;
445
+ const aiService = ctx.services?.ai;
446
+ if (helpService) {
447
+ let helpCount = 0;
448
+ for (const metadata of pluginMetadata) {
449
+ if (!metadata.config.help) continue;
450
+ helpService.registerHelp(metadata.name, metadata.config.help);
451
+ helpCount += 1;
452
+ }
453
+ logger.info(`[plugin-artifacts] Registered ${helpCount} help manifest(s)`);
454
+ }
455
+ if (!aiService) return;
456
+ let skillCount = 0;
457
+ for (const metadata of pluginMetadata) {
458
+ const skillsEntry = await resolveSkillsEntry(metadata.path);
459
+ if (!skillsEntry) continue;
460
+ try {
461
+ const moduleExports = await import(toImportPath(skillsEntry));
462
+ const skills = extractSkills(moduleExports);
463
+ if (skills.length === 0) {
464
+ logger.warn(`[plugin-artifacts] Plugin ${metadata.name} has ${path$2.basename(skillsEntry)} but exported no valid skill`);
465
+ continue;
466
+ }
467
+ for (const skill of skills) {
468
+ aiService.registerSkill(skill);
469
+ skillCount += 1;
470
+ }
471
+ } catch (error) {
472
+ logger.error(`[plugin-artifacts] Failed to load skills for plugin ${metadata.name}: ${error?.message || error}`);
473
+ }
474
+ }
475
+ logger.info(`[plugin-artifacts] Registered ${skillCount} skill(s)`);
476
+ }
477
+
478
+ //#endregion
479
+ //#region src/service-types.ts
480
+ const TOOL_RESULT_FOLLOWUP_KEY = "__miokuFollowup";
481
+
482
+ //#endregion
483
+ //#region src/core/data-paths.ts
484
+ /**
485
+ * Get the data directory for a specific plugin
486
+ * Returns: {cwd}/data/{pluginName}
487
+ */
488
+ function getPluginDataDir(pluginName) {
489
+ const dataDir = path$1.join(process.cwd(), "data", pluginName);
490
+ return dataDir;
491
+ }
492
+ /**
493
+ * Get the data directory for a service
494
+ * Returns: {cwd}/data/{serviceName}
495
+ */
496
+ function getServiceDataDir(serviceName) {
497
+ const dataDir = path$1.join(process.cwd(), "data", serviceName);
498
+ return dataDir;
499
+ }
500
+ /**
501
+ * Get the main data directory
502
+ * Returns: {cwd}/data
503
+ */
504
+ function getDataDir() {
505
+ return path$1.join(process.cwd(), "data");
506
+ }
507
+ /**
508
+ * Get the config directory for a plugin
509
+ * Returns: {cwd}/config/{pluginName}
510
+ */
511
+ function getPluginConfigDir(pluginName) {
512
+ const configDir = path$1.join(process.cwd(), "config", pluginName);
513
+ return configDir;
514
+ }
515
+ /**
516
+ * Get the config directory for a service
517
+ * Returns: {cwd}/config/{serviceName}
518
+ */
519
+ function getServiceConfigDir(serviceName) {
520
+ const configDir = path$1.join(process.cwd(), "config", serviceName);
521
+ return configDir;
522
+ }
523
+ /**
524
+ * Get the main config directory
525
+ * Returns: {cwd}/config
526
+ */
527
+ function getConfigDir() {
528
+ return path$1.join(process.cwd(), "config");
529
+ }
530
+ /**
531
+ * Ensure a directory exists, creating it if necessary
532
+ */
533
+ function ensureDataDir(pluginName) {
534
+ const dir = getPluginDataDir(pluginName);
535
+ const { existsSync: existsSync$1, mkdirSync: mkdirSync$1 } = __require("fs");
536
+ if (!existsSync$1(dir)) mkdirSync$1(dir, { recursive: true });
537
+ return dir;
538
+ }
539
+
540
+ //#endregion
541
+ //#region src/core/plugin-runtime-state.ts
542
+ const runtimeState = {};
543
+ /**
544
+ * Get the runtime state for a plugin
545
+ */
546
+ function getPluginRuntimeState(pluginName) {
547
+ if (!runtimeState[pluginName]) runtimeState[pluginName] = {};
548
+ return runtimeState[pluginName];
549
+ }
550
+ /**
551
+ * Set/update the runtime state for a plugin
552
+ */
553
+ function setPluginRuntimeState(pluginName, state) {
554
+ if (!runtimeState[pluginName]) runtimeState[pluginName] = {};
555
+ Object.assign(runtimeState[pluginName], state);
556
+ return runtimeState[pluginName];
557
+ }
558
+ /**
559
+ * Reset the runtime state for a plugin
560
+ */
561
+ function resetPluginRuntimeState(pluginName) {
562
+ delete runtimeState[pluginName];
563
+ }
564
+
565
+ //#endregion
566
+ //#region src/index.ts
567
+ function definePlugin(plugin) {
568
+ return plugin;
569
+ }
570
+ /**
571
+ * Start Mioku with plugin and service discovery
572
+ */
573
+ async function start(options = {}) {
574
+ const { cwd = process.cwd() } = options;
575
+ if (cwd) process.chdir(cwd);
576
+ const { start: startMioki, logger: logger$1, botConfig } = await import("mioki");
577
+ setMiokuLogger(logger$1);
578
+ const packageJsonPath = path.join(process.cwd(), "package.json");
579
+ let miokuConfig = {};
580
+ if (fs.existsSync(packageJsonPath)) {
581
+ const pkg = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8"));
582
+ miokuConfig = pkg.mioki || {};
583
+ }
584
+ logger$1.info("こんにちは..");
585
+ logger$1.info("---------------------------------------");
586
+ logger$1.info("---------- Mioku 正在启动 ------------");
587
+ logger$1.info("---------------------------------------");
588
+ const requiredDirs = [
589
+ "data",
590
+ "config",
591
+ "temp"
592
+ ];
593
+ for (const dir of requiredDirs) if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
594
+ logger$1.info("O.o Miku 正在翻找插件..");
595
+ const discoveredPlugins = await plugin_manager_default.discoverPlugins(miokuConfig);
596
+ logger$1.info(`O.o 共发现 ${discoveredPlugins.length} 个插件: ${discoveredPlugins.map((p) => p.name).join(", ")}`);
597
+ const runtimePluginsDir = path.resolve(process.cwd(), DEFAULT_RUNTIME_PLUGINS_DIR);
598
+ const linkedPluginNames = await prepareRuntimePluginLinks(discoveredPlugins, runtimePluginsDir);
599
+ botConfig.plugins_dir = DEFAULT_RUNTIME_PLUGINS_DIR;
600
+ logger$1.info("o.O Miku 正在翻找服务..");
601
+ await service_manager_default.discoverServices(miokuConfig);
602
+ const requiredServices = plugin_manager_default.collectRequiredServices();
603
+ const missingServices = await service_manager_default.checkMissingServices(requiredServices);
604
+ if (missingServices.length > 0) logger$1.warn(`发现缺失服务: ${missingServices.join(", ")}`);
605
+ const discoveredPluginNames = linkedPluginNames;
606
+ for (const name of discoveredPluginNames) if (!botConfig.plugins.includes(name)) botConfig.plugins.push(name);
607
+ await startMioki({ cwd });
608
+ }
609
+ const version = "1.0.0";
610
+
611
+ //#endregion
612
+ export { TOOL_RESULT_FOLLOWUP_KEY, definePlugin, ensureDataDir, getConfigDir, getDataDir, getPluginConfigDir, getPluginDataDir, getPluginRuntimeState, getServiceConfigDir, getServiceDataDir, plugin_manager_default as pluginManager, registerPluginArtifacts, resetPluginRuntimeState, service_manager_default as serviceManager, setPluginRuntimeState, start, version };
613
+ //# sourceMappingURL=index.js.map