@actiondock/core 2.0.11 → 2.2.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 -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 +9 -0
- package/dist/catalog/action-index.js +93 -0
- package/dist/catalog/action-resolver.d.ts +20 -0
- package/dist/catalog/action-resolver.js +95 -0
- package/dist/catalog/index.d.ts +5 -0
- package/dist/catalog/index.js +5 -0
- package/dist/catalog/location-registry.d.ts +15 -0
- package/dist/catalog/location-registry.js +138 -0
- package/dist/catalog/package-catalog.d.ts +7 -0
- package/dist/catalog/package-catalog.js +76 -0
- package/dist/catalog/types.d.ts +68 -0
- package/dist/catalog/types.js +1 -0
- package/dist/doctor/doctor.d.ts +7 -0
- package/dist/doctor/doctor.js +613 -0
- package/dist/doctor/index.d.ts +2 -0
- package/dist/doctor/index.js +2 -0
- package/dist/doctor/types.d.ts +23 -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 -0
- package/dist/execution/index.js +2 -0
- package/dist/execution/service.d.ts +79 -0
- package/dist/execution/service.js +633 -0
- package/dist/execution/types.d.ts +131 -0
- package/dist/execution/types.js +1 -0
- package/dist/export/index.d.ts +1 -0
- package/dist/export/index.js +1 -0
- package/dist/export/templates.d.ts +71 -0
- package/dist/export/templates.js +621 -0
- package/dist/filter/index.d.ts +1 -0
- package/dist/filter/index.js +1 -0
- package/dist/filter/intent.d.ts +33 -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 -0
- package/dist/index.js +20 -0
- 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 +162 -0
- package/dist/profile/client.js +467 -0
- package/dist/profile/index.d.ts +3 -0
- package/dist/profile/index.js +3 -0
- package/dist/profile/manager.d.ts +47 -0
- package/dist/profile/manager.js +294 -0
- package/dist/profile/types.d.ts +61 -0
- package/dist/profile/types.js +1 -0
- package/dist/project/closure.d.ts +25 -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 -0
- package/dist/project/index.js +10 -0
- package/dist/project/init.d.ts +26 -0
- package/dist/project/init.js +175 -0
- package/dist/project/loader.d.ts +99 -0
- 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 +22 -0
- 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 +107 -0
- package/dist/project/types.js +1 -0
- package/dist/registry/index.d.ts +5 -0
- 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 +45 -0
- 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 +117 -0
- 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 +19 -0
- package/dist/runtime/clock.js +17 -0
- package/dist/runtime/context.d.ts +86 -0
- package/dist/runtime/context.js +242 -0
- package/dist/runtime/env.d.ts +56 -0
- package/dist/runtime/env.js +159 -0
- package/dist/runtime/events.d.ts +93 -0
- package/dist/runtime/events.js +604 -0
- package/dist/runtime/execution-manager.d.ts +48 -0
- package/dist/runtime/execution-manager.js +66 -0
- package/dist/runtime/index.d.ts +10 -0
- package/dist/runtime/index.js +10 -0
- package/dist/runtime/module-loader.d.ts +34 -0
- package/dist/runtime/module-loader.js +16 -0
- package/dist/runtime/process.d.ts +9 -0
- package/dist/runtime/process.js +146 -0
- package/dist/runtime/runner.d.ts +293 -0
- package/dist/runtime/runner.js +984 -0
- package/dist/runtime/standalone.d.ts +89 -0
- package/dist/runtime/standalone.js +536 -0
- package/dist/schema/validator.d.ts +28 -0
- package/dist/schema/validator.js +116 -0
- package/dist/server/body.d.ts +40 -0
- package/dist/server/body.js +93 -0
- package/dist/server/index.d.ts +5 -0
- package/dist/server/index.js +5 -0
- package/dist/server/routes/actions.d.ts +5 -0
- package/dist/server/routes/actions.js +298 -0
- package/dist/server/routes/common.d.ts +47 -0
- package/dist/server/routes/common.js +104 -0
- package/dist/server/routes/config.d.ts +6 -0
- package/dist/server/routes/config.js +173 -0
- package/dist/server/routes/doctor.d.ts +5 -0
- package/dist/server/routes/doctor.js +63 -0
- package/dist/server/routes/health.d.ts +5 -0
- package/dist/server/routes/health.js +35 -0
- package/dist/server/routes/index.d.ts +9 -0
- package/dist/server/routes/index.js +9 -0
- package/dist/server/routes/info.d.ts +7 -0
- package/dist/server/routes/info.js +158 -0
- package/dist/server/routes/playbooks.d.ts +5 -0
- package/dist/server/routes/playbooks.js +134 -0
- package/dist/server/routes/runs.d.ts +5 -0
- package/dist/server/routes/runs.js +343 -0
- package/dist/server/routes/state.d.ts +6 -0
- package/dist/server/routes/state.js +169 -0
- package/dist/server/security.d.ts +44 -0
- package/dist/server/security.js +101 -0
- package/dist/server/server.d.ts +15 -0
- package/dist/server/server.js +355 -0
- package/dist/server/types.d.ts +78 -0
- 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 +9 -0
- package/dist/storage/driver.js +59 -0
- package/dist/storage/index.d.ts +64 -0
- 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 +26 -0
- 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 +79 -0
- package/dist/storage/sqlite.js +689 -0
- package/dist/storage/types.d.ts +172 -0
- 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 +49 -0
- package/dist/utils/index.js +180 -0
- package/dist/version.d.ts +4 -0
- package/dist/version.js +4 -0
- package/package.json +13 -13
- package/src/build/index.ts +0 -1
- package/src/build/templates.ts +0 -59
- package/src/catalog/action-index.ts +0 -92
- package/src/catalog/action-resolver.ts +0 -120
- package/src/catalog/index.ts +0 -5
- package/src/catalog/location-registry.ts +0 -134
- package/src/catalog/package-catalog.ts +0 -87
- package/src/catalog/types.ts +0 -75
- package/src/doctor/doctor.ts +0 -419
- package/src/doctor/index.ts +0 -2
- package/src/doctor/types.ts +0 -25
- package/src/execution/index.ts +0 -2
- package/src/execution/service.ts +0 -322
- package/src/execution/types.ts +0 -73
- package/src/export/index.ts +0 -1
- package/src/export/templates.ts +0 -590
- package/src/filter/index.ts +0 -1
- package/src/filter/intent.ts +0 -154
- package/src/index.ts +0 -16
- package/src/profile/client.ts +0 -552
- package/src/profile/index.ts +0 -3
- package/src/profile/manager.ts +0 -341
- package/src/profile/types.ts +0 -71
- package/src/project/index.ts +0 -4
- package/src/project/init.ts +0 -242
- package/src/project/loader.ts +0 -479
- package/src/project/manifest.ts +0 -299
- package/src/project/types.ts +0 -141
- package/src/registry/index.ts +0 -2
- package/src/registry/registry.ts +0 -940
- package/src/registry/types.ts +0 -127
- package/src/runtime/clock.ts +0 -41
- package/src/runtime/context.ts +0 -259
- package/src/runtime/env.ts +0 -172
- package/src/runtime/events.ts +0 -142
- package/src/runtime/execution-manager.ts +0 -74
- package/src/runtime/index.ts +0 -10
- package/src/runtime/module-loader.ts +0 -67
- package/src/runtime/process.ts +0 -245
- package/src/runtime/runner.ts +0 -527
- package/src/runtime/standalone.ts +0 -429
- package/src/schema/validator.ts +0 -61
- package/src/server/body.ts +0 -112
- package/src/server/index.ts +0 -7
- package/src/server/routes/actions.ts +0 -262
- package/src/server/routes/common.ts +0 -126
- package/src/server/routes/config.ts +0 -147
- package/src/server/routes/doctor.ts +0 -29
- package/src/server/routes/health.ts +0 -40
- package/src/server/routes/index.ts +0 -9
- package/src/server/routes/info.ts +0 -221
- package/src/server/routes/playbooks.ts +0 -109
- package/src/server/routes/runs.ts +0 -301
- package/src/server/routes/state.ts +0 -133
- package/src/server/runtime-registry.ts +0 -115
- package/src/server/security.ts +0 -115
- package/src/server/server.ts +0 -251
- package/src/server/types.ts +0 -57
- package/src/storage/driver.ts +0 -126
- package/src/storage/index.ts +0 -81
- package/src/storage/mask.ts +0 -34
- package/src/storage/sqlite.ts +0 -714
- package/src/storage/types.ts +0 -139
- package/src/utils/index.ts +0 -62
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import type { ActionRef, ExecutionEvent, ExecutionResult, JsonValue, Logger, ProcessAPI, RunRecord } from "@actiondock/sdk";
|
|
2
|
+
import type { ActionDockApp, ActionDockAppOptions, ActionSpec, ActionSummary, ListActionsOptions, PackageInfo, PlaybookSpec, PlaybookSummary } from "../app/types.js";
|
|
3
|
+
import type { CancelResult, ExecuteOptions, ExecutionTicket } from "../execution/types.js";
|
|
4
|
+
import type { Clock } from "../runtime/clock.js";
|
|
5
|
+
import type { EventSink } from "../runtime/events.js";
|
|
6
|
+
import type { RuntimePlatform } from "../platform/types.js";
|
|
7
|
+
/**
|
|
8
|
+
* ActionDock 宿主容器初始化配置选项。
|
|
9
|
+
*/
|
|
10
|
+
export interface ActionDockHostOptions {
|
|
11
|
+
/** 显式预注册的包列表(现成 ActionDockApp 实例或 ActionDockAppOptions 配置)。外部传入的 App 属于借用(borrowed),生命周期完全由调用方负责管理,Host 关闭或初始化失败时仅解绑引用并清理自身内部实例,严禁关闭外部借用的 App 实例。 */
|
|
12
|
+
packages?: Array<ActionDockApp | ActionDockAppOptions>;
|
|
13
|
+
/** 当前工程根目录绝对物理路径 */
|
|
14
|
+
projectRoot?: string;
|
|
15
|
+
/** 是否自动加载当前工程(默认为 true) */
|
|
16
|
+
autoLoadCurrentProject?: boolean;
|
|
17
|
+
/** 是否扫描已软链接的外部包(通过 listLinkedPackages,默认为 false) */
|
|
18
|
+
scanLinkedPackages?: boolean;
|
|
19
|
+
/** 显式注入的运行时平台适配 */
|
|
20
|
+
platform?: RuntimePlatform;
|
|
21
|
+
/** 全局最大并发活跃运行数 */
|
|
22
|
+
maxActiveRuns?: number;
|
|
23
|
+
/** 全局调用嵌套深度限制(默认 16) */
|
|
24
|
+
maxCallDepth?: number;
|
|
25
|
+
/** 全局子任务数限制(默认 64) */
|
|
26
|
+
maxSubRuns?: number;
|
|
27
|
+
/** 日志记录器 */
|
|
28
|
+
logger?: Logger;
|
|
29
|
+
/** 时钟源 */
|
|
30
|
+
clock?: Clock;
|
|
31
|
+
/** 进程执行器 */
|
|
32
|
+
process?: ProcessAPI;
|
|
33
|
+
/** 数据持久化存储目录 */
|
|
34
|
+
dataDir?: string;
|
|
35
|
+
/** 自定义 ActionDock 家目录 */
|
|
36
|
+
customHome?: string;
|
|
37
|
+
/** 是否采用纯内存运行模式 */
|
|
38
|
+
inMemory?: boolean;
|
|
39
|
+
/** 事件接收器 */
|
|
40
|
+
eventSink?: EventSink;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* ActionDock 多包宿主容器领域契约。
|
|
44
|
+
* 作为多包环境下的全局协调中枢,负责多包生命周期、完全限定引用路由、依赖校验与配额管理。
|
|
45
|
+
*/
|
|
46
|
+
export interface ActionDockHost {
|
|
47
|
+
/** 获取所有已注册包的元数据信息列表 */
|
|
48
|
+
info(): Promise<PackageInfo[]>;
|
|
49
|
+
/** 静态列出所有已注册包中可用的 Action 摘要 */
|
|
50
|
+
listActions(options?: ListActionsOptions): Promise<ActionSummary[]>;
|
|
51
|
+
/** 静态查询并返回指定 Action 的规范结构与模式定义 */
|
|
52
|
+
describeAction(ref: ActionRef | string): Promise<ActionSpec>;
|
|
53
|
+
/** 静态列出所有已注册包中可用的 Playbook 规程摘要 */
|
|
54
|
+
listPlaybooks(): Promise<PlaybookSummary[]>;
|
|
55
|
+
/** 静态查询并返回指定 Playbook 的规范内容与操作指南 */
|
|
56
|
+
describePlaybook(id: string): Promise<PlaybookSpec>;
|
|
57
|
+
/** 同步执行指定 Action 并等待终态结果 */
|
|
58
|
+
runAction(ref: ActionRef | string, input: JsonValue, options?: ExecuteOptions): Promise<ExecutionResult>;
|
|
59
|
+
/** 异步启动指定 Action 并立即返回任务执行票据 */
|
|
60
|
+
startAction(ref: ActionRef | string, input: JsonValue, options?: ExecuteOptions): Promise<ExecutionTicket>;
|
|
61
|
+
/** 查询指定运行标识的记录详情 */
|
|
62
|
+
getRun(runId: string): Promise<RunRecord | undefined>;
|
|
63
|
+
/** 取消指定在运行的任务 */
|
|
64
|
+
cancelRun(runId: string, reason?: string): Promise<CancelResult>;
|
|
65
|
+
/** 订阅指定运行的事件流 */
|
|
66
|
+
events(runId: string, options?: {
|
|
67
|
+
after?: number | string;
|
|
68
|
+
signal?: AbortSignal;
|
|
69
|
+
maxQueueSize?: number;
|
|
70
|
+
}): AsyncIterable<ExecutionEvent>;
|
|
71
|
+
/** 根据包唯一标识获取指定 App 实例 */
|
|
72
|
+
getApp(packageId: string): ActionDockApp | undefined;
|
|
73
|
+
/** 获取所有当前已注册的 App 实例列表 */
|
|
74
|
+
listApps(): ActionDockApp[];
|
|
75
|
+
/** 注册新的 App 实例至当前宿主容器 */
|
|
76
|
+
registerApp(app: ActionDockApp): void;
|
|
77
|
+
/** 优雅关闭宿主容器。仅对内部创建的 App 实例执行 close 并安全释放底层资源;外部传入借用的 App 实例生命周期完全由调用方负责管理,Host 关闭时仅解绑引用并清理自身内部实例。 */
|
|
78
|
+
close(options?: {
|
|
79
|
+
graceMs?: number;
|
|
80
|
+
}): Promise<void>;
|
|
81
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export * from "./catalog/index.js";
|
|
2
|
+
export * from "./doctor/index.js";
|
|
3
|
+
export * from "./errors.js";
|
|
4
|
+
export * from "./execution/index.js";
|
|
5
|
+
export * from "./export/index.js";
|
|
6
|
+
export * from "./filter/index.js";
|
|
7
|
+
export * from "./platform/index.js";
|
|
8
|
+
export * from "./profile/index.js";
|
|
9
|
+
export * from "./project/index.js";
|
|
10
|
+
export * from "./registry/index.js";
|
|
11
|
+
export * from "./runtime/index.js";
|
|
12
|
+
export * from "./schema/validator.js";
|
|
13
|
+
export * from "./server/index.js";
|
|
14
|
+
export * from "./storage/index.js";
|
|
15
|
+
export * from "./utils/index.js";
|
|
16
|
+
export * from "./version.js";
|
|
17
|
+
export * from "./app/index.js";
|
|
18
|
+
export * from "./host/index.js";
|
|
19
|
+
export * from "./target/index.js";
|
|
20
|
+
export * from "./ipc/index.js";
|
|
21
|
+
export type { ModuleLoader } from "./runtime/index.js";
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export * from "./catalog/index.js";
|
|
2
|
+
export * from "./doctor/index.js";
|
|
3
|
+
export * from "./errors.js";
|
|
4
|
+
export * from "./execution/index.js";
|
|
5
|
+
export * from "./export/index.js";
|
|
6
|
+
export * from "./filter/index.js";
|
|
7
|
+
export * from "./platform/index.js";
|
|
8
|
+
export * from "./profile/index.js";
|
|
9
|
+
export * from "./project/index.js";
|
|
10
|
+
export * from "./registry/index.js";
|
|
11
|
+
export * from "./runtime/index.js";
|
|
12
|
+
export * from "./schema/validator.js";
|
|
13
|
+
export * from "./server/index.js";
|
|
14
|
+
export * from "./storage/index.js";
|
|
15
|
+
export * from "./utils/index.js";
|
|
16
|
+
export * from "./version.js";
|
|
17
|
+
export * from "./app/index.js";
|
|
18
|
+
export * from "./host/index.js";
|
|
19
|
+
export * from "./target/index.js";
|
|
20
|
+
export * from "./ipc/index.js";
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import type { Readable, Writable } from "node:stream";
|
|
2
|
+
/**
|
|
3
|
+
* 诊断日志限流排空转发器配置选项。
|
|
4
|
+
*/
|
|
5
|
+
export interface DiagnosticForwarderOptions {
|
|
6
|
+
/** 允许转发的累计最大字节数(默认 512 KB) */
|
|
7
|
+
maxBytes?: number;
|
|
8
|
+
/** 每秒允许转发的最大字节速率(默认 64 KB/秒) */
|
|
9
|
+
maxRateBytesPerSec?: number;
|
|
10
|
+
/** 目标输出流(默认 process.stderr) */
|
|
11
|
+
target?: Writable;
|
|
12
|
+
/** 诊断流标识前缀 */
|
|
13
|
+
prefix?: string;
|
|
14
|
+
/** 触发超限截断时的回调通知 */
|
|
15
|
+
onTruncated?: (reason: "size_limit" | "rate_limit") => void;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* 诊断流受控转发与限流排空器(DiagnosticForwarder)。
|
|
19
|
+
*
|
|
20
|
+
* 职责:
|
|
21
|
+
* 1. 独占捕获子进程的标准输出与标准错误流,杜绝第三方代码污染父进程标准协议通道。
|
|
22
|
+
* 2. 实时监测字节总量与秒级传输速率上限。
|
|
23
|
+
* 3. 达到阈值后立即停止对外转发、向诊断通道记录截断事件。
|
|
24
|
+
* 4. 持续以非阻塞方式静默排空后续数据流,避免子进程因管道背压堆积死锁。
|
|
25
|
+
*/
|
|
26
|
+
export declare class DiagnosticForwarder {
|
|
27
|
+
private readonly maxBytes;
|
|
28
|
+
private readonly maxRateBytesPerSec;
|
|
29
|
+
private readonly target;
|
|
30
|
+
private readonly prefix;
|
|
31
|
+
private readonly onTruncated?;
|
|
32
|
+
private totalBytesEmitted;
|
|
33
|
+
private windowStartMs;
|
|
34
|
+
private bytesInCurrentWindow;
|
|
35
|
+
private truncated;
|
|
36
|
+
private attachedStreams;
|
|
37
|
+
constructor(options?: DiagnosticForwarderOptions);
|
|
38
|
+
/**
|
|
39
|
+
* 是否已达到上限并处于截断状态。
|
|
40
|
+
*/
|
|
41
|
+
get isTruncated(): boolean;
|
|
42
|
+
/**
|
|
43
|
+
* 已成功转发的累计字节数。
|
|
44
|
+
*/
|
|
45
|
+
get bytesEmitted(): number;
|
|
46
|
+
/**
|
|
47
|
+
* 绑定并监听可读流(如 childProcess.stdout 或 childProcess.stderr)。
|
|
48
|
+
*
|
|
49
|
+
* @param stream 待转发的可读流
|
|
50
|
+
* @param label 流标识(如 "stdout" 或 "stderr")
|
|
51
|
+
*/
|
|
52
|
+
attach(stream: Readable, label?: string): void;
|
|
53
|
+
/**
|
|
54
|
+
* 解绑指定的流监听。
|
|
55
|
+
*/
|
|
56
|
+
detach(stream: Readable): void;
|
|
57
|
+
/**
|
|
58
|
+
* 解绑所有已连接的流。
|
|
59
|
+
*/
|
|
60
|
+
detachAll(): void;
|
|
61
|
+
/**
|
|
62
|
+
* 重置计数器与截断标志。
|
|
63
|
+
*/
|
|
64
|
+
reset(): void;
|
|
65
|
+
}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 诊断流受控转发与限流排空器(DiagnosticForwarder)。
|
|
3
|
+
*
|
|
4
|
+
* 职责:
|
|
5
|
+
* 1. 独占捕获子进程的标准输出与标准错误流,杜绝第三方代码污染父进程标准协议通道。
|
|
6
|
+
* 2. 实时监测字节总量与秒级传输速率上限。
|
|
7
|
+
* 3. 达到阈值后立即停止对外转发、向诊断通道记录截断事件。
|
|
8
|
+
* 4. 持续以非阻塞方式静默排空后续数据流,避免子进程因管道背压堆积死锁。
|
|
9
|
+
*/
|
|
10
|
+
export class DiagnosticForwarder {
|
|
11
|
+
maxBytes;
|
|
12
|
+
maxRateBytesPerSec;
|
|
13
|
+
target;
|
|
14
|
+
prefix;
|
|
15
|
+
onTruncated;
|
|
16
|
+
totalBytesEmitted = 0;
|
|
17
|
+
windowStartMs = Date.now();
|
|
18
|
+
bytesInCurrentWindow = 0;
|
|
19
|
+
truncated = false;
|
|
20
|
+
attachedStreams = new Map();
|
|
21
|
+
constructor(options = {}) {
|
|
22
|
+
this.maxBytes = options.maxBytes ?? 512 * 1024;
|
|
23
|
+
this.maxRateBytesPerSec = options.maxRateBytesPerSec ?? 64 * 1024;
|
|
24
|
+
this.target = options.target ?? process.stderr;
|
|
25
|
+
this.prefix = options.prefix ?? "";
|
|
26
|
+
this.onTruncated = options.onTruncated;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* 是否已达到上限并处于截断状态。
|
|
30
|
+
*/
|
|
31
|
+
get isTruncated() {
|
|
32
|
+
return this.truncated;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* 已成功转发的累计字节数。
|
|
36
|
+
*/
|
|
37
|
+
get bytesEmitted() {
|
|
38
|
+
return this.totalBytesEmitted;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* 绑定并监听可读流(如 childProcess.stdout 或 childProcess.stderr)。
|
|
42
|
+
*
|
|
43
|
+
* @param stream 待转发的可读流
|
|
44
|
+
* @param label 流标识(如 "stdout" 或 "stderr")
|
|
45
|
+
*/
|
|
46
|
+
attach(stream, label) {
|
|
47
|
+
if (this.attachedStreams.has(stream))
|
|
48
|
+
return;
|
|
49
|
+
const handler = (chunk) => {
|
|
50
|
+
const buf = typeof chunk === "string" ? Buffer.from(chunk, "utf-8") : chunk;
|
|
51
|
+
const len = buf.length;
|
|
52
|
+
// 刷新秒级速率统计窗口
|
|
53
|
+
const now = Date.now();
|
|
54
|
+
if (now - this.windowStartMs >= 1000) {
|
|
55
|
+
this.windowStartMs = now;
|
|
56
|
+
this.bytesInCurrentWindow = 0;
|
|
57
|
+
}
|
|
58
|
+
if (this.truncated) {
|
|
59
|
+
// 已截断:仅排空丢弃数据,不转发,保持流处于读取排空状态
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
// 检查容量与速率上限
|
|
63
|
+
let exceedReason = null;
|
|
64
|
+
if (this.totalBytesEmitted + len > this.maxBytes) {
|
|
65
|
+
exceedReason = "size_limit";
|
|
66
|
+
}
|
|
67
|
+
else if (this.bytesInCurrentWindow + len > this.maxRateBytesPerSec) {
|
|
68
|
+
exceedReason = "rate_limit";
|
|
69
|
+
}
|
|
70
|
+
if (exceedReason) {
|
|
71
|
+
this.truncated = true;
|
|
72
|
+
const tag = label ? `[${label}] ` : "";
|
|
73
|
+
const notice = `\n[Supervisor] ${tag}Diagnostic output exceeded ${exceedReason === "size_limit" ? `size limit (${this.maxBytes} bytes)` : `rate limit (${this.maxRateBytesPerSec} B/s)`}. Forwarding suspended; draining stream.\n`;
|
|
74
|
+
try {
|
|
75
|
+
this.target.write(notice);
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
// 忽略写入失败
|
|
79
|
+
}
|
|
80
|
+
this.onTruncated?.(exceedReason);
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
// 正常转发
|
|
84
|
+
this.totalBytesEmitted += len;
|
|
85
|
+
this.bytesInCurrentWindow += len;
|
|
86
|
+
try {
|
|
87
|
+
if (this.prefix) {
|
|
88
|
+
this.target.write(`${this.prefix}${buf.toString("utf-8")}`);
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
this.target.write(buf);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
// 忽略目标写入异常
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
stream.on("data", handler);
|
|
99
|
+
this.attachedStreams.set(stream, handler);
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* 解绑指定的流监听。
|
|
103
|
+
*/
|
|
104
|
+
detach(stream) {
|
|
105
|
+
const handler = this.attachedStreams.get(stream);
|
|
106
|
+
if (handler) {
|
|
107
|
+
stream.removeListener("data", handler);
|
|
108
|
+
this.attachedStreams.delete(stream);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* 解绑所有已连接的流。
|
|
113
|
+
*/
|
|
114
|
+
detachAll() {
|
|
115
|
+
for (const [stream, handler] of this.attachedStreams.entries()) {
|
|
116
|
+
stream.removeListener("data", handler);
|
|
117
|
+
}
|
|
118
|
+
this.attachedStreams.clear();
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* 重置计数器与截断标志。
|
|
122
|
+
*/
|
|
123
|
+
reset() {
|
|
124
|
+
this.totalBytesEmitted = 0;
|
|
125
|
+
this.bytesInCurrentWindow = 0;
|
|
126
|
+
this.windowStartMs = Date.now();
|
|
127
|
+
this.truncated = false;
|
|
128
|
+
}
|
|
129
|
+
}
|
package/dist/ipc/host.js
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 在 Host 子进程中启动 Node IPC 服务,向父进程暴露 ActionDockTarget 门面能力。
|
|
3
|
+
*
|
|
4
|
+
* @param target 已构造好的 ActionDockTarget 实例
|
|
5
|
+
*/
|
|
6
|
+
export async function serveParentIpc(target) {
|
|
7
|
+
if (!process.send) {
|
|
8
|
+
// 若当前未以 IPC 模式运行,直接退出
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
let isClosing = false;
|
|
12
|
+
const safeClose = async () => {
|
|
13
|
+
if (isClosing)
|
|
14
|
+
return;
|
|
15
|
+
isClosing = true;
|
|
16
|
+
try {
|
|
17
|
+
await target.close();
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
// 忽略关闭异常
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
// 监听父进程断连或退出信号
|
|
24
|
+
process.once("disconnect", async () => {
|
|
25
|
+
await safeClose();
|
|
26
|
+
process.exit(0);
|
|
27
|
+
});
|
|
28
|
+
process.once("SIGINT", async () => {
|
|
29
|
+
await safeClose();
|
|
30
|
+
process.exit(130);
|
|
31
|
+
});
|
|
32
|
+
process.once("SIGTERM", async () => {
|
|
33
|
+
await safeClose();
|
|
34
|
+
process.exit(143);
|
|
35
|
+
});
|
|
36
|
+
// 处理父进程 IPC 调用请求
|
|
37
|
+
process.on("message", async (msg) => {
|
|
38
|
+
if (!msg || typeof msg !== "object")
|
|
39
|
+
return;
|
|
40
|
+
if (msg.type === "call") {
|
|
41
|
+
const callMsg = msg;
|
|
42
|
+
const { id, method, args } = callMsg;
|
|
43
|
+
try {
|
|
44
|
+
const fn = target[method];
|
|
45
|
+
if (typeof fn !== "function") {
|
|
46
|
+
throw new Error(`Target method '${method}' not found`);
|
|
47
|
+
}
|
|
48
|
+
const result = await fn.apply(target, args || []);
|
|
49
|
+
const response = {
|
|
50
|
+
id,
|
|
51
|
+
type: "response",
|
|
52
|
+
ok: true,
|
|
53
|
+
data: result,
|
|
54
|
+
};
|
|
55
|
+
if (process.send) {
|
|
56
|
+
process.send(response);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
catch (err) {
|
|
60
|
+
const response = {
|
|
61
|
+
id,
|
|
62
|
+
type: "response",
|
|
63
|
+
ok: false,
|
|
64
|
+
error: {
|
|
65
|
+
code: err?.code || "TARGET_ERROR",
|
|
66
|
+
message: err?.message || String(err),
|
|
67
|
+
stack: err?.stack,
|
|
68
|
+
details: err?.details,
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
if (process.send) {
|
|
72
|
+
process.send(response);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
else if (msg.type === "close") {
|
|
77
|
+
await safeClose();
|
|
78
|
+
if (process.send) {
|
|
79
|
+
process.send({ id: msg.id, type: "response", ok: true });
|
|
80
|
+
}
|
|
81
|
+
process.exit(0);
|
|
82
|
+
}
|
|
83
|
+
else if (msg.type === "ping") {
|
|
84
|
+
if (process.send) {
|
|
85
|
+
process.send({ type: "pong" });
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
// 通知监督父进程:Host 已就绪
|
|
90
|
+
if (process.send) {
|
|
91
|
+
process.send({ type: "ready" });
|
|
92
|
+
}
|
|
93
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { type ChildProcess } from "node:child_process";
|
|
2
|
+
import type { ActionRef, ExecutionEvent, ExecutionResult, JsonValue, RunRecord } from "@actiondock/sdk";
|
|
3
|
+
import type { ActionSpec, ActionSummary, ListActionsOptions, PackageInfo, PlaybookSpec, PlaybookSummary } from "../app/types.js";
|
|
4
|
+
import type { CancelResult, ExecuteOptions, ExecutionTicket } from "../execution/types.js";
|
|
5
|
+
import type { ActionDockTarget, ConfigValueView, IpcTargetOptions, StateScopeOptions, TargetInfo } from "../target/types.js";
|
|
6
|
+
/**
|
|
7
|
+
* 基于 Node IPC 监督进程通信通道的 ActionDockTarget 实现。
|
|
8
|
+
*
|
|
9
|
+
* 职责:
|
|
10
|
+
* 1. 监督并隔离子进程的生命周期与标准输出,保证父进程标准输入输出通道 100% 纯净。
|
|
11
|
+
* 2. 将子进程标准输出/错误通过 DiagnosticForwarder 进行受控排空与诊断流限流转发。
|
|
12
|
+
* 3. 当子进程异常终止时,立即将当前活跃调用转换为结构化 HOST_PROCESS_EXITED 错误,防止调用方死锁。
|
|
13
|
+
*/
|
|
14
|
+
export declare class IpcActionDockTarget implements ActionDockTarget {
|
|
15
|
+
private child;
|
|
16
|
+
private forwarder;
|
|
17
|
+
private pendingCalls;
|
|
18
|
+
private isClosed;
|
|
19
|
+
private exitError?;
|
|
20
|
+
private readyPromise;
|
|
21
|
+
constructor(options: IpcTargetOptions);
|
|
22
|
+
/**
|
|
23
|
+
* 等待宿主子进程初始化就绪。
|
|
24
|
+
*/
|
|
25
|
+
waitReady(timeoutMs?: number): Promise<void>;
|
|
26
|
+
/**
|
|
27
|
+
* 获取底层子进程实例。
|
|
28
|
+
*/
|
|
29
|
+
get process(): ChildProcess;
|
|
30
|
+
private callRemote;
|
|
31
|
+
info(): Promise<TargetInfo>;
|
|
32
|
+
listPackages(): Promise<PackageInfo[]>;
|
|
33
|
+
listActions(options?: ListActionsOptions): Promise<ActionSummary[]>;
|
|
34
|
+
describeAction(ref: ActionRef | string): Promise<ActionSpec>;
|
|
35
|
+
listPlaybooks(options?: {
|
|
36
|
+
intent?: string;
|
|
37
|
+
package?: string;
|
|
38
|
+
}): Promise<PlaybookSummary[]>;
|
|
39
|
+
describePlaybook(id: string): Promise<PlaybookSpec>;
|
|
40
|
+
runAction(ref: ActionRef | string, input: JsonValue, options?: ExecuteOptions): Promise<ExecutionResult>;
|
|
41
|
+
startAction(ref: ActionRef | string, input: JsonValue, options?: ExecuteOptions): Promise<ExecutionTicket>;
|
|
42
|
+
getRun(runId: string): Promise<RunRecord | undefined>;
|
|
43
|
+
cancelRun(runId: string): Promise<CancelResult>;
|
|
44
|
+
listRuns(options?: any): Promise<RunRecord[]>;
|
|
45
|
+
events(_runId: string, _options?: any): AsyncIterable<ExecutionEvent>;
|
|
46
|
+
listConfig(packageId: string): Promise<ConfigValueView[]>;
|
|
47
|
+
getConfig(packageId: string, key: string): Promise<ConfigValueView>;
|
|
48
|
+
setConfig(packageId: string, key: string, value: JsonValue): Promise<void>;
|
|
49
|
+
deleteConfig(packageId: string, key: string): Promise<boolean>;
|
|
50
|
+
getState<T extends JsonValue = JsonValue>(packageId: string, actionId: string, key: string, options?: StateScopeOptions): Promise<T | undefined>;
|
|
51
|
+
setState<T extends JsonValue = JsonValue>(packageId: string, actionId: string, key: string, value: T, options?: StateScopeOptions): Promise<void>;
|
|
52
|
+
deleteState(packageId: string, actionId: string, key: string, options?: StateScopeOptions): Promise<boolean>;
|
|
53
|
+
listStateKeys(packageId: string, actionId?: string, options?: StateScopeOptions): Promise<string[]>;
|
|
54
|
+
clearState(packageId: string, actionId: string, options?: StateScopeOptions): Promise<number>;
|
|
55
|
+
close(): Promise<void>;
|
|
56
|
+
}
|