@zhin.js/core 1.0.24 → 1.0.26

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 (211) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/README.md +84 -342
  3. package/lib/adapter.d.ts +45 -1
  4. package/lib/adapter.d.ts.map +1 -1
  5. package/lib/adapter.js +182 -1
  6. package/lib/adapter.js.map +1 -1
  7. package/lib/ai/agent.d.ts +126 -0
  8. package/lib/ai/agent.d.ts.map +1 -0
  9. package/lib/ai/agent.js +645 -0
  10. package/lib/ai/agent.js.map +1 -0
  11. package/lib/ai/context-manager.d.ts +213 -0
  12. package/lib/ai/context-manager.d.ts.map +1 -0
  13. package/lib/ai/context-manager.js +313 -0
  14. package/lib/ai/context-manager.js.map +1 -0
  15. package/lib/ai/conversation-memory.d.ts +181 -0
  16. package/lib/ai/conversation-memory.d.ts.map +1 -0
  17. package/lib/ai/conversation-memory.js +581 -0
  18. package/lib/ai/conversation-memory.js.map +1 -0
  19. package/lib/ai/follow-up.d.ts +131 -0
  20. package/lib/ai/follow-up.d.ts.map +1 -0
  21. package/lib/ai/follow-up.js +265 -0
  22. package/lib/ai/follow-up.js.map +1 -0
  23. package/lib/ai/index.d.ts +29 -0
  24. package/lib/ai/index.d.ts.map +1 -0
  25. package/lib/ai/index.js +34 -0
  26. package/lib/ai/index.js.map +1 -0
  27. package/lib/ai/init.d.ts +30 -0
  28. package/lib/ai/init.d.ts.map +1 -0
  29. package/lib/ai/init.js +424 -0
  30. package/lib/ai/init.js.map +1 -0
  31. package/lib/ai/output.d.ts +93 -0
  32. package/lib/ai/output.d.ts.map +1 -0
  33. package/lib/ai/output.js +176 -0
  34. package/lib/ai/output.js.map +1 -0
  35. package/lib/ai/providers/anthropic.d.ts +23 -0
  36. package/lib/ai/providers/anthropic.d.ts.map +1 -0
  37. package/lib/ai/providers/anthropic.js +322 -0
  38. package/lib/ai/providers/anthropic.js.map +1 -0
  39. package/lib/ai/providers/base.d.ts +43 -0
  40. package/lib/ai/providers/base.d.ts.map +1 -0
  41. package/lib/ai/providers/base.js +135 -0
  42. package/lib/ai/providers/base.js.map +1 -0
  43. package/lib/ai/providers/index.d.ts +12 -0
  44. package/lib/ai/providers/index.d.ts.map +1 -0
  45. package/lib/ai/providers/index.js +9 -0
  46. package/lib/ai/providers/index.js.map +1 -0
  47. package/lib/ai/providers/ollama.d.ts +25 -0
  48. package/lib/ai/providers/ollama.d.ts.map +1 -0
  49. package/lib/ai/providers/ollama.js +243 -0
  50. package/lib/ai/providers/ollama.js.map +1 -0
  51. package/lib/ai/providers/openai.d.ts +46 -0
  52. package/lib/ai/providers/openai.d.ts.map +1 -0
  53. package/lib/ai/providers/openai.js +132 -0
  54. package/lib/ai/providers/openai.js.map +1 -0
  55. package/lib/ai/rate-limiter.d.ts +38 -0
  56. package/lib/ai/rate-limiter.d.ts.map +1 -0
  57. package/lib/ai/rate-limiter.js +86 -0
  58. package/lib/ai/rate-limiter.js.map +1 -0
  59. package/lib/ai/service.d.ts +81 -0
  60. package/lib/ai/service.d.ts.map +1 -0
  61. package/lib/ai/service.js +274 -0
  62. package/lib/ai/service.js.map +1 -0
  63. package/lib/ai/session.d.ts +186 -0
  64. package/lib/ai/session.d.ts.map +1 -0
  65. package/lib/ai/session.js +443 -0
  66. package/lib/ai/session.js.map +1 -0
  67. package/lib/ai/tone-detector.d.ts +19 -0
  68. package/lib/ai/tone-detector.d.ts.map +1 -0
  69. package/lib/ai/tone-detector.js +72 -0
  70. package/lib/ai/tone-detector.js.map +1 -0
  71. package/lib/ai/tools.d.ts +45 -0
  72. package/lib/ai/tools.d.ts.map +1 -0
  73. package/lib/ai/tools.js +206 -0
  74. package/lib/ai/tools.js.map +1 -0
  75. package/lib/ai/types.d.ts +264 -0
  76. package/lib/ai/types.d.ts.map +1 -0
  77. package/lib/ai/types.js +6 -0
  78. package/lib/ai/types.js.map +1 -0
  79. package/lib/ai/user-profile.d.ts +56 -0
  80. package/lib/ai/user-profile.d.ts.map +1 -0
  81. package/lib/ai/user-profile.js +130 -0
  82. package/lib/ai/user-profile.js.map +1 -0
  83. package/lib/ai/zhin-agent.d.ts +165 -0
  84. package/lib/ai/zhin-agent.d.ts.map +1 -0
  85. package/lib/ai/zhin-agent.js +707 -0
  86. package/lib/ai/zhin-agent.js.map +1 -0
  87. package/lib/built/adapter-process.d.ts +4 -0
  88. package/lib/built/adapter-process.d.ts.map +1 -1
  89. package/lib/built/adapter-process.js +94 -0
  90. package/lib/built/adapter-process.js.map +1 -1
  91. package/lib/built/ai-trigger.d.ts +89 -0
  92. package/lib/built/ai-trigger.d.ts.map +1 -0
  93. package/lib/built/ai-trigger.js +166 -0
  94. package/lib/built/ai-trigger.js.map +1 -0
  95. package/lib/built/command.d.ts +33 -17
  96. package/lib/built/command.d.ts.map +1 -1
  97. package/lib/built/command.js +71 -44
  98. package/lib/built/command.js.map +1 -1
  99. package/lib/built/component.d.ts +42 -15
  100. package/lib/built/component.d.ts.map +1 -1
  101. package/lib/built/component.js +84 -52
  102. package/lib/built/component.js.map +1 -1
  103. package/lib/built/config.d.ts +54 -5
  104. package/lib/built/config.d.ts.map +1 -1
  105. package/lib/built/config.js +76 -10
  106. package/lib/built/config.js.map +1 -1
  107. package/lib/built/cron.d.ts +41 -18
  108. package/lib/built/cron.d.ts.map +1 -1
  109. package/lib/built/cron.js +106 -63
  110. package/lib/built/cron.js.map +1 -1
  111. package/lib/built/database.d.ts +55 -6
  112. package/lib/built/database.d.ts.map +1 -1
  113. package/lib/built/database.js +93 -22
  114. package/lib/built/database.js.map +1 -1
  115. package/lib/built/dispatcher.d.ts +118 -0
  116. package/lib/built/dispatcher.d.ts.map +1 -0
  117. package/lib/built/dispatcher.js +196 -0
  118. package/lib/built/dispatcher.js.map +1 -0
  119. package/lib/built/permission.d.ts +45 -5
  120. package/lib/built/permission.d.ts.map +1 -1
  121. package/lib/built/permission.js +56 -11
  122. package/lib/built/permission.js.map +1 -1
  123. package/lib/built/skill.d.ts +117 -0
  124. package/lib/built/skill.d.ts.map +1 -0
  125. package/lib/built/skill.js +191 -0
  126. package/lib/built/skill.js.map +1 -0
  127. package/lib/built/tool.d.ts +188 -0
  128. package/lib/built/tool.d.ts.map +1 -0
  129. package/lib/built/tool.js +749 -0
  130. package/lib/built/tool.js.map +1 -0
  131. package/lib/feature.d.ts +75 -0
  132. package/lib/feature.d.ts.map +1 -0
  133. package/lib/feature.js +69 -0
  134. package/lib/feature.js.map +1 -0
  135. package/lib/index.d.ts +6 -0
  136. package/lib/index.d.ts.map +1 -1
  137. package/lib/index.js +11 -0
  138. package/lib/index.js.map +1 -1
  139. package/lib/plugin.d.ts +53 -18
  140. package/lib/plugin.d.ts.map +1 -1
  141. package/lib/plugin.js +301 -31
  142. package/lib/plugin.js.map +1 -1
  143. package/lib/types.d.ts +248 -9
  144. package/lib/types.d.ts.map +1 -1
  145. package/lib/utils.d.ts.map +1 -1
  146. package/lib/utils.js +38 -12
  147. package/lib/utils.js.map +1 -1
  148. package/package.json +4 -4
  149. package/src/adapter.ts +206 -2
  150. package/src/ai/agent.ts +772 -0
  151. package/src/ai/context-manager.ts +440 -0
  152. package/src/ai/conversation-memory.ts +774 -0
  153. package/src/ai/follow-up.ts +357 -0
  154. package/src/ai/index.ts +128 -0
  155. package/src/ai/init.ts +502 -0
  156. package/src/ai/output.ts +261 -0
  157. package/src/ai/providers/anthropic.ts +375 -0
  158. package/src/ai/providers/base.ts +173 -0
  159. package/src/ai/providers/index.ts +13 -0
  160. package/src/ai/providers/ollama.ts +292 -0
  161. package/src/ai/providers/openai.ts +167 -0
  162. package/src/ai/rate-limiter.ts +129 -0
  163. package/src/ai/service.ts +319 -0
  164. package/src/ai/session.ts +544 -0
  165. package/src/ai/tone-detector.ts +89 -0
  166. package/src/ai/tools.ts +218 -0
  167. package/src/ai/types.ts +296 -0
  168. package/src/ai/user-profile.ts +181 -0
  169. package/src/ai/zhin-agent.ts +845 -0
  170. package/src/built/adapter-process.ts +99 -0
  171. package/src/built/ai-trigger.ts +259 -0
  172. package/src/built/command.ts +75 -69
  173. package/src/built/component.ts +94 -76
  174. package/src/built/config.ts +238 -128
  175. package/src/built/cron.ts +117 -101
  176. package/src/built/database.ts +128 -33
  177. package/src/built/dispatcher.ts +332 -0
  178. package/src/built/permission.ts +146 -54
  179. package/src/built/skill.ts +280 -0
  180. package/src/built/tool.ts +928 -0
  181. package/src/feature.ts +113 -0
  182. package/src/index.ts +11 -0
  183. package/src/plugin.ts +359 -69
  184. package/src/types.ts +306 -11
  185. package/src/utils.ts +37 -13
  186. package/tests/adapter.test.ts +153 -1
  187. package/tests/ai/agent.test.ts +614 -0
  188. package/tests/ai/ai-trigger.test.ts +368 -0
  189. package/tests/ai/context-manager.test.ts +413 -0
  190. package/tests/ai/conversation-memory.test.ts +128 -0
  191. package/tests/ai/follow-up.test.ts +175 -0
  192. package/tests/ai/integration.test.ts +584 -0
  193. package/tests/ai/output.test.ts +128 -0
  194. package/tests/ai/providers.integration.test.ts +227 -0
  195. package/tests/ai/rate-limiter.test.ts +108 -0
  196. package/tests/ai/session.test.ts +375 -0
  197. package/tests/ai/setup.ts +308 -0
  198. package/tests/ai/tone-detector.test.ts +80 -0
  199. package/tests/ai/tool.test.ts +800 -0
  200. package/tests/ai/tools-builtin.test.ts +346 -0
  201. package/tests/ai/user-profile.test.ts +73 -0
  202. package/tests/ai/zhin-agent.test.ts +177 -0
  203. package/tests/component-new.test.ts +17 -6
  204. package/tests/config.test.ts +46 -0
  205. package/tests/cron.test.ts +94 -5
  206. package/tests/dispatcher.test.ts +146 -0
  207. package/tests/feature.test.ts +145 -0
  208. package/tests/features-builtin.test.ts +191 -0
  209. package/tests/plugin.test.ts +88 -14
  210. package/tests/skill-feature.test.ts +179 -0
  211. package/tests/tool-feature.test.ts +254 -0
package/src/built/cron.ts CHANGED
@@ -1,9 +1,10 @@
1
1
  /**
2
- * Cron Context
3
- * 管理所有插件注册的定时任务
2
+ * CronFeature
3
+ * 管理所有插件注册的定时任务,继承自 Feature 抽象类
4
4
  */
5
+ import { Feature, FeatureJSON } from "../feature.js";
5
6
  import { Cron } from "../cron.js";
6
- import { Context, Plugin, getPlugin } from "../plugin.js";
7
+ import { Plugin, getPlugin } from "../plugin.js";
7
8
 
8
9
  /**
9
10
  * CronContext 扩展方法类型
@@ -18,123 +19,138 @@ declare module "../plugin.js" {
18
19
  namespace Plugin {
19
20
  interface Extensions extends CronContextExtensions {}
20
21
  interface Contexts {
21
- cron: CronService;
22
+ cron: CronFeature;
22
23
  }
23
24
  }
24
25
  }
25
26
 
26
27
  /**
27
- * 定时任务服务数据
28
+ * 定时任务服务 Feature
28
29
  */
29
- export interface CronService {
30
- /** 任务列表 */
31
- readonly items: Cron[];
30
+ export class CronFeature extends Feature<Cron> {
31
+ readonly name = 'cron' as const;
32
+ readonly icon = 'Clock';
33
+ readonly desc = '定时任务';
34
+
32
35
  /** 按 ID/表达式 索引 */
33
- readonly byName: Map<string, Cron>;
34
- /** 添加任务 */
35
- add(cron: Cron, pluginName: string): () => void;
36
- /** 移除任务 */
37
- remove(cron: Cron): boolean;
38
- /** 按名称获取 */
39
- get(id: string): Cron | undefined;
40
- /** 停止所有任务 */
41
- stopAll(): void;
42
- /** 启动所有任务 */
43
- startAll(): void;
44
- /** 获取状态 */
36
+ readonly byName = new Map<string, Cron>();
37
+
38
+ /**
39
+ * 添加定时任务,自动启动
40
+ */
41
+ add(cron: Cron, pluginName: string): () => void {
42
+ this.byName.set(cron.id || cron.cronExpression, cron);
43
+ // 自动启动
44
+ if (!cron.running) {
45
+ cron.run();
46
+ }
47
+ return super.add(cron, pluginName);
48
+ }
49
+
50
+ /**
51
+ * 移除定时任务,自动停止
52
+ */
53
+ remove(cron: Cron): boolean {
54
+ if (cron.running) {
55
+ cron.stop();
56
+ }
57
+ this.byName.delete(cron.id || cron.cronExpression);
58
+ return super.remove(cron);
59
+ }
60
+
61
+ /**
62
+ * 按 ID/表达式 获取
63
+ */
64
+ get(id: string): Cron | undefined {
65
+ return this.byName.get(id);
66
+ }
67
+
68
+ /**
69
+ * 停止所有任务
70
+ */
71
+ stopAll(): void {
72
+ for (const cron of this.items) {
73
+ if (cron.running) {
74
+ cron.stop();
75
+ }
76
+ }
77
+ }
78
+
79
+ /**
80
+ * 启动所有任务
81
+ */
82
+ startAll(): void {
83
+ for (const cron of this.items) {
84
+ if (!cron.running && !cron.disposed) {
85
+ cron.run();
86
+ }
87
+ }
88
+ }
89
+
90
+ /**
91
+ * 获取所有任务状态
92
+ */
45
93
  getStatus(): Array<{
46
94
  expression: string;
47
95
  running: boolean;
48
96
  nextExecution: Date | null;
49
97
  plugin: string;
50
- }>;
51
- }
52
-
53
- /**
54
- * 创建定时任务 Context
55
- */
56
- export function createCronService(): Context<'cron', CronContextExtensions> {
57
- const items: Cron[] = [];
58
- const byName = new Map<string, Cron>();
59
- const pluginMap = new Map<Cron, string>();
60
-
61
- const value: CronService = {
62
- items,
63
- byName,
64
-
65
- add(cron, pluginName) {
66
- items.push(cron);
67
- byName.set(cron.id || cron.cronExpression, cron);
68
- pluginMap.set(cron, pluginName);
69
- // 自动启动
70
- if (!cron.running) {
71
- cron.run();
72
- }
73
- return () => value.remove(cron);
74
- },
75
-
76
- remove(cron) {
77
- const index = items.indexOf(cron);
78
- if (index !== -1) {
79
- // 自动停止
80
- if (cron.running) {
81
- cron.stop();
98
+ }> {
99
+ return this.items.map(cron => {
100
+ // 从 pluginItems 中找到对应的插件名
101
+ let pluginName = 'unknown';
102
+ for (const [name, items] of this.pluginItems) {
103
+ if (items.includes(cron)) {
104
+ pluginName = name;
105
+ break;
82
106
  }
83
- items.splice(index, 1);
84
- byName.delete(cron.id || cron.cronExpression);
85
- pluginMap.delete(cron);
86
- return true;
87
107
  }
88
- return false;
89
- },
90
-
91
- get(id) {
92
- return byName.get(id);
93
- },
94
-
95
- stopAll() {
96
- for (const cron of items) {
97
- if (cron.running) {
98
- cron.stop();
99
- }
100
- }
101
- },
102
-
103
- startAll() {
104
- for (const cron of items) {
105
- if (!cron.running && !cron.disposed) {
106
- cron.run();
107
- }
108
- }
109
- },
110
-
111
- getStatus() {
112
- return items.map(cron => ({
108
+ return {
113
109
  expression: cron.cronExpression,
114
110
  running: cron.running,
115
111
  nextExecution: cron.running ? cron.getNextExecutionTime() : null,
116
- plugin: pluginMap.get(cron) || 'unknown',
117
- }));
118
- }
119
- };
120
-
121
- return {
122
- name: 'cron',
123
- description: '定时任务服务',
124
- value,
125
-
126
- dispose() {
127
- value.stopAll();
128
- },
129
-
130
- extensions: {
112
+ plugin: pluginName,
113
+ };
114
+ });
115
+ }
116
+
117
+ /**
118
+ * 生命周期: 销毁时停止所有任务
119
+ */
120
+ dispose(): void {
121
+ this.stopAll();
122
+ }
123
+
124
+ /**
125
+ * 序列化为 JSON
126
+ */
127
+ toJSON(pluginName?: string): FeatureJSON {
128
+ const list = pluginName ? this.getByPlugin(pluginName) : this.items;
129
+ return {
130
+ name: this.name,
131
+ icon: this.icon,
132
+ desc: this.desc,
133
+ count: list.length,
134
+ items: list.map(c => ({
135
+ expression: c.cronExpression,
136
+ running: c.running,
137
+ })),
138
+ };
139
+ }
140
+
141
+ /**
142
+ * 提供给 Plugin.prototype 的扩展方法
143
+ */
144
+ get extensions() {
145
+ const feature = this;
146
+ return {
131
147
  addCron(cron: Cron) {
132
148
  const plugin = getPlugin();
133
- const dispose = value.add(cron, plugin.name);
149
+ const dispose = feature.add(cron, plugin.name);
150
+ plugin.recordFeatureContribution(feature.name, cron.id || cron.cronExpression);
134
151
  plugin.onDispose(dispose);
135
152
  return dispose;
136
- }
137
- }
138
- };
153
+ },
154
+ };
155
+ }
139
156
  }
140
-
@@ -1,38 +1,133 @@
1
- import { Registry,Definition,Databases,Database } from "@zhin.js/database";
2
- import { DatabaseConfig,Models } from "../types.js";
3
- import { defineContext,Plugin } from "../plugin.js";
1
+ /**
2
+ * DatabaseFeature
3
+ * 数据库服务,管理数据模型定义,继承自 Feature 抽象类
4
+ */
5
+ import { Registry, Definition, Databases, Database } from "@zhin.js/database";
6
+ import { DatabaseConfig, Models } from "../types.js";
7
+ import { Feature, FeatureJSON } from "../feature.js";
8
+ import { Plugin, getPlugin } from "../plugin.js";
4
9
  import { SystemLogDefinition } from "../models/system-log.js";
5
10
  import { UserDefinition } from "../models/user.js";
6
- declare module "../plugin" {
7
- namespace Plugin {
8
- interface Extensions {
9
- defineModel<K extends keyof Models>(name: K, definition: Definition<Models[K]>): void;
10
- }
11
- interface Contexts {
12
- database: Database<any,Models,any>;
13
- }
11
+
12
+ /**
13
+ * 模型定义记录
14
+ */
15
+ export interface ModelRecord {
16
+ name: string;
17
+ definition: Definition<any>;
18
+ }
19
+
20
+ declare module "../plugin.js" {
21
+ namespace Plugin {
22
+ interface Extensions {
23
+ defineModel<K extends keyof Models>(name: K, definition: Definition<Models[K]>): void;
24
+ }
25
+ interface Contexts {
26
+ database: DatabaseFeature;
14
27
  }
28
+ }
15
29
  }
16
- export function defineDatabaseService<K extends keyof Databases>(config: DatabaseConfig<K>) {
17
- const db = Registry.create<Models,K>(config.dialect, config,{
18
- SystemLog: SystemLogDefinition,
19
- User: UserDefinition,
30
+
31
+ export class DatabaseFeature extends Feature<ModelRecord> {
32
+ readonly name = 'database' as const;
33
+ readonly icon = 'Database';
34
+ readonly desc = '数据模型';
35
+
36
+ /** 内部数据库实例 */
37
+ readonly db: Database<any, Models, any>;
38
+
39
+ /** 按模型名索引 */
40
+ readonly byName = new Map<string, ModelRecord>();
41
+
42
+ constructor(config: DatabaseConfig) {
43
+ super();
44
+ this.db = Registry.create<Models, keyof Databases>(config.dialect, config, {
45
+ SystemLog: SystemLogDefinition,
46
+ User: UserDefinition,
20
47
  });
21
- return defineContext({
22
- name: 'database',
23
- description: '数据库服务',
24
- mounted: async () => {
25
- await db.start();
26
- return db;
27
- },
28
- dispose: async () => {
29
- await db.stop();
30
- },
31
- extensions: {
32
- defineModel<K extends keyof Models>(this:Plugin,name: K, definition: Definition<Models[K]>) {
33
- db.define(name, definition);
34
- this.logger.debug(`Model "${String(name)}" defined by plugin "${this.name}"`);
35
- }
36
- },
37
- });
38
- }
48
+ }
49
+
50
+ // ====================================================================
51
+ // 向后兼容代理:旧代码 inject('database').xxx 可直接使用
52
+ // ====================================================================
53
+
54
+ get models() {
55
+ return this.db.models;
56
+ }
57
+
58
+ define<K extends keyof Models>(name: K, definition: Definition<Models[K]>) {
59
+ return this.db.define(name, definition);
60
+ }
61
+
62
+ start() {
63
+ return this.db.start();
64
+ }
65
+
66
+ stop() {
67
+ return this.db.stop();
68
+ }
69
+
70
+ /**
71
+ * 添加模型定义
72
+ */
73
+ add(record: ModelRecord, pluginName: string): () => void {
74
+ this.db.define(record.name as keyof Models, record.definition);
75
+ this.byName.set(record.name, record);
76
+ return super.add(record, pluginName);
77
+ }
78
+
79
+ /**
80
+ * 移除模型定义
81
+ */
82
+ remove(record: ModelRecord): boolean {
83
+ this.byName.delete(record.name);
84
+ return super.remove(record);
85
+ }
86
+
87
+ /**
88
+ * 生命周期: 启动数据库
89
+ */
90
+ async mounted(plugin: Plugin): Promise<void> {
91
+ plugin.logger.info('Database service started');
92
+ await this.db.start();
93
+ }
94
+
95
+ /**
96
+ * 生命周期: 停止数据库
97
+ */
98
+ async dispose(): Promise<void> {
99
+ await this.db.stop();
100
+ }
101
+
102
+ /**
103
+ * 序列化为 JSON
104
+ */
105
+ toJSON(pluginName?: string): FeatureJSON {
106
+ const list = pluginName ? this.getByPlugin(pluginName) : this.items;
107
+ return {
108
+ name: this.name,
109
+ icon: this.icon,
110
+ desc: this.desc,
111
+ count: list.length,
112
+ items: list.map(r => ({
113
+ name: r.name,
114
+ })),
115
+ };
116
+ }
117
+
118
+ /**
119
+ * 提供给 Plugin.prototype 的扩展方法
120
+ */
121
+ get extensions() {
122
+ const feature = this;
123
+ return {
124
+ defineModel<K extends keyof Models>(name: K, definition: Definition<Models[K]>) {
125
+ const plugin = getPlugin();
126
+ const record: ModelRecord = { name: name as string, definition };
127
+ const dispose = feature.add(record, plugin.name);
128
+ plugin.recordFeatureContribution(feature.name, name as string);
129
+ plugin.onDispose(dispose);
130
+ },
131
+ };
132
+ }
133
+ }