@actiondock/core 2.6.0 → 2.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +61 -68
- package/dist/catalog/action-catalog.d.ts +56 -0
- package/dist/catalog/action-catalog.js +202 -0
- package/dist/catalog/discovery.d.ts +60 -0
- package/dist/catalog/discovery.js +119 -0
- package/dist/catalog/graph.d.ts +190 -0
- package/dist/catalog/graph.js +589 -0
- package/dist/catalog/index.d.ts +5 -5
- package/dist/catalog/index.js +5 -5
- package/dist/catalog/resolve-action.d.ts +43 -0
- package/dist/catalog/resolve-action.js +119 -0
- package/dist/catalog/resolve-playbook.d.ts +26 -0
- package/dist/catalog/resolve-playbook.js +114 -0
- package/dist/doctor/checks/project.js +27 -8
- package/dist/doctor/checks/registry.js +2 -2
- package/dist/doctor/checks/runtime.js +34 -1
- package/dist/errors.d.ts +122 -10
- package/dist/errors.js +123 -10
- package/dist/execution/service.d.ts +18 -16
- package/dist/execution/service.js +183 -252
- package/dist/execution/types.d.ts +25 -69
- package/dist/execution/types.js +2 -1
- package/dist/filter/intent.d.ts +8 -9
- package/dist/filter/intent.js +49 -10
- package/dist/graph/index.d.ts +4 -0
- package/dist/graph/index.js +4 -0
- package/dist/host/host.d.ts +74 -32
- package/dist/host/host.js +585 -336
- package/dist/host/routing.d.ts +15 -48
- package/dist/host/routing.js +90 -153
- package/dist/host/types.d.ts +50 -17
- package/dist/index.d.ts +21 -22
- package/dist/index.js +19 -21
- package/dist/input/advice.d.ts +104 -0
- package/dist/input/advice.js +716 -0
- package/dist/input/describe.d.ts +106 -0
- package/dist/input/describe.js +176 -0
- package/dist/input/file-input.d.ts +54 -0
- package/dist/input/file-input.js +124 -0
- package/dist/input/flat-decode.d.ts +11 -0
- package/dist/input/flat-decode.js +13 -0
- package/dist/input/flat-errors.d.ts +71 -0
- package/dist/input/flat-errors.js +87 -0
- package/dist/input/flat-materializer.d.ts +29 -0
- package/dist/input/flat-materializer.js +177 -0
- package/dist/input/flat-parser.d.ts +50 -0
- package/dist/input/flat-parser.js +169 -0
- package/dist/input/flat-predicates.d.ts +34 -0
- package/dist/input/flat-predicates.js +50 -0
- package/dist/input/index.d.ts +14 -0
- package/dist/input/index.js +14 -0
- package/dist/input/input-resolver.d.ts +63 -0
- package/dist/input/input-resolver.js +254 -0
- package/dist/input/json-depth-scanner.d.ts +17 -0
- package/dist/input/json-depth-scanner.js +49 -0
- package/dist/input/metadata.d.ts +99 -0
- package/dist/input/metadata.js +99 -0
- package/dist/input/stdin-input.d.ts +26 -0
- package/dist/input/stdin-input.js +125 -0
- package/dist/input/utf8.d.ts +19 -0
- package/dist/input/utf8.js +36 -0
- package/dist/input/validation-mapper.d.ts +27 -0
- package/dist/input/validation-mapper.js +144 -0
- package/dist/invocation/index.d.ts +2 -0
- package/dist/invocation/index.js +2 -0
- package/dist/invocation/policy.d.ts +157 -0
- package/dist/invocation/policy.js +231 -0
- package/dist/invocation/types.d.ts +172 -0
- package/dist/invocation/types.js +97 -0
- package/dist/ipc/diagnostic.d.ts +0 -12
- package/dist/ipc/diagnostic.js +0 -21
- package/dist/ipc/host.d.ts +4 -4
- package/dist/ipc/host.js +44 -47
- package/dist/ipc/index.d.ts +1 -1
- package/dist/ipc/index.js +1 -1
- package/dist/ipc/service.d.ts +40 -0
- package/dist/ipc/service.js +349 -0
- package/dist/ipc/types.d.ts +21 -15
- package/dist/json/index.d.ts +1 -0
- package/dist/json/index.js +1 -0
- package/dist/json/value-validator.d.ts +88 -0
- package/dist/json/value-validator.js +330 -0
- package/dist/node/index.d.ts +1 -0
- package/dist/node/index.js +1 -0
- package/dist/node/module-loader.d.ts +63 -0
- package/dist/node/module-loader.js +112 -0
- package/dist/package/index.d.ts +23 -0
- package/dist/package/index.js +18 -0
- package/dist/{app/app.d.ts → package/runtime.d.ts} +41 -20
- package/dist/{app/app.js → package/runtime.js} +140 -95
- package/dist/{app → package}/static-index.js +58 -41
- package/dist/package/storage-view.d.ts +13 -0
- package/dist/package/storage-view.js +22 -0
- package/dist/{app → package}/types.d.ts +76 -57
- package/dist/package/types.js +22 -0
- package/dist/platform/index.d.ts +1 -1
- package/dist/platform/index.js +1 -1
- package/dist/platform/node.d.ts +48 -0
- package/dist/platform/node.js +96 -0
- package/dist/platform/types.d.ts +0 -9
- package/dist/process/control-arbiter.d.ts +2 -1
- package/dist/process/control-arbiter.js +1 -2
- package/dist/process/driver.d.ts +9 -8
- package/dist/process/driver.js +11 -22
- package/dist/process/index.d.ts +2 -0
- package/dist/process/index.js +2 -0
- package/dist/process/managed-record.d.ts +2 -2
- package/dist/process/process-driver.d.ts +109 -0
- package/dist/process/process-driver.js +650 -0
- package/dist/process/process-executor.d.ts +47 -0
- package/dist/process/process-executor.js +296 -0
- package/dist/process/process-manager.js +48 -26
- package/dist/process/run-executor.js +12 -12
- package/dist/profile/client-actions.js +2 -2
- package/dist/profile/client-health.js +3 -2
- package/dist/profile/client-query.js +5 -6
- package/dist/profile/client-transport.d.ts +19 -17
- package/dist/profile/client-transport.js +48 -80
- package/dist/profile/client.d.ts +2 -2
- package/dist/profile/client.js +1 -1
- package/dist/profile/index.d.ts +1 -0
- package/dist/profile/index.js +1 -0
- package/dist/profile/manager.d.ts +5 -0
- package/dist/profile/manager.js +41 -6
- package/dist/project/closure.js +2 -2
- package/dist/project/index.d.ts +8 -1
- package/dist/project/index.js +10 -1
- package/dist/project/init.js +2 -2
- package/dist/project/loader.d.ts +1 -1
- package/dist/project/loader.js +26 -29
- package/dist/project/transactions.js +5 -10
- package/dist/registry/index.d.ts +3 -1
- package/dist/registry/index.js +2 -1
- package/dist/registry/lock.d.ts +28 -7
- package/dist/registry/lock.js +136 -16
- package/dist/registry/registry.d.ts +1 -5
- package/dist/registry/registry.js +1 -53
- package/dist/registry/scan.d.ts +0 -15
- package/dist/registry/scan.js +0 -59
- package/dist/registry/store.d.ts +42 -0
- package/dist/registry/store.js +43 -0
- package/dist/registry/types.d.ts +0 -24
- package/dist/runtime/action-collection.d.ts +1 -1
- package/dist/runtime/action-registry.d.ts +0 -4
- package/dist/runtime/action-registry.js +0 -7
- package/dist/runtime/context.js +5 -11
- package/dist/runtime/events.js +3 -6
- package/dist/runtime/identity.d.ts +22 -0
- package/dist/runtime/identity.js +10 -0
- package/dist/runtime/index.d.ts +1 -2
- package/dist/runtime/index.js +1 -2
- package/dist/runtime/module-loader.d.ts +2 -34
- package/dist/runtime/module-loader.js +1 -16
- package/dist/runtime/process.d.ts +6 -24
- package/dist/runtime/process.js +1 -118
- package/dist/runtime/run-persistence.js +2 -5
- package/dist/runtime/runner.d.ts +33 -103
- package/dist/runtime/runner.js +142 -404
- package/dist/runtime/standalone.d.ts +37 -9
- package/dist/runtime/standalone.js +195 -136
- package/dist/schema/index.d.ts +1 -0
- package/dist/schema/index.js +1 -0
- package/dist/schema/validator.d.ts +10 -0
- package/dist/schema/validator.js +48 -54
- package/dist/server/body.d.ts +16 -8
- package/dist/server/body.js +33 -16
- package/dist/server/dispatcher.d.ts +6 -10
- package/dist/server/dispatcher.js +24 -32
- package/dist/server/http-server.d.ts +87 -0
- package/dist/server/http-server.js +304 -0
- package/dist/server/index.d.ts +11 -0
- package/dist/server/index.js +10 -0
- package/dist/server/mcp-endpoint.d.ts +61 -0
- package/dist/server/mcp-endpoint.js +118 -0
- package/dist/server/routes/actions.js +34 -28
- package/dist/server/routes/common.d.ts +10 -14
- package/dist/server/routes/common.js +32 -56
- package/dist/server/routes/config.js +54 -64
- package/dist/server/routes/doctor.d.ts +1 -1
- package/dist/server/routes/doctor.js +10 -18
- package/dist/server/routes/health.d.ts +1 -1
- package/dist/server/routes/health.js +2 -3
- package/dist/server/routes/info.d.ts +2 -2
- package/dist/server/routes/info.js +12 -13
- package/dist/server/routes/playbooks.js +16 -29
- package/dist/server/routes/runs.js +95 -117
- package/dist/server/routes/state.js +63 -62
- package/dist/server/server.d.ts +2 -2
- package/dist/server/server.js +43 -227
- package/dist/server/types.d.ts +8 -19
- package/dist/service/factory.d.ts +12 -0
- package/dist/service/factory.js +85 -0
- package/dist/{target → service}/index.d.ts +1 -1
- package/dist/{target → service}/index.js +1 -1
- package/dist/service/local.d.ts +27 -0
- package/dist/service/local.js +138 -0
- package/dist/{target → service}/remote-errors.d.ts +3 -6
- package/dist/service/remote-errors.js +38 -0
- package/dist/{target → service}/remote-polling.d.ts +2 -2
- package/dist/{target → service}/remote-polling.js +8 -8
- package/dist/service/remote.d.ts +34 -0
- package/dist/service/remote.js +634 -0
- package/dist/service/sse-stream.d.ts +24 -0
- package/dist/service/sse-stream.js +139 -0
- package/dist/service/types.d.ts +272 -0
- package/dist/service/types.js +32 -0
- package/dist/storage/data-dir-lock.js +10 -5
- package/dist/storage/driver.d.ts +2 -1
- package/dist/storage/driver.js +3 -52
- package/dist/storage/index.d.ts +1 -0
- package/dist/storage/index.js +1 -0
- package/dist/storage/lock-core.d.ts +2 -6
- package/dist/storage/lock-core.js +4 -17
- package/dist/storage/params.d.ts +2 -8
- package/dist/storage/params.js +2 -8
- package/dist/storage/sqlite-driver.d.ts +40 -0
- package/dist/storage/sqlite-driver.js +116 -0
- package/dist/storage/sqlite.js +21 -6
- package/dist/storage/types.d.ts +4 -4
- package/dist/storage/types.js +2 -2
- package/dist/utils/index.d.ts +53 -0
- package/dist/utils/index.js +99 -4
- package/dist/utils/process.d.ts +10 -0
- package/dist/utils/process.js +21 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +41 -3
- package/dist/app/index.d.ts +0 -2
- package/dist/app/index.js +0 -2
- package/dist/app/types.js +0 -1
- package/dist/catalog/action-index.d.ts +0 -9
- package/dist/catalog/action-index.js +0 -95
- package/dist/catalog/action-resolver.d.ts +0 -20
- package/dist/catalog/action-resolver.js +0 -95
- package/dist/catalog/location-registry.d.ts +0 -15
- package/dist/catalog/location-registry.js +0 -138
- package/dist/catalog/package-catalog.d.ts +0 -7
- package/dist/catalog/package-catalog.js +0 -77
- package/dist/catalog/types.d.ts +0 -68
- package/dist/catalog/types.js +0 -1
- package/dist/export/index.d.ts +0 -1
- package/dist/export/index.js +0 -1
- package/dist/export/templates.d.ts +0 -71
- package/dist/export/templates.js +0 -623
- package/dist/ipc/target.d.ts +0 -74
- package/dist/ipc/target.js +0 -365
- package/dist/platform/default.d.ts +0 -38
- package/dist/platform/default.js +0 -78
- package/dist/project/resolver.d.ts +0 -116
- package/dist/project/resolver.js +0 -376
- package/dist/registry/resolve.d.ts +0 -62
- package/dist/registry/resolve.js +0 -195
- package/dist/runtime/execution-manager.d.ts +0 -48
- package/dist/runtime/execution-manager.js +0 -66
- package/dist/runtime/package-runner-factory.d.ts +0 -82
- package/dist/runtime/package-runner-factory.js +0 -186
- package/dist/target/local.d.ts +0 -53
- package/dist/target/local.js +0 -349
- package/dist/target/remote-errors.js +0 -51
- package/dist/target/remote.d.ts +0 -86
- package/dist/target/remote.js +0 -818
- package/dist/target/target.d.ts +0 -6
- package/dist/target/target.js +0 -37
- package/dist/target/types.d.ts +0 -261
- package/dist/target/types.js +0 -35
- /package/dist/{app → package}/static-index.d.ts +0 -0
- /package/dist/{target → service}/sse-parser.d.ts +0 -0
- /package/dist/{target → service}/sse-parser.js +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type ActionDefinition } from "@actiondock/sdk";
|
|
2
|
-
import type { ActionSpec } from "../
|
|
2
|
+
import type { ActionSpec } from "../package/types.js";
|
|
3
3
|
import type { ConfigItemDefinition } from "../project/types.js";
|
|
4
|
-
import type {
|
|
4
|
+
import type { ActionDockService } from "../service/types.js";
|
|
5
5
|
/**
|
|
6
6
|
* 退出状态码常量。
|
|
7
7
|
*/
|
|
@@ -11,6 +11,13 @@ export declare const ExitCode: {
|
|
|
11
11
|
readonly INVALID_ARGUMENT: 2;
|
|
12
12
|
readonly SIGINT: 130;
|
|
13
13
|
};
|
|
14
|
+
/**
|
|
15
|
+
* 调用控制选项契约。
|
|
16
|
+
*/
|
|
17
|
+
export interface InvocationControl {
|
|
18
|
+
signal?: AbortSignal;
|
|
19
|
+
cancellationSource?: "external" | "sigint";
|
|
20
|
+
}
|
|
14
21
|
/**
|
|
15
22
|
* 独立二进制运行分发器配置选项。
|
|
16
23
|
*/
|
|
@@ -21,8 +28,8 @@ export interface StandaloneDispatcherOptions {
|
|
|
21
28
|
version: string;
|
|
22
29
|
/** 描述信息 */
|
|
23
30
|
description?: string;
|
|
24
|
-
/** 已构造的
|
|
25
|
-
|
|
31
|
+
/** 已构造的 ActionDockService 服务(若未传入则依据 actions/config 自动创建) */
|
|
32
|
+
service?: ActionDockService;
|
|
26
33
|
/** 声明的配置依赖定义(兼容选项) */
|
|
27
34
|
configDefs?: Record<string, ConfigItemDefinition>;
|
|
28
35
|
config?: Record<string, ConfigItemDefinition>;
|
|
@@ -49,7 +56,7 @@ export interface StandaloneDispatcherOptions {
|
|
|
49
56
|
*
|
|
50
57
|
* 职责:
|
|
51
58
|
* 1. 负责轻量参数解析、诊断输出渲染与统一退出码管理。
|
|
52
|
-
* 2. 统一面向
|
|
59
|
+
* 2. 统一面向 ActionDockService 服务调用能力。
|
|
53
60
|
* 3. 严格遵循 ActionDock 2.0 输出协议约定:结果数据专走 stdout,日志与错误专走 stderr。
|
|
54
61
|
* 4. 独立入口拒绝异步启动语义,显式拦截并返回 STANDALONE_ASYNC_UNSUPPORTED。
|
|
55
62
|
*/
|
|
@@ -58,23 +65,39 @@ export declare class StandaloneDispatcher {
|
|
|
58
65
|
constructor(options: StandaloneDispatcherOptions);
|
|
59
66
|
private writeOut;
|
|
60
67
|
private writeErr;
|
|
61
|
-
|
|
68
|
+
/**
|
|
69
|
+
* 统一错误输出辅助方法。
|
|
70
|
+
*
|
|
71
|
+
* JSON 模式向 stdout 输出两空格缩进的标准错误结构;
|
|
72
|
+
* 纯文本模式向 stderr 输出单行错误消息(默认携带 Error: 前缀)。
|
|
73
|
+
* 消息文本与退出码由调用方逐字给定,输出字节严格保持不变。
|
|
74
|
+
*
|
|
75
|
+
* @param isJson 是否处于 JSON 输出模式
|
|
76
|
+
* @param code 错误码
|
|
77
|
+
* @param message JSON 模式错误消息(兼作纯文本默认消息主体)
|
|
78
|
+
* @param exitCode 调用方应返回的退出状态码
|
|
79
|
+
* @param options 可选项:textMessage 覆盖纯文本消息全文;details 为 JSON 模式可选结构化详情
|
|
80
|
+
* @returns 透传 exitCode 供调用方直接返回
|
|
81
|
+
*/
|
|
82
|
+
private emitError;
|
|
83
|
+
private createLocalService;
|
|
62
84
|
/**
|
|
63
85
|
* 解析命令行参数并分发执行对应子命令。
|
|
64
86
|
*
|
|
65
87
|
* @param argv 命令行参数数组(如 process.argv.slice(2))
|
|
88
|
+
* @param control 可选的中断与取消控制契约
|
|
66
89
|
* @returns 退出状态码(0: 成功, 1: 失败, 2: 参数错误, 130: 中断)
|
|
67
90
|
*/
|
|
68
|
-
dispatch(argv: string[]): Promise<number>;
|
|
91
|
+
dispatch(argv: string[], control?: InvocationControl): Promise<number>;
|
|
69
92
|
private handleList;
|
|
70
93
|
private handleDescribe;
|
|
71
94
|
private handleRun;
|
|
72
95
|
private handleConfig;
|
|
73
96
|
private handleState;
|
|
74
97
|
/**
|
|
75
|
-
*
|
|
98
|
+
* 判定配置读取异常是否为服务能力缺失(键未配置语义)而非内部故障。
|
|
76
99
|
*/
|
|
77
|
-
private
|
|
100
|
+
private isServiceCapabilityError;
|
|
78
101
|
/**
|
|
79
102
|
* 解析携带命名空间前缀的状态键参数:委托 sdk 单一事实源 decodeStateKey。
|
|
80
103
|
*
|
|
@@ -97,3 +120,8 @@ export declare class StandaloneRuntime {
|
|
|
97
120
|
* 工厂函数:创建独立运行时实例。
|
|
98
121
|
*/
|
|
99
122
|
export declare function createStandaloneRuntime(options: StandaloneRuntimeOptions): StandaloneRuntime;
|
|
123
|
+
/**
|
|
124
|
+
* 独立二进制进程入口适配器。
|
|
125
|
+
* 仅在命令行可执行入口调用,负责全局 SIGINT 监听与退出状态码写入。
|
|
126
|
+
*/
|
|
127
|
+
export declare function runStandaloneProcess(argv: string[], options: StandaloneDispatcherOptions): Promise<void>;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { readFileSync } from "node:fs";
|
|
2
1
|
import { decodeStateKey } from "@actiondock/sdk";
|
|
3
2
|
import { filterWithFallbackInfo } from "../filter/index.js";
|
|
4
|
-
import {
|
|
3
|
+
import { createActionDock } from "../service/factory.js";
|
|
5
4
|
import { STANDALONE_ASYNC_UNSUPPORTED } from "../errors.js";
|
|
5
|
+
import { resolveActionInput, formatActionDetail, buildActionDescribePayload, mapInputValidationFailure, } from "../input/index.js";
|
|
6
|
+
import { validateActionInputValue } from "../json/value-validator.js";
|
|
6
7
|
import { normalizeActionCollection } from "./action-collection.js";
|
|
7
8
|
import { parseDuration } from "../utils/index.js";
|
|
8
9
|
/**
|
|
@@ -19,7 +20,7 @@ export const ExitCode = {
|
|
|
19
20
|
*
|
|
20
21
|
* 职责:
|
|
21
22
|
* 1. 负责轻量参数解析、诊断输出渲染与统一退出码管理。
|
|
22
|
-
* 2. 统一面向
|
|
23
|
+
* 2. 统一面向 ActionDockService 服务调用能力。
|
|
23
24
|
* 3. 严格遵循 ActionDock 2.0 输出协议约定:结果数据专走 stdout,日志与错误专走 stderr。
|
|
24
25
|
* 4. 独立入口拒绝异步启动语义,显式拦截并返回 STANDALONE_ASYNC_UNSUPPORTED。
|
|
25
26
|
*/
|
|
@@ -44,18 +45,49 @@ export class StandaloneDispatcher {
|
|
|
44
45
|
console.error(msg);
|
|
45
46
|
}
|
|
46
47
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
48
|
+
/**
|
|
49
|
+
* 统一错误输出辅助方法。
|
|
50
|
+
*
|
|
51
|
+
* JSON 模式向 stdout 输出两空格缩进的标准错误结构;
|
|
52
|
+
* 纯文本模式向 stderr 输出单行错误消息(默认携带 Error: 前缀)。
|
|
53
|
+
* 消息文本与退出码由调用方逐字给定,输出字节严格保持不变。
|
|
54
|
+
*
|
|
55
|
+
* @param isJson 是否处于 JSON 输出模式
|
|
56
|
+
* @param code 错误码
|
|
57
|
+
* @param message JSON 模式错误消息(兼作纯文本默认消息主体)
|
|
58
|
+
* @param exitCode 调用方应返回的退出状态码
|
|
59
|
+
* @param options 可选项:textMessage 覆盖纯文本消息全文;details 为 JSON 模式可选结构化详情
|
|
60
|
+
* @returns 透传 exitCode 供调用方直接返回
|
|
61
|
+
*/
|
|
62
|
+
emitError(isJson, code, message, exitCode, options) {
|
|
63
|
+
if (isJson) {
|
|
64
|
+
const details = options?.details;
|
|
65
|
+
this.writeOut(JSON.stringify({
|
|
66
|
+
ok: false,
|
|
67
|
+
error: {
|
|
68
|
+
code,
|
|
69
|
+
message,
|
|
70
|
+
...(details !== undefined ? { details } : {}),
|
|
71
|
+
},
|
|
72
|
+
}, null, 2));
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
this.writeErr(options?.textMessage ?? `Error: ${message}`);
|
|
76
|
+
}
|
|
77
|
+
return exitCode;
|
|
78
|
+
}
|
|
79
|
+
async createLocalService(dataDir, configOverrides = {}) {
|
|
80
|
+
if (this.options.service) {
|
|
81
|
+
return { service: this.options.service, ownsService: false };
|
|
50
82
|
}
|
|
51
|
-
if (this.options.inMemory && this.options.
|
|
52
|
-
return {
|
|
83
|
+
if (this.options.inMemory && this.options._sharedService) {
|
|
84
|
+
return { service: this.options._sharedService, ownsService: false };
|
|
53
85
|
}
|
|
54
86
|
// 归一化 Action 集合:单一入口统一三形态输入
|
|
55
87
|
const { actionsMap, actionSpecs } = normalizeActionCollection(this.options.actions);
|
|
56
88
|
// projectConfig.actions 要求 manifest 形态,字段语义兼容,此处显式收敛类型
|
|
57
89
|
const manifestActions = actionSpecs;
|
|
58
|
-
const
|
|
90
|
+
const runtimeOptions = {
|
|
59
91
|
projectConfig: {
|
|
60
92
|
id: this.options.packageId,
|
|
61
93
|
name: this.options.packageId,
|
|
@@ -70,38 +102,40 @@ export class StandaloneDispatcher {
|
|
|
70
102
|
customHome: this.options.customHome,
|
|
71
103
|
inMemory: this.options.inMemory,
|
|
72
104
|
};
|
|
73
|
-
const
|
|
74
|
-
|
|
75
|
-
appOptions,
|
|
105
|
+
const service = await createActionDock({
|
|
106
|
+
runtimeOptions,
|
|
76
107
|
});
|
|
77
108
|
if (this.options.inMemory) {
|
|
78
|
-
this.options.
|
|
79
|
-
return {
|
|
109
|
+
this.options._sharedService = service;
|
|
110
|
+
return { service, ownsService: false };
|
|
80
111
|
}
|
|
81
|
-
return {
|
|
112
|
+
return { service, ownsService: true };
|
|
82
113
|
}
|
|
83
114
|
/**
|
|
84
115
|
* 解析命令行参数并分发执行对应子命令。
|
|
85
116
|
*
|
|
86
117
|
* @param argv 命令行参数数组(如 process.argv.slice(2))
|
|
118
|
+
* @param control 可选的中断与取消控制契约
|
|
87
119
|
* @returns 退出状态码(0: 成功, 1: 失败, 2: 参数错误, 130: 中断)
|
|
88
120
|
*/
|
|
89
|
-
async dispatch(argv) {
|
|
90
|
-
const
|
|
121
|
+
async dispatch(argv, control) {
|
|
122
|
+
const separator = argv.indexOf("--");
|
|
123
|
+
const controlArgs = separator >= 0 ? argv.slice(0, separator) : argv;
|
|
124
|
+
const actionArgs = separator >= 0 ? argv.slice(separator + 1) : [];
|
|
91
125
|
let dataDir;
|
|
92
126
|
const configOverrides = {};
|
|
93
|
-
// 1. 提取全局参数(--data-dir, --config
|
|
127
|
+
// 1. 提取全局参数(--data-dir, --config)仅从 controlArgs 中解析
|
|
94
128
|
const filteredArgs = [];
|
|
95
|
-
for (let i = 0; i <
|
|
96
|
-
const arg =
|
|
97
|
-
if (arg === "--data-dir" && i + 1 <
|
|
98
|
-
dataDir =
|
|
129
|
+
for (let i = 0; i < controlArgs.length; i++) {
|
|
130
|
+
const arg = controlArgs[i];
|
|
131
|
+
if (arg === "--data-dir" && i + 1 < controlArgs.length) {
|
|
132
|
+
dataDir = controlArgs[++i];
|
|
99
133
|
}
|
|
100
134
|
else if (arg.startsWith("--data-dir=")) {
|
|
101
135
|
dataDir = arg.slice(11);
|
|
102
136
|
}
|
|
103
|
-
else if (arg === "--config" && i + 1 <
|
|
104
|
-
const pair =
|
|
137
|
+
else if (arg === "--config" && i + 1 < controlArgs.length) {
|
|
138
|
+
const pair = controlArgs[++i];
|
|
105
139
|
const [k, ...v] = pair.split("=");
|
|
106
140
|
if (k)
|
|
107
141
|
configOverrides[k] = v.join("=");
|
|
@@ -119,21 +153,10 @@ export class StandaloneDispatcher {
|
|
|
119
153
|
const command = filteredArgs[0] || "help";
|
|
120
154
|
const subArgs = filteredArgs.slice(1);
|
|
121
155
|
// 2. 独立入口拒绝异步启动语义
|
|
122
|
-
if (
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
ok: false,
|
|
127
|
-
error: {
|
|
128
|
-
code: STANDALONE_ASYNC_UNSUPPORTED,
|
|
129
|
-
message: "Async execution is not supported in standalone single-execution binaries. Use 'ad serve' or remote target.",
|
|
130
|
-
},
|
|
131
|
-
}, null, 2));
|
|
132
|
-
}
|
|
133
|
-
else {
|
|
134
|
-
this.writeErr(`Error [${STANDALONE_ASYNC_UNSUPPORTED}]: Async execution is not supported in standalone single-execution binaries.`);
|
|
135
|
-
}
|
|
136
|
-
return ExitCode.FAILURE;
|
|
156
|
+
if (controlArgs.includes("--async")) {
|
|
157
|
+
return this.emitError(controlArgs.includes("--json"), STANDALONE_ASYNC_UNSUPPORTED, "Async execution is not supported in standalone single-execution binaries. Use 'ad serve' or remote target.", ExitCode.FAILURE, {
|
|
158
|
+
textMessage: `Error [${STANDALONE_ASYNC_UNSUPPORTED}]: Async execution is not supported in standalone single-execution binaries.`,
|
|
159
|
+
});
|
|
137
160
|
}
|
|
138
161
|
// 3. 版本与帮助快速处理(无需初始化 Host / Storage)
|
|
139
162
|
if (command === "-v" || command === "-V" || command === "--version" || command === "version") {
|
|
@@ -144,56 +167,61 @@ export class StandaloneDispatcher {
|
|
|
144
167
|
this.printHelp();
|
|
145
168
|
return ExitCode.SUCCESS;
|
|
146
169
|
}
|
|
147
|
-
let
|
|
148
|
-
let
|
|
170
|
+
let service;
|
|
171
|
+
let ownsService = false;
|
|
149
172
|
try {
|
|
150
|
-
const
|
|
151
|
-
|
|
152
|
-
|
|
173
|
+
const serviceRes = await this.createLocalService(dataDir, configOverrides);
|
|
174
|
+
service = serviceRes.service;
|
|
175
|
+
ownsService = serviceRes.ownsService;
|
|
153
176
|
}
|
|
154
177
|
catch (err) {
|
|
155
|
-
this.writeErr(`Error initializing standalone
|
|
178
|
+
this.writeErr(`Error initializing standalone service: ${err?.message || err}`);
|
|
156
179
|
return ExitCode.FAILURE;
|
|
157
180
|
}
|
|
158
|
-
const controller = new AbortController();
|
|
159
|
-
const sigintHandler = () => {
|
|
160
|
-
controller.abort(new Error("Interrupted by SIGINT"));
|
|
161
|
-
};
|
|
162
|
-
process.once("SIGINT", sigintHandler);
|
|
163
181
|
try {
|
|
182
|
+
let code;
|
|
164
183
|
switch (command) {
|
|
165
184
|
case "list":
|
|
166
|
-
|
|
185
|
+
code = await this.handleList(service, subArgs);
|
|
186
|
+
break;
|
|
167
187
|
case "describe":
|
|
168
188
|
case "show":
|
|
169
|
-
|
|
189
|
+
code = await this.handleDescribe(service, subArgs);
|
|
190
|
+
break;
|
|
170
191
|
case "run":
|
|
171
|
-
|
|
192
|
+
code = await this.handleRun(service, subArgs, actionArgs, control?.signal);
|
|
193
|
+
break;
|
|
172
194
|
case "config":
|
|
173
|
-
|
|
195
|
+
code = await this.handleConfig(service, subArgs);
|
|
196
|
+
break;
|
|
174
197
|
case "state":
|
|
175
|
-
|
|
198
|
+
code = await this.handleState(service, subArgs);
|
|
199
|
+
break;
|
|
176
200
|
default:
|
|
177
201
|
this.writeErr(`Unknown command: '${command}'`);
|
|
178
202
|
this.printHelp();
|
|
179
203
|
return ExitCode.INVALID_ARGUMENT;
|
|
180
204
|
}
|
|
205
|
+
if (control?.cancellationSource === "sigint" && control?.signal?.aborted) {
|
|
206
|
+
return ExitCode.SIGINT;
|
|
207
|
+
}
|
|
208
|
+
return code;
|
|
181
209
|
}
|
|
182
210
|
catch (err) {
|
|
183
|
-
if (
|
|
211
|
+
if (control?.cancellationSource === "sigint" &&
|
|
212
|
+
(control?.signal?.aborted || err?.name === "AbortError" || err?.code === "SIGINT_INTERRUPTED")) {
|
|
184
213
|
return ExitCode.SIGINT;
|
|
185
214
|
}
|
|
186
215
|
this.writeErr(`Error: ${err?.message || err}`);
|
|
187
216
|
return ExitCode.FAILURE;
|
|
188
217
|
}
|
|
189
218
|
finally {
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
await target.close();
|
|
219
|
+
if (ownsService) {
|
|
220
|
+
await service.close();
|
|
193
221
|
}
|
|
194
222
|
}
|
|
195
223
|
}
|
|
196
|
-
async handleList(
|
|
224
|
+
async handleList(service, subArgs) {
|
|
197
225
|
const isJson = subArgs.includes("--json");
|
|
198
226
|
const noFallback = subArgs.includes("--no-fallback");
|
|
199
227
|
let intent;
|
|
@@ -215,7 +243,7 @@ export class StandaloneDispatcher {
|
|
|
215
243
|
}
|
|
216
244
|
}
|
|
217
245
|
const effectiveIntent = intent || (positionalPatterns.length > 0 ? positionalPatterns.join("|") : undefined);
|
|
218
|
-
const actions = await
|
|
246
|
+
const actions = await service.discovery.listActions();
|
|
219
247
|
const list = actions.map((a) => ({
|
|
220
248
|
id: a.id,
|
|
221
249
|
description: a.description || "",
|
|
@@ -233,94 +261,89 @@ export class StandaloneDispatcher {
|
|
|
233
261
|
}
|
|
234
262
|
return ExitCode.SUCCESS;
|
|
235
263
|
}
|
|
236
|
-
async handleDescribe(
|
|
264
|
+
async handleDescribe(service, subArgs) {
|
|
237
265
|
const id = subArgs.find((a) => !a.startsWith("-"));
|
|
238
266
|
const isJson = subArgs.includes("--json");
|
|
239
267
|
if (!id) {
|
|
240
|
-
this.
|
|
241
|
-
return ExitCode.INVALID_ARGUMENT;
|
|
268
|
+
return this.emitError(isJson, "INVALID_ARGUMENT", "Action ID is required for describe", ExitCode.INVALID_ARGUMENT);
|
|
242
269
|
}
|
|
243
270
|
let action;
|
|
244
271
|
try {
|
|
245
|
-
action = await
|
|
272
|
+
action = await service.discovery.describeAction(id);
|
|
246
273
|
}
|
|
247
274
|
catch {
|
|
248
|
-
this.
|
|
249
|
-
return ExitCode.INVALID_ARGUMENT;
|
|
275
|
+
return this.emitError(isJson, "INVALID_ARGUMENT", `Action '${id}' not found`, ExitCode.INVALID_ARGUMENT);
|
|
250
276
|
}
|
|
251
|
-
const
|
|
252
|
-
id: action.id,
|
|
277
|
+
const payload = buildActionDescribePayload(action, {
|
|
253
278
|
packageId: this.options.packageId,
|
|
254
|
-
|
|
255
|
-
inputSchema: action.inputSchema,
|
|
256
|
-
outputSchema: action.outputSchema,
|
|
257
|
-
};
|
|
279
|
+
});
|
|
258
280
|
if (isJson) {
|
|
259
|
-
this.writeOut(JSON.stringify(
|
|
281
|
+
this.writeOut(JSON.stringify(payload, null, 2));
|
|
260
282
|
}
|
|
261
283
|
else {
|
|
262
|
-
|
|
263
|
-
if (action.description)
|
|
264
|
-
text += `Description: ${action.description}\n`;
|
|
265
|
-
if (action.inputSchema) {
|
|
266
|
-
text += `\nInput Schema:\n${JSON.stringify(action.inputSchema, null, 2)}\n`;
|
|
267
|
-
}
|
|
268
|
-
if (action.outputSchema) {
|
|
269
|
-
text += `\nOutput Schema:\n${JSON.stringify(action.outputSchema, null, 2)}\n`;
|
|
270
|
-
}
|
|
271
|
-
this.writeOut(text.trimEnd());
|
|
284
|
+
this.writeOut(formatActionDetail(payload));
|
|
272
285
|
}
|
|
273
286
|
return ExitCode.SUCCESS;
|
|
274
287
|
}
|
|
275
|
-
async handleRun(
|
|
288
|
+
async handleRun(service, subArgs, actionArgs, signal) {
|
|
289
|
+
const isJson = subArgs.includes("--json");
|
|
276
290
|
const id = subArgs.find((a) => !a.startsWith("-"));
|
|
277
291
|
if (!id) {
|
|
278
|
-
this.
|
|
279
|
-
return ExitCode.INVALID_ARGUMENT;
|
|
292
|
+
return this.emitError(isJson, "INVALID_ARGUMENT", "Error: Action ID is required for run", ExitCode.INVALID_ARGUMENT, { textMessage: "Error: Action ID is required for run" });
|
|
280
293
|
}
|
|
281
|
-
let
|
|
294
|
+
let inputStr;
|
|
295
|
+
let inputFile;
|
|
282
296
|
let timeoutMs;
|
|
283
|
-
let isJson = false;
|
|
284
297
|
for (let i = 0; i < subArgs.length; i++) {
|
|
285
298
|
const arg = subArgs[i];
|
|
286
|
-
if (arg === "--
|
|
287
|
-
isJson = true;
|
|
288
|
-
}
|
|
289
|
-
else if (arg === "--timeout" && i + 1 < subArgs.length) {
|
|
290
|
-
timeoutMs = parseDuration(subArgs[++i]);
|
|
291
|
-
}
|
|
292
|
-
else if (arg.startsWith("--timeout=")) {
|
|
293
|
-
timeoutMs = parseDuration(arg.slice(10));
|
|
294
|
-
}
|
|
295
|
-
else if (arg === "--input" && i + 1 < subArgs.length) {
|
|
299
|
+
if (arg === "--timeout" && i + 1 < subArgs.length) {
|
|
296
300
|
try {
|
|
297
|
-
|
|
301
|
+
timeoutMs = parseDuration(subArgs[++i]);
|
|
298
302
|
}
|
|
299
|
-
catch (
|
|
300
|
-
this.
|
|
301
|
-
return ExitCode.INVALID_ARGUMENT;
|
|
303
|
+
catch (err) {
|
|
304
|
+
return this.emitError(isJson, "INVALID_ARGUMENT", `Invalid timeout format: ${err?.message || err}`, ExitCode.INVALID_ARGUMENT);
|
|
302
305
|
}
|
|
303
306
|
}
|
|
304
|
-
else if (arg.startsWith("--
|
|
307
|
+
else if (arg.startsWith("--timeout=")) {
|
|
305
308
|
try {
|
|
306
|
-
|
|
309
|
+
timeoutMs = parseDuration(arg.slice(10));
|
|
307
310
|
}
|
|
308
|
-
catch (
|
|
309
|
-
this.
|
|
310
|
-
return ExitCode.INVALID_ARGUMENT;
|
|
311
|
+
catch (err) {
|
|
312
|
+
return this.emitError(isJson, "INVALID_ARGUMENT", `Invalid timeout format: ${err?.message || err}`, ExitCode.INVALID_ARGUMENT);
|
|
311
313
|
}
|
|
312
314
|
}
|
|
315
|
+
else if (arg === "--input" && i + 1 < subArgs.length) {
|
|
316
|
+
inputStr = subArgs[++i];
|
|
317
|
+
}
|
|
318
|
+
else if (arg.startsWith("--input=")) {
|
|
319
|
+
inputStr = arg.slice(8);
|
|
320
|
+
}
|
|
313
321
|
else if (arg === "--input-file" && i + 1 < subArgs.length) {
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
322
|
+
inputFile = subArgs[++i];
|
|
323
|
+
}
|
|
324
|
+
else if (arg.startsWith("--input-file=")) {
|
|
325
|
+
inputFile = arg.slice(13);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
let input;
|
|
329
|
+
try {
|
|
330
|
+
input = await resolveActionInput({
|
|
331
|
+
input: inputStr,
|
|
332
|
+
inputFile,
|
|
333
|
+
flatArgs: actionArgs.length > 0 ? actionArgs : undefined,
|
|
334
|
+
stdin: process.stdin,
|
|
335
|
+
});
|
|
336
|
+
const check = validateActionInputValue(input);
|
|
337
|
+
if (!check.valid) {
|
|
338
|
+
throw mapInputValidationFailure("cli-pre-target", check);
|
|
321
339
|
}
|
|
322
340
|
}
|
|
323
|
-
|
|
341
|
+
catch (err) {
|
|
342
|
+
return this.emitError(isJson, err?.code || "INVALID_ARGUMENT", err?.message || String(err), ExitCode.INVALID_ARGUMENT, {
|
|
343
|
+
details: err?.details,
|
|
344
|
+
});
|
|
345
|
+
}
|
|
346
|
+
const result = await service.execution.run(id, input, {
|
|
324
347
|
signal,
|
|
325
348
|
timeoutMs,
|
|
326
349
|
});
|
|
@@ -409,10 +432,14 @@ export class StandaloneDispatcher {
|
|
|
409
432
|
}
|
|
410
433
|
return result.ok ? ExitCode.SUCCESS : ExitCode.FAILURE;
|
|
411
434
|
}
|
|
412
|
-
async handleConfig(
|
|
435
|
+
async handleConfig(service, subArgs) {
|
|
413
436
|
const sub = subArgs[0] || "list";
|
|
437
|
+
if (!service.management) {
|
|
438
|
+
this.writeErr("Error: management port is not enabled on this service");
|
|
439
|
+
return ExitCode.FAILURE;
|
|
440
|
+
}
|
|
414
441
|
if (sub === "list") {
|
|
415
|
-
const views = await
|
|
442
|
+
const views = await service.management.config.list(this.options.packageId);
|
|
416
443
|
const dict = {};
|
|
417
444
|
for (const v of views) {
|
|
418
445
|
if (v.configured && v.value !== undefined) {
|
|
@@ -429,13 +456,13 @@ export class StandaloneDispatcher {
|
|
|
429
456
|
return ExitCode.INVALID_ARGUMENT;
|
|
430
457
|
}
|
|
431
458
|
try {
|
|
432
|
-
const item = await
|
|
459
|
+
const item = await service.management.config.get(this.options.packageId, key);
|
|
433
460
|
this.writeOut(item.configured ? JSON.stringify(item.value) : "undefined");
|
|
434
461
|
return ExitCode.SUCCESS;
|
|
435
462
|
}
|
|
436
463
|
catch (err) {
|
|
437
|
-
//
|
|
438
|
-
if (this.
|
|
464
|
+
// 服务能力缺失(如远端未开启管理接口)视为键未配置,输出 undefined
|
|
465
|
+
if (this.isServiceCapabilityError(err)) {
|
|
439
466
|
this.writeOut("undefined");
|
|
440
467
|
return ExitCode.SUCCESS;
|
|
441
468
|
}
|
|
@@ -458,7 +485,7 @@ export class StandaloneDispatcher {
|
|
|
458
485
|
catch {
|
|
459
486
|
parsed = rawVal;
|
|
460
487
|
}
|
|
461
|
-
await
|
|
488
|
+
await service.management.config.set(this.options.packageId, key, parsed);
|
|
462
489
|
this.writeOut(`Config '${key}' updated`);
|
|
463
490
|
return ExitCode.SUCCESS;
|
|
464
491
|
}
|
|
@@ -468,18 +495,22 @@ export class StandaloneDispatcher {
|
|
|
468
495
|
this.writeErr("Error: config key required");
|
|
469
496
|
return ExitCode.INVALID_ARGUMENT;
|
|
470
497
|
}
|
|
471
|
-
await
|
|
498
|
+
await service.management.config.delete(this.options.packageId, key);
|
|
472
499
|
this.writeOut(`Config '${key}' deleted`);
|
|
473
500
|
return ExitCode.SUCCESS;
|
|
474
501
|
}
|
|
475
502
|
this.writeErr(`Unknown config subcommand: '${sub}'`);
|
|
476
503
|
return ExitCode.INVALID_ARGUMENT;
|
|
477
504
|
}
|
|
478
|
-
async handleState(
|
|
505
|
+
async handleState(service, subArgs) {
|
|
479
506
|
const sub = subArgs[0] || "list";
|
|
480
507
|
let namespace;
|
|
481
508
|
let isAll = false;
|
|
482
509
|
let isJson = false;
|
|
510
|
+
if (!service.management) {
|
|
511
|
+
this.writeErr("Error: management port is not enabled on this service");
|
|
512
|
+
return ExitCode.FAILURE;
|
|
513
|
+
}
|
|
483
514
|
for (let i = 1; i < subArgs.length; i++) {
|
|
484
515
|
if ((subArgs[i] === "-n" || subArgs[i] === "--namespace") && i + 1 < subArgs.length) {
|
|
485
516
|
namespace = subArgs[++i];
|
|
@@ -496,7 +527,7 @@ export class StandaloneDispatcher {
|
|
|
496
527
|
}
|
|
497
528
|
if (sub === "list") {
|
|
498
529
|
const prefix = subArgs[1] && !subArgs[1].startsWith("-") ? subArgs[1] : "";
|
|
499
|
-
const keys = await
|
|
530
|
+
const keys = await service.management.state.list(this.options.packageId, "", {
|
|
500
531
|
namespace,
|
|
501
532
|
prefix: prefix || undefined,
|
|
502
533
|
all: isAll,
|
|
@@ -517,7 +548,7 @@ export class StandaloneDispatcher {
|
|
|
517
548
|
ns = decoded.namespace || undefined;
|
|
518
549
|
actualKey = decoded.key;
|
|
519
550
|
}
|
|
520
|
-
const val = await
|
|
551
|
+
const val = await service.management.state.get(this.options.packageId, "", actualKey, { namespace: ns });
|
|
521
552
|
if (isJson) {
|
|
522
553
|
this.writeOut(JSON.stringify({ key, value: val }, null, 2));
|
|
523
554
|
}
|
|
@@ -556,7 +587,7 @@ export class StandaloneDispatcher {
|
|
|
556
587
|
ttl = parseInt(subArgs[i].slice(6), 10);
|
|
557
588
|
}
|
|
558
589
|
}
|
|
559
|
-
await
|
|
590
|
+
await service.management.state.set(this.options.packageId, "", actualKey, parsed, { namespace: ns, ttl });
|
|
560
591
|
const displayKey = ns ? `${ns}:${actualKey}` : actualKey;
|
|
561
592
|
this.writeOut(`State '${displayKey}' updated`);
|
|
562
593
|
return ExitCode.SUCCESS;
|
|
@@ -567,7 +598,7 @@ export class StandaloneDispatcher {
|
|
|
567
598
|
this.writeErr("Error: state key required");
|
|
568
599
|
return ExitCode.INVALID_ARGUMENT;
|
|
569
600
|
}
|
|
570
|
-
const deleted = await
|
|
601
|
+
const deleted = await service.management.state.delete(this.options.packageId, "", key, { namespace });
|
|
571
602
|
if (deleted) {
|
|
572
603
|
this.writeOut(`State '${key}' deleted`);
|
|
573
604
|
return ExitCode.SUCCESS;
|
|
@@ -577,7 +608,7 @@ export class StandaloneDispatcher {
|
|
|
577
608
|
}
|
|
578
609
|
if (sub === "clear" || sub === "clean") {
|
|
579
610
|
const prefix = subArgs[1] && !subArgs[1].startsWith("-") ? subArgs[1] : "";
|
|
580
|
-
const count = await
|
|
611
|
+
const count = await service.management.state.clear(this.options.packageId, "", {
|
|
581
612
|
namespace,
|
|
582
613
|
all: isAll,
|
|
583
614
|
prefix: prefix || undefined,
|
|
@@ -589,15 +620,12 @@ export class StandaloneDispatcher {
|
|
|
589
620
|
return ExitCode.INVALID_ARGUMENT;
|
|
590
621
|
}
|
|
591
622
|
/**
|
|
592
|
-
*
|
|
623
|
+
* 判定配置读取异常是否为服务能力缺失(键未配置语义)而非内部故障。
|
|
593
624
|
*/
|
|
594
|
-
|
|
625
|
+
isServiceCapabilityError(err) {
|
|
595
626
|
const code = String(err?.code || "");
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
code === "CAPABILITY_UNAVAILABLE" ||
|
|
599
|
-
msg.includes("TARGET_CAPABILITY_UNAVAILABLE") ||
|
|
600
|
-
msg.includes("Management APIs are not enabled"));
|
|
627
|
+
return (code === "CAPABILITY_UNAVAILABLE" ||
|
|
628
|
+
code === "TARGET_CAPABILITY_UNAVAILABLE");
|
|
601
629
|
}
|
|
602
630
|
/**
|
|
603
631
|
* 解析携带命名空间前缀的状态键参数:委托 sdk 单一事实源 decodeStateKey。
|
|
@@ -646,3 +674,34 @@ export class StandaloneRuntime {
|
|
|
646
674
|
export function createStandaloneRuntime(options) {
|
|
647
675
|
return new StandaloneRuntime(options);
|
|
648
676
|
}
|
|
677
|
+
/**
|
|
678
|
+
* 独立二进制进程入口适配器。
|
|
679
|
+
* 仅在命令行可执行入口调用,负责全局 SIGINT 监听与退出状态码写入。
|
|
680
|
+
*/
|
|
681
|
+
export async function runStandaloneProcess(argv, options) {
|
|
682
|
+
const controller = new AbortController();
|
|
683
|
+
const control = {
|
|
684
|
+
signal: controller.signal,
|
|
685
|
+
};
|
|
686
|
+
let sigintCount = 0;
|
|
687
|
+
const sigintHandler = () => {
|
|
688
|
+
sigintCount++;
|
|
689
|
+
if (sigintCount === 1) {
|
|
690
|
+
control.cancellationSource = "sigint";
|
|
691
|
+
controller.abort(new Error("Interrupted by SIGINT"));
|
|
692
|
+
}
|
|
693
|
+
else {
|
|
694
|
+
process.exitCode = 130;
|
|
695
|
+
process.exit(130);
|
|
696
|
+
}
|
|
697
|
+
};
|
|
698
|
+
process.on("SIGINT", sigintHandler);
|
|
699
|
+
try {
|
|
700
|
+
const dispatcher = new StandaloneDispatcher(options);
|
|
701
|
+
const exitCode = await dispatcher.dispatch(argv, control);
|
|
702
|
+
process.exitCode = exitCode;
|
|
703
|
+
}
|
|
704
|
+
finally {
|
|
705
|
+
process.removeListener("SIGINT", sigintHandler);
|
|
706
|
+
}
|
|
707
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./validator.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./validator.js";
|