@actiondock/cli 2.5.1 → 2.7.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 +60 -5
- package/bin/ad.js +4 -4
- package/dist/commands/action/create.js +7 -22
- package/dist/commands/add.js +5 -5
- package/dist/commands/build.js +4 -5
- package/dist/commands/config/delete.js +2 -2
- package/dist/commands/config/env.js +6 -15
- package/dist/commands/config/get.js +8 -39
- package/dist/commands/config/list.js +8 -55
- package/dist/commands/config/schema.js +4 -6
- package/dist/commands/config/set.js +2 -2
- package/dist/commands/describe.js +8 -22
- package/dist/commands/doctor.js +3 -10
- package/dist/commands/export.js +4 -7
- package/dist/commands/generate.js +2 -4
- package/dist/commands/index.js +2 -5
- package/dist/commands/info.js +7 -15
- package/dist/commands/list.js +3 -5
- package/dist/commands/mcp.js +10 -3
- package/dist/commands/pack.js +4 -5
- package/dist/commands/playbook.js +14 -36
- package/dist/commands/profile.js +4 -11
- package/dist/commands/remove.js +13 -9
- package/dist/commands/run.d.ts +10 -1
- package/dist/commands/run.js +161 -52
- package/dist/commands/runs.js +10 -25
- package/dist/commands/serve.js +9 -1
- package/dist/commands/state-list.js +2 -5
- package/dist/commands/state.js +29 -16
- package/dist/commands/test.js +6 -2
- package/dist/commands/validate.js +3 -5
- package/dist/errors.d.ts +14 -1
- package/dist/errors.js +53 -3
- package/dist/index.d.ts +8 -1
- package/dist/index.js +61 -10
- package/dist/renderer.d.ts +3 -4
- package/dist/renderer.js +7 -34
- package/dist/services/config-merge.d.ts +41 -0
- package/dist/services/config-merge.js +93 -0
- package/dist/services/index.d.ts +1 -0
- package/dist/services/index.js +1 -0
- package/dist/standalone/index.d.ts +8 -2
- package/dist/standalone/index.js +32 -2
- package/dist/types.d.ts +6 -3
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.js +1 -0
- package/dist/utils/input.d.ts +1 -0
- package/dist/utils/input.js +1 -0
- package/dist/utils/spawn.d.ts +13 -0
- package/dist/utils/spawn.js +31 -0
- package/dist/utils/target.d.ts +21 -0
- package/dist/utils/target.js +29 -14
- package/dist/utils/utils.d.ts +2 -3
- package/dist/utils/utils.js +6 -6
- package/package.json +6 -6
package/dist/utils/spawn.js
CHANGED
|
@@ -1,9 +1,40 @@
|
|
|
1
1
|
import { spawn } from "node:child_process";
|
|
2
|
+
import { ArgumentError } from "../errors.js";
|
|
3
|
+
/**
|
|
4
|
+
* npm/bun 包说明符白名单字符集。
|
|
5
|
+
*
|
|
6
|
+
* 覆盖 npm 依赖说明符语法所需的安全字符:
|
|
7
|
+
* - 字母数字与 `.`(名称与版本组成)
|
|
8
|
+
* - `@`(scope 前缀与版本定界符)、`/`(scope 分隔符)
|
|
9
|
+
* - `:`(git 协议与 tag 前缀)、`-` 与 `_`(名称连字符与版本预发布段)
|
|
10
|
+
* - `+`(semver build 元数据)
|
|
11
|
+
*
|
|
12
|
+
* 显式拒绝全部 shell 元字符(空格、引号、`$`、反引号、`&`、`|`、`<`、`>`、`(`、`)` 等),
|
|
13
|
+
* 从源头消除 win32 shell 拼接模式下的命令注入面。
|
|
14
|
+
*/
|
|
15
|
+
const PACKAGE_SPEC_PATTERN = /^[a-zA-Z0-9@/:\-_.+]+$/;
|
|
16
|
+
/**
|
|
17
|
+
* 校验包管理器依赖说明符仅包含白名单字符。
|
|
18
|
+
* 非法字符直接抛出参数错误,不进入子进程拼接链路。
|
|
19
|
+
*
|
|
20
|
+
* @param spec 待校验的包说明符(如 `@scope/pkg@^1.2.3`)
|
|
21
|
+
*/
|
|
22
|
+
export function assertSafePackageSpec(spec) {
|
|
23
|
+
if (!PACKAGE_SPEC_PATTERN.test(spec)) {
|
|
24
|
+
throw new ArgumentError(`Invalid package specifier '${spec}': only letters, digits, '@', '/', ':', '-', '_', '.', '+' are allowed`);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
2
27
|
/**
|
|
3
28
|
* 异步执行子进程(Promise 化 spawn),保留 win32 shell 处理与退出码透传。
|
|
4
29
|
*
|
|
5
30
|
* 与 spawnSync 语义对齐:stdio 默认 pipe,进程结束(而非继承输出)后返回聚合结果。
|
|
6
31
|
*
|
|
32
|
+
* win32 shell 取舍说明:npm 在 Windows 上是 `.cmd` 批处理脚本,Node 20.12+
|
|
33
|
+
* 针对 CVE-2024-27980 的缓解措施使 `shell:false` 直接 spawn `.cmd` 抛出 EINVAL,
|
|
34
|
+
* 因此 win32 保留 shell 拼接模式;命令注入面由调用方的
|
|
35
|
+
* assertSafePackageSpec 白名单前置校验关闭(包说明符仅允许
|
|
36
|
+
* 字母数字与 `@/:/-_/.+`,全部 shell 元字符被拒绝)。
|
|
37
|
+
*
|
|
7
38
|
* @param command 可执行文件名
|
|
8
39
|
* @param args 参数列表
|
|
9
40
|
* @param options 附加选项(cwd 与 shell 策略)
|
package/dist/utils/target.d.ts
CHANGED
|
@@ -29,12 +29,27 @@ export interface TargetResolutionOptions {
|
|
|
29
29
|
/** 是否允许向非回环地址发送明文 HTTP 请求(对应 --allow-insecure-http) */
|
|
30
30
|
allowInsecureHttp?: boolean;
|
|
31
31
|
}
|
|
32
|
+
/**
|
|
33
|
+
* 目标拓扑解析单一入口:从命令选项视图解析远端/本地目标拓扑信息。
|
|
34
|
+
*
|
|
35
|
+
* 收拢全部解析字段(profile/server/token/insecure/allowInsecureHttp),
|
|
36
|
+
* 消除命令间逐字段内联复制导致的漂移(如漏传 allowInsecureHttp)。
|
|
37
|
+
*
|
|
38
|
+
* @param options 命令选项视图(支持直接传入 Commander 解析后的 options 对象)
|
|
39
|
+
* @param context CLI 上下文
|
|
40
|
+
* @returns 解析后的目标拓扑信息(仅信息解析,不创建 Target 实例)
|
|
41
|
+
*/
|
|
42
|
+
export declare function resolveTargetFromOptions(options: TargetResolutionOptions, context?: CliContext): ResolvedTarget;
|
|
32
43
|
/**
|
|
33
44
|
* 高阶目标执行辅助:统一封装「目标解析 → Target 创建 → 业务回调 → try/finally close」样板。
|
|
34
45
|
*
|
|
35
46
|
* 回调获得创建好的 target 与解析后的目标拓扑信息;无论回调成功或抛出,
|
|
36
47
|
* 都保证 target 资源被正确释放,业务异常原样透传。
|
|
37
48
|
*
|
|
49
|
+
* 默认旁观打开:内部创建的本地 Host 以非收割模式打开存储(不置 recoverOrphans),
|
|
50
|
+
* 供 ad state / ad runs / ad config 等查询命令与运行中的 serve 进程并发访问同一库;
|
|
51
|
+
* 需要持有者语义的执行命令通过 localOptions.ownDataDir 显式声明。
|
|
52
|
+
*
|
|
38
53
|
* @param options 命令选项视图(profile/server/token/package/dataDir/insecure/allowInsecureHttp)
|
|
39
54
|
* @param context CLI 上下文
|
|
40
55
|
* @param fn 业务回调(target 为已创建的门面实例,resolved 为拓扑解析结果)
|
|
@@ -45,6 +60,12 @@ export declare function withTarget(options: TargetResolutionOptions, context: Cl
|
|
|
45
60
|
localRoot?: string | (() => string | undefined);
|
|
46
61
|
/** 是否扫描全局链接包(对应 scanLinkedPackages) */
|
|
47
62
|
scanLinkedPackages?: boolean;
|
|
63
|
+
/**
|
|
64
|
+
* 是否以数据目录持有者身份打开本地 Host:true 时 App 存储打开阶段收割遗留孤儿运行。
|
|
65
|
+
* 执行类命令(ad run)应置 true;查询类命令(state/runs/config/list/describe)
|
|
66
|
+
* 保持缺省 false,避免误收割并发 serve 进程的在途运行记录。
|
|
67
|
+
*/
|
|
68
|
+
ownDataDir?: boolean;
|
|
48
69
|
}): Promise<void>;
|
|
49
70
|
/**
|
|
50
71
|
* 仅远端模式目标执行辅助:创建远端 Target 并保证资源释放。
|
package/dist/utils/target.js
CHANGED
|
@@ -15,31 +15,51 @@ export function applyTargetOptions(command) {
|
|
|
15
15
|
.option("-k, --insecure", "Allow insecure server connections (skip TLS certificate validation)")
|
|
16
16
|
.option("--allow-insecure-http", "Allow sending auth token over unencrypted HTTP to non-loopback hosts");
|
|
17
17
|
}
|
|
18
|
+
/**
|
|
19
|
+
* 目标拓扑解析单一入口:从命令选项视图解析远端/本地目标拓扑信息。
|
|
20
|
+
*
|
|
21
|
+
* 收拢全部解析字段(profile/server/token/insecure/allowInsecureHttp),
|
|
22
|
+
* 消除命令间逐字段内联复制导致的漂移(如漏传 allowInsecureHttp)。
|
|
23
|
+
*
|
|
24
|
+
* @param options 命令选项视图(支持直接传入 Commander 解析后的 options 对象)
|
|
25
|
+
* @param context CLI 上下文
|
|
26
|
+
* @returns 解析后的目标拓扑信息(仅信息解析,不创建 Target 实例)
|
|
27
|
+
*/
|
|
28
|
+
export function resolveTargetFromOptions(options, context) {
|
|
29
|
+
return resolveTarget({
|
|
30
|
+
profile: options.profile,
|
|
31
|
+
server: options.server,
|
|
32
|
+
token: options.token,
|
|
33
|
+
insecure: options.insecure,
|
|
34
|
+
allowInsecureHttp: options.allowInsecureHttp,
|
|
35
|
+
}, context?.customHome);
|
|
36
|
+
}
|
|
18
37
|
/**
|
|
19
38
|
* 高阶目标执行辅助:统一封装「目标解析 → Target 创建 → 业务回调 → try/finally close」样板。
|
|
20
39
|
*
|
|
21
40
|
* 回调获得创建好的 target 与解析后的目标拓扑信息;无论回调成功或抛出,
|
|
22
41
|
* 都保证 target 资源被正确释放,业务异常原样透传。
|
|
23
42
|
*
|
|
43
|
+
* 默认旁观打开:内部创建的本地 Host 以非收割模式打开存储(不置 recoverOrphans),
|
|
44
|
+
* 供 ad state / ad runs / ad config 等查询命令与运行中的 serve 进程并发访问同一库;
|
|
45
|
+
* 需要持有者语义的执行命令通过 localOptions.ownDataDir 显式声明。
|
|
46
|
+
*
|
|
24
47
|
* @param options 命令选项视图(profile/server/token/package/dataDir/insecure/allowInsecureHttp)
|
|
25
48
|
* @param context CLI 上下文
|
|
26
49
|
* @param fn 业务回调(target 为已创建的门面实例,resolved 为拓扑解析结果)
|
|
27
50
|
* @param localOptions 本地分支附加选项(如 scanLinkedPackages)与 localRoot 回退策略
|
|
28
51
|
*/
|
|
29
52
|
export async function withTarget(options, context, fn, localOptions) {
|
|
30
|
-
const resolved =
|
|
31
|
-
profile: options.profile,
|
|
32
|
-
server: options.server,
|
|
33
|
-
token: options.token,
|
|
34
|
-
insecure: options.insecure,
|
|
35
|
-
allowInsecureHttp: options.allowInsecureHttp,
|
|
36
|
-
}, context?.customHome);
|
|
53
|
+
const resolved = resolveTargetFromOptions(options, context);
|
|
37
54
|
// localRoot 仅在 local 分支求值,避免远端模式下触发包寻址副作用
|
|
38
55
|
const localRoot = resolved.type === "local"
|
|
39
56
|
? (typeof localOptions?.localRoot === "function" ? localOptions.localRoot() : localOptions?.localRoot) ??
|
|
40
57
|
findProjectRoot() ??
|
|
41
58
|
undefined
|
|
42
59
|
: undefined;
|
|
60
|
+
// 本地执行命令声明持有者身份时,向 App 层透传收割开关;
|
|
61
|
+
// 查询命令保持缺省不传,存储以旁观模式打开
|
|
62
|
+
const appRecoverOrphans = localOptions?.ownDataDir === true ? { recoverOrphans: true } : undefined;
|
|
43
63
|
const target = await createActionDockTarget(resolved.type === "remote"
|
|
44
64
|
? {
|
|
45
65
|
type: "remote",
|
|
@@ -61,6 +81,7 @@ export async function withTarget(options, context, fn, localOptions) {
|
|
|
61
81
|
...(localOptions?.scanLinkedPackages !== undefined
|
|
62
82
|
? { scanLinkedPackages: localOptions.scanLinkedPackages }
|
|
63
83
|
: undefined),
|
|
84
|
+
...(appRecoverOrphans ? { recoverOrphans: true } : undefined),
|
|
64
85
|
});
|
|
65
86
|
try {
|
|
66
87
|
await fn(target, resolved);
|
|
@@ -74,13 +95,7 @@ export async function withTarget(options, context, fn, localOptions) {
|
|
|
74
95
|
* 适用于 runs cancel 等明确要求远端目标的命令。
|
|
75
96
|
*/
|
|
76
97
|
export async function withRemoteTarget(options, context, fn) {
|
|
77
|
-
const resolved =
|
|
78
|
-
profile: options.profile,
|
|
79
|
-
server: options.server,
|
|
80
|
-
token: options.token,
|
|
81
|
-
insecure: options.insecure,
|
|
82
|
-
allowInsecureHttp: options.allowInsecureHttp,
|
|
83
|
-
}, context?.customHome);
|
|
98
|
+
const resolved = resolveTargetFromOptions(options, context);
|
|
84
99
|
const target = await createActionDockTarget({
|
|
85
100
|
type: "remote",
|
|
86
101
|
serverUrl: resolved.serverUrl,
|
package/dist/utils/utils.d.ts
CHANGED
|
@@ -20,18 +20,17 @@ export declare function getTargetRoot(packageOption?: string, keyHint?: string):
|
|
|
20
20
|
key: string;
|
|
21
21
|
};
|
|
22
22
|
/**
|
|
23
|
-
* 聚合命令自身选项与根程序全局选项(如 --json、--
|
|
23
|
+
* 聚合命令自身选项与根程序全局选项(如 --json、--data-dir 等)。
|
|
24
24
|
*/
|
|
25
25
|
export declare function getEffectiveOptions(rawOptions: any, cmd?: any): any;
|
|
26
26
|
/**
|
|
27
27
|
* 解析意图过滤回退策略。
|
|
28
|
-
* 机器输出模式(--json
|
|
28
|
+
* 机器输出模式(--json)仅在显式传 --fallback 时回退,
|
|
29
29
|
* 人类交互模式默认回退(可被 --no-fallback 关闭)。
|
|
30
30
|
*/
|
|
31
31
|
export declare function resolveFallbackStrategy(options: {
|
|
32
32
|
fallback?: boolean;
|
|
33
33
|
json?: boolean;
|
|
34
|
-
envelope?: boolean;
|
|
35
34
|
}): {
|
|
36
35
|
isMachine: boolean;
|
|
37
36
|
shouldFallback: boolean;
|
package/dist/utils/utils.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { resolvePackageRoot, findProjectRoot } from "@actiondock/core";
|
|
2
|
-
import { ArgumentError } from "../errors.js";
|
|
2
|
+
import { ArgumentError, notInProjectError, packageNotFoundError } from "../errors.js";
|
|
3
3
|
/**
|
|
4
4
|
* 解析意图字符串(从显式 --intent 或位置模式参数聚合)。
|
|
5
5
|
* 多个关键字使用 '|'(正则逻辑或)连接。
|
|
@@ -78,16 +78,16 @@ export function getTargetRoot(packageOption, keyHint) {
|
|
|
78
78
|
const root = resolvePackageRoot(targetPackage) || (targetPackage ? null : findProjectRoot());
|
|
79
79
|
if (!root) {
|
|
80
80
|
if (targetPackage) {
|
|
81
|
-
throw
|
|
81
|
+
throw packageNotFoundError(targetPackage);
|
|
82
82
|
}
|
|
83
83
|
else {
|
|
84
|
-
throw
|
|
84
|
+
throw notInProjectError("Please specify -P, --package <id> or cd into a project directory.");
|
|
85
85
|
}
|
|
86
86
|
}
|
|
87
87
|
return { root, key: effectiveKey };
|
|
88
88
|
}
|
|
89
89
|
/**
|
|
90
|
-
* 聚合命令自身选项与根程序全局选项(如 --json、--
|
|
90
|
+
* 聚合命令自身选项与根程序全局选项(如 --json、--data-dir 等)。
|
|
91
91
|
*/
|
|
92
92
|
export function getEffectiveOptions(rawOptions, cmd) {
|
|
93
93
|
if (cmd && typeof cmd.optsWithGlobals === "function") {
|
|
@@ -97,11 +97,11 @@ export function getEffectiveOptions(rawOptions, cmd) {
|
|
|
97
97
|
}
|
|
98
98
|
/**
|
|
99
99
|
* 解析意图过滤回退策略。
|
|
100
|
-
* 机器输出模式(--json
|
|
100
|
+
* 机器输出模式(--json)仅在显式传 --fallback 时回退,
|
|
101
101
|
* 人类交互模式默认回退(可被 --no-fallback 关闭)。
|
|
102
102
|
*/
|
|
103
103
|
export function resolveFallbackStrategy(options) {
|
|
104
|
-
const isMachine = Boolean(options.json
|
|
104
|
+
const isMachine = Boolean(options.json);
|
|
105
105
|
const fallbackExplicit = options.fallback === true ||
|
|
106
106
|
(Array.isArray(process.argv) && process.argv.includes("--fallback"));
|
|
107
107
|
return {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@actiondock/cli",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.7.0",
|
|
4
4
|
"description": "ActionDock CLI facade for developing, testing, building, and exporting standalone Agent Actions and Skills",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -34,11 +34,11 @@
|
|
|
34
34
|
"test": "node ../../scripts/run-tests.ts"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@actiondock/builder": "^2.
|
|
38
|
-
"@actiondock/core": "^2.
|
|
39
|
-
"@actiondock/mcp": "^2.
|
|
40
|
-
"@actiondock/runtime-node": "^2.
|
|
41
|
-
"@actiondock/sdk": "^2.
|
|
37
|
+
"@actiondock/builder": "^2.7.0",
|
|
38
|
+
"@actiondock/core": "^2.7.0",
|
|
39
|
+
"@actiondock/mcp": "^2.7.0",
|
|
40
|
+
"@actiondock/runtime-node": "^2.7.0",
|
|
41
|
+
"@actiondock/sdk": "^2.7.0",
|
|
42
42
|
"commander": "^13.1.0",
|
|
43
43
|
"selfsigned": "^5.5.0"
|
|
44
44
|
},
|