@actiondock/core 2.6.0 → 2.8.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 (268) hide show
  1. package/README.md +61 -68
  2. package/dist/catalog/action-catalog.d.ts +56 -0
  3. package/dist/catalog/action-catalog.js +202 -0
  4. package/dist/catalog/discovery.d.ts +60 -0
  5. package/dist/catalog/discovery.js +119 -0
  6. package/dist/catalog/graph.d.ts +190 -0
  7. package/dist/catalog/graph.js +589 -0
  8. package/dist/catalog/index.d.ts +5 -5
  9. package/dist/catalog/index.js +5 -5
  10. package/dist/catalog/resolve-action.d.ts +43 -0
  11. package/dist/catalog/resolve-action.js +119 -0
  12. package/dist/catalog/resolve-playbook.d.ts +26 -0
  13. package/dist/catalog/resolve-playbook.js +114 -0
  14. package/dist/doctor/checks/project.js +27 -8
  15. package/dist/doctor/checks/registry.js +2 -2
  16. package/dist/doctor/checks/runtime.js +34 -1
  17. package/dist/errors.d.ts +122 -10
  18. package/dist/errors.js +123 -10
  19. package/dist/execution/service.d.ts +18 -16
  20. package/dist/execution/service.js +183 -252
  21. package/dist/execution/types.d.ts +25 -69
  22. package/dist/execution/types.js +2 -1
  23. package/dist/filter/intent.d.ts +8 -9
  24. package/dist/filter/intent.js +49 -10
  25. package/dist/graph/index.d.ts +4 -0
  26. package/dist/graph/index.js +4 -0
  27. package/dist/host/host.d.ts +74 -32
  28. package/dist/host/host.js +585 -336
  29. package/dist/host/routing.d.ts +15 -48
  30. package/dist/host/routing.js +90 -153
  31. package/dist/host/types.d.ts +50 -17
  32. package/dist/index.d.ts +21 -22
  33. package/dist/index.js +19 -21
  34. package/dist/input/advice.d.ts +104 -0
  35. package/dist/input/advice.js +716 -0
  36. package/dist/input/describe.d.ts +106 -0
  37. package/dist/input/describe.js +176 -0
  38. package/dist/input/file-input.d.ts +54 -0
  39. package/dist/input/file-input.js +124 -0
  40. package/dist/input/flat-decode.d.ts +11 -0
  41. package/dist/input/flat-decode.js +13 -0
  42. package/dist/input/flat-errors.d.ts +71 -0
  43. package/dist/input/flat-errors.js +87 -0
  44. package/dist/input/flat-materializer.d.ts +29 -0
  45. package/dist/input/flat-materializer.js +177 -0
  46. package/dist/input/flat-parser.d.ts +50 -0
  47. package/dist/input/flat-parser.js +169 -0
  48. package/dist/input/flat-predicates.d.ts +34 -0
  49. package/dist/input/flat-predicates.js +50 -0
  50. package/dist/input/index.d.ts +14 -0
  51. package/dist/input/index.js +14 -0
  52. package/dist/input/input-resolver.d.ts +63 -0
  53. package/dist/input/input-resolver.js +254 -0
  54. package/dist/input/json-depth-scanner.d.ts +17 -0
  55. package/dist/input/json-depth-scanner.js +49 -0
  56. package/dist/input/metadata.d.ts +99 -0
  57. package/dist/input/metadata.js +99 -0
  58. package/dist/input/stdin-input.d.ts +26 -0
  59. package/dist/input/stdin-input.js +125 -0
  60. package/dist/input/utf8.d.ts +19 -0
  61. package/dist/input/utf8.js +36 -0
  62. package/dist/input/validation-mapper.d.ts +27 -0
  63. package/dist/input/validation-mapper.js +144 -0
  64. package/dist/invocation/index.d.ts +2 -0
  65. package/dist/invocation/index.js +2 -0
  66. package/dist/invocation/policy.d.ts +157 -0
  67. package/dist/invocation/policy.js +231 -0
  68. package/dist/invocation/types.d.ts +172 -0
  69. package/dist/invocation/types.js +97 -0
  70. package/dist/ipc/diagnostic.d.ts +0 -12
  71. package/dist/ipc/diagnostic.js +0 -21
  72. package/dist/ipc/host.d.ts +4 -4
  73. package/dist/ipc/host.js +44 -47
  74. package/dist/ipc/index.d.ts +1 -1
  75. package/dist/ipc/index.js +1 -1
  76. package/dist/ipc/service.d.ts +40 -0
  77. package/dist/ipc/service.js +349 -0
  78. package/dist/ipc/types.d.ts +21 -15
  79. package/dist/json/index.d.ts +1 -0
  80. package/dist/json/index.js +1 -0
  81. package/dist/json/value-validator.d.ts +88 -0
  82. package/dist/json/value-validator.js +330 -0
  83. package/dist/node/index.d.ts +1 -0
  84. package/dist/node/index.js +1 -0
  85. package/dist/node/module-loader.d.ts +63 -0
  86. package/dist/node/module-loader.js +112 -0
  87. package/dist/package/index.d.ts +23 -0
  88. package/dist/package/index.js +18 -0
  89. package/dist/{app/app.d.ts → package/runtime.d.ts} +41 -20
  90. package/dist/{app/app.js → package/runtime.js} +140 -95
  91. package/dist/{app → package}/static-index.js +58 -41
  92. package/dist/package/storage-view.d.ts +13 -0
  93. package/dist/package/storage-view.js +22 -0
  94. package/dist/{app → package}/types.d.ts +76 -57
  95. package/dist/package/types.js +22 -0
  96. package/dist/platform/index.d.ts +1 -1
  97. package/dist/platform/index.js +1 -1
  98. package/dist/platform/node.d.ts +48 -0
  99. package/dist/platform/node.js +96 -0
  100. package/dist/platform/types.d.ts +0 -9
  101. package/dist/process/control-arbiter.d.ts +2 -1
  102. package/dist/process/control-arbiter.js +1 -2
  103. package/dist/process/driver.d.ts +9 -8
  104. package/dist/process/driver.js +11 -22
  105. package/dist/process/index.d.ts +2 -0
  106. package/dist/process/index.js +2 -0
  107. package/dist/process/managed-record.d.ts +2 -2
  108. package/dist/process/process-driver.d.ts +109 -0
  109. package/dist/process/process-driver.js +650 -0
  110. package/dist/process/process-executor.d.ts +47 -0
  111. package/dist/process/process-executor.js +296 -0
  112. package/dist/process/process-manager.js +48 -26
  113. package/dist/process/run-executor.js +12 -12
  114. package/dist/profile/client-actions.js +2 -2
  115. package/dist/profile/client-health.js +3 -2
  116. package/dist/profile/client-query.js +5 -6
  117. package/dist/profile/client-transport.d.ts +19 -17
  118. package/dist/profile/client-transport.js +48 -80
  119. package/dist/profile/client.d.ts +2 -2
  120. package/dist/profile/client.js +1 -1
  121. package/dist/profile/index.d.ts +1 -0
  122. package/dist/profile/index.js +1 -0
  123. package/dist/profile/manager.d.ts +5 -0
  124. package/dist/profile/manager.js +41 -6
  125. package/dist/project/closure.js +2 -2
  126. package/dist/project/index.d.ts +8 -1
  127. package/dist/project/index.js +10 -1
  128. package/dist/project/init.js +2 -2
  129. package/dist/project/loader.d.ts +1 -1
  130. package/dist/project/loader.js +26 -29
  131. package/dist/project/transactions.js +5 -10
  132. package/dist/registry/index.d.ts +3 -1
  133. package/dist/registry/index.js +2 -1
  134. package/dist/registry/lock.d.ts +28 -7
  135. package/dist/registry/lock.js +136 -16
  136. package/dist/registry/registry.d.ts +1 -5
  137. package/dist/registry/registry.js +1 -53
  138. package/dist/registry/scan.d.ts +0 -15
  139. package/dist/registry/scan.js +0 -59
  140. package/dist/registry/store.d.ts +42 -0
  141. package/dist/registry/store.js +43 -0
  142. package/dist/registry/types.d.ts +0 -24
  143. package/dist/runtime/action-collection.d.ts +1 -1
  144. package/dist/runtime/action-registry.d.ts +0 -4
  145. package/dist/runtime/action-registry.js +0 -7
  146. package/dist/runtime/context.js +5 -11
  147. package/dist/runtime/events.js +3 -6
  148. package/dist/runtime/identity.d.ts +22 -0
  149. package/dist/runtime/identity.js +10 -0
  150. package/dist/runtime/index.d.ts +1 -2
  151. package/dist/runtime/index.js +1 -2
  152. package/dist/runtime/module-loader.d.ts +2 -34
  153. package/dist/runtime/module-loader.js +1 -16
  154. package/dist/runtime/process.d.ts +6 -24
  155. package/dist/runtime/process.js +1 -118
  156. package/dist/runtime/run-persistence.js +2 -5
  157. package/dist/runtime/runner.d.ts +33 -103
  158. package/dist/runtime/runner.js +142 -404
  159. package/dist/runtime/standalone.d.ts +37 -9
  160. package/dist/runtime/standalone.js +195 -136
  161. package/dist/schema/index.d.ts +1 -0
  162. package/dist/schema/index.js +1 -0
  163. package/dist/schema/validator.d.ts +10 -0
  164. package/dist/schema/validator.js +48 -54
  165. package/dist/server/body.d.ts +16 -8
  166. package/dist/server/body.js +33 -16
  167. package/dist/server/dispatcher.d.ts +6 -10
  168. package/dist/server/dispatcher.js +24 -32
  169. package/dist/server/http-server.d.ts +87 -0
  170. package/dist/server/http-server.js +304 -0
  171. package/dist/server/index.d.ts +11 -0
  172. package/dist/server/index.js +10 -0
  173. package/dist/server/mcp-endpoint.d.ts +61 -0
  174. package/dist/server/mcp-endpoint.js +118 -0
  175. package/dist/server/routes/actions.js +34 -28
  176. package/dist/server/routes/common.d.ts +10 -14
  177. package/dist/server/routes/common.js +32 -56
  178. package/dist/server/routes/config.js +54 -64
  179. package/dist/server/routes/doctor.d.ts +1 -1
  180. package/dist/server/routes/doctor.js +10 -18
  181. package/dist/server/routes/health.d.ts +1 -1
  182. package/dist/server/routes/health.js +2 -3
  183. package/dist/server/routes/info.d.ts +2 -2
  184. package/dist/server/routes/info.js +12 -13
  185. package/dist/server/routes/playbooks.js +16 -29
  186. package/dist/server/routes/runs.js +95 -117
  187. package/dist/server/routes/state.js +63 -62
  188. package/dist/server/server.d.ts +2 -2
  189. package/dist/server/server.js +43 -227
  190. package/dist/server/types.d.ts +8 -19
  191. package/dist/service/factory.d.ts +12 -0
  192. package/dist/service/factory.js +85 -0
  193. package/dist/{target → service}/index.d.ts +1 -1
  194. package/dist/{target → service}/index.js +1 -1
  195. package/dist/service/local.d.ts +27 -0
  196. package/dist/service/local.js +138 -0
  197. package/dist/{target → service}/remote-errors.d.ts +3 -6
  198. package/dist/service/remote-errors.js +38 -0
  199. package/dist/{target → service}/remote-polling.d.ts +2 -2
  200. package/dist/{target → service}/remote-polling.js +8 -8
  201. package/dist/service/remote.d.ts +34 -0
  202. package/dist/service/remote.js +634 -0
  203. package/dist/service/sse-stream.d.ts +24 -0
  204. package/dist/service/sse-stream.js +139 -0
  205. package/dist/service/types.d.ts +272 -0
  206. package/dist/service/types.js +32 -0
  207. package/dist/storage/data-dir-lock.js +10 -5
  208. package/dist/storage/driver.d.ts +2 -1
  209. package/dist/storage/driver.js +3 -52
  210. package/dist/storage/index.d.ts +1 -0
  211. package/dist/storage/index.js +1 -0
  212. package/dist/storage/lock-core.d.ts +2 -6
  213. package/dist/storage/lock-core.js +4 -17
  214. package/dist/storage/params.d.ts +2 -8
  215. package/dist/storage/params.js +2 -8
  216. package/dist/storage/sqlite-driver.d.ts +40 -0
  217. package/dist/storage/sqlite-driver.js +116 -0
  218. package/dist/storage/sqlite.js +21 -6
  219. package/dist/storage/types.d.ts +4 -4
  220. package/dist/storage/types.js +2 -2
  221. package/dist/utils/index.d.ts +53 -0
  222. package/dist/utils/index.js +99 -4
  223. package/dist/utils/process.d.ts +10 -0
  224. package/dist/utils/process.js +21 -0
  225. package/dist/version.d.ts +1 -1
  226. package/dist/version.js +1 -1
  227. package/package.json +41 -3
  228. package/dist/app/index.d.ts +0 -2
  229. package/dist/app/index.js +0 -2
  230. package/dist/app/types.js +0 -1
  231. package/dist/catalog/action-index.d.ts +0 -9
  232. package/dist/catalog/action-index.js +0 -95
  233. package/dist/catalog/action-resolver.d.ts +0 -20
  234. package/dist/catalog/action-resolver.js +0 -95
  235. package/dist/catalog/location-registry.d.ts +0 -15
  236. package/dist/catalog/location-registry.js +0 -138
  237. package/dist/catalog/package-catalog.d.ts +0 -7
  238. package/dist/catalog/package-catalog.js +0 -77
  239. package/dist/catalog/types.d.ts +0 -68
  240. package/dist/catalog/types.js +0 -1
  241. package/dist/export/index.d.ts +0 -1
  242. package/dist/export/index.js +0 -1
  243. package/dist/export/templates.d.ts +0 -71
  244. package/dist/export/templates.js +0 -623
  245. package/dist/ipc/target.d.ts +0 -74
  246. package/dist/ipc/target.js +0 -365
  247. package/dist/platform/default.d.ts +0 -38
  248. package/dist/platform/default.js +0 -78
  249. package/dist/project/resolver.d.ts +0 -116
  250. package/dist/project/resolver.js +0 -376
  251. package/dist/registry/resolve.d.ts +0 -62
  252. package/dist/registry/resolve.js +0 -195
  253. package/dist/runtime/execution-manager.d.ts +0 -48
  254. package/dist/runtime/execution-manager.js +0 -66
  255. package/dist/runtime/package-runner-factory.d.ts +0 -82
  256. package/dist/runtime/package-runner-factory.js +0 -186
  257. package/dist/target/local.d.ts +0 -53
  258. package/dist/target/local.js +0 -349
  259. package/dist/target/remote-errors.js +0 -51
  260. package/dist/target/remote.d.ts +0 -86
  261. package/dist/target/remote.js +0 -818
  262. package/dist/target/target.d.ts +0 -6
  263. package/dist/target/target.js +0 -37
  264. package/dist/target/types.d.ts +0 -261
  265. package/dist/target/types.js +0 -35
  266. /package/dist/{app → package}/static-index.d.ts +0 -0
  267. /package/dist/{target → service}/sse-parser.d.ts +0 -0
  268. /package/dist/{target → service}/sse-parser.js +0 -0
@@ -0,0 +1,139 @@
1
+ import { ActionDockError, EVENT_CURSOR_EXPIRED, REMOTE_STREAM_UNAVAILABLE } from "../errors.js";
2
+ import { assertSecureTransport } from "../profile/client.js";
3
+ import { normalizeServerUrl } from "../profile/manager.js";
4
+ import { getInsecureDispatcher } from "../server/dispatcher.js";
5
+ import { parseSseMessages } from "./sse-parser.js";
6
+ /**
7
+ * 将 SSE 消息载荷解码为统一执行事件。
8
+ *
9
+ * 非 JSON 数据行直接忽略;finish 事件取 data.result 字段,其余事件字段展开合并。
10
+ */
11
+ export function decodeExecutionEvent(msg, runId) {
12
+ try {
13
+ const data = JSON.parse(msg.data);
14
+ if (msg.event === "finish") {
15
+ return {
16
+ eventId: msg.id ?? data.eventId,
17
+ type: "finish",
18
+ runId,
19
+ timestamp: new Date().toISOString(),
20
+ result: data.result || data,
21
+ };
22
+ }
23
+ else {
24
+ return {
25
+ eventId: msg.id ?? data.eventId,
26
+ type: (msg.event || "message"),
27
+ runId,
28
+ timestamp: new Date().toISOString(),
29
+ ...data,
30
+ };
31
+ }
32
+ }
33
+ catch {
34
+ // 忽略非 JSON 数据行
35
+ return undefined;
36
+ }
37
+ }
38
+ /**
39
+ * 订阅远端运行事件流(Server-Sent Events)。
40
+ *
41
+ * 候选路由探测与自动回退:优先尝试标准 v2 路由 /api/v2/runs/:runId/events,
42
+ * 失败时回退至既有路由 /api/v2/runs/:runId/stream;
43
+ * 全部候选均不可用(网络异常或非流式响应)时抛出携带各候选 URL 与
44
+ * 失败原因的 REMOTE_STREAM_UNAVAILABLE 聚合错误,严禁以空流伪装正常。
45
+ */
46
+ export async function* streamRemoteEvents(serverUrl, runId, token, options) {
47
+ assertSecureTransport(serverUrl, token, {
48
+ allowInsecureHttp: options?.allowInsecureHttp,
49
+ insecure: options?.insecure,
50
+ });
51
+ const base = normalizeServerUrl(serverUrl);
52
+ const runRoute = `runs/${encodeURIComponent(runId)}`;
53
+ // 候选路由:v2 /events -> v2 /stream
54
+ const candidateUrls = [
55
+ `${base}/api/v2/${runRoute}/events`,
56
+ `${base}/api/v2/${runRoute}/stream`,
57
+ ];
58
+ const headers = {
59
+ Accept: "text/event-stream",
60
+ };
61
+ if (token && token.trim()) {
62
+ headers.Authorization = `Bearer ${token.trim()}`;
63
+ }
64
+ if (options?.after !== undefined) {
65
+ headers["Last-Event-ID"] = String(options.after);
66
+ }
67
+ /**
68
+ * 依次尝试全部候选路由,返回首个可用响应。
69
+ */
70
+ async function resolveStreamCandidate() {
71
+ const candidateFailures = [];
72
+ for (const url of candidateUrls) {
73
+ const fetchInit = {
74
+ headers,
75
+ signal: options?.signal,
76
+ };
77
+ if (options?.dispatcher) {
78
+ fetchInit.dispatcher = options.dispatcher;
79
+ }
80
+ else if (options?.insecure) {
81
+ fetchInit.dispatcher = getInsecureDispatcher();
82
+ }
83
+ try {
84
+ const resp = await fetch(url, fetchInit);
85
+ if (resp.status === 410) {
86
+ let errJson;
87
+ try {
88
+ errJson = await resp.json();
89
+ }
90
+ catch { }
91
+ throw new ActionDockError(errJson?.error?.code || EVENT_CURSOR_EXPIRED, errJson?.error?.message || "Event cursor has expired", errJson?.error?.details);
92
+ }
93
+ if (resp.ok && resp.body) {
94
+ return { ok: true, body: resp.body };
95
+ }
96
+ candidateFailures.push({
97
+ url,
98
+ reason: `HTTP ${resp.status} ${resp.statusText || ""}`.trim(),
99
+ });
100
+ }
101
+ catch (err) {
102
+ if (err?.code === "EVENT_CURSOR_EXPIRED") {
103
+ throw err;
104
+ }
105
+ candidateFailures.push({
106
+ url,
107
+ reason: err?.message ? `${err.name || "Error"}: ${err.message}` : String(err),
108
+ });
109
+ }
110
+ }
111
+ return { ok: false, candidateFailures };
112
+ }
113
+ function buildStreamUnavailableError(candidateFailures) {
114
+ const summary = candidateFailures
115
+ .map((f) => `${f.url} (${f.reason})`)
116
+ .join(", ");
117
+ return new ActionDockError(REMOTE_STREAM_UNAVAILABLE, `REMOTE_STREAM_UNAVAILABLE: All event stream candidates failed for run '${runId}': ${summary}`, {
118
+ runId,
119
+ candidates: candidateFailures.map((f) => ({ url: f.url, reason: f.reason })),
120
+ });
121
+ }
122
+ const res = await resolveStreamCandidate();
123
+ if (!res.ok) {
124
+ throw buildStreamUnavailableError(res.candidateFailures);
125
+ }
126
+ try {
127
+ for await (const msg of parseSseMessages(res.body, { signal: options?.signal })) {
128
+ const evt = decodeExecutionEvent(msg, runId);
129
+ if (evt)
130
+ yield evt;
131
+ }
132
+ }
133
+ catch (err) {
134
+ if (err.name === "AbortError" || options?.signal?.aborted) {
135
+ return;
136
+ }
137
+ throw err;
138
+ }
139
+ }
@@ -0,0 +1,272 @@
1
+ import type { ActionRef, ExecutionEvent, ExecutionResult, JsonValue, RunRecord } from "@actiondock/sdk";
2
+ import type { ActionSpec, ActionSummary, ListActionsOptions, PackageInfo, PackageRuntime, PackageRuntimeOptions, PlaybookSpec, PlaybookSummary } from "../package/types.js";
3
+ import type { CancelResult, ExecutionTicket } from "../execution/types.js";
4
+ import type { ActionDockHostOptions } from "../host/types.js";
5
+ import type { RuntimePlatform } from "../platform/types.js";
6
+ import type { StateEntry } from "../storage/types.js";
7
+ import { ActionDockError, type ErrorCode, PROTOCOL_UNSUPPORTED, SERVICE_RESULT_UNKNOWN, SERVICE_CLOSED } from "../errors.js";
8
+ /**
9
+ * 公开运行控制选项(RunOptions)。
10
+ * 面向外部调用方的公开契约,彻底剥离内部 Lineage 字段,严禁污染内部运行时状态。
11
+ */
12
+ export interface RunOptions {
13
+ /** 外部传入的 AbortSignal 取消信号 */
14
+ signal?: AbortSignal;
15
+ /** 最大超时时间(毫秒) */
16
+ timeoutMs?: number;
17
+ /** 执行级临时配置覆盖字典 */
18
+ config?: Record<string, JsonValue>;
19
+ /** 幂等请求标识 */
20
+ requestId?: string;
21
+ }
22
+ /**
23
+ * 统一协议版本常量。
24
+ */
25
+ export declare const ACTIONDOCK_PROTOCOL_VERSION = "2.0";
26
+ /**
27
+ * 服务端/通信协议错误码常量(单一事实源引用自 errors.ts)。
28
+ */
29
+ export { PROTOCOL_UNSUPPORTED, SERVICE_RESULT_UNKNOWN, SERVICE_CLOSED };
30
+ /**
31
+ * 结构化服务通信异常类。
32
+ */
33
+ export declare class ServiceError extends ActionDockError {
34
+ readonly details?: Record<string, unknown>;
35
+ constructor(code: ErrorCode, message: string, details?: Record<string, unknown>);
36
+ }
37
+ /**
38
+ * 服务关闭超时异常类。
39
+ */
40
+ export declare class CloseTimeoutError extends Error {
41
+ readonly runIds?: string[];
42
+ constructor(message?: string, runIds?: string[]);
43
+ }
44
+ /**
45
+ * 配置项安全视图契约。
46
+ * 屏蔽敏感配置原文,仅暴露是否已配置、是否为秘密及实际解析来源。
47
+ */
48
+ export interface ConfigValueView {
49
+ /** 配置项键名 */
50
+ key: string;
51
+ /** 是否已显式配置或存在有效值 */
52
+ configured: boolean;
53
+ /** 是否为秘密敏感配置 */
54
+ secret: boolean;
55
+ /** 配置值实际解析来源 */
56
+ source: string;
57
+ /** 非秘密配置的实际数据值 */
58
+ value?: JsonValue;
59
+ }
60
+ /**
61
+ * 状态作用域与筛选控制选项。
62
+ */
63
+ export interface StateScopeOptions {
64
+ /** 显式绑定的 Action 标识 */
65
+ actionId?: string;
66
+ /** 显式子命名空间(相对于 Action 根命名空间) */
67
+ namespace?: string;
68
+ /** 存活有效期(秒),仅在写入状态时生效 */
69
+ ttl?: number;
70
+ /** 键名前缀过滤匹配 */
71
+ prefix?: string;
72
+ /** 是否清空所有条目 */
73
+ all?: boolean;
74
+ /** 是否返回完整条目详情 */
75
+ detail?: boolean;
76
+ }
77
+ /**
78
+ * 任务运行记录列表查询选项。
79
+ */
80
+ export interface ListRunsOptions {
81
+ /** 目标包唯一标识 */
82
+ packageId?: string;
83
+ /** Action 动作唯一标识 */
84
+ actionId?: string;
85
+ /** 运行终态状态筛选 */
86
+ status?: string;
87
+ /** 模糊意图检索模式 */
88
+ intent?: string;
89
+ /** 最大返回记录条数限制 */
90
+ limit?: number;
91
+ }
92
+ /**
93
+ * 远程服务连接配置选项。
94
+ */
95
+ export interface RemoteServiceOptions {
96
+ /** 远端 ActionDock 服务 HTTP 根地址 */
97
+ serverUrl: string;
98
+ /** 鉴权 Bearer Token(可选) */
99
+ token?: string;
100
+ /** 是否允许向非回环地址发送明文 HTTP 请求(默认 false) */
101
+ allowInsecureHttp?: boolean;
102
+ /** 是否跳过 TLS 证书合法性校验(用于局域网自签证书) */
103
+ insecure?: boolean;
104
+ /** 自定义底层 HTTP 调度器(平台中立) */
105
+ dispatcher?: unknown;
106
+ /** 请求超时时间(毫秒) */
107
+ timeoutMs?: number;
108
+ /** 轮询等待基准底线超时时间(毫秒,默认 60000ms) */
109
+ baseTimeoutMs?: number;
110
+ /** 是否启用配置与状态管理端口(默认 true) */
111
+ enableManagement?: boolean;
112
+ }
113
+ /**
114
+ * 资产与元数据发现服务端口。
115
+ */
116
+ export interface DiscoveryPort {
117
+ /** 列出已注册的所有宏包元数据 */
118
+ listPackages(): Promise<PackageInfo[]>;
119
+ /** 列出所有可用的 Action 摘要 */
120
+ listActions(options?: ListActionsOptions): Promise<ActionSummary[]>;
121
+ /** 查询指定 Action 的规范结构与模式定义 */
122
+ describeAction(ref: ActionRef | string): Promise<ActionSpec>;
123
+ /** 列出可用的 Playbook 规程摘要 */
124
+ listPlaybooks(options?: {
125
+ intent?: string;
126
+ package?: string;
127
+ }): Promise<PlaybookSummary[]>;
128
+ /** 查询指定 Playbook 的规范内容与操作指南 */
129
+ describePlaybook(id: string): Promise<PlaybookSpec>;
130
+ }
131
+ /**
132
+ * Action 执行调用服务端口。
133
+ */
134
+ export interface ExecutionPort {
135
+ /** 同步执行指定 Action 并等待终态结果 */
136
+ run(ref: ActionRef | string, input?: unknown, options?: RunOptions): Promise<ExecutionResult>;
137
+ /** 异步启动指定 Action 并立即返回任务执行票据 */
138
+ start(ref: ActionRef | string, input?: unknown, options?: RunOptions): Promise<ExecutionTicket>;
139
+ }
140
+ /**
141
+ * 运行事件订阅控制选项。
142
+ */
143
+ export interface RunEventSubscriptionOptions {
144
+ /** 起始游标位置(序号或标识) */
145
+ after?: number | string;
146
+ /** 外部取消信号 */
147
+ signal?: AbortSignal;
148
+ /** 最大背压队列深度 */
149
+ maxQueueSize?: number;
150
+ }
151
+ /**
152
+ * 任务执行事件流服务端口。
153
+ */
154
+ export interface EventsPort {
155
+ /** 订阅指定运行的事件流 */
156
+ events(runId: string, options?: RunEventSubscriptionOptions): AsyncIterable<ExecutionEvent>;
157
+ }
158
+ /**
159
+ * 任务运行记录管理服务端口。
160
+ */
161
+ export interface RunsPort {
162
+ /** 查询任务执行记录列表 */
163
+ list(query?: ListRunsOptions): Promise<RunRecord[]>;
164
+ /** 查询指定运行标识的记录详情 */
165
+ get(runId: string): Promise<RunRecord | undefined>;
166
+ /** 取消指定在运行的任务 */
167
+ cancel(runId: string, reason?: string): Promise<CancelResult>;
168
+ /** 清空历史任务运行记录 */
169
+ clear?(options?: {
170
+ packageId?: string;
171
+ actionId?: string;
172
+ status?: string;
173
+ }): Promise<number>;
174
+ }
175
+ /**
176
+ * 配置项管理服务端口。
177
+ */
178
+ export interface ConfigPort {
179
+ /** 获取指定包的单项配置安全视图 */
180
+ get(packageId: string, key: string): Promise<ConfigValueView>;
181
+ /** 写入或覆盖指定包的配置项 */
182
+ set(packageId: string, key: string, value: JsonValue): Promise<void>;
183
+ /** 删除指定包的指定配置项 */
184
+ delete(packageId: string, key: string): Promise<boolean>;
185
+ /** 列出指定包所有配置项的安全视图列表 */
186
+ list(packageId: string): Promise<ConfigValueView[]>;
187
+ }
188
+ /**
189
+ * 状态存储管理服务端口。
190
+ */
191
+ export interface StatePort {
192
+ /** 获取指定包指定动作的作用域状态值 */
193
+ get<T extends JsonValue = JsonValue>(packageId: string, actionId: string, key: string, options?: StateScopeOptions): Promise<T | undefined>;
194
+ /** 写入指定包指定动作的作用域状态值 */
195
+ set<T extends JsonValue = JsonValue>(packageId: string, actionId: string, key: string, value: T, options?: StateScopeOptions): Promise<void>;
196
+ /** 删除指定包指定动作的作用域状态项 */
197
+ delete(packageId: string, actionId: string, key: string, options?: StateScopeOptions): Promise<boolean>;
198
+ /** 列出指定包指定动作在存储中的状态键名列表 */
199
+ list(packageId: string, actionId: string, options?: StateScopeOptions): Promise<string[]>;
200
+ /** 清空指定包指定动作在存储中的状态条目 */
201
+ clear(packageId: string, actionId: string, options?: StateScopeOptions): Promise<number>;
202
+ /** 列出指定包在存储中的状态条目(含完整元数据) */
203
+ listEntries?(packageId: string, options?: any): Promise<StateEntry[]>;
204
+ }
205
+ /**
206
+ * ActionDock 统一聚合服务端口契约。
207
+ */
208
+ export interface ActionDockService {
209
+ /** 获取所有包的基础信息概览 */
210
+ info(): Promise<PackageInfo[]>;
211
+ /** 发现服务端口 */
212
+ discovery: DiscoveryPort;
213
+ /** 执行服务端口 */
214
+ execution: ExecutionPort;
215
+ /** 运行记录服务端口 */
216
+ runs: RunsPort;
217
+ /** 执行事件流服务端口(可选,若通道不支持流式事件则为 undefined) */
218
+ events?: EventsPort;
219
+ /** 管理服务端口(可选,若服务端未开启管理能力则为 undefined) */
220
+ management?: {
221
+ config: ConfigPort;
222
+ state: StatePort;
223
+ };
224
+ /** 关闭服务并释放底层关联资源 */
225
+ close(options?: {
226
+ timeoutMs?: number;
227
+ graceMs?: number;
228
+ }): Promise<void>;
229
+ }
230
+ /**
231
+ * 创建 ActionDock 本地服务选项。
232
+ */
233
+ export interface CreateActionDockOptions {
234
+ /** 模式类型(可选) */
235
+ type?: "local";
236
+ /** 单包 PackageRuntime 初始化配置 */
237
+ runtimeOptions?: PackageRuntimeOptions;
238
+ /** 宿主 Host 初始化配置 */
239
+ hostOptions?: ActionDockHostOptions;
240
+ /** 当前工程根目录绝对路径 */
241
+ projectRoot?: string;
242
+ /** 是否自动加载当前工程(默认为 true) */
243
+ autoLoadCurrentProject?: boolean;
244
+ /** 预注册包配置列表(PackageRuntime 实例、PackageRuntimeOptions 配置或包目录绝对物理路径) */
245
+ packages?: Array<PackageRuntime | PackageRuntimeOptions | string>;
246
+ /** 自定义 ActionDock 家目录 */
247
+ customHome?: string;
248
+ /** 是否采用纯内存运行模式 */
249
+ inMemory?: boolean;
250
+ /** 自定义全局数据存储目录 */
251
+ dataDir?: string;
252
+ /** 是否扫描已软链接的外部包 */
253
+ scanLinkedPackages?: boolean;
254
+ /** 运行时平台适配 */
255
+ platform?: RuntimePlatform;
256
+ /** 是否以数据目录持有者身份打开本地存储 */
257
+ recoverOrphans?: boolean;
258
+ /** 是否开启管理端口(默认 true) */
259
+ enableManagement?: boolean;
260
+ }
261
+ /**
262
+ * 连接 ActionDock 远程服务选项。
263
+ *
264
+ * 与 RemoteServiceOptions 字段同源:远程服务连接配置为单一事实源,
265
+ * 此处仅放宽 serverUrl 必选性并补充独立家目录差异字段,公开形状不变。
266
+ */
267
+ export interface ConnectActionDockOptions extends Omit<RemoteServiceOptions, "serverUrl"> {
268
+ /** 远端 ActionDock 服务 HTTP 根地址(连接入口负责解析,此处可缺省) */
269
+ serverUrl?: string;
270
+ /** 自定义 ActionDock 家目录(用于读取自定义位置 profiles.json) */
271
+ customHome?: string;
272
+ }
@@ -0,0 +1,32 @@
1
+ import { ActionDockError, PROTOCOL_UNSUPPORTED, SERVICE_RESULT_UNKNOWN, SERVICE_CLOSED, } from "../errors.js";
2
+ /**
3
+ * 统一协议版本常量。
4
+ */
5
+ export const ACTIONDOCK_PROTOCOL_VERSION = "2.0";
6
+ /**
7
+ * 服务端/通信协议错误码常量(单一事实源引用自 errors.ts)。
8
+ */
9
+ export { PROTOCOL_UNSUPPORTED, SERVICE_RESULT_UNKNOWN, SERVICE_CLOSED };
10
+ /**
11
+ * 结构化服务通信异常类。
12
+ */
13
+ export class ServiceError extends ActionDockError {
14
+ details;
15
+ constructor(code, message, details) {
16
+ super(code, message, details);
17
+ this.name = "ServiceError";
18
+ this.details = details;
19
+ Object.setPrototypeOf(this, ServiceError.prototype);
20
+ }
21
+ }
22
+ /**
23
+ * 服务关闭超时异常类。
24
+ */
25
+ export class CloseTimeoutError extends Error {
26
+ runIds;
27
+ constructor(message = "Service close operation timed out", runIds) {
28
+ super(message);
29
+ this.name = "CloseTimeoutError";
30
+ this.runIds = runIds;
31
+ }
32
+ }
@@ -2,6 +2,7 @@ import { existsSync, mkdirSync, renameSync, statSync, writeFileSync } from "node
2
2
  import { hostname } from "node:os";
3
3
  import { dirname, join } from "node:path";
4
4
  import { randomUUID } from "node:crypto";
5
+ import { DATA_DIR_IN_USE, DATA_DIR_RECOVERY_REQUIRED } from "../errors.js";
5
6
  import { acquireDirectoryLock, cleanStaleQuarantines, isProcessAlive, parseQuarantineTimestamp, safeReleaseLock as coreSafeReleaseLock, safeRemoveStaleReclaimGuard, safeRollbackLock, } from "./lock-core.js";
6
7
  const LOCK_DIR_NAME = ".actiondock.data.lock";
7
8
  export { isProcessAlive, parseQuarantineTimestamp, cleanStaleQuarantines, safeRemoveStaleReclaimGuard, safeRollbackLock, };
@@ -89,8 +90,12 @@ export class DataDirLock {
89
90
  renameSync(tmpPath, this.lockDirPath);
90
91
  }
91
92
  }
92
- catch {
93
- // 忽略刷新写入异常
93
+ catch (err) {
94
+ // 元数据刷新失败不可中断宿主启动,但绝不能静默吞没:childPids 是
95
+ // DATA_DIR_RECOVERY_REQUIRED 判定的唯一依据,丢失会使恢复决策退化为直接接管。
96
+ // 输出单行告警携带原因,保证降级事件可观测。
97
+ const reason = err instanceof Error ? err.message : String(err);
98
+ console.warn(`[actiondock] data dir lock metadata flush failed (lock='${this.lockDirPath}'): ${reason}`);
94
99
  }
95
100
  }
96
101
  /**
@@ -150,7 +155,7 @@ export class DataDirLock {
150
155
  acquireTimeoutMs: options.acquireTimeoutMs,
151
156
  createLockError(message) {
152
157
  const timeoutErr = new Error(message);
153
- timeoutErr.code = "DATA_DIR_IN_USE";
158
+ timeoutErr.code = DATA_DIR_IN_USE;
154
159
  return timeoutErr;
155
160
  },
156
161
  messages: {
@@ -166,14 +171,14 @@ export class DataDirLock {
166
171
  const holderPid = info.pid;
167
172
  if (isProcessAlive(holderPid)) {
168
173
  const inUseErr = new Error(`DATA_DIR_IN_USE: Data directory '${dataDir}' is in use by another active Host process (PID ${holderPid})`);
169
- inUseErr.code = "DATA_DIR_IN_USE";
174
+ inUseErr.code = DATA_DIR_IN_USE;
170
175
  throw inUseErr;
171
176
  }
172
177
  // 主进程已死亡,检查关联子进程存活状态
173
178
  const activeChildren = (info.childPids || []).filter((childPid) => isProcessAlive(childPid));
174
179
  if (activeChildren.length > 0) {
175
180
  const recoveryErr = new Error(`DATA_DIR_RECOVERY_REQUIRED: Data directory recovery required for '${dataDir}': previous host (PID ${holderPid}) exited but child processes (${activeChildren.join(", ")}) are still running`);
176
- recoveryErr.code = "DATA_DIR_RECOVERY_REQUIRED";
181
+ recoveryErr.code = DATA_DIR_RECOVERY_REQUIRED;
177
182
  throw recoveryErr;
178
183
  }
179
184
  },
@@ -1,7 +1,8 @@
1
1
  import { normalizeSqliteParams } from "./params.js";
2
+ import { NodeSqliteDriver } from "./sqlite-driver.js";
2
3
  import type { SqliteDriver } from "./types.js";
3
4
  export type SqliteDriverFactory = (dbPath: string) => SqliteDriver;
4
- export { normalizeSqliteParams };
5
+ export { normalizeSqliteParams, NodeSqliteDriver };
5
6
  /**
6
7
  * 创建默认 SQLite 驱动实例。
7
8
  * 基于 Node.js 原生 node:sqlite (DatabaseSync) 驱动实现,严格同步契约。
@@ -1,59 +1,10 @@
1
- import { createRequire } from "node:module";
2
1
  import { normalizeSqliteParams } from "./params.js";
3
- export { normalizeSqliteParams };
4
- /** ESM 环境下可用的 CommonJS require,用于动态加载 node:sqlite */
5
- const cjsRequire = createRequire(import.meta.url);
2
+ import { NodeSqliteDriver } from "./sqlite-driver.js";
3
+ export { normalizeSqliteParams, NodeSqliteDriver };
6
4
  /**
7
5
  * 创建默认 SQLite 驱动实例。
8
6
  * 基于 Node.js 原生 node:sqlite (DatabaseSync) 驱动实现,严格同步契约。
9
7
  */
10
8
  export function createDefaultSqliteDriver(dbPath) {
11
- try {
12
- const { DatabaseSync } = cjsRequire("node:sqlite");
13
- const db = new DatabaseSync(dbPath);
14
- return {
15
- exec(sql) {
16
- db.exec(sql);
17
- },
18
- prepare(sql) {
19
- const stmt = db.prepare(sql);
20
- return {
21
- run(...args) {
22
- const params = normalizeSqliteParams(args);
23
- const res = stmt.run(...params);
24
- return { changes: res.changes, lastInsertRowid: res.lastInsertRowid };
25
- },
26
- get(...args) {
27
- const params = normalizeSqliteParams(args);
28
- return stmt.get(...params);
29
- },
30
- all(...args) {
31
- const params = normalizeSqliteParams(args);
32
- return stmt.all(...params);
33
- },
34
- };
35
- },
36
- transaction(fn) {
37
- db.exec("BEGIN");
38
- try {
39
- const res = fn();
40
- if (res !== null && (typeof res === "object" || typeof res === "function") && typeof res.then === "function") {
41
- throw new Error("Async transactions are not allowed in SQLite");
42
- }
43
- db.exec("COMMIT");
44
- return res;
45
- }
46
- catch (e) {
47
- db.exec("ROLLBACK");
48
- throw e;
49
- }
50
- },
51
- close() {
52
- db.close();
53
- },
54
- };
55
- }
56
- catch (err) {
57
- throw new Error(`Failed to initialize SQLite driver: ${err?.message || String(err)}`);
58
- }
9
+ return new NodeSqliteDriver(dbPath);
59
10
  }
@@ -2,6 +2,7 @@ import type { RuntimeStorage } from "./types.js";
2
2
  export { DataDirLock, type DataDirLockInfo, isProcessAlive, } from "./data-dir-lock.js";
3
3
  export * from "./clock.js";
4
4
  export * from "./driver.js";
5
+ export * from "./sqlite-driver.js";
5
6
  export * from "./lazy.js";
6
7
  export * from "./mask.js";
7
8
  export * from "./params.js";
@@ -4,6 +4,7 @@ import { SqliteRuntimeStorage } from "./sqlite.js";
4
4
  export { DataDirLock, isProcessAlive, } from "./data-dir-lock.js";
5
5
  export * from "./clock.js";
6
6
  export * from "./driver.js";
7
+ export * from "./sqlite-driver.js";
7
8
  export * from "./lazy.js";
8
9
  export * from "./mask.js";
9
10
  export * from "./params.js";
@@ -1,3 +1,5 @@
1
+ import { isProcessAlive } from "../utils/process.js";
2
+ export { isProcessAlive };
1
3
  /**
2
4
  * 目录锁元数据通用契约。
3
5
  * 工程锁与数据目录锁共用同一物理布局,仅部分字段按场景取舍。
@@ -30,12 +32,6 @@ export interface ReclaimGuardState {
30
32
  holderPid?: number;
31
33
  guardToken?: string;
32
34
  }
33
- /**
34
- * 检查目标进程是否处于存活状态。
35
- *
36
- * @param pid 待检测的进程标识符
37
- */
38
- export declare function isProcessAlive(pid: number): boolean;
39
35
  /**
40
36
  * 读取排他锁元数据并执行宽限期检测。
41
37
  */
@@ -1,6 +1,10 @@
1
1
  import fs, { existsSync, mkdirSync, readdirSync, readFileSync, renameSync, rmSync, statSync, writeFileSync, } from "node:fs";
2
2
  import { basename, dirname, join } from "node:path";
3
3
  import { randomUUID } from "node:crypto";
4
+ import { isProcessAlive } from "../utils/process.js";
5
+ // isProcessAlive 已上移至 utils/process.ts(跨域通用谓词单一事实源),
6
+ // 此处仅保留 re-export 兼容旧引用路径
7
+ export { isProcessAlive };
4
8
  /**
5
9
  * 目录锁内核(单一事实源)。
6
10
  *
@@ -16,23 +20,6 @@ import { randomUUID } from "node:crypto";
16
20
  */
17
21
  const METADATA_FILE = "metadata.json";
18
22
  const RECLAIM_SUFFIX = ".reclaim";
19
- /**
20
- * 检查目标进程是否处于存活状态。
21
- *
22
- * @param pid 待检测的进程标识符
23
- */
24
- export function isProcessAlive(pid) {
25
- if (typeof pid !== "number" || isNaN(pid) || pid <= 0) {
26
- return false;
27
- }
28
- try {
29
- process.kill(pid, 0);
30
- return true;
31
- }
32
- catch (err) {
33
- return Boolean(err && err.code === "EPERM");
34
- }
35
- }
36
23
  /**
37
24
  * 同步休眠指定毫秒数。
38
25
  */
@@ -1,13 +1,7 @@
1
1
  /**
2
2
  * SQLite 绑定参数规范化共享纯函数。
3
3
  *
4
- * 单一事实源:主线程驱动(core 默认驱动与 runtime-node 的 NodeSqliteDriver)
5
- * 与 WorkerSqliteDriver 的 worker 内联脚本均使用本模块生成的同一份实现。
6
- *
7
- * 工程说明:worker 内联脚本以字符串形式 eval 执行、无法直接 import 模块,
8
- * 因此 worker 侧通过 Function.prototype.toString 将本函数源码序列化注入脚本。
9
- * 该函数必须保持完全自包含:仅依赖运行时全局 Buffer 与 Uint8Array,
10
- * 不得引用任何模块作用域内的其他标识符,也不得引入会被打包器改写的外部闭包,
11
- * 否则序列化注入后将在 worker 作用域内产生未定义引用。
4
+ * 单一事实源:各同步驱动(如 NodeSqliteDriver)统一使用本实现,
5
+ * 避免参数归一逻辑出现双实现漂移。
12
6
  */
13
7
  export declare function normalizeSqliteParams(args: any[]): any[];
@@ -1,14 +1,8 @@
1
1
  /**
2
2
  * SQLite 绑定参数规范化共享纯函数。
3
3
  *
4
- * 单一事实源:主线程驱动(core 默认驱动与 runtime-node 的 NodeSqliteDriver)
5
- * 与 WorkerSqliteDriver 的 worker 内联脚本均使用本模块生成的同一份实现。
6
- *
7
- * 工程说明:worker 内联脚本以字符串形式 eval 执行、无法直接 import 模块,
8
- * 因此 worker 侧通过 Function.prototype.toString 将本函数源码序列化注入脚本。
9
- * 该函数必须保持完全自包含:仅依赖运行时全局 Buffer 与 Uint8Array,
10
- * 不得引用任何模块作用域内的其他标识符,也不得引入会被打包器改写的外部闭包,
11
- * 否则序列化注入后将在 worker 作用域内产生未定义引用。
4
+ * 单一事实源:各同步驱动(如 NodeSqliteDriver)统一使用本实现,
5
+ * 避免参数归一逻辑出现双实现漂移。
12
6
  */
13
7
  export function normalizeSqliteParams(args) {
14
8
  if (!args || args.length === 0) {