@actiondock/core 2.9.1 → 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.
- package/dist/catalog/graph.js +5 -2
- package/dist/doctor/checks/project.js +4 -4
- package/dist/doctor/checks/registry.js +1 -1
- package/dist/errors.d.ts +32 -1
- package/dist/errors.js +62 -2
- package/dist/host/host.js +3 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/input/describe.d.ts +6 -0
- package/dist/input/describe.js +26 -1
- package/dist/input/input-resolver.js +1 -1
- package/dist/invocation/policy.js +2 -0
- package/dist/project/index.d.ts +1 -1
- package/dist/project/index.js +1 -1
- package/dist/project/init.js +2 -2
- package/dist/project/loader.js +1 -1
- package/dist/runtime/standalone.js +50 -4
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +2 -2
package/dist/catalog/graph.js
CHANGED
|
@@ -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
|
|
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
|
|
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: "
|
|
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: "
|
|
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
|
|
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
|
-
|
|
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
|
-
?
|
|
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
|
-
|
|
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
|
*/
|
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
|
-
|
|
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
|
// 调用嵌套深度限制校验
|
package/dist/index.d.ts
CHANGED
|
@@ -20,4 +20,4 @@ export { initProject } from "./project/init.js";
|
|
|
20
20
|
export { loadProjectConfig, findProjectRoot, } from "./project/loader.js";
|
|
21
21
|
export type { ProjectConfig, } from "./project/types.js";
|
|
22
22
|
export type { PackageGraph, } from "./catalog/graph.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, } 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
|
@@ -18,4 +18,4 @@ export { startActionDockServer, } from "./server/server.js";
|
|
|
18
18
|
export { initProject } from "./project/init.js";
|
|
19
19
|
export { loadProjectConfig, findProjectRoot, } from "./project/loader.js";
|
|
20
20
|
// 8. 统一错误模型与核心标准错误码常量
|
|
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, } 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";
|
package/dist/input/describe.d.ts
CHANGED
|
@@ -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 统一复用该函数,避免长期排版漂移。
|
package/dist/input/describe.js
CHANGED
|
@@ -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
|
-
|
|
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:
|
|
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/project/index.d.ts
CHANGED
|
@@ -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";
|
package/dist/project/index.js
CHANGED
|
@@ -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";
|
package/dist/project/init.js
CHANGED
|
@@ -86,10 +86,10 @@ export function initProject(targetDir, options = {}) {
|
|
|
86
86
|
node: ">=24.12.0",
|
|
87
87
|
},
|
|
88
88
|
dependencies: {
|
|
89
|
-
"@actiondock/sdk": "^2.
|
|
89
|
+
"@actiondock/sdk": "^2.10.0",
|
|
90
90
|
},
|
|
91
91
|
devDependencies: {
|
|
92
|
-
"@actiondock/testing": "^2.
|
|
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",
|
package/dist/project/loader.js
CHANGED
|
@@ -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;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { decodeStateKey } from "@actiondock/sdk";
|
|
2
2
|
import { filterWithFallbackInfo } from "../filter/index.js";
|
|
3
3
|
import { createActionDock } from "../service/factory.js";
|
|
4
|
-
import { STANDALONE_ASYNC_UNSUPPORTED } from "../errors.js";
|
|
4
|
+
import { STANDALONE_ASYNC_UNSUPPORTED, resolveExecutionHint, } from "../errors.js";
|
|
5
5
|
import { resolveActionInput, formatActionDetail, buildActionDescribePayload, mapInputValidationFailure, } from "../input/index.js";
|
|
6
6
|
import { validateActionInputValue } from "../json/value-validator.js";
|
|
7
7
|
import { normalizeActionCollection } from "./action-collection.js";
|
|
@@ -62,6 +62,10 @@ export class StandaloneDispatcher {
|
|
|
62
62
|
emitError(isJson, code, message, exitCode, options) {
|
|
63
63
|
if (isJson) {
|
|
64
64
|
const details = options?.details;
|
|
65
|
+
const hint = options?.hint ??
|
|
66
|
+
(details && typeof details === "object" && typeof details.hint === "string"
|
|
67
|
+
? details.hint
|
|
68
|
+
: undefined);
|
|
65
69
|
this.writeOut(JSON.stringify({
|
|
66
70
|
ok: false,
|
|
67
71
|
error: {
|
|
@@ -69,6 +73,7 @@ export class StandaloneDispatcher {
|
|
|
69
73
|
message,
|
|
70
74
|
...(details !== undefined ? { details } : {}),
|
|
71
75
|
},
|
|
76
|
+
...(hint !== undefined ? { hint } : {}),
|
|
72
77
|
}, null, 2));
|
|
73
78
|
}
|
|
74
79
|
else {
|
|
@@ -249,8 +254,11 @@ export class StandaloneDispatcher {
|
|
|
249
254
|
description: a.description || "",
|
|
250
255
|
}));
|
|
251
256
|
const filterRes = filterWithFallbackInfo(list, effectiveIntent, [(a) => a.id, (a) => a.description], !noFallback);
|
|
257
|
+
const hints = [
|
|
258
|
+
"Tip: For composite or multi-step tasks, check 'ad playbook list' for standard operating procedures.",
|
|
259
|
+
];
|
|
252
260
|
if (isJson) {
|
|
253
|
-
this.writeOut(JSON.stringify(filterRes.items, null, 2));
|
|
261
|
+
this.writeOut(JSON.stringify({ items: filterRes.items, hints }, null, 2));
|
|
254
262
|
}
|
|
255
263
|
else {
|
|
256
264
|
let text = `Actions in ${this.options.packageId} (v${this.options.version}):\n\n`;
|
|
@@ -272,7 +280,11 @@ export class StandaloneDispatcher {
|
|
|
272
280
|
action = await service.discovery.describeAction(id);
|
|
273
281
|
}
|
|
274
282
|
catch {
|
|
275
|
-
|
|
283
|
+
const hint = "Tip: Run 'ad list' to discover available actions.";
|
|
284
|
+
return this.emitError(isJson, "INVALID_ARGUMENT", `Action '${id}' not found`, ExitCode.INVALID_ARGUMENT, {
|
|
285
|
+
textMessage: `Error: Action '${id}' not found\n${hint}`,
|
|
286
|
+
hint,
|
|
287
|
+
});
|
|
276
288
|
}
|
|
277
289
|
const payload = buildActionDescribePayload(action, {
|
|
278
290
|
packageId: this.options.packageId,
|
|
@@ -294,8 +306,12 @@ export class StandaloneDispatcher {
|
|
|
294
306
|
let inputStr;
|
|
295
307
|
let inputFile;
|
|
296
308
|
let timeoutMs;
|
|
309
|
+
const recognizedFlags = new Set(["--json", "--async"]);
|
|
297
310
|
for (let i = 0; i < subArgs.length; i++) {
|
|
298
311
|
const arg = subArgs[i];
|
|
312
|
+
if (arg === id || recognizedFlags.has(arg)) {
|
|
313
|
+
continue;
|
|
314
|
+
}
|
|
299
315
|
if (arg === "--timeout" && i + 1 < subArgs.length) {
|
|
300
316
|
try {
|
|
301
317
|
timeoutMs = parseDuration(subArgs[++i]);
|
|
@@ -318,12 +334,31 @@ export class StandaloneDispatcher {
|
|
|
318
334
|
else if (arg.startsWith("--input=")) {
|
|
319
335
|
inputStr = arg.slice(8);
|
|
320
336
|
}
|
|
337
|
+
else if (arg === "-i" && i + 1 < subArgs.length) {
|
|
338
|
+
inputStr = subArgs[++i];
|
|
339
|
+
}
|
|
340
|
+
else if (arg.startsWith("-i=")) {
|
|
341
|
+
inputStr = arg.slice(3);
|
|
342
|
+
}
|
|
321
343
|
else if (arg === "--input-file" && i + 1 < subArgs.length) {
|
|
322
344
|
inputFile = subArgs[++i];
|
|
323
345
|
}
|
|
324
346
|
else if (arg.startsWith("--input-file=")) {
|
|
325
347
|
inputFile = arg.slice(13);
|
|
326
348
|
}
|
|
349
|
+
else if (arg === "-f" && i + 1 < subArgs.length) {
|
|
350
|
+
inputFile = subArgs[++i];
|
|
351
|
+
}
|
|
352
|
+
else if (arg.startsWith("-f=")) {
|
|
353
|
+
inputFile = arg.slice(3);
|
|
354
|
+
}
|
|
355
|
+
else if (arg.startsWith("-")) {
|
|
356
|
+
const hint = "Hint: Separate action inputs from CLI options using '--', e.g.: ad run <id> [options] -- <param>=<val> or <param>:=<json>.";
|
|
357
|
+
return this.emitError(isJson, "INVALID_ARGUMENT", `error: unknown option '${arg}'`, ExitCode.INVALID_ARGUMENT, {
|
|
358
|
+
textMessage: `error: unknown option '${arg}'\n${hint}`,
|
|
359
|
+
hint,
|
|
360
|
+
});
|
|
361
|
+
}
|
|
327
362
|
}
|
|
328
363
|
let input;
|
|
329
364
|
try {
|
|
@@ -348,7 +383,14 @@ export class StandaloneDispatcher {
|
|
|
348
383
|
timeoutMs,
|
|
349
384
|
});
|
|
350
385
|
if (isJson) {
|
|
351
|
-
|
|
386
|
+
if (!result.ok) {
|
|
387
|
+
const hint = resolveExecutionHint(id, result.error);
|
|
388
|
+
const machineOutput = hint !== undefined ? { ...result, hint } : result;
|
|
389
|
+
this.writeOut(JSON.stringify(machineOutput, null, 2));
|
|
390
|
+
}
|
|
391
|
+
else {
|
|
392
|
+
this.writeOut(JSON.stringify(result, null, 2));
|
|
393
|
+
}
|
|
352
394
|
}
|
|
353
395
|
else {
|
|
354
396
|
if (result.ok) {
|
|
@@ -428,6 +470,10 @@ export class StandaloneDispatcher {
|
|
|
428
470
|
? result.error.details
|
|
429
471
|
: JSON.stringify(result.error.details, null, 2));
|
|
430
472
|
}
|
|
473
|
+
const hint = resolveExecutionHint(id, result.error);
|
|
474
|
+
if (hint) {
|
|
475
|
+
this.writeErr(hint);
|
|
476
|
+
}
|
|
431
477
|
}
|
|
432
478
|
}
|
|
433
479
|
return result.ok ? ExitCode.SUCCESS : ExitCode.FAILURE;
|
package/dist/version.d.ts
CHANGED
package/dist/version.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@actiondock/core",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.10.0",
|
|
4
4
|
"description": "ActionDock Core Engine - Project loader, runtime execution, SQLite storage, standalone builder, and skill exporter",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
"test": "node ../../scripts/run-tests.ts"
|
|
67
67
|
},
|
|
68
68
|
"dependencies": {
|
|
69
|
-
"@actiondock/sdk": "^2.
|
|
69
|
+
"@actiondock/sdk": "^2.10.0",
|
|
70
70
|
"ajv": "^8.17.1",
|
|
71
71
|
"ajv-formats": "^3.0.1",
|
|
72
72
|
"undici": "^7.29.1"
|