@actiondock/core 2.7.0 → 2.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +61 -68
- package/dist/catalog/action-catalog.d.ts +56 -0
- package/dist/catalog/action-catalog.js +202 -0
- package/dist/catalog/discovery.d.ts +60 -0
- package/dist/catalog/discovery.js +119 -0
- package/dist/catalog/graph.d.ts +190 -0
- package/dist/catalog/graph.js +589 -0
- package/dist/catalog/index.d.ts +5 -5
- package/dist/catalog/index.js +5 -5
- package/dist/catalog/resolve-action.d.ts +43 -0
- package/dist/catalog/resolve-action.js +119 -0
- package/dist/catalog/resolve-playbook.d.ts +26 -0
- package/dist/catalog/resolve-playbook.js +114 -0
- package/dist/doctor/checks/project.js +27 -8
- package/dist/doctor/checks/registry.js +2 -2
- package/dist/doctor/checks/runtime.js +34 -1
- package/dist/errors.d.ts +102 -10
- package/dist/errors.js +103 -10
- package/dist/execution/service.d.ts +18 -16
- package/dist/execution/service.js +183 -252
- package/dist/execution/types.d.ts +25 -69
- package/dist/execution/types.js +2 -1
- package/dist/filter/intent.d.ts +8 -9
- package/dist/filter/intent.js +49 -10
- package/dist/graph/index.d.ts +4 -0
- package/dist/graph/index.js +4 -0
- package/dist/host/host.d.ts +74 -32
- package/dist/host/host.js +585 -336
- package/dist/host/routing.d.ts +15 -48
- package/dist/host/routing.js +90 -153
- package/dist/host/types.d.ts +50 -17
- package/dist/index.d.ts +21 -24
- package/dist/index.js +19 -23
- package/dist/input/advice.d.ts +5 -1
- package/dist/input/advice.js +163 -214
- package/dist/input/describe.d.ts +1 -1
- package/dist/input/flat-errors.d.ts +5 -6
- package/dist/input/flat-errors.js +6 -6
- package/dist/input/flat-materializer.js +42 -44
- package/dist/invocation/index.d.ts +2 -0
- package/dist/invocation/index.js +2 -0
- package/dist/invocation/policy.d.ts +157 -0
- package/dist/invocation/policy.js +231 -0
- package/dist/invocation/types.d.ts +172 -0
- package/dist/invocation/types.js +97 -0
- package/dist/ipc/diagnostic.d.ts +0 -12
- package/dist/ipc/diagnostic.js +0 -21
- package/dist/ipc/host.d.ts +4 -4
- package/dist/ipc/host.js +44 -47
- package/dist/ipc/index.d.ts +1 -1
- package/dist/ipc/index.js +1 -1
- package/dist/ipc/service.d.ts +40 -0
- package/dist/ipc/service.js +349 -0
- package/dist/ipc/types.d.ts +21 -15
- package/dist/node/index.d.ts +1 -0
- package/dist/node/index.js +1 -0
- package/dist/node/module-loader.d.ts +63 -0
- package/dist/node/module-loader.js +112 -0
- package/dist/package/index.d.ts +23 -0
- package/dist/package/index.js +18 -0
- package/dist/{app/app.d.ts → package/runtime.d.ts} +41 -20
- package/dist/{app/app.js → package/runtime.js} +140 -95
- package/dist/{app → package}/static-index.js +58 -41
- package/dist/package/storage-view.d.ts +13 -0
- package/dist/package/storage-view.js +22 -0
- package/dist/{app → package}/types.d.ts +76 -57
- package/dist/package/types.js +22 -0
- package/dist/platform/index.d.ts +1 -1
- package/dist/platform/index.js +1 -1
- package/dist/platform/node.d.ts +48 -0
- package/dist/platform/node.js +96 -0
- package/dist/platform/types.d.ts +0 -9
- package/dist/process/control-arbiter.d.ts +2 -1
- package/dist/process/control-arbiter.js +1 -2
- package/dist/process/driver.d.ts +9 -8
- package/dist/process/driver.js +11 -22
- package/dist/process/index.d.ts +2 -0
- package/dist/process/index.js +2 -0
- package/dist/process/managed-record.d.ts +2 -2
- package/dist/process/process-driver.d.ts +109 -0
- package/dist/process/process-driver.js +650 -0
- package/dist/process/process-executor.d.ts +47 -0
- package/dist/process/process-executor.js +296 -0
- package/dist/process/process-manager.js +48 -26
- package/dist/process/run-executor.js +12 -12
- package/dist/profile/client-actions.js +2 -2
- package/dist/profile/client-health.js +2 -2
- package/dist/profile/client-query.js +5 -6
- package/dist/profile/client-transport.d.ts +19 -17
- package/dist/profile/client-transport.js +47 -80
- package/dist/profile/client.d.ts +2 -2
- package/dist/profile/client.js +1 -1
- package/dist/profile/index.d.ts +1 -0
- package/dist/profile/index.js +1 -0
- package/dist/profile/manager.d.ts +5 -0
- package/dist/profile/manager.js +41 -6
- package/dist/project/closure.js +2 -2
- package/dist/project/index.d.ts +8 -1
- package/dist/project/index.js +10 -1
- package/dist/project/init.js +2 -2
- package/dist/project/loader.d.ts +1 -1
- package/dist/project/loader.js +26 -29
- package/dist/project/transactions.js +5 -10
- package/dist/registry/index.d.ts +3 -1
- package/dist/registry/index.js +2 -1
- package/dist/registry/lock.d.ts +28 -7
- package/dist/registry/lock.js +136 -16
- package/dist/registry/registry.d.ts +1 -5
- package/dist/registry/registry.js +1 -53
- package/dist/registry/scan.d.ts +0 -15
- package/dist/registry/scan.js +0 -59
- package/dist/registry/store.d.ts +42 -0
- package/dist/registry/store.js +43 -0
- package/dist/registry/types.d.ts +0 -24
- package/dist/runtime/action-collection.d.ts +1 -1
- package/dist/runtime/action-registry.d.ts +0 -4
- package/dist/runtime/action-registry.js +0 -7
- package/dist/runtime/context.js +5 -11
- package/dist/runtime/events.js +3 -6
- package/dist/runtime/identity.d.ts +22 -0
- package/dist/runtime/identity.js +10 -0
- package/dist/runtime/index.d.ts +1 -2
- package/dist/runtime/index.js +1 -2
- package/dist/runtime/module-loader.d.ts +2 -34
- package/dist/runtime/module-loader.js +1 -16
- package/dist/runtime/process.d.ts +6 -24
- package/dist/runtime/process.js +1 -118
- package/dist/runtime/run-persistence.js +2 -5
- package/dist/runtime/runner.d.ts +33 -93
- package/dist/runtime/runner.js +132 -364
- package/dist/runtime/standalone.d.ts +23 -8
- package/dist/runtime/standalone.js +100 -147
- package/dist/server/body.d.ts +16 -8
- package/dist/server/body.js +33 -16
- package/dist/server/dispatcher.d.ts +6 -10
- package/dist/server/dispatcher.js +24 -32
- package/dist/server/http-server.d.ts +87 -0
- package/dist/server/http-server.js +304 -0
- package/dist/server/index.d.ts +11 -0
- package/dist/server/index.js +10 -0
- package/dist/server/mcp-endpoint.d.ts +61 -0
- package/dist/server/mcp-endpoint.js +118 -0
- package/dist/server/routes/actions.js +34 -28
- package/dist/server/routes/common.d.ts +10 -14
- package/dist/server/routes/common.js +32 -56
- package/dist/server/routes/config.js +54 -64
- package/dist/server/routes/doctor.d.ts +1 -1
- package/dist/server/routes/doctor.js +10 -18
- package/dist/server/routes/health.d.ts +1 -1
- package/dist/server/routes/health.js +2 -3
- package/dist/server/routes/info.d.ts +2 -2
- package/dist/server/routes/info.js +12 -13
- package/dist/server/routes/playbooks.js +16 -29
- package/dist/server/routes/runs.js +95 -117
- package/dist/server/routes/state.js +63 -62
- package/dist/server/server.d.ts +2 -2
- package/dist/server/server.js +43 -227
- package/dist/server/types.d.ts +8 -19
- package/dist/service/factory.d.ts +12 -0
- package/dist/service/factory.js +85 -0
- package/dist/{target → service}/index.d.ts +1 -1
- package/dist/{target → service}/index.js +1 -1
- package/dist/service/local.d.ts +27 -0
- package/dist/service/local.js +138 -0
- package/dist/{target → service}/remote-errors.d.ts +3 -6
- package/dist/service/remote-errors.js +38 -0
- package/dist/{target → service}/remote-polling.d.ts +2 -2
- package/dist/{target → service}/remote-polling.js +8 -8
- package/dist/service/remote.d.ts +34 -0
- package/dist/service/remote.js +634 -0
- package/dist/service/sse-stream.d.ts +24 -0
- package/dist/service/sse-stream.js +139 -0
- package/dist/service/types.d.ts +272 -0
- package/dist/service/types.js +32 -0
- package/dist/storage/data-dir-lock.js +10 -5
- package/dist/storage/driver.d.ts +2 -1
- package/dist/storage/driver.js +3 -52
- package/dist/storage/index.d.ts +1 -0
- package/dist/storage/index.js +1 -0
- package/dist/storage/lock-core.d.ts +2 -6
- package/dist/storage/lock-core.js +4 -17
- package/dist/storage/params.d.ts +2 -8
- package/dist/storage/params.js +2 -8
- package/dist/storage/sqlite-driver.d.ts +40 -0
- package/dist/storage/sqlite-driver.js +116 -0
- package/dist/storage/sqlite.js +21 -6
- package/dist/storage/types.d.ts +4 -4
- package/dist/storage/types.js +2 -2
- package/dist/utils/index.d.ts +53 -0
- package/dist/utils/index.js +99 -4
- package/dist/utils/process.d.ts +10 -0
- package/dist/utils/process.js +21 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +41 -3
- package/dist/app/index.d.ts +0 -2
- package/dist/app/index.js +0 -2
- package/dist/app/types.js +0 -1
- package/dist/catalog/action-index.d.ts +0 -9
- package/dist/catalog/action-index.js +0 -95
- package/dist/catalog/action-resolver.d.ts +0 -20
- package/dist/catalog/action-resolver.js +0 -95
- package/dist/catalog/location-registry.d.ts +0 -15
- package/dist/catalog/location-registry.js +0 -138
- package/dist/catalog/package-catalog.d.ts +0 -7
- package/dist/catalog/package-catalog.js +0 -77
- package/dist/catalog/types.d.ts +0 -68
- package/dist/catalog/types.js +0 -1
- package/dist/export/index.d.ts +0 -1
- package/dist/export/index.js +0 -1
- package/dist/export/templates.d.ts +0 -71
- package/dist/export/templates.js +0 -635
- package/dist/ipc/target.d.ts +0 -74
- package/dist/ipc/target.js +0 -365
- package/dist/platform/default.d.ts +0 -38
- package/dist/platform/default.js +0 -78
- package/dist/project/resolver.d.ts +0 -116
- package/dist/project/resolver.js +0 -376
- package/dist/registry/resolve.d.ts +0 -62
- package/dist/registry/resolve.js +0 -195
- package/dist/runtime/execution-manager.d.ts +0 -48
- package/dist/runtime/execution-manager.js +0 -66
- package/dist/runtime/package-runner-factory.d.ts +0 -82
- package/dist/runtime/package-runner-factory.js +0 -186
- package/dist/target/local.d.ts +0 -53
- package/dist/target/local.js +0 -349
- package/dist/target/remote-errors.js +0 -51
- package/dist/target/remote.d.ts +0 -86
- package/dist/target/remote.js +0 -818
- package/dist/target/target.d.ts +0 -6
- package/dist/target/target.js +0 -37
- package/dist/target/types.d.ts +0 -261
- package/dist/target/types.js +0 -35
- /package/dist/{app → package}/static-index.d.ts +0 -0
- /package/dist/{target → service}/sse-parser.d.ts +0 -0
- /package/dist/{target → service}/sse-parser.js +0 -0
package/dist/runtime/runner.js
CHANGED
|
@@ -1,33 +1,47 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { ActionResolver } from "../catalog/action-resolver.js";
|
|
4
|
-
import { loadActions, loadProjectConfig } from "../project/loader.js";
|
|
5
|
-
import { resolveActionProject } from "../registry/registry.js";
|
|
6
|
-
import { ACTION_CALL_CYCLE, ACTION_CYCLE_DETECTED, ACTION_FAILED, ACTION_MAX_DEPTH_EXCEEDED, ACTION_NOT_FOUND, ACTION_SUBRUN_LIMIT, ACTION_TIMEOUT, describeActionLoadFailure, INPUT_NOT_JSON, MAX_SUBRUNS_REACHED, OUTPUT_NOT_JSON, ACTION_CANCELLED, PACKAGE_NOT_FOUND, INPUT_VALIDATION_FAILED, OUTPUT_VALIDATION_FAILED, UNDECLARED_ACTION_DEPENDENCY, } from "../errors.js";
|
|
1
|
+
import { parseActionRef } from "../catalog/resolve-action.js";
|
|
2
|
+
import { ACTION_FAILED, ACTION_NOT_FOUND, ACTION_TIMEOUT, INPUT_NOT_JSON, OUTPUT_NOT_JSON, ACTION_CANCELLED, INPUT_VALIDATION_FAILED, OUTPUT_VALIDATION_FAILED, INVOCATION_UNSUPPORTED, ActionDockError, } from "../errors.js";
|
|
7
3
|
import { validateSchemaOnly } from "../schema/validator.js";
|
|
4
|
+
import { validateActionInputValue } from "../json/value-validator.js";
|
|
8
5
|
import { createActionContext, StderrLogger } from "./context.js";
|
|
9
|
-
import {
|
|
6
|
+
import { createDefaultProcessOwner } from "../invocation/types.js";
|
|
7
|
+
import { ActionRegistry, findLocalAction, isActionDefinitionObject, resolveAnonymousActionId, } from "./action-registry.js";
|
|
10
8
|
import { buildInitialRunRecord, createRunFinalizer, createRunOrThrow, tryCreateRun, } from "./run-persistence.js";
|
|
11
|
-
import {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
9
|
+
import { validateJsonValue } from "../json/value-validator.js";
|
|
10
|
+
/**
|
|
11
|
+
* 将输入值校验结果映射为标准运行时错误(单一事实源)。
|
|
12
|
+
*
|
|
13
|
+
* json-value 分支映射 INPUT_NOT_JSON(非 JSON 类型值),input-policy 分支映射
|
|
14
|
+
* INPUT_VALIDATION_FAILED(策略违规)并携带 details 数组;start 同步路径与
|
|
15
|
+
* raceExecutionAndAbort 延迟解析路径共用,确保错误码与 details 结构一致。
|
|
16
|
+
*/
|
|
17
|
+
function buildInputValidationError(targetActionId, check) {
|
|
18
|
+
if (check.kind === "json-value") {
|
|
19
|
+
return {
|
|
20
|
+
code: INPUT_NOT_JSON,
|
|
21
|
+
message: `Input validation failed for action '${targetActionId}': ${check.reason}`,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
return {
|
|
25
|
+
code: INPUT_VALIDATION_FAILED,
|
|
26
|
+
message: `Input validation failed for action '${targetActionId}': ${check.reason}`,
|
|
27
|
+
details: [check.reason],
|
|
28
|
+
};
|
|
29
|
+
}
|
|
17
30
|
/**
|
|
18
31
|
* ActionDock 核心执行引擎(ActionRunner)。
|
|
19
32
|
*
|
|
20
33
|
* 本类为执行编排壳:负责 Action 执行的全生命周期编排(校验、深度与环路检测、
|
|
21
34
|
* 超时与取消竞态、子调用 uses 授权与错误分类),并将单一职责域委托至独立模块:
|
|
22
|
-
* - Action 注册与检索委托
|
|
35
|
+
* - Action 注册与检索委托 ActionRegistry(action-registry.ts)
|
|
23
36
|
* - RunRecord 构造与落库委托 run-persistence.ts
|
|
24
|
-
* -
|
|
37
|
+
* - 跨包动作调用委托注入的 ActionInvoker 并重返目标包执行服务
|
|
25
38
|
*
|
|
26
39
|
* 入参 (inputSchema) 与出参 (outputSchema) 的 JSON Schema 严格校验、嵌套 Action
|
|
27
40
|
* 相互调用的环路检测(Cycle Detection)、超时 (Timeout) 与中断信号 (AbortSignal)
|
|
28
41
|
* 竞态控制与运行记录持久化编排仍由本类承担。
|
|
29
42
|
*/
|
|
30
43
|
export class ActionRunner {
|
|
44
|
+
identity;
|
|
31
45
|
packageId;
|
|
32
46
|
packageInstanceId;
|
|
33
47
|
generationId;
|
|
@@ -39,76 +53,41 @@ export class ActionRunner {
|
|
|
39
53
|
registry;
|
|
40
54
|
clock;
|
|
41
55
|
process;
|
|
42
|
-
platform;
|
|
43
|
-
maxCallDepth;
|
|
44
|
-
maxSubRuns;
|
|
45
|
-
activeSubRuns = 0;
|
|
46
|
-
packageFactory;
|
|
47
|
-
actionResolver;
|
|
48
|
-
getStorageForPackage;
|
|
49
56
|
customHome;
|
|
57
|
+
actionResolver;
|
|
50
58
|
hostSessionId;
|
|
59
|
+
actionInvoker;
|
|
51
60
|
constructor(options) {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
61
|
+
if (!options.identity) {
|
|
62
|
+
throw new Error("ActionRunner requires 'identity' PackageIdentity option");
|
|
63
|
+
}
|
|
64
|
+
this.identity = options.identity;
|
|
65
|
+
this.packageId = this.identity.id;
|
|
66
|
+
this.packageInstanceId = this.identity.instanceId;
|
|
67
|
+
this.generationId = this.identity.generation;
|
|
55
68
|
this.hostSessionId = options.hostSessionId;
|
|
56
69
|
this.projectRoot = options.projectRoot;
|
|
57
70
|
this.projectConfig = options.projectConfig;
|
|
58
71
|
this.configOverrides = options.configOverrides || {};
|
|
59
72
|
this.registry = new ActionRegistry(options.actions);
|
|
60
73
|
this.customHome = options.customHome;
|
|
61
|
-
this.
|
|
62
|
-
if (options.platform) {
|
|
63
|
-
this.clock = options.platform.clock;
|
|
64
|
-
this.process = options.platform.process;
|
|
65
|
-
this.storage = options.storage ?? options.platform.storage.createStorage(this.packageId, {
|
|
66
|
-
projectRoot: this.projectRoot,
|
|
67
|
-
customHome: this.customHome,
|
|
68
|
-
// Runner 作为执行宿主组件属于持有者路径,打开时收割遗留孤儿运行
|
|
69
|
-
recoverOrphans: true,
|
|
70
|
-
});
|
|
71
|
-
this.globalStorage = options.globalStorage ?? options.platform.storage.createGlobalStorage({
|
|
72
|
-
customHome: this.customHome,
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
else {
|
|
76
|
-
if (!options.storage) {
|
|
77
|
-
throw new Error("ActionRunner requires either 'storage' or 'platform' option");
|
|
78
|
-
}
|
|
79
|
-
this.storage = options.storage;
|
|
80
|
-
this.globalStorage = options.globalStorage;
|
|
81
|
-
this.process = options.process;
|
|
82
|
-
this.clock = options.clock;
|
|
83
|
-
}
|
|
84
|
-
this.maxCallDepth = options.maxCallDepth ?? 16;
|
|
85
|
-
this.maxSubRuns = options.maxSubRuns ?? 64;
|
|
74
|
+
this.actionInvoker = options.actionInvoker;
|
|
86
75
|
this.actionResolver = options.actionResolver;
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
maxCallDepth: this.maxCallDepth,
|
|
95
|
-
maxSubRuns: this.maxSubRuns,
|
|
96
|
-
actionResolver: this.actionResolver,
|
|
97
|
-
getStorageForPackage: this.getStorageForPackage,
|
|
98
|
-
packageContextResolver: options.packageContextResolver,
|
|
99
|
-
customHome: this.customHome,
|
|
100
|
-
}, (opts) => new ActionRunner(opts));
|
|
76
|
+
if (!options.storage) {
|
|
77
|
+
throw new Error("ActionRunner requires 'storage' option");
|
|
78
|
+
}
|
|
79
|
+
this.storage = options.storage;
|
|
80
|
+
this.globalStorage = options.globalStorage;
|
|
81
|
+
this.clock = options.clock;
|
|
82
|
+
this.process = options.process;
|
|
101
83
|
}
|
|
102
|
-
/** 本地 Action
|
|
84
|
+
/** 本地 Action 注册表底层映射 */
|
|
103
85
|
get actions() {
|
|
104
86
|
return this.registry.map;
|
|
105
87
|
}
|
|
106
88
|
getStorage() {
|
|
107
89
|
return this.storage;
|
|
108
90
|
}
|
|
109
|
-
getPackageRunners() {
|
|
110
|
-
return this.packageFactory.runners;
|
|
111
|
-
}
|
|
112
91
|
registerAction(idOrAction, actionDef) {
|
|
113
92
|
this.registry.registerAction(idOrAction, actionDef);
|
|
114
93
|
}
|
|
@@ -118,11 +97,17 @@ export class ActionRunner {
|
|
|
118
97
|
getAction(id) {
|
|
119
98
|
return this.registry.getAction(id);
|
|
120
99
|
}
|
|
100
|
+
/**
|
|
101
|
+
* 设置子任务动作调用委托器。
|
|
102
|
+
*/
|
|
103
|
+
setActionInvoker(invoker) {
|
|
104
|
+
this.actionInvoker = invoker;
|
|
105
|
+
}
|
|
121
106
|
/**
|
|
122
107
|
* 动态解析 Action(支持本地注册表、自定义解析器委托与已链接包目录索引检索)。
|
|
123
108
|
*
|
|
124
109
|
* @param actionOrRef Action 定义对象、引用或标识符
|
|
125
|
-
* @returns 解析判别联合结果(found | not_found
|
|
110
|
+
* @returns 解析判别联合结果(found | not_found)
|
|
126
111
|
*/
|
|
127
112
|
async resolveAction(actionOrRef) {
|
|
128
113
|
if (isActionDefinitionObject(actionOrRef)) {
|
|
@@ -138,24 +123,26 @@ export class ActionRunner {
|
|
|
138
123
|
}
|
|
139
124
|
const targetActionId = parsed.actionId;
|
|
140
125
|
const targetPackageId = parsed.packageId;
|
|
126
|
+
// 铁律:ActionRunner 仅限执行当前包局部 Action,任何跨包请求直接拒绝,禁止跨包解析和执行
|
|
127
|
+
if (targetPackageId && targetPackageId !== this.packageId) {
|
|
128
|
+
return {
|
|
129
|
+
status: "not_found",
|
|
130
|
+
reason: `Cross-package action '${targetPackageId}/${targetActionId}' cannot be resolved by ActionRunner of package '${this.packageId}'`,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
141
133
|
// 本地 actions 映射表优先检索
|
|
142
134
|
const localMatched = findLocalAction(this.actions, parsed, this.packageId);
|
|
143
135
|
if (localMatched) {
|
|
144
136
|
return { status: "found", action: localMatched };
|
|
145
137
|
}
|
|
146
|
-
//
|
|
138
|
+
// 外部注入的局部 actionResolver 调度
|
|
147
139
|
if (this.actionResolver) {
|
|
148
140
|
try {
|
|
149
|
-
const customResolved = await this.actionResolver(
|
|
141
|
+
const customResolved = await this.actionResolver(targetActionId);
|
|
150
142
|
if (customResolved) {
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
else {
|
|
155
|
-
this.actions.set(targetActionId, customResolved);
|
|
156
|
-
if (this.packageId) {
|
|
157
|
-
this.actions.set(`${this.packageId}/${targetActionId}`, customResolved);
|
|
158
|
-
}
|
|
143
|
+
this.actions.set(targetActionId, customResolved);
|
|
144
|
+
if (this.packageId) {
|
|
145
|
+
this.actions.set(`${this.packageId}/${targetActionId}`, customResolved);
|
|
159
146
|
}
|
|
160
147
|
return { status: "found", action: customResolved };
|
|
161
148
|
}
|
|
@@ -164,61 +151,10 @@ export class ActionRunner {
|
|
|
164
151
|
return { status: "not_found", reason: err.message };
|
|
165
152
|
}
|
|
166
153
|
}
|
|
167
|
-
//
|
|
168
|
-
const identifier = targetPackageId
|
|
169
|
-
? `${targetPackageId}/${targetActionId}`
|
|
170
|
-
: targetActionId;
|
|
171
|
-
let resolved;
|
|
172
|
-
try {
|
|
173
|
-
resolved = await resolveActionProject(identifier, this.projectRoot, this.customHome);
|
|
174
|
-
}
|
|
175
|
-
catch (err) {
|
|
176
|
-
return { status: "not_found", reason: err.message };
|
|
177
|
-
}
|
|
178
|
-
if (!resolved || !existsSync(resolved.projectRoot)) {
|
|
179
|
-
return {
|
|
180
|
-
status: "not_found",
|
|
181
|
-
reason: `Project root not found for action '${identifier}'`,
|
|
182
|
-
};
|
|
183
|
-
}
|
|
184
|
-
let config;
|
|
185
|
-
try {
|
|
186
|
-
config = loadProjectConfig(resolved.projectRoot);
|
|
187
|
-
}
|
|
188
|
-
catch (err) {
|
|
189
|
-
return {
|
|
190
|
-
status: "load_failed",
|
|
191
|
-
error: err instanceof Error ? err : new Error(String(err)),
|
|
192
|
-
packageId: resolved.packageId,
|
|
193
|
-
projectRoot: resolved.projectRoot,
|
|
194
|
-
};
|
|
195
|
-
}
|
|
196
|
-
let actionsMap;
|
|
197
|
-
try {
|
|
198
|
-
actionsMap = await loadActions(resolved.projectRoot, config.actionsDir, {
|
|
199
|
-
loader: this.platform?.modules,
|
|
200
|
-
});
|
|
201
|
-
}
|
|
202
|
-
catch (err) {
|
|
203
|
-
return {
|
|
204
|
-
status: "load_failed",
|
|
205
|
-
error: err instanceof Error ? err : new Error(String(err)),
|
|
206
|
-
packageId: resolved.packageId,
|
|
207
|
-
projectRoot: resolved.projectRoot,
|
|
208
|
-
};
|
|
209
|
-
}
|
|
210
|
-
const matched = actionsMap.get(resolved.actionId);
|
|
211
|
-
if (matched) {
|
|
212
|
-
this.actions.set(`${resolved.packageId}/${resolved.actionId}`, matched);
|
|
213
|
-
// 仅当目标包就是当前项目时才注册短标识符,避免跨包动态载入污染全局短标识符
|
|
214
|
-
if (!targetPackageId || resolved.packageId === this.packageId) {
|
|
215
|
-
this.actions.set(resolved.actionId, matched);
|
|
216
|
-
}
|
|
217
|
-
return { status: "found", action: matched };
|
|
218
|
-
}
|
|
154
|
+
// 铁律 4:Runner 不找 Package:只能执行自己所属 Package 的 Action
|
|
219
155
|
return {
|
|
220
156
|
status: "not_found",
|
|
221
|
-
reason: `Action '${
|
|
157
|
+
reason: `Action '${targetActionId}' not found in package '${this.packageId}'`,
|
|
222
158
|
};
|
|
223
159
|
}
|
|
224
160
|
/**
|
|
@@ -227,22 +163,6 @@ export class ActionRunner {
|
|
|
227
163
|
listActions() {
|
|
228
164
|
return this.registry.listActions();
|
|
229
165
|
}
|
|
230
|
-
/**
|
|
231
|
-
* 注入或更新跨包运行上下文解析委托。
|
|
232
|
-
*/
|
|
233
|
-
setPackageContextResolver(resolver) {
|
|
234
|
-
this.packageFactory.setPackageContextResolver(resolver);
|
|
235
|
-
}
|
|
236
|
-
/**
|
|
237
|
-
* 跨包运行时解析与获取(确保跨包执行具备独立的配置、存储、状态与 Action 注册表)。
|
|
238
|
-
*
|
|
239
|
-
* 缓存 miss 后存在长异步窗口(加载配置、扫描 Action、打开存储),并发调用会重复构建
|
|
240
|
-
* Runner、重复打开 SQLite 连接且子任务限流计数分裂;故以 in-flight Promise 去重,
|
|
241
|
-
* 并发方 await 同一构建任务,构建失败时移除该 Promise 以便后续重试。
|
|
242
|
-
*/
|
|
243
|
-
async resolveTargetPackageRunner(targetPackageId) {
|
|
244
|
-
return this.packageFactory.resolveTargetPackageRunner(targetPackageId);
|
|
245
|
-
}
|
|
246
166
|
/**
|
|
247
167
|
* 异步启动 Action 的执行并立即返回 ExecutionHandle 句柄。
|
|
248
168
|
*
|
|
@@ -257,16 +177,7 @@ export class ActionRunner {
|
|
|
257
177
|
// 输入参数 JSON 格式与合法性防御校验(拦截 NaN/Infinity/循环引用等非 JSON 类型及非法原型键策略违规)
|
|
258
178
|
const inputCheck = validateActionInputValue(input);
|
|
259
179
|
if (!inputCheck.valid) {
|
|
260
|
-
const error = inputCheck
|
|
261
|
-
? {
|
|
262
|
-
code: INPUT_NOT_JSON,
|
|
263
|
-
message: `Input validation failed for action '${targetActionId}': ${inputCheck.reason}`,
|
|
264
|
-
}
|
|
265
|
-
: {
|
|
266
|
-
code: INPUT_VALIDATION_FAILED,
|
|
267
|
-
message: `Input validation failed for action '${targetActionId}': ${inputCheck.reason}`,
|
|
268
|
-
details: [inputCheck.reason],
|
|
269
|
-
};
|
|
180
|
+
const error = buildInputValidationError(targetActionId, inputCheck);
|
|
270
181
|
// 安全记录 failed 状态(不可序列化或策略违规的非法 input 严禁直接写入持久化存储)
|
|
271
182
|
tryCreateRun(this.storage, buildInitialRunRecord(this.buildRunPersistenceInput(runCtx), "failed", error));
|
|
272
183
|
return {
|
|
@@ -278,27 +189,15 @@ export class ActionRunner {
|
|
|
278
189
|
// 始终优先将执行尝试持久化到存储中(确保任意异常与终态都可追溯)
|
|
279
190
|
createRunOrThrow(this.storage, buildInitialRunRecord(this.buildRunPersistenceInput(runCtx), "running"));
|
|
280
191
|
const finalizer = createRunFinalizer(this.storage, runCtx.runId);
|
|
281
|
-
//
|
|
282
|
-
const
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
};
|
|
192
|
+
// 记录调用栈快照(供子任务追溯,若已处于调用栈顶则不重复追加)
|
|
193
|
+
const callKey = targetPackageId ? `${targetPackageId}/${targetActionId}` : targetActionId;
|
|
194
|
+
const lastStackItem = runCtx.callStack[runCtx.callStack.length - 1];
|
|
195
|
+
const isAlreadyAtTop = lastStackItem === callKey ||
|
|
196
|
+
(targetActionId && lastStackItem === targetActionId) ||
|
|
197
|
+
(targetPackageId && lastStackItem === `${targetPackageId}/${targetActionId}`);
|
|
198
|
+
if (!isAlreadyAtTop) {
|
|
199
|
+
runCtx.callStack.push(callKey);
|
|
290
200
|
}
|
|
291
|
-
// 环路死锁检测 (Cycle Detection)
|
|
292
|
-
const cycle = this.computeCallKey(runCtx.callStack, targetActionId, targetPackageId);
|
|
293
|
-
if (cycle.error) {
|
|
294
|
-
finalizer.finalize("failed", undefined, cycle.error);
|
|
295
|
-
return {
|
|
296
|
-
runId,
|
|
297
|
-
result: Promise.resolve({ ok: false, runId, error: cycle.error }),
|
|
298
|
-
cancel: () => false,
|
|
299
|
-
};
|
|
300
|
-
}
|
|
301
|
-
runCtx.callStack.push(cycle.callKey);
|
|
302
201
|
// 输入参数 JSON Schema 校验(若 action 已就绪)
|
|
303
202
|
const schemaError = this.checkActionInputSchema(runCtx.action, targetActionId, input);
|
|
304
203
|
if (schemaError) {
|
|
@@ -368,9 +267,9 @@ export class ActionRunner {
|
|
|
368
267
|
* 预解析执行目标并装配运行期共享上下文对象(runId、目标标识、时钟源与调用栈快照)。
|
|
369
268
|
*/
|
|
370
269
|
prepareRunContext(actionOrId, input, options) {
|
|
371
|
-
const runId = options.runId || randomUUID();
|
|
372
|
-
const effectiveClock = options.
|
|
373
|
-
const effectiveProcess = options.process ||
|
|
270
|
+
const runId = options.runId || crypto.randomUUID();
|
|
271
|
+
const effectiveClock = options.clock ?? this.clock;
|
|
272
|
+
const effectiveProcess = options.process || this.process;
|
|
374
273
|
const startedAt = effectiveClock?.now().toISOString() ||
|
|
375
274
|
(typeof this.storage.clock?.now === "function"
|
|
376
275
|
? this.storage.clock.now().toISOString()
|
|
@@ -434,44 +333,6 @@ export class ActionRunner {
|
|
|
434
333
|
runnerHostSessionId: this.hostSessionId,
|
|
435
334
|
};
|
|
436
335
|
}
|
|
437
|
-
/**
|
|
438
|
-
* 调用嵌套深度限制检测(超限时返回 ACTION_CALL_CYCLE 错误)。
|
|
439
|
-
*/
|
|
440
|
-
checkCallDepth(callStack, targetActionId, options) {
|
|
441
|
-
// 执行级 options.maxCallDepth 可覆盖构造级默认值,保留原覆盖契约
|
|
442
|
-
const maxDepth = options.maxCallDepth ?? this.maxCallDepth;
|
|
443
|
-
if (callStack.length >= maxDepth) {
|
|
444
|
-
return {
|
|
445
|
-
code: ACTION_CALL_CYCLE,
|
|
446
|
-
message: `Maximum call depth of ${maxDepth} exceeded: ${callStack.join(" -> ")} -> ${targetActionId}`,
|
|
447
|
-
details: { alias: ACTION_MAX_DEPTH_EXCEEDED, reason: "depth_exceeded", maxDepth, callStack: [...callStack] },
|
|
448
|
-
};
|
|
449
|
-
}
|
|
450
|
-
return undefined;
|
|
451
|
-
}
|
|
452
|
-
/**
|
|
453
|
-
* 计算调用键并执行环路死锁检测(命中时返回携带错误的调用键结果)。
|
|
454
|
-
*/
|
|
455
|
-
computeCallKey(callStack, targetActionId, targetPackageId) {
|
|
456
|
-
const isExternal = Boolean(targetPackageId && targetPackageId !== this.packageId);
|
|
457
|
-
const callKey = isExternal
|
|
458
|
-
? `${targetPackageId}/${targetActionId}`
|
|
459
|
-
: targetActionId;
|
|
460
|
-
const hasCycle = isExternal
|
|
461
|
-
? callStack.includes(callKey)
|
|
462
|
-
: (callStack.includes(callKey) || (this.packageId ? callStack.includes(`${this.packageId}/${targetActionId}`) : false));
|
|
463
|
-
if (hasCycle) {
|
|
464
|
-
return {
|
|
465
|
-
callKey,
|
|
466
|
-
error: {
|
|
467
|
-
code: ACTION_CALL_CYCLE,
|
|
468
|
-
message: `Cycle detected in action invocation: ${callStack.join(" -> ")} -> ${callKey}`,
|
|
469
|
-
details: { alias: ACTION_CYCLE_DETECTED, reason: "cycle_detected", callStack: [...callStack], target: callKey },
|
|
470
|
-
},
|
|
471
|
-
};
|
|
472
|
-
}
|
|
473
|
-
return { callKey };
|
|
474
|
-
}
|
|
475
336
|
/**
|
|
476
337
|
* 输入参数 JSON Schema 校验(若 action 已就绪,返回校验错误或 undefined)。
|
|
477
338
|
*/
|
|
@@ -497,12 +358,13 @@ export class ActionRunner {
|
|
|
497
358
|
buildActionContext(args) {
|
|
498
359
|
const { runCtx, controller, rootRunId } = args;
|
|
499
360
|
const { options, targetPackageId, targetActionId, effectiveProcess } = runCtx;
|
|
500
|
-
const effectiveOwner = options.owner ||
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
361
|
+
const effectiveOwner = options.owner ||
|
|
362
|
+
createDefaultProcessOwner({
|
|
363
|
+
tenantId: options.tenantId,
|
|
364
|
+
principalId: options.principalId || options.ownerId,
|
|
365
|
+
packageInstanceId: options.packageInstanceId || this.packageInstanceId,
|
|
366
|
+
generationId: options.generationId || this.generationId,
|
|
367
|
+
});
|
|
506
368
|
return createActionContext({
|
|
507
369
|
actionId: targetActionId,
|
|
508
370
|
storage: this.storage,
|
|
@@ -528,121 +390,51 @@ export class ActionRunner {
|
|
|
528
390
|
});
|
|
529
391
|
}
|
|
530
392
|
/**
|
|
531
|
-
* 子 Action
|
|
393
|
+
* 子 Action 调用委托:
|
|
394
|
+
* 必须委托 Host 动作调用器(走 Host 执行主链与 InvocationPolicy 鉴权);
|
|
395
|
+
* 缺少 actionInvoker 时直接抛出 INVOCATION_UNSUPPORTED,严禁跨包或同包无约束执行逃逸。
|
|
532
396
|
*/
|
|
533
397
|
async invokeChildAction(args) {
|
|
534
398
|
const { runCtx, controller, rootRunId, childAction, childInput, parentRunId } = args;
|
|
535
|
-
const { options,
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
}
|
|
547
|
-
const childActionId = parsed.actionId;
|
|
548
|
-
const effectiveParentOwner = options.owner || {
|
|
549
|
-
tenantId: options.tenantId || "default",
|
|
550
|
-
principalId: options.principalId || options.ownerId || "default",
|
|
551
|
-
packageInstanceId: options.packageInstanceId || this.packageInstanceId || this.packageId,
|
|
552
|
-
generationId: options.generationId || this.generationId || "1",
|
|
553
|
-
};
|
|
554
|
-
const isSamePackage = !childPackageId || childPackageId === this.packageId;
|
|
555
|
-
this.activeSubRuns++;
|
|
556
|
-
try {
|
|
557
|
-
const runnerToUse = await this.resolveChildRunner(childPackageId, childActionId);
|
|
558
|
-
if (runnerToUse !== this) {
|
|
559
|
-
this.assertDeclaredUses(runCtx.action, targetActionId, childPackageId, childActionId);
|
|
560
|
-
}
|
|
561
|
-
const childPackageInstanceId = isSamePackage
|
|
562
|
-
? effectiveParentOwner.packageInstanceId
|
|
563
|
-
: (runnerToUse !== this ? runnerToUse.packageInstanceId : childPackageId);
|
|
564
|
-
const childGenerationId = isSamePackage
|
|
565
|
-
? effectiveParentOwner.generationId
|
|
566
|
-
: (runnerToUse !== this ? runnerToUse.generationId : "1");
|
|
567
|
-
const childOwner = {
|
|
568
|
-
tenantId: effectiveParentOwner.tenantId,
|
|
569
|
-
principalId: effectiveParentOwner.principalId,
|
|
570
|
-
packageInstanceId: childPackageInstanceId,
|
|
571
|
-
generationId: childGenerationId,
|
|
572
|
-
};
|
|
573
|
-
const childResult = await runnerToUse.execute(childAction, childInput, {
|
|
574
|
-
rootRunId,
|
|
575
|
-
parentRunId,
|
|
576
|
-
callStack,
|
|
577
|
-
signal: controller.signal,
|
|
578
|
-
process: effectiveProcess,
|
|
579
|
-
platform: options.platform || this.platform,
|
|
580
|
-
progress: options.progress,
|
|
581
|
-
logger: options.logger,
|
|
582
|
-
configOverrides: options.configOverrides,
|
|
583
|
-
maxCallDepth: options.maxCallDepth ?? this.maxCallDepth,
|
|
584
|
-
tenantId: childOwner.tenantId,
|
|
585
|
-
principalId: childOwner.principalId,
|
|
586
|
-
ownerId: childOwner.principalId,
|
|
587
|
-
packageInstanceId: childOwner.packageInstanceId,
|
|
588
|
-
generationId: childOwner.generationId,
|
|
589
|
-
owner: childOwner,
|
|
590
|
-
hostSessionId: options.hostSessionId ?? this.hostSessionId,
|
|
399
|
+
const { options, effectiveProcess, callStack } = runCtx;
|
|
400
|
+
const invoker = options.actionInvoker || this.actionInvoker;
|
|
401
|
+
if (!invoker) {
|
|
402
|
+
throw new ActionDockError(INVOCATION_UNSUPPORTED, "Nested action invocation requires a Host ActionInvoker");
|
|
403
|
+
}
|
|
404
|
+
const effectiveParentOwner = options.owner ||
|
|
405
|
+
createDefaultProcessOwner({
|
|
406
|
+
tenantId: options.tenantId,
|
|
407
|
+
principalId: options.principalId || options.ownerId,
|
|
408
|
+
packageInstanceId: this.packageInstanceId,
|
|
409
|
+
generationId: this.generationId,
|
|
591
410
|
});
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
err.details = {
|
|
620
|
-
caller: `${this.packageId}/${targetActionId}`,
|
|
621
|
-
target: targetRef,
|
|
622
|
-
declaredUses: rawUses,
|
|
623
|
-
};
|
|
624
|
-
throw err;
|
|
625
|
-
}
|
|
626
|
-
}
|
|
627
|
-
/**
|
|
628
|
-
* 解析子调用应使用的 Runner(本包或已解析的目标包 Runner)。
|
|
629
|
-
*/
|
|
630
|
-
async resolveChildRunner(childPackageId, childActionId) {
|
|
631
|
-
if (childPackageId && childPackageId !== this.packageId) {
|
|
632
|
-
const targetRunner = await this.resolveTargetPackageRunner(childPackageId);
|
|
633
|
-
if (targetRunner) {
|
|
634
|
-
return targetRunner;
|
|
635
|
-
}
|
|
636
|
-
if (this.actions.has(`${childPackageId}/${childActionId}`)) {
|
|
637
|
-
return this;
|
|
638
|
-
}
|
|
639
|
-
if (!this.actionResolver) {
|
|
640
|
-
const err = new Error(`Package '${childPackageId}' could not be resolved`);
|
|
641
|
-
err.code = PACKAGE_NOT_FOUND;
|
|
642
|
-
throw err;
|
|
643
|
-
}
|
|
644
|
-
}
|
|
645
|
-
return this;
|
|
411
|
+
const childRunId = crypto.randomUUID();
|
|
412
|
+
const invocationContext = {
|
|
413
|
+
runId: childRunId,
|
|
414
|
+
rootRunId,
|
|
415
|
+
parentRunId: parentRunId || runCtx.runId,
|
|
416
|
+
caller: {
|
|
417
|
+
packageId: this.packageId,
|
|
418
|
+
actionId: runCtx.targetActionId,
|
|
419
|
+
runId: runCtx.runId,
|
|
420
|
+
declaredUses: runCtx.action?.uses ||
|
|
421
|
+
this.projectConfig?.actions?.[runCtx.targetActionId]?.uses,
|
|
422
|
+
},
|
|
423
|
+
callStack: [...callStack],
|
|
424
|
+
package: this.identity,
|
|
425
|
+
signal: controller.signal,
|
|
426
|
+
timeoutMs: options.timeoutMs,
|
|
427
|
+
maxCallDepth: options.maxCallDepth,
|
|
428
|
+
config: options.configOverrides,
|
|
429
|
+
tenantId: effectiveParentOwner.tenantId,
|
|
430
|
+
principalId: effectiveParentOwner.principalId,
|
|
431
|
+
hostSessionId: options.hostSessionId || this.hostSessionId,
|
|
432
|
+
logger: options.logger,
|
|
433
|
+
progress: options.progress,
|
|
434
|
+
process: effectiveProcess,
|
|
435
|
+
owner: effectiveParentOwner,
|
|
436
|
+
};
|
|
437
|
+
return await invoker(childAction, childInput, invocationContext);
|
|
646
438
|
}
|
|
647
439
|
/**
|
|
648
440
|
* 执行 Action 业务逻辑并与取消/超时信号进行竞态,返回执行结果信封 Promise。
|
|
@@ -672,16 +464,6 @@ export class ActionRunner {
|
|
|
672
464
|
currentAction = resolution.action;
|
|
673
465
|
runCtx.action = currentAction;
|
|
674
466
|
}
|
|
675
|
-
else if (resolution.status === "load_failed") {
|
|
676
|
-
const cause = resolution.error;
|
|
677
|
-
const error = describeActionLoadFailure(cause, {
|
|
678
|
-
actionId: targetActionId,
|
|
679
|
-
packageId: resolution.packageId,
|
|
680
|
-
projectRoot: resolution.projectRoot,
|
|
681
|
-
});
|
|
682
|
-
finalizer.finalize("failed", undefined, error);
|
|
683
|
-
return { ok: false, runId, error };
|
|
684
|
-
}
|
|
685
467
|
else {
|
|
686
468
|
const error = {
|
|
687
469
|
code: ACTION_NOT_FOUND,
|
|
@@ -693,16 +475,7 @@ export class ActionRunner {
|
|
|
693
475
|
}
|
|
694
476
|
const inputCheck = validateActionInputValue(input);
|
|
695
477
|
if (!inputCheck.valid) {
|
|
696
|
-
const error = inputCheck
|
|
697
|
-
? {
|
|
698
|
-
code: INPUT_NOT_JSON,
|
|
699
|
-
message: `Input validation failed for action '${targetActionId}': ${inputCheck.reason}`,
|
|
700
|
-
}
|
|
701
|
-
: {
|
|
702
|
-
code: INPUT_VALIDATION_FAILED,
|
|
703
|
-
message: `Input validation failed for action '${targetActionId}': ${inputCheck.reason}`,
|
|
704
|
-
details: [inputCheck.reason],
|
|
705
|
-
};
|
|
478
|
+
const error = buildInputValidationError(targetActionId, inputCheck);
|
|
706
479
|
finalizer.finalize("failed", undefined, error);
|
|
707
480
|
return { ok: false, runId, error };
|
|
708
481
|
}
|
|
@@ -819,15 +592,10 @@ export class ActionRunner {
|
|
|
819
592
|
};
|
|
820
593
|
}
|
|
821
594
|
/**
|
|
822
|
-
* 释放 Runner
|
|
823
|
-
*
|
|
824
|
-
* 幂等且并发安全:重复调用直接复用首次 Promise;子包存储异常不阻断其余释放;
|
|
825
|
-
* 仅关闭由本 Runner 构建子包 Runner 时独立创建的存储,外部注入的存储(如经
|
|
826
|
-
* packageContextResolver 传入的目标包自身存储)生命周期归所有者管理,不在此误关。
|
|
595
|
+
* 释放 Runner 持有的资源。
|
|
596
|
+
* 铁律 4:Runner 仅执行自己所属 Package 的 Action,不管理外部包生命周期。
|
|
827
597
|
*/
|
|
828
|
-
async dispose() {
|
|
829
|
-
return this.packageFactory.dispose();
|
|
830
|
-
}
|
|
598
|
+
async dispose() { }
|
|
831
599
|
/**
|
|
832
600
|
* 同步等待方式执行指定 Action,直接返回 ExecutionResult 信封结果。
|
|
833
601
|
*
|