@actiondock/core 2.0.11 → 2.2.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 (258) hide show
  1. package/README.md +61 -30
  2. package/dist/app/app.d.ts +73 -0
  3. package/dist/app/app.js +700 -0
  4. package/dist/app/index.d.ts +2 -0
  5. package/dist/app/index.js +2 -0
  6. package/dist/app/types.d.ts +283 -0
  7. package/dist/app/types.js +1 -0
  8. package/dist/catalog/action-index.d.ts +9 -0
  9. package/dist/catalog/action-index.js +93 -0
  10. package/dist/catalog/action-resolver.d.ts +20 -0
  11. package/dist/catalog/action-resolver.js +95 -0
  12. package/dist/catalog/index.d.ts +5 -0
  13. package/dist/catalog/index.js +5 -0
  14. package/dist/catalog/location-registry.d.ts +15 -0
  15. package/dist/catalog/location-registry.js +138 -0
  16. package/dist/catalog/package-catalog.d.ts +7 -0
  17. package/dist/catalog/package-catalog.js +76 -0
  18. package/dist/catalog/types.d.ts +68 -0
  19. package/dist/catalog/types.js +1 -0
  20. package/dist/doctor/doctor.d.ts +7 -0
  21. package/dist/doctor/doctor.js +613 -0
  22. package/dist/doctor/index.d.ts +2 -0
  23. package/dist/doctor/index.js +2 -0
  24. package/dist/doctor/types.d.ts +23 -0
  25. package/dist/doctor/types.js +1 -0
  26. package/dist/errors.d.ts +122 -0
  27. package/dist/errors.js +123 -0
  28. package/dist/execution/index.d.ts +2 -0
  29. package/dist/execution/index.js +2 -0
  30. package/dist/execution/service.d.ts +79 -0
  31. package/dist/execution/service.js +633 -0
  32. package/dist/execution/types.d.ts +131 -0
  33. package/dist/execution/types.js +1 -0
  34. package/dist/export/index.d.ts +1 -0
  35. package/dist/export/index.js +1 -0
  36. package/dist/export/templates.d.ts +71 -0
  37. package/dist/export/templates.js +621 -0
  38. package/dist/filter/index.d.ts +1 -0
  39. package/dist/filter/index.js +1 -0
  40. package/dist/filter/intent.d.ts +33 -0
  41. package/dist/filter/intent.js +123 -0
  42. package/dist/host/host.d.ts +55 -0
  43. package/dist/host/host.js +740 -0
  44. package/dist/host/index.d.ts +2 -0
  45. package/dist/host/index.js +2 -0
  46. package/dist/host/types.d.ts +81 -0
  47. package/dist/host/types.js +1 -0
  48. package/dist/index.d.ts +21 -0
  49. package/dist/index.js +20 -0
  50. package/dist/ipc/diagnostic.d.ts +65 -0
  51. package/dist/ipc/diagnostic.js +129 -0
  52. package/dist/ipc/host.d.ts +7 -0
  53. package/dist/ipc/host.js +93 -0
  54. package/dist/ipc/index.d.ts +4 -0
  55. package/dist/ipc/index.js +4 -0
  56. package/dist/ipc/target.d.ts +56 -0
  57. package/dist/ipc/target.js +297 -0
  58. package/dist/ipc/types.d.ts +42 -0
  59. package/dist/ipc/types.js +1 -0
  60. package/dist/platform/default.d.ts +32 -0
  61. package/dist/platform/default.js +40 -0
  62. package/dist/platform/index.d.ts +3 -0
  63. package/dist/platform/index.js +3 -0
  64. package/dist/platform/node-fs.d.ts +37 -0
  65. package/dist/platform/node-fs.js +81 -0
  66. package/dist/platform/types.d.ts +104 -0
  67. package/dist/platform/types.js +1 -0
  68. package/dist/profile/client.d.ts +162 -0
  69. package/dist/profile/client.js +467 -0
  70. package/dist/profile/index.d.ts +3 -0
  71. package/dist/profile/index.js +3 -0
  72. package/dist/profile/manager.d.ts +47 -0
  73. package/dist/profile/manager.js +294 -0
  74. package/dist/profile/types.d.ts +61 -0
  75. package/dist/profile/types.js +1 -0
  76. package/dist/project/closure.d.ts +25 -0
  77. package/dist/project/closure.js +68 -0
  78. package/dist/project/digest.d.ts +29 -0
  79. package/dist/project/digest.js +324 -0
  80. package/dist/project/index.d.ts +10 -0
  81. package/dist/project/index.js +10 -0
  82. package/dist/project/init.d.ts +26 -0
  83. package/dist/project/init.js +175 -0
  84. package/dist/project/loader.d.ts +99 -0
  85. package/dist/project/loader.js +484 -0
  86. package/dist/project/lockfile.d.ts +55 -0
  87. package/dist/project/lockfile.js +175 -0
  88. package/dist/project/manifest.d.ts +22 -0
  89. package/dist/project/manifest.js +220 -0
  90. package/dist/project/resolver.d.ts +116 -0
  91. package/dist/project/resolver.js +376 -0
  92. package/dist/project/transactions.d.ts +103 -0
  93. package/dist/project/transactions.js +1203 -0
  94. package/dist/project/types-generator.d.ts +33 -0
  95. package/dist/project/types-generator.js +168 -0
  96. package/dist/project/types.d.ts +107 -0
  97. package/dist/project/types.js +1 -0
  98. package/dist/registry/index.d.ts +5 -0
  99. package/dist/registry/index.js +5 -0
  100. package/dist/registry/lock.d.ts +27 -0
  101. package/dist/registry/lock.js +93 -0
  102. package/dist/registry/registry.d.ts +45 -0
  103. package/dist/registry/registry.js +611 -0
  104. package/dist/registry/resolve.d.ts +62 -0
  105. package/dist/registry/resolve.js +195 -0
  106. package/dist/registry/scan.d.ts +38 -0
  107. package/dist/registry/scan.js +135 -0
  108. package/dist/registry/types.d.ts +117 -0
  109. package/dist/registry/types.js +1 -0
  110. package/dist/runtime/action-collection.d.ts +27 -0
  111. package/dist/runtime/action-collection.js +57 -0
  112. package/dist/runtime/clock.d.ts +19 -0
  113. package/dist/runtime/clock.js +17 -0
  114. package/dist/runtime/context.d.ts +86 -0
  115. package/dist/runtime/context.js +242 -0
  116. package/dist/runtime/env.d.ts +56 -0
  117. package/dist/runtime/env.js +159 -0
  118. package/dist/runtime/events.d.ts +93 -0
  119. package/dist/runtime/events.js +604 -0
  120. package/dist/runtime/execution-manager.d.ts +48 -0
  121. package/dist/runtime/execution-manager.js +66 -0
  122. package/dist/runtime/index.d.ts +10 -0
  123. package/dist/runtime/index.js +10 -0
  124. package/dist/runtime/module-loader.d.ts +34 -0
  125. package/dist/runtime/module-loader.js +16 -0
  126. package/dist/runtime/process.d.ts +9 -0
  127. package/dist/runtime/process.js +146 -0
  128. package/dist/runtime/runner.d.ts +293 -0
  129. package/dist/runtime/runner.js +984 -0
  130. package/dist/runtime/standalone.d.ts +89 -0
  131. package/dist/runtime/standalone.js +536 -0
  132. package/dist/schema/validator.d.ts +28 -0
  133. package/dist/schema/validator.js +116 -0
  134. package/dist/server/body.d.ts +40 -0
  135. package/dist/server/body.js +93 -0
  136. package/dist/server/index.d.ts +5 -0
  137. package/dist/server/index.js +5 -0
  138. package/dist/server/routes/actions.d.ts +5 -0
  139. package/dist/server/routes/actions.js +298 -0
  140. package/dist/server/routes/common.d.ts +47 -0
  141. package/dist/server/routes/common.js +104 -0
  142. package/dist/server/routes/config.d.ts +6 -0
  143. package/dist/server/routes/config.js +173 -0
  144. package/dist/server/routes/doctor.d.ts +5 -0
  145. package/dist/server/routes/doctor.js +63 -0
  146. package/dist/server/routes/health.d.ts +5 -0
  147. package/dist/server/routes/health.js +35 -0
  148. package/dist/server/routes/index.d.ts +9 -0
  149. package/dist/server/routes/index.js +9 -0
  150. package/dist/server/routes/info.d.ts +7 -0
  151. package/dist/server/routes/info.js +158 -0
  152. package/dist/server/routes/playbooks.d.ts +5 -0
  153. package/dist/server/routes/playbooks.js +134 -0
  154. package/dist/server/routes/runs.d.ts +5 -0
  155. package/dist/server/routes/runs.js +343 -0
  156. package/dist/server/routes/state.d.ts +6 -0
  157. package/dist/server/routes/state.js +169 -0
  158. package/dist/server/security.d.ts +44 -0
  159. package/dist/server/security.js +101 -0
  160. package/dist/server/server.d.ts +15 -0
  161. package/dist/server/server.js +355 -0
  162. package/dist/server/types.d.ts +78 -0
  163. package/dist/server/types.js +1 -0
  164. package/dist/storage/data-dir-lock.d.ts +119 -0
  165. package/dist/storage/data-dir-lock.js +1016 -0
  166. package/dist/storage/driver.d.ts +9 -0
  167. package/dist/storage/driver.js +59 -0
  168. package/dist/storage/index.d.ts +64 -0
  169. package/dist/storage/index.js +98 -0
  170. package/dist/storage/lazy.d.ts +8 -0
  171. package/dist/storage/lazy.js +44 -0
  172. package/dist/storage/mask.d.ts +26 -0
  173. package/dist/storage/mask.js +48 -0
  174. package/dist/storage/params.d.ts +13 -0
  175. package/dist/storage/params.js +32 -0
  176. package/dist/storage/sqlite.d.ts +79 -0
  177. package/dist/storage/sqlite.js +689 -0
  178. package/dist/storage/types.d.ts +172 -0
  179. package/dist/storage/types.js +14 -0
  180. package/dist/target/index.d.ts +4 -0
  181. package/dist/target/index.js +4 -0
  182. package/dist/target/local.d.ts +52 -0
  183. package/dist/target/local.js +343 -0
  184. package/dist/target/remote.d.ts +76 -0
  185. package/dist/target/remote.js +839 -0
  186. package/dist/target/target.d.ts +6 -0
  187. package/dist/target/target.js +35 -0
  188. package/dist/target/types.d.ts +246 -0
  189. package/dist/target/types.js +34 -0
  190. package/dist/utils/index.d.ts +49 -0
  191. package/dist/utils/index.js +180 -0
  192. package/dist/version.d.ts +4 -0
  193. package/dist/version.js +4 -0
  194. package/package.json +13 -13
  195. package/src/build/index.ts +0 -1
  196. package/src/build/templates.ts +0 -59
  197. package/src/catalog/action-index.ts +0 -92
  198. package/src/catalog/action-resolver.ts +0 -120
  199. package/src/catalog/index.ts +0 -5
  200. package/src/catalog/location-registry.ts +0 -134
  201. package/src/catalog/package-catalog.ts +0 -87
  202. package/src/catalog/types.ts +0 -75
  203. package/src/doctor/doctor.ts +0 -419
  204. package/src/doctor/index.ts +0 -2
  205. package/src/doctor/types.ts +0 -25
  206. package/src/execution/index.ts +0 -2
  207. package/src/execution/service.ts +0 -322
  208. package/src/execution/types.ts +0 -73
  209. package/src/export/index.ts +0 -1
  210. package/src/export/templates.ts +0 -590
  211. package/src/filter/index.ts +0 -1
  212. package/src/filter/intent.ts +0 -154
  213. package/src/index.ts +0 -16
  214. package/src/profile/client.ts +0 -552
  215. package/src/profile/index.ts +0 -3
  216. package/src/profile/manager.ts +0 -341
  217. package/src/profile/types.ts +0 -71
  218. package/src/project/index.ts +0 -4
  219. package/src/project/init.ts +0 -242
  220. package/src/project/loader.ts +0 -479
  221. package/src/project/manifest.ts +0 -299
  222. package/src/project/types.ts +0 -141
  223. package/src/registry/index.ts +0 -2
  224. package/src/registry/registry.ts +0 -940
  225. package/src/registry/types.ts +0 -127
  226. package/src/runtime/clock.ts +0 -41
  227. package/src/runtime/context.ts +0 -259
  228. package/src/runtime/env.ts +0 -172
  229. package/src/runtime/events.ts +0 -142
  230. package/src/runtime/execution-manager.ts +0 -74
  231. package/src/runtime/index.ts +0 -10
  232. package/src/runtime/module-loader.ts +0 -67
  233. package/src/runtime/process.ts +0 -245
  234. package/src/runtime/runner.ts +0 -527
  235. package/src/runtime/standalone.ts +0 -429
  236. package/src/schema/validator.ts +0 -61
  237. package/src/server/body.ts +0 -112
  238. package/src/server/index.ts +0 -7
  239. package/src/server/routes/actions.ts +0 -262
  240. package/src/server/routes/common.ts +0 -126
  241. package/src/server/routes/config.ts +0 -147
  242. package/src/server/routes/doctor.ts +0 -29
  243. package/src/server/routes/health.ts +0 -40
  244. package/src/server/routes/index.ts +0 -9
  245. package/src/server/routes/info.ts +0 -221
  246. package/src/server/routes/playbooks.ts +0 -109
  247. package/src/server/routes/runs.ts +0 -301
  248. package/src/server/routes/state.ts +0 -133
  249. package/src/server/runtime-registry.ts +0 -115
  250. package/src/server/security.ts +0 -115
  251. package/src/server/server.ts +0 -251
  252. package/src/server/types.ts +0 -57
  253. package/src/storage/driver.ts +0 -126
  254. package/src/storage/index.ts +0 -81
  255. package/src/storage/mask.ts +0 -34
  256. package/src/storage/sqlite.ts +0 -714
  257. package/src/storage/types.ts +0 -139
  258. package/src/utils/index.ts +0 -62
@@ -0,0 +1,700 @@
1
+ import { existsSync, readFileSync } from "node:fs";
2
+ import { join, resolve } from "node:path";
3
+ import { DefaultExecutionService } from "../execution/service.js";
4
+ import { createDefaultPlatform } from "../platform/index.js";
5
+ import { findProjectRoot, loadPlaybooks, loadProjectConfig } from "../project/loader.js";
6
+ import { loadManifest } from "../project/manifest.js";
7
+ import { RuntimeConfig } from "../runtime/context.js";
8
+ import { normalizeActionCollection } from "../runtime/action-collection.js";
9
+ import { createGlobalStorage, createLazyStorage, createStorage } from "../storage/index.js";
10
+ import { isSecretConfigKey, sanitizeConfigDefinitions } from "../storage/mask.js";
11
+ import { decodeStateKey, SqliteRuntimeStorage } from "../storage/sqlite.js";
12
+ /**
13
+ * ActionDock 统一应用默认实现。
14
+ * 封装并管理单个 Action Package 的执行引擎、静态元数据索引、配置与状态存储生命周期。
15
+ */
16
+ export class DefaultActionDockApp {
17
+ packageId;
18
+ packageRoot;
19
+ projectConfig;
20
+ platform;
21
+ storage;
22
+ globalStorage;
23
+ executionService;
24
+ actionsMap;
25
+ options;
26
+ runtimeConfig;
27
+ isClosed = false;
28
+ constructor(options = {}) {
29
+ this.options = options;
30
+ // 1. 确定项目根路径与配置对象
31
+ let packageRoot = options.packageRoot;
32
+ let projectConfig = options.projectConfig;
33
+ if (!packageRoot && !projectConfig) {
34
+ const detected = findProjectRoot();
35
+ if (detected) {
36
+ packageRoot = detected;
37
+ }
38
+ }
39
+ if (!projectConfig && packageRoot) {
40
+ const configPath = join(packageRoot, "actiondock.json");
41
+ if (existsSync(configPath)) {
42
+ try {
43
+ projectConfig = loadProjectConfig(packageRoot);
44
+ }
45
+ catch {
46
+ // 忽略解析失败,使用回退配置
47
+ }
48
+ }
49
+ }
50
+ if (!projectConfig) {
51
+ projectConfig = {
52
+ id: "default",
53
+ name: "default",
54
+ version: "0.1.0",
55
+ };
56
+ }
57
+ this.packageRoot = packageRoot;
58
+ this.projectConfig = projectConfig;
59
+ this.packageId = projectConfig.id;
60
+ // 2. 转换 Action 集合:委托归一化单一入口
61
+ this.actionsMap = normalizeActionCollection(options.actions).actionsMap;
62
+ // 3. 确定平台适配层
63
+ this.platform = options.platform ?? createDefaultPlatform();
64
+ // 4. 确定并初始化存储实例
65
+ if (options.storage) {
66
+ this.storage = options.storage;
67
+ }
68
+ else {
69
+ const storageOpts = {
70
+ projectRoot: this.packageRoot,
71
+ dataDir: options.dataDir,
72
+ customHome: options.customHome,
73
+ inMemory: options.inMemory,
74
+ };
75
+ const storageFactory = this.platform.storage;
76
+ const initStorage = () => {
77
+ if (typeof storageFactory === "function") {
78
+ return storageFactory(this.packageId, storageOpts);
79
+ }
80
+ else if (storageFactory && typeof storageFactory.createStorage === "function") {
81
+ return storageFactory.createStorage(this.packageId, storageOpts);
82
+ }
83
+ else if (storageFactory && typeof storageFactory.create === "function") {
84
+ return storageFactory.create(this.packageId, storageOpts);
85
+ }
86
+ else {
87
+ return createStorage(this.packageId, storageOpts);
88
+ }
89
+ };
90
+ if (options.inMemory) {
91
+ this.storage = initStorage();
92
+ }
93
+ else {
94
+ this.storage = createLazyStorage(initStorage);
95
+ }
96
+ }
97
+ // 5. 确定全局存储实例
98
+ if (options.globalStorage) {
99
+ this.globalStorage = options.globalStorage;
100
+ }
101
+ else if (options.inMemory) {
102
+ this.globalStorage = new SqliteRuntimeStorage({
103
+ dbPath: ":memory:",
104
+ packageId: "__global__",
105
+ });
106
+ }
107
+ else {
108
+ const globalOpts = {
109
+ customHome: options.customHome,
110
+ dataDir: options.dataDir,
111
+ inMemory: options.inMemory,
112
+ };
113
+ const storageFactory = this.platform.storage;
114
+ const initGlobalStorage = () => {
115
+ if (storageFactory && typeof storageFactory.createGlobalStorage === "function") {
116
+ return storageFactory.createGlobalStorage(globalOpts);
117
+ }
118
+ return createGlobalStorage(globalOpts);
119
+ };
120
+ this.globalStorage = createLazyStorage(initGlobalStorage);
121
+ }
122
+ // 6. 初始化唯一执行协调服务
123
+ this.executionService = new DefaultExecutionService({
124
+ packageId: this.packageId,
125
+ hostSessionId: options.hostSessionId,
126
+ storage: this.storage,
127
+ globalStorage: this.globalStorage,
128
+ projectRoot: this.packageRoot,
129
+ projectConfig: this.projectConfig,
130
+ configOverrides: options.configOverrides,
131
+ actions: this.actionsMap,
132
+ process: options.process ?? this.platform.process,
133
+ clock: options.clock ?? this.platform.clock,
134
+ logger: options.logger,
135
+ eventSink: options.eventSink ?? this.platform?.eventSink,
136
+ maxActiveRuns: options.maxActiveRuns,
137
+ maxCallDepth: options.maxCallDepth,
138
+ maxSubRuns: options.maxSubRuns,
139
+ ownerId: options.ownerId,
140
+ actionResolver: options.actionResolver,
141
+ packageContextResolver: options.packageContextResolver,
142
+ customHome: options.customHome,
143
+ platform: this.platform,
144
+ });
145
+ // 7. 初始化配置解析器
146
+ this.runtimeConfig = new RuntimeConfig(this.storage, options.configOverrides, this.projectConfig, this.globalStorage);
147
+ }
148
+ /**
149
+ * 静态读取并聚合当前包的 Action 规范索引。
150
+ * 不产生全量模块导入与执行副作用。
151
+ */
152
+ getStaticActionMap() {
153
+ const map = new Map();
154
+ // 1. 读取声明式清单文件 (actiondock.json)
155
+ if (this.packageRoot) {
156
+ try {
157
+ const manifest = loadManifest(this.packageRoot);
158
+ if (manifest?.actions) {
159
+ for (const [id, item] of Object.entries(manifest.actions)) {
160
+ map.set(id, {
161
+ id,
162
+ packageId: this.packageId,
163
+ description: item.description,
164
+ inputSchema: item.inputSchema,
165
+ outputSchema: item.outputSchema,
166
+ tags: item.tags ? [...item.tags] : [],
167
+ annotations: item.annotations,
168
+ uses: item.uses ? [...item.uses] : [],
169
+ entry: item.entry,
170
+ filePath: item.entry ? resolve(this.packageRoot, item.entry) : undefined,
171
+ });
172
+ }
173
+ }
174
+ }
175
+ catch {
176
+ // 忽略清单缺失或解析异常
177
+ }
178
+ }
179
+ // 2. 读取项目配置文件中声明的 actions (Manifest v2 格式)
180
+ if (this.projectConfig && this.projectConfig.actions) {
181
+ const rawActions = this.projectConfig.actions;
182
+ if (typeof rawActions === "object" && rawActions !== null) {
183
+ for (const [id, item] of Object.entries(rawActions)) {
184
+ const existing = map.get(id);
185
+ map.set(id, {
186
+ id,
187
+ packageId: this.packageId,
188
+ description: item.description ?? existing?.description,
189
+ inputSchema: item.inputSchema ?? existing?.inputSchema,
190
+ outputSchema: item.outputSchema ?? existing?.outputSchema,
191
+ tags: item.tags ?? existing?.tags,
192
+ annotations: item.annotations ?? existing?.annotations,
193
+ uses: item.uses ?? existing?.uses,
194
+ entry: item.entry ?? existing?.entry,
195
+ filePath: item.entry && this.packageRoot
196
+ ? resolve(this.packageRoot, item.entry)
197
+ : existing?.filePath,
198
+ });
199
+ }
200
+ }
201
+ }
202
+ // 3. 读取内存显式注入的 Action 定义
203
+ for (const [id, act] of this.actionsMap) {
204
+ const existing = map.get(id);
205
+ const actObj = act;
206
+ map.set(id, {
207
+ id,
208
+ packageId: this.packageId,
209
+ description: actObj.description ?? existing?.description,
210
+ inputSchema: actObj.inputSchema ?? existing?.inputSchema,
211
+ outputSchema: actObj.outputSchema ?? existing?.outputSchema,
212
+ tags: actObj.tags ? [...actObj.tags] : existing?.tags,
213
+ annotations: actObj.annotations ?? existing?.annotations,
214
+ uses: actObj.uses ? [...actObj.uses] : existing?.uses,
215
+ entry: existing?.entry,
216
+ filePath: existing?.filePath,
217
+ });
218
+ }
219
+ return map;
220
+ }
221
+ /**
222
+ * 静态读取并聚合当前包的 Playbook 规范索引。
223
+ */
224
+ getStaticPlaybookMap() {
225
+ const map = new Map();
226
+ // 1. 扫描磁盘规程文件
227
+ if (this.packageRoot) {
228
+ const playbooksDir = this.projectConfig?.playbooksDir || "playbooks";
229
+ const dirPath = join(this.packageRoot, playbooksDir);
230
+ if (existsSync(dirPath)) {
231
+ try {
232
+ const loaded = loadPlaybooks(this.packageRoot, playbooksDir);
233
+ for (const [id, def] of loaded) {
234
+ map.set(id, {
235
+ id: def.id,
236
+ packageId: this.packageId,
237
+ description: def.description,
238
+ actions: def.actions,
239
+ content: def.content,
240
+ filePath: def.filePath,
241
+ });
242
+ }
243
+ }
244
+ catch {
245
+ // 忽略规程加载异常
246
+ }
247
+ }
248
+ }
249
+ // 2. 读取项目配置文件中的 playbooks
250
+ if (this.projectConfig && this.projectConfig.playbooks) {
251
+ const rawPlaybooks = this.projectConfig.playbooks;
252
+ if (typeof rawPlaybooks === "object" && rawPlaybooks !== null) {
253
+ for (const [id, item] of Object.entries(rawPlaybooks)) {
254
+ const existing = map.get(id);
255
+ let content = item.content ?? existing?.content ?? "";
256
+ let filePath = item.entry && this.packageRoot
257
+ ? resolve(this.packageRoot, item.entry)
258
+ : existing?.filePath;
259
+ if (!content && filePath && existsSync(filePath)) {
260
+ try {
261
+ content = readFileSync(filePath, "utf-8");
262
+ }
263
+ catch {
264
+ // 忽略读取异常
265
+ }
266
+ }
267
+ map.set(id, {
268
+ id,
269
+ packageId: this.packageId,
270
+ description: item.description ?? existing?.description,
271
+ actions: item.actions ?? existing?.actions,
272
+ content,
273
+ filePath,
274
+ });
275
+ }
276
+ }
277
+ }
278
+ return map;
279
+ }
280
+ async info(options) {
281
+ const actionsMap = this.getStaticActionMap();
282
+ const playbooksMap = this.getStaticPlaybookMap();
283
+ const actions = Array.from(actionsMap.keys());
284
+ const playbooks = Array.from(playbooksMap.keys());
285
+ const showPackageRoot = (options?.exposeDebugInfo ?? this.options.exposeDebugInfo) !== false;
286
+ return {
287
+ id: this.packageId,
288
+ name: this.projectConfig.name || this.packageId,
289
+ version: this.projectConfig.version || "0.1.0",
290
+ description: this.projectConfig.description,
291
+ ...(showPackageRoot ? { packageRoot: this.packageRoot } : {}),
292
+ actionsDir: this.projectConfig.actionsDir,
293
+ playbooksDir: this.projectConfig.playbooksDir,
294
+ config: sanitizeConfigDefinitions(this.projectConfig.config),
295
+ actions,
296
+ actionsCount: actions.length,
297
+ playbooks,
298
+ playbooksCount: playbooks.length,
299
+ };
300
+ }
301
+ async listActions(options) {
302
+ const map = this.getStaticActionMap();
303
+ let summaries = Array.from(map.values()).map((spec) => ({
304
+ id: spec.id,
305
+ packageId: this.packageId,
306
+ description: spec.description,
307
+ tags: spec.tags,
308
+ entry: spec.entry,
309
+ annotations: spec.annotations,
310
+ uses: spec.uses,
311
+ inputSchema: spec.inputSchema,
312
+ outputSchema: spec.outputSchema,
313
+ }));
314
+ if (options?.tags && options.tags.length > 0) {
315
+ summaries = summaries.filter((s) => options.tags.every((t) => s.tags?.includes(t)));
316
+ }
317
+ if (options?.query) {
318
+ const q = options.query.toLowerCase();
319
+ summaries = summaries.filter((s) => s.id.toLowerCase().includes(q) ||
320
+ (s.description && s.description.toLowerCase().includes(q)));
321
+ }
322
+ if (options?.prefix) {
323
+ summaries = summaries.filter((s) => s.id.startsWith(options.prefix));
324
+ }
325
+ return summaries;
326
+ }
327
+ async describeAction(id) {
328
+ const map = this.getStaticActionMap();
329
+ let spec = map.get(id);
330
+ if (!spec && id.startsWith(`${this.packageId}/`)) {
331
+ spec = map.get(id.slice(this.packageId.length + 1));
332
+ }
333
+ if (!spec) {
334
+ for (const [key, value] of map) {
335
+ if (key === id || `${this.packageId}/${key}` === id) {
336
+ spec = value;
337
+ break;
338
+ }
339
+ }
340
+ }
341
+ let liveAction = this.actionsMap.get(id) || (spec ? this.actionsMap.get(spec.id) : undefined);
342
+ if (!liveAction && this.executionService.getAction) {
343
+ liveAction =
344
+ this.executionService.getAction(id) ||
345
+ (spec ? this.executionService.getAction(spec.id) : undefined);
346
+ }
347
+ if (!liveAction && this.executionService.runner?.resolveAction) {
348
+ try {
349
+ // 仅在本包范围内解析动态动作:限定 packageId 前缀,避免全局兜底搜索把
350
+ // 其他包的动作误计为本包提供者(host 层据此统计候选导致 AMBIGUOUS_ACTION_REF 误报)。
351
+ const qualifiedId = id.includes("/") ? id : `${this.packageId}/${id}`;
352
+ const resolution = await this.executionService.runner.resolveAction(qualifiedId);
353
+ if (resolution.status === "found") {
354
+ liveAction = resolution.action;
355
+ }
356
+ }
357
+ catch {
358
+ // 忽略动态解析异常
359
+ }
360
+ }
361
+ if (liveAction) {
362
+ const actObj = liveAction;
363
+ return {
364
+ id: actObj.id || id,
365
+ packageId: this.packageId,
366
+ description: actObj.description ?? spec?.description,
367
+ inputSchema: actObj.inputSchema ?? spec?.inputSchema,
368
+ outputSchema: actObj.outputSchema ?? spec?.outputSchema,
369
+ tags: actObj.tags ? [...actObj.tags] : spec?.tags,
370
+ annotations: actObj.annotations ?? spec?.annotations,
371
+ uses: actObj.uses ? [...actObj.uses] : spec?.uses,
372
+ entry: spec?.entry,
373
+ filePath: spec?.filePath,
374
+ };
375
+ }
376
+ if (!spec) {
377
+ throw new Error(`Action '${id}' not found in package '${this.packageId}'`);
378
+ }
379
+ return {
380
+ ...spec,
381
+ packageId: this.packageId,
382
+ };
383
+ }
384
+ async listPlaybooks() {
385
+ const map = this.getStaticPlaybookMap();
386
+ return Array.from(map.values()).map((spec) => ({
387
+ id: spec.id,
388
+ packageId: this.packageId,
389
+ description: spec.description,
390
+ actions: spec.actions,
391
+ filePath: spec.filePath,
392
+ }));
393
+ }
394
+ async describePlaybook(id) {
395
+ const map = this.getStaticPlaybookMap();
396
+ const cleanId = id.replace(/\.md$/, "");
397
+ const spec = map.get(cleanId) || map.get(id);
398
+ if (!spec) {
399
+ throw new Error(`Playbook '${id}' not found in package '${this.packageId}'`);
400
+ }
401
+ return {
402
+ ...spec,
403
+ packageId: this.packageId,
404
+ };
405
+ }
406
+ async runAction(id, input, options) {
407
+ let actionId = id;
408
+ if (actionId.includes("/")) {
409
+ if (actionId.startsWith(`${this.packageId}/`)) {
410
+ actionId = actionId.slice(this.packageId.length + 1);
411
+ }
412
+ else {
413
+ throw new Error(`ActionDockApp only accepts local action short ID '${id}'. Cross-package invocations must be dispatched via Host invoker.`);
414
+ }
415
+ }
416
+ return this.executionService.execute(actionId, input, options);
417
+ }
418
+ async startAction(id, input, options) {
419
+ let actionId = id;
420
+ if (actionId.includes("/")) {
421
+ if (actionId.startsWith(`${this.packageId}/`)) {
422
+ actionId = actionId.slice(this.packageId.length + 1);
423
+ }
424
+ else {
425
+ throw new Error(`ActionDockApp only accepts local action short ID '${id}'. Cross-package invocations must be dispatched via Host invoker.`);
426
+ }
427
+ }
428
+ return this.executionService.start(actionId, input, options);
429
+ }
430
+ async getRun(runId) {
431
+ return this.executionService.get(runId);
432
+ }
433
+ async cancelRun(runId, reason) {
434
+ return this.executionService.cancel(runId, reason);
435
+ }
436
+ events(runId, options) {
437
+ return this.executionService.events(runId, options);
438
+ }
439
+ async listConfig() {
440
+ const declared = this.projectConfig.config || {};
441
+ const stored = this.storage.listConfig();
442
+ const allKeys = Array.from(new Set([...Object.keys(declared), ...Object.keys(stored)]));
443
+ const views = [];
444
+ for (const key of allKeys) {
445
+ const item = await this.getConfig(key);
446
+ if (item) {
447
+ views.push(item);
448
+ }
449
+ }
450
+ return views;
451
+ }
452
+ async getConfig(key) {
453
+ const itemDef = this.projectConfig.config?.[key];
454
+ const isSecret = isSecretConfigKey(key, itemDef);
455
+ // 委托 RuntimeConfig 五层优先级链单一事实源,避免重复实现解析链
456
+ const resolved = this.runtimeConfig.describe(key);
457
+ // overrides 来源对外统一星现为包级覆盖视角
458
+ const source = resolved.source === "overrides" ? "package" : resolved.source;
459
+ const configured = resolved.source !== "default";
460
+ return {
461
+ key,
462
+ configured,
463
+ secret: isSecret,
464
+ source,
465
+ value: isSecret ? undefined : resolved.value,
466
+ };
467
+ }
468
+ async setConfig(key, value) {
469
+ await this.storage.setConfig(key, value);
470
+ }
471
+ async deleteConfig(key) {
472
+ return await this.storage.deleteConfig(key);
473
+ }
474
+ async getState(actionIdOrKey, keyOrOptions, options) {
475
+ let actionId;
476
+ let key;
477
+ let opts;
478
+ if (typeof keyOrOptions === "string") {
479
+ actionId = actionIdOrKey;
480
+ key = keyOrOptions;
481
+ opts = options;
482
+ if (opts?.actionId && opts.actionId !== actionId) {
483
+ throw new Error(`Conflicting actionId specified: positional '${actionId}' vs options.actionId '${opts.actionId}'`);
484
+ }
485
+ }
486
+ else {
487
+ actionId = "";
488
+ key = actionIdOrKey;
489
+ opts = keyOrOptions;
490
+ }
491
+ if (!actionId && opts?.actionId) {
492
+ actionId = opts.actionId;
493
+ }
494
+ const ns = actionId
495
+ ? (opts?.namespace ? `${actionId}:${opts.namespace}` : actionId)
496
+ : (opts?.namespace ?? "");
497
+ if (opts?.detail) {
498
+ const entry = await this.storage.findState(key, ns || undefined);
499
+ return entry;
500
+ }
501
+ if (actionId) {
502
+ return await this.storage.getState(ns, key);
503
+ }
504
+ if (ns) {
505
+ return await this.storage.getState(ns, key);
506
+ }
507
+ const entry = await this.storage.findState(key);
508
+ return entry?.value;
509
+ }
510
+ async setState(actionIdOrKey, keyOrValue, valueOrOptions, options) {
511
+ let actionId;
512
+ let key;
513
+ let value;
514
+ let opts;
515
+ if (arguments.length >= 4) {
516
+ if (options?.actionId && options.actionId !== actionIdOrKey) {
517
+ throw new Error(`Conflicting actionId specified: positional '${actionIdOrKey}' vs options.actionId '${options.actionId}'`);
518
+ }
519
+ actionId = actionIdOrKey;
520
+ key = keyOrValue;
521
+ value = valueOrOptions;
522
+ opts = options;
523
+ }
524
+ else if (arguments.length === 2) {
525
+ actionId = "";
526
+ key = actionIdOrKey;
527
+ value = keyOrValue;
528
+ opts = undefined;
529
+ }
530
+ else {
531
+ if (valueOrOptions !== undefined &&
532
+ (typeof valueOrOptions !== "object" || valueOrOptions === null || Array.isArray(valueOrOptions))) {
533
+ throw new Error("Invalid options provided to setState. Use setActionState(actionId, key, value, options) or 4-argument setState for action state.");
534
+ }
535
+ key = actionIdOrKey;
536
+ value = keyOrValue;
537
+ opts = valueOrOptions;
538
+ actionId = opts?.actionId ?? "";
539
+ }
540
+ const ns = actionId
541
+ ? (opts?.namespace ? `${actionId}:${opts.namespace}` : actionId)
542
+ : (opts?.namespace ?? "");
543
+ if (ns) {
544
+ await this.storage.setState(ns, key, value, opts?.ttl);
545
+ return;
546
+ }
547
+ let targetKey = key;
548
+ let targetNs = "";
549
+ try {
550
+ const decoded = decodeStateKey(key);
551
+ targetNs = decoded.namespace;
552
+ targetKey = decoded.key;
553
+ }
554
+ catch {
555
+ targetNs = "";
556
+ }
557
+ await this.storage.setState(targetNs, targetKey, value, opts?.ttl);
558
+ }
559
+ async deleteState(actionIdOrKey, keyOrOptions, options) {
560
+ let actionId;
561
+ let key;
562
+ let opts;
563
+ if (typeof keyOrOptions === "string") {
564
+ actionId = actionIdOrKey;
565
+ key = keyOrOptions;
566
+ opts = options;
567
+ if (opts?.actionId && opts.actionId !== actionId) {
568
+ throw new Error(`Conflicting actionId specified: positional '${actionId}' vs options.actionId '${opts.actionId}'`);
569
+ }
570
+ }
571
+ else {
572
+ actionId = "";
573
+ key = actionIdOrKey;
574
+ opts = keyOrOptions;
575
+ }
576
+ if (!actionId && opts?.actionId) {
577
+ actionId = opts.actionId;
578
+ }
579
+ const ns = actionId
580
+ ? (opts?.namespace ? `${actionId}:${opts.namespace}` : actionId)
581
+ : (opts?.namespace ?? "");
582
+ if (ns) {
583
+ return await this.storage.deleteState(ns, key);
584
+ }
585
+ let targetKey = key;
586
+ let targetNs = "";
587
+ try {
588
+ const decoded = decodeStateKey(key);
589
+ targetNs = decoded.namespace;
590
+ targetKey = decoded.key;
591
+ }
592
+ catch {
593
+ targetNs = "";
594
+ }
595
+ return await this.storage.deleteState(targetNs, targetKey);
596
+ }
597
+ async getActionState(actionId, key, options) {
598
+ if (options?.actionId && options.actionId !== actionId) {
599
+ throw new Error(`Conflicting actionId specified: positional '${actionId}' vs options.actionId '${options.actionId}'`);
600
+ }
601
+ const ns = options?.namespace ? `${actionId}:${options.namespace}` : actionId;
602
+ if (options?.detail) {
603
+ const entry = await this.storage.findState(key, ns || undefined);
604
+ return entry;
605
+ }
606
+ return await this.storage.getState(ns, key);
607
+ }
608
+ async setActionState(actionId, key, value, options) {
609
+ if (options?.actionId && options.actionId !== actionId) {
610
+ throw new Error(`Conflicting actionId specified: positional '${actionId}' vs options.actionId '${options.actionId}'`);
611
+ }
612
+ const ns = options?.namespace ? `${actionId}:${options.namespace}` : actionId;
613
+ await this.storage.setState(ns, key, value, options?.ttl);
614
+ }
615
+ async deleteActionState(actionId, key, options) {
616
+ if (options?.actionId && options.actionId !== actionId) {
617
+ throw new Error(`Conflicting actionId specified: positional '${actionId}' vs options.actionId '${options.actionId}'`);
618
+ }
619
+ const ns = options?.namespace ? `${actionId}:${options.namespace}` : actionId;
620
+ return await this.storage.deleteState(ns, key);
621
+ }
622
+ async listStateKeys(actionIdOrOptions, options) {
623
+ let actionId;
624
+ let opts;
625
+ if (typeof actionIdOrOptions === "string") {
626
+ actionId = actionIdOrOptions;
627
+ opts = options;
628
+ if (opts?.actionId && opts.actionId !== actionId) {
629
+ throw new Error(`Conflicting actionId specified: positional '${actionId}' vs options.actionId '${opts.actionId}'`);
630
+ }
631
+ }
632
+ else {
633
+ actionId = "";
634
+ opts = actionIdOrOptions;
635
+ }
636
+ if (!actionId && opts?.actionId) {
637
+ actionId = opts.actionId;
638
+ }
639
+ const ns = actionId
640
+ ? (opts?.namespace ? `${actionId}:${opts.namespace}` : actionId)
641
+ : (opts?.namespace ?? null);
642
+ return this.storage.listStateKeys(ns, opts?.prefix);
643
+ }
644
+ async clearState(actionIdOrOptions, options) {
645
+ let actionId;
646
+ let opts;
647
+ if (typeof actionIdOrOptions === "string") {
648
+ actionId = actionIdOrOptions;
649
+ opts = options;
650
+ if (opts?.actionId && opts.actionId !== actionId) {
651
+ throw new Error(`Conflicting actionId specified: positional '${actionId}' vs options.actionId '${opts.actionId}'`);
652
+ }
653
+ }
654
+ else {
655
+ actionId = "";
656
+ opts = actionIdOrOptions;
657
+ }
658
+ if (!actionId && opts?.actionId) {
659
+ actionId = opts.actionId;
660
+ }
661
+ const ns = actionId
662
+ ? (opts?.namespace ? `${actionId}:${opts.namespace}` : actionId)
663
+ : (opts?.namespace ?? undefined);
664
+ return this.storage.clearState({
665
+ namespace: ns,
666
+ prefix: opts?.prefix,
667
+ all: opts?.all,
668
+ });
669
+ }
670
+ async close(options) {
671
+ if (this.isClosed)
672
+ return;
673
+ this.isClosed = true;
674
+ try {
675
+ await this.executionService.close(options);
676
+ }
677
+ finally {
678
+ try {
679
+ this.storage.close();
680
+ }
681
+ catch {
682
+ // 忽略存储重复关闭异常
683
+ }
684
+ finally {
685
+ try {
686
+ this.globalStorage?.close();
687
+ }
688
+ catch {
689
+ // 忽略全局存储关闭异常
690
+ }
691
+ }
692
+ }
693
+ }
694
+ }
695
+ /**
696
+ * 工厂函数:创建并初始化 ActionDockApp 实例。
697
+ */
698
+ export async function createActionDockApp(options = {}) {
699
+ return new DefaultActionDockApp(options);
700
+ }
@@ -0,0 +1,2 @@
1
+ export * from "./types.js";
2
+ export * from "./app.js";