@aalis/core 0.1.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.
Files changed (217) hide show
  1. package/README.md +21 -0
  2. package/dist/app.d.ts +166 -0
  3. package/dist/app.d.ts.map +1 -0
  4. package/dist/app.js +348 -0
  5. package/dist/app.js.map +1 -0
  6. package/dist/config.d.ts +174 -0
  7. package/dist/config.d.ts.map +1 -0
  8. package/dist/config.js +377 -0
  9. package/dist/config.js.map +1 -0
  10. package/dist/constants.d.ts +31 -0
  11. package/dist/constants.d.ts.map +1 -0
  12. package/dist/constants.js +36 -0
  13. package/dist/constants.js.map +1 -0
  14. package/dist/context.d.ts +328 -0
  15. package/dist/context.d.ts.map +1 -0
  16. package/dist/context.js +521 -0
  17. package/dist/context.js.map +1 -0
  18. package/dist/disposable-chain.d.ts +31 -0
  19. package/dist/disposable-chain.d.ts.map +1 -0
  20. package/dist/disposable-chain.js +66 -0
  21. package/dist/disposable-chain.js.map +1 -0
  22. package/dist/events.d.ts +64 -0
  23. package/dist/events.d.ts.map +1 -0
  24. package/dist/events.js +145 -0
  25. package/dist/events.js.map +1 -0
  26. package/dist/hooks.d.ts +49 -0
  27. package/dist/hooks.d.ts.map +1 -0
  28. package/dist/hooks.js +102 -0
  29. package/dist/hooks.js.map +1 -0
  30. package/dist/i18n.d.ts +6 -0
  31. package/dist/i18n.d.ts.map +1 -0
  32. package/dist/i18n.js +26 -0
  33. package/dist/i18n.js.map +1 -0
  34. package/dist/identity.d.ts +26 -0
  35. package/dist/identity.d.ts.map +1 -0
  36. package/dist/identity.js +36 -0
  37. package/dist/identity.js.map +1 -0
  38. package/dist/index.d.ts +17 -0
  39. package/dist/index.d.ts.map +1 -0
  40. package/dist/index.js +29 -0
  41. package/dist/index.js.map +1 -0
  42. package/dist/init.d.ts +20 -0
  43. package/dist/init.d.ts.map +1 -0
  44. package/dist/init.js +455 -0
  45. package/dist/init.js.map +1 -0
  46. package/dist/llm-router.d.ts.map +1 -0
  47. package/dist/llm-router.js +123 -0
  48. package/dist/llm-router.js.map +1 -0
  49. package/dist/logger.d.ts +76 -0
  50. package/dist/logger.d.ts.map +1 -0
  51. package/dist/logger.js +187 -0
  52. package/dist/logger.js.map +1 -0
  53. package/dist/marketplace-bootstrap.d.ts +54 -0
  54. package/dist/marketplace-bootstrap.d.ts.map +1 -0
  55. package/dist/marketplace-bootstrap.js +132 -0
  56. package/dist/marketplace-bootstrap.js.map +1 -0
  57. package/dist/mixin-registry.d.ts +34 -0
  58. package/dist/mixin-registry.d.ts.map +1 -0
  59. package/dist/mixin-registry.js +60 -0
  60. package/dist/mixin-registry.js.map +1 -0
  61. package/dist/model-ref.d.ts +22 -0
  62. package/dist/model-ref.d.ts.map +1 -0
  63. package/dist/model-ref.js +46 -0
  64. package/dist/model-ref.js.map +1 -0
  65. package/dist/pending-buffer.d.ts +46 -0
  66. package/dist/pending-buffer.d.ts.map +1 -0
  67. package/dist/pending-buffer.js +131 -0
  68. package/dist/pending-buffer.js.map +1 -0
  69. package/dist/platform-registry.d.ts +40 -0
  70. package/dist/platform-registry.d.ts.map +1 -0
  71. package/dist/platform-registry.js +64 -0
  72. package/dist/platform-registry.js.map +1 -0
  73. package/dist/plugin-activation.d.ts +43 -0
  74. package/dist/plugin-activation.d.ts.map +1 -0
  75. package/dist/plugin-activation.js +172 -0
  76. package/dist/plugin-activation.js.map +1 -0
  77. package/dist/plugin-topology.d.ts +40 -0
  78. package/dist/plugin-topology.d.ts.map +1 -0
  79. package/dist/plugin-topology.js +126 -0
  80. package/dist/plugin-topology.js.map +1 -0
  81. package/dist/plugin.d.ts +184 -0
  82. package/dist/plugin.d.ts.map +1 -0
  83. package/dist/plugin.js +549 -0
  84. package/dist/plugin.js.map +1 -0
  85. package/dist/providers.d.ts +85 -0
  86. package/dist/providers.d.ts.map +1 -0
  87. package/dist/providers.js +2 -0
  88. package/dist/providers.js.map +1 -0
  89. package/dist/semver-mini.d.ts +20 -0
  90. package/dist/semver-mini.d.ts.map +1 -0
  91. package/dist/semver-mini.js +94 -0
  92. package/dist/semver-mini.js.map +1 -0
  93. package/dist/service-helpers.d.ts +34 -0
  94. package/dist/service-helpers.d.ts.map +1 -0
  95. package/dist/service-helpers.js +68 -0
  96. package/dist/service-helpers.js.map +1 -0
  97. package/dist/service.d.ts +145 -0
  98. package/dist/service.d.ts.map +1 -0
  99. package/dist/service.js +279 -0
  100. package/dist/service.js.map +1 -0
  101. package/dist/types/agent.d.ts +51 -0
  102. package/dist/types/agent.d.ts.map +1 -0
  103. package/dist/types/agent.js +3 -0
  104. package/dist/types/agent.js.map +1 -0
  105. package/dist/types/app.d.ts +74 -0
  106. package/dist/types/app.d.ts.map +1 -0
  107. package/dist/types/app.js +3 -0
  108. package/dist/types/app.js.map +1 -0
  109. package/dist/types/archive.d.ts +59 -0
  110. package/dist/types/archive.d.ts.map +1 -0
  111. package/dist/types/archive.js +16 -0
  112. package/dist/types/archive.js.map +1 -0
  113. package/dist/types/authority.d.ts +63 -0
  114. package/dist/types/authority.d.ts.map +1 -0
  115. package/dist/types/authority.js +3 -0
  116. package/dist/types/authority.js.map +1 -0
  117. package/dist/types/capabilities.d.ts +53 -0
  118. package/dist/types/capabilities.d.ts.map +1 -0
  119. package/dist/types/capabilities.js +87 -0
  120. package/dist/types/capabilities.js.map +1 -0
  121. package/dist/types/cli.d.ts +14 -0
  122. package/dist/types/cli.d.ts.map +1 -0
  123. package/dist/types/cli.js +3 -0
  124. package/dist/types/cli.js.map +1 -0
  125. package/dist/types/commands.d.ts +98 -0
  126. package/dist/types/commands.d.ts.map +1 -0
  127. package/dist/types/commands.js +3 -0
  128. package/dist/types/commands.js.map +1 -0
  129. package/dist/types/core.d.ts +117 -0
  130. package/dist/types/core.d.ts.map +1 -0
  131. package/dist/types/core.js +6 -0
  132. package/dist/types/core.js.map +1 -0
  133. package/dist/types/disposable-service.d.ts +31 -0
  134. package/dist/types/disposable-service.d.ts.map +1 -0
  135. package/dist/types/disposable-service.js +3 -0
  136. package/dist/types/disposable-service.js.map +1 -0
  137. package/dist/types/embedding.d.ts +7 -0
  138. package/dist/types/embedding.d.ts.map +1 -0
  139. package/dist/types/embedding.js +3 -0
  140. package/dist/types/embedding.js.map +1 -0
  141. package/dist/types/flow-control.d.ts +51 -0
  142. package/dist/types/flow-control.d.ts.map +1 -0
  143. package/dist/types/flow-control.js +12 -0
  144. package/dist/types/flow-control.js.map +1 -0
  145. package/dist/types/gateway.d.ts +24 -0
  146. package/dist/types/gateway.d.ts.map +1 -0
  147. package/dist/types/gateway.js +15 -0
  148. package/dist/types/gateway.js.map +1 -0
  149. package/dist/types/hooks.d.ts +3 -0
  150. package/dist/types/hooks.d.ts.map +1 -0
  151. package/dist/types/hooks.js +18 -0
  152. package/dist/types/hooks.js.map +1 -0
  153. package/dist/types/image-recognition.d.ts +123 -0
  154. package/dist/types/image-recognition.d.ts.map +1 -0
  155. package/dist/types/image-recognition.js +31 -0
  156. package/dist/types/image-recognition.js.map +1 -0
  157. package/dist/types/index.d.ts +8 -0
  158. package/dist/types/index.d.ts.map +1 -0
  159. package/dist/types/index.js +17 -0
  160. package/dist/types/index.js.map +1 -0
  161. package/dist/types/llm.d.ts +146 -0
  162. package/dist/types/llm.d.ts.map +1 -0
  163. package/dist/types/llm.js +27 -0
  164. package/dist/types/llm.js.map +1 -0
  165. package/dist/types/memory.d.ts +62 -0
  166. package/dist/types/memory.d.ts.map +1 -0
  167. package/dist/types/memory.js +22 -0
  168. package/dist/types/memory.js.map +1 -0
  169. package/dist/types/persona.d.ts +45 -0
  170. package/dist/types/persona.d.ts.map +1 -0
  171. package/dist/types/persona.js +3 -0
  172. package/dist/types/persona.js.map +1 -0
  173. package/dist/types/platform.d.ts +126 -0
  174. package/dist/types/platform.d.ts.map +1 -0
  175. package/dist/types/platform.js +5 -0
  176. package/dist/types/platform.js.map +1 -0
  177. package/dist/types/plugin.d.ts +84 -0
  178. package/dist/types/plugin.d.ts.map +1 -0
  179. package/dist/types/plugin.js +24 -0
  180. package/dist/types/plugin.js.map +1 -0
  181. package/dist/types/service.d.ts +43 -0
  182. package/dist/types/service.d.ts.map +1 -0
  183. package/dist/types/service.js +38 -0
  184. package/dist/types/service.js.map +1 -0
  185. package/dist/types/services.d.ts +17 -0
  186. package/dist/types/services.d.ts.map +1 -0
  187. package/dist/types/services.js +41 -0
  188. package/dist/types/services.js.map +1 -0
  189. package/dist/types/session.d.ts +153 -0
  190. package/dist/types/session.d.ts.map +1 -0
  191. package/dist/types/session.js +19 -0
  192. package/dist/types/session.js.map +1 -0
  193. package/dist/types/storage.d.ts +100 -0
  194. package/dist/types/storage.d.ts.map +1 -0
  195. package/dist/types/storage.js +29 -0
  196. package/dist/types/storage.js.map +1 -0
  197. package/dist/types/tools.d.ts +39 -0
  198. package/dist/types/tools.d.ts.map +1 -0
  199. package/dist/types/tools.js +3 -0
  200. package/dist/types/tools.js.map +1 -0
  201. package/dist/types/trigger-policy.d.ts +16 -0
  202. package/dist/types/trigger-policy.d.ts.map +1 -0
  203. package/dist/types/trigger-policy.js +6 -0
  204. package/dist/types/trigger-policy.js.map +1 -0
  205. package/dist/types/vectorstore.d.ts +23 -0
  206. package/dist/types/vectorstore.d.ts.map +1 -0
  207. package/dist/types/vectorstore.js +3 -0
  208. package/dist/types/vectorstore.js.map +1 -0
  209. package/dist/types/web-search.d.ts +88 -0
  210. package/dist/types/web-search.d.ts.map +1 -0
  211. package/dist/types/web-search.js +23 -0
  212. package/dist/types/web-search.js.map +1 -0
  213. package/dist/types/webui.d.ts +137 -0
  214. package/dist/types/webui.d.ts.map +1 -0
  215. package/dist/types/webui.js +3 -0
  216. package/dist/types/webui.js.map +1 -0
  217. package/package.json +22 -0
@@ -0,0 +1,126 @@
1
+ // ============================================================
2
+ // plugin-topology.ts — 插件依赖图工具
3
+ //
4
+ // 从 plugin.ts 拆出的纯依赖图算法:
5
+ // - topoSortByDeps:按"提供者→消费者"方向的 Kahn 拓扑排序
6
+ // - evictDownstreamConsumers:把所有依赖某 provider provided 服务的下游
7
+ // active 插件降级为 pending(用于 updatePluginConfig / bouncePlugin
8
+ // 瞬态:provider 即将被 dispose+重启,下游持有的服务引用即失效)
9
+ //
10
+ // 这些是无状态/弱状态的操作,分出去让 PluginManager 主体只关心生命周期编排。
11
+ // ============================================================
12
+ /**
13
+ * 按"提供者 → 消费者"方向的拓扑排序(Kahn)。
14
+ *
15
+ * 关闭顺序 = 此结果反向;激活顺序 = 此结果正序。
16
+ * 服务名 → 提供者映射只取首个 provides 该服务名的 entry,足以表达依赖图。
17
+ *
18
+ * 仅 `requiredDeps` 参与建图:optional 依赖语义为"如果存在则消费",
19
+ * 由运行时 `service-up`/`service-down` recompute 异步补救(whenService 钩子等),
20
+ * 不应制造排序约束。否则插件之间互相 optional 会产生伪环并退化到声明序。
21
+ *
22
+ * 残留环(仅由 required 形成的真环)按声明序兜底追加。
23
+ */
24
+ export function topoSortByDeps(entries, logger) {
25
+ const providerOf = new Map();
26
+ for (const e of entries) {
27
+ for (const svc of e.module.provides ?? []) {
28
+ if (!providerOf.has(svc))
29
+ providerOf.set(svc, e.instanceId);
30
+ }
31
+ }
32
+ const inDegree = new Map();
33
+ const dependents = new Map();
34
+ const entryById = new Map(entries.map(e => [e.instanceId, e]));
35
+ for (const e of entries) {
36
+ inDegree.set(e.instanceId, 0);
37
+ dependents.set(e.instanceId, new Set());
38
+ }
39
+ for (const e of entries) {
40
+ const seenProviders = new Set();
41
+ for (const dep of e.requiredDeps) {
42
+ const providerId = providerOf.get(dep.service);
43
+ if (!providerId || providerId === e.instanceId)
44
+ continue;
45
+ if (!entryById.has(providerId))
46
+ continue;
47
+ if (seenProviders.has(providerId))
48
+ continue;
49
+ seenProviders.add(providerId);
50
+ dependents.get(providerId).add(e.instanceId);
51
+ inDegree.set(e.instanceId, (inDegree.get(e.instanceId) ?? 0) + 1);
52
+ }
53
+ }
54
+ const result = [];
55
+ const queue = [];
56
+ for (const [id, deg] of inDegree) {
57
+ if (deg === 0)
58
+ queue.push(id);
59
+ }
60
+ while (queue.length) {
61
+ const id = queue.shift();
62
+ result.push(entryById.get(id));
63
+ for (const dep of dependents.get(id) ?? []) {
64
+ inDegree.set(dep, (inDegree.get(dep) ?? 0) - 1);
65
+ if (inDegree.get(dep) === 0)
66
+ queue.push(dep);
67
+ }
68
+ }
69
+ if (result.length < entries.length) {
70
+ const seen = new Set(result.map(e => e.instanceId));
71
+ for (const e of entries) {
72
+ if (!seen.has(e.instanceId))
73
+ result.push(e);
74
+ }
75
+ logger.warn(`topoSortByDeps: 检测到 required 依赖环,残留 ${entries.length - seen.size} 个按声明序追加`);
76
+ }
77
+ return result;
78
+ }
79
+ /**
80
+ * 把下游消费者降级为 pending —— 仅对显式声明 `requiresBounceOnDepChange: true`
81
+ * 的插件生效。
82
+ *
83
+ * 历史背景:早期 core 默认对所有 active 下游做级联 bounce,前提是所有插件都会
84
+ * 在 apply 时把 `ctx.getService(...)` 的结果缓存到长寿命对象里(class field /
85
+ * 闭包),导致 provider 一旦 dispose+重启,下游缓存的裸引用立刻失效。
86
+ *
87
+ * 当前的契约改为:"插件应在每次访问时通过 `ctx.getService(...)` 惰性查询",
88
+ * 这样 provider 切换天然跟随,无需级联 bounce。绝大多数 first-party 插件已经
89
+ * 满足该契约,因此默认行为是**不**级联 dispose 下游。
90
+ *
91
+ * `requiresBounceOnDepChange: true` 是给少数无法响应式处理状态的插件
92
+ * (或迁移成本高的第三方插件)的逃生舱。
93
+ *
94
+ * 同步执行(不 await),caller 紧接着会 await softReload 完成全部重激活。
95
+ */
96
+ export function evictDownstreamConsumers(args) {
97
+ const { provider, plugins, rootCtx, logger } = args;
98
+ const provided = provider.module.provides ?? [];
99
+ if (provided.length === 0)
100
+ return;
101
+ const providedSet = new Set(provided);
102
+ for (const other of plugins.values()) {
103
+ if (other === provider || other.state !== 'active')
104
+ continue;
105
+ if (!other.module.requiresBounceOnDepChange)
106
+ continue;
107
+ const allDeps = [...other.requiredDeps, ...other.optionalDeps];
108
+ if (!allDeps.some(d => providedSet.has(d.service)))
109
+ continue;
110
+ if (other.context) {
111
+ try {
112
+ other.context.dispose();
113
+ }
114
+ catch (err) {
115
+ logger.error(`下游消费者 "${other.instanceId}" dispose 抛错: ${err instanceof Error ? err.message : String(err)}`);
116
+ }
117
+ other.context = undefined;
118
+ }
119
+ other.state = 'pending';
120
+ logger.info(`级联 bounce 下游消费者 "${other.instanceId}"(requiresBounceOnDepChange=true,依赖 provider "${provider.instanceId}")`);
121
+ rootCtx.emit('plugin:unloaded', other.instanceId).catch(err => {
122
+ logger.warn(`emit plugin:unloaded 失败 (${other.instanceId}): ${err}`);
123
+ });
124
+ }
125
+ }
126
+ //# sourceMappingURL=plugin-topology.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin-topology.js","sourceRoot":"","sources":["../src/plugin-topology.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,184 @@
1
+ import type { Context } from './context.js';
2
+ import type { Logger } from './logger.js';
3
+ import type { PluginStatusEntry } from './types/index.js';
4
+ import { type PluginEntry, type PluginModule, type PluginState, parseInstanceId, type RecomputeReason } from './types/plugin.js';
5
+ export type { PluginEntry, PluginModule, PluginState };
6
+ export { parseInstanceId };
7
+ /**
8
+ * 插件管理器
9
+ *
10
+ * 负责:
11
+ * - 注册/加载/卸载插件
12
+ * - 依赖追踪 (required + optional, 支持 capability 匹配)
13
+ * - 当所需服务就绪时自动激活插件
14
+ * - 当所需服务移除时自动停用插件
15
+ * - 插件启用/禁用控制
16
+ */
17
+ export declare class PluginManager {
18
+ private plugins;
19
+ private rootCtx;
20
+ private logger;
21
+ /** recompute 单飞标志:true 表示一次 recompute(含排队补跑)正在进行 */
22
+ private reloading;
23
+ /**
24
+ * 手动 dispose 段计数器:disablePlugin / unload / bouncePlugin 在「dispose 旧
25
+ * ctx → 改 entry.state」这段不可分割的状态变更期间 +1。期间 dispose 触发的
26
+ * service:unregistered 反应式 recompute 会被**排队**(而非立即跑——那会看到
27
+ * 半成品状态,比如把正在禁用的插件重新激活),由这些方法收尾的 softReload 统一消化。
28
+ *
29
+ * 用计数器而非布尔:dispose hook 内可能同步级联调用 disablePlugin/unload(级联
30
+ * 禁用),嵌套时内层的 finally 若复位布尔会过早解除外层的挂起态——计数器确保
31
+ * 只有最外层退出(归零)才解除(审计 HIGH #3)。
32
+ */
33
+ private suspendDepth;
34
+ private get suspended();
35
+ /**
36
+ * 被推迟的 recompute 请求(修 lost wakeup:在飞期间到达的请求不再被丢弃)。
37
+ * 多个请求合并为一——除 shutdown 保留原 reason 外统一退化为
38
+ * plugin-state-changed(service-up/down 的特殊语义本就只在第一轮生效)。
39
+ */
40
+ private queuedReason;
41
+ /**
42
+ * 全局关机标志。app.stop() 在 dispose 前置位,所有反应式级联(service:registered/
43
+ * unregistered → checkPending/Active)都会因此跳过——避免「正在关机还去 bounce
44
+ * 一个永远不会被重新激活的插件」这种无意义噪声,也避免下游插件 dispose 中
45
+ * 试图 register 命令 / 监听服务等动作触发误重入。
46
+ */
47
+ private shuttingDown;
48
+ /** 是否正在关机——供插件 dispose hook 短路用 */
49
+ isShuttingDown(): boolean;
50
+ /**
51
+ * 必需服务列表: softReload 完成后若缺失会自动恢复。
52
+ * 由 App 设置。
53
+ */
54
+ requiredServices: readonly string[];
55
+ /**
56
+ * 必需服务恢复政策(由 App 从 AppOptions.serviceRecovery 设置)。
57
+ * autoEnableDisabled=false 时恢复路径不会自动启用被用户禁用的提供者插件。
58
+ */
59
+ recoveryPolicy: {
60
+ autoEnableDisabled: boolean;
61
+ };
62
+ constructor(rootCtx: Context, logger: Logger);
63
+ /**
64
+ * 注册并尝试加载一个插件
65
+ *
66
+ * @param module 插件模块
67
+ * @param config 插件配置
68
+ * @param instanceId 实例 ID(多实例时为 `name:suffix`,留空则使用 module.name)
69
+ */
70
+ register(module: PluginModule, config?: Record<string, unknown>, instanceId?: string): Promise<void>;
71
+ /**
72
+ * 卸载一个插件
73
+ */
74
+ unload(name: string): Promise<void>;
75
+ /**
76
+ * 启用一个已禁用的插件
77
+ */
78
+ enablePlugin(name: string): Promise<boolean>;
79
+ /**
80
+ * 禁用一个活跃的插件(core 插件不能禁用)
81
+ */
82
+ disablePlugin(name: string): Promise<boolean>;
83
+ /**
84
+ * 获取所有已注册插件的状态
85
+ *
86
+ * 返回类型即 PluginManagerService 接口的 PluginStatusEntry(types/app.ts),
87
+ * 编译期保证两边不漂移。
88
+ */
89
+ getStatus(): PluginStatusEntry[];
90
+ /**
91
+ * 获取单个插件
92
+ */
93
+ getPlugin(name: string): PluginEntry | undefined;
94
+ /**
95
+ * 更新插件配置(thin alias,转发到 bouncePlugin)。保留独立方法名是为了
96
+ * 让 host 层调用点(WebUI / 配置文件热重载)语义清晰且向后兼容。
97
+ */
98
+ updatePluginConfig(name: string, config: Record<string, unknown>): Promise<boolean>;
99
+ /**
100
+ * 增量重载单个插件(核心入口):
101
+ *
102
+ * 1. 持久化新 config(如有)+ 替换 module(如有)+ dispose 旧 ctx
103
+ * + 转 pending + softReload 重新激活。下游消费者默认不会被级联 bounce,
104
+ * 除非显式声明 `requiresBounceOnDepChange: true`(见 evictDownstreamConsumers)。
105
+ * 2. `error` 态插件会被重置为 pending 重试 apply。
106
+ *
107
+ * 不负责"重新从磁盘 import"——那是宿主层的职责。
108
+ *
109
+ * @returns false 表示找不到 entry 或处于 disabled 态(拒绝 bounce)。
110
+ */
111
+ bouncePlugin(name: string, opts?: {
112
+ config?: Record<string, unknown>;
113
+ module?: PluginModule;
114
+ }): Promise<boolean>;
115
+ /**
116
+ * 在运行时基于 reusable 模块新增一个实例(写入配置 + 触发激活)。
117
+ *
118
+ * @param moduleName 原始模块名(如 `@aalis/plugin-openai`)
119
+ * @param suffix 实例后缀(如 `vision`),将生成 instanceId `moduleName:suffix`
120
+ * @param config 新实例的配置
121
+ * @returns 新实例的 instanceId,失败返回 undefined
122
+ */
123
+ createInstance(moduleName: string, suffix: string, config?: Record<string, unknown>): Promise<string | undefined>;
124
+ /**
125
+ * 移除一个多实例插件(不允许移除主实例)
126
+ */
127
+ removeInstance(instanceId: string): Promise<boolean>;
128
+ /**
129
+ * 全局停机:按依赖拓扑逆序 dispose 所有 active 插件。
130
+ *
131
+ * 顺序原则:「消费者先关,提供者后关」——一个插件若 require/optional 依赖另一个
132
+ * 插件 provides 的服务,则前者 dispose 必须先于后者。这样下游插件的 dispose hook
133
+ * 还能安全地访问其依赖的服务(如把待持久化数据冲到 storage、把订阅从 gateway 摘掉)。
134
+ *
135
+ * 实现是 Kahn 风格 BFS:
136
+ * 1. 把 active 插件构成「依赖图」边:consumer → provider(基于 module.provides)
137
+ * 2. 反复挑出 in-degree==0 的节点(没人依赖它们 = 处于拓扑顶端 = 应当先 dispose)
138
+ * 3. dispose 后从图中移除,刷新 in-degree
139
+ * 4. 若残留环(不应该发生,softReload 期间会警告),按声明顺序 dispose 兜底
140
+ *
141
+ * 此方法预设 `shuttingDown=true`,service:unregistered 不再触发反应式 bounce;
142
+ * 因此本方法是**关机时唯一**的 dispose 编排者,不与级联机制竞争。
143
+ */
144
+ stopAll(): Promise<void>;
145
+ /**
146
+ * 软重载(薄壳):把"插件状态需要重算"统一委托给 recompute()。
147
+ *
148
+ * 历史上 softReload / stopAll / checkActivePlugins / checkPendingPlugins 是四
149
+ * 条独立路径,每条都自己判断"哪些插件该跑、按什么顺序"。逻辑漂移导致 stopAll
150
+ * 之外的三条路径在"同一轮多个插件同时变状态"时无法保证消费者先于提供者关闭,
151
+ * 瞬态会出现 dispose hook 访问已失效服务的情况。现在四条路径共用 recompute()。
152
+ */
153
+ softReload(): Promise<void>;
154
+ /**
155
+ * 重算所有插件的目标态并按依赖拓扑序应用转移。
156
+ *
157
+ * 这是 PluginManager 唯一的状态变更入口(除 ensureServiceProvider 这种显式
158
+ * 启用 disabled 提供者的恢复策略之外)。
159
+ *
160
+ * 算法:
161
+ * 1. 反应式 reason 决定"是否走完整 fixed-point + 是否触发 optional bounce";
162
+ * shutdown 走单向 down 路径,其它走 fixed-point。
163
+ * 2. 每轮先按依赖正序(提供者→消费者)做拓扑排序。
164
+ * 3. Phase A:反向遍历,把"目标不再 active"的 entry 一并 dispose
165
+ * (消费者先关、提供者后关,dispose hook 访问依赖服务安全)。
166
+ * 4. Phase B(非 shutdown):正向遍历,激活"目标 active 且依赖满足"的 pending entry
167
+ * (提供者先起、消费者后起)。
168
+ * 5. 若本轮有变动则继续下一轮,直到稳定或达到 maxRounds。
169
+ * 6. 非 shutdown 时检查必需服务并发出 plugins:changed。
170
+ *
171
+ * Aalis 直接用"服务在不在 + capabilities 命中"
172
+ * 做判断 —— 表达力等价、复杂度更低。
173
+ */
174
+ recompute(reason: RecomputeReason): Promise<void>;
175
+ /** 单次完整重算:fixed-point 状态转移 + (非关机)必需服务恢复与 plugins:changed 通知 */
176
+ private recomputeOnce;
177
+ /**
178
+ * 为外部(App)暴露的「必需服务自动恢复」入口。
179
+ *
180
+ * 实际逻辑在 plugin-activation.ts。PluginManager 仅负责注入 plugins/rootCtx/logger。
181
+ */
182
+ ensureServiceProvider(serviceName: string): Promise<string | undefined>;
183
+ }
184
+ //# sourceMappingURL=plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"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"}