@actiondock/core 2.9.0 → 2.10.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 (45) hide show
  1. package/README.md +1 -1
  2. package/dist/catalog/graph.js +5 -2
  3. package/dist/doctor/checks/project.js +4 -4
  4. package/dist/doctor/checks/registry.js +1 -1
  5. package/dist/errors.d.ts +32 -1
  6. package/dist/errors.js +62 -2
  7. package/dist/host/host.d.ts +2 -0
  8. package/dist/host/host.js +13 -1
  9. package/dist/host/types.d.ts +3 -0
  10. package/dist/index.d.ts +3 -1
  11. package/dist/index.js +3 -1
  12. package/dist/input/describe.d.ts +6 -0
  13. package/dist/input/describe.js +26 -1
  14. package/dist/input/input-resolver.js +1 -1
  15. package/dist/invocation/policy.js +2 -0
  16. package/dist/ipc/host.js +1 -0
  17. package/dist/ipc/service.js +3 -0
  18. package/dist/package/runtime.d.ts +3 -0
  19. package/dist/package/runtime.js +8 -0
  20. package/dist/package/types.d.ts +4 -0
  21. package/dist/platform/node.js +1 -0
  22. package/dist/platform/types.d.ts +3 -1
  23. package/dist/profile/client-runs.d.ts +10 -1
  24. package/dist/profile/client-runs.js +14 -1
  25. package/dist/profile/client.d.ts +1 -1
  26. package/dist/profile/client.js +1 -1
  27. package/dist/project/index.d.ts +1 -1
  28. package/dist/project/index.js +1 -1
  29. package/dist/project/init.js +2 -2
  30. package/dist/project/loader.js +1 -1
  31. package/dist/runtime/standalone.js +50 -4
  32. package/dist/server/routes/runs.js +50 -1
  33. package/dist/server/server.js +15 -0
  34. package/dist/service/local.js +3 -0
  35. package/dist/service/remote.js +16 -1
  36. package/dist/service/types.d.ts +4 -0
  37. package/dist/storage/index.d.ts +1 -0
  38. package/dist/storage/index.js +6 -1
  39. package/dist/storage/sqlite.d.ts +18 -1
  40. package/dist/storage/sqlite.js +159 -2
  41. package/dist/storage/types.d.ts +29 -0
  42. package/dist/storage/types.js +12 -0
  43. package/dist/version.d.ts +1 -1
  44. package/dist/version.js +1 -1
  45. package/package.json +2 -2
package/README.md CHANGED
@@ -56,7 +56,7 @@ Service -> Resolution -> PackageRuntime -> ExecutionService -> ActionRunner -> A
56
56
 
57
57
  - 发现端口 `DiscoveryPort`:负责包与动作的元数据发现、清单检索、全文过滤与规程查询。
58
58
  - 执行端口 `ExecutionPort`:负责动作的同步阻塞执行(`run`)与异步启动执行(`start`)。
59
- - 运行端口 `RunsPort`:负责任务运行历史列表、单次详情查询与协同取消(`cancel`)。
59
+ - 运行端口 `RunsPort`:负责任务运行历史列表、单次详情查询、协同取消(`cancel`)以及历史记录清理与保留策略淘汰(`clearRuns`、`cleanExpiredRuns`)。
60
60
  - 事件端口 `EventsPort`:负责任务执行实时事件流订阅。
61
61
  - 配置端口 `ConfigPort`:负责运行时分层配置读取、持久化配置管理与环境变量满足度体检。
62
62
  - 状态端口 `StatePort`:负责包级与动作级持久化键值存取、前缀列举与过期清理。
@@ -57,10 +57,13 @@ export class UndeclaredActionDependencyError extends ActionDockError {
57
57
  targetRef;
58
58
  caller;
59
59
  constructor(targetRef, caller, reason) {
60
+ const hint = caller
61
+ ? `Hint: Add '${targetRef}' to the 'uses' array of action '${caller}' in actiondock.json, then run 'ad validate'.`
62
+ : undefined;
60
63
  const msg = caller
61
- ? `UNDECLARED_ACTION_DEPENDENCY: Action '${caller}' 未在 'uses' 中声明对 '${targetRef}' 的跨包依赖`
64
+ ? `UNDECLARED_ACTION_DEPENDENCY: Action '${caller}' 未在 'uses' 中声明对 '${targetRef}' 的跨包依赖${hint ? `\n${hint}` : ""}`
62
65
  : `UNDECLARED_ACTION_DEPENDENCY: 根调用 Action '${targetRef}' 被拒绝: 目标包既非 actiondock.json 直接依赖,亦未被可见 Playbook 委托${reason ? ` (${reason})` : ""}`;
63
- super(UNDECLARED_ACTION_DEPENDENCY, msg);
66
+ super(UNDECLARED_ACTION_DEPENDENCY, msg, hint ? { hint } : undefined, undefined, hint);
64
67
  this.name = "UndeclaredActionDependencyError";
65
68
  this.targetRef = targetRef;
66
69
  this.caller = caller;
@@ -115,7 +115,7 @@ async function checkProjectActions(scope) {
115
115
  name: "Actions",
116
116
  status: "warn",
117
117
  message: `No actions found in '${config.actionsDir || "actions"}'`,
118
- fix: "Run 'ad action new <id>' to create your first action",
118
+ fix: "Run 'ad action create <id>' to create your first action",
119
119
  });
120
120
  }
121
121
  else {
@@ -155,7 +155,7 @@ function checkProjectManifest(scope) {
155
155
  name: "Action Manifest",
156
156
  status: "warn",
157
157
  message: `${MANIFEST_FILE_NAME} not found (${actionFiles.length} action source file(s) exist)`,
158
- fix: "Run 'ad validate' to generate or check manifest",
158
+ fix: "Run 'ad init' to initialize project manifest, or manually create 'actiondock.json'",
159
159
  });
160
160
  }
161
161
  }
@@ -174,7 +174,7 @@ function checkProjectManifest(scope) {
174
174
  name: "Action Manifest",
175
175
  status: "warn",
176
176
  message: `${missingFiles.length} action(s) in manifest point to missing files: ${missingFiles.join(", ")}`,
177
- fix: "Run 'ad validate' to check or update actiondock.json",
177
+ fix: "Update actiondock.json or use 'ad action create <id>'",
178
178
  });
179
179
  }
180
180
  else if (untracked.length > 0) {
@@ -184,7 +184,7 @@ function checkProjectManifest(scope) {
184
184
  name: "Action Manifest",
185
185
  status: "warn",
186
186
  message: `${untracked.length} action file(s) not declared in manifest: ${untracked.join(", ")}`,
187
- fix: "Run 'ad validate' to check or update actiondock.json",
187
+ fix: "Update actiondock.json or use 'ad action create <id>'",
188
188
  });
189
189
  }
190
190
  else {
@@ -88,7 +88,7 @@ export const checkLinkedPackageDependencies = {
88
88
  name: "Linked Package Dependencies",
89
89
  status: "warn",
90
90
  message: `${missingNodeModules.length} linked package(s) declare dependencies but miss node_modules: ${missingNodeModules.join(", ")}`,
91
- fix: "Run 'npm install' in the affected package directories, or execute 'ad run' to auto-install",
91
+ fix: "Run 'npm install --omit=dev' in the affected package directories",
92
92
  });
93
93
  }
94
94
  else {
package/dist/errors.d.ts CHANGED
@@ -262,8 +262,39 @@ export declare class ActionDockError<T = any> extends Error {
262
262
  readonly code: ErrorCode;
263
263
  readonly details?: T;
264
264
  readonly status?: number;
265
- constructor(code: ErrorCode, message: string, details?: T, status?: number);
265
+ readonly hint?: string;
266
+ constructor(code: ErrorCode, message: string, details?: T, status?: number, hint?: string);
266
267
  }
268
+ /**
269
+ * 结构化机器错误信封。
270
+ */
271
+ export interface ErrorEnvelope {
272
+ ok: false;
273
+ error: {
274
+ code: string;
275
+ message: string;
276
+ details?: unknown;
277
+ };
278
+ hint?: string;
279
+ meta?: Record<string, unknown>;
280
+ }
281
+ /**
282
+ * 统一构造机器错误信封。
283
+ */
284
+ export declare function createErrorEnvelope(code: string, message: string, details?: unknown, meta?: Record<string, unknown>, hint?: string): ErrorEnvelope;
285
+ /**
286
+ * 根据 Action 执行失败错误解析自愈指引提示文案。
287
+ *
288
+ * 作为 CLI 与独立分发器(StandaloneDispatcher)执行失败时提示解析的单一事实源。
289
+ *
290
+ * @param targetRef 目标 Action 引用标识(如 "greet" 或 "pkg/greet")
291
+ * @param error 执行失败错误对象
292
+ */
293
+ export declare function resolveExecutionHint(targetRef: string, error?: {
294
+ code?: string;
295
+ details?: unknown;
296
+ hint?: string;
297
+ }): string | undefined;
267
298
  /**
268
299
  * 集中定义的标准结构化错误码联合类型。
269
300
  */
package/dist/errors.js CHANGED
@@ -178,7 +178,7 @@ export function describeActionLoadFailure(err, context) {
178
178
  const rootCause = err instanceof Error ? err.message : String(err ?? "");
179
179
  const isMissingModule = isMissingModuleError(rootCause);
180
180
  const hint = isMissingModule
181
- ? `依赖未安装,在 '${context.projectRoot}' 执行 npm install 或先执行 'ad run ${context.packageId}/${context.actionId}'`
181
+ ? `项目依赖缺失,请在 '${context.projectRoot}' 目录下运行 'npm install --omit=dev' 安装依赖后再试。`
182
182
  : undefined;
183
183
  return {
184
184
  code: ACTION_LOAD_FAILED,
@@ -263,15 +263,75 @@ export class ActionDockError extends Error {
263
263
  code;
264
264
  details;
265
265
  status;
266
- constructor(code, message, details, status) {
266
+ hint;
267
+ constructor(code, message, details, status, hint) {
267
268
  super(message);
268
269
  this.name = "ActionDockError";
269
270
  this.code = code;
270
271
  this.details = details;
271
272
  this.status = status;
273
+ this.hint =
274
+ hint ??
275
+ (details && typeof details === "object" && typeof details.hint === "string"
276
+ ? details.hint
277
+ : undefined);
272
278
  Object.setPrototypeOf(this, ActionDockError.prototype);
273
279
  }
274
280
  }
281
+ /**
282
+ * 统一构造机器错误信封。
283
+ */
284
+ export function createErrorEnvelope(code, message, details, meta, hint) {
285
+ const effectiveHint = hint ??
286
+ (details && typeof details === "object" && typeof details.hint === "string"
287
+ ? details.hint
288
+ : undefined);
289
+ const result = {
290
+ ok: false,
291
+ error: {
292
+ code,
293
+ message,
294
+ ...(details !== undefined ? { details } : {}),
295
+ },
296
+ };
297
+ if (effectiveHint !== undefined) {
298
+ result.hint = effectiveHint;
299
+ }
300
+ if (meta && Object.keys(meta).length > 0) {
301
+ result.meta = meta;
302
+ }
303
+ return result;
304
+ }
305
+ /**
306
+ * 根据 Action 执行失败错误解析自愈指引提示文案。
307
+ *
308
+ * 作为 CLI 与独立分发器(StandaloneDispatcher)执行失败时提示解析的单一事实源。
309
+ *
310
+ * @param targetRef 目标 Action 引用标识(如 "greet" 或 "pkg/greet")
311
+ * @param error 执行失败错误对象
312
+ */
313
+ export function resolveExecutionHint(targetRef, error) {
314
+ if (!error)
315
+ return undefined;
316
+ if (error.code === INPUT_VALIDATION_FAILED) {
317
+ return `Tip: Run 'ad describe ${targetRef}' to inspect schema and syntax examples.`;
318
+ }
319
+ if (error.code === ACTION_NOT_FOUND) {
320
+ return "Tip: Run 'ad list' to discover available actions, or 'ad info' to inspect packages.";
321
+ }
322
+ if (error.code === ACTION_TIMEOUT) {
323
+ return "Tip: Increase timeout via '--timeout <duration>', or run in background via '--async' and track with 'ad runs show <runId>'.";
324
+ }
325
+ if (error.hint && typeof error.hint === "string") {
326
+ return error.hint;
327
+ }
328
+ if (error.details &&
329
+ typeof error.details === "object" &&
330
+ typeof error.details.hint === "string") {
331
+ return error.details.hint;
332
+ }
333
+ return undefined;
334
+ }
275
335
  /**
276
336
  * 进程领域结构化异常类。
277
337
  */
@@ -91,7 +91,9 @@ export declare class DefaultActionDockHost implements ActionDockHost {
91
91
  actionId?: string;
92
92
  status?: string;
93
93
  olderThanMs?: number;
94
+ keep?: number;
94
95
  }): Promise<number>;
96
+ cleanExpiredRuns(policy?: import("../storage/types.js").RunsRetentionPolicy): Promise<number>;
95
97
  cancelRun(runId: string, reason?: string): Promise<CancelResult>;
96
98
  events(runId: string, options?: {
97
99
  after?: number | string;
package/dist/host/host.js CHANGED
@@ -368,7 +368,9 @@ export class DefaultActionDockHost {
368
368
  declaredUses,
369
369
  }, { packageId: targetPackageId, actionId: targetActionId }, this.graph);
370
370
  if (authErr) {
371
- throw new ActionDockError(authErr.code, authErr.message, authErr.details);
371
+ const hint = authErr.details?.hint;
372
+ const msg = hint ? `${authErr.message}\n${hint}` : authErr.message;
373
+ throw new ActionDockError(authErr.code, msg, authErr.details, undefined, hint);
372
374
  }
373
375
  }
374
376
  // 调用嵌套深度限制校验
@@ -684,6 +686,16 @@ export class DefaultActionDockHost {
684
686
  }
685
687
  return total;
686
688
  }
689
+ async cleanExpiredRuns(policy) {
690
+ let total = 0;
691
+ for (const runtime of this.listRuntimes()) {
692
+ if (typeof runtime.cleanExpiredRuns === "function") {
693
+ const res = await runtime.cleanExpiredRuns(policy);
694
+ total += res;
695
+ }
696
+ }
697
+ return total;
698
+ }
687
699
  async cancelRun(runId, reason) {
688
700
  for (const runtime of this.listRuntimes()) {
689
701
  const res = await runtime.cancelRun(runId, reason);
@@ -80,7 +80,10 @@ export interface ActionDockHost {
80
80
  actionId?: string;
81
81
  status?: string;
82
82
  olderThanMs?: number;
83
+ keep?: number;
83
84
  }): Promise<number>;
85
+ /** 按保留策略清理所有运行时中的过期及超额终态运行记录 */
86
+ cleanExpiredRuns(policy?: import("../storage/types.js").RunsRetentionPolicy): Promise<number>;
84
87
  /** 取消指定在运行的任务 */
85
88
  cancelRun(runId: string, reason?: string): Promise<CancelResult>;
86
89
  /** 订阅指定运行的事件流 */
package/dist/index.d.ts CHANGED
@@ -8,6 +8,8 @@
8
8
  export { ACTIONDOCK_VERSION } from "./version.js";
9
9
  export { createActionDock, connectActionDock, } from "./service/factory.js";
10
10
  export type { ActionDockService, ActionDockService as ActionDock, DiscoveryPort, ExecutionPort, RunsPort, EventsPort, RunEventSubscriptionOptions, ConfigPort, StatePort, CreateActionDockOptions, ConnectActionDockOptions, RemoteServiceOptions, ConfigValueView, ListRunsOptions, StateScopeOptions, } from "./service/types.js";
11
+ export { DEFAULT_RUNS_RETENTION_MS, DEFAULT_MAX_RUNS_PER_PACKAGE, DEFAULT_MIN_RETAIN_RUNS, type RunsRetentionPolicy, } from "./storage/types.js";
12
+ export { parseDuration } from "./utils/index.js";
11
13
  export type { ActionRef, ResolvedActionRef, ExecutionResult, RunRecord, ExecutionEvent, } from "@actiondock/sdk";
12
14
  export type { RunOptions, ExecutionTicket, CancelResult, } from "./execution/types.js";
13
15
  export type { ActionSpec, ActionSummary, PlaybookSpec, PlaybookSummary, PackageInfo, ListActionsOptions, } from "./package/types.js";
@@ -18,4 +20,4 @@ export { initProject } from "./project/init.js";
18
20
  export { loadProjectConfig, findProjectRoot, } from "./project/loader.js";
19
21
  export type { ProjectConfig, } from "./project/types.js";
20
22
  export type { PackageGraph, } from "./catalog/graph.js";
21
- export { ActionDockError, ProcessError, type ErrorCode, type ActionDockErrorCode, PACKAGE_NOT_FOUND, ACTION_PACKAGE_VERSION_CONFLICT, ACTION_NOT_FOUND, ACTION_LOAD_FAILED, ACTION_FAILED, ACTION_TIMEOUT, ACTION_CANCELLED, INPUT_VALIDATION_FAILED, OUTPUT_VALIDATION_FAILED, INPUT_NOT_JSON, OUTPUT_NOT_JSON, ACTION_SUBRUN_LIMIT, ACTION_CALL_CYCLE, UNDECLARED_ACTION_DEPENDENCY, INVALID_ACTION_REF, IDEMPOTENCY_CONFLICT, EXECUTION_FAILED, UNHANDLED_EXECUTION_ERROR, RUN_REPOSITORY_UNAVAILABLE, RUN_PERSISTENCE_FAILED, STANDALONE_ASYNC_UNSUPPORTED, INVOCATION_UNSUPPORTED, HOST_PROCESS_EXITED, EXECUTION_ABORTED, TIMEOUT, NETWORK_ERROR, REMOTE_STREAM_UNAVAILABLE, CAPABILITY_UNAVAILABLE, STATE_KEY_NOT_FOUND, STORAGE_BUSY, PROJECT_BUSY, PROJECT_RECOVERY_REQUIRED, STORAGE_WORKER_EXITED, EVENT_BACKPRESSURE_LIMIT, EVENT_CURSOR_EXPIRED, PROCESS_OUTPUT_LIMIT, PROCESS_SPAWN_ERROR, PROCESS_CANCELLED, PROCESS_TIMEOUT, UNAUTHORIZED, NOT_FOUND, SERVER_ERROR, BAD_REQUEST, PACKAGE_FORBIDDEN, ACTION_FORBIDDEN, PLAYBOOK_NOT_FOUND, REQUEST_TOO_LARGE, ACTION_START_FAILED, ACTION_EXECUTION_ERROR, ACTIONS_LIST_ERROR, PLAYBOOKS_LIST_ERROR, RUNS_LIST_ERROR, RUNS_CLEAR_ERROR, INFO_ERROR, PACKAGES_INFO_ERROR, DOCTOR_ERROR, RUN_INTERRUPTED, CONFIG_ENV_ERROR, CONFIG_LIST_ERROR, CONFIG_SET_ERROR, CONFIG_DELETE_ERROR, STATE_LIST_ERROR, STATE_CLEAR_ERROR, STATE_KEY_ERROR, DATA_DIR_IN_USE, DATA_DIR_RECOVERY_REQUIRED, UNSUPPORTED_STORAGE_SCHEMA, STORED_ERROR_DECODE_FAILED, PROCESS_FAILED, GENERATED_TYPES_OUTDATED, PROTOCOL_UNSUPPORTED, SERVICE_RESULT_UNKNOWN, MCP_TOOL_NAME_COLLISION, ACCESS_DENIED, UNSUPPORTED_CAPABILITY, CONTROL_BUSY, CONTROL_EXPIRED, CONTROL_REVOKED, PROCESS_QUARANTINED, PROCESS_LOST, REQUEST_CONFLICT, INPUT_OUTCOME_UNKNOWN, OUTPUT_GAP, OUTPUT_UNAVAILABLE, INVALID_CURSOR, QUEUE_FULL, QUOTA_EXCEEDED, INPUT_CLOSED, INVALID_FLAT_ARGUMENT, INVALID_JSON, INVALID_JSON_LITERAL, INPUT_PATH_CONFLICT, FLAT_INPUT_LIMIT_EXCEEDED, INPUT_LIMIT_EXCEEDED, INPUT_POLICY_VIOLATION, INPUT_CONFLICT, INPUT_FILE_NOT_FOUND, INPUT_FILE_READ_FAILED, INVALID_ARGUMENT, PACKAGE_NOT_ALLOWED, INVALID_PACKAGE_ID, PATH_TRAVERSAL, AMBIGUOUS_STATE_KEY, RUN_NOT_FOUND, RUN_ALREADY_FINISHED, IPC_ERROR, } from "./errors.js";
23
+ export { ActionDockError, ProcessError, type ErrorCode, type ActionDockErrorCode, PACKAGE_NOT_FOUND, ACTION_PACKAGE_VERSION_CONFLICT, ACTION_NOT_FOUND, ACTION_LOAD_FAILED, ACTION_FAILED, ACTION_TIMEOUT, ACTION_CANCELLED, INPUT_VALIDATION_FAILED, OUTPUT_VALIDATION_FAILED, INPUT_NOT_JSON, OUTPUT_NOT_JSON, ACTION_SUBRUN_LIMIT, ACTION_CALL_CYCLE, UNDECLARED_ACTION_DEPENDENCY, INVALID_ACTION_REF, IDEMPOTENCY_CONFLICT, EXECUTION_FAILED, UNHANDLED_EXECUTION_ERROR, RUN_REPOSITORY_UNAVAILABLE, RUN_PERSISTENCE_FAILED, STANDALONE_ASYNC_UNSUPPORTED, INVOCATION_UNSUPPORTED, HOST_PROCESS_EXITED, EXECUTION_ABORTED, TIMEOUT, NETWORK_ERROR, REMOTE_STREAM_UNAVAILABLE, CAPABILITY_UNAVAILABLE, STATE_KEY_NOT_FOUND, STORAGE_BUSY, PROJECT_BUSY, PROJECT_RECOVERY_REQUIRED, STORAGE_WORKER_EXITED, EVENT_BACKPRESSURE_LIMIT, EVENT_CURSOR_EXPIRED, PROCESS_OUTPUT_LIMIT, PROCESS_SPAWN_ERROR, PROCESS_CANCELLED, PROCESS_TIMEOUT, UNAUTHORIZED, NOT_FOUND, SERVER_ERROR, BAD_REQUEST, PACKAGE_FORBIDDEN, ACTION_FORBIDDEN, PLAYBOOK_NOT_FOUND, REQUEST_TOO_LARGE, ACTION_START_FAILED, ACTION_EXECUTION_ERROR, ACTIONS_LIST_ERROR, PLAYBOOKS_LIST_ERROR, RUNS_LIST_ERROR, RUNS_CLEAR_ERROR, INFO_ERROR, PACKAGES_INFO_ERROR, DOCTOR_ERROR, RUN_INTERRUPTED, CONFIG_ENV_ERROR, CONFIG_LIST_ERROR, CONFIG_SET_ERROR, CONFIG_DELETE_ERROR, STATE_LIST_ERROR, STATE_CLEAR_ERROR, STATE_KEY_ERROR, DATA_DIR_IN_USE, DATA_DIR_RECOVERY_REQUIRED, UNSUPPORTED_STORAGE_SCHEMA, STORED_ERROR_DECODE_FAILED, PROCESS_FAILED, GENERATED_TYPES_OUTDATED, PROTOCOL_UNSUPPORTED, SERVICE_RESULT_UNKNOWN, MCP_TOOL_NAME_COLLISION, ACCESS_DENIED, UNSUPPORTED_CAPABILITY, CONTROL_BUSY, CONTROL_EXPIRED, CONTROL_REVOKED, PROCESS_QUARANTINED, PROCESS_LOST, REQUEST_CONFLICT, INPUT_OUTCOME_UNKNOWN, OUTPUT_GAP, OUTPUT_UNAVAILABLE, INVALID_CURSOR, QUEUE_FULL, QUOTA_EXCEEDED, INPUT_CLOSED, INVALID_FLAT_ARGUMENT, INVALID_JSON, INVALID_JSON_LITERAL, INPUT_PATH_CONFLICT, FLAT_INPUT_LIMIT_EXCEEDED, INPUT_LIMIT_EXCEEDED, INPUT_POLICY_VIOLATION, INPUT_CONFLICT, INPUT_FILE_NOT_FOUND, INPUT_FILE_READ_FAILED, INVALID_ARGUMENT, PACKAGE_NOT_ALLOWED, INVALID_PACKAGE_ID, PATH_TRAVERSAL, AMBIGUOUS_STATE_KEY, RUN_NOT_FOUND, RUN_ALREADY_FINISHED, IPC_ERROR, describeActionLoadFailure, type ActionLoadFailureContext, createErrorEnvelope, type ErrorEnvelope, resolveExecutionHint, } from "./errors.js";
package/dist/index.js CHANGED
@@ -9,6 +9,8 @@
9
9
  export { ACTIONDOCK_VERSION } from "./version.js";
10
10
  // 2. 统一服务门面与聚合契约接口
11
11
  export { createActionDock, connectActionDock, } from "./service/factory.js";
12
+ export { DEFAULT_RUNS_RETENTION_MS, DEFAULT_MAX_RUNS_PER_PACKAGE, DEFAULT_MIN_RETAIN_RUNS, } from "./storage/types.js";
13
+ export { parseDuration } from "./utils/index.js";
12
14
  // 5. 原生平台装配与服务启动
13
15
  export { createNodePlatform, } from "./platform/node.js";
14
16
  export { startActionDockServer, } from "./server/server.js";
@@ -16,4 +18,4 @@ export { startActionDockServer, } from "./server/server.js";
16
18
  export { initProject } from "./project/init.js";
17
19
  export { loadProjectConfig, findProjectRoot, } from "./project/loader.js";
18
20
  // 8. 统一错误模型与核心标准错误码常量
19
- export { ActionDockError, ProcessError, PACKAGE_NOT_FOUND, ACTION_PACKAGE_VERSION_CONFLICT, ACTION_NOT_FOUND, ACTION_LOAD_FAILED, ACTION_FAILED, ACTION_TIMEOUT, ACTION_CANCELLED, INPUT_VALIDATION_FAILED, OUTPUT_VALIDATION_FAILED, INPUT_NOT_JSON, OUTPUT_NOT_JSON, ACTION_SUBRUN_LIMIT, ACTION_CALL_CYCLE, UNDECLARED_ACTION_DEPENDENCY, INVALID_ACTION_REF, IDEMPOTENCY_CONFLICT, EXECUTION_FAILED, UNHANDLED_EXECUTION_ERROR, RUN_REPOSITORY_UNAVAILABLE, RUN_PERSISTENCE_FAILED, STANDALONE_ASYNC_UNSUPPORTED, INVOCATION_UNSUPPORTED, HOST_PROCESS_EXITED, EXECUTION_ABORTED, TIMEOUT, NETWORK_ERROR, REMOTE_STREAM_UNAVAILABLE, CAPABILITY_UNAVAILABLE, STATE_KEY_NOT_FOUND, STORAGE_BUSY, PROJECT_BUSY, PROJECT_RECOVERY_REQUIRED, STORAGE_WORKER_EXITED, EVENT_BACKPRESSURE_LIMIT, EVENT_CURSOR_EXPIRED, PROCESS_OUTPUT_LIMIT, PROCESS_SPAWN_ERROR, PROCESS_CANCELLED, PROCESS_TIMEOUT, UNAUTHORIZED, NOT_FOUND, SERVER_ERROR, BAD_REQUEST, PACKAGE_FORBIDDEN, ACTION_FORBIDDEN, PLAYBOOK_NOT_FOUND, REQUEST_TOO_LARGE, ACTION_START_FAILED, ACTION_EXECUTION_ERROR, ACTIONS_LIST_ERROR, PLAYBOOKS_LIST_ERROR, RUNS_LIST_ERROR, RUNS_CLEAR_ERROR, INFO_ERROR, PACKAGES_INFO_ERROR, DOCTOR_ERROR, RUN_INTERRUPTED, CONFIG_ENV_ERROR, CONFIG_LIST_ERROR, CONFIG_SET_ERROR, CONFIG_DELETE_ERROR, STATE_LIST_ERROR, STATE_CLEAR_ERROR, STATE_KEY_ERROR, DATA_DIR_IN_USE, DATA_DIR_RECOVERY_REQUIRED, UNSUPPORTED_STORAGE_SCHEMA, STORED_ERROR_DECODE_FAILED, PROCESS_FAILED, GENERATED_TYPES_OUTDATED, PROTOCOL_UNSUPPORTED, SERVICE_RESULT_UNKNOWN, MCP_TOOL_NAME_COLLISION, ACCESS_DENIED, UNSUPPORTED_CAPABILITY, CONTROL_BUSY, CONTROL_EXPIRED, CONTROL_REVOKED, PROCESS_QUARANTINED, PROCESS_LOST, REQUEST_CONFLICT, INPUT_OUTCOME_UNKNOWN, OUTPUT_GAP, OUTPUT_UNAVAILABLE, INVALID_CURSOR, QUEUE_FULL, QUOTA_EXCEEDED, INPUT_CLOSED, INVALID_FLAT_ARGUMENT, INVALID_JSON, INVALID_JSON_LITERAL, INPUT_PATH_CONFLICT, FLAT_INPUT_LIMIT_EXCEEDED, INPUT_LIMIT_EXCEEDED, INPUT_POLICY_VIOLATION, INPUT_CONFLICT, INPUT_FILE_NOT_FOUND, INPUT_FILE_READ_FAILED, INVALID_ARGUMENT, PACKAGE_NOT_ALLOWED, INVALID_PACKAGE_ID, PATH_TRAVERSAL, AMBIGUOUS_STATE_KEY, RUN_NOT_FOUND, RUN_ALREADY_FINISHED, IPC_ERROR, } from "./errors.js";
21
+ export { ActionDockError, ProcessError, PACKAGE_NOT_FOUND, ACTION_PACKAGE_VERSION_CONFLICT, ACTION_NOT_FOUND, ACTION_LOAD_FAILED, ACTION_FAILED, ACTION_TIMEOUT, ACTION_CANCELLED, INPUT_VALIDATION_FAILED, OUTPUT_VALIDATION_FAILED, INPUT_NOT_JSON, OUTPUT_NOT_JSON, ACTION_SUBRUN_LIMIT, ACTION_CALL_CYCLE, UNDECLARED_ACTION_DEPENDENCY, INVALID_ACTION_REF, IDEMPOTENCY_CONFLICT, EXECUTION_FAILED, UNHANDLED_EXECUTION_ERROR, RUN_REPOSITORY_UNAVAILABLE, RUN_PERSISTENCE_FAILED, STANDALONE_ASYNC_UNSUPPORTED, INVOCATION_UNSUPPORTED, HOST_PROCESS_EXITED, EXECUTION_ABORTED, TIMEOUT, NETWORK_ERROR, REMOTE_STREAM_UNAVAILABLE, CAPABILITY_UNAVAILABLE, STATE_KEY_NOT_FOUND, STORAGE_BUSY, PROJECT_BUSY, PROJECT_RECOVERY_REQUIRED, STORAGE_WORKER_EXITED, EVENT_BACKPRESSURE_LIMIT, EVENT_CURSOR_EXPIRED, PROCESS_OUTPUT_LIMIT, PROCESS_SPAWN_ERROR, PROCESS_CANCELLED, PROCESS_TIMEOUT, UNAUTHORIZED, NOT_FOUND, SERVER_ERROR, BAD_REQUEST, PACKAGE_FORBIDDEN, ACTION_FORBIDDEN, PLAYBOOK_NOT_FOUND, REQUEST_TOO_LARGE, ACTION_START_FAILED, ACTION_EXECUTION_ERROR, ACTIONS_LIST_ERROR, PLAYBOOKS_LIST_ERROR, RUNS_LIST_ERROR, RUNS_CLEAR_ERROR, INFO_ERROR, PACKAGES_INFO_ERROR, DOCTOR_ERROR, RUN_INTERRUPTED, CONFIG_ENV_ERROR, CONFIG_LIST_ERROR, CONFIG_SET_ERROR, CONFIG_DELETE_ERROR, STATE_LIST_ERROR, STATE_CLEAR_ERROR, STATE_KEY_ERROR, DATA_DIR_IN_USE, DATA_DIR_RECOVERY_REQUIRED, UNSUPPORTED_STORAGE_SCHEMA, STORED_ERROR_DECODE_FAILED, PROCESS_FAILED, GENERATED_TYPES_OUTDATED, PROTOCOL_UNSUPPORTED, SERVICE_RESULT_UNKNOWN, MCP_TOOL_NAME_COLLISION, ACCESS_DENIED, UNSUPPORTED_CAPABILITY, CONTROL_BUSY, CONTROL_EXPIRED, CONTROL_REVOKED, PROCESS_QUARANTINED, PROCESS_LOST, REQUEST_CONFLICT, INPUT_OUTCOME_UNKNOWN, OUTPUT_GAP, OUTPUT_UNAVAILABLE, INVALID_CURSOR, QUEUE_FULL, QUOTA_EXCEEDED, INPUT_CLOSED, INVALID_FLAT_ARGUMENT, INVALID_JSON, INVALID_JSON_LITERAL, INPUT_PATH_CONFLICT, FLAT_INPUT_LIMIT_EXCEEDED, INPUT_LIMIT_EXCEEDED, INPUT_POLICY_VIOLATION, INPUT_CONFLICT, INPUT_FILE_NOT_FOUND, INPUT_FILE_READ_FAILED, INVALID_ARGUMENT, PACKAGE_NOT_ALLOWED, INVALID_PACKAGE_ID, PATH_TRAVERSAL, AMBIGUOUS_STATE_KEY, RUN_NOT_FOUND, RUN_ALREADY_FINISHED, IPC_ERROR, describeActionLoadFailure, createErrorEnvelope, resolveExecutionHint, } from "./errors.js";
@@ -47,6 +47,8 @@ export interface ActionDescribePayload {
47
47
  entry?: string;
48
48
  /** 统一输入模式建议 */
49
49
  inputAdvice: ActionDescribeAdvice;
50
+ /** 扁平输入通用语法速查行列表 */
51
+ syntaxReference?: string[];
50
52
  }
51
53
  /**
52
54
  * 构造 Action 描述载荷的可选选项。
@@ -82,6 +84,10 @@ export declare function buildActionDescribePayload(spec: {
82
84
  entry?: string;
83
85
  [key: string]: any;
84
86
  }, options?: BuildActionDescribePayloadOptions): ActionDescribePayload;
87
+ /**
88
+ * 扁平输入通用语法速查行列表。
89
+ */
90
+ export declare const ACTION_DESCRIBE_SYNTAX_REFERENCE: readonly string[];
85
91
  /**
86
92
  * 格式化渲染 Action 详情人类可读文本。
87
93
  * 普通 CLI 与 Standalone 统一复用该函数,避免长期排版漂移。
@@ -109,8 +109,26 @@ export function buildActionDescribePayload(spec, options) {
109
109
  ...(spec.entry !== undefined ? { entry: spec.entry } : {}),
110
110
  inputAdvice: computeActionDescribeAdvice(spec.inputSchema),
111
111
  };
112
+ const hasAssignments = Boolean(payload.inputAdvice.assignments &&
113
+ Object.keys(payload.inputAdvice.assignments).length > 0);
114
+ if (payload.inputAdvice.recommendedMode === "flat" || hasAssignments) {
115
+ payload.syntaxReference = [...ACTION_DESCRIBE_SYNTAX_REFERENCE];
116
+ }
112
117
  return payload;
113
118
  }
119
+ /**
120
+ * 扁平输入通用语法速查行列表。
121
+ */
122
+ export const ACTION_DESCRIBE_SYNTAX_REFERENCE = [
123
+ " # String assignment (= keeps raw string, no type coercion)",
124
+ ' key="value"',
125
+ " # Typed / JSON assignment (:= parses numbers, booleans, arrays, objects)",
126
+ " count:=10 enabled:=true",
127
+ " # Array structure (direct JSON array or sequential index)",
128
+ ' tags:=\'["a", "b"]\' (or tags.0="a" tags.1="b")',
129
+ " # Complex or multiline inputs (pass via JSON file)",
130
+ " --input-file input.json",
131
+ ];
114
132
  /**
115
133
  * 格式化渲染 Action 详情人类可读文本。
116
134
  * 普通 CLI 与 Standalone 统一复用该函数,避免长期排版漂移。
@@ -158,13 +176,20 @@ export function formatActionDetail(input) {
158
176
  if (payload.inputAdvice.reason) {
159
177
  lines.push(`Reason: ${payload.inputAdvice.reason}`);
160
178
  }
161
- if (payload.inputAdvice.assignments && Object.keys(payload.inputAdvice.assignments).length > 0) {
179
+ const hasAssignments = Boolean(payload.inputAdvice.assignments &&
180
+ Object.keys(payload.inputAdvice.assignments).length > 0);
181
+ if (hasAssignments) {
162
182
  lines.push("");
163
183
  lines.push("Assignments:");
164
184
  for (const [key, op] of Object.entries(payload.inputAdvice.assignments)) {
165
185
  lines.push(` ${key}${op}`);
166
186
  }
167
187
  }
188
+ if (payload.inputAdvice.recommendedMode === "flat" || hasAssignments) {
189
+ lines.push("");
190
+ lines.push("Syntax Reference:");
191
+ lines.push(...(payload.syntaxReference || ACTION_DESCRIBE_SYNTAX_REFERENCE));
192
+ }
168
193
  if (payload.inputAdvice.issues && payload.inputAdvice.issues.length > 0) {
169
194
  lines.push("");
170
195
  lines.push("Issues:");
@@ -173,7 +173,7 @@ export async function resolveActionInput(options) {
173
173
  if (hasFileJson)
174
174
  modeCount++;
175
175
  if (modeCount > 1) {
176
- const err = inputConflict("Input options conflict: flatArgs, input, and inputFile are mutually exclusive", {
176
+ const err = inputConflict("Input options conflict: flat arguments (-- key=val), inline JSON (-i/--input), and file (-f/--input-file) are mutually exclusive. Specify only one input mode.", {
177
177
  reason: "MULTIPLE_INPUT_MODES",
178
178
  hasFlatArgs: effectiveFlat,
179
179
  hasInput: hasInlineJson,
@@ -93,6 +93,7 @@ export class InvocationPolicy {
93
93
  ? graph.canCascadeCall(caller.packageId, caller.actionId, target.packageId, target.actionId)
94
94
  : usesList.some((u) => isUsesDeclared(u, target.packageId, target.actionId));
95
95
  if (!isAllowed) {
96
+ const hint = `Hint: Add '${targetRef}' to the 'uses' array of action '${caller.actionId}' in actiondock.json, then run 'ad validate'.`;
96
97
  return {
97
98
  code: UNDECLARED_ACTION_DEPENDENCY,
98
99
  message: `Undeclared cross-package dependency: Action '${caller.packageId}/${caller.actionId}' does not declare dependency on '${targetRef}' in 'uses'`,
@@ -100,6 +101,7 @@ export class InvocationPolicy {
100
101
  caller: `${caller.packageId}/${caller.actionId}`,
101
102
  target: targetRef,
102
103
  declaredUses: usesList,
104
+ hint,
103
105
  },
104
106
  };
105
107
  }
package/dist/ipc/host.js CHANGED
@@ -20,6 +20,7 @@ const IPC_METHOD_HANDLERS = {
20
20
  getRun: async (service, a) => service.runs.get(a[0]),
21
21
  cancelRun: async (service, a) => service.runs.cancel(a[0], a[1]),
22
22
  clearRuns: async (service, a) => service.runs.clear ? await service.runs.clear(a[0]) : 0,
23
+ cleanExpiredRuns: async (service, a) => service.runs.cleanExpired ? await service.runs.cleanExpired(a[0]) : 0,
23
24
  getConfig: async (service, a) => service.management?.config.get(a[0], a[1]),
24
25
  setConfig: async (service, a) => service.management?.config.set(a[0], a[1], a[2]),
25
26
  deleteConfig: async (service, a) => service.management?.config.delete(a[0], a[1]),
@@ -184,6 +184,9 @@ export class IpcActionDockService {
184
184
  async clear(opts) {
185
185
  return forward("clearRuns", [opts]);
186
186
  },
187
+ async cleanExpired(policy) {
188
+ return forward("cleanExpiredRuns", [policy]);
189
+ },
187
190
  };
188
191
  if (options.enableManagement !== false) {
189
192
  this.management = {
@@ -97,7 +97,10 @@ export declare class DefaultPackageRuntime implements HostManagedPackageRuntime
97
97
  clearRuns(options?: {
98
98
  actionId?: string;
99
99
  status?: string;
100
+ olderThanMs?: number;
101
+ keep?: number;
100
102
  }): Promise<number>;
103
+ cleanExpiredRuns(policy?: import("../storage/types.js").RunsRetentionPolicy): Promise<number>;
101
104
  listStateEntries(options?: any): Promise<import("../storage/types.js").StateEntry[]>;
102
105
  close(options?: {
103
106
  graceMs?: number;
@@ -581,8 +581,16 @@ export class DefaultPackageRuntime {
581
581
  return this.storage.clearRuns({
582
582
  actionId: options?.actionId,
583
583
  status: options?.status,
584
+ olderThanMs: options?.olderThanMs,
585
+ keep: options?.keep,
584
586
  });
585
587
  }
588
+ async cleanExpiredRuns(policy) {
589
+ if (typeof this.storage.cleanExpiredRuns === "function") {
590
+ return this.storage.cleanExpiredRuns(policy);
591
+ }
592
+ return 0;
593
+ }
586
594
  async listStateEntries(options) {
587
595
  if (typeof this.storage.listStateEntries === "function") {
588
596
  return this.storage.listStateEntries(options);
@@ -268,7 +268,11 @@ export interface PackageRuntime {
268
268
  clearRuns(options?: {
269
269
  actionId?: string;
270
270
  status?: string;
271
+ olderThanMs?: number;
272
+ keep?: number;
271
273
  }): Promise<number>;
274
+ /** 按保留策略清理过期及超额的终态运行记录(基于时间与数量策略) */
275
+ cleanExpiredRuns?(policy?: import("../storage/types.js").RunsRetentionPolicy): Promise<number>;
272
276
  /** 订阅指定运行的事件流 */
273
277
  events(runId: string, options?: {
274
278
  after?: number | string;
@@ -64,6 +64,7 @@ export function createNodePlatform(options = {}) {
64
64
  clock,
65
65
  driver: createDriver(dbPath),
66
66
  recoverOrphans: opts?.recoverOrphans === true,
67
+ retentionPolicy: opts?.retentionPolicy,
67
68
  });
68
69
  },
69
70
  createGlobalStorage(opts) {
@@ -1,7 +1,7 @@
1
1
  import type { ProcessAPI } from "@actiondock/sdk";
2
2
  import type { Clock } from "../runtime/clock.js";
3
3
  import type { ModuleLoader } from "../runtime/module-loader.js";
4
- import type { RuntimeStorage } from "../storage/types.js";
4
+ import type { RunsRetentionPolicy, RuntimeStorage } from "../storage/types.js";
5
5
  /**
6
6
  * 文件元数据信息契约。
7
7
  */
@@ -58,6 +58,8 @@ export interface StorageFactoryOptions {
58
58
  * 默认 false(旁观查询打开,不触碰在途记录),供 CLI 查询命令与执行宿主并发共存。
59
59
  */
60
60
  recoverOrphans?: boolean;
61
+ /** 运行记录保留策略配置 */
62
+ retentionPolicy?: RunsRetentionPolicy;
61
63
  }
62
64
  /**
63
65
  * 跨运行时全局存储工厂配置选项。
@@ -30,13 +30,22 @@ export declare function fetchRemoteRuns(serverUrl: string, token?: string, optio
30
30
  items: RunRecord[];
31
31
  }>;
32
32
  /**
33
- * 清空远端运行记录(可按包、Action、状态过滤清除范围)。
33
+ * 清空远端运行记录(可按包、Action、状态、保留时长、保留数量过滤清除范围)。
34
34
  */
35
35
  export declare function clearRemoteRuns(serverUrl: string, token?: string, options?: {
36
36
  packageId?: string;
37
37
  actionId?: string;
38
38
  status?: string;
39
+ olderThanMs?: number;
40
+ keep?: number;
39
41
  } & RemoteClientRequestOptions): Promise<{
40
42
  ok: boolean;
41
43
  clearedCount: number;
42
44
  }>;
45
+ /**
46
+ * 按保留策略清理远端过期及超额运行记录。
47
+ */
48
+ export declare function cleanExpiredRemoteRuns(serverUrl: string, token?: string, options?: import("../storage/types.js").RunsRetentionPolicy & RemoteClientRequestOptions): Promise<{
49
+ ok: boolean;
50
+ cleanedCount: number;
51
+ }>;
@@ -44,7 +44,7 @@ export async function fetchRemoteRuns(serverUrl, token, options) {
44
44
  });
45
45
  }
46
46
  /**
47
- * 清空远端运行记录(可按包、Action、状态过滤清除范围)。
47
+ * 清空远端运行记录(可按包、Action、状态、保留时长、保留数量过滤清除范围)。
48
48
  */
49
49
  export async function clearRemoteRuns(serverUrl, token, options) {
50
50
  return fetchRemoteJson(serverUrl, "/api/v2/runs/clear", token, {
@@ -56,3 +56,16 @@ export async function clearRemoteRuns(serverUrl, token, options) {
56
56
  dispatcher: options?.dispatcher,
57
57
  });
58
58
  }
59
+ /**
60
+ * 按保留策略清理远端过期及超额运行记录。
61
+ */
62
+ export async function cleanExpiredRemoteRuns(serverUrl, token, options) {
63
+ return fetchRemoteJson(serverUrl, "/api/v2/runs/clean-expired", token, {
64
+ method: "POST",
65
+ body: options || {},
66
+ errorPrefix: "Failed to clean expired remote runs",
67
+ allowInsecureHttp: options?.allowInsecureHttp,
68
+ insecure: options?.insecure,
69
+ dispatcher: options?.dispatcher,
70
+ });
71
+ }
@@ -21,6 +21,6 @@ export { checkRemoteHealth } from "./client-health.js";
21
21
  export { executeRemoteAction, fetchRemoteActionShow, fetchRemoteActions, fetchRemoteDoctor, fetchRemoteInfo, } from "./client-actions.js";
22
22
  export type { RemoteExecuteOptions, RemoteExecutionResult } from "./client-actions.js";
23
23
  export { fetchRemotePlaybookShow, fetchRemotePlaybooks } from "./client-playbooks.js";
24
- export { cancelRemoteRun, clearRemoteRuns, fetchRemoteRun, fetchRemoteRuns, } from "./client-runs.js";
24
+ export { cancelRemoteRun, clearRemoteRuns, cleanExpiredRemoteRuns, fetchRemoteRun, fetchRemoteRuns, } from "./client-runs.js";
25
25
  export { clearRemoteState, deleteRemoteStateKey, fetchRemoteStateList, getRemoteStateKey, setRemoteStateKey, } from "./client-state.js";
26
26
  export { deleteRemoteConfig, fetchRemoteConfig, fetchRemoteConfigEnv, setRemoteConfig, } from "./client-config.js";
@@ -24,7 +24,7 @@ export { executeRemoteAction, fetchRemoteActionShow, fetchRemoteActions, fetchRe
24
24
  // Playbook 规程查询
25
25
  export { fetchRemotePlaybookShow, fetchRemotePlaybooks } from "./client-playbooks.js";
26
26
  // 运行记录管理
27
- export { cancelRemoteRun, clearRemoteRuns, fetchRemoteRun, fetchRemoteRuns, } from "./client-runs.js";
27
+ export { cancelRemoteRun, clearRemoteRuns, cleanExpiredRemoteRuns, fetchRemoteRun, fetchRemoteRuns, } from "./client-runs.js";
28
28
  // 状态存储管理
29
29
  export { clearRemoteState, deleteRemoteStateKey, fetchRemoteStateList, getRemoteStateKey, setRemoteStateKey, } from "./client-state.js";
30
30
  // 配置管理
@@ -10,7 +10,7 @@ export * from "./types-generator.js";
10
10
  export { assertPathWithinRoot, isPathOutsideBoundary, getPackageSlug, parseDuration, traverseDirectory, type TraverseDirectoryEntry, type TraverseDirectoryOptions, } from "../utils/index.js";
11
11
  export { isSecretConfigKey, maskSecretValue, sanitizeConfigDefinitions, } from "../storage/mask.js";
12
12
  export { runDoctorChecks, } from "../doctor/doctor.js";
13
- export { resolveActionInput, buildActionInputAdvice, formatActionDetail, buildActionDescribePayload, mapInputValidationFailure, stripBom, readStdinBounded, type ResolveActionInputOptions, type ReadStdinBoundedOptions, } from "../input/index.js";
13
+ export { resolveActionInput, buildActionInputAdvice, formatActionDetail, buildActionDescribePayload, ACTION_DESCRIBE_SYNTAX_REFERENCE, mapInputValidationFailure, stripBom, readStdinBounded, type ResolveActionInputOptions, type ReadStdinBoundedOptions, } from "../input/index.js";
14
14
  export { validateActionInputValue } from "../json/value-validator.js";
15
15
  export { parseJson } from "../input/input-resolver.js";
16
16
  export { InputError, FlatInputError, } from "../input/flat-errors.js";
@@ -11,7 +11,7 @@ export { assertPathWithinRoot, isPathOutsideBoundary, getPackageSlug, parseDurat
11
11
  export { isSecretConfigKey, maskSecretValue, sanitizeConfigDefinitions, } from "../storage/mask.js";
12
12
  export { runDoctorChecks, } from "../doctor/doctor.js";
13
13
  // 动作入参解析、校验与格式化(含 BOM 剥离与标准输入有界读取的单一事实源转引)
14
- export { resolveActionInput, buildActionInputAdvice, formatActionDetail, buildActionDescribePayload, mapInputValidationFailure, stripBom, readStdinBounded, } from "../input/index.js";
14
+ export { resolveActionInput, buildActionInputAdvice, formatActionDetail, buildActionDescribePayload, ACTION_DESCRIBE_SYNTAX_REFERENCE, mapInputValidationFailure, stripBom, readStdinBounded, } from "../input/index.js";
15
15
  export { validateActionInputValue } from "../json/value-validator.js";
16
16
  export { parseJson } from "../input/input-resolver.js";
17
17
  export { InputError, FlatInputError, } from "../input/flat-errors.js";
@@ -86,10 +86,10 @@ export function initProject(targetDir, options = {}) {
86
86
  node: ">=24.12.0",
87
87
  },
88
88
  dependencies: {
89
- "@actiondock/sdk": "^2.9.0",
89
+ "@actiondock/sdk": "^2.10.0",
90
90
  },
91
91
  devDependencies: {
92
- "@actiondock/testing": "^2.9.0",
92
+ "@actiondock/testing": "^2.10.0",
93
93
  "@types/node": "^22.13.0",
94
94
  "tsx": "^4.19.0",
95
95
  "typescript": "^5.7.0",
@@ -214,7 +214,7 @@ export async function loadActions(projectRoot, _actionsDir = "actions", options
214
214
  entryPath,
215
215
  rootCause: msg,
216
216
  hint: isMissingModuleError(msg)
217
- ? `项目依赖缺失,请在 '${projectRoot}' 目录下运行 npm install 安装依赖。`
217
+ ? `项目依赖缺失,请在 '${projectRoot}' 目录下运行 'npm install --omit=dev' 安装依赖后再试。`
218
218
  : undefined,
219
219
  };
220
220
  throw error;