@actiondock/core 2.7.0 → 2.9.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 (243) hide show
  1. package/README.md +77 -64
  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 +106 -10
  18. package/dist/errors.js +105 -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 -24
  33. package/dist/index.js +19 -23
  34. package/dist/input/advice.d.ts +5 -1
  35. package/dist/input/advice.js +163 -214
  36. package/dist/input/describe.d.ts +1 -1
  37. package/dist/input/flat-errors.d.ts +5 -6
  38. package/dist/input/flat-errors.js +6 -6
  39. package/dist/input/flat-materializer.js +42 -44
  40. package/dist/invocation/index.d.ts +2 -0
  41. package/dist/invocation/index.js +2 -0
  42. package/dist/invocation/policy.d.ts +157 -0
  43. package/dist/invocation/policy.js +231 -0
  44. package/dist/invocation/types.d.ts +172 -0
  45. package/dist/invocation/types.js +97 -0
  46. package/dist/ipc/diagnostic.d.ts +0 -12
  47. package/dist/ipc/diagnostic.js +0 -21
  48. package/dist/ipc/host.d.ts +4 -4
  49. package/dist/ipc/host.js +44 -47
  50. package/dist/ipc/index.d.ts +1 -1
  51. package/dist/ipc/index.js +1 -1
  52. package/dist/ipc/service.d.ts +40 -0
  53. package/dist/ipc/service.js +349 -0
  54. package/dist/ipc/types.d.ts +21 -15
  55. package/dist/node/index.d.ts +1 -0
  56. package/dist/node/index.js +1 -0
  57. package/dist/node/module-loader.d.ts +63 -0
  58. package/dist/node/module-loader.js +112 -0
  59. package/dist/package/index.d.ts +23 -0
  60. package/dist/package/index.js +18 -0
  61. package/dist/{app/app.d.ts → package/runtime.d.ts} +41 -20
  62. package/dist/{app/app.js → package/runtime.js} +140 -95
  63. package/dist/{app → package}/static-index.js +58 -41
  64. package/dist/package/storage-view.d.ts +13 -0
  65. package/dist/package/storage-view.js +22 -0
  66. package/dist/{app → package}/types.d.ts +76 -57
  67. package/dist/package/types.js +22 -0
  68. package/dist/platform/index.d.ts +1 -1
  69. package/dist/platform/index.js +1 -1
  70. package/dist/platform/node.d.ts +48 -0
  71. package/dist/platform/node.js +96 -0
  72. package/dist/platform/types.d.ts +0 -9
  73. package/dist/process/control-arbiter.d.ts +2 -1
  74. package/dist/process/control-arbiter.js +1 -2
  75. package/dist/process/driver.d.ts +9 -8
  76. package/dist/process/driver.js +11 -22
  77. package/dist/process/index.d.ts +2 -0
  78. package/dist/process/index.js +2 -0
  79. package/dist/process/managed-record.d.ts +2 -2
  80. package/dist/process/process-driver.d.ts +109 -0
  81. package/dist/process/process-driver.js +650 -0
  82. package/dist/process/process-executor.d.ts +47 -0
  83. package/dist/process/process-executor.js +296 -0
  84. package/dist/process/process-manager.js +48 -26
  85. package/dist/process/run-executor.js +12 -12
  86. package/dist/profile/client-actions.js +2 -2
  87. package/dist/profile/client-health.js +2 -2
  88. package/dist/profile/client-query.js +5 -6
  89. package/dist/profile/client-transport.d.ts +19 -17
  90. package/dist/profile/client-transport.js +47 -80
  91. package/dist/profile/client.d.ts +2 -2
  92. package/dist/profile/client.js +1 -1
  93. package/dist/profile/index.d.ts +1 -0
  94. package/dist/profile/index.js +1 -0
  95. package/dist/profile/manager.d.ts +5 -0
  96. package/dist/profile/manager.js +41 -6
  97. package/dist/project/closure.js +2 -2
  98. package/dist/project/index.d.ts +8 -1
  99. package/dist/project/index.js +10 -1
  100. package/dist/project/init.js +2 -2
  101. package/dist/project/loader.d.ts +1 -1
  102. package/dist/project/loader.js +26 -29
  103. package/dist/project/transactions.js +5 -10
  104. package/dist/project/types.d.ts +5 -0
  105. package/dist/registry/index.d.ts +3 -1
  106. package/dist/registry/index.js +2 -1
  107. package/dist/registry/lock.d.ts +28 -7
  108. package/dist/registry/lock.js +136 -16
  109. package/dist/registry/registry.d.ts +1 -5
  110. package/dist/registry/registry.js +1 -53
  111. package/dist/registry/scan.d.ts +0 -15
  112. package/dist/registry/scan.js +0 -59
  113. package/dist/registry/store.d.ts +42 -0
  114. package/dist/registry/store.js +43 -0
  115. package/dist/registry/types.d.ts +0 -24
  116. package/dist/runtime/action-collection.d.ts +1 -1
  117. package/dist/runtime/action-registry.d.ts +0 -4
  118. package/dist/runtime/action-registry.js +0 -7
  119. package/dist/runtime/context.js +5 -11
  120. package/dist/runtime/events.js +3 -6
  121. package/dist/runtime/identity.d.ts +22 -0
  122. package/dist/runtime/identity.js +10 -0
  123. package/dist/runtime/index.d.ts +1 -2
  124. package/dist/runtime/index.js +1 -2
  125. package/dist/runtime/module-loader.d.ts +2 -34
  126. package/dist/runtime/module-loader.js +1 -16
  127. package/dist/runtime/process.d.ts +6 -24
  128. package/dist/runtime/process.js +1 -118
  129. package/dist/runtime/run-persistence.js +2 -5
  130. package/dist/runtime/runner.d.ts +33 -93
  131. package/dist/runtime/runner.js +132 -364
  132. package/dist/runtime/standalone.d.ts +23 -8
  133. package/dist/runtime/standalone.js +100 -147
  134. package/dist/server/body.d.ts +16 -8
  135. package/dist/server/body.js +33 -16
  136. package/dist/server/dispatcher.d.ts +6 -10
  137. package/dist/server/dispatcher.js +24 -32
  138. package/dist/server/http-server.d.ts +87 -0
  139. package/dist/server/http-server.js +304 -0
  140. package/dist/server/index.d.ts +12 -0
  141. package/dist/server/index.js +11 -0
  142. package/dist/server/mcp-endpoint.d.ts +61 -0
  143. package/dist/server/mcp-endpoint.js +118 -0
  144. package/dist/server/policy.d.ts +138 -0
  145. package/dist/server/policy.js +368 -0
  146. package/dist/server/routes/actions.js +114 -64
  147. package/dist/server/routes/common.d.ts +18 -33
  148. package/dist/server/routes/common.js +45 -65
  149. package/dist/server/routes/config.d.ts +1 -1
  150. package/dist/server/routes/config.js +55 -65
  151. package/dist/server/routes/doctor.d.ts +1 -1
  152. package/dist/server/routes/doctor.js +13 -21
  153. package/dist/server/routes/health.d.ts +1 -1
  154. package/dist/server/routes/health.js +4 -5
  155. package/dist/server/routes/info.d.ts +2 -2
  156. package/dist/server/routes/info.js +17 -24
  157. package/dist/server/routes/playbooks.js +23 -36
  158. package/dist/server/routes/runs.js +151 -141
  159. package/dist/server/routes/state.d.ts +1 -1
  160. package/dist/server/routes/state.js +64 -63
  161. package/dist/server/security.d.ts +11 -0
  162. package/dist/server/security.js +36 -19
  163. package/dist/server/server.d.ts +2 -2
  164. package/dist/server/server.js +224 -238
  165. package/dist/server/types.d.ts +68 -21
  166. package/dist/service/factory.d.ts +12 -0
  167. package/dist/service/factory.js +85 -0
  168. package/dist/{target → service}/index.d.ts +1 -1
  169. package/dist/{target → service}/index.js +1 -1
  170. package/dist/service/local.d.ts +27 -0
  171. package/dist/service/local.js +138 -0
  172. package/dist/{target → service}/remote-errors.d.ts +3 -6
  173. package/dist/service/remote-errors.js +38 -0
  174. package/dist/{target → service}/remote-polling.d.ts +2 -2
  175. package/dist/{target → service}/remote-polling.js +8 -8
  176. package/dist/service/remote.d.ts +34 -0
  177. package/dist/service/remote.js +634 -0
  178. package/dist/service/sse-stream.d.ts +24 -0
  179. package/dist/service/sse-stream.js +139 -0
  180. package/dist/service/types.d.ts +272 -0
  181. package/dist/service/types.js +32 -0
  182. package/dist/storage/data-dir-lock.js +10 -5
  183. package/dist/storage/driver.d.ts +2 -1
  184. package/dist/storage/driver.js +3 -52
  185. package/dist/storage/index.d.ts +1 -0
  186. package/dist/storage/index.js +1 -0
  187. package/dist/storage/lock-core.d.ts +2 -6
  188. package/dist/storage/lock-core.js +4 -17
  189. package/dist/storage/params.d.ts +2 -8
  190. package/dist/storage/params.js +2 -8
  191. package/dist/storage/sqlite-driver.d.ts +40 -0
  192. package/dist/storage/sqlite-driver.js +116 -0
  193. package/dist/storage/sqlite.js +21 -6
  194. package/dist/storage/types.d.ts +4 -4
  195. package/dist/storage/types.js +2 -2
  196. package/dist/utils/index.d.ts +53 -0
  197. package/dist/utils/index.js +99 -4
  198. package/dist/utils/process.d.ts +10 -0
  199. package/dist/utils/process.js +21 -0
  200. package/dist/version.d.ts +1 -1
  201. package/dist/version.js +1 -1
  202. package/package.json +41 -3
  203. package/dist/app/index.d.ts +0 -2
  204. package/dist/app/index.js +0 -2
  205. package/dist/app/types.js +0 -1
  206. package/dist/catalog/action-index.d.ts +0 -9
  207. package/dist/catalog/action-index.js +0 -95
  208. package/dist/catalog/action-resolver.d.ts +0 -20
  209. package/dist/catalog/action-resolver.js +0 -95
  210. package/dist/catalog/location-registry.d.ts +0 -15
  211. package/dist/catalog/location-registry.js +0 -138
  212. package/dist/catalog/package-catalog.d.ts +0 -7
  213. package/dist/catalog/package-catalog.js +0 -77
  214. package/dist/catalog/types.d.ts +0 -68
  215. package/dist/catalog/types.js +0 -1
  216. package/dist/export/index.d.ts +0 -1
  217. package/dist/export/index.js +0 -1
  218. package/dist/export/templates.d.ts +0 -71
  219. package/dist/export/templates.js +0 -635
  220. package/dist/ipc/target.d.ts +0 -74
  221. package/dist/ipc/target.js +0 -365
  222. package/dist/platform/default.d.ts +0 -38
  223. package/dist/platform/default.js +0 -78
  224. package/dist/project/resolver.d.ts +0 -116
  225. package/dist/project/resolver.js +0 -376
  226. package/dist/registry/resolve.d.ts +0 -62
  227. package/dist/registry/resolve.js +0 -195
  228. package/dist/runtime/execution-manager.d.ts +0 -48
  229. package/dist/runtime/execution-manager.js +0 -66
  230. package/dist/runtime/package-runner-factory.d.ts +0 -82
  231. package/dist/runtime/package-runner-factory.js +0 -186
  232. package/dist/target/local.d.ts +0 -53
  233. package/dist/target/local.js +0 -349
  234. package/dist/target/remote-errors.js +0 -51
  235. package/dist/target/remote.d.ts +0 -86
  236. package/dist/target/remote.js +0 -818
  237. package/dist/target/target.d.ts +0 -6
  238. package/dist/target/target.js +0 -37
  239. package/dist/target/types.d.ts +0 -261
  240. package/dist/target/types.js +0 -35
  241. /package/dist/{app → package}/static-index.d.ts +0 -0
  242. /package/dist/{target → service}/sse-parser.d.ts +0 -0
  243. /package/dist/{target → service}/sse-parser.js +0 -0
@@ -1,7 +1,7 @@
1
1
  import { type ActionDefinition } from "@actiondock/sdk";
2
- import type { ActionSpec } from "../app/types.js";
2
+ import type { ActionSpec } from "../package/types.js";
3
3
  import type { ConfigItemDefinition } from "../project/types.js";
4
- import type { ActionDockTarget } from "../target/types.js";
4
+ import type { ActionDockService } from "../service/types.js";
5
5
  /**
6
6
  * 退出状态码常量。
7
7
  */
@@ -28,8 +28,8 @@ export interface StandaloneDispatcherOptions {
28
28
  version: string;
29
29
  /** 描述信息 */
30
30
  description?: string;
31
- /** 已构造的 ActionDockTarget 门面(若未传入则依据 actions/config 自动创建) */
32
- target?: ActionDockTarget;
31
+ /** 已构造的 ActionDockService 服务(若未传入则依据 actions/config 自动创建) */
32
+ service?: ActionDockService;
33
33
  /** 声明的配置依赖定义(兼容选项) */
34
34
  configDefs?: Record<string, ConfigItemDefinition>;
35
35
  config?: Record<string, ConfigItemDefinition>;
@@ -56,7 +56,7 @@ export interface StandaloneDispatcherOptions {
56
56
  *
57
57
  * 职责:
58
58
  * 1. 负责轻量参数解析、诊断输出渲染与统一退出码管理。
59
- * 2. 统一面向 ActionDockTarget 门面调用能力(支持本地 LocalTarget 与 IPC 监督隔离 Target)。
59
+ * 2. 统一面向 ActionDockService 服务调用能力。
60
60
  * 3. 严格遵循 ActionDock 2.0 输出协议约定:结果数据专走 stdout,日志与错误专走 stderr。
61
61
  * 4. 独立入口拒绝异步启动语义,显式拦截并返回 STANDALONE_ASYNC_UNSUPPORTED。
62
62
  */
@@ -65,7 +65,22 @@ export declare class StandaloneDispatcher {
65
65
  constructor(options: StandaloneDispatcherOptions);
66
66
  private writeOut;
67
67
  private writeErr;
68
- private createLocalTarget;
68
+ /**
69
+ * 统一错误输出辅助方法。
70
+ *
71
+ * JSON 模式向 stdout 输出两空格缩进的标准错误结构;
72
+ * 纯文本模式向 stderr 输出单行错误消息(默认携带 Error: 前缀)。
73
+ * 消息文本与退出码由调用方逐字给定,输出字节严格保持不变。
74
+ *
75
+ * @param isJson 是否处于 JSON 输出模式
76
+ * @param code 错误码
77
+ * @param message JSON 模式错误消息(兼作纯文本默认消息主体)
78
+ * @param exitCode 调用方应返回的退出状态码
79
+ * @param options 可选项:textMessage 覆盖纯文本消息全文;details 为 JSON 模式可选结构化详情
80
+ * @returns 透传 exitCode 供调用方直接返回
81
+ */
82
+ private emitError;
83
+ private createLocalService;
69
84
  /**
70
85
  * 解析命令行参数并分发执行对应子命令。
71
86
  *
@@ -80,9 +95,9 @@ export declare class StandaloneDispatcher {
80
95
  private handleConfig;
81
96
  private handleState;
82
97
  /**
83
- * 判定配置读取异常是否为目标层能力缺失(键未配置语义)而非内部故障。
98
+ * 判定配置读取异常是否为服务能力缺失(键未配置语义)而非内部故障。
84
99
  */
85
- private isTargetCapabilityError;
100
+ private isServiceCapabilityError;
86
101
  /**
87
102
  * 解析携带命名空间前缀的状态键参数:委托 sdk 单一事实源 decodeStateKey。
88
103
  *
@@ -1,6 +1,6 @@
1
1
  import { decodeStateKey } from "@actiondock/sdk";
2
2
  import { filterWithFallbackInfo } from "../filter/index.js";
3
- import { createActionDockTarget } from "../target/target.js";
3
+ import { createActionDock } from "../service/factory.js";
4
4
  import { STANDALONE_ASYNC_UNSUPPORTED } from "../errors.js";
5
5
  import { resolveActionInput, formatActionDetail, buildActionDescribePayload, mapInputValidationFailure, } from "../input/index.js";
6
6
  import { validateActionInputValue } from "../json/value-validator.js";
@@ -20,7 +20,7 @@ export const ExitCode = {
20
20
  *
21
21
  * 职责:
22
22
  * 1. 负责轻量参数解析、诊断输出渲染与统一退出码管理。
23
- * 2. 统一面向 ActionDockTarget 门面调用能力(支持本地 LocalTarget 与 IPC 监督隔离 Target)。
23
+ * 2. 统一面向 ActionDockService 服务调用能力。
24
24
  * 3. 严格遵循 ActionDock 2.0 输出协议约定:结果数据专走 stdout,日志与错误专走 stderr。
25
25
  * 4. 独立入口拒绝异步启动语义,显式拦截并返回 STANDALONE_ASYNC_UNSUPPORTED。
26
26
  */
@@ -45,18 +45,49 @@ export class StandaloneDispatcher {
45
45
  console.error(msg);
46
46
  }
47
47
  }
48
- async createLocalTarget(dataDir, configOverrides = {}) {
49
- if (this.options.target) {
50
- return { target: this.options.target, ownsTarget: false };
48
+ /**
49
+ * 统一错误输出辅助方法。
50
+ *
51
+ * JSON 模式向 stdout 输出两空格缩进的标准错误结构;
52
+ * 纯文本模式向 stderr 输出单行错误消息(默认携带 Error: 前缀)。
53
+ * 消息文本与退出码由调用方逐字给定,输出字节严格保持不变。
54
+ *
55
+ * @param isJson 是否处于 JSON 输出模式
56
+ * @param code 错误码
57
+ * @param message JSON 模式错误消息(兼作纯文本默认消息主体)
58
+ * @param exitCode 调用方应返回的退出状态码
59
+ * @param options 可选项:textMessage 覆盖纯文本消息全文;details 为 JSON 模式可选结构化详情
60
+ * @returns 透传 exitCode 供调用方直接返回
61
+ */
62
+ emitError(isJson, code, message, exitCode, options) {
63
+ if (isJson) {
64
+ const details = options?.details;
65
+ this.writeOut(JSON.stringify({
66
+ ok: false,
67
+ error: {
68
+ code,
69
+ message,
70
+ ...(details !== undefined ? { details } : {}),
71
+ },
72
+ }, null, 2));
51
73
  }
52
- if (this.options.inMemory && this.options._sharedTarget) {
53
- return { target: this.options._sharedTarget, ownsTarget: false };
74
+ else {
75
+ this.writeErr(options?.textMessage ?? `Error: ${message}`);
76
+ }
77
+ return exitCode;
78
+ }
79
+ async createLocalService(dataDir, configOverrides = {}) {
80
+ if (this.options.service) {
81
+ return { service: this.options.service, ownsService: false };
82
+ }
83
+ if (this.options.inMemory && this.options._sharedService) {
84
+ return { service: this.options._sharedService, ownsService: false };
54
85
  }
55
86
  // 归一化 Action 集合:单一入口统一三形态输入
56
87
  const { actionsMap, actionSpecs } = normalizeActionCollection(this.options.actions);
57
88
  // projectConfig.actions 要求 manifest 形态,字段语义兼容,此处显式收敛类型
58
89
  const manifestActions = actionSpecs;
59
- const appOptions = {
90
+ const runtimeOptions = {
60
91
  projectConfig: {
61
92
  id: this.options.packageId,
62
93
  name: this.options.packageId,
@@ -71,15 +102,14 @@ export class StandaloneDispatcher {
71
102
  customHome: this.options.customHome,
72
103
  inMemory: this.options.inMemory,
73
104
  };
74
- const target = await createActionDockTarget({
75
- type: "local",
76
- appOptions,
105
+ const service = await createActionDock({
106
+ runtimeOptions,
77
107
  });
78
108
  if (this.options.inMemory) {
79
- this.options._sharedTarget = target;
80
- return { target, ownsTarget: false };
109
+ this.options._sharedService = service;
110
+ return { service, ownsService: false };
81
111
  }
82
- return { target, ownsTarget: true };
112
+ return { service, ownsService: true };
83
113
  }
84
114
  /**
85
115
  * 解析命令行参数并分发执行对应子命令。
@@ -124,20 +154,9 @@ export class StandaloneDispatcher {
124
154
  const subArgs = filteredArgs.slice(1);
125
155
  // 2. 独立入口拒绝异步启动语义
126
156
  if (controlArgs.includes("--async")) {
127
- const isJson = controlArgs.includes("--json");
128
- if (isJson) {
129
- this.writeOut(JSON.stringify({
130
- ok: false,
131
- error: {
132
- code: STANDALONE_ASYNC_UNSUPPORTED,
133
- message: "Async execution is not supported in standalone single-execution binaries. Use 'ad serve' or remote target.",
134
- },
135
- }, null, 2));
136
- }
137
- else {
138
- this.writeErr(`Error [${STANDALONE_ASYNC_UNSUPPORTED}]: Async execution is not supported in standalone single-execution binaries.`);
139
- }
140
- return ExitCode.FAILURE;
157
+ return this.emitError(controlArgs.includes("--json"), STANDALONE_ASYNC_UNSUPPORTED, "Async execution is not supported in standalone single-execution binaries. Use 'ad serve' or remote target.", ExitCode.FAILURE, {
158
+ textMessage: `Error [${STANDALONE_ASYNC_UNSUPPORTED}]: Async execution is not supported in standalone single-execution binaries.`,
159
+ });
141
160
  }
142
161
  // 3. 版本与帮助快速处理(无需初始化 Host / Storage)
143
162
  if (command === "-v" || command === "-V" || command === "--version" || command === "version") {
@@ -148,35 +167,35 @@ export class StandaloneDispatcher {
148
167
  this.printHelp();
149
168
  return ExitCode.SUCCESS;
150
169
  }
151
- let target;
152
- let ownsTarget = false;
170
+ let service;
171
+ let ownsService = false;
153
172
  try {
154
- const targetRes = await this.createLocalTarget(dataDir, configOverrides);
155
- target = targetRes.target;
156
- ownsTarget = targetRes.ownsTarget;
173
+ const serviceRes = await this.createLocalService(dataDir, configOverrides);
174
+ service = serviceRes.service;
175
+ ownsService = serviceRes.ownsService;
157
176
  }
158
177
  catch (err) {
159
- this.writeErr(`Error initializing standalone target: ${err?.message || err}`);
178
+ this.writeErr(`Error initializing standalone service: ${err?.message || err}`);
160
179
  return ExitCode.FAILURE;
161
180
  }
162
181
  try {
163
182
  let code;
164
183
  switch (command) {
165
184
  case "list":
166
- code = await this.handleList(target, subArgs);
185
+ code = await this.handleList(service, subArgs);
167
186
  break;
168
187
  case "describe":
169
188
  case "show":
170
- code = await this.handleDescribe(target, subArgs);
189
+ code = await this.handleDescribe(service, subArgs);
171
190
  break;
172
191
  case "run":
173
- code = await this.handleRun(target, subArgs, actionArgs, control?.signal);
192
+ code = await this.handleRun(service, subArgs, actionArgs, control?.signal);
174
193
  break;
175
194
  case "config":
176
- code = await this.handleConfig(target, subArgs);
195
+ code = await this.handleConfig(service, subArgs);
177
196
  break;
178
197
  case "state":
179
- code = await this.handleState(target, subArgs);
198
+ code = await this.handleState(service, subArgs);
180
199
  break;
181
200
  default:
182
201
  this.writeErr(`Unknown command: '${command}'`);
@@ -190,19 +209,19 @@ export class StandaloneDispatcher {
190
209
  }
191
210
  catch (err) {
192
211
  if (control?.cancellationSource === "sigint" &&
193
- (control?.signal?.aborted || err?.name === "AbortError" || err?.message?.includes("SIGINT"))) {
212
+ (control?.signal?.aborted || err?.name === "AbortError" || err?.code === "SIGINT_INTERRUPTED")) {
194
213
  return ExitCode.SIGINT;
195
214
  }
196
215
  this.writeErr(`Error: ${err?.message || err}`);
197
216
  return ExitCode.FAILURE;
198
217
  }
199
218
  finally {
200
- if (ownsTarget) {
201
- await target.close();
219
+ if (ownsService) {
220
+ await service.close();
202
221
  }
203
222
  }
204
223
  }
205
- async handleList(target, subArgs) {
224
+ async handleList(service, subArgs) {
206
225
  const isJson = subArgs.includes("--json");
207
226
  const noFallback = subArgs.includes("--no-fallback");
208
227
  let intent;
@@ -224,7 +243,7 @@ export class StandaloneDispatcher {
224
243
  }
225
244
  }
226
245
  const effectiveIntent = intent || (positionalPatterns.length > 0 ? positionalPatterns.join("|") : undefined);
227
- const actions = await target.listActions();
246
+ const actions = await service.discovery.listActions();
228
247
  const list = actions.map((a) => ({
229
248
  id: a.id,
230
249
  description: a.description || "",
@@ -242,42 +261,18 @@ export class StandaloneDispatcher {
242
261
  }
243
262
  return ExitCode.SUCCESS;
244
263
  }
245
- async handleDescribe(target, subArgs) {
264
+ async handleDescribe(service, subArgs) {
246
265
  const id = subArgs.find((a) => !a.startsWith("-"));
247
266
  const isJson = subArgs.includes("--json");
248
267
  if (!id) {
249
- if (isJson) {
250
- this.writeOut(JSON.stringify({
251
- ok: false,
252
- error: {
253
- code: "INVALID_ARGUMENT",
254
- message: "Action ID is required for describe",
255
- },
256
- }, null, 2));
257
- }
258
- else {
259
- this.writeErr("Error: Action ID is required for describe");
260
- }
261
- return ExitCode.INVALID_ARGUMENT;
268
+ return this.emitError(isJson, "INVALID_ARGUMENT", "Action ID is required for describe", ExitCode.INVALID_ARGUMENT);
262
269
  }
263
270
  let action;
264
271
  try {
265
- action = await target.describeAction(id);
272
+ action = await service.discovery.describeAction(id);
266
273
  }
267
274
  catch {
268
- if (isJson) {
269
- this.writeOut(JSON.stringify({
270
- ok: false,
271
- error: {
272
- code: "INVALID_ARGUMENT",
273
- message: `Action '${id}' not found`,
274
- },
275
- }, null, 2));
276
- }
277
- else {
278
- this.writeErr(`Error: Action '${id}' not found`);
279
- }
280
- return ExitCode.INVALID_ARGUMENT;
275
+ return this.emitError(isJson, "INVALID_ARGUMENT", `Action '${id}' not found`, ExitCode.INVALID_ARGUMENT);
281
276
  }
282
277
  const payload = buildActionDescribePayload(action, {
283
278
  packageId: this.options.packageId,
@@ -290,23 +285,11 @@ export class StandaloneDispatcher {
290
285
  }
291
286
  return ExitCode.SUCCESS;
292
287
  }
293
- async handleRun(target, subArgs, actionArgs, signal) {
288
+ async handleRun(service, subArgs, actionArgs, signal) {
294
289
  const isJson = subArgs.includes("--json");
295
290
  const id = subArgs.find((a) => !a.startsWith("-"));
296
291
  if (!id) {
297
- if (isJson) {
298
- this.writeOut(JSON.stringify({
299
- ok: false,
300
- error: {
301
- code: "INVALID_ARGUMENT",
302
- message: "Error: Action ID is required for run",
303
- },
304
- }, null, 2));
305
- }
306
- else {
307
- this.writeErr("Error: Action ID is required for run");
308
- }
309
- return ExitCode.INVALID_ARGUMENT;
292
+ return this.emitError(isJson, "INVALID_ARGUMENT", "Error: Action ID is required for run", ExitCode.INVALID_ARGUMENT, { textMessage: "Error: Action ID is required for run" });
310
293
  }
311
294
  let inputStr;
312
295
  let inputFile;
@@ -318,19 +301,7 @@ export class StandaloneDispatcher {
318
301
  timeoutMs = parseDuration(subArgs[++i]);
319
302
  }
320
303
  catch (err) {
321
- if (isJson) {
322
- this.writeOut(JSON.stringify({
323
- ok: false,
324
- error: {
325
- code: "INVALID_ARGUMENT",
326
- message: `Invalid timeout format: ${err?.message || err}`,
327
- },
328
- }, null, 2));
329
- }
330
- else {
331
- this.writeErr(`Error: Invalid timeout format: ${err?.message || err}`);
332
- }
333
- return ExitCode.INVALID_ARGUMENT;
304
+ return this.emitError(isJson, "INVALID_ARGUMENT", `Invalid timeout format: ${err?.message || err}`, ExitCode.INVALID_ARGUMENT);
334
305
  }
335
306
  }
336
307
  else if (arg.startsWith("--timeout=")) {
@@ -338,19 +309,7 @@ export class StandaloneDispatcher {
338
309
  timeoutMs = parseDuration(arg.slice(10));
339
310
  }
340
311
  catch (err) {
341
- if (isJson) {
342
- this.writeOut(JSON.stringify({
343
- ok: false,
344
- error: {
345
- code: "INVALID_ARGUMENT",
346
- message: `Invalid timeout format: ${err?.message || err}`,
347
- },
348
- }, null, 2));
349
- }
350
- else {
351
- this.writeErr(`Error: Invalid timeout format: ${err?.message || err}`);
352
- }
353
- return ExitCode.INVALID_ARGUMENT;
312
+ return this.emitError(isJson, "INVALID_ARGUMENT", `Invalid timeout format: ${err?.message || err}`, ExitCode.INVALID_ARGUMENT);
354
313
  }
355
314
  }
356
315
  else if (arg === "--input" && i + 1 < subArgs.length) {
@@ -380,22 +339,11 @@ export class StandaloneDispatcher {
380
339
  }
381
340
  }
382
341
  catch (err) {
383
- if (isJson) {
384
- this.writeOut(JSON.stringify({
385
- ok: false,
386
- error: {
387
- code: err?.code || "INVALID_ARGUMENT",
388
- message: err?.message || String(err),
389
- ...(err?.details !== undefined ? { details: err.details } : {}),
390
- },
391
- }, null, 2));
392
- }
393
- else {
394
- this.writeErr(`Error: ${err?.message || String(err)}`);
395
- }
396
- return ExitCode.INVALID_ARGUMENT;
342
+ return this.emitError(isJson, err?.code || "INVALID_ARGUMENT", err?.message || String(err), ExitCode.INVALID_ARGUMENT, {
343
+ details: err?.details,
344
+ });
397
345
  }
398
- const result = await target.runAction(id, input, {
346
+ const result = await service.execution.run(id, input, {
399
347
  signal,
400
348
  timeoutMs,
401
349
  });
@@ -484,10 +432,14 @@ export class StandaloneDispatcher {
484
432
  }
485
433
  return result.ok ? ExitCode.SUCCESS : ExitCode.FAILURE;
486
434
  }
487
- async handleConfig(target, subArgs) {
435
+ async handleConfig(service, subArgs) {
488
436
  const sub = subArgs[0] || "list";
437
+ if (!service.management) {
438
+ this.writeErr("Error: management port is not enabled on this service");
439
+ return ExitCode.FAILURE;
440
+ }
489
441
  if (sub === "list") {
490
- const views = await target.listConfig(this.options.packageId);
442
+ const views = await service.management.config.list(this.options.packageId);
491
443
  const dict = {};
492
444
  for (const v of views) {
493
445
  if (v.configured && v.value !== undefined) {
@@ -504,13 +456,13 @@ export class StandaloneDispatcher {
504
456
  return ExitCode.INVALID_ARGUMENT;
505
457
  }
506
458
  try {
507
- const item = await target.getConfig(this.options.packageId, key);
459
+ const item = await service.management.config.get(this.options.packageId, key);
508
460
  this.writeOut(item.configured ? JSON.stringify(item.value) : "undefined");
509
461
  return ExitCode.SUCCESS;
510
462
  }
511
463
  catch (err) {
512
- // 目标层能力缺失(如远端未开启管理接口)视为键未配置,输出 undefined
513
- if (this.isTargetCapabilityError(err)) {
464
+ // 服务能力缺失(如远端未开启管理接口)视为键未配置,输出 undefined
465
+ if (this.isServiceCapabilityError(err)) {
514
466
  this.writeOut("undefined");
515
467
  return ExitCode.SUCCESS;
516
468
  }
@@ -533,7 +485,7 @@ export class StandaloneDispatcher {
533
485
  catch {
534
486
  parsed = rawVal;
535
487
  }
536
- await target.setConfig(this.options.packageId, key, parsed);
488
+ await service.management.config.set(this.options.packageId, key, parsed);
537
489
  this.writeOut(`Config '${key}' updated`);
538
490
  return ExitCode.SUCCESS;
539
491
  }
@@ -543,18 +495,22 @@ export class StandaloneDispatcher {
543
495
  this.writeErr("Error: config key required");
544
496
  return ExitCode.INVALID_ARGUMENT;
545
497
  }
546
- await target.deleteConfig(this.options.packageId, key);
498
+ await service.management.config.delete(this.options.packageId, key);
547
499
  this.writeOut(`Config '${key}' deleted`);
548
500
  return ExitCode.SUCCESS;
549
501
  }
550
502
  this.writeErr(`Unknown config subcommand: '${sub}'`);
551
503
  return ExitCode.INVALID_ARGUMENT;
552
504
  }
553
- async handleState(target, subArgs) {
505
+ async handleState(service, subArgs) {
554
506
  const sub = subArgs[0] || "list";
555
507
  let namespace;
556
508
  let isAll = false;
557
509
  let isJson = false;
510
+ if (!service.management) {
511
+ this.writeErr("Error: management port is not enabled on this service");
512
+ return ExitCode.FAILURE;
513
+ }
558
514
  for (let i = 1; i < subArgs.length; i++) {
559
515
  if ((subArgs[i] === "-n" || subArgs[i] === "--namespace") && i + 1 < subArgs.length) {
560
516
  namespace = subArgs[++i];
@@ -571,7 +527,7 @@ export class StandaloneDispatcher {
571
527
  }
572
528
  if (sub === "list") {
573
529
  const prefix = subArgs[1] && !subArgs[1].startsWith("-") ? subArgs[1] : "";
574
- const keys = await target.listStateKeys(this.options.packageId, "", {
530
+ const keys = await service.management.state.list(this.options.packageId, "", {
575
531
  namespace,
576
532
  prefix: prefix || undefined,
577
533
  all: isAll,
@@ -592,7 +548,7 @@ export class StandaloneDispatcher {
592
548
  ns = decoded.namespace || undefined;
593
549
  actualKey = decoded.key;
594
550
  }
595
- const val = await target.getState(this.options.packageId, "", actualKey, { namespace: ns });
551
+ const val = await service.management.state.get(this.options.packageId, "", actualKey, { namespace: ns });
596
552
  if (isJson) {
597
553
  this.writeOut(JSON.stringify({ key, value: val }, null, 2));
598
554
  }
@@ -631,7 +587,7 @@ export class StandaloneDispatcher {
631
587
  ttl = parseInt(subArgs[i].slice(6), 10);
632
588
  }
633
589
  }
634
- await target.setState(this.options.packageId, "", actualKey, parsed, { namespace: ns, ttl });
590
+ await service.management.state.set(this.options.packageId, "", actualKey, parsed, { namespace: ns, ttl });
635
591
  const displayKey = ns ? `${ns}:${actualKey}` : actualKey;
636
592
  this.writeOut(`State '${displayKey}' updated`);
637
593
  return ExitCode.SUCCESS;
@@ -642,7 +598,7 @@ export class StandaloneDispatcher {
642
598
  this.writeErr("Error: state key required");
643
599
  return ExitCode.INVALID_ARGUMENT;
644
600
  }
645
- const deleted = await target.deleteState(this.options.packageId, "", key, { namespace });
601
+ const deleted = await service.management.state.delete(this.options.packageId, "", key, { namespace });
646
602
  if (deleted) {
647
603
  this.writeOut(`State '${key}' deleted`);
648
604
  return ExitCode.SUCCESS;
@@ -652,7 +608,7 @@ export class StandaloneDispatcher {
652
608
  }
653
609
  if (sub === "clear" || sub === "clean") {
654
610
  const prefix = subArgs[1] && !subArgs[1].startsWith("-") ? subArgs[1] : "";
655
- const count = await target.clearState(this.options.packageId, "", {
611
+ const count = await service.management.state.clear(this.options.packageId, "", {
656
612
  namespace,
657
613
  all: isAll,
658
614
  prefix: prefix || undefined,
@@ -664,15 +620,12 @@ export class StandaloneDispatcher {
664
620
  return ExitCode.INVALID_ARGUMENT;
665
621
  }
666
622
  /**
667
- * 判定配置读取异常是否为目标层能力缺失(键未配置语义)而非内部故障。
623
+ * 判定配置读取异常是否为服务能力缺失(键未配置语义)而非内部故障。
668
624
  */
669
- isTargetCapabilityError(err) {
625
+ isServiceCapabilityError(err) {
670
626
  const code = String(err?.code || "");
671
- const msg = String(err?.message || "");
672
- return (code === "TARGET_CAPABILITY_UNAVAILABLE" ||
673
- code === "CAPABILITY_UNAVAILABLE" ||
674
- msg.includes("TARGET_CAPABILITY_UNAVAILABLE") ||
675
- msg.includes("Management APIs are not enabled"));
627
+ return (code === "CAPABILITY_UNAVAILABLE" ||
628
+ code === "TARGET_CAPABILITY_UNAVAILABLE");
676
629
  }
677
630
  /**
678
631
  * 解析携带命名空间前缀的状态键参数:委托 sdk 单一事实源 decodeStateKey。
@@ -1,3 +1,4 @@
1
+ import { ActionDockError } from "../errors.js";
1
2
  /**
2
3
  * 默认单次 HTTP 请求体最大字节上限(1 MiB)。
3
4
  */
@@ -5,15 +6,13 @@ export declare const DEFAULT_MAX_BODY_BYTES: number;
5
6
  /**
6
7
  * 请求体超出最大允许体积时抛出的异常(对应 HTTP 413 Payload Too Large)。
7
8
  */
8
- export declare class RequestTooLargeError extends Error {
9
- code: string;
9
+ export declare class RequestTooLargeError extends ActionDockError {
10
10
  constructor(message?: string);
11
11
  }
12
12
  /**
13
13
  * 请求体非合法 JSON 格式时抛出的异常(对应 HTTP 400 Bad Request)。
14
14
  */
15
- export declare class InvalidJsonError extends Error {
16
- code: string;
15
+ export declare class InvalidJsonError extends ActionDockError {
17
16
  constructor(message?: string);
18
17
  }
19
18
  /**
@@ -24,12 +23,21 @@ export interface ReadJsonBodyOptions {
24
23
  maxBytes?: number;
25
24
  }
26
25
  /**
27
- * 流式安全地读取 HTTP 请求体并解析为 JSON 对象。
26
+ * 流式安全地读取 HTTP 请求体为原始字节数组(有界读取单一事实源)。
28
27
  *
29
28
  * 防护机制:
30
- * 1. 快速拒绝(Fast-path):若请求头中存在 `Content-Length` 且超过 `maxBytes`,立即抛出 RequestTooLargeError,不进行内存分配。
31
- * 2. 流式计数器(Chunk Streaming):在读取 ReadableStream 过程中实时累计字节数,中途超出上限即刻截断并释放流锁,防止大文件 DoS 与内存耗尽(OOM)。
32
- * 3. 安全解码:处理空请求体与 UTF-8 字符集解码。
29
+ * 1. 快速拒绝(Fast-path):若请求头中存在 Content-Length 且超过 maxBytes,立即抛出 RequestTooLargeError,不进行内存分配。
30
+ * 2. 流式计数器(Chunk Streaming):读取 ReadableStream 过程中实时累计字节数,中途超出上限即刻截断并释放流锁,防止大文件 DoS 与内存耗尽(OOM)。
31
+ *
32
+ * @param req 传入的 Request 对象
33
+ * @param options 读取配置选项
34
+ * @returns 原始字节数组(空请求体返回空数组)
35
+ * @throws {RequestTooLargeError} 若请求体体积超限
36
+ */
37
+ export declare function readBodyWithLimit(req: Request, options?: ReadJsonBodyOptions): Promise<Uint8Array>;
38
+ /**
39
+ * 流式安全地读取 HTTP 请求体并解析为 JSON 对象。
40
+ * 防护机制见 readBodyWithLimit;此外处理空请求体与 UTF-8 字符集解码。
33
41
  *
34
42
  * @param req 传入的 Request 对象
35
43
  * @param options 读取配置选项