@zhin.js/core 1.0.52 → 1.0.54

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.
Files changed (42) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/lib/adapter.d.ts +13 -23
  3. package/lib/adapter.d.ts.map +1 -1
  4. package/lib/adapter.js +26 -71
  5. package/lib/adapter.js.map +1 -1
  6. package/lib/built/adapter-process.d.ts.map +1 -1
  7. package/lib/built/adapter-process.js +1 -0
  8. package/lib/built/adapter-process.js.map +1 -1
  9. package/lib/built/agent-preset.d.ts +40 -0
  10. package/lib/built/agent-preset.d.ts.map +1 -0
  11. package/lib/built/agent-preset.js +13 -0
  12. package/lib/built/agent-preset.js.map +1 -0
  13. package/lib/built/component.d.ts +2 -2
  14. package/lib/built/component.d.ts.map +1 -1
  15. package/lib/built/component.js +3 -2
  16. package/lib/built/component.js.map +1 -1
  17. package/lib/built/database.d.ts +2 -2
  18. package/lib/built/database.d.ts.map +1 -1
  19. package/lib/built/database.js.map +1 -1
  20. package/lib/built/skill.d.ts +10 -0
  21. package/lib/built/skill.d.ts.map +1 -1
  22. package/lib/built/skill.js.map +1 -1
  23. package/lib/index.d.ts +1 -0
  24. package/lib/index.d.ts.map +1 -1
  25. package/lib/index.js +2 -0
  26. package/lib/index.js.map +1 -1
  27. package/lib/plugin.d.ts +43 -95
  28. package/lib/plugin.d.ts.map +1 -1
  29. package/lib/plugin.js +135 -268
  30. package/lib/plugin.js.map +1 -1
  31. package/lib/types.d.ts +11 -0
  32. package/lib/types.d.ts.map +1 -1
  33. package/package.json +6 -6
  34. package/src/adapter.ts +37 -95
  35. package/src/built/adapter-process.ts +1 -0
  36. package/src/built/agent-preset.ts +55 -0
  37. package/src/built/component.ts +5 -3
  38. package/src/built/database.ts +2 -1
  39. package/src/built/skill.ts +14 -0
  40. package/src/index.ts +2 -0
  41. package/src/plugin.ts +198 -373
  42. package/src/types.ts +16 -0
package/lib/plugin.js CHANGED
@@ -7,15 +7,14 @@ import { EventEmitter } from "events";
7
7
  import { createRequire } from "module";
8
8
  import * as fs from "fs";
9
9
  import * as path from "path";
10
- import { fileURLToPath, pathToFileURL } from "url";
10
+ import { fileURLToPath } from "url";
11
11
  import logger from "@zhin.js/logger";
12
12
  import { compose, remove, resolveEntry } from "./utils.js";
13
13
  import { Adapter } from "./adapter.js";
14
- import { Feature } from "./feature.js";
15
14
  import { createHash } from "crypto";
15
+ import { Feature } from "./feature.js";
16
16
  const contextsKey = Symbol("contexts");
17
- const extensionOwnersKey = Symbol("extensionOwners");
18
- const loadedModules = new Map();
17
+ const loadedModules = new Map(); // 记录已加载的模块
19
18
  const require = createRequire(import.meta.url);
20
19
  // ============================================================================
21
20
  // AsyncLocalStorage 上下文
@@ -46,17 +45,16 @@ function getCurrentFile(metaUrl = import.meta.url) {
46
45
  /**
47
46
  * usePlugin - 获取或创建当前插件实例
48
47
  * 类似 React Hooks 的设计,根据调用文件自动创建插件树
49
- *
50
- * 同一个文件多次调用 usePlugin() 返回同一个实例,
51
- * 避免 Plugin.create() + usePlugin() 产生不必要的双层包装。
48
+ * 同一上下文中同一文件多次调用返回同一实例
52
49
  */
53
50
  export function usePlugin() {
54
51
  const callerFile = getCurrentFile();
55
- const parentPlugin = storage.getStore();
56
- // 同一文件再次调用 usePlugin(),直接复用已有实例
57
- if (parentPlugin && parentPlugin.filePath === callerFile) {
58
- return parentPlugin;
52
+ // 如果当前 store 已是同一文件创建的插件,直接返回
53
+ const current = storage.getStore();
54
+ if (current && current.filePath.replace(/\?t=\d+$/, '') === callerFile.replace(/\?t=\d+$/, '')) {
55
+ return current;
59
56
  }
57
+ const parentPlugin = current;
60
58
  const newPlugin = new Plugin(callerFile, parentPlugin);
61
59
  storage.enterWith(newPlugin);
62
60
  return newPlugin;
@@ -109,10 +107,8 @@ function watchFile(filePath, callback) {
109
107
  export class Plugin extends EventEmitter {
110
108
  parent;
111
109
  static [contextsKey] = [];
112
- /** Maps extension method name → context name that owns it */
113
- static [extensionOwnersKey] = new Map();
114
110
  #cachedName;
115
- #explicitName;
111
+ #manifest;
116
112
  adapters = [];
117
113
  started = false;
118
114
  // 上下文存储
@@ -139,21 +135,20 @@ export class Plugin extends EventEmitter {
139
135
  };
140
136
  // 插件功能
141
137
  #middlewares = [this.#messageMiddleware];
142
- // 本地工具存储(当 ToolService 不可用时使用)
138
+ // AI 工具
143
139
  #tools = new Map();
140
+ // Feature 贡献追踪
141
+ #featureContributions = new Map();
144
142
  // 统一的清理函数集合
145
143
  #disposables = new Set();
146
- // 记录当前插件向哪些 Feature 贡献了哪些 item
147
- #featureContributions = new Map();
148
144
  get middleware() {
149
145
  return compose(this.#middlewares);
150
146
  }
151
- /**
152
- * Returns custom middlewares (excluding the built-in command middleware).
153
- * Used by MessageDispatcher to run legacy middlewares after dispatch.
154
- */
155
- _getCustomMiddlewares() {
156
- return this.#middlewares.filter(m => m !== this.#messageMiddleware);
147
+ recordFeatureContribution(featureName, itemName) {
148
+ if (!this.#featureContributions.has(featureName)) {
149
+ this.#featureContributions.set(featureName, new Set());
150
+ }
151
+ this.#featureContributions.get(featureName).add(itemName);
157
152
  }
158
153
  /**
159
154
  * 构造函数
@@ -178,19 +173,8 @@ export class Plugin extends EventEmitter {
178
173
  /**
179
174
  * 添加中间件
180
175
  * 中间件用于处理消息流转
181
- * @param middleware 中间件函数
182
176
  */
183
- addMiddleware(middleware) {
184
- // Always register on root so middlewares reach the global chain
185
- const target = this.root;
186
- if (target !== this) {
187
- const dispose = target.addMiddleware(middleware);
188
- this.#disposables.add(dispose);
189
- return () => {
190
- dispose();
191
- this.#disposables.delete(dispose);
192
- };
193
- }
177
+ addMiddleware(middleware, name) {
194
178
  this.#middlewares.push(middleware);
195
179
  const dispose = () => {
196
180
  remove(this.#middlewares, middleware);
@@ -200,23 +184,13 @@ export class Plugin extends EventEmitter {
200
184
  return dispose;
201
185
  }
202
186
  /**
203
- * 添加工具
204
- * 工具可以被 AI 服务调用,也会自动生成对应的命令
187
+ * 添加 AI 工具
188
+ * 工具可以被 AI 服务调用来执行操作
205
189
  * @param tool 工具定义
206
- * @param generateCommand 是否生成对应命令(默认 true)
207
190
  * @returns 返回一个移除工具的函数
208
191
  */
209
- addTool(tool, generateCommand = true) {
210
- const toolService = this.root.inject('tool');
211
- if (toolService && typeof toolService.addTool === 'function') {
212
- const dispose = toolService.addTool(tool, this.name, generateCommand);
213
- this.#disposables.add(dispose);
214
- return () => {
215
- dispose();
216
- this.#disposables.delete(dispose);
217
- };
218
- }
219
- // 回退到本地存储
192
+ addTool(tool) {
193
+ // 自动添加插件源标识
220
194
  const toolWithSource = {
221
195
  ...tool,
222
196
  source: tool.source || `plugin:${this.name}`,
@@ -263,15 +237,10 @@ export class Plugin extends EventEmitter {
263
237
  return undefined;
264
238
  }
265
239
  /**
266
- * 收集所有可用的工具
267
- * 优先使用 ToolService,否则回退到本地收集
240
+ * 收集所有可用的工具(包括适配器提供的)
241
+ * 这是 AI 服务获取工具的主入口
268
242
  */
269
243
  collectAllTools() {
270
- const toolService = this.root.inject('tool');
271
- if (toolService && typeof toolService.collectAll === 'function') {
272
- return toolService.collectAll(this.root);
273
- }
274
- // 回退到本地收集
275
244
  const tools = [];
276
245
  // 收集插件树中的所有工具
277
246
  const rootPlugin = this.root;
@@ -287,45 +256,71 @@ export class Plugin extends EventEmitter {
287
256
  return tools;
288
257
  }
289
258
  /**
290
- * 显式设置插件名称(优先级高于路径推导)。
291
- * 可通过以下方式声明:
292
- * 1. 模块导出 `export const pluginName = 'my-plugin'`
293
- * 2. 调用 `plugin.setName('my-plugin')`
294
- */
295
- setName(name) {
296
- this.#explicitName = name;
297
- this.#cachedName = name;
298
- this.logger = logger.getLogger(name);
299
- }
300
- /**
301
- * 插件名称(显式名称 > 路径推导)
259
+ * 插件名称
302
260
  */
303
261
  get name() {
304
- if (this.#explicitName)
305
- return this.#explicitName;
306
262
  if (this.#cachedName)
307
263
  return this.#cachedName;
308
- let name = path
264
+ this.#cachedName = path
309
265
  .relative(process.cwd(), this.filePath)
310
266
  .replace(/\?t=\d+$/, "")
311
267
  .replace(/\\/g, "/")
312
268
  .replace(/\/index\.(js|ts)x?$/, "")
313
- .replace(/\/(lib|src|dist)$/, "");
314
- // 安全地提取 node_modules 后的包名或最后的文件名
315
- const nodeModulesIndex = name.indexOf('node_modules/');
316
- if (nodeModulesIndex !== -1) {
317
- name = name.substring(nodeModulesIndex + 'node_modules/'.length);
318
- }
319
- // 提取最后一个路径段
320
- const lastSlash = name.lastIndexOf('/');
321
- if (lastSlash !== -1) {
322
- name = name.substring(lastSlash + 1);
323
- }
324
- // 移除文件扩展名
325
- name = name.replace(/\.(js|ts)x?$/, "");
326
- this.#cachedName = name;
269
+ .replace(/\/(lib|src|dist)$/, "")
270
+ .replace(/.*\/node_modules\//, "")
271
+ .replace(/.*\//, "")
272
+ .replace(/\.(js|ts)x?$/, "");
327
273
  return this.#cachedName;
328
274
  }
275
+ /**
276
+ * 插件清单(从 plugin.yml 或 package.json 延迟读取)
277
+ */
278
+ get manifest() {
279
+ if (this.#manifest !== undefined)
280
+ return this.#manifest ?? undefined;
281
+ if (!this.filePath) {
282
+ this.#manifest = null;
283
+ return undefined;
284
+ }
285
+ const dir = path.dirname(this.filePath);
286
+ // 优先读取 plugin.yml
287
+ const ymlPath = path.join(dir, 'plugin.yml');
288
+ if (fs.existsSync(ymlPath)) {
289
+ try {
290
+ const content = fs.readFileSync(ymlPath, 'utf-8');
291
+ const match = content.match(/^name:\s*(.+)$/m);
292
+ const descMatch = content.match(/^description:\s*(.+)$/m);
293
+ const verMatch = content.match(/^version:\s*(.+)$/m);
294
+ if (match) {
295
+ this.#manifest = {
296
+ name: match[1].trim(),
297
+ description: descMatch?.[1]?.trim(),
298
+ version: verMatch?.[1]?.trim(),
299
+ };
300
+ return this.#manifest;
301
+ }
302
+ }
303
+ catch { /* ignore */ }
304
+ }
305
+ // Fallback: package.json
306
+ const pkgPath = path.join(dir, 'package.json');
307
+ if (fs.existsSync(pkgPath)) {
308
+ try {
309
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
310
+ if (pkg.name) {
311
+ this.#manifest = {
312
+ name: pkg.name,
313
+ description: pkg.description,
314
+ version: pkg.version,
315
+ };
316
+ return this.#manifest;
317
+ }
318
+ }
319
+ catch { /* ignore */ }
320
+ }
321
+ this.#manifest = null;
322
+ return undefined;
323
+ }
329
324
  /**
330
325
  * 根插件
331
326
  */
@@ -365,6 +360,7 @@ export class Plugin extends EventEmitter {
365
360
  sideEffect.finished = false;
366
361
  };
367
362
  this.on('context.dispose', disposeFn);
363
+ // 确保 dispose 时清理监听器(只注册一次)
368
364
  const cleanupOnDispose = () => {
369
365
  this.off('context.dispose', disposeFn);
370
366
  dispose(this.inject(args[0]));
@@ -414,9 +410,18 @@ export class Plugin extends EventEmitter {
414
410
  for (const context of this.$contexts.values()) {
415
411
  if (typeof context.mounted === "function") {
416
412
  const result = await context.mounted(this);
417
- // 仅当 value 未预设时才赋值(mounted 始终执行,以支持副作用如设置内部引用)
418
- if (!context.value)
413
+ // 仅在没有预设 value 时才用 mounted 返回值赋值
414
+ if (!context.value) {
419
415
  context.value = result;
416
+ }
417
+ }
418
+ // 注册扩展方法到 Plugin.prototype
419
+ if (context.extensions) {
420
+ for (const [name, fn] of Object.entries(context.extensions)) {
421
+ if (typeof fn === 'function') {
422
+ Reflect.set(Plugin.prototype, name, fn);
423
+ }
424
+ }
420
425
  }
421
426
  this.dispatch('context.mounted', context.name);
422
427
  }
@@ -425,149 +430,55 @@ export class Plugin extends EventEmitter {
425
430
  for (const child of this.children) {
426
431
  await child.start(t);
427
432
  }
428
- this.logger.debug(`Plugin "${this.name}" ${t ? `reloaded in ${Date.now() - t}ms` : "started"}`);
429
- }
430
- /**
431
- * 记录 Feature 贡献(由 Feature extensions 内部调用)
432
- * @param featureName Feature 名称(如 'command')
433
- * @param itemName item 标识(如命令 pattern)
434
- */
435
- recordFeatureContribution(featureName, itemName) {
436
- if (!this.#featureContributions.has(featureName)) {
437
- this.#featureContributions.set(featureName, new Set());
438
- }
439
- this.#featureContributions.get(featureName).add(itemName);
440
- }
441
- /**
442
- * 收集本插件及所有后代插件的 Feature 贡献名称
443
- * 解决 Plugin.create() 包装问题:外层插件的 #featureContributions 为空,
444
- * 实际贡献记录在 usePlugin() 创建的内层子插件上
445
- */
446
- #collectAllFeatureNames(names) {
447
- for (const name of this.#featureContributions.keys()) {
448
- names.add(name);
433
+ // 输出启动日志(使用 debug 级别,避免重复输出)
434
+ // 只在根插件或重要插件时使用 info 级别
435
+ if (!this.parent || this.name === 'setup') {
436
+ this.logger.info(`Plugin "${this.name}" ${t ? `reloaded in ${Date.now() - t}ms` : "started"}`);
449
437
  }
450
- for (const child of this.children) {
451
- child.#collectAllFeatureNames(names);
438
+ else {
439
+ this.logger.debug(`Plugin "${this.name}" ${t ? `reloaded in ${Date.now() - t}ms` : "started"}`);
452
440
  }
453
441
  }
454
442
  /**
455
- * 收集本插件及所有后代插件的 plugin name 集合
456
- * 用于 Feature.toJSON(pluginName) 匹配
443
+ * 获取插件提供的功能
444
+ * 从各个服务中获取数据
457
445
  */
458
- #collectAllPluginNames(names) {
459
- names.add(this.name);
460
- for (const child of this.children) {
461
- child.#collectAllPluginNames(names);
462
- }
446
+ get features() {
447
+ const commandService = this.inject('command');
448
+ const componentService = this.inject('component');
449
+ const cronService = this.inject('cron');
450
+ return {
451
+ commands: commandService ? commandService.items.map(c => c.pattern) : [],
452
+ components: componentService ? componentService.getAllNames() : [],
453
+ crons: cronService ? cronService.items.map(c => c.cronExpression) : [],
454
+ middlewares: this.#middlewares.map((m, i) => m.name || `middleware_${i}`),
455
+ };
463
456
  }
464
457
  /**
465
- * 获取当前插件的所有 Feature 数据(用于 HTTP API)
466
- * 遍历插件贡献的 Feature,调用各 Feature 的 toJSON(pluginName) 获取序列化数据
467
- * 同时包含 middleware(方案 B: 本地构造)
468
- *
469
- * 注意:Plugin.create() 创建 "外层" 插件,usePlugin() 创建 "内层" 子插件。
470
- * extension 方法 (addCommand 等) 通过 getPlugin() 记录在内层插件上。
471
- * 因此需要遍历整个子树来收集 feature 贡献名称。
458
+ * 获取插件功能摘要(数组形式)
459
+ * 返回各功能类型的名称和数量
472
460
  */
473
461
  getFeatures() {
474
462
  const result = [];
475
- // 收集本插件及所有后代插件的 feature 名称和 plugin 名称
476
- const featureNames = new Set();
477
- this.#collectAllFeatureNames(featureNames);
478
- const pluginNames = new Set();
479
- this.#collectAllPluginNames(pluginNames);
480
- // Feature 贡献中收集
481
- for (const featureName of featureNames) {
482
- const feature = this.inject(featureName);
483
- if (feature instanceof Feature) {
484
- // 先用当前插件名尝试
485
- let json = feature.toJSON(this.name);
486
- if (json.count === 0) {
487
- // 当前插件名匹配不到(可能名称不同),尝试后代插件名
488
- for (const pName of pluginNames) {
489
- if (pName === this.name)
490
- continue;
491
- json = feature.toJSON(pName);
492
- if (json.count > 0)
493
- break;
494
- }
495
- }
496
- if (json.count > 0) {
497
- result.push(json);
498
- }
499
- }
500
- }
501
- // middleware(方案 B: 本地构造,因为 middleware 是 Plugin 私有属性)
502
- // 同样需要收集子插件树中的 middleware
503
- const allMiddlewareNames = [];
504
- const collectMiddlewares = (plugin) => {
505
- const mws = plugin.#middlewares
506
- .filter(m => m !== plugin.#messageMiddleware)
507
- .map((m, i) => m.name || `middleware_${i}`);
508
- allMiddlewareNames.push(...mws);
509
- for (const child of plugin.children) {
510
- collectMiddlewares(child);
511
- }
512
- };
513
- collectMiddlewares(this);
514
- if (allMiddlewareNames.length > 0) {
515
- result.push({
516
- name: 'middleware',
517
- icon: 'Layers',
518
- desc: '中间件',
519
- count: allMiddlewareNames.length,
520
- items: allMiddlewareNames.map(name => ({ name })),
521
- });
522
- }
523
- // 自动检测适配器和服务上下文(从 $contexts 中发现非 Feature 的贡献)
524
- const adapterItems = [];
525
- const serviceItems = [];
526
- const scanContexts = (plugin) => {
527
- for (const [name, context] of plugin.$contexts) {
528
- const value = context.value;
529
- if (value instanceof Adapter) {
530
- adapterItems.push({
531
- name,
532
- bots: value.bots.size,
533
- online: Array.from(value.bots.values()).filter(b => b.$connected).length,
534
- tools: value.tools.size,
535
- });
536
- }
537
- else if (value !== undefined && !(value instanceof Feature)) {
538
- // 非 Feature、非 Adapter 的上下文 = 服务
539
- serviceItems.push({ name, desc: context.description || name });
540
- }
541
- }
542
- for (const child of plugin.children) {
543
- scanContexts(child);
544
- }
545
- };
546
- scanContexts(this);
547
- if (adapterItems.length > 0) {
548
- result.push({
549
- name: 'adapter',
550
- icon: 'Plug',
551
- desc: '适配器',
552
- count: adapterItems.length,
553
- items: adapterItems,
554
- });
555
- }
556
- if (serviceItems.length > 0) {
557
- result.push({
558
- name: 'service',
559
- icon: 'Server',
560
- desc: '服务',
561
- count: serviceItems.length,
562
- items: serviceItems,
563
- });
564
- }
463
+ const f = this.features;
464
+ if (f.commands.length > 0)
465
+ result.push({ name: 'command', count: f.commands.length });
466
+ if (f.components.length > 0)
467
+ result.push({ name: 'component', count: f.components.length });
468
+ if (f.crons.length > 0)
469
+ result.push({ name: 'cron', count: f.crons.length });
470
+ // #middlewares includes the default command middleware, only count user-added ones
471
+ const userMiddlewareCount = this.#middlewares.length - 1; // subtract default #messageMiddleware
472
+ if (userMiddlewareCount > 0)
473
+ result.push({ name: 'middleware', count: userMiddlewareCount });
474
+ if (this.#tools.size > 0)
475
+ result.push({ name: 'tool', count: this.#tools.size });
565
476
  return result;
566
477
  }
567
478
  info() {
568
479
  return {
569
480
  [this.name]: {
570
- features: this.getFeatures(),
481
+ features: this.features,
571
482
  children: this.children.map(child => child.info())
572
483
  }
573
484
  };
@@ -585,15 +496,13 @@ export class Plugin extends EventEmitter {
585
496
  await child.stop();
586
497
  }
587
498
  this.children = [];
588
- // 停止服务 — only remove extensions owned by this plugin's contexts
499
+ // 停止服务
589
500
  for (const [name, context] of this.$contexts) {
590
501
  remove(Plugin[contextsKey], name);
502
+ // 移除扩展方法
591
503
  if (context.extensions) {
592
504
  for (const key of Object.keys(context.extensions)) {
593
- if (Plugin[extensionOwnersKey].get(key) === name) {
594
- delete Plugin.prototype[key];
595
- Plugin[extensionOwnersKey].delete(key);
596
- }
505
+ delete Plugin.prototype[key];
597
506
  }
598
507
  }
599
508
  if (typeof context.dispose === "function") {
@@ -672,16 +581,10 @@ export class Plugin extends EventEmitter {
672
581
  await child.broadcast(name, ...args);
673
582
  }
674
583
  }
675
- // ============================================================================
676
- // 依赖注入
677
- // ============================================================================
678
- /**
679
- * 注册上下文(支持 Feature 实例或传统 Context 对象)
680
- */
681
584
  provide(target) {
682
585
  if (target instanceof Feature) {
683
586
  const feature = target;
684
- const context = {
587
+ const ctx = {
685
588
  name: feature.name,
686
589
  description: feature.desc,
687
590
  value: feature,
@@ -696,29 +599,22 @@ export class Plugin extends EventEmitter {
696
599
  : undefined,
697
600
  extensions: feature.extensions,
698
601
  };
699
- return this.provide(context);
602
+ return this.provide(ctx);
700
603
  }
701
604
  const context = target;
702
605
  if (!Plugin[contextsKey].includes(context.name)) {
703
606
  Plugin[contextsKey].push(context.name);
704
607
  }
705
608
  this.logger.debug(`Context "${context.name}" provided`);
706
- // Track which extension methods this context registers.
707
- // On collision, log a warning but allow override (last-write-wins).
609
+ this.$contexts.set(context.name, context);
610
+ // 立即注册扩展方法到 Plugin.prototype,确保后续 import 的插件可用
708
611
  if (context.extensions) {
709
- const extNames = [];
710
612
  for (const [name, fn] of Object.entries(context.extensions)) {
711
613
  if (typeof fn === 'function') {
712
- if (Reflect.has(Plugin.prototype, name) && !Plugin[extensionOwnersKey].has(name)) {
713
- this.logger.warn(`Extension method "${name}" shadows an existing Plugin method`);
714
- }
715
614
  Reflect.set(Plugin.prototype, name, fn);
716
- Plugin[extensionOwnersKey].set(name, context.name);
717
- extNames.push(name);
718
615
  }
719
616
  }
720
617
  }
721
- this.$contexts.set(context.name, context);
722
618
  return this;
723
619
  }
724
620
  // ============================================================================
@@ -800,8 +696,7 @@ export class Plugin extends EventEmitter {
800
696
  static #coreMethods = new Set([
801
697
  'addMiddleware', 'useContext', 'inject', 'contextIsReady',
802
698
  'start', 'stop', 'onMounted', 'onDispose',
803
- 'dispatch', 'broadcast', 'provide', 'import', 'reload', 'watch', 'info',
804
- 'recordFeatureContribution', 'getFeatures',
699
+ 'dispatch', 'broadcast', 'provide', 'import', 'reload', 'watch', 'info'
805
700
  ]);
806
701
  /**
807
702
  * 自动绑定核心方法(只在构造函数中调用一次)
@@ -837,41 +732,13 @@ export class Plugin extends EventEmitter {
837
732
  plugin.fileHash = getFileHash(entryFile);
838
733
  // 先记录,防止循环依赖时重复加载
839
734
  loadedModules.set(realPath, plugin);
840
- let mod;
841
735
  await storage.run(plugin, async () => {
842
- mod = await import(`${pathToFileURL(entryFile).href}?t=${Date.now()}`);
736
+ await import(`${import.meta.resolve(entryFile)}?t=${Date.now()}`);
843
737
  });
844
- // 支持模块显式声明插件名称:export const pluginName = 'my-plugin'
845
- if (mod?.pluginName && typeof mod.pluginName === 'string') {
846
- plugin.setName(mod.pluginName);
847
- }
848
738
  return plugin;
849
739
  }
850
740
  }
851
741
  export function defineContext(options) {
852
742
  return options;
853
743
  }
854
- /**
855
- * 声明式定义插件。
856
- * 提供显式名称 + setup 函数,自动设置当前插件名称并执行 setup。
857
- *
858
- * @example
859
- * ```typescript
860
- * // plugins/weather/index.ts
861
- * export default definePlugin({
862
- * name: 'weather',
863
- * setup(plugin) {
864
- * plugin.addTool({ ... });
865
- * },
866
- * });
867
- * ```
868
- */
869
- export function definePlugin(options) {
870
- const plugin = usePlugin();
871
- if (options.name) {
872
- plugin.setName(options.name);
873
- }
874
- options.setup(plugin);
875
- return { pluginName: options.name };
876
- }
877
744
  //# sourceMappingURL=plugin.js.map