foliko 2.0.3 → 2.0.5

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.
@@ -117,6 +117,9 @@ class Framework extends EventEmitter {
117
117
  // Coordinator
118
118
  this._coordinatorManager = null;
119
119
 
120
+ // Global abort controller for framework.stop()
121
+ this._abortController = null;
122
+
120
123
  // Session TTL
121
124
  this._sessionTTL = new SessionTTL({
122
125
  getSessionContexts: () => this._sessionContexts,
@@ -255,7 +258,400 @@ class Framework extends EventEmitter {
255
258
 
256
259
  // prompts 对象别名(系统提示词注册表)
257
260
  get prompts() {
258
- return this.promptRegistry;
261
+ const reg = this.promptRegistry;
262
+ return {
263
+ available: true,
264
+ /**
265
+ * 注册 prompt part
266
+ * @param {string} owner 拥有者
267
+ * @param {string} name part 名
268
+ * @param {Function} provider () => string|null
269
+ * @param {Object} [options]
270
+ * @param {string} [options.scope='global'] 作用域: 'global'|'main'|agentId
271
+ * @param {number} [options.priority=100] 优先级(越小越靠前)
272
+ * @param {string} [options.description] 描述
273
+ */
274
+ register: (owner, name, provider, options) => reg.register(owner, name, provider, options),
275
+ /**
276
+ * 从文件注册 prompt(支持变量插值)
277
+ * @param {string} owner 拥有者
278
+ * @param {string} filePath 文件路径
279
+ * @param {Object} [vars] 变量对象,模板中用 {{varName}} 引用
280
+ * @param {Object} [options] 同 register 选项
281
+ */
282
+ registerFile: (owner, filePath, vars, options) => reg.registerFile(owner, filePath, vars, options),
283
+ /**
284
+ * 注销 prompt part
285
+ */
286
+ unregister: (owner, name) => reg.unregister(owner, name),
287
+ /**
288
+ * 清空指定 owner 的所有 parts
289
+ */
290
+ clearOwner: (owner) => reg.clearOwner(owner),
291
+ /**
292
+ * 检查是否存在
293
+ */
294
+ has: (owner, name) => reg.has(owner, name),
295
+ /**
296
+ * 获取单个 part
297
+ */
298
+ getPart: (owner, name) => reg.getPart(owner, name),
299
+ /**
300
+ * 列出所有 parts(按 priority 排序)
301
+ */
302
+ list: () => reg.list(),
303
+ /**
304
+ * 按 scope 过滤
305
+ */
306
+ listByScope: (scope) => reg.listByScope(scope),
307
+ /**
308
+ * 获取适用于指定 agent 的 parts
309
+ */
310
+ listForAgent: (agentId) => reg.listForAgent(agentId),
311
+ /**
312
+ * 结构化检查(调试用)
313
+ */
314
+ inspect: () => reg.inspect(),
315
+ /**
316
+ * 渲染完整提示词
317
+ */
318
+ build: () => reg.build(),
319
+ /**
320
+ * 渲染适用于指定 agent 的 prompt
321
+ * @param {string|null} agentId agent ID,null 表示主 agent
322
+ */
323
+ buildForAgent: (agentId) => reg.buildForAgent(agentId),
324
+ /**
325
+ * build() 的语义别名
326
+ */
327
+ preview: () => reg.preview(),
328
+ /**
329
+ * 失效指定 part
330
+ */
331
+ invalidate: (owner, name) => reg.invalidate(owner, name),
332
+ /**
333
+ * 失效所有 parts
334
+ */
335
+ invalidateAll: () => reg.invalidateAll(),
336
+ /**
337
+ * 获取 part 数量
338
+ */
339
+ count: () => reg.count(),
340
+ };
341
+ }
342
+
343
+ // skills 对象别名(技能管理器)
344
+ get skills() {
345
+ const self = this;
346
+ const skillManager = this.pluginManager?.get('skill-manager');
347
+ if (!skillManager) {
348
+ return {
349
+ available: false,
350
+ list: () => [],
351
+ get: () => null,
352
+ has: () => false,
353
+ register: () => null,
354
+ remove: () => false,
355
+ details: () => null,
356
+ listCommands: () => [],
357
+ getCommand: () => null,
358
+ listReferences: () => [],
359
+ getReference: () => null,
360
+ listScripts: () => [],
361
+ getScript: () => null,
362
+ reload: () => {},
363
+ };
364
+ }
365
+ return {
366
+ available: true,
367
+ /**
368
+ * 列出所有已加载的技能
369
+ */
370
+ list: () => skillManager.getAllSkills() || [],
371
+ /**
372
+ * 获取单个技能
373
+ * @param {string} name 技能名称
374
+ */
375
+ get: (name) => skillManager.getSkill(name) || null,
376
+ /**
377
+ * 检查技能是否存在
378
+ */
379
+ has: (name) => skillManager.hasSkill(name) || false,
380
+ /**
381
+ * 获取技能详情(包含 metadata、content、path 等)
382
+ */
383
+ details: (name) => {
384
+ const skill = skillManager.getSkill(name);
385
+ if (!skill) return null;
386
+ return {
387
+ name: skill.name,
388
+ description: skill.metadata?.description || '',
389
+ content: skill.content || '',
390
+ path: skill.path || null,
391
+ metadata: skill.metadata || null,
392
+ references: skill.references ? Array.from(skill.references.keys()) : [],
393
+ scripts: skill.scripts ? Array.from(skill.scripts.keys()) : [],
394
+ fromPlugin: skill.fromPlugin || false,
395
+ };
396
+ },
397
+ /**
398
+ * 注册一个新 skill(程序化注册,不依赖文件)
399
+ * @param {string} name 技能名称
400
+ * @param {string} content 技能内容(markdown)
401
+ * @param {Object} [metadata] 技能元数据 { description, license, compatibility, allowedTools }
402
+ * @param {Object} [options] 选项
403
+ * @param {Array} [options.commands] 命令定义数组
404
+ * @param {string} [options.path] 技能路径
405
+ */
406
+ register: (name, content, metadata = {}, options = {}) => skillManager.register(name, content, metadata, options),
407
+ /**
408
+ * 移除 skill
409
+ * @param {string} name 技能名称
410
+ */
411
+ remove: (name) => skillManager.remove(name),
412
+ /**
413
+ * 列出技能的所有命令
414
+ * @param {string} name 技能名称
415
+ */
416
+ listCommands: (name) => {
417
+ const skill = skillManager.getSkill(name);
418
+ if (!skill || !skill.instance?._commands) return [];
419
+ return skill.instance._commands.map(cmd => {
420
+ const extExecutor = self.pluginManager?.get('extension-executor');
421
+ const toolDef = extExecutor?.getExtensionTool?.('skill', `${name}:${cmd}`);
422
+ return {
423
+ name: cmd,
424
+ description: toolDef?.description || '',
425
+ options: toolDef?._options || null,
426
+ };
427
+ });
428
+ },
429
+ /**
430
+ * 获取技能的单个命令详情
431
+ * @param {string} name 技能名称
432
+ * @param {string} command 命令名(不含技能名前缀)
433
+ */
434
+ getCommand: (name, command) => {
435
+ const fullName = `${name}:${command}`;
436
+ const extExecutor = self.pluginManager?.get('extension-executor');
437
+ const toolDef = extExecutor?.getExtensionTool?.('skill', fullName);
438
+ if (!toolDef) return null;
439
+ return {
440
+ name: fullName,
441
+ description: toolDef.description || '',
442
+ options: toolDef._options || null,
443
+ inputSchema: toolDef.inputSchema || null,
444
+ };
445
+ },
446
+ /**
447
+ * 列出技能的所有 reference 文件
448
+ * @param {string} name 技能名称
449
+ */
450
+ listReferences: (name) => skillManager.listReferences(name) || [],
451
+ /**
452
+ * 获取 reference 文件内容(按需加载)
453
+ * @param {string} name 技能名称
454
+ * @param {string} refName reference 名(不含 .md)
455
+ */
456
+ getReference: (name, refName) => skillManager.loadReference(name, refName),
457
+ /**
458
+ * 列出技能的所有脚本
459
+ * @param {string} name 技能名称
460
+ */
461
+ listScripts: (name) => skillManager.listScripts(name) || [],
462
+ /**
463
+ * 获取脚本内容
464
+ * @param {string} name 技能名称
465
+ * @param {string} scriptName 脚本名(含扩展名)
466
+ */
467
+ getScript: (name, scriptName) => skillManager.loadScript(name, scriptName),
468
+ /**
469
+ * 重载所有技能
470
+ */
471
+ reload: () => skillManager.reload(self),
472
+ };
473
+ }
474
+
475
+ // workflows 对象别名(工作流引擎)
476
+ get workflows() {
477
+ const self = this;
478
+ const workflowPlugin = this.pluginManager?.get('workflow');
479
+ if (!workflowPlugin) {
480
+ return {
481
+ available: false,
482
+ list: () => [],
483
+ get: () => null,
484
+ has: () => false,
485
+ execute: async () => ({ success: false, error: 'workflow plugin not loaded' }),
486
+ register: () => null,
487
+ remove: () => false,
488
+ reload: () => {},
489
+ };
490
+ }
491
+ return {
492
+ available: true,
493
+ /**
494
+ * 列出所有已加载的工作流
495
+ */
496
+ list: () => {
497
+ const workflows = [];
498
+ for (const [name, workflow] of workflowPlugin._workflows) {
499
+ workflows.push({
500
+ name,
501
+ description: workflow.description || '',
502
+ stepCount: workflow.steps?.length || 0,
503
+ type: workflow.type || 'sequential',
504
+ });
505
+ }
506
+ return workflows;
507
+ },
508
+ /**
509
+ * 获取单个工作流定义
510
+ */
511
+ get: (name) => workflowPlugin._workflows.get(name) || null,
512
+ /**
513
+ * 检查工作流是否存在
514
+ */
515
+ has: (name) => workflowPlugin._workflows.has(name),
516
+ /**
517
+ * 执行工作流
518
+ * @param {string|Object} workflowDef 工作流定义(名称/JSON/JS 代码)
519
+ * @param {Object} input 工作流输入参数
520
+ * @param {string} sessionId 会话 ID(可选)
521
+ */
522
+ execute: (workflowDef, input = {}, sessionId = null) =>
523
+ workflowPlugin.executeWorkflow(workflowDef, input, sessionId),
524
+ /**
525
+ * 注册工作流定义(程序化注册)
526
+ * @param {string} name 工作流名称
527
+ * @param {Object} workflowDef 工作流定义
528
+ */
529
+ register: (name, workflowDef) => {
530
+ if (workflowPlugin._workflows.has(name)) {
531
+ return { success: false, error: `Workflow "${name}" already exists` };
532
+ }
533
+ if (!workflowDef || !workflowDef.steps) {
534
+ return { success: false, error: 'Invalid workflow: missing steps' };
535
+ }
536
+ workflowPlugin._workflows.set(name, workflowDef);
537
+ // 注册为工具
538
+ const toolName = `workflow_${name}`;
539
+ const description = workflowDef.description || `执行工作流: ${name}`;
540
+ self.registerTool({
541
+ name: toolName,
542
+ description,
543
+ inputSchema: require('zod').object({
544
+ input: require('zod').object({}).optional().describe('工作流输入参数'),
545
+ }),
546
+ execute: async (args, framework) => {
547
+ let sid = null;
548
+ const ctx = framework?.getExecutionContext?.();
549
+ if (ctx?.sessionId) sid = ctx.sessionId;
550
+ return await workflowPlugin.executeWorkflow(workflowDef, args.input || {}, sid);
551
+ },
552
+ });
553
+ workflowPlugin._workflowTools.set(name, toolName);
554
+ return { success: true, data: { name, toolName } };
555
+ },
556
+ /**
557
+ * 移除工作流
558
+ * @param {string} name 工作流名称
559
+ */
560
+ remove: (name) => workflowPlugin.remove(name),
561
+ /**
562
+ * 获取工作流引擎
563
+ */
564
+ getEngine: () => workflowPlugin.getEngine(),
565
+ /**
566
+ * 重载工作流
567
+ */
568
+ reload: () => workflowPlugin.reload(self),
569
+ };
570
+ }
571
+
572
+ // rules 对象别名(规则引擎)
573
+ get rules() {
574
+ const self = this;
575
+ const rulesPlugin = this.pluginManager?.get('rules');
576
+ if (!rulesPlugin) {
577
+ return {
578
+ available: false,
579
+ list: () => [],
580
+ add: () => null,
581
+ remove: () => false,
582
+ test: () => null,
583
+ stats: () => null,
584
+ };
585
+ }
586
+ return {
587
+ available: true,
588
+ /**
589
+ * 列出所有规则
590
+ */
591
+ list: () => rulesPlugin._rules.map(r => ({
592
+ name: r.name,
593
+ type: r.type,
594
+ target: r.target,
595
+ description: r.description,
596
+ enabled: r.enabled,
597
+ })),
598
+ /**
599
+ * 添加规则
600
+ * @param {Object} rule 规则定义
601
+ */
602
+ add: (rule) => {
603
+ const newRule = {
604
+ name: rule.name,
605
+ type: rule.type,
606
+ target: rule.target,
607
+ pattern: rule.pattern ? new RegExp(rule.pattern) : null,
608
+ description: rule.description || '',
609
+ action: rule.action || {},
610
+ enabled: rule.enabled !== false,
611
+ };
612
+ rulesPlugin._rules.push(newRule);
613
+ return newRule;
614
+ },
615
+ /**
616
+ * 移除规则
617
+ */
618
+ remove: (name) => rulesPlugin.removeRule(name),
619
+ /**
620
+ * 测试规则匹配
621
+ * @param {string} target 目标(工具名或事件类型)
622
+ * @param {Object} input 输入参数
623
+ */
624
+ test: (target, input = {}) => {
625
+ const result = rulesPlugin.evaluate(target, input);
626
+ return {
627
+ allowed: result.allowed,
628
+ ruleName: result.rule?.name || null,
629
+ ruleType: result.rule?.type || null,
630
+ };
631
+ },
632
+ /**
633
+ * 获取规则统计
634
+ */
635
+ stats: () => ({ ...rulesPlugin._ruleStats }),
636
+ /**
637
+ * 检查工具调用
638
+ */
639
+ checkToolCall: (toolName, args) => {
640
+ const result = rulesPlugin.checkToolCall(toolName, args);
641
+ return { allowed: result.allowed, rule: result.rule };
642
+ },
643
+ /**
644
+ * 检查消息
645
+ */
646
+ checkMessage: (message, context) => {
647
+ const result = rulesPlugin.checkMessage(message, context);
648
+ return { allowed: result.allowed, rule: result.rule };
649
+ },
650
+ /**
651
+ * 重载规则
652
+ */
653
+ reload: () => rulesPlugin.reload(self),
654
+ };
259
655
  }
260
656
 
261
657
  // plugins 对象别名
@@ -295,7 +691,7 @@ class Framework extends EventEmitter {
295
691
  }
296
692
 
297
693
  // Extension 对象别名
298
- get extension() {
694
+ get extensions() {
299
695
  const self = this;
300
696
  return {
301
697
  tool: (pluginName, tools) => self.registerExtensionTools(pluginName, tools),
@@ -328,6 +724,227 @@ class Framework extends EventEmitter {
328
724
  return this.executeTool('ext_call', { plugin, tool, args });
329
725
  }
330
726
 
727
+ // storage 对象别名(键值存储)
728
+ get storage() {
729
+ const storagePlugin = this.pluginManager?.get('storage');
730
+ if (!storagePlugin) {
731
+ return {
732
+ available: false,
733
+ get: () => null,
734
+ set: () => null,
735
+ delete: () => null,
736
+ list: () => [],
737
+ clear: () => null,
738
+ stats: () => null,
739
+ compact: () => null,
740
+ };
741
+ }
742
+ return {
743
+ available: true,
744
+ /**
745
+ * 获取存储的值
746
+ */
747
+ get: (key, namespace) => {
748
+ storagePlugin._initStorage();
749
+ const ns = namespace ? `${namespace}:` : '';
750
+ return storagePlugin._storageManager.get(`${ns}${key}`);
751
+ },
752
+ /**
753
+ * 设置存储的值
754
+ */
755
+ set: (key, value, namespace) => {
756
+ storagePlugin._initStorage();
757
+ const ns = namespace ? `${namespace}:` : '';
758
+ return storagePlugin._storageManager.set(`${ns}${key}`, value);
759
+ },
760
+ /**
761
+ * 删除存储的键(软删除)
762
+ */
763
+ delete: (key, namespace) => {
764
+ storagePlugin._initStorage();
765
+ const ns = namespace ? `${namespace}:` : '';
766
+ return storagePlugin._storageManager.delete(`${ns}${key}`);
767
+ },
768
+ /**
769
+ * 列出命名空间下的所有键
770
+ */
771
+ list: (namespace) => {
772
+ storagePlugin._initStorage();
773
+ const ns = namespace ? `${namespace}:` : '';
774
+ return storagePlugin._storageManager.list(ns).map(k => k.substring(ns.length));
775
+ },
776
+ /**
777
+ * 清空命名空间下的所有数据
778
+ */
779
+ clear: (namespace) => {
780
+ storagePlugin._initStorage();
781
+ const ns = namespace ? `${namespace}:` : '';
782
+ const keys = storagePlugin._storageManager.list(ns);
783
+ let count = 0;
784
+ for (const key of keys) {
785
+ if (storagePlugin._storageManager.delete(key)) count++;
786
+ }
787
+ return { cleared: count };
788
+ },
789
+ /**
790
+ * 获取存储统计信息
791
+ */
792
+ stats: () => {
793
+ storagePlugin._initStorage();
794
+ return storagePlugin._storageManager.getCompactionStats();
795
+ },
796
+ /**
797
+ * 手动触发 compaction
798
+ */
799
+ compact: () => storagePlugin._storageManager.compact(),
800
+ /**
801
+ * 获取底层 StorageManager
802
+ */
803
+ getStore: () => storagePlugin.getStore(),
804
+ };
805
+ }
806
+
807
+ // sessions 对象别名(会话管理)
808
+ get sessions() {
809
+ const self = this;
810
+ return {
811
+ /**
812
+ * 列出所有会话 ID
813
+ */
814
+ list: () => Array.from(this._sessionContexts.keys()),
815
+ /**
816
+ * 获取会话上下文
817
+ */
818
+ get: (sessionId) => this.getSessionContext(sessionId),
819
+ /**
820
+ * 创建或获取会话
821
+ */
822
+ getOrCreate: (sessionId, options) => this.getOrCreateSessionContext(sessionId, options),
823
+ /**
824
+ * 销毁会话
825
+ */
826
+ destroy: (sessionId) => this.destroySessionContext(sessionId),
827
+ /**
828
+ * 获取当前会话 ID
829
+ */
830
+ currentId: () => this.getCurrentSessionId(),
831
+ /**
832
+ * 在会话中执行代码
833
+ */
834
+ runIn: (sessionId, options, fn) => this.runInSession(sessionId, options, fn),
835
+ };
836
+ }
837
+
838
+ // mcps 对象别名(MCP 服务器管理)
839
+ get mcps() {
840
+ const self = this;
841
+ const mcpPlugin = this.pluginManager?.get('mcp');
842
+ if (!mcpPlugin) {
843
+ return {
844
+ available: false,
845
+ list: () => [],
846
+ get: () => null,
847
+ has: () => false,
848
+ addServer: async () => ({ success: false, error: 'mcp plugin not loaded' }),
849
+ removeServer: async () => false,
850
+ call: async () => ({ success: false, error: 'mcp plugin not loaded' }),
851
+ getToolSchema: async () => null,
852
+ setEnabled: async () => null,
853
+ reload: async () => null,
854
+ };
855
+ }
856
+ return {
857
+ available: true,
858
+ /**
859
+ * 列出所有已连接的 MCP 服务器
860
+ */
861
+ list: () => {
862
+ const servers = [];
863
+ for (const [name, info] of mcpPlugin._clients) {
864
+ servers.push({
865
+ name,
866
+ enabled: true,
867
+ connected: true,
868
+ tools: info.tools.map((t) => ({ name: t.name, description: t.description })),
869
+ });
870
+ }
871
+ for (const [name, config] of mcpPlugin._serverConfigs) {
872
+ if (!mcpPlugin._clients.has(name)) {
873
+ servers.push({ name, enabled: false, connected: false, tools: [] });
874
+ }
875
+ }
876
+ return servers;
877
+ },
878
+ /**
879
+ * 获取 MCP 服务器信息
880
+ */
881
+ get: (name) => {
882
+ const clientInfo = mcpPlugin._clients.get(name);
883
+ if (!clientInfo) {
884
+ const config = mcpPlugin._serverConfigs.get(name);
885
+ return config ? { name, enabled: false, connected: false, tools: [] } : null;
886
+ }
887
+ return {
888
+ name,
889
+ enabled: true,
890
+ connected: true,
891
+ tools: clientInfo.tools.map((t) => ({ name: t.name, description: t.description })),
892
+ };
893
+ },
894
+ /**
895
+ * 检查 MCP 服务器是否存在
896
+ */
897
+ has: (name) => mcpPlugin._clients.has(name) || mcpPlugin._serverConfigs.has(name),
898
+ /**
899
+ * 添加 MCP 服务器
900
+ * @param {Object} config 服务器配置 { name, command, args, env, type, url, headers }
901
+ */
902
+ add: (config) => mcpPlugin.addServer(config),
903
+ /**
904
+ * 添加 MCP 服务器(add 的别名)
905
+ */
906
+ addServer: (config) => mcpPlugin.addServer(config),
907
+ /**
908
+ * 移除 MCP 服务器
909
+ */
910
+ removeServer: async (name) => {
911
+ await mcpPlugin.removeServer(name);
912
+ return true;
913
+ },
914
+ /**
915
+ * 调用 MCP 工具
916
+ * @param {string} server 服务器名
917
+ * @param {string} tool 工具名
918
+ * @param {Object} args 参数
919
+ */
920
+ call: async (server, tool, args) => {
921
+ return await self.executeTool('mcp_call', {
922
+ server,
923
+ tool,
924
+ args_json: JSON.stringify(args || {}),
925
+ });
926
+ },
927
+ /**
928
+ * 获取工具调用示例
929
+ */
930
+ getToolSchema: async (server, tool) => {
931
+ return await self.executeTool('mcp_tool_schema', { server, tool });
932
+ },
933
+ /**
934
+ * 动态开启/关闭 MCP 服务器
935
+ */
936
+ setEnabled: async (server, enabled) => {
937
+ return await self.executeTool('mcp_set_enabled', { server, enabled });
938
+ },
939
+ /**
940
+ * 重载 MCP 配置
941
+ */
942
+ reload: async () => {
943
+ return await self.executeTool('mcp_reload', {});
944
+ },
945
+ };
946
+ }
947
+
331
948
  getMainAgent() { return this._mainAgent; }
332
949
  getSystemPrompt() { return this._mainAgent?._buildSystemPrompt?.() || ''; }
333
950
  getPluginInstance(name) { return this.pluginManager.get(name) || null; }
@@ -336,6 +953,36 @@ class Framework extends EventEmitter {
336
953
 
337
954
  getCwd() { return this._cwd; }
338
955
 
956
+ /**
957
+ * 获取全局 abort signal,用于中断正在运行的对话
958
+ */
959
+ getAbortSignal() {
960
+ if (!this._abortController || this._abortController.signal.aborted) {
961
+ this._abortController = new AbortController();
962
+ }
963
+ return this._abortController.signal;
964
+ }
965
+
966
+ /**
967
+ * 立即中断所有正在运行的 Agent 对话
968
+ */
969
+ stop() {
970
+ if (this._abortController) {
971
+ this._abortController.abort(new Error('用户中断'));
972
+ this._abortController = null;
973
+ }
974
+ // 清空消息队列
975
+ for (const agent of this._agents) {
976
+ if (agent._chatHandler?.queueManager) {
977
+ agent._chatHandler.queueManager.clear();
978
+ }
979
+ if (typeof agent.cancelSession === 'function') {
980
+ agent.cancelSession('default');
981
+ }
982
+ }
983
+ this.emit('framework:stopped');
984
+ }
985
+
339
986
  registerEventDescription(eventType, description, schema = null) { this.pluginManager.registerEventDescription(eventType, description, schema); return this; }
340
987
  getEventDescriptions() { return this.pluginManager.getEventDescriptions(); }
341
988
  getEventDescription(eventType) { return this.pluginManager.getEventDescription(eventType); }
@@ -29,10 +29,10 @@ class Plugin {
29
29
  * prompts = [
30
30
  * {
31
31
  * name: 'my-part',
32
- * slot: 'BEHAVIOR', // 可选,PROMPT_SLOT 中的一个;默认 CUSTOM
33
- * order: 50, // 可选,覆盖 slot 默认 order
32
+ * scope: 'global', // 可选:'global'|'main'|agentId,默认 'global'
33
+ * priority: 50, // 可选,数字越小越靠前,默认 100
34
34
  * description: '描述', // 可选
35
- * provider() { // 'this' 绑定到 plugin 实例;不要用箭头函数
35
+ * provider() { // 'this' 绑定到 plugin 实例;不要用箭头函数
36
36
  * return this._buildSomething();
37
37
  * },
38
38
  * },
@@ -99,8 +99,8 @@ class Plugin {
99
99
  // bind 让 provider 中的 this 指向 plugin 实例
100
100
  const boundProvider = entry.provider.bind(this);
101
101
  reg.register(this.name, entry.name, boundProvider, {
102
- slot: entry.slot,
103
- order: entry.order,
102
+ scope: entry.scope,
103
+ priority: entry.priority,
104
104
  description: entry.description,
105
105
  });
106
106
  } catch (err) {