@actiondock/core 2.10.0 → 2.12.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 +1 -2
- package/dist/catalog/action-catalog.js +3 -33
- package/dist/catalog/discovery.d.ts +0 -3
- package/dist/catalog/discovery.js +4 -4
- package/dist/catalog/graph.d.ts +0 -4
- package/dist/catalog/graph.js +8 -14
- package/dist/{profile/client-actions.d.ts → client/actions.d.ts} +1 -1
- package/dist/{profile/client-actions.js → client/actions.js} +2 -8
- package/dist/{profile/client-config.d.ts → client/config.d.ts} +1 -1
- package/dist/{profile/client-config.js → client/config.js} +1 -1
- package/dist/client/dispatcher.d.ts +4 -0
- package/dist/client/dispatcher.js +21 -0
- package/dist/client/health.d.ts +38 -0
- package/dist/{profile/client-health.js → client/health.js} +9 -6
- package/dist/client/index.d.ts +16 -0
- package/dist/client/index.js +20 -0
- package/dist/{profile/client-playbooks.d.ts → client/playbooks.d.ts} +1 -1
- package/dist/{profile/client-playbooks.js → client/playbooks.js} +1 -1
- package/dist/{profile/client-runs.d.ts → client/runs.d.ts} +4 -2
- package/dist/{profile/client-runs.js → client/runs.js} +7 -1
- package/dist/{profile/client-state.d.ts → client/state.d.ts} +1 -1
- package/dist/{profile/client-state.js → client/state.js} +1 -1
- package/dist/{profile/client-transport.d.ts → client/transport.d.ts} +29 -10
- package/dist/{profile/client-transport.js → client/transport.js} +125 -35
- package/dist/doctor/checks/index.d.ts +1 -1
- package/dist/doctor/checks/index.js +1 -1
- package/dist/doctor/checks/project.js +20 -88
- package/dist/doctor/checks/runtime.d.ts +0 -4
- package/dist/doctor/checks/runtime.js +0 -28
- package/dist/doctor/doctor.js +1 -2
- package/dist/errors.d.ts +53 -3
- package/dist/errors.js +53 -3
- package/dist/execution/service.d.ts +55 -37
- package/dist/execution/service.js +601 -212
- package/dist/execution/types.d.ts +24 -5
- package/dist/host/host.d.ts +42 -22
- package/dist/host/host.js +562 -149
- package/dist/host/routing.js +6 -6
- package/dist/host/types.d.ts +25 -13
- package/dist/index.d.ts +9 -4
- package/dist/index.js +5 -2
- package/dist/input/advice.d.ts +0 -44
- package/dist/input/advice.js +7 -141
- package/dist/input/flat-materializer.js +1 -1
- package/dist/input/flat-parser.js +1 -1
- package/dist/input/index.d.ts +0 -1
- package/dist/input/index.js +0 -1
- package/dist/input/input-resolver.js +1 -1
- package/dist/input/validation-mapper.d.ts +1 -1
- package/dist/ipc/diagnostic.d.ts +8 -21
- package/dist/ipc/diagnostic.js +24 -57
- package/dist/ipc/host.js +21 -7
- package/dist/ipc/service.d.ts +14 -0
- package/dist/ipc/service.js +132 -26
- package/dist/ipc/types.d.ts +0 -4
- package/dist/package/index.d.ts +4 -5
- package/dist/package/index.js +1 -2
- package/dist/package/runtime.d.ts +94 -23
- package/dist/package/runtime.js +628 -274
- package/dist/package/static-index.d.ts +3 -6
- package/dist/package/static-index.js +11 -40
- package/dist/package/types.d.ts +19 -4
- package/dist/platform/index.d.ts +2 -1
- package/dist/platform/index.js +2 -1
- package/dist/platform/loader-hook.d.ts +32 -0
- package/dist/platform/loader-hook.js +90 -0
- package/dist/{node → platform}/module-loader.d.ts +13 -0
- package/dist/{node → platform}/module-loader.js +51 -4
- package/dist/platform/node.d.ts +19 -8
- package/dist/platform/node.js +50 -20
- package/dist/platform/types.d.ts +7 -47
- package/dist/process/context-process.d.ts +3 -18
- package/dist/process/context-process.js +3 -44
- package/dist/process/control.d.ts +21 -0
- package/dist/process/control.js +34 -0
- package/dist/process/converters.d.ts +23 -0
- package/dist/process/converters.js +92 -0
- package/dist/process/cursor.js +2 -22
- package/dist/process/{diagnostics-sink.d.ts → diagnostics.d.ts} +0 -7
- package/dist/process/{diagnostics-sink.js → diagnostics.js} +6 -8
- package/dist/process/index.d.ts +1 -3
- package/dist/process/index.js +1 -3
- package/dist/process/input-dispatcher.d.ts +4 -13
- package/dist/process/input-dispatcher.js +48 -69
- package/dist/process/managed-record.d.ts +3 -31
- package/dist/process/metadata-store.d.ts +0 -41
- package/dist/process/metadata-store.js +2 -341
- package/dist/process/process-driver.js +2 -2
- package/dist/process/process-manager.d.ts +8 -50
- package/dist/process/process-manager.js +28 -417
- package/dist/process/quotas.d.ts +14 -0
- package/dist/process/quotas.js +29 -0
- package/dist/process/run-executor.js +0 -1
- package/dist/process/terminal-output-cache.d.ts +20 -34
- package/dist/process/terminal-output-cache.js +43 -64
- package/dist/profile/index.d.ts +1 -2
- package/dist/profile/index.js +1 -2
- package/dist/profile/manager.d.ts +2 -4
- package/dist/profile/manager.js +10 -40
- package/dist/profile/types.d.ts +1 -17
- package/dist/project/digest.d.ts +5 -1
- package/dist/project/digest.js +81 -219
- package/dist/project/index.d.ts +4 -5
- package/dist/project/index.js +4 -5
- package/dist/project/init.js +2 -2
- package/dist/project/loader.d.ts +3 -3
- package/dist/project/loader.js +72 -50
- package/dist/project/lockfile.js +6 -5
- package/dist/project/manifest.js +5 -4
- package/dist/project/transactions.d.ts +4 -42
- package/dist/project/transactions.js +83 -138
- package/dist/project/types-generator.js +2 -1
- package/dist/project/types.d.ts +2 -0
- package/dist/registry/index.d.ts +0 -1
- package/dist/registry/index.js +0 -1
- package/dist/registry/lock.d.ts +2 -11
- package/dist/registry/lock.js +14 -183
- package/dist/registry/registry.d.ts +1 -6
- package/dist/registry/registry.js +5 -17
- package/dist/runtime/action-registry.d.ts +1 -5
- package/dist/runtime/action-registry.js +0 -12
- package/dist/runtime/context.js +2 -2
- package/dist/runtime/events.d.ts +11 -50
- package/dist/runtime/events.js +88 -368
- package/dist/runtime/index.d.ts +0 -4
- package/dist/runtime/index.js +0 -4
- package/dist/runtime/run-persistence.d.ts +2 -0
- package/dist/runtime/run-persistence.js +2 -1
- package/dist/runtime/standalone-commands.d.ts +18 -0
- package/dist/runtime/standalone-commands.js +466 -0
- package/dist/runtime/standalone-help.d.ts +20 -0
- package/dist/runtime/standalone-help.js +72 -0
- package/dist/runtime/standalone.d.ts +1 -44
- package/dist/runtime/standalone.js +32 -573
- package/dist/schema/validator.d.ts +2 -2
- package/dist/schema/validator.js +2 -9
- package/dist/server/index.d.ts +0 -2
- package/dist/server/index.js +0 -2
- package/dist/server/routes/actions.js +1 -1
- package/dist/server/routes/info.js +1 -1
- package/dist/server/routes/playbooks.js +1 -1
- package/dist/server/routes/runs.js +123 -16
- package/dist/server/routes/state.js +43 -18
- package/dist/server/security.d.ts +1 -1
- package/dist/server/security.js +2 -2
- package/dist/server/server.js +3 -7
- package/dist/service/factory.js +4 -3
- package/dist/service/index.d.ts +1 -1
- package/dist/service/index.js +1 -1
- package/dist/service/remote-errors.d.ts +1 -1
- package/dist/service/remote-errors.js +6 -6
- package/dist/service/remote-polling.d.ts +3 -0
- package/dist/service/remote-polling.js +10 -5
- package/dist/service/remote.d.ts +5 -1
- package/dist/service/remote.js +108 -17
- package/dist/service/sse-stream.js +2 -2
- package/dist/service/types.d.ts +22 -19
- package/dist/service/types.js +1 -24
- package/dist/storage/clock.d.ts +1 -1
- package/dist/storage/clock.js +1 -1
- package/dist/storage/data-dir-lock.d.ts +10 -22
- package/dist/storage/data-dir-lock.js +28 -56
- package/dist/storage/file-lock.d.ts +64 -0
- package/dist/storage/file-lock.js +447 -0
- package/dist/storage/index.d.ts +2 -2
- package/dist/storage/index.js +5 -4
- package/dist/storage/run-liveness.d.ts +48 -0
- package/dist/storage/run-liveness.js +44 -0
- package/dist/storage/sqlite-config.d.ts +16 -0
- package/dist/storage/sqlite-config.js +59 -0
- package/dist/storage/sqlite-driver.d.ts +3 -1
- package/dist/storage/sqlite-driver.js +14 -4
- package/dist/storage/sqlite-events.d.ts +13 -0
- package/dist/storage/sqlite-events.js +48 -0
- package/dist/storage/sqlite-runs.d.ts +107 -0
- package/dist/storage/sqlite-runs.js +622 -0
- package/dist/storage/sqlite-schema.d.ts +5 -0
- package/dist/storage/sqlite-schema.js +143 -0
- package/dist/storage/sqlite-state.d.ts +33 -0
- package/dist/storage/sqlite-state.js +270 -0
- package/dist/storage/sqlite.d.ts +30 -57
- package/dist/storage/sqlite.js +84 -741
- package/dist/storage/types.d.ts +35 -2
- package/dist/utils/index.d.ts +18 -14
- package/dist/utils/index.js +37 -29
- package/dist/utils/semver.d.ts +18 -0
- package/dist/utils/semver.js +19 -0
- package/dist/utils/warning.d.ts +1 -0
- package/dist/utils/warning.js +52 -0
- package/dist/{json/value-validator.d.ts → value-validator.d.ts} +9 -0
- package/dist/value-validator.js +330 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +10 -12
- package/dist/execution/index.d.ts +0 -2
- package/dist/execution/index.js +0 -2
- package/dist/filter/index.d.ts +0 -1
- package/dist/filter/index.js +0 -1
- package/dist/graph/index.d.ts +0 -4
- package/dist/graph/index.js +0 -4
- package/dist/input/metadata.d.ts +0 -99
- package/dist/input/metadata.js +0 -99
- package/dist/invocation/index.d.ts +0 -2
- package/dist/invocation/index.js +0 -2
- package/dist/ipc/index.d.ts +0 -4
- package/dist/ipc/index.js +0 -4
- package/dist/json/index.d.ts +0 -1
- package/dist/json/index.js +0 -1
- package/dist/json/value-validator.js +0 -330
- package/dist/node/index.d.ts +0 -1
- package/dist/node/index.js +0 -1
- package/dist/platform/node-fs.d.ts +0 -37
- package/dist/platform/node-fs.js +0 -81
- package/dist/process/control-arbiter.d.ts +0 -108
- package/dist/process/control-arbiter.js +0 -250
- package/dist/process/process-executor.d.ts +0 -47
- package/dist/process/process-executor.js +0 -296
- package/dist/profile/client-health.d.ts +0 -14
- package/dist/profile/client-query.d.ts +0 -30
- package/dist/profile/client-query.js +0 -69
- package/dist/profile/client.d.ts +0 -26
- package/dist/profile/client.js +0 -31
- package/dist/project/closure.d.ts +0 -25
- package/dist/project/closure.js +0 -74
- package/dist/registry/store.d.ts +0 -42
- package/dist/registry/store.js +0 -43
- package/dist/runtime/clock.d.ts +0 -7
- package/dist/runtime/clock.js +0 -7
- package/dist/runtime/module-loader.d.ts +0 -2
- package/dist/runtime/module-loader.js +0 -1
- package/dist/runtime/process.d.ts +0 -8
- package/dist/runtime/process.js +0 -1
- package/dist/runtime/runner.d.ts +0 -234
- package/dist/runtime/runner.js +0 -609
- package/dist/schema/index.d.ts +0 -1
- package/dist/schema/index.js +0 -1
- package/dist/server/dispatcher.d.ts +0 -25
- package/dist/server/dispatcher.js +0 -54
- package/dist/service/local.d.ts +0 -27
- package/dist/service/local.js +0 -141
- package/dist/storage/driver.d.ts +0 -10
- package/dist/storage/driver.js +0 -10
- package/dist/storage/lazy.d.ts +0 -8
- package/dist/storage/lazy.js +0 -45
- package/dist/storage/lock-core.d.ts +0 -158
- package/dist/storage/lock-core.js +0 -872
- package/dist/utils/net.d.ts +0 -10
- package/dist/utils/net.js +0 -16
- package/dist/utils/process.d.ts +0 -10
- package/dist/utils/process.js +0 -21
- /package/dist/{filter → utils}/intent.d.ts +0 -0
- /package/dist/{filter → utils}/intent.js +0 -0
package/dist/schema/validator.js
CHANGED
|
@@ -18,15 +18,8 @@ const validatorCache = new WeakMap();
|
|
|
18
18
|
/**
|
|
19
19
|
* 递归检查数据中是否包含危险的原型污染属性键名(__proto__、constructor、prototype)。
|
|
20
20
|
*/
|
|
21
|
-
import {
|
|
22
|
-
|
|
23
|
-
* 递归检查数据中是否包含危险的原型污染属性键名(__proto__、constructor、prototype)。
|
|
24
|
-
* 内部委托 validateActionInputValue 执行迭代遍历,确保环路安全、有向无环图安全且无调用栈溢出风险。
|
|
25
|
-
*/
|
|
26
|
-
export function hasDangerousKeys(data) {
|
|
27
|
-
const result = validateActionInputValue(data);
|
|
28
|
-
return !result.valid && result.kind === "input-policy";
|
|
29
|
-
}
|
|
21
|
+
import { hasDangerousKeys } from "../value-validator.js";
|
|
22
|
+
export { hasDangerousKeys };
|
|
30
23
|
/**
|
|
31
24
|
* 内部纯 Schema 校验器。
|
|
32
25
|
* 仅处理布尔 Schema 与 Ajv 规则校验,严禁执行 dangerous-key 遍历。
|
package/dist/server/index.d.ts
CHANGED
|
@@ -5,7 +5,6 @@ export * from "./body.js";
|
|
|
5
5
|
export * from "./routes/index.js";
|
|
6
6
|
export * from "./server.js";
|
|
7
7
|
export * from "./mcp-endpoint.js";
|
|
8
|
-
export * from "./dispatcher.js";
|
|
9
8
|
export * from "./http-server.js";
|
|
10
9
|
export { serveParentIpc } from "../ipc/host.js";
|
|
11
10
|
export { IpcActionDockService } from "../ipc/service.js";
|
|
@@ -13,6 +12,5 @@ export type { IpcServiceOptions } from "../ipc/types.js";
|
|
|
13
12
|
export { parseDuration } from "../utils/index.js";
|
|
14
13
|
export type { ActionDockHost, ActionDockHostOptions, } from "../host/types.js";
|
|
15
14
|
export { createActionDockHost, DefaultActionDockHost, } from "../host/host.js";
|
|
16
|
-
export { LocalActionDockService, } from "../service/local.js";
|
|
17
15
|
export { RemoteActionDockService, } from "../service/remote.js";
|
|
18
16
|
export { ExitCode, StandaloneDispatcher, type StandaloneDispatcherOptions, type InvocationControl, runStandaloneProcess, } from "../runtime/standalone.js";
|
package/dist/server/index.js
CHANGED
|
@@ -5,13 +5,11 @@ export * from "./body.js";
|
|
|
5
5
|
export * from "./routes/index.js";
|
|
6
6
|
export * from "./server.js";
|
|
7
7
|
export * from "./mcp-endpoint.js";
|
|
8
|
-
export * from "./dispatcher.js";
|
|
9
8
|
export * from "./http-server.js";
|
|
10
9
|
export { serveParentIpc } from "../ipc/host.js";
|
|
11
10
|
export { IpcActionDockService } from "../ipc/service.js";
|
|
12
11
|
export { parseDuration } from "../utils/index.js";
|
|
13
12
|
export { createActionDockHost, DefaultActionDockHost, } from "../host/host.js";
|
|
14
|
-
export { LocalActionDockService, } from "../service/local.js";
|
|
15
13
|
export { RemoteActionDockService, } from "../service/remote.js";
|
|
16
14
|
// 独立进程分发器与退出控制
|
|
17
15
|
export { ExitCode, StandaloneDispatcher, runStandaloneProcess, } from "../runtime/standalone.js";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { parseActionRef } from "../../catalog/resolve-action.js";
|
|
2
|
-
import { filterByIntent } from "../../
|
|
2
|
+
import { filterByIntent } from "../../utils/intent.js";
|
|
3
3
|
import { ACTION_EXECUTION_ERROR, ACTION_FORBIDDEN, ACTION_NOT_FOUND, ACTION_START_FAILED, ACTION_TIMEOUT, ACTIONS_LIST_ERROR, IDEMPOTENCY_CONFLICT, INPUT_VALIDATION_FAILED, INVALID_JSON, PACKAGE_FORBIDDEN, PACKAGE_NOT_FOUND, REQUEST_TOO_LARGE, } from "../../errors.js";
|
|
4
4
|
import { InvalidJsonError, readJsonBody, RequestTooLargeError } from "../body.js";
|
|
5
5
|
import { filterActionsByPolicy, getSubPath, isActionAllowedByPolicy, isPackageAllowedByPolicy, jsonResponse, } from "./common.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { filterWithFallbackInfo } from "../../
|
|
1
|
+
import { filterWithFallbackInfo } from "../../utils/intent.js";
|
|
2
2
|
import { INFO_ERROR, PACKAGE_NOT_ALLOWED, PACKAGE_NOT_FOUND, PACKAGES_INFO_ERROR } from "../../errors.js";
|
|
3
3
|
import { ACTIONDOCK_VERSION } from "../../version.js";
|
|
4
4
|
import { sanitizeConfigDefinitions } from "../../storage/index.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { filterByIntent } from "../../
|
|
1
|
+
import { filterByIntent } from "../../utils/intent.js";
|
|
2
2
|
import { PACKAGE_NOT_ALLOWED, PLAYBOOK_NOT_FOUND, PLAYBOOKS_LIST_ERROR } from "../../errors.js";
|
|
3
3
|
import { assertPackageAllowed, getSubPath, isPackageAllowedByPolicy, jsonResponse } from "./common.js";
|
|
4
4
|
/**
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { ACTION_FORBIDDEN, CAPABILITY_UNAVAILABLE, EVENT_BACKPRESSURE_LIMIT, EVENT_CURSOR_EXPIRED, EXECUTION_FAILED, PACKAGE_FORBIDDEN, RUN_ALREADY_FINISHED, RUN_INTERRUPTED, RUN_NOT_FOUND, RUNS_CLEAR_ERROR, RUNS_LIST_ERROR, } from "../../errors.js";
|
|
1
|
+
import { ACTION_FORBIDDEN, CAPABILITY_UNAVAILABLE, EVENT_BACKPRESSURE_LIMIT, EVENT_CURSOR_EXPIRED, EXECUTION_FAILED, INVALID_ARGUMENT, PACKAGE_FORBIDDEN, RUN_ALREADY_FINISHED, RUN_INTERRUPTED, RUN_NOT_FOUND, RUNS_CLEAR_ERROR, RUNS_LIST_ERROR, } from "../../errors.js";
|
|
2
2
|
import { isTerminalRunStatus } from "../../storage/types.js";
|
|
3
|
+
import { createAbortError } from "../../ipc/service.js";
|
|
3
4
|
import { parseDuration } from "../../utils/index.js";
|
|
4
5
|
import { readJsonBody } from "../body.js";
|
|
5
6
|
import { getSubPath, isActionAllowedByPolicy, isPackageAllowedByPolicy, jsonResponse } from "./common.js";
|
|
@@ -16,11 +17,36 @@ export async function handleRunsRoutes(ctx) {
|
|
|
16
17
|
const actionId = url.searchParams.get("actionId") || undefined;
|
|
17
18
|
const packageId = url.searchParams.get("packageId") || undefined;
|
|
18
19
|
const intent = url.searchParams.get("intent") || undefined;
|
|
19
|
-
//
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
20
|
+
// requestId 反查:支持 requestId 与 requestIds 重复查询参数,将每一个参数值作为原样字符串保存
|
|
21
|
+
const requestIds = [
|
|
22
|
+
...url.searchParams.getAll("requestId"),
|
|
23
|
+
...url.searchParams.getAll("requestIds"),
|
|
24
|
+
].filter((id) => id.length > 0);
|
|
25
|
+
// offset 校验:非负安全整数,默认为 0,上限 100000 防止滥用
|
|
26
|
+
const rawOffset = url.searchParams.get("offset");
|
|
27
|
+
let offset = 0;
|
|
28
|
+
if (rawOffset !== null && rawOffset !== "") {
|
|
29
|
+
const parsedOffset = Number(rawOffset);
|
|
30
|
+
if (!Number.isSafeInteger(parsedOffset) || parsedOffset < 0 || parsedOffset > 100_000) {
|
|
31
|
+
return jsonResponse({
|
|
32
|
+
ok: false,
|
|
33
|
+
error: {
|
|
34
|
+
code: INVALID_ARGUMENT,
|
|
35
|
+
message: `Invalid offset '${rawOffset}': must be a non-negative safe integer <= 100000`,
|
|
36
|
+
},
|
|
37
|
+
}, 400, corsHeaders);
|
|
38
|
+
}
|
|
39
|
+
offset = parsedOffset;
|
|
40
|
+
}
|
|
41
|
+
// limit 边界防护:未提供保持默认值 50,提供则夹紧在 1 至 500 区间
|
|
42
|
+
const rawLimit = url.searchParams.get("limit");
|
|
43
|
+
let limit = 50;
|
|
44
|
+
if (rawLimit !== null) {
|
|
45
|
+
const parsedLimit = parseInt(rawLimit, 10);
|
|
46
|
+
if (Number.isFinite(parsedLimit)) {
|
|
47
|
+
limit = Math.min(Math.max(parsedLimit, 1), 500);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
24
50
|
if (packageId && !isPackageAllowedByPolicy(packageId, policy)) {
|
|
25
51
|
return jsonResponse({
|
|
26
52
|
ok: false,
|
|
@@ -39,23 +65,104 @@ export async function handleRunsRoutes(ctx) {
|
|
|
39
65
|
},
|
|
40
66
|
}, 403, corsHeaders);
|
|
41
67
|
}
|
|
42
|
-
|
|
68
|
+
const queryOptions = {
|
|
43
69
|
actionId,
|
|
44
70
|
status,
|
|
45
71
|
packageId,
|
|
46
72
|
intent,
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
73
|
+
requestIds: requestIds.length > 0 ? requestIds : undefined,
|
|
74
|
+
signal: req.signal,
|
|
75
|
+
packageAllowlist: policy.packageAllowlist && policy.packageAllowlist.length > 0
|
|
76
|
+
? policy.packageAllowlist
|
|
77
|
+
: undefined,
|
|
78
|
+
};
|
|
79
|
+
const hasPolicyFilter = Boolean((policy.packageAllowlist && policy.packageAllowlist.length > 0) ||
|
|
80
|
+
(policy.actionAllowlist && policy.actionAllowlist.length > 0));
|
|
81
|
+
let runs;
|
|
82
|
+
let total;
|
|
83
|
+
if (hasPolicyFilter) {
|
|
84
|
+
const BATCH_SIZE = 100;
|
|
85
|
+
let cursorOffset = 0;
|
|
86
|
+
let matchedCount = 0;
|
|
87
|
+
const pagedRuns = [];
|
|
88
|
+
while (true) {
|
|
89
|
+
if (req.signal?.aborted) {
|
|
90
|
+
throw createAbortError(req.signal.reason);
|
|
91
|
+
}
|
|
92
|
+
const batch = await service.runs.list({
|
|
93
|
+
...queryOptions,
|
|
94
|
+
limit: BATCH_SIZE,
|
|
95
|
+
offset: cursorOffset,
|
|
96
|
+
signal: req.signal,
|
|
97
|
+
}, { signal: req.signal });
|
|
98
|
+
if (req.signal?.aborted) {
|
|
99
|
+
throw createAbortError(req.signal.reason);
|
|
100
|
+
}
|
|
101
|
+
if (batch.length === 0) {
|
|
102
|
+
break;
|
|
103
|
+
}
|
|
104
|
+
for (const run of batch) {
|
|
105
|
+
const packageAllowed = isPackageAllowedByPolicy(run.packageId, policy);
|
|
106
|
+
const actionAllowed = isActionAllowedByPolicy({ packageId: run.packageId, actionId: run.actionId }, policy);
|
|
107
|
+
if (packageAllowed && actionAllowed) {
|
|
108
|
+
if (matchedCount >= offset && pagedRuns.length < limit) {
|
|
109
|
+
pagedRuns.push(run);
|
|
110
|
+
}
|
|
111
|
+
matchedCount++;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
cursorOffset += batch.length;
|
|
115
|
+
if (batch.length < BATCH_SIZE) {
|
|
116
|
+
break;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
runs = pagedRuns;
|
|
120
|
+
total = matchedCount;
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
// 当 hasPolicyFilter 为 false 时:下推 limit 与 offset 到底层查询
|
|
124
|
+
if (req.signal?.aborted) {
|
|
125
|
+
throw createAbortError(req.signal.reason);
|
|
126
|
+
}
|
|
127
|
+
runs = await service.runs.list({
|
|
128
|
+
...queryOptions,
|
|
129
|
+
limit,
|
|
130
|
+
offset,
|
|
131
|
+
signal: req.signal,
|
|
132
|
+
}, { signal: req.signal });
|
|
133
|
+
if (req.signal?.aborted) {
|
|
134
|
+
throw createAbortError(req.signal.reason);
|
|
135
|
+
}
|
|
136
|
+
// 统计总数 total 的可靠处理:
|
|
137
|
+
if (typeof service.runs.count === "function") {
|
|
138
|
+
total = await service.runs.count({
|
|
139
|
+
...queryOptions,
|
|
140
|
+
signal: req.signal,
|
|
141
|
+
}, { signal: req.signal });
|
|
142
|
+
}
|
|
143
|
+
else if (runs.length === 0 && offset === 0) {
|
|
144
|
+
total = 0;
|
|
145
|
+
}
|
|
146
|
+
else if (runs.length > 0 && runs.length < limit) {
|
|
147
|
+
total = offset + runs.length;
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
total = undefined;
|
|
151
|
+
}
|
|
51
152
|
}
|
|
52
|
-
|
|
53
|
-
|
|
153
|
+
const responseData = {
|
|
154
|
+
ok: true,
|
|
155
|
+
items: runs,
|
|
156
|
+
};
|
|
157
|
+
if (typeof total === "number") {
|
|
158
|
+
responseData.total = total;
|
|
54
159
|
}
|
|
55
|
-
|
|
56
|
-
return jsonResponse({ ok: true, total: allRuns.length, items: sliced }, 200, corsHeaders);
|
|
160
|
+
return jsonResponse(responseData, 200, corsHeaders);
|
|
57
161
|
}
|
|
58
162
|
catch (err) {
|
|
163
|
+
if (req.signal?.aborted || err?.name === "AbortError") {
|
|
164
|
+
throw err;
|
|
165
|
+
}
|
|
59
166
|
return jsonResponse({ ok: false, error: { code: RUNS_LIST_ERROR, message: err.message } }, 500, corsHeaders);
|
|
60
167
|
}
|
|
61
168
|
}
|
|
@@ -310,7 +417,7 @@ export async function handleRunsRoutes(ctx) {
|
|
|
310
417
|
const runShowMatch = subpath.match(/^\/runs\/([^/]+)$/);
|
|
311
418
|
if (runShowMatch && req.method === "GET") {
|
|
312
419
|
const runId = decodeURIComponent(runShowMatch[1]);
|
|
313
|
-
const run = await service.runs.get(runId);
|
|
420
|
+
const run = await service.runs.get(runId, { signal: req.signal });
|
|
314
421
|
if (!run) {
|
|
315
422
|
return jsonResponse({
|
|
316
423
|
ok: false,
|
|
@@ -38,7 +38,8 @@ export async function handleStateRoutes(ctx) {
|
|
|
38
38
|
if (subpath === "/state" && req.method === "GET") {
|
|
39
39
|
try {
|
|
40
40
|
const pkgParam = url.searchParams.get("package") || url.searchParams.get("packageId") || undefined;
|
|
41
|
-
const
|
|
41
|
+
const rawAction = url.searchParams.get("action") ?? url.searchParams.get("actionId");
|
|
42
|
+
const actionParam = rawAction !== null ? rawAction : undefined;
|
|
42
43
|
const nsParam = url.searchParams.get("namespace") ?? undefined;
|
|
43
44
|
const prefix = url.searchParams.get("prefix") || "";
|
|
44
45
|
const pkgs = await service.discovery.listPackages();
|
|
@@ -68,8 +69,13 @@ export async function handleStateRoutes(ctx) {
|
|
|
68
69
|
try {
|
|
69
70
|
const body = await readJsonBody(req, { maxBytes: options.maxBodyBytes }).catch(() => ({}));
|
|
70
71
|
const pkgParam = url.searchParams.get("package") || url.searchParams.get("packageId") || body.package || undefined;
|
|
71
|
-
const
|
|
72
|
-
|
|
72
|
+
const rawAction = url.searchParams.get("action") ??
|
|
73
|
+
url.searchParams.get("actionId") ??
|
|
74
|
+
body.action ??
|
|
75
|
+
body.actionId;
|
|
76
|
+
const actionParam = rawAction !== null && rawAction !== undefined ? rawAction : undefined;
|
|
77
|
+
const rawNs = body.namespace ?? url.searchParams.get("namespace");
|
|
78
|
+
const baseNs = rawNs !== null && rawNs !== undefined ? rawNs : undefined;
|
|
73
79
|
const pkgs = await service.discovery.listPackages();
|
|
74
80
|
const targetPackageId = resolveTargetPackageId(pkgs, pkgParam, policy);
|
|
75
81
|
const clearedCount = await service.management.state.clear(targetPackageId, actionParam, {
|
|
@@ -99,13 +105,21 @@ export async function handleStateRoutes(ctx) {
|
|
|
99
105
|
try {
|
|
100
106
|
const key = decodeURIComponent(stateKeyMatch[1]);
|
|
101
107
|
const pkgParam = url.searchParams.get("package") || url.searchParams.get("packageId") || undefined;
|
|
102
|
-
const
|
|
103
|
-
const
|
|
108
|
+
const rawAction = url.searchParams.get("action") ?? url.searchParams.get("actionId");
|
|
109
|
+
const actionParam = rawAction !== null ? rawAction : undefined;
|
|
110
|
+
const nsParam = url.searchParams.get("namespace") ?? undefined;
|
|
104
111
|
const pkgs = await service.discovery.listPackages();
|
|
105
112
|
const targetPackageId = resolveTargetPackageId(pkgs, pkgParam, policy);
|
|
106
113
|
if (req.method === "GET") {
|
|
107
|
-
|
|
108
|
-
|
|
114
|
+
let actualKey = key;
|
|
115
|
+
let ns = nsParam;
|
|
116
|
+
if (actionParam === undefined && nsParam === undefined) {
|
|
117
|
+
const decoded = decodeStateKey(key);
|
|
118
|
+
ns = decoded.namespace;
|
|
119
|
+
actualKey = decoded.key;
|
|
120
|
+
}
|
|
121
|
+
const entry = await service.management.state.get(targetPackageId, actionParam ?? "", actualKey, {
|
|
122
|
+
namespace: ns,
|
|
109
123
|
detail: true,
|
|
110
124
|
});
|
|
111
125
|
if (!entry || (typeof entry === "object" && entry.value === undefined)) {
|
|
@@ -113,12 +127,12 @@ export async function handleStateRoutes(ctx) {
|
|
|
113
127
|
}
|
|
114
128
|
const data = typeof entry === "object" && "value" in entry
|
|
115
129
|
? entry
|
|
116
|
-
: { key, namespace:
|
|
130
|
+
: { key: actualKey, namespace: ns ?? "", value: entry, expiresAt: undefined };
|
|
117
131
|
return jsonResponse({
|
|
118
132
|
ok: true,
|
|
119
133
|
packageId: targetPackageId,
|
|
120
|
-
key: data.key
|
|
121
|
-
namespace: data.namespace ??
|
|
134
|
+
key: data.key ?? actualKey,
|
|
135
|
+
namespace: data.namespace ?? ns ?? "",
|
|
122
136
|
value: data.value,
|
|
123
137
|
expiresAt: data.expiresAt,
|
|
124
138
|
}, 200, corsHeaders);
|
|
@@ -127,29 +141,40 @@ export async function handleStateRoutes(ctx) {
|
|
|
127
141
|
const body = await readJsonBody(req, { maxBytes: options.maxBodyBytes });
|
|
128
142
|
const val = body.value !== undefined ? body.value : body;
|
|
129
143
|
const ttl = typeof body.ttl === "number" ? body.ttl : undefined;
|
|
130
|
-
const
|
|
131
|
-
|
|
144
|
+
const rawActionFromReq = url.searchParams.get("action") ??
|
|
145
|
+
url.searchParams.get("actionId") ??
|
|
146
|
+
body.action ??
|
|
147
|
+
body.actionId;
|
|
148
|
+
const bodyAction = rawActionFromReq !== null && rawActionFromReq !== undefined ? rawActionFromReq : undefined;
|
|
149
|
+
const explicitNs = body.namespace ?? nsParam;
|
|
132
150
|
let actualKey = key;
|
|
133
151
|
let ns = explicitNs;
|
|
134
|
-
if (
|
|
152
|
+
if (bodyAction === undefined && explicitNs === undefined) {
|
|
135
153
|
const decoded = decodeStateKey(key);
|
|
136
154
|
ns = decoded.namespace;
|
|
137
155
|
actualKey = decoded.key;
|
|
138
156
|
}
|
|
139
|
-
await service.management.state.set(targetPackageId, bodyAction, actualKey, val, {
|
|
157
|
+
await service.management.state.set(targetPackageId, bodyAction ?? "", actualKey, val, {
|
|
140
158
|
namespace: ns,
|
|
141
159
|
ttl,
|
|
142
160
|
});
|
|
143
|
-
return jsonResponse({ ok: true, packageId: targetPackageId, key: actualKey, namespace: ns
|
|
161
|
+
return jsonResponse({ ok: true, packageId: targetPackageId, key: actualKey, namespace: ns ?? bodyAction ?? "", message: "updated" }, 200, corsHeaders);
|
|
144
162
|
}
|
|
145
163
|
if (req.method === "DELETE") {
|
|
146
|
-
|
|
147
|
-
|
|
164
|
+
let actualKey = key;
|
|
165
|
+
let ns = nsParam;
|
|
166
|
+
if (actionParam === undefined && nsParam === undefined) {
|
|
167
|
+
const decoded = decodeStateKey(key);
|
|
168
|
+
ns = decoded.namespace;
|
|
169
|
+
actualKey = decoded.key;
|
|
170
|
+
}
|
|
171
|
+
const deleted = await service.management.state.delete(targetPackageId, actionParam ?? "", actualKey, {
|
|
172
|
+
namespace: ns,
|
|
148
173
|
});
|
|
149
174
|
if (!deleted) {
|
|
150
175
|
return jsonResponse({ ok: false, error: { code: STATE_KEY_NOT_FOUND, message: `State key '${key}' not found` } }, 404, corsHeaders);
|
|
151
176
|
}
|
|
152
|
-
return jsonResponse({ ok: true, packageId: targetPackageId, key, deleted: true }, 200, corsHeaders);
|
|
177
|
+
return jsonResponse({ ok: true, packageId: targetPackageId, key: actualKey, deleted: true }, 200, corsHeaders);
|
|
153
178
|
}
|
|
154
179
|
}
|
|
155
180
|
catch (err) {
|
package/dist/server/security.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { timingSafeEqual } from "node:crypto";
|
|
2
|
-
// isLoopbackHost 已上移至 utils
|
|
3
|
-
export { isLoopbackHost } from "../utils/
|
|
2
|
+
// isLoopbackHost 已上移至 utils(通用谓词单一事实源),此处仅保留 re-export 兼容旧引用路径
|
|
3
|
+
export { isLoopbackHost } from "../utils/index.js";
|
|
4
4
|
/**
|
|
5
5
|
* 恒定时间字符串比较(Constant-time comparison)。
|
|
6
6
|
* 使用底层的 `crypto.timingSafeEqual` 防范时序攻击(Timing Attack)。
|
package/dist/server/server.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { posix, resolve } from "node:path";
|
|
2
2
|
import { NodeHttpServer } from "./http-server.js";
|
|
3
3
|
import { createActionDock } from "../service/factory.js";
|
|
4
|
-
import { NOT_FOUND, UNAUTHORIZED } from "../errors.js";
|
|
4
|
+
import { ActionDockError, ACCESS_DENIED, NOT_FOUND, SERVICE_ERROR, UNAUTHORIZED } from "../errors.js";
|
|
5
5
|
import { parseActionRef } from "../catalog/resolve-action.js";
|
|
6
|
-
import { ensureDependencyClosure } from "../project/closure.js";
|
|
7
6
|
import { findProjectRoot } from "../project/loader.js";
|
|
8
7
|
import { listLinkedPackages, resolvePackageRoot } from "../registry/registry.js";
|
|
9
8
|
import { handleActionsRoutes, handleConfigRoutes, handleDoctorRoute, handleHealthRoute, handleInfoRoute, handlePlaybooksRoutes, handleRunsRoutes, handleStateRoutes, jsonResponse, } from "./routes/index.js";
|
|
@@ -57,7 +56,7 @@ export async function startActionDockServer(options = {}) {
|
|
|
57
56
|
defaultView.policy.token ||
|
|
58
57
|
Array.from(views.values()).some((v) => Boolean(v.policy.token)));
|
|
59
58
|
if (!isLoopbackHost(host) && !hasTokenConfigured && !options.allowInsecureNoAuth) {
|
|
60
|
-
throw new
|
|
59
|
+
throw new ActionDockError(ACCESS_DENIED, "Authentication token is required when binding to a non-loopback address. Use --allow-insecure-no-auth to override.");
|
|
61
60
|
}
|
|
62
61
|
let serviceInstance = options.service;
|
|
63
62
|
// 若未传 service,服务端统一通过 createActionDock() 实例化,不再接受或处理外部传入的 Host 实体
|
|
@@ -74,7 +73,7 @@ export async function startActionDockServer(options = {}) {
|
|
|
74
73
|
});
|
|
75
74
|
}
|
|
76
75
|
if (!serviceInstance) {
|
|
77
|
-
throw new
|
|
76
|
+
throw new ActionDockError(SERVICE_ERROR, "Failed to initialize ActionDockService for server");
|
|
78
77
|
}
|
|
79
78
|
// 2. 聚合所有 views 声明的依赖包与动作,确保依赖闭包满足
|
|
80
79
|
const roots = [];
|
|
@@ -124,9 +123,6 @@ export async function startActionDockServer(options = {}) {
|
|
|
124
123
|
catch { }
|
|
125
124
|
}
|
|
126
125
|
}
|
|
127
|
-
if (roots.length > 0) {
|
|
128
|
-
await ensureDependencyClosure(roots, { customHome });
|
|
129
|
-
}
|
|
130
126
|
// 3. 为每个启用 MCP 的视图独立装配 MCP 处理器
|
|
131
127
|
if (options.enableMcp !== false) {
|
|
132
128
|
for (const v of views.values()) {
|
package/dist/service/factory.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { createActionDockHost } from "../host/host.js";
|
|
2
|
-
import { LocalActionDockService } from "./local.js";
|
|
3
2
|
import { RemoteActionDockService } from "./remote.js";
|
|
4
3
|
import { ActionDockError, INVALID_ARGUMENT, NOT_FOUND } from "../errors.js";
|
|
5
4
|
/**
|
|
@@ -21,16 +20,18 @@ export async function createActionDock(options = {}) {
|
|
|
21
20
|
process: options.runtimeOptions.process,
|
|
22
21
|
logger: options.runtimeOptions.logger,
|
|
23
22
|
recoverOrphans: options.recoverOrphans,
|
|
23
|
+
enableManagement: options.enableManagement,
|
|
24
24
|
});
|
|
25
|
-
return
|
|
25
|
+
return host;
|
|
26
26
|
}
|
|
27
27
|
const host = await createActionDockHost({
|
|
28
28
|
scanLinkedPackages: options.scanLinkedPackages ?? true,
|
|
29
29
|
...options,
|
|
30
30
|
recoverOrphans: options.recoverOrphans ?? true,
|
|
31
|
+
enableManagement: options.enableManagement,
|
|
31
32
|
...(options.hostOptions || {}),
|
|
32
33
|
});
|
|
33
|
-
return
|
|
34
|
+
return host;
|
|
34
35
|
}
|
|
35
36
|
/**
|
|
36
37
|
* 工厂函数:连接远端 ActionDock 服务实例。
|
package/dist/service/index.d.ts
CHANGED
package/dist/service/index.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* 远端通信错误翻译层。
|
|
3
3
|
*
|
|
4
|
-
* 职责单一:将
|
|
4
|
+
* 职责单一:将 client 传输层抛出的底层异常翻译为统一的
|
|
5
5
|
* 结构化异常,供 RemoteActionDockService 各操作边界复用;
|
|
6
6
|
* 优先读取传输层透传的结构化错误码,无法识别时原样透传。
|
|
7
7
|
*/
|
|
8
|
-
import { CAPABILITY_UNAVAILABLE, STATE_KEY_NOT_FOUND } from "../errors.js";
|
|
9
|
-
import { PROTOCOL_UNSUPPORTED, SERVICE_RESULT_UNKNOWN,
|
|
8
|
+
import { ActionDockError, CAPABILITY_UNAVAILABLE, STATE_KEY_NOT_FOUND } from "../errors.js";
|
|
9
|
+
import { PROTOCOL_UNSUPPORTED, SERVICE_RESULT_UNKNOWN, } from "./types.js";
|
|
10
10
|
/**
|
|
11
11
|
* 将远端通信异常包装翻译为统一的异常。
|
|
12
12
|
*
|
|
@@ -16,16 +16,16 @@ export function wrapRemoteError(err) {
|
|
|
16
16
|
const code = err?.code || "";
|
|
17
17
|
if (code === "CAPABILITY_UNAVAILABLE" ||
|
|
18
18
|
code === "TARGET_CAPABILITY_UNAVAILABLE") {
|
|
19
|
-
throw new
|
|
19
|
+
throw new ActionDockError(CAPABILITY_UNAVAILABLE, `CAPABILITY_UNAVAILABLE: Management APIs are not enabled on remote service`, { originalMessage: err?.message });
|
|
20
20
|
}
|
|
21
21
|
if (code === "PROTOCOL_UNSUPPORTED" ||
|
|
22
22
|
code === "TARGET_PROTOCOL_UNSUPPORTED") {
|
|
23
|
-
throw new
|
|
23
|
+
throw new ActionDockError(PROTOCOL_UNSUPPORTED, `PROTOCOL_UNSUPPORTED: ${err?.message || ""}`, { originalMessage: err?.message });
|
|
24
24
|
}
|
|
25
25
|
if (code === "SERVICE_RESULT_UNKNOWN" ||
|
|
26
26
|
code === "TARGET_RESULT_UNKNOWN" ||
|
|
27
27
|
code === "RESULT_UNKNOWN") {
|
|
28
|
-
throw new
|
|
28
|
+
throw new ActionDockError(SERVICE_RESULT_UNKNOWN, `SERVICE_RESULT_UNKNOWN: ${err?.message || ""}`, { originalMessage: err?.message });
|
|
29
29
|
}
|
|
30
30
|
throw err;
|
|
31
31
|
}
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* ExecutionResult 结构。不感知 SSE 通道与门面生命周期。
|
|
7
7
|
*/
|
|
8
8
|
import type { ExecutionResult, RunRecord } from "@actiondock/sdk";
|
|
9
|
+
import { type Clock } from "../storage/clock.js";
|
|
9
10
|
/**
|
|
10
11
|
* 轮询依赖上下文:由 RemoteActionDockService 门面注入自身能力,
|
|
11
12
|
* 保持本模块与门面实现解耦。
|
|
@@ -17,6 +18,8 @@ export interface RunPollingContext {
|
|
|
17
18
|
isClosed(): boolean;
|
|
18
19
|
/** 查询远端运行详情(键不存在时返回 undefined) */
|
|
19
20
|
getRun(runId: string): Promise<RunRecord | undefined>;
|
|
21
|
+
/** 可选注入时钟抽象(缺省使用系统时钟) */
|
|
22
|
+
clock?: Clock;
|
|
20
23
|
}
|
|
21
24
|
/**
|
|
22
25
|
* 将终态运行记录翻译为统一 ExecutionResult 结构。
|
|
@@ -6,8 +6,11 @@
|
|
|
6
6
|
* ExecutionResult 结构。不感知 SSE 通道与门面生命周期。
|
|
7
7
|
*/
|
|
8
8
|
import { ACTION_CANCELLED, EXECUTION_FAILED, RUN_INTERRUPTED, TIMEOUT } from "../errors.js";
|
|
9
|
+
import { SystemClock } from "../storage/clock.js";
|
|
9
10
|
import { isTerminalRunStatus } from "../storage/types.js";
|
|
10
11
|
import { SERVICE_CLOSED } from "./types.js";
|
|
12
|
+
/** 模块级默认时钟实例 */
|
|
13
|
+
const defaultClock = new SystemClock();
|
|
11
14
|
/**
|
|
12
15
|
* 将终态运行记录翻译为统一 ExecutionResult 结构。
|
|
13
16
|
*/
|
|
@@ -44,12 +47,14 @@ export function formatTerminalRunResult(run, runId) {
|
|
|
44
47
|
* @param startTime 等待起点时间戳(缺省当前时间)
|
|
45
48
|
* @param totalMaxWaitMs 已消耗等待预算对应的总上限(SSE 阶段已等待时传入)
|
|
46
49
|
*/
|
|
47
|
-
export async function pollRunCompletion(ctx, runId, signal, timeoutMs, startTime
|
|
50
|
+
export async function pollRunCompletion(ctx, runId, signal, timeoutMs, startTime, totalMaxWaitMs) {
|
|
51
|
+
const clock = ctx.clock ?? defaultClock;
|
|
52
|
+
const effectiveStartTime = startTime ?? clock.monotonic();
|
|
48
53
|
const maxWaitMs = totalMaxWaitMs ?? Math.max(ctx.baseTimeoutMs, timeoutMs ?? 0);
|
|
49
|
-
const remainingWaitMs = Math.max(0, maxWaitMs - (
|
|
54
|
+
const remainingWaitMs = Math.max(0, maxWaitMs - (clock.monotonic() - effectiveStartTime));
|
|
50
55
|
let delayMs = Math.min(150, Math.max(10, Math.floor((remainingWaitMs || maxWaitMs) / 4)));
|
|
51
56
|
const maxDelayMs = 2000;
|
|
52
|
-
while (
|
|
57
|
+
while (clock.monotonic() - effectiveStartTime < maxWaitMs) {
|
|
53
58
|
if (ctx.isClosed()) {
|
|
54
59
|
return {
|
|
55
60
|
ok: false,
|
|
@@ -89,10 +94,10 @@ export async function pollRunCompletion(ctx, runId, signal, timeoutMs, startTime
|
|
|
89
94
|
}
|
|
90
95
|
throw err;
|
|
91
96
|
}
|
|
92
|
-
await
|
|
97
|
+
await clock.sleep(delayMs);
|
|
93
98
|
delayMs = Math.min(delayMs * 2, maxDelayMs);
|
|
94
99
|
}
|
|
95
|
-
const waitedMs =
|
|
100
|
+
const waitedMs = Math.round(clock.monotonic() - effectiveStartTime);
|
|
96
101
|
return {
|
|
97
102
|
ok: false,
|
|
98
103
|
runId,
|
package/dist/service/remote.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { PackageInfo } from "../package/types.js";
|
|
2
|
+
import { type Clock } from "../storage/clock.js";
|
|
2
3
|
import { type RemoteServiceOptions } from "./types.js";
|
|
3
4
|
import type { ActionDockService, ConfigPort, ConnectActionDockOptions, DiscoveryPort, EventsPort, ExecutionPort, RunsPort, StatePort } from "./types.js";
|
|
4
5
|
/**
|
|
@@ -14,6 +15,7 @@ export declare class RemoteActionDockService implements ActionDockService {
|
|
|
14
15
|
readonly allowInsecureHttp?: boolean;
|
|
15
16
|
readonly insecure?: boolean;
|
|
16
17
|
readonly dispatcher?: unknown;
|
|
18
|
+
readonly clock: Clock;
|
|
17
19
|
private isClosed;
|
|
18
20
|
readonly discovery: DiscoveryPort;
|
|
19
21
|
readonly execution: ExecutionPort;
|
|
@@ -23,7 +25,9 @@ export declare class RemoteActionDockService implements ActionDockService {
|
|
|
23
25
|
config: ConfigPort;
|
|
24
26
|
state: StatePort;
|
|
25
27
|
};
|
|
26
|
-
constructor(options: ConnectActionDockOptions | RemoteServiceOptions)
|
|
28
|
+
constructor(options: (ConnectActionDockOptions | RemoteServiceOptions) & {
|
|
29
|
+
clock?: Clock;
|
|
30
|
+
});
|
|
27
31
|
private assertNotClosed;
|
|
28
32
|
info(): Promise<PackageInfo[]>;
|
|
29
33
|
private waitForRunCompletion;
|