@actiondock/core 2.0.12 → 2.2.1
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 -30
- package/dist/app/app.d.ts +73 -0
- package/dist/app/app.js +700 -0
- package/dist/app/index.d.ts +2 -0
- package/dist/app/index.js +2 -0
- package/dist/app/types.d.ts +283 -0
- package/dist/app/types.js +1 -0
- package/dist/catalog/action-index.d.ts +1 -1
- package/dist/catalog/action-index.js +93 -0
- package/dist/catalog/action-resolver.d.ts +2 -2
- package/dist/catalog/action-resolver.js +95 -0
- package/dist/catalog/index.d.ts +5 -5
- package/dist/catalog/index.js +5 -0
- package/dist/catalog/location-registry.d.ts +5 -5
- package/dist/catalog/location-registry.js +138 -0
- package/dist/catalog/package-catalog.d.ts +2 -2
- package/dist/catalog/package-catalog.js +76 -0
- package/dist/catalog/types.d.ts +2 -2
- package/dist/catalog/types.js +1 -0
- package/dist/doctor/doctor.d.ts +2 -1
- package/dist/doctor/doctor.js +613 -0
- package/dist/doctor/index.d.ts +2 -2
- package/dist/doctor/index.js +2 -0
- package/dist/doctor/types.js +1 -0
- package/dist/errors.d.ts +122 -0
- package/dist/errors.js +123 -0
- package/dist/execution/index.d.ts +2 -2
- package/dist/execution/index.js +2 -0
- package/dist/execution/service.d.ts +46 -41
- package/dist/execution/service.js +633 -0
- package/dist/execution/types.d.ts +59 -2
- package/dist/execution/types.js +1 -0
- package/dist/export/index.d.ts +1 -1
- package/dist/export/index.js +1 -0
- package/dist/export/templates.d.ts +45 -7
- package/dist/export/templates.js +631 -0
- package/dist/filter/index.d.ts +1 -1
- package/dist/filter/index.js +1 -0
- package/dist/filter/intent.js +123 -0
- package/dist/host/host.d.ts +55 -0
- package/dist/host/host.js +740 -0
- package/dist/host/index.d.ts +2 -0
- package/dist/host/index.js +2 -0
- package/dist/host/types.d.ts +81 -0
- package/dist/host/types.js +1 -0
- package/dist/index.d.ts +21 -16
- package/dist/index.js +20 -8458
- package/dist/ipc/diagnostic.d.ts +65 -0
- package/dist/ipc/diagnostic.js +129 -0
- package/dist/ipc/host.d.ts +7 -0
- package/dist/ipc/host.js +93 -0
- package/dist/ipc/index.d.ts +4 -0
- package/dist/ipc/index.js +4 -0
- package/dist/ipc/target.d.ts +56 -0
- package/dist/ipc/target.js +297 -0
- package/dist/ipc/types.d.ts +42 -0
- package/dist/ipc/types.js +1 -0
- package/dist/platform/default.d.ts +32 -0
- package/dist/platform/default.js +40 -0
- package/dist/platform/index.d.ts +3 -0
- package/dist/platform/index.js +3 -0
- package/dist/platform/node-fs.d.ts +37 -0
- package/dist/platform/node-fs.js +81 -0
- package/dist/platform/types.d.ts +104 -0
- package/dist/platform/types.js +1 -0
- package/dist/profile/client.d.ts +58 -12
- package/dist/profile/client.js +467 -0
- package/dist/profile/index.d.ts +3 -3
- package/dist/profile/index.js +3 -0
- package/dist/profile/manager.d.ts +2 -2
- package/dist/profile/manager.js +294 -0
- package/dist/profile/types.d.ts +1 -1
- package/dist/profile/types.js +1 -0
- package/dist/project/closure.js +68 -0
- package/dist/project/digest.d.ts +29 -0
- package/dist/project/digest.js +324 -0
- package/dist/project/index.d.ts +10 -5
- package/dist/project/index.js +10 -0
- package/dist/project/init.d.ts +3 -4
- package/dist/project/init.js +175 -0
- package/dist/project/loader.d.ts +21 -27
- package/dist/project/loader.js +484 -0
- package/dist/project/lockfile.d.ts +55 -0
- package/dist/project/lockfile.js +175 -0
- package/dist/project/manifest.d.ts +6 -28
- package/dist/project/manifest.js +220 -0
- package/dist/project/resolver.d.ts +116 -0
- package/dist/project/resolver.js +376 -0
- package/dist/project/transactions.d.ts +103 -0
- package/dist/project/transactions.js +1203 -0
- package/dist/project/types-generator.d.ts +33 -0
- package/dist/project/types-generator.js +168 -0
- package/dist/project/types.d.ts +58 -82
- package/dist/project/types.js +1 -0
- package/dist/registry/index.d.ts +5 -2
- package/dist/registry/index.js +5 -0
- package/dist/registry/lock.d.ts +27 -0
- package/dist/registry/lock.js +93 -0
- package/dist/registry/registry.d.ts +32 -11
- package/dist/registry/registry.js +611 -0
- package/dist/registry/resolve.d.ts +62 -0
- package/dist/registry/resolve.js +195 -0
- package/dist/registry/scan.d.ts +38 -0
- package/dist/registry/scan.js +135 -0
- package/dist/registry/types.d.ts +1 -1
- package/dist/registry/types.js +1 -0
- package/dist/runtime/action-collection.d.ts +27 -0
- package/dist/runtime/action-collection.js +57 -0
- package/dist/runtime/clock.d.ts +0 -2
- package/dist/runtime/clock.js +17 -0
- package/dist/runtime/context.d.ts +16 -5
- package/dist/runtime/context.js +242 -0
- package/dist/runtime/env.d.ts +3 -1
- package/dist/runtime/env.js +159 -0
- package/dist/runtime/events.d.ts +46 -14
- package/dist/runtime/events.js +604 -0
- package/dist/runtime/execution-manager.d.ts +1 -1
- package/dist/runtime/execution-manager.js +66 -0
- package/dist/runtime/index.d.ts +10 -9
- package/dist/runtime/index.js +10 -0
- package/dist/runtime/module-loader.d.ts +0 -8
- package/dist/runtime/module-loader.js +16 -0
- package/dist/runtime/process.d.ts +2 -4
- package/dist/runtime/process.js +146 -0
- package/dist/runtime/runner.d.ts +117 -10
- package/dist/runtime/runner.js +984 -0
- package/dist/runtime/standalone.d.ts +68 -19
- package/dist/runtime/standalone.js +536 -0
- package/dist/schema/validator.js +122 -0
- package/dist/server/body.js +93 -0
- package/dist/server/index.d.ts +5 -6
- package/dist/server/index.js +5 -0
- package/dist/server/routes/actions.d.ts +2 -2
- package/dist/server/routes/actions.js +298 -0
- package/dist/server/routes/common.d.ts +28 -17
- package/dist/server/routes/common.js +104 -0
- package/dist/server/routes/config.d.ts +2 -1
- package/dist/server/routes/config.js +173 -0
- package/dist/server/routes/doctor.d.ts +2 -2
- package/dist/server/routes/doctor.js +63 -0
- package/dist/server/routes/health.d.ts +2 -2
- package/dist/server/routes/health.js +35 -0
- package/dist/server/routes/index.d.ts +9 -9
- package/dist/server/routes/index.js +9 -0
- package/dist/server/routes/info.d.ts +4 -2
- package/dist/server/routes/info.js +158 -0
- package/dist/server/routes/playbooks.d.ts +2 -2
- package/dist/server/routes/playbooks.js +134 -0
- package/dist/server/routes/runs.d.ts +2 -2
- package/dist/server/routes/runs.js +343 -0
- package/dist/server/routes/state.d.ts +2 -1
- package/dist/server/routes/state.js +169 -0
- package/dist/server/security.d.ts +11 -4
- package/dist/server/security.js +101 -0
- package/dist/server/server.d.ts +6 -6
- package/dist/server/server.js +355 -0
- package/dist/server/types.d.ts +27 -8
- package/dist/server/types.js +1 -0
- package/dist/storage/data-dir-lock.d.ts +119 -0
- package/dist/storage/data-dir-lock.js +1016 -0
- package/dist/storage/driver.d.ts +4 -10
- package/dist/storage/driver.js +59 -0
- package/dist/storage/index.d.ts +30 -10
- package/dist/storage/index.js +98 -0
- package/dist/storage/lazy.d.ts +8 -0
- package/dist/storage/lazy.js +44 -0
- package/dist/storage/mask.d.ts +12 -5
- package/dist/storage/mask.js +48 -0
- package/dist/storage/params.d.ts +13 -0
- package/dist/storage/params.js +32 -0
- package/dist/storage/sqlite.d.ts +19 -6
- package/dist/storage/sqlite.js +689 -0
- package/dist/storage/types.d.ts +57 -6
- package/dist/storage/types.js +14 -0
- package/dist/target/index.d.ts +4 -0
- package/dist/target/index.js +4 -0
- package/dist/target/local.d.ts +52 -0
- package/dist/target/local.js +343 -0
- package/dist/target/remote.d.ts +76 -0
- package/dist/target/remote.js +839 -0
- package/dist/target/target.d.ts +6 -0
- package/dist/target/target.js +35 -0
- package/dist/target/types.d.ts +246 -0
- package/dist/target/types.js +34 -0
- package/dist/utils/index.d.ts +22 -2
- package/dist/utils/index.js +180 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +4 -0
- package/package.json +6 -7
- package/dist/build/index.d.ts +0 -1
- package/dist/build/templates.d.ts +0 -19
- package/dist/server/runtime-registry.d.ts +0 -78
package/dist/storage/types.d.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import type { RuntimeError, RunRecord } from "@actiondock/sdk";
|
|
2
|
-
import type { Clock } from "../runtime/clock";
|
|
2
|
+
import type { Clock } from "../runtime/clock.js";
|
|
3
|
+
/**
|
|
4
|
+
* 固定的存储 Schema 目标版本常量。
|
|
5
|
+
*/
|
|
6
|
+
export declare const STORAGE_SCHEMA_VERSION = 2;
|
|
3
7
|
/**
|
|
4
8
|
* SQLite 基础参数值类型。
|
|
5
9
|
*/
|
|
@@ -20,7 +24,13 @@ export interface SqliteStatement {
|
|
|
20
24
|
all<T>(...params: any[]): T[];
|
|
21
25
|
}
|
|
22
26
|
/**
|
|
23
|
-
* 统一 SQLite
|
|
27
|
+
* 统一 SQLite 驱动层接口(严格同步契约)。
|
|
28
|
+
*
|
|
29
|
+
* 本契约为同步驱动:exec、prepare 与 transaction 全部以同步语义返回结果,
|
|
30
|
+
* 不接受任何 Promise 或异步实现。SqliteRuntimeStorage 的公共同步方法
|
|
31
|
+
* (getConfig、listConfig、getRun、listRuns、checkAndRecordIdempotency 等)
|
|
32
|
+
* 直接依赖这一同步保证。异步驱动(如 runtime-node 的 WorkerSqliteDriver)
|
|
33
|
+
* 不应注入本契约,需通过 RuntimeStorage 的异步外观层另行适配。
|
|
24
34
|
*/
|
|
25
35
|
export interface SqliteDriver {
|
|
26
36
|
exec(sql: string): void;
|
|
@@ -68,15 +78,48 @@ export interface StorageOptions {
|
|
|
68
78
|
dbPath?: string;
|
|
69
79
|
/** 所绑定的 Package ID */
|
|
70
80
|
packageId: string;
|
|
71
|
-
/** 显式注入的 SQLite
|
|
81
|
+
/** 显式注入的 SQLite 底层驱动(必须满足同步 SqliteDriver 契约) */
|
|
72
82
|
driver?: SqliteDriver;
|
|
73
83
|
/** 可选注入的时间提供器,便于与模拟时钟联动 */
|
|
74
84
|
clock?: Clock;
|
|
75
85
|
}
|
|
86
|
+
/**
|
|
87
|
+
* 数据库中存储的幂等请求去重记录实体。
|
|
88
|
+
*/
|
|
89
|
+
export interface IdempotencyRecord {
|
|
90
|
+
/** 鉴权主体标识 */
|
|
91
|
+
ownerId: string;
|
|
92
|
+
/** 完全限定动作标识 */
|
|
93
|
+
actionRef: string;
|
|
94
|
+
/** 客户端幂等请求标识 */
|
|
95
|
+
requestId: string;
|
|
96
|
+
/** 输入参数与选项的 SHA-256 规范化摘要 */
|
|
97
|
+
inputDigest: string;
|
|
98
|
+
/** 关联的运行记录标识 */
|
|
99
|
+
runId: string;
|
|
100
|
+
/** 创建时间戳(ISO 8601 格式) */
|
|
101
|
+
createdAt?: string;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* 幂等检查与登记结果。
|
|
105
|
+
*/
|
|
106
|
+
export type IdempotencyCheckResult = {
|
|
107
|
+
outcome: "new";
|
|
108
|
+
} | {
|
|
109
|
+
outcome: "duplicate";
|
|
110
|
+
runId: string;
|
|
111
|
+
} | {
|
|
112
|
+
outcome: "conflict";
|
|
113
|
+
existingDigest: string;
|
|
114
|
+
};
|
|
76
115
|
/**
|
|
77
116
|
* Action 执行终态枚举。
|
|
78
117
|
*/
|
|
79
118
|
export type TerminalRunStatus = "success" | "failed" | "cancelled" | "timed_out" | "interrupted";
|
|
119
|
+
/**
|
|
120
|
+
* 判断指定运行状态是否为终态(收敛 success, failed, cancelled, timed_out, interrupted)。
|
|
121
|
+
*/
|
|
122
|
+
export declare function isTerminalRunStatus(status: string): status is TerminalRunStatus;
|
|
80
123
|
/**
|
|
81
124
|
* 统一运行时存储抽象接口。
|
|
82
125
|
*/
|
|
@@ -87,8 +130,8 @@ export interface RuntimeStorage {
|
|
|
87
130
|
readonly closed?: boolean;
|
|
88
131
|
getConfig<T = unknown>(key: string): T | undefined;
|
|
89
132
|
listConfig(): Record<string, unknown>;
|
|
90
|
-
setConfig(key: string, value: unknown): void
|
|
91
|
-
deleteConfig(key: string): boolean
|
|
133
|
+
setConfig(key: string, value: unknown): void | Promise<void>;
|
|
134
|
+
deleteConfig(key: string): boolean | Promise<boolean>;
|
|
92
135
|
getState<T = unknown>(namespace: string, key: string): Promise<T | undefined>;
|
|
93
136
|
findState<T = unknown>(targetKey: string, namespace?: string): Promise<StateEntry | undefined>;
|
|
94
137
|
setState<T = unknown>(namespace: string, key: string, value: T, ttl?: number): Promise<void>;
|
|
@@ -116,6 +159,14 @@ export interface RuntimeStorage {
|
|
|
116
159
|
actionId?: string;
|
|
117
160
|
status?: string;
|
|
118
161
|
}): number;
|
|
162
|
+
/** 故障重启恢复:将遗留非终态运行收敛为 interrupted */
|
|
163
|
+
recoverRunningRuns?(currentHostSessionId?: string): number | Promise<number>;
|
|
164
|
+
/** 收敛死亡会话遗留的非终态运行任务 */
|
|
165
|
+
recoverDeadSessionRuns?(currentHostSessionId?: string): number | Promise<number>;
|
|
166
|
+
/** 确保底层存储与 Schema 初始化完成 */
|
|
167
|
+
ensureInitialized?(): Promise<void>;
|
|
168
|
+
checkAndRecordIdempotency?(record: IdempotencyRecord): IdempotencyCheckResult;
|
|
169
|
+
getIdempotencyRecord?(ownerId: string, actionRef: string, requestId: string): IdempotencyRecord | undefined;
|
|
119
170
|
/** 关闭底层 SQLite 数据库连接并释放句柄 */
|
|
120
|
-
close(): void
|
|
171
|
+
close(): void | Promise<void>;
|
|
121
172
|
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 固定的存储 Schema 目标版本常量。
|
|
3
|
+
*/
|
|
4
|
+
export const STORAGE_SCHEMA_VERSION = 2;
|
|
5
|
+
/**
|
|
6
|
+
* 判断指定运行状态是否为终态(收敛 success, failed, cancelled, timed_out, interrupted)。
|
|
7
|
+
*/
|
|
8
|
+
export function isTerminalRunStatus(status) {
|
|
9
|
+
return (status === "success" ||
|
|
10
|
+
status === "failed" ||
|
|
11
|
+
status === "cancelled" ||
|
|
12
|
+
status === "timed_out" ||
|
|
13
|
+
status === "interrupted");
|
|
14
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { ActionRef, ExecutionEvent, ExecutionResult, JsonValue, RunRecord } from "@actiondock/sdk";
|
|
2
|
+
import type { ActionDockApp, ActionSpec, ActionSummary, ListActionsOptions, PackageInfo, PlaybookSpec, PlaybookSummary } from "../app/types.js";
|
|
3
|
+
import type { CancelResult, ExecuteOptions, ExecutionTicket } from "../execution/types.js";
|
|
4
|
+
import type { ActionDockHost } from "../host/types.js";
|
|
5
|
+
import type { StateEntry } from "../storage/types.js";
|
|
6
|
+
import { type ActionDockTarget, type ConfigValueView, type ListRunsOptions, type StateScopeOptions, type TargetInfo } from "./types.js";
|
|
7
|
+
/**
|
|
8
|
+
* 本地 ActionDockTarget 门面实现。
|
|
9
|
+
* 内部包装 ActionDockHost 或 ActionDockApp,将统一调用直接转交给 Host 或 App。
|
|
10
|
+
*/
|
|
11
|
+
export declare class LocalActionDockTarget implements ActionDockTarget {
|
|
12
|
+
readonly target: ActionDockHost | ActionDockApp;
|
|
13
|
+
constructor(target: ActionDockHost | ActionDockApp);
|
|
14
|
+
unwrap(): ActionDockHost | ActionDockApp;
|
|
15
|
+
info(): Promise<TargetInfo>;
|
|
16
|
+
listPackages(): Promise<PackageInfo[]>;
|
|
17
|
+
listActions(options?: ListActionsOptions): Promise<ActionSummary[]>;
|
|
18
|
+
describeAction(ref: ActionRef | string): Promise<ActionSpec>;
|
|
19
|
+
listPlaybooks(): Promise<PlaybookSummary[]>;
|
|
20
|
+
describePlaybook(id: string): Promise<PlaybookSpec>;
|
|
21
|
+
runAction(ref: ActionRef | string, input: JsonValue, options?: ExecuteOptions): Promise<ExecutionResult>;
|
|
22
|
+
startAction(ref: ActionRef | string, input: JsonValue, options?: ExecuteOptions): Promise<ExecutionTicket>;
|
|
23
|
+
listRuns(options?: ListRunsOptions): Promise<RunRecord[]>;
|
|
24
|
+
clearRuns(options?: {
|
|
25
|
+
packageId?: string;
|
|
26
|
+
actionId?: string;
|
|
27
|
+
status?: string;
|
|
28
|
+
}): Promise<number>;
|
|
29
|
+
getRun(runId: string): Promise<RunRecord | undefined>;
|
|
30
|
+
cancelRun(runId: string, reason?: string): Promise<CancelResult>;
|
|
31
|
+
events(runId: string, options?: {
|
|
32
|
+
after?: number | string;
|
|
33
|
+
signal?: AbortSignal;
|
|
34
|
+
maxQueueSize?: number;
|
|
35
|
+
}): AsyncIterable<ExecutionEvent>;
|
|
36
|
+
private resolveApp;
|
|
37
|
+
private getGlobalStorage;
|
|
38
|
+
private findDeclaredConfigItem;
|
|
39
|
+
getConfig(packageId: string, key: string): Promise<ConfigValueView>;
|
|
40
|
+
setConfig(packageId: string, key: string, value: JsonValue): Promise<void>;
|
|
41
|
+
deleteConfig(packageId: string, key: string): Promise<boolean>;
|
|
42
|
+
listConfig(packageId: string): Promise<ConfigValueView[]>;
|
|
43
|
+
getState<T extends JsonValue = JsonValue>(packageId: string, actionId: string, key: string, options?: StateScopeOptions): Promise<T | undefined>;
|
|
44
|
+
setState<T extends JsonValue = JsonValue>(packageId: string, actionId: string, key: string, value: T, options?: StateScopeOptions): Promise<void>;
|
|
45
|
+
deleteState(packageId: string, actionId: string, key: string, options?: StateScopeOptions): Promise<boolean>;
|
|
46
|
+
listStateKeys(packageId: string, actionId: string, options?: StateScopeOptions): Promise<string[]>;
|
|
47
|
+
clearState(packageId: string, actionId: string, options?: StateScopeOptions): Promise<number>;
|
|
48
|
+
listStateEntries(packageId: string, options?: any): Promise<StateEntry[]>;
|
|
49
|
+
close(options?: {
|
|
50
|
+
timeoutMs?: number;
|
|
51
|
+
}): Promise<void>;
|
|
52
|
+
}
|
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
import { createGlobalStorage, isSecretConfigKey } from "../storage/index.js";
|
|
2
|
+
import { ACTIONDOCK_PROTOCOL_VERSION, TargetError, CloseTimeoutError, TARGET_CAPABILITY_UNAVAILABLE, } from "./types.js";
|
|
3
|
+
/**
|
|
4
|
+
* 本地 ActionDockTarget 门面实现。
|
|
5
|
+
* 内部包装 ActionDockHost 或 ActionDockApp,将统一调用直接转交给 Host 或 App。
|
|
6
|
+
*/
|
|
7
|
+
export class LocalActionDockTarget {
|
|
8
|
+
target;
|
|
9
|
+
constructor(target) {
|
|
10
|
+
this.target = target;
|
|
11
|
+
}
|
|
12
|
+
unwrap() {
|
|
13
|
+
return this.target;
|
|
14
|
+
}
|
|
15
|
+
async info() {
|
|
16
|
+
const packages = await this.listPackages();
|
|
17
|
+
let id = "local-host";
|
|
18
|
+
let name = "Local Host";
|
|
19
|
+
if ("listApps" in this.target) {
|
|
20
|
+
id = this.target.id || "local-host";
|
|
21
|
+
name = this.target.name || "Local Host";
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
id = this.target.packageId;
|
|
25
|
+
name = packages[0]?.name || this.target.packageId;
|
|
26
|
+
}
|
|
27
|
+
return {
|
|
28
|
+
id,
|
|
29
|
+
name,
|
|
30
|
+
protocolVersion: ACTIONDOCK_PROTOCOL_VERSION,
|
|
31
|
+
packages,
|
|
32
|
+
capabilities: [
|
|
33
|
+
"actions",
|
|
34
|
+
"playbooks",
|
|
35
|
+
"runs",
|
|
36
|
+
"events",
|
|
37
|
+
"management.config",
|
|
38
|
+
"management.state",
|
|
39
|
+
],
|
|
40
|
+
idempotencyPolicy: {
|
|
41
|
+
retentionMs: 86400000,
|
|
42
|
+
header: "x-request-id",
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
async listPackages() {
|
|
47
|
+
if ("listApps" in this.target) {
|
|
48
|
+
const apps = this.target.listApps();
|
|
49
|
+
return Promise.all(apps.map((app) => app.info()));
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
return [await this.target.info()];
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
async listActions(options) {
|
|
56
|
+
return this.target.listActions(options);
|
|
57
|
+
}
|
|
58
|
+
async describeAction(ref) {
|
|
59
|
+
if ("getApp" in this.target) {
|
|
60
|
+
return this.target.describeAction(ref);
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
const actionId = typeof ref === "string" ? ref : ref.actionId;
|
|
64
|
+
return this.target.describeAction(actionId);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
async listPlaybooks() {
|
|
68
|
+
return this.target.listPlaybooks();
|
|
69
|
+
}
|
|
70
|
+
async describePlaybook(id) {
|
|
71
|
+
return this.target.describePlaybook(id);
|
|
72
|
+
}
|
|
73
|
+
async runAction(ref, input, options) {
|
|
74
|
+
if ("listApps" in this.target) {
|
|
75
|
+
return this.target.runAction(ref, input, options);
|
|
76
|
+
}
|
|
77
|
+
const actionId = typeof ref === "string" ? (ref.includes(":") ? ref.split(":").pop() : ref) : ref.actionId;
|
|
78
|
+
return this.target.runAction(actionId, input, options);
|
|
79
|
+
}
|
|
80
|
+
async startAction(ref, input, options) {
|
|
81
|
+
if ("listApps" in this.target) {
|
|
82
|
+
return this.target.startAction(ref, input, options);
|
|
83
|
+
}
|
|
84
|
+
const actionId = typeof ref === "string" ? (ref.includes(":") ? ref.split(":").pop() : ref) : ref.actionId;
|
|
85
|
+
return this.target.startAction(actionId, input, options);
|
|
86
|
+
}
|
|
87
|
+
async listRuns(options) {
|
|
88
|
+
if ("listApps" in this.target) {
|
|
89
|
+
const apps = options?.packageId
|
|
90
|
+
? [this.target.getApp(options.packageId)].filter(Boolean)
|
|
91
|
+
: this.target.listApps();
|
|
92
|
+
let records = [];
|
|
93
|
+
for (const app of apps) {
|
|
94
|
+
const recs = app.storage.listRuns({
|
|
95
|
+
actionId: options?.actionId,
|
|
96
|
+
limit: options?.limit,
|
|
97
|
+
});
|
|
98
|
+
for (const r of recs) {
|
|
99
|
+
records.push({
|
|
100
|
+
...r,
|
|
101
|
+
packageId: r.packageId || app.packageId,
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
records.sort((a, b) => new Date(b.startedAt).getTime() - new Date(a.startedAt).getTime());
|
|
106
|
+
if (options?.status) {
|
|
107
|
+
records = records.filter((r) => r.status === options.status);
|
|
108
|
+
}
|
|
109
|
+
if (options?.limit && records.length > options.limit) {
|
|
110
|
+
records = records.slice(0, options.limit);
|
|
111
|
+
}
|
|
112
|
+
return records;
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
if (options?.packageId && options.packageId !== this.target.packageId) {
|
|
116
|
+
return [];
|
|
117
|
+
}
|
|
118
|
+
let records = this.target.storage.listRuns({
|
|
119
|
+
actionId: options?.actionId,
|
|
120
|
+
limit: options?.limit,
|
|
121
|
+
});
|
|
122
|
+
if (options?.status) {
|
|
123
|
+
records = records.filter((r) => r.status === options.status);
|
|
124
|
+
}
|
|
125
|
+
if (options?.limit && records.length > options.limit) {
|
|
126
|
+
records = records.slice(0, options.limit);
|
|
127
|
+
}
|
|
128
|
+
return records;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
async clearRuns(options) {
|
|
132
|
+
if ("listApps" in this.target) {
|
|
133
|
+
const apps = options?.packageId
|
|
134
|
+
? [this.target.getApp(options.packageId)].filter(Boolean)
|
|
135
|
+
: this.target.listApps();
|
|
136
|
+
let total = 0;
|
|
137
|
+
for (const app of apps) {
|
|
138
|
+
total += app.storage.clearRuns({
|
|
139
|
+
actionId: options?.actionId,
|
|
140
|
+
status: options?.status,
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
return total;
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
if (options?.packageId && options.packageId !== this.target.packageId) {
|
|
147
|
+
return 0;
|
|
148
|
+
}
|
|
149
|
+
return this.target.storage.clearRuns({
|
|
150
|
+
actionId: options?.actionId,
|
|
151
|
+
status: options?.status,
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
async getRun(runId) {
|
|
156
|
+
return this.target.getRun(runId);
|
|
157
|
+
}
|
|
158
|
+
async cancelRun(runId, reason) {
|
|
159
|
+
return this.target.cancelRun(runId, reason);
|
|
160
|
+
}
|
|
161
|
+
events(runId, options) {
|
|
162
|
+
return this.target.events(runId, options);
|
|
163
|
+
}
|
|
164
|
+
resolveApp(packageId) {
|
|
165
|
+
if ("listApps" in this.target) {
|
|
166
|
+
if (packageId) {
|
|
167
|
+
return this.target.getApp(packageId);
|
|
168
|
+
}
|
|
169
|
+
const apps = this.target.listApps();
|
|
170
|
+
return apps.length === 1 ? apps[0] : undefined;
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
if (!packageId || packageId === this.target.packageId) {
|
|
174
|
+
return this.target;
|
|
175
|
+
}
|
|
176
|
+
return undefined;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
getGlobalStorage() {
|
|
180
|
+
if ("globalStorage" in this.target && this.target.globalStorage) {
|
|
181
|
+
return this.target.globalStorage;
|
|
182
|
+
}
|
|
183
|
+
const apps = "listApps" in this.target ? this.target.listApps() : [];
|
|
184
|
+
for (const app of apps) {
|
|
185
|
+
if (app.globalStorage)
|
|
186
|
+
return app.globalStorage;
|
|
187
|
+
}
|
|
188
|
+
return createGlobalStorage({
|
|
189
|
+
dataDir: this.target.options?.dataDir,
|
|
190
|
+
customHome: this.target.options?.customHome,
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
findDeclaredConfigItem(key) {
|
|
194
|
+
if ("listApps" in this.target) {
|
|
195
|
+
let foundItem;
|
|
196
|
+
for (const app of this.target.listApps()) {
|
|
197
|
+
const item = app.projectConfig?.config?.[key];
|
|
198
|
+
if (item) {
|
|
199
|
+
if (item.secret)
|
|
200
|
+
return item;
|
|
201
|
+
foundItem = item;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
return foundItem;
|
|
205
|
+
}
|
|
206
|
+
else if ("projectConfig" in this.target) {
|
|
207
|
+
return this.target.projectConfig?.config?.[key];
|
|
208
|
+
}
|
|
209
|
+
return undefined;
|
|
210
|
+
}
|
|
211
|
+
async getConfig(packageId, key) {
|
|
212
|
+
if (packageId === "global") {
|
|
213
|
+
const globalStorage = this.getGlobalStorage();
|
|
214
|
+
const val = globalStorage.getConfig(key);
|
|
215
|
+
const configured = val !== undefined;
|
|
216
|
+
const declaredItem = this.findDeclaredConfigItem(key);
|
|
217
|
+
const isSecret = isSecretConfigKey(key, declaredItem);
|
|
218
|
+
return {
|
|
219
|
+
key,
|
|
220
|
+
configured,
|
|
221
|
+
secret: isSecret,
|
|
222
|
+
source: configured ? "global" : "default",
|
|
223
|
+
value: !isSecret && configured ? val : undefined,
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
const app = this.resolveApp(packageId);
|
|
227
|
+
if (!app) {
|
|
228
|
+
throw new Error(`Package '${packageId}' not found in target`);
|
|
229
|
+
}
|
|
230
|
+
return app.getConfig(key);
|
|
231
|
+
}
|
|
232
|
+
async setConfig(packageId, key, value) {
|
|
233
|
+
if (packageId === "global") {
|
|
234
|
+
await this.getGlobalStorage().setConfig(key, value);
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
const app = this.resolveApp(packageId);
|
|
238
|
+
if (!app) {
|
|
239
|
+
throw new Error(`Package '${packageId}' not found in target`);
|
|
240
|
+
}
|
|
241
|
+
await app.setConfig(key, value);
|
|
242
|
+
}
|
|
243
|
+
async deleteConfig(packageId, key) {
|
|
244
|
+
if (packageId === "global") {
|
|
245
|
+
return await this.getGlobalStorage().deleteConfig(key);
|
|
246
|
+
}
|
|
247
|
+
const app = this.resolveApp(packageId);
|
|
248
|
+
if (!app) {
|
|
249
|
+
throw new Error(`Package '${packageId}' not found in target`);
|
|
250
|
+
}
|
|
251
|
+
return await app.deleteConfig(key);
|
|
252
|
+
}
|
|
253
|
+
async listConfig(packageId) {
|
|
254
|
+
if (packageId === "global") {
|
|
255
|
+
const globalStorage = this.getGlobalStorage();
|
|
256
|
+
const all = globalStorage.listConfig();
|
|
257
|
+
return Object.entries(all).map(([key, val]) => {
|
|
258
|
+
const declaredItem = this.findDeclaredConfigItem(key);
|
|
259
|
+
const isSecret = isSecretConfigKey(key, declaredItem);
|
|
260
|
+
return {
|
|
261
|
+
key,
|
|
262
|
+
configured: true,
|
|
263
|
+
secret: isSecret,
|
|
264
|
+
source: "global",
|
|
265
|
+
value: isSecret ? undefined : val,
|
|
266
|
+
};
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
const app = this.resolveApp(packageId);
|
|
270
|
+
if (!app) {
|
|
271
|
+
throw new Error(`Package '${packageId}' not found in target`);
|
|
272
|
+
}
|
|
273
|
+
return app.listConfig();
|
|
274
|
+
}
|
|
275
|
+
async getState(packageId, actionId, key, options) {
|
|
276
|
+
const app = this.resolveApp(packageId);
|
|
277
|
+
if (!app) {
|
|
278
|
+
throw new Error(`Package '${packageId}' not found in target`);
|
|
279
|
+
}
|
|
280
|
+
return app.getState(actionId, key, options);
|
|
281
|
+
}
|
|
282
|
+
async setState(packageId, actionId, key, value, options) {
|
|
283
|
+
const app = this.resolveApp(packageId);
|
|
284
|
+
if (!app) {
|
|
285
|
+
throw new Error(`Package '${packageId}' not found in target`);
|
|
286
|
+
}
|
|
287
|
+
if (actionId) {
|
|
288
|
+
await app.setActionState(actionId, key, value, options);
|
|
289
|
+
}
|
|
290
|
+
else {
|
|
291
|
+
await app.setState(key, value, options);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
async deleteState(packageId, actionId, key, options) {
|
|
295
|
+
const app = this.resolveApp(packageId);
|
|
296
|
+
if (!app) {
|
|
297
|
+
throw new Error(`Package '${packageId}' not found in target`);
|
|
298
|
+
}
|
|
299
|
+
return app.deleteState(actionId, key, options);
|
|
300
|
+
}
|
|
301
|
+
async listStateKeys(packageId, actionId, options) {
|
|
302
|
+
const app = this.resolveApp(packageId);
|
|
303
|
+
if (!app) {
|
|
304
|
+
throw new Error(`Package '${packageId}' not found in target`);
|
|
305
|
+
}
|
|
306
|
+
return app.listStateKeys(actionId, options);
|
|
307
|
+
}
|
|
308
|
+
async clearState(packageId, actionId, options) {
|
|
309
|
+
const app = this.resolveApp(packageId);
|
|
310
|
+
if (!app) {
|
|
311
|
+
throw new Error(`Package '${packageId}' not found in target`);
|
|
312
|
+
}
|
|
313
|
+
return app.clearState(actionId, options);
|
|
314
|
+
}
|
|
315
|
+
async listStateEntries(packageId, options) {
|
|
316
|
+
const app = this.resolveApp(packageId);
|
|
317
|
+
if (!app) {
|
|
318
|
+
throw new TargetError(TARGET_CAPABILITY_UNAVAILABLE, `TARGET_CAPABILITY_UNAVAILABLE: Package '${packageId}' not found in target`);
|
|
319
|
+
}
|
|
320
|
+
if (!app.storage || typeof app.storage.listStateEntries !== "function") {
|
|
321
|
+
throw new TargetError(TARGET_CAPABILITY_UNAVAILABLE, `TARGET_CAPABILITY_UNAVAILABLE: listStateEntries is not supported by package '${packageId}' storage`);
|
|
322
|
+
}
|
|
323
|
+
return app.storage.listStateEntries(options);
|
|
324
|
+
}
|
|
325
|
+
async close(options) {
|
|
326
|
+
if (options?.timeoutMs && options.timeoutMs > 0) {
|
|
327
|
+
let timer;
|
|
328
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
329
|
+
timer = setTimeout(() => {
|
|
330
|
+
reject(new CloseTimeoutError(`Target close operation timed out after ${options.timeoutMs}ms`));
|
|
331
|
+
}, options.timeoutMs);
|
|
332
|
+
});
|
|
333
|
+
try {
|
|
334
|
+
await Promise.race([this.target.close(), timeoutPromise]);
|
|
335
|
+
}
|
|
336
|
+
finally {
|
|
337
|
+
clearTimeout(timer);
|
|
338
|
+
}
|
|
339
|
+
return;
|
|
340
|
+
}
|
|
341
|
+
return this.target.close();
|
|
342
|
+
}
|
|
343
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import type { ActionRef, ExecutionEvent, ExecutionResult, JsonValue, RunRecord } from "@actiondock/sdk";
|
|
2
|
+
import type { ActionSpec, ActionSummary, ListActionsOptions, PackageInfo, PlaybookSpec, PlaybookSummary } from "../app/types.js";
|
|
3
|
+
import type { CancelResult, ExecuteOptions, ExecutionTicket } from "../execution/types.js";
|
|
4
|
+
import { type StateEntry } from "../storage/types.js";
|
|
5
|
+
import { type ActionDockTarget, type ConfigValueView, type ListRunsOptions, type RemoteTargetOptions, type StateScopeOptions, type TargetInfo } from "./types.js";
|
|
6
|
+
/**
|
|
7
|
+
* 读取并解析远端 SSE 事件流。
|
|
8
|
+
*/
|
|
9
|
+
export declare function streamRemoteEvents(serverUrl: string, runId: string, token?: string, options?: {
|
|
10
|
+
after?: number | string;
|
|
11
|
+
signal?: AbortSignal;
|
|
12
|
+
maxQueueSize?: number;
|
|
13
|
+
allowInsecureHttp?: boolean;
|
|
14
|
+
}): AsyncIterable<ExecutionEvent>;
|
|
15
|
+
/**
|
|
16
|
+
* 远程 ActionDockTarget 门面实现。
|
|
17
|
+
* 内部封装基于 HTTP/SSE 协议与远端 ActionDock 服务端的通信管道。
|
|
18
|
+
*/
|
|
19
|
+
export declare class RemoteActionDockTarget implements ActionDockTarget {
|
|
20
|
+
readonly serverUrl: string;
|
|
21
|
+
readonly token?: string;
|
|
22
|
+
readonly timeoutMs?: number;
|
|
23
|
+
readonly baseTimeoutMs: number;
|
|
24
|
+
readonly allowInsecureHttp?: boolean;
|
|
25
|
+
constructor(options: RemoteTargetOptions);
|
|
26
|
+
info(): Promise<TargetInfo>;
|
|
27
|
+
listPackages(): Promise<PackageInfo[]>;
|
|
28
|
+
listActions(options?: ListActionsOptions): Promise<ActionSummary[]>;
|
|
29
|
+
describeAction(ref: ActionRef | string): Promise<ActionSpec>;
|
|
30
|
+
listPlaybooks(options?: {
|
|
31
|
+
intent?: string;
|
|
32
|
+
package?: string;
|
|
33
|
+
}): Promise<PlaybookSummary[]>;
|
|
34
|
+
describePlaybook(id: string): Promise<PlaybookSpec>;
|
|
35
|
+
runAction(ref: ActionRef | string, input: JsonValue, options?: ExecuteOptions): Promise<ExecutionResult>;
|
|
36
|
+
startAction(ref: ActionRef | string, input: JsonValue, options?: ExecuteOptions): Promise<ExecutionTicket>;
|
|
37
|
+
/**
|
|
38
|
+
* 等待远端运行抵达终态:优先监听 SSE 事件流,失败后按指数退避轮询运行详情。
|
|
39
|
+
*
|
|
40
|
+
* @param runId 运行标识
|
|
41
|
+
* @param signal 外部取消信号
|
|
42
|
+
* @param timeoutMs 运行自身声明的超时(等待上限取该值与默认上限中的较大者)
|
|
43
|
+
*/
|
|
44
|
+
private waitForRunCompletion;
|
|
45
|
+
/**
|
|
46
|
+
* 指数退避轮询远端运行详情直至终态、取消或超时上限。
|
|
47
|
+
*/
|
|
48
|
+
private pollRunCompletion;
|
|
49
|
+
private formatTerminalRunResult;
|
|
50
|
+
listRuns(options?: ListRunsOptions): Promise<RunRecord[]>;
|
|
51
|
+
clearRuns(options?: {
|
|
52
|
+
packageId?: string;
|
|
53
|
+
actionId?: string;
|
|
54
|
+
status?: string;
|
|
55
|
+
}): Promise<number>;
|
|
56
|
+
getRun(runId: string): Promise<RunRecord | undefined>;
|
|
57
|
+
cancelRun(runId: string, reason?: string): Promise<CancelResult>;
|
|
58
|
+
events(runId: string, options?: {
|
|
59
|
+
after?: number | string;
|
|
60
|
+
signal?: AbortSignal;
|
|
61
|
+
maxQueueSize?: number;
|
|
62
|
+
}): AsyncIterable<ExecutionEvent>;
|
|
63
|
+
getConfig(packageId: string, key: string): Promise<ConfigValueView>;
|
|
64
|
+
setConfig(packageId: string, key: string, value: JsonValue): Promise<void>;
|
|
65
|
+
deleteConfig(packageId: string, key: string): Promise<boolean>;
|
|
66
|
+
listConfig(packageId: string): Promise<ConfigValueView[]>;
|
|
67
|
+
getState<T extends JsonValue = JsonValue>(packageId: string, actionId: string, key: string, options?: StateScopeOptions): Promise<T | undefined>;
|
|
68
|
+
setState<T extends JsonValue = JsonValue>(packageId: string, actionId: string, key: string, value: T, options?: StateScopeOptions): Promise<void>;
|
|
69
|
+
deleteState(packageId: string, actionId: string, key: string, options?: StateScopeOptions): Promise<boolean>;
|
|
70
|
+
listStateKeys(packageId: string, actionId: string, options?: StateScopeOptions): Promise<string[]>;
|
|
71
|
+
clearState(packageId: string, actionId: string, options?: StateScopeOptions): Promise<number>;
|
|
72
|
+
listStateEntries(packageId: string, options?: any): Promise<StateEntry[]>;
|
|
73
|
+
close(_options?: {
|
|
74
|
+
timeoutMs?: number;
|
|
75
|
+
}): Promise<void>;
|
|
76
|
+
}
|