@actiondock/cli 2.4.0 → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/commands/config/delete.js +3 -6
- package/dist/commands/config/env.js +9 -7
- package/dist/commands/config/get.js +9 -7
- package/dist/commands/config/list.js +14 -8
- package/dist/commands/config/set.js +3 -6
- package/dist/commands/describe.js +4 -6
- package/dist/commands/doctor.js +9 -7
- package/dist/commands/info.js +7 -6
- package/dist/commands/list.js +4 -6
- package/dist/commands/playbook.js +15 -12
- package/dist/commands/profile.js +58 -6
- package/dist/commands/run.js +5 -6
- package/dist/commands/runs.js +10 -21
- package/dist/commands/serve.js +56 -5
- package/dist/commands/state.js +13 -31
- package/dist/utils/cert.d.ts +42 -0
- package/dist/utils/cert.js +211 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.js +1 -0
- package/dist/utils/target.d.ts +14 -1
- package/dist/utils/target.js +30 -1
- package/package.json +8 -7
package/README.md
CHANGED
|
@@ -126,7 +126,7 @@ ad pack
|
|
|
126
126
|
| `ad export skill` | 导出 Agent Skill 技能包(支持 `--mode source` 与 `--mode node`) |
|
|
127
127
|
| `ad link` / `unlink` | 注册或注销工作区全局路由与符号链接 |
|
|
128
128
|
| `ad profile` | 管理远程执行节点凭证与环境配置 |
|
|
129
|
-
| `ad serve` | 启动远程 HTTP
|
|
129
|
+
| `ad serve` | 启动远程 HTTP/HTTPS 执行调度微服务(原生支持 `--https` 自签名与生产证书) |
|
|
130
130
|
| `ad mcp` | 以 STDIO 或 HTTP 协议启动 MCP 服务 |
|
|
131
131
|
|
|
132
132
|
---
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { loadProjectConfig, resolvePackageRoot, } from "@actiondock/core";
|
|
2
2
|
import { ArgumentError } from "../../errors.js";
|
|
3
3
|
import { writeStdout } from "../../renderer.js";
|
|
4
|
-
import { getEffectiveOptions, withTarget } from "../../utils/index.js";
|
|
4
|
+
import { applyTargetOptions, getEffectiveOptions, withTarget } from "../../utils/index.js";
|
|
5
5
|
/**
|
|
6
6
|
* 注册 config delete 子命令:删除配置项。
|
|
7
7
|
*
|
|
@@ -9,15 +9,12 @@ import { getEffectiveOptions, withTarget } from "../../utils/index.js";
|
|
|
9
9
|
* @param context 命令行上下文
|
|
10
10
|
*/
|
|
11
11
|
export function registerConfigDeleteCommand(configCmd, context) {
|
|
12
|
-
configCmd
|
|
12
|
+
applyTargetOptions(configCmd
|
|
13
13
|
.command("delete <key>")
|
|
14
14
|
.alias("rm")
|
|
15
15
|
.description("Delete configuration entry")
|
|
16
16
|
.option("-P, --package <id>", "Target package ID or path")
|
|
17
|
-
.option("-g, --global", "Delete from global configuration")
|
|
18
|
-
.option("-p, --profile <name>", "Delete on a remote target")
|
|
19
|
-
.option("-s, --server <url>", "Remote server URL")
|
|
20
|
-
.option("-t, --token <token>", "Auth token for remote server")
|
|
17
|
+
.option("-g, --global", "Delete from global configuration"))
|
|
21
18
|
.option("--data-dir <path>", "Custom database storage directory")
|
|
22
19
|
.action(async (key, rawOptions, cmd) => {
|
|
23
20
|
const options = getEffectiveOptions(rawOptions, cmd);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { fetchRemoteConfigEnv, isSecretConfigKey, loadProjectConfig, resolveEnvValue, resolvePackageRoot, resolveTarget, } from "@actiondock/core";
|
|
2
2
|
import { ArgumentError } from "../../errors.js";
|
|
3
3
|
import { renderConfigEnv, renderResult } from "../../renderer.js";
|
|
4
|
-
import { getEffectiveOptions } from "../../utils/index.js";
|
|
4
|
+
import { applyTargetOptions, getEffectiveOptions } from "../../utils/index.js";
|
|
5
5
|
/**
|
|
6
6
|
* 注册 config env 子命令:诊断环境变量对声明配置的满足率。
|
|
7
7
|
*
|
|
@@ -9,13 +9,10 @@ import { getEffectiveOptions } from "../../utils/index.js";
|
|
|
9
9
|
* @param context 命令行上下文
|
|
10
10
|
*/
|
|
11
11
|
export function registerConfigEnvCommand(configCmd, context) {
|
|
12
|
-
configCmd
|
|
12
|
+
applyTargetOptions(configCmd
|
|
13
13
|
.command("env [identifier]")
|
|
14
14
|
.description("Diagnose environment variable satisfaction for declared configuration")
|
|
15
|
-
.option("-P, --package <id>", "Target package ID or path")
|
|
16
|
-
.option("-p, --profile <name>", "Query on a remote target")
|
|
17
|
-
.option("-s, --server <url>", "Remote server URL")
|
|
18
|
-
.option("-t, --token <token>", "Auth token for remote server")
|
|
15
|
+
.option("-P, --package <id>", "Target package ID or path"))
|
|
19
16
|
.option("--json", "Output as JSON")
|
|
20
17
|
.option("--envelope", "Wrap JSON output in standard envelope")
|
|
21
18
|
.action(async (identifier, rawOptions, cmd) => {
|
|
@@ -26,9 +23,14 @@ export function registerConfigEnvCommand(configCmd, context) {
|
|
|
26
23
|
profile: options.profile,
|
|
27
24
|
server: options.server,
|
|
28
25
|
token: options.token,
|
|
26
|
+
insecure: options.insecure,
|
|
27
|
+
allowInsecureHttp: options.allowInsecureHttp,
|
|
29
28
|
}, context?.customHome);
|
|
30
29
|
if (target.type === "remote") {
|
|
31
|
-
const res = await fetchRemoteConfigEnv(target.serverUrl, target.token, targetPkg
|
|
30
|
+
const res = await fetchRemoteConfigEnv(target.serverUrl, target.token, targetPkg, {
|
|
31
|
+
allowInsecureHttp: Boolean(options.allowInsecureHttp),
|
|
32
|
+
insecure: target.insecure,
|
|
33
|
+
});
|
|
32
34
|
renderResult(res, {
|
|
33
35
|
json: options.json,
|
|
34
36
|
envelope: options.envelope,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { fetchRemoteConfig, isSecretConfigKey, loadProjectConfig, maskSecretValue, resolveEnvValue, resolvePackageRoot, resolveTarget, } from "@actiondock/core";
|
|
2
2
|
import { ArgumentError } from "../../errors.js";
|
|
3
3
|
import { renderResult } from "../../renderer.js";
|
|
4
|
-
import { getEffectiveOptions, withTarget } from "../../utils/index.js";
|
|
4
|
+
import { applyTargetOptions, getEffectiveOptions, withTarget } from "../../utils/index.js";
|
|
5
5
|
/**
|
|
6
6
|
* 解析远端目标拓扑信息(仅信息解析,不创建 Target 实例)。
|
|
7
7
|
*/
|
|
@@ -10,6 +10,8 @@ function resolveRemoteTargetInfo(options, context) {
|
|
|
10
10
|
profile: options.profile,
|
|
11
11
|
server: options.server,
|
|
12
12
|
token: options.token,
|
|
13
|
+
insecure: options.insecure,
|
|
14
|
+
allowInsecureHttp: options.allowInsecureHttp,
|
|
13
15
|
}, context?.customHome);
|
|
14
16
|
}
|
|
15
17
|
/**
|
|
@@ -19,14 +21,11 @@ function resolveRemoteTargetInfo(options, context) {
|
|
|
19
21
|
* @param context 命令行上下文
|
|
20
22
|
*/
|
|
21
23
|
export function registerConfigGetCommand(configCmd, context) {
|
|
22
|
-
configCmd
|
|
24
|
+
applyTargetOptions(configCmd
|
|
23
25
|
.command("get <key>")
|
|
24
26
|
.description("Get configuration value for key")
|
|
25
27
|
.option("-P, --package <id>", "Target package ID or path")
|
|
26
|
-
.option("-g, --global", "Get from global configuration")
|
|
27
|
-
.option("-p, --profile <name>", "Query config on a remote target")
|
|
28
|
-
.option("-s, --server <url>", "Remote server URL")
|
|
29
|
-
.option("-t, --token <token>", "Auth token for remote server")
|
|
28
|
+
.option("-g, --global", "Get from global configuration"))
|
|
30
29
|
.option("--reveal, --show-secrets", "Reveal plain text values for secrets")
|
|
31
30
|
.option("--data-dir <path>", "Custom database storage directory")
|
|
32
31
|
.option("--json", "Output as JSON")
|
|
@@ -40,7 +39,10 @@ export function registerConfigGetCommand(configCmd, context) {
|
|
|
40
39
|
// 远端服务分支不经过 Target 门面,直接查询远端配置接口
|
|
41
40
|
const target = resolveRemoteTargetInfo(options, context);
|
|
42
41
|
if (target.type === "remote") {
|
|
43
|
-
const res = await fetchRemoteConfig(target.serverUrl, target.token, options.package
|
|
42
|
+
const res = await fetchRemoteConfig(target.serverUrl, target.token, options.package, {
|
|
43
|
+
allowInsecureHttp: Boolean(options.allowInsecureHttp),
|
|
44
|
+
insecure: target.insecure,
|
|
45
|
+
});
|
|
44
46
|
const val = res.values?.[key];
|
|
45
47
|
const isSecret = isSecretConfigKey(key, res.declared?.[key]);
|
|
46
48
|
const displayValue = !reveal && isSecret && val !== undefined ? maskSecretValue(val) : val;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { fetchRemoteConfig, filterWithFallbackInfo, findProjectRoot, isSecretConfigKey, loadProjectConfig, maskSecretValue, resolveEnvValue, resolvePackageRoot, resolveTarget, } from "@actiondock/core";
|
|
2
2
|
import { ArgumentError } from "../../errors.js";
|
|
3
3
|
import { renderConfigList, renderResult } from "../../renderer.js";
|
|
4
|
-
import { getEffectiveOptions, resolveIntent, withTarget } from "../../utils/index.js";
|
|
4
|
+
import { applyTargetOptions, getEffectiveOptions, resolveIntent, withTarget } from "../../utils/index.js";
|
|
5
5
|
/**
|
|
6
6
|
* 构造单条配置项的展示视图(含掩码决策,reveal 为假且为敏感键时打码)。
|
|
7
7
|
* 掩码决策收敛于命令层,renderer 仅负责值的字符串格式化。
|
|
@@ -23,14 +23,11 @@ function toDisplayEntry(key, rawValue, source, isSecret, reveal, description) {
|
|
|
23
23
|
* @param context 命令行上下文
|
|
24
24
|
*/
|
|
25
25
|
export function registerConfigListCommand(configCmd, context) {
|
|
26
|
-
configCmd
|
|
26
|
+
applyTargetOptions(configCmd
|
|
27
27
|
.command("list [patterns...]")
|
|
28
28
|
.description("List configuration entries (Global & Project)")
|
|
29
29
|
.option("-P, --package <id>", "Target package ID or path")
|
|
30
|
-
.option("-g, --global", "Show only global configurations")
|
|
31
|
-
.option("-p, --profile <name>", "Query config on a remote target")
|
|
32
|
-
.option("-s, --server <url>", "Remote server URL")
|
|
33
|
-
.option("-t, --token <token>", "Auth token for remote server")
|
|
30
|
+
.option("-g, --global", "Show only global configurations"))
|
|
34
31
|
.option("-i, --intent <pattern>", "Regex or fuzzy intent filter; falls back to full list when no match")
|
|
35
32
|
.option("--reveal, --show-secrets", "Reveal plain text values for secrets")
|
|
36
33
|
.option("--no-fallback", "Disable fallback to full list when no items match intent")
|
|
@@ -43,9 +40,18 @@ export function registerConfigListCommand(configCmd, context) {
|
|
|
43
40
|
const shouldFallback = options.fallback !== false;
|
|
44
41
|
const reveal = Boolean(options.reveal || options.showSecrets);
|
|
45
42
|
// 远端服务分支不经过 Target 门面,直接查询远端配置接口
|
|
46
|
-
const remoteTargetInfo = resolveTarget({
|
|
43
|
+
const remoteTargetInfo = resolveTarget({
|
|
44
|
+
profile: options.profile,
|
|
45
|
+
server: options.server,
|
|
46
|
+
token: options.token,
|
|
47
|
+
insecure: options.insecure,
|
|
48
|
+
allowInsecureHttp: options.allowInsecureHttp,
|
|
49
|
+
}, context?.customHome);
|
|
47
50
|
if (remoteTargetInfo.type === "remote") {
|
|
48
|
-
const res = await fetchRemoteConfig(remoteTargetInfo.serverUrl, remoteTargetInfo.token, options.package
|
|
51
|
+
const res = await fetchRemoteConfig(remoteTargetInfo.serverUrl, remoteTargetInfo.token, options.package, {
|
|
52
|
+
allowInsecureHttp: Boolean(options.allowInsecureHttp),
|
|
53
|
+
insecure: remoteTargetInfo.insecure,
|
|
54
|
+
});
|
|
49
55
|
const entries = Object.entries(res.values || {}).map(([k, v]) => toDisplayEntry(k, v, "remote", isSecretConfigKey(k, res.declared?.[k]), reveal, res.declared?.[k]?.description || ""));
|
|
50
56
|
renderResult(entries, {
|
|
51
57
|
json: options.json,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { isSecretConfigKey, loadProjectConfig, resolvePackageRoot, } from "@actiondock/core";
|
|
2
2
|
import { ArgumentError } from "../../errors.js";
|
|
3
3
|
import { writeStdout } from "../../renderer.js";
|
|
4
|
-
import { getEffectiveOptions, withTarget } from "../../utils/index.js";
|
|
4
|
+
import { applyTargetOptions, getEffectiveOptions, withTarget } from "../../utils/index.js";
|
|
5
5
|
import { resolveConfigValueInput } from "../../prompt.js";
|
|
6
6
|
/**
|
|
7
7
|
* 注册 config set 子命令:写入配置值(支持标准输入与安全提示)。
|
|
@@ -10,14 +10,11 @@ import { resolveConfigValueInput } from "../../prompt.js";
|
|
|
10
10
|
* @param context 命令行上下文
|
|
11
11
|
*/
|
|
12
12
|
export function registerConfigSetCommand(configCmd, context) {
|
|
13
|
-
configCmd
|
|
13
|
+
applyTargetOptions(configCmd
|
|
14
14
|
.command("set <key> [value]")
|
|
15
15
|
.description("Set configuration value (supports stdin and secure prompt)")
|
|
16
16
|
.option("-P, --package <id>", "Target package ID or path")
|
|
17
|
-
.option("-g, --global", "Set in global configuration")
|
|
18
|
-
.option("-p, --profile <name>", "Configure on a remote target")
|
|
19
|
-
.option("-s, --server <url>", "Remote server URL")
|
|
20
|
-
.option("-t, --token <token>", "Auth token for remote server")
|
|
17
|
+
.option("-g, --global", "Set in global configuration"))
|
|
21
18
|
.option("--stdin", "Read value from standard input")
|
|
22
19
|
.option("--data-dir <path>", "Custom database storage directory")
|
|
23
20
|
.action(async (key, rawVal, rawOptions, cmd) => {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ArgumentError, ExecutionError } from "../errors.js";
|
|
2
2
|
import { renderActionDetail, renderResult } from "../renderer.js";
|
|
3
|
-
import { getEffectiveOptions, resolveLocalPackageRoot, withTarget, } from "../utils/index.js";
|
|
3
|
+
import { applyTargetOptions, getEffectiveOptions, resolveLocalPackageRoot, withTarget, } from "../utils/index.js";
|
|
4
4
|
/**
|
|
5
5
|
* 挂载 describe 子命令至指定 Commander 节点。
|
|
6
6
|
*
|
|
@@ -8,14 +8,12 @@ import { getEffectiveOptions, resolveLocalPackageRoot, withTarget, } from "../ut
|
|
|
8
8
|
* @param context 命令行上下文
|
|
9
9
|
*/
|
|
10
10
|
export function attachDescribeCommand(parent, context) {
|
|
11
|
-
|
|
11
|
+
const cmd = parent
|
|
12
12
|
.command("describe <id>")
|
|
13
13
|
.alias("show")
|
|
14
14
|
.description("Show action definition, schema, and description")
|
|
15
|
-
.option("-P, --package <id>", "Target package ID or path")
|
|
16
|
-
|
|
17
|
-
.option("-s, --server <url>", "Remote server URL")
|
|
18
|
-
.option("-t, --token <token>", "Auth token for remote server")
|
|
15
|
+
.option("-P, --package <id>", "Target package ID or path");
|
|
16
|
+
return applyTargetOptions(cmd)
|
|
19
17
|
.option("--json", "Output as JSON")
|
|
20
18
|
.option("--envelope", "Wrap JSON output in standard envelope")
|
|
21
19
|
.option("--data-dir <path>", "Custom database storage directory")
|
package/dist/commands/doctor.js
CHANGED
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
import { fetchRemoteDoctor, resolveTarget, runDoctorChecks } from "@actiondock/core";
|
|
2
2
|
import { ExecutionError } from "../errors.js";
|
|
3
3
|
import { renderResult } from "../renderer.js";
|
|
4
|
-
import { getEffectiveOptions } from "../utils/index.js";
|
|
4
|
+
import { applyTargetOptions, getEffectiveOptions } from "../utils/index.js";
|
|
5
5
|
export function registerDoctorCommand(program, context) {
|
|
6
|
-
program
|
|
6
|
+
const cmd = program
|
|
7
7
|
.command("doctor")
|
|
8
8
|
.description("Check ActionDock environment, registry health, and project diagnostics")
|
|
9
|
-
.option("-P, --package <id|path>", "Target package ID or directory path for project diagnostics")
|
|
10
|
-
|
|
11
|
-
.option("-s, --server <url>", "Remote server URL")
|
|
12
|
-
.option("-t, --token <token>", "Auth token for remote server")
|
|
9
|
+
.option("-P, --package <id|path>", "Target package ID or directory path for project diagnostics");
|
|
10
|
+
applyTargetOptions(cmd)
|
|
13
11
|
.option("--json", "Output diagnostics report in JSON format")
|
|
14
12
|
.option("--envelope", "Wrap JSON output in standard envelope")
|
|
15
13
|
.action(async (rawOptions, cmd) => {
|
|
@@ -19,10 +17,14 @@ export function registerDoctorCommand(program, context) {
|
|
|
19
17
|
profile: options.profile,
|
|
20
18
|
server: options.server,
|
|
21
19
|
token: options.token,
|
|
20
|
+
insecure: options.insecure,
|
|
22
21
|
}, context?.customHome);
|
|
23
22
|
let report;
|
|
24
23
|
if (target.type === "remote") {
|
|
25
|
-
const remoteRes = await fetchRemoteDoctor(target.serverUrl, target.token, options.package
|
|
24
|
+
const remoteRes = await fetchRemoteDoctor(target.serverUrl, target.token, options.package, {
|
|
25
|
+
allowInsecureHttp: Boolean(options.allowInsecureHttp),
|
|
26
|
+
insecure: target.insecure,
|
|
27
|
+
});
|
|
26
28
|
report = remoteRes.report || remoteRes;
|
|
27
29
|
}
|
|
28
30
|
else {
|
package/dist/commands/info.js
CHANGED
|
@@ -2,7 +2,7 @@ import { fetchRemoteInfo, filterWithFallbackInfo, getRegistryStatus, resolvePack
|
|
|
2
2
|
import { ArgumentError, ExecutionError } from "../errors.js";
|
|
3
3
|
import { projectDetailToJson, renderAggregatedPackages, renderProjectDetail, renderRegistryTree, renderResult, } from "../renderer.js";
|
|
4
4
|
import { getProjectDetailInfo, scanLocalAggregatedPackages } from "../services/index.js";
|
|
5
|
-
import { getEffectiveOptions, resolveFallbackStrategy, resolveIntent } from "../utils/index.js";
|
|
5
|
+
import { applyTargetOptions, getEffectiveOptions, resolveFallbackStrategy, resolveIntent } from "../utils/index.js";
|
|
6
6
|
/**
|
|
7
7
|
* 将远端信息响应归一为本地工程详情视图。
|
|
8
8
|
*/
|
|
@@ -41,15 +41,13 @@ function renderProjectDetailOutput(detail, options) {
|
|
|
41
41
|
* @param context 命令行上下文
|
|
42
42
|
*/
|
|
43
43
|
export function registerInfoCommand(program, context) {
|
|
44
|
-
program
|
|
44
|
+
const cmd = program
|
|
45
45
|
.command("info [patterns...]")
|
|
46
46
|
.description("Display information about current project, linked package, or remote target")
|
|
47
47
|
.option("-i, --intent <pattern>", "Regex or fuzzy intent filter; falls back to full list when no match")
|
|
48
48
|
.option("-P, --package <id>", "Target package ID or path")
|
|
49
|
-
.option("--tree", "Display packages in hierarchical tree view grouped by workspace")
|
|
50
|
-
|
|
51
|
-
.option("-s, --server <url>", "Remote server URL")
|
|
52
|
-
.option("-t, --token <token>", "Auth token for remote server")
|
|
49
|
+
.option("--tree", "Display packages in hierarchical tree view grouped by workspace");
|
|
50
|
+
applyTargetOptions(cmd)
|
|
53
51
|
.option("--fallback", "Enable fallback to full list when no items match intent")
|
|
54
52
|
.option("--no-fallback", "Disable fallback to full list when no items match intent")
|
|
55
53
|
.option("--json", "Output information as JSON")
|
|
@@ -65,12 +63,15 @@ export function registerInfoCommand(program, context) {
|
|
|
65
63
|
profile: options.profile,
|
|
66
64
|
server: options.server,
|
|
67
65
|
token: options.token,
|
|
66
|
+
insecure: options.insecure,
|
|
68
67
|
}, context?.customHome);
|
|
69
68
|
if (target.type === "remote") {
|
|
70
69
|
const remoteInfo = await fetchRemoteInfo(target.serverUrl, target.token, {
|
|
71
70
|
intent: effectiveIntent,
|
|
72
71
|
package: options.package,
|
|
73
72
|
tree: Boolean(options.tree),
|
|
73
|
+
allowInsecureHttp: Boolean(options.allowInsecureHttp),
|
|
74
|
+
insecure: target.insecure,
|
|
74
75
|
});
|
|
75
76
|
if (isMachine) {
|
|
76
77
|
renderResult(remoteInfo, outOpts);
|
package/dist/commands/list.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { filterWithFallbackInfo } from "@actiondock/core";
|
|
2
2
|
import { ArgumentError } from "../errors.js";
|
|
3
3
|
import { renderActionList, renderResult } from "../renderer.js";
|
|
4
|
-
import { getEffectiveOptions, resolveFallbackStrategy, resolveIntent, resolveLocalPackageRoot, withTarget } from "../utils/index.js";
|
|
4
|
+
import { applyTargetOptions, getEffectiveOptions, resolveFallbackStrategy, resolveIntent, resolveLocalPackageRoot, withTarget, } from "../utils/index.js";
|
|
5
5
|
/**
|
|
6
6
|
* 挂载 list 子命令至指定 Commander 节点。
|
|
7
7
|
*
|
|
@@ -9,14 +9,12 @@ import { getEffectiveOptions, resolveFallbackStrategy, resolveIntent, resolveLoc
|
|
|
9
9
|
* @param context 命令行上下文
|
|
10
10
|
*/
|
|
11
11
|
export function attachListCommand(parent, context) {
|
|
12
|
-
|
|
12
|
+
const cmd = parent
|
|
13
13
|
.command("list [patterns...]")
|
|
14
14
|
.description("List actions in current project, linked packages, or remote profile")
|
|
15
15
|
.option("-i, --intent <pattern>", "Regex or fuzzy intent filter; falls back to full list when no match")
|
|
16
|
-
.option("-P, --package <id>", "Target package ID or path")
|
|
17
|
-
|
|
18
|
-
.option("-s, --server <url>", "Remote server URL")
|
|
19
|
-
.option("-t, --token <token>", "Auth token for remote server")
|
|
16
|
+
.option("-P, --package <id>", "Target package ID or path");
|
|
17
|
+
return applyTargetOptions(cmd)
|
|
20
18
|
.option("--fallback", "Enable fallback to full list when no items match intent")
|
|
21
19
|
.option("--no-fallback", "Disable fallback to full list when no items match intent")
|
|
22
20
|
.option("--json", "Output as JSON")
|
|
@@ -3,7 +3,7 @@ import { dirname, isAbsolute, relative, resolve } from "node:path";
|
|
|
3
3
|
import { assertPathWithinRoot, fetchRemotePlaybooks, fetchRemotePlaybookShow, filterWithFallbackInfo, findProjectRoot, listLinkedPackages, loadActions, loadManifest, loadPlaybooks, loadProjectConfig, resolveActionProject, resolvePackageRoot, resolvePlaybookProject, resolveTarget, saveManifest, } from "@actiondock/core";
|
|
4
4
|
import { ArgumentError, CliError, ExecutionError } from "../errors.js";
|
|
5
5
|
import { renderPlaybookDetail, renderPlaybookList, renderResult, writeStdout, } from "../renderer.js";
|
|
6
|
-
import { getEffectiveOptions, resolveIntent } from "../utils/index.js";
|
|
6
|
+
import { applyTargetOptions, getEffectiveOptions, resolveIntent } from "../utils/index.js";
|
|
7
7
|
/**
|
|
8
8
|
* 注册 Playbook 命令集合(list, show, validate, create)。
|
|
9
9
|
*
|
|
@@ -15,14 +15,11 @@ export function registerPlaybookCommands(program, context) {
|
|
|
15
15
|
.command("playbook")
|
|
16
16
|
.description("Manage task Playbooks (Task SOPs for AI Agents)");
|
|
17
17
|
// playbook list
|
|
18
|
-
pbCmd
|
|
18
|
+
applyTargetOptions(pbCmd
|
|
19
19
|
.command("list [patterns...]")
|
|
20
20
|
.description("List playbooks in current project or linked packages")
|
|
21
21
|
.option("-i, --intent <pattern>", "Regex or fuzzy intent filter; falls back to full list when no match")
|
|
22
|
-
.option("-P, --package <id>", "Target package ID or path")
|
|
23
|
-
.option("-p, --profile <name>", "Query against a specific profile")
|
|
24
|
-
.option("-s, --server <url>", "Remote server URL")
|
|
25
|
-
.option("-t, --token <token>", "Auth token for remote server")
|
|
22
|
+
.option("-P, --package <id>", "Target package ID or path"))
|
|
26
23
|
.option("--no-fallback", "Disable fallback to full list when no items match intent")
|
|
27
24
|
.option("--json", "Output as JSON")
|
|
28
25
|
.option("--envelope", "Wrap JSON output in standard envelope")
|
|
@@ -36,11 +33,15 @@ export function registerPlaybookCommands(program, context) {
|
|
|
36
33
|
profile: options.profile,
|
|
37
34
|
server: options.server,
|
|
38
35
|
token: options.token,
|
|
36
|
+
insecure: options.insecure,
|
|
37
|
+
allowInsecureHttp: options.allowInsecureHttp,
|
|
39
38
|
}, context?.customHome);
|
|
40
39
|
if (target.type === "remote") {
|
|
41
40
|
const remotePbs = await fetchRemotePlaybooks(target.serverUrl, target.token, {
|
|
42
41
|
intent: effectiveIntent,
|
|
43
42
|
package: options.package,
|
|
43
|
+
allowInsecureHttp: Boolean(options.allowInsecureHttp),
|
|
44
|
+
insecure: target.insecure,
|
|
44
45
|
});
|
|
45
46
|
renderResult(remotePbs, {
|
|
46
47
|
json: options.json,
|
|
@@ -162,13 +163,10 @@ export function registerPlaybookCommands(program, context) {
|
|
|
162
163
|
});
|
|
163
164
|
});
|
|
164
165
|
// playbook show <id>
|
|
165
|
-
pbCmd
|
|
166
|
+
applyTargetOptions(pbCmd
|
|
166
167
|
.command("show <id>")
|
|
167
168
|
.description("Show playbook content and metadata")
|
|
168
|
-
.option("-P, --package <id>", "Target package ID or path")
|
|
169
|
-
.option("-p, --profile <name>", "Query against a specific profile")
|
|
170
|
-
.option("-s, --server <url>", "Remote server URL")
|
|
171
|
-
.option("-t, --token <token>", "Auth token for remote server")
|
|
169
|
+
.option("-P, --package <id>", "Target package ID or path"))
|
|
172
170
|
.option("--json", "Output as JSON")
|
|
173
171
|
.option("--envelope", "Wrap JSON output in standard envelope")
|
|
174
172
|
.action(async (id, rawOptions, cmd) => {
|
|
@@ -181,9 +179,14 @@ export function registerPlaybookCommands(program, context) {
|
|
|
181
179
|
profile: options.profile,
|
|
182
180
|
server: options.server,
|
|
183
181
|
token: options.token,
|
|
182
|
+
insecure: options.insecure,
|
|
183
|
+
allowInsecureHttp: options.allowInsecureHttp,
|
|
184
184
|
}, context?.customHome);
|
|
185
185
|
if (target.type === "remote") {
|
|
186
|
-
const detail = await fetchRemotePlaybookShow(target.serverUrl, id, target.token
|
|
186
|
+
const detail = await fetchRemotePlaybookShow(target.serverUrl, id, target.token, {
|
|
187
|
+
allowInsecureHttp: Boolean(options.allowInsecureHttp),
|
|
188
|
+
insecure: target.insecure,
|
|
189
|
+
});
|
|
187
190
|
renderResult(detail, {
|
|
188
191
|
json: options.json,
|
|
189
192
|
envelope: options.envelope,
|
package/dist/commands/profile.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { addProfile, checkRemoteHealth, filterWithFallbackInfo, getProfile, listProfiles, loadProfiles, maskSecretValue, removeProfile, resolveProfileToken, resolveTarget, toSnakeUpperCase, useProfile, } from "@actiondock/core";
|
|
1
|
+
import { addProfile, checkRemoteHealth, filterWithFallbackInfo, getProfile, listProfiles, loadProfiles, maskSecretValue, removeProfile, resolveProfileToken, resolveTarget, toSnakeUpperCase, updateProfile, useProfile, } from "@actiondock/core";
|
|
2
2
|
import { ArgumentError, CliError, ExecutionError, } from "../errors.js";
|
|
3
3
|
import { renderResult, writeStdout } from "../renderer.js";
|
|
4
4
|
import { getEffectiveOptions, resolveFallbackStrategy, resolveIntent } from "../utils/index.js";
|
|
@@ -34,9 +34,10 @@ export function registerProfileCommands(program) {
|
|
|
34
34
|
tokenConfigured: resolved.source !== "none",
|
|
35
35
|
tokenSource: resolved.source,
|
|
36
36
|
token: reveal ? resolved.token : (resolved.token ? maskSecretValue(resolved.token) : undefined),
|
|
37
|
+
insecure: Boolean(p.entry.insecure),
|
|
37
38
|
};
|
|
38
39
|
});
|
|
39
|
-
const filterRes = filterWithFallbackInfo(enriched, effectiveIntent, [(p) => p.name, (p) => p.serverUrl, (p) => p.description, (p) => p.tokenSource], shouldFallback);
|
|
40
|
+
const filterRes = filterWithFallbackInfo(enriched, effectiveIntent, [(p) => p.name, (p) => p.serverUrl, (p) => p.description, (p) => p.tokenSource, (p) => (p.insecure ? "insecure" : "")], shouldFallback);
|
|
40
41
|
if (filterRes.isFallback && isMachine) {
|
|
41
42
|
renderResult({ items: filterRes.items, isFallback: true, matchedCount: 0 }, { json: options.json, envelope: options.envelope });
|
|
42
43
|
return;
|
|
@@ -67,8 +68,9 @@ export function registerProfileCommands(program) {
|
|
|
67
68
|
if (reveal && item.token) {
|
|
68
69
|
tokenInfo += ` = ${item.token}`;
|
|
69
70
|
}
|
|
71
|
+
const insecureTag = item.insecure ? " [insecure]" : "";
|
|
70
72
|
const desc = item.description ? ` - ${item.description}` : "";
|
|
71
|
-
lines.push(`${currentMarker}${item.name.padEnd(20)} ${item.serverUrl}${tokenInfo}${desc}`);
|
|
73
|
+
lines.push(`${currentMarker}${item.name.padEnd(20)} ${item.serverUrl}${tokenInfo}${insecureTag}${desc}`);
|
|
72
74
|
}
|
|
73
75
|
lines.push("\nUse 'ad profile use <name>' to switch or 'ad run <action> --profile <name>' to execute on a specific target.");
|
|
74
76
|
return lines.join("\n");
|
|
@@ -89,6 +91,7 @@ export function registerProfileCommands(program) {
|
|
|
89
91
|
.option("-t, --token <token>", "Authentication token for the remote server (deprecated; prefer --token-env)")
|
|
90
92
|
.option("--token-env <env>", "Environment variable name containing the authentication token")
|
|
91
93
|
.option("-d, --desc <description>", "Description of this profile/machine")
|
|
94
|
+
.option("-k, --insecure", "Allow insecure server connections (skip TLS certificate validation)")
|
|
92
95
|
.action((name, options) => {
|
|
93
96
|
try {
|
|
94
97
|
if (options.token) {
|
|
@@ -99,8 +102,44 @@ export function registerProfileCommands(program) {
|
|
|
99
102
|
token: options.token,
|
|
100
103
|
tokenEnv: options.tokenEnv,
|
|
101
104
|
description: options.desc,
|
|
105
|
+
insecure: options.insecure ? true : undefined,
|
|
102
106
|
});
|
|
103
|
-
writeStdout(`[OK] Profile '${name}' configured for server: ${options.server}`);
|
|
107
|
+
writeStdout(`[OK] Profile '${name}' configured for server: ${options.server}${options.insecure ? " (insecure: true)" : ""}`);
|
|
108
|
+
}
|
|
109
|
+
catch (err) {
|
|
110
|
+
throw new ExecutionError(err.message);
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
// ad profile update <name>
|
|
114
|
+
profileCmd
|
|
115
|
+
.command("update <name>")
|
|
116
|
+
.description("Update an existing remote execution profile")
|
|
117
|
+
.option("-s, --server <url>", "Remote ActionDock server URL (e.g. http://1.2.3.4:5177)")
|
|
118
|
+
.option("-t, --token <token>", "Authentication token for the remote server (deprecated; prefer --token-env)")
|
|
119
|
+
.option("--token-env <env>", "Environment variable name containing the authentication token")
|
|
120
|
+
.option("-d, --desc <description>", "Description of this profile/machine")
|
|
121
|
+
.option("-k, --insecure", "Allow insecure server connections (skip TLS certificate validation)")
|
|
122
|
+
.option("--no-insecure", "Enforce strict TLS certificate validation")
|
|
123
|
+
.action((name, options) => {
|
|
124
|
+
try {
|
|
125
|
+
if (options.token) {
|
|
126
|
+
console.warn("Warning: storing tokens directly in profiles.json is deprecated. Use --token-env or standard environment variables (e.g. ACTIONDOCK_<PROFILE>_TOKEN) instead.");
|
|
127
|
+
}
|
|
128
|
+
let insecure;
|
|
129
|
+
if (options.insecure === true) {
|
|
130
|
+
insecure = true;
|
|
131
|
+
}
|
|
132
|
+
else if (options.insecure === false) {
|
|
133
|
+
insecure = false;
|
|
134
|
+
}
|
|
135
|
+
updateProfile(name, {
|
|
136
|
+
serverUrl: options.server,
|
|
137
|
+
token: options.token,
|
|
138
|
+
tokenEnv: options.tokenEnv,
|
|
139
|
+
description: options.desc,
|
|
140
|
+
insecure,
|
|
141
|
+
});
|
|
142
|
+
writeStdout(`[OK] Profile '${name}' updated`);
|
|
104
143
|
}
|
|
105
144
|
catch (err) {
|
|
106
145
|
throw new ExecutionError(err.message);
|
|
@@ -148,6 +187,7 @@ export function registerProfileCommands(program) {
|
|
|
148
187
|
tokenSource: resolved.source,
|
|
149
188
|
tokenEnv: entry?.tokenEnv,
|
|
150
189
|
token: displayToken,
|
|
190
|
+
insecure: Boolean(entry?.insecure),
|
|
151
191
|
description: entry?.description || "",
|
|
152
192
|
};
|
|
153
193
|
renderResult(data, {
|
|
@@ -174,6 +214,9 @@ export function registerProfileCommands(program) {
|
|
|
174
214
|
if (data.tokenConfigured) {
|
|
175
215
|
lines.push(`Token Value: ${data.token}`);
|
|
176
216
|
}
|
|
217
|
+
if (data.serverUrl !== "local") {
|
|
218
|
+
lines.push(`TLS Verify: ${data.insecure ? "Disabled (Insecure)" : "Strict (Default)"}`);
|
|
219
|
+
}
|
|
177
220
|
if (data.description) {
|
|
178
221
|
lines.push(`Description: ${data.description}`);
|
|
179
222
|
}
|
|
@@ -215,12 +258,18 @@ export function registerProfileCommands(program) {
|
|
|
215
258
|
profileCmd
|
|
216
259
|
.command("test [name]")
|
|
217
260
|
.description("Test connection latency and health of a profile")
|
|
261
|
+
.option("-k, --insecure", "Allow insecure TLS connections (skip TLS certificate validation)")
|
|
262
|
+
.option("--allow-insecure-http", "Allow insecure HTTP connections with auth token")
|
|
218
263
|
.option("--json", "Output as JSON")
|
|
219
264
|
.option("--envelope", "Wrap JSON output in standard envelope")
|
|
220
265
|
.action(async (name, rawOptions, cmd) => {
|
|
221
266
|
try {
|
|
222
267
|
const options = getEffectiveOptions(rawOptions, cmd);
|
|
223
|
-
const target = resolveTarget({
|
|
268
|
+
const target = resolveTarget({
|
|
269
|
+
profile: name,
|
|
270
|
+
insecure: options.insecure !== undefined ? Boolean(options.insecure) : undefined,
|
|
271
|
+
allowInsecureHttp: options.allowInsecureHttp,
|
|
272
|
+
});
|
|
224
273
|
if (target.type === "local") {
|
|
225
274
|
renderResult({ ok: true, type: "local", message: "Local execution" }, {
|
|
226
275
|
json: options.json,
|
|
@@ -229,7 +278,10 @@ export function registerProfileCommands(program) {
|
|
|
229
278
|
});
|
|
230
279
|
return;
|
|
231
280
|
}
|
|
232
|
-
const health = await checkRemoteHealth(target.serverUrl, target.token
|
|
281
|
+
const health = await checkRemoteHealth(target.serverUrl, target.token, 5000, {
|
|
282
|
+
allowInsecureHttp: Boolean(options.allowInsecureHttp),
|
|
283
|
+
insecure: target.insecure,
|
|
284
|
+
});
|
|
233
285
|
renderResult(health, {
|
|
234
286
|
json: options.json,
|
|
235
287
|
envelope: options.envelope,
|
package/dist/commands/run.js
CHANGED
|
@@ -2,7 +2,7 @@ import { readFileSync } from "node:fs";
|
|
|
2
2
|
import { parseDuration, resolveTarget } from "@actiondock/core";
|
|
3
3
|
import { ArgumentError, ExecutionError, SigintError } from "../errors.js";
|
|
4
4
|
import { writeStdout } from "../renderer.js";
|
|
5
|
-
import { getEffectiveOptions, resolveLocalPackageRoot, withTarget } from "../utils/index.js";
|
|
5
|
+
import { applyTargetOptions, getEffectiveOptions, resolveLocalPackageRoot, withTarget, } from "../utils/index.js";
|
|
6
6
|
/**
|
|
7
7
|
* 统一执行 Action 核心逻辑(使用 ActionDockTarget 门面)。
|
|
8
8
|
*/
|
|
@@ -58,6 +58,7 @@ export async function executeAction(id, options, context) {
|
|
|
58
58
|
profile: options.profile,
|
|
59
59
|
server: options.server,
|
|
60
60
|
token: options.token,
|
|
61
|
+
insecure: options.insecure,
|
|
61
62
|
}, context?.customHome);
|
|
62
63
|
if (resolvedTopology.type === "local" && options.async) {
|
|
63
64
|
throw new ExecutionError("Async execution requires a long-running ActionDock server.\nUse --profile, --server, or start 'ad serve'.");
|
|
@@ -123,16 +124,14 @@ export async function executeAction(id, options, context) {
|
|
|
123
124
|
* @param context 命令行上下文
|
|
124
125
|
*/
|
|
125
126
|
export function attachRunCommand(parent, context) {
|
|
126
|
-
|
|
127
|
+
const cmd = parent
|
|
127
128
|
.command("run <id>")
|
|
128
129
|
.description("Execute an action (from current project, linked packages, or remote profile)")
|
|
129
130
|
.option("-P, --package <id>", "Target package ID or path")
|
|
130
131
|
.option("-i, --input <json>", "Input as JSON string")
|
|
131
132
|
.option("-f, --input-file <path>", "Input from JSON file")
|
|
132
|
-
.option("-c, --config <key=value...>", "Temporary config override (repeatable)")
|
|
133
|
-
|
|
134
|
-
.option("-s, --server <url>", "Remote server URL")
|
|
135
|
-
.option("-t, --token <token>", "Auth token for remote server")
|
|
133
|
+
.option("-c, --config <key=value...>", "Temporary config override (repeatable)");
|
|
134
|
+
return applyTargetOptions(cmd)
|
|
136
135
|
.option("--timeout <duration>", "Execution timeout (e.g. 30s, 5m, 500ms)")
|
|
137
136
|
.option("--request-id <id>", "Idempotency request ID for deduplication")
|
|
138
137
|
.option("--async", "Execute asynchronously in background (requires remote server or profile)")
|