@actiondock/cli 2.7.0 → 2.9.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 +6 -7
- package/bin/ad.js +52 -23
- package/dist/commands/action/create.js +4 -5
- package/dist/commands/add.js +9 -17
- package/dist/commands/build.js +3 -18
- package/dist/commands/config/delete.js +8 -7
- package/dist/commands/config/env.js +7 -11
- package/dist/commands/config/get.js +8 -5
- package/dist/commands/config/list.js +16 -22
- package/dist/commands/config/schema.d.ts +7 -1
- package/dist/commands/config/schema.js +44 -67
- package/dist/commands/config/set.js +9 -7
- package/dist/commands/describe.js +10 -9
- package/dist/commands/doctor.js +4 -3
- package/dist/commands/export.js +5 -13
- package/dist/commands/generate.js +4 -3
- package/dist/commands/info.js +3 -1
- package/dist/commands/init.js +3 -3
- package/dist/commands/link.js +4 -4
- package/dist/commands/list.js +19 -10
- package/dist/commands/mcp.js +27 -66
- package/dist/commands/pack.js +3 -12
- package/dist/commands/playbook.js +30 -10
- package/dist/commands/profile.js +10 -19
- package/dist/commands/remove.js +5 -14
- package/dist/commands/run.d.ts +5 -2
- package/dist/commands/run.js +19 -20
- package/dist/commands/runs.js +26 -35
- package/dist/commands/serve.js +177 -57
- package/dist/commands/state-list.d.ts +2 -2
- package/dist/commands/state-list.js +10 -8
- package/dist/commands/state.d.ts +2 -2
- package/dist/commands/state.js +110 -103
- package/dist/commands/test.js +1 -1
- package/dist/commands/validate.js +4 -17
- package/dist/errors.d.ts +14 -0
- package/dist/errors.js +46 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +3 -3
- package/dist/renderer.d.ts +1 -1
- package/dist/renderer.js +1 -1
- package/dist/services/config-merge.d.ts +6 -5
- package/dist/services/config-merge.js +10 -8
- package/dist/services/inspect.js +3 -1
- package/dist/standalone/index.d.ts +4 -14
- package/dist/standalone/index.js +5 -44
- package/dist/types.d.ts +2 -1
- package/dist/types.js +1 -1
- package/dist/utils/cert.js +1 -1
- package/dist/utils/duration.d.ts +1 -1
- package/dist/utils/duration.js +1 -1
- package/dist/utils/index.d.ts +1 -2
- package/dist/utils/index.js +1 -2
- package/dist/utils/input.d.ts +9 -1
- package/dist/utils/input.js +12 -1
- package/dist/utils/server-launch.d.ts +114 -0
- package/dist/utils/server-launch.js +275 -0
- package/dist/utils/target.d.ts +14 -13
- package/dist/utils/target.js +20 -39
- package/dist/utils/utils.d.ts +101 -1
- package/dist/utils/utils.js +97 -7
- package/package.json +5 -6
- package/dist/utils/bytes.d.ts +0 -1
- package/dist/utils/bytes.js +0 -1
- package/dist/utils/filter.d.ts +0 -1
- package/dist/utils/filter.js +0 -1
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import { isSecretConfigKey,
|
|
1
|
+
import { isSecretConfigKey, } from "@actiondock/core/project";
|
|
2
|
+
import { loadProjectConfig, } from "@actiondock/core";
|
|
3
|
+
import { resolvePackageRoot, } from "@actiondock/core/registry";
|
|
2
4
|
import { ArgumentError, packageNotFoundError } from "../../errors.js";
|
|
3
5
|
import { writeStdout } from "../../renderer.js";
|
|
4
|
-
import { applyTargetOptions, getEffectiveOptions,
|
|
6
|
+
import { applyTargetOptions, getEffectiveOptions, withService } from "../../utils/index.js";
|
|
5
7
|
import { resolveConfigValueInput } from "../../prompt.js";
|
|
6
8
|
/**
|
|
7
9
|
* 注册 config set 子命令:写入配置值(支持标准输入与安全提示)。
|
|
@@ -56,14 +58,14 @@ export function registerConfigSetCommand(configCmd, context) {
|
|
|
56
58
|
parsedVal = effectiveValueStr;
|
|
57
59
|
}
|
|
58
60
|
// 目标解析与写入(远端分支直接写远端作用域,本地分支按全局/项目作用域写入)
|
|
59
|
-
await
|
|
61
|
+
await withService(options, context, async (service, resolved) => {
|
|
60
62
|
if (resolved.type === "remote") {
|
|
61
|
-
await
|
|
63
|
+
await service.management?.config.set(options.package || "", key, parsedVal);
|
|
62
64
|
writeStdout(`[OK] Configuration '${key}' updated on remote server`, context);
|
|
63
65
|
return;
|
|
64
66
|
}
|
|
65
67
|
if (options.global) {
|
|
66
|
-
await
|
|
68
|
+
await service.management?.config.set("global", key, parsedVal);
|
|
67
69
|
writeStdout(`[OK] Global configuration '${key}' updated`, context);
|
|
68
70
|
return;
|
|
69
71
|
}
|
|
@@ -71,11 +73,11 @@ export function registerConfigSetCommand(configCmd, context) {
|
|
|
71
73
|
if (options.package) {
|
|
72
74
|
throw packageNotFoundError(options.package);
|
|
73
75
|
}
|
|
74
|
-
await
|
|
76
|
+
await service.management?.config.set("global", key, parsedVal);
|
|
75
77
|
writeStdout(`[OK] Global configuration '${key}' updated (no project in current directory)`, context);
|
|
76
78
|
return;
|
|
77
79
|
}
|
|
78
|
-
await
|
|
80
|
+
await service.management?.config.set(projConfig.id, key, parsedVal);
|
|
79
81
|
writeStdout(`[OK] Configuration '${key}' updated for package '${projConfig.id}'`, context);
|
|
80
82
|
});
|
|
81
83
|
});
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ACTION_NOT_FOUND, PACKAGE_NOT_FOUND, NOT_FOUND, } from "@actiondock/core";
|
|
2
|
+
import { buildActionDescribePayload, formatActionDetail, } from "@actiondock/core/project";
|
|
2
3
|
import { ArgumentError, ExecutionError, packageNotFoundError } from "../errors.js";
|
|
3
4
|
import { renderResult } from "../renderer.js";
|
|
4
|
-
import { applyTargetOptions, getEffectiveOptions, resolveLocalPackageRoot,
|
|
5
|
+
import { applyTargetOptions, getEffectiveOptions, resolveLocalPackageRoot, withService, } from "../utils/index.js";
|
|
5
6
|
/**
|
|
6
7
|
* 挂载 describe 子命令至指定 Commander 节点。
|
|
7
8
|
*
|
|
@@ -28,18 +29,18 @@ export function attachDescribeCommand(parent, context) {
|
|
|
28
29
|
throw packageNotFoundError(options.package);
|
|
29
30
|
}
|
|
30
31
|
const targetRef = id;
|
|
31
|
-
// 通过
|
|
32
|
-
await
|
|
32
|
+
// 通过 Service 门面统一查询 Action 规范
|
|
33
|
+
await withService(options, context, async (service) => {
|
|
33
34
|
let spec;
|
|
34
35
|
try {
|
|
35
|
-
spec = await
|
|
36
|
+
spec = await service.discovery.describeAction(targetRef);
|
|
36
37
|
}
|
|
37
38
|
catch (err) {
|
|
38
|
-
const
|
|
39
|
-
if (
|
|
40
|
-
throw new ArgumentError(
|
|
39
|
+
const code = err?.code;
|
|
40
|
+
if (code === ACTION_NOT_FOUND || code === NOT_FOUND || code === PACKAGE_NOT_FOUND) {
|
|
41
|
+
throw new ArgumentError(err?.message || String(err), err?.details, code);
|
|
41
42
|
}
|
|
42
|
-
throw new ExecutionError(
|
|
43
|
+
throw new ExecutionError(err?.message || String(err), err?.details, code);
|
|
43
44
|
}
|
|
44
45
|
const payload = buildActionDescribePayload(spec);
|
|
45
46
|
renderResult(payload, {
|
package/dist/commands/doctor.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { fetchRemoteDoctor,
|
|
2
|
-
import {
|
|
1
|
+
import { fetchRemoteDoctor, } from "@actiondock/core/profile";
|
|
2
|
+
import { runDoctorChecks, } from "@actiondock/core/project";
|
|
3
|
+
import { wrapAsExecutionError } from "../errors.js";
|
|
3
4
|
import { renderResult } from "../renderer.js";
|
|
4
5
|
import { applyTargetOptions, getEffectiveOptions, resolveTargetFromOptions } from "../utils/index.js";
|
|
5
6
|
export function registerDoctorCommand(program, context) {
|
|
@@ -71,7 +72,7 @@ export function registerDoctorCommand(program, context) {
|
|
|
71
72
|
}
|
|
72
73
|
}
|
|
73
74
|
catch (err) {
|
|
74
|
-
throw
|
|
75
|
+
throw wrapAsExecutionError(err, "Doctor failed to run diagnostics: ");
|
|
75
76
|
}
|
|
76
77
|
});
|
|
77
78
|
}
|
package/dist/commands/export.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { existsSync } from "node:fs";
|
|
2
2
|
import { basename } from "node:path";
|
|
3
|
-
import { discoverProjects,
|
|
4
|
-
import {
|
|
3
|
+
import { discoverProjects, listLinkedPackages, resolvePackageRoot, } from "@actiondock/core/registry";
|
|
4
|
+
import { findProjectRoot, } from "@actiondock/core";
|
|
5
|
+
import { ExecutionError, notInProjectError, packageNotFoundError, wrapAsExecutionError } from "../errors.js";
|
|
5
6
|
import { renderResult, writeStdout } from "../renderer.js";
|
|
6
7
|
import { getEffectiveOptions, parseListOption } from "../utils/index.js";
|
|
7
8
|
export function registerExportCommand(program, context) {
|
|
@@ -16,9 +17,6 @@ export function registerExportCommand(program, context) {
|
|
|
16
17
|
.option("--all", "Export all linked packages from global registry")
|
|
17
18
|
.option("--bundle [name]", "Export multiple packages as a unified composite Skill bundle (defaults to workspace directory name if omitted)")
|
|
18
19
|
.option("-m, --mode <mode>", "Skill export mode ('source' or 'node')", "source")
|
|
19
|
-
.option("-s, --standalone", "Export standalone binary skill (removed)")
|
|
20
|
-
.option("-t, --target <target>", "Target compilation platform (removed)")
|
|
21
|
-
.option("--bytecode", "Bytecode compilation (removed)")
|
|
22
20
|
.option("-o, --out <path>", "Output skill directory")
|
|
23
21
|
.option("-p, --playbook <playbooks...>", "Only export specific playbook(s) and their dependent actions", parseListOption)
|
|
24
22
|
.option("-a, --actions <actions...>", "Only export specific action(s)", parseListOption)
|
|
@@ -31,10 +29,6 @@ export function registerExportCommand(program, context) {
|
|
|
31
29
|
.option("--require-reproducible", "Require reproducible build and fail if install scripts must run")
|
|
32
30
|
.action(async (rawOptions, cmd) => {
|
|
33
31
|
const options = getEffectiveOptions(rawOptions, cmd);
|
|
34
|
-
// 彻底删除 --standalone 单文件编译选项
|
|
35
|
-
if (options.standalone || options.target !== undefined || options.bytecode !== undefined) {
|
|
36
|
-
throw new ExecutionError("The '--standalone' option and binary target flags have been removed in ActionDock 2.0. Please use '--mode node' for self-contained Node.js directory skills, or '--mode source' for source-based skills.", undefined, "UNSUPPORTED_BUILD_MODE");
|
|
37
|
-
}
|
|
38
32
|
const mode = options.mode === "node" ? "node" : "source";
|
|
39
33
|
if (options.bundle && mode === "node") {
|
|
40
34
|
throw new ExecutionError("Composite Skill export (--bundle) currently only supports source mode. Please use '--mode source' to export as a composite workspace Skill.");
|
|
@@ -200,10 +194,8 @@ export function registerExportCommand(program, context) {
|
|
|
200
194
|
});
|
|
201
195
|
}
|
|
202
196
|
catch (err) {
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
}
|
|
206
|
-
throw new ExecutionError(`Export failed: ${err.message}`);
|
|
197
|
+
// wrapAsExecutionError 保留原始错误码(含 UNSUPPORTED_BUILD_MODE)
|
|
198
|
+
throw wrapAsExecutionError(err, "Export failed: ");
|
|
207
199
|
}
|
|
208
200
|
});
|
|
209
201
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { findProjectRoot,
|
|
2
|
-
import {
|
|
1
|
+
import { findProjectRoot, } from "@actiondock/core";
|
|
2
|
+
import { writeActionTypes, } from "@actiondock/core/project";
|
|
3
|
+
import { notInProjectError, wrapAsExecutionError } from "../errors.js";
|
|
3
4
|
import { renderResult } from "../renderer.js";
|
|
4
5
|
import { getEffectiveOptions } from "../utils/index.js";
|
|
5
6
|
/**
|
|
@@ -36,7 +37,7 @@ export function registerGenerateCommands(program, context) {
|
|
|
36
37
|
});
|
|
37
38
|
}
|
|
38
39
|
catch (err) {
|
|
39
|
-
throw
|
|
40
|
+
throw wrapAsExecutionError(err, "Failed to generate types: ");
|
|
40
41
|
}
|
|
41
42
|
});
|
|
42
43
|
}
|
package/dist/commands/info.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import { fetchRemoteInfo,
|
|
1
|
+
import { fetchRemoteInfo, } from "@actiondock/core/profile";
|
|
2
|
+
import { filterWithFallbackInfo, } from "@actiondock/core/project";
|
|
3
|
+
import { getRegistryStatus, resolvePackageRoot, } from "@actiondock/core/registry";
|
|
2
4
|
import { ExecutionError, NO_PROJECT_NO_LINKED_MESSAGE, packageNotFoundError } from "../errors.js";
|
|
3
5
|
import { projectDetailToJson, renderAggregatedPackages, renderProjectDetail, renderRegistryTree, renderResult, } from "../renderer.js";
|
|
4
6
|
import { getProjectDetailInfo, scanLocalAggregatedPackages } from "../services/index.js";
|
package/dist/commands/init.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { initProject } from "@actiondock/core";
|
|
1
|
+
import { initProject, } from "@actiondock/core";
|
|
2
2
|
import { writeStdout } from "../renderer.js";
|
|
3
|
-
import {
|
|
3
|
+
import { wrapAsExecutionError } from "../errors.js";
|
|
4
4
|
export function registerInitCommand(program) {
|
|
5
5
|
program
|
|
6
6
|
.command("init [directory]")
|
|
@@ -18,7 +18,7 @@ export function registerInitCommand(program) {
|
|
|
18
18
|
writeStdout(`Successfully initialized ActionDock project in ${dir}`);
|
|
19
19
|
}
|
|
20
20
|
catch (err) {
|
|
21
|
-
throw
|
|
21
|
+
throw wrapAsExecutionError(err);
|
|
22
22
|
}
|
|
23
23
|
});
|
|
24
24
|
}
|
package/dist/commands/link.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { linkPackage, pruneRegistry, unlinkPackage, } from "@actiondock/core";
|
|
2
|
-
import {
|
|
1
|
+
import { linkPackage, pruneRegistry, unlinkPackage, } from "@actiondock/core/registry";
|
|
2
|
+
import { wrapAsExecutionError } from "../errors.js";
|
|
3
3
|
import { writeStdout } from "../renderer.js";
|
|
4
4
|
export function registerLinkCommands(program) {
|
|
5
5
|
// ad link [path]
|
|
@@ -24,7 +24,7 @@ export function registerLinkCommands(program) {
|
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
26
|
catch (err) {
|
|
27
|
-
throw
|
|
27
|
+
throw wrapAsExecutionError(err);
|
|
28
28
|
}
|
|
29
29
|
});
|
|
30
30
|
// ad unlink [id|path]
|
|
@@ -65,7 +65,7 @@ export function registerLinkCommands(program) {
|
|
|
65
65
|
}
|
|
66
66
|
}
|
|
67
67
|
catch (err) {
|
|
68
|
-
throw
|
|
68
|
+
throw wrapAsExecutionError(err);
|
|
69
69
|
}
|
|
70
70
|
});
|
|
71
71
|
}
|
package/dist/commands/list.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { filterWithFallbackInfo } from "@actiondock/core";
|
|
1
|
+
import { filterWithFallbackInfo, } from "@actiondock/core/project";
|
|
2
2
|
import { packageNotFoundError } from "../errors.js";
|
|
3
3
|
import { renderActionList, renderResult } from "../renderer.js";
|
|
4
|
-
import { applyTargetOptions, getEffectiveOptions, resolveFallbackStrategy, resolveIntent, resolveLocalPackageRoot,
|
|
4
|
+
import { applyTargetOptions, getEffectiveOptions, remoteTargetSuffix, resolveFallbackStrategy, resolveIntent, resolveLocalPackageRoot, withService, } from "../utils/index.js";
|
|
5
5
|
/**
|
|
6
6
|
* 挂载 list 子命令至指定 Commander 节点。
|
|
7
7
|
*
|
|
@@ -28,14 +28,23 @@ export function attachListCommand(parent, context) {
|
|
|
28
28
|
if (options.package && !targetPackageRoot) {
|
|
29
29
|
throw packageNotFoundError(options.package);
|
|
30
30
|
}
|
|
31
|
-
// 通过
|
|
32
|
-
await
|
|
33
|
-
let rawSummaries = await
|
|
34
|
-
//
|
|
31
|
+
// 通过 Service 门面统一获取 Action 列表
|
|
32
|
+
await withService(options, context, async (service, resolved) => {
|
|
33
|
+
let rawSummaries = await service.discovery.listActions();
|
|
34
|
+
// 若指定了目标包但本地未过滤,则按包归属精确过滤:
|
|
35
|
+
// 仅保留全限定名命中目标包前缀、或 packageId 归属目标包的条目;
|
|
36
|
+
// 无法归属到目标包的无前缀短 id 条目不放行,避免他包短 id 混入
|
|
35
37
|
if (options.package && !options.profile && !options.server) {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
38
|
+
const targetPkg = options.package;
|
|
39
|
+
rawSummaries = rawSummaries.filter((s) => {
|
|
40
|
+
if (s.packageId) {
|
|
41
|
+
return (s.packageId === targetPkg ||
|
|
42
|
+
s.id === targetPkg ||
|
|
43
|
+
s.id.startsWith(`${targetPkg}/`));
|
|
44
|
+
}
|
|
45
|
+
// 无 packageId 归属信息的条目:仅全限定名前缀命中时放行
|
|
46
|
+
return s.id === targetPkg || s.id.startsWith(`${targetPkg}/`);
|
|
47
|
+
});
|
|
39
48
|
}
|
|
40
49
|
const rawList = rawSummaries.map((s) => {
|
|
41
50
|
let id = s.id;
|
|
@@ -59,7 +68,7 @@ export function attachListCommand(parent, context) {
|
|
|
59
68
|
return;
|
|
60
69
|
}
|
|
61
70
|
const title = resolved.type === "remote"
|
|
62
|
-
? `Actions
|
|
71
|
+
? `Actions ${remoteTargetSuffix(resolved)}`
|
|
63
72
|
: targetPackageRoot
|
|
64
73
|
? `Actions in ${options.package || "current project"}`
|
|
65
74
|
: "Available Actions";
|
package/dist/commands/mcp.js
CHANGED
|
@@ -1,9 +1,22 @@
|
|
|
1
1
|
import { resolve } from "node:path";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { getEffectiveOptions,
|
|
2
|
+
import { createNodePlatform, findProjectRoot, loadProjectConfig, } from "@actiondock/core";
|
|
3
|
+
import { formatHostForUrl, } from "@actiondock/core/server";
|
|
4
|
+
import { ExecutionError } from "../errors.js";
|
|
5
|
+
import { writeStdout } from "../renderer.js";
|
|
6
|
+
import { getEffectiveOptions, normalizeCorsOrigins, parseListOption, printServerBanner, registerStopSignalHandler, resolveMaxBodyBytes, resolveServerHost, resolveServerPort, resolveServerToken, resolveTimeoutMs, } from "../utils/index.js";
|
|
7
|
+
/**
|
|
8
|
+
* 解析 mcp 命令双分支共享的目标选项(目录、包、超时)。
|
|
9
|
+
*/
|
|
10
|
+
function resolveMcpServeOptions(options) {
|
|
11
|
+
return {
|
|
12
|
+
projectRoots: options.dir && options.dir.length > 0
|
|
13
|
+
? options.dir.map((d) => resolve(d))
|
|
14
|
+
: undefined,
|
|
15
|
+
packageIds: options.package && options.package.length > 0 ? options.package : undefined,
|
|
16
|
+
all: Boolean(options.all),
|
|
17
|
+
timeoutMs: resolveTimeoutMs(options.timeout),
|
|
18
|
+
};
|
|
19
|
+
}
|
|
7
20
|
/**
|
|
8
21
|
* 注册 mcp 命令(STDIO 与 HTTP 传输服务模式)。
|
|
9
22
|
*
|
|
@@ -21,20 +34,7 @@ export function registerMcpCommands(program, context) {
|
|
|
21
34
|
.option("--data-dir <path>", "Custom database storage directory")
|
|
22
35
|
.action(async (rawOptions, cmd) => {
|
|
23
36
|
const options = getEffectiveOptions(rawOptions, cmd);
|
|
24
|
-
|
|
25
|
-
if (options.timeout) {
|
|
26
|
-
try {
|
|
27
|
-
timeoutMs = parseDuration(options.timeout);
|
|
28
|
-
}
|
|
29
|
-
catch (err) {
|
|
30
|
-
throw new ArgumentError(`Invalid timeout format: ${err.message}`);
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
const projectRoots = options.dir && options.dir.length > 0
|
|
34
|
-
? options.dir.map((d) => resolve(d))
|
|
35
|
-
: undefined;
|
|
36
|
-
const packageIds = options.package && options.package.length > 0 ? options.package : undefined;
|
|
37
|
-
const all = Boolean(options.all);
|
|
37
|
+
const { projectRoots, packageIds, all, timeoutMs } = resolveMcpServeOptions(options);
|
|
38
38
|
try {
|
|
39
39
|
const { startMcpStdio } = await import("@actiondock/mcp");
|
|
40
40
|
await startMcpStdio({
|
|
@@ -69,38 +69,15 @@ export function registerMcpCommands(program, context) {
|
|
|
69
69
|
.option("--data-dir <path>", "Custom database storage directory")
|
|
70
70
|
.action(async (rawOptions, cmd) => {
|
|
71
71
|
const options = getEffectiveOptions(rawOptions, cmd);
|
|
72
|
-
const port =
|
|
73
|
-
const host = options.host
|
|
74
|
-
const token = options.token
|
|
75
|
-
(options.tokenEnv && typeof process !== "undefined" ? process.env?.[options.tokenEnv] : undefined) ||
|
|
76
|
-
(typeof process !== "undefined" ? process.env?.ACTIONDOCK_TOKEN : undefined);
|
|
72
|
+
const port = resolveServerPort(options.port, 5178, true);
|
|
73
|
+
const host = resolveServerHost(options.host);
|
|
74
|
+
const token = resolveServerToken(options.token, options.tokenEnv);
|
|
77
75
|
const allowInsecureNoAuth = Boolean(options.allowInsecureNoAuth);
|
|
78
76
|
const allowInsecureHttp = Boolean(options.allowInsecureHttp);
|
|
79
77
|
const allowQueryToken = Boolean(options.allowQueryToken);
|
|
80
|
-
const corsOrigins = options.corsOrigin
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
try {
|
|
84
|
-
maxBodyBytes = parseByteSize(options.maxBody);
|
|
85
|
-
}
|
|
86
|
-
catch (err) {
|
|
87
|
-
throw new ArgumentError(`Invalid max-body format: ${err.message}`);
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
let timeoutMs;
|
|
91
|
-
if (options.timeout) {
|
|
92
|
-
try {
|
|
93
|
-
timeoutMs = parseDuration(options.timeout);
|
|
94
|
-
}
|
|
95
|
-
catch (err) {
|
|
96
|
-
throw new ArgumentError(`Invalid timeout format: ${err.message}`);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
const projectRoots = options.dir && options.dir.length > 0
|
|
100
|
-
? options.dir.map((d) => resolve(d))
|
|
101
|
-
: undefined;
|
|
102
|
-
const packageIds = options.package && options.package.length > 0 ? options.package : undefined;
|
|
103
|
-
const all = Boolean(options.all);
|
|
78
|
+
const corsOrigins = normalizeCorsOrigins(options.corsOrigin);
|
|
79
|
+
const maxBodyBytes = resolveMaxBodyBytes(options.maxBody);
|
|
80
|
+
const { projectRoots, packageIds, all, timeoutMs } = resolveMcpServeOptions(options);
|
|
104
81
|
let targetDescription = "ActionDock MCP Server";
|
|
105
82
|
if (all) {
|
|
106
83
|
targetDescription = "All Linked Packages (Global Registry Mode)";
|
|
@@ -161,30 +138,14 @@ export function registerMcpCommands(program, context) {
|
|
|
161
138
|
});
|
|
162
139
|
const displayHost = formatHostForUrl(host);
|
|
163
140
|
const actualMcpHost = formatHostForUrl(host === "0.0.0.0" ? "127.0.0.1" : host);
|
|
164
|
-
|
|
165
|
-
writeStdout(` ActionDock 2.0 MCP HTTP Server`, context);
|
|
166
|
-
writeStdout(`======================================================`, context);
|
|
167
|
-
writeStdout(` * Listening on: http://${displayHost}:${server.port}`, context);
|
|
141
|
+
printServerBanner(`ActionDock 2.0 MCP HTTP Server`, "http", displayHost, server.port, context);
|
|
168
142
|
writeStdout(` * MCP Endpoint: http://${actualMcpHost}:${server.port}/mcp`, context);
|
|
169
143
|
writeStdout(` * Target: ${targetDescription}`, context);
|
|
170
144
|
writeStdout(` * Authentication: ${token ? "Bearer Token Enabled" : "Disabled (Local)"}`, context);
|
|
171
145
|
writeStdout(` * CORS Origins: ${corsOrigins ? corsOrigins.join(", ") : "Disabled (Default)"}`, context);
|
|
172
146
|
writeStdout(`======================================================\n`, context);
|
|
173
147
|
writeStdout(`Press Ctrl+C to terminate.\n`, context);
|
|
174
|
-
|
|
175
|
-
writeStdout("\nStopping MCP HTTP server...", context);
|
|
176
|
-
Promise.resolve(server.stop())
|
|
177
|
-
.catch((err) => {
|
|
178
|
-
// 停止失败必须可见:写入 stderr 一行并标记失败退出码
|
|
179
|
-
writeStderr(`[ERROR] Failed to stop MCP HTTP server gracefully: ${err instanceof Error ? err.message : String(err)}`, context);
|
|
180
|
-
process.exitCode = 1;
|
|
181
|
-
})
|
|
182
|
-
.finally(() => {
|
|
183
|
-
process.exit(typeof process.exitCode === "number" ? process.exitCode : 0);
|
|
184
|
-
});
|
|
185
|
-
};
|
|
186
|
-
process.once("SIGINT", stopSignalHandler);
|
|
187
|
-
process.once("SIGTERM", stopSignalHandler);
|
|
148
|
+
registerStopSignalHandler(server, `MCP HTTP server`, context);
|
|
188
149
|
}
|
|
189
150
|
catch (err) {
|
|
190
151
|
throw new ExecutionError(`Failed to start ActionDock MCP HTTP server: ${err.message}`, err);
|
package/dist/commands/pack.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { ExecutionError, notInProjectError, packageNotFoundError } from "../errors.js";
|
|
1
|
+
import { ExecutionError } from "../errors.js";
|
|
3
2
|
import { renderResult, writeStdout } from "../renderer.js";
|
|
4
|
-
import { getEffectiveOptions } from "../utils/index.js";
|
|
3
|
+
import { getEffectiveOptions, requirePackageRoot } from "../utils/index.js";
|
|
5
4
|
export function registerPackCommand(program, context) {
|
|
6
5
|
program
|
|
7
6
|
.command("pack")
|
|
@@ -12,15 +11,7 @@ export function registerPackCommand(program, context) {
|
|
|
12
11
|
.option("--json", "Output as JSON")
|
|
13
12
|
.action(async (rawOptions, cmd) => {
|
|
14
13
|
const options = getEffectiveOptions(rawOptions, cmd);
|
|
15
|
-
const root = options.package
|
|
16
|
-
? resolvePackageRoot(options.package)
|
|
17
|
-
: findProjectRoot();
|
|
18
|
-
if (!root) {
|
|
19
|
-
if (options.package) {
|
|
20
|
-
throw packageNotFoundError(options.package);
|
|
21
|
-
}
|
|
22
|
-
throw notInProjectError("Please specify -P, --package <id> or cd into a project directory.");
|
|
23
|
-
}
|
|
14
|
+
const { root } = requirePackageRoot(options.package);
|
|
24
15
|
const isMachine = Boolean(options.json);
|
|
25
16
|
if (!isMachine && !options.dryRun) {
|
|
26
17
|
writeStdout("Packing Action package...");
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import { existsSync, mkdirSync, writeFileSync } from "node:fs";
|
|
2
2
|
import { dirname, isAbsolute, relative, resolve } from "node:path";
|
|
3
|
-
import { assertPathWithinRoot,
|
|
4
|
-
import {
|
|
3
|
+
import { assertPathWithinRoot, loadActions, loadManifest, loadPlaybooks, saveManifest, filterWithFallbackInfo, } from "@actiondock/core/project";
|
|
4
|
+
import { DefaultActionCatalog, PackageGraphBuilder, resolveAction, resolvePlaybook, } from "@actiondock/core/graph";
|
|
5
|
+
import { fetchRemotePlaybooks, fetchRemotePlaybookShow, } from "@actiondock/core/profile";
|
|
6
|
+
import { findProjectRoot, loadProjectConfig, } from "@actiondock/core";
|
|
7
|
+
import { listLinkedPackages, resolvePackageRoot, } from "@actiondock/core/registry";
|
|
8
|
+
import { ArgumentError, CliError, ExecutionError, NO_PROJECT_NO_LINKED_MESSAGE, notInProjectError, packageNotFoundError, wrapAsExecutionError, } from "../errors.js";
|
|
5
9
|
import { renderPlaybookDetail, renderPlaybookList, renderResult, writeStdout, } from "../renderer.js";
|
|
6
|
-
import { applyTargetOptions, getEffectiveOptions, resolveIntent, resolveTargetFromOptions, } from "../utils/index.js";
|
|
10
|
+
import { applyTargetOptions, getEffectiveOptions, remoteTargetSuffix, resolveFallbackStrategy, resolveIntent, resolveTargetFromOptions, } from "../utils/index.js";
|
|
7
11
|
/**
|
|
8
12
|
* 注册 Playbook 命令集合(list, show, validate, create)。
|
|
9
13
|
*
|
|
@@ -20,13 +24,13 @@ export function registerPlaybookCommands(program, context) {
|
|
|
20
24
|
.description("List playbooks in current project or linked packages")
|
|
21
25
|
.option("-i, --intent <pattern>", "Regex or fuzzy intent filter; falls back to full list when no match")
|
|
22
26
|
.option("-P, --package <id>", "Target package ID or path"))
|
|
27
|
+
.option("--fallback", "Enable fallback to full list when no items match intent")
|
|
23
28
|
.option("--no-fallback", "Disable fallback to full list when no items match intent")
|
|
24
29
|
.option("--json", "Output as JSON")
|
|
25
30
|
.action(async (patterns = [], rawOptions, cmd) => {
|
|
26
31
|
const options = getEffectiveOptions(rawOptions, cmd);
|
|
27
32
|
const effectiveIntent = resolveIntent(options.intent, patterns);
|
|
28
|
-
const shouldFallback = options
|
|
29
|
-
const isMachine = Boolean(options.json);
|
|
33
|
+
const { shouldFallback, isMachine } = resolveFallbackStrategy(options);
|
|
30
34
|
// 1. 远端服务分支
|
|
31
35
|
const target = resolveTargetFromOptions(options, context);
|
|
32
36
|
if (target.type === "remote") {
|
|
@@ -38,7 +42,7 @@ export function registerPlaybookCommands(program, context) {
|
|
|
38
42
|
});
|
|
39
43
|
renderResult(remotePbs, {
|
|
40
44
|
json: options.json,
|
|
41
|
-
humanFormatter: () => renderPlaybookList(remotePbs, `Playbooks
|
|
45
|
+
humanFormatter: () => renderPlaybookList(remotePbs, `Playbooks ${remoteTargetSuffix(target)}`, false, effectiveIntent),
|
|
42
46
|
context,
|
|
43
47
|
});
|
|
44
48
|
return;
|
|
@@ -187,7 +191,12 @@ export function registerPlaybookCommands(program, context) {
|
|
|
187
191
|
}
|
|
188
192
|
let resolved;
|
|
189
193
|
try {
|
|
190
|
-
|
|
194
|
+
const graph = new PackageGraphBuilder({
|
|
195
|
+
root: findProjectRoot() || undefined,
|
|
196
|
+
customHome: context?.customHome,
|
|
197
|
+
allowDevLinks: true,
|
|
198
|
+
}).buildSync();
|
|
199
|
+
resolved = resolvePlaybook(showTarget, { graph });
|
|
191
200
|
}
|
|
192
201
|
catch (err) {
|
|
193
202
|
throw new ArgumentError(err.message);
|
|
@@ -243,7 +252,12 @@ export function registerPlaybookCommands(program, context) {
|
|
|
243
252
|
else if (id) {
|
|
244
253
|
let resolved;
|
|
245
254
|
try {
|
|
246
|
-
|
|
255
|
+
const graph = new PackageGraphBuilder({
|
|
256
|
+
root: findProjectRoot() || undefined,
|
|
257
|
+
customHome: context?.customHome,
|
|
258
|
+
allowDevLinks: true,
|
|
259
|
+
}).buildSync();
|
|
260
|
+
resolved = resolvePlaybook(id, { graph });
|
|
247
261
|
}
|
|
248
262
|
catch (err) {
|
|
249
263
|
throw new ArgumentError(err.message);
|
|
@@ -277,6 +291,12 @@ export function registerPlaybookCommands(program, context) {
|
|
|
277
291
|
}
|
|
278
292
|
}
|
|
279
293
|
const results = [];
|
|
294
|
+
const graph = new PackageGraphBuilder({
|
|
295
|
+
root: findProjectRoot() || undefined,
|
|
296
|
+
customHome: context?.customHome,
|
|
297
|
+
allowDevLinks: true,
|
|
298
|
+
}).buildSync();
|
|
299
|
+
const catalog = new DefaultActionCatalog(graph);
|
|
280
300
|
for (const target of targets) {
|
|
281
301
|
const config = loadProjectConfig(target.root);
|
|
282
302
|
const manifest = loadManifest(target.root);
|
|
@@ -294,7 +314,7 @@ export function registerPlaybookCommands(program, context) {
|
|
|
294
314
|
for (const actRef of pb.actions) {
|
|
295
315
|
if (actRef.includes("/")) {
|
|
296
316
|
try {
|
|
297
|
-
|
|
317
|
+
resolveAction(actRef, { graph, catalog, caller: target.packageId });
|
|
298
318
|
}
|
|
299
319
|
catch (e) {
|
|
300
320
|
errors.push(`Referenced cross-package action '${actRef}' not resolvable: ${e.message}`);
|
|
@@ -408,6 +428,6 @@ This playbook provides task execution guidance for AI Agents.
|
|
|
408
428
|
if (err instanceof CliError) {
|
|
409
429
|
throw err;
|
|
410
430
|
}
|
|
411
|
-
throw
|
|
431
|
+
throw wrapAsExecutionError(err);
|
|
412
432
|
}
|
|
413
433
|
}
|
package/dist/commands/profile.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { addProfile, checkRemoteHealth,
|
|
2
|
-
import {
|
|
1
|
+
import { addProfile, checkRemoteHealth, getProfile, listProfiles, loadProfiles, removeProfile, resolveProfileToken, resolveTarget, toSnakeUpperCase, updateProfile, useProfile, } from "@actiondock/core/profile";
|
|
2
|
+
import { filterWithFallbackInfo, maskSecretValue, } from "@actiondock/core/project";
|
|
3
|
+
import { ArgumentError, ExecutionError, wrapAsExecutionError, } from "../errors.js";
|
|
3
4
|
import { renderResult, writeStderr, writeStdout } from "../renderer.js";
|
|
4
5
|
import { getEffectiveOptions, resolveFallbackStrategy, resolveIntent } from "../utils/index.js";
|
|
5
6
|
export function registerProfileCommands(program) {
|
|
@@ -76,9 +77,7 @@ export function registerProfileCommands(program) {
|
|
|
76
77
|
});
|
|
77
78
|
}
|
|
78
79
|
catch (err) {
|
|
79
|
-
|
|
80
|
-
throw err;
|
|
81
|
-
throw new ExecutionError(err.message);
|
|
80
|
+
throw wrapAsExecutionError(err);
|
|
82
81
|
}
|
|
83
82
|
});
|
|
84
83
|
// ad profile add <name>
|
|
@@ -105,7 +104,7 @@ export function registerProfileCommands(program) {
|
|
|
105
104
|
writeStdout(`[OK] Profile '${name}' configured for server: ${options.server}${options.insecure ? " (insecure: true)" : ""}`);
|
|
106
105
|
}
|
|
107
106
|
catch (err) {
|
|
108
|
-
throw
|
|
107
|
+
throw wrapAsExecutionError(err);
|
|
109
108
|
}
|
|
110
109
|
});
|
|
111
110
|
// ad profile update <name>
|
|
@@ -140,7 +139,7 @@ export function registerProfileCommands(program) {
|
|
|
140
139
|
writeStdout(`[OK] Profile '${name}' updated`);
|
|
141
140
|
}
|
|
142
141
|
catch (err) {
|
|
143
|
-
throw
|
|
142
|
+
throw wrapAsExecutionError(err);
|
|
144
143
|
}
|
|
145
144
|
});
|
|
146
145
|
// ad profile use <name>
|
|
@@ -153,7 +152,7 @@ export function registerProfileCommands(program) {
|
|
|
153
152
|
writeStdout(`[OK] Active profile switched to '${name}'`);
|
|
154
153
|
}
|
|
155
154
|
catch (err) {
|
|
156
|
-
throw
|
|
155
|
+
throw wrapAsExecutionError(err);
|
|
157
156
|
}
|
|
158
157
|
});
|
|
159
158
|
// ad profile show [name]
|
|
@@ -221,10 +220,7 @@ export function registerProfileCommands(program) {
|
|
|
221
220
|
});
|
|
222
221
|
}
|
|
223
222
|
catch (err) {
|
|
224
|
-
|
|
225
|
-
throw err;
|
|
226
|
-
}
|
|
227
|
-
throw new ExecutionError(err.message);
|
|
223
|
+
throw wrapAsExecutionError(err);
|
|
228
224
|
}
|
|
229
225
|
});
|
|
230
226
|
// ad profile rm / remove <name>
|
|
@@ -244,10 +240,7 @@ export function registerProfileCommands(program) {
|
|
|
244
240
|
writeStdout(`[OK] Profile '${name}' removed`);
|
|
245
241
|
}
|
|
246
242
|
catch (err) {
|
|
247
|
-
|
|
248
|
-
throw err;
|
|
249
|
-
}
|
|
250
|
-
throw new ExecutionError(err.message);
|
|
243
|
+
throw wrapAsExecutionError(err);
|
|
251
244
|
}
|
|
252
245
|
});
|
|
253
246
|
// ad profile test [name]
|
|
@@ -290,9 +283,7 @@ export function registerProfileCommands(program) {
|
|
|
290
283
|
}
|
|
291
284
|
}
|
|
292
285
|
catch (err) {
|
|
293
|
-
|
|
294
|
-
throw err;
|
|
295
|
-
throw new ExecutionError(err.message);
|
|
286
|
+
throw wrapAsExecutionError(err);
|
|
296
287
|
}
|
|
297
288
|
});
|
|
298
289
|
}
|
package/dist/commands/remove.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { ArgumentError, ExecutionError, notInProjectError } from "../errors.js";
|
|
1
|
+
import { beginTransaction, getInstallCommand, loadLockfile, saveLockfile, saveManifest, } from "@actiondock/core/project";
|
|
2
|
+
import { ArgumentError, ExecutionError } from "../errors.js";
|
|
4
3
|
import { renderResult, writeStderr } from "../renderer.js";
|
|
5
|
-
import { assertSafePackageSpec, getEffectiveOptions, spawnAsync } from "../utils/index.js";
|
|
4
|
+
import { assertSafePackageSpec, getEffectiveOptions, requireProjectManifestRoot, rollbackAndRethrow, spawnAsync, } from "../utils/index.js";
|
|
6
5
|
/**
|
|
7
6
|
* 注册 ad remove 依赖移除命令。
|
|
8
7
|
* 遵循规范:移除依赖并更新锁文件,保留该包的历史存储数据,检查反向引用防止误删。
|
|
@@ -15,14 +14,7 @@ export function registerRemoveCommand(program, context) {
|
|
|
15
14
|
.option("--json", "Output as JSON")
|
|
16
15
|
.action(async (packageIdentifier, rawOptions, cmd) => {
|
|
17
16
|
const options = getEffectiveOptions(rawOptions, cmd);
|
|
18
|
-
const root
|
|
19
|
-
if (!root) {
|
|
20
|
-
throw notInProjectError("Please specify -P, --package <path> or cd into a project directory.");
|
|
21
|
-
}
|
|
22
|
-
const manifest = loadManifest(root);
|
|
23
|
-
if (!manifest) {
|
|
24
|
-
throw new ArgumentError(`actiondock.json not found in ${root}`);
|
|
25
|
-
}
|
|
17
|
+
const { root, manifest } = requireProjectManifestRoot(options.package);
|
|
26
18
|
// 寻址逻辑包标识
|
|
27
19
|
let targetPackageId = null;
|
|
28
20
|
let npmPackageName = packageIdentifier;
|
|
@@ -115,8 +107,7 @@ export function registerRemoveCommand(program, context) {
|
|
|
115
107
|
});
|
|
116
108
|
}
|
|
117
109
|
catch (err) {
|
|
118
|
-
await tx
|
|
119
|
-
throw new ExecutionError(err.message, err, err.code || "REMOVE_DEPENDENCY_FAILED");
|
|
110
|
+
await rollbackAndRethrow(tx, err, "REMOVE_DEPENDENCY_FAILED");
|
|
120
111
|
}
|
|
121
112
|
});
|
|
122
113
|
}
|