@actiondock/cli 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.
Files changed (66) hide show
  1. package/README.md +34 -22
  2. package/bin/ad.js +4 -4
  3. package/dist/commands/action/create.js +9 -25
  4. package/dist/commands/add.js +9 -17
  5. package/dist/commands/build.js +3 -18
  6. package/dist/commands/config/delete.js +8 -7
  7. package/dist/commands/config/env.js +7 -11
  8. package/dist/commands/config/get.js +8 -5
  9. package/dist/commands/config/list.js +16 -22
  10. package/dist/commands/config/schema.d.ts +7 -1
  11. package/dist/commands/config/schema.js +44 -67
  12. package/dist/commands/config/set.js +9 -7
  13. package/dist/commands/describe.js +15 -26
  14. package/dist/commands/doctor.js +4 -3
  15. package/dist/commands/export.js +5 -13
  16. package/dist/commands/generate.js +4 -3
  17. package/dist/commands/info.js +3 -1
  18. package/dist/commands/init.js +3 -3
  19. package/dist/commands/link.js +4 -4
  20. package/dist/commands/list.js +19 -10
  21. package/dist/commands/mcp.js +27 -66
  22. package/dist/commands/pack.js +3 -12
  23. package/dist/commands/playbook.js +30 -10
  24. package/dist/commands/profile.js +10 -19
  25. package/dist/commands/remove.js +5 -14
  26. package/dist/commands/run.d.ts +6 -2
  27. package/dist/commands/run.js +60 -37
  28. package/dist/commands/runs.js +26 -35
  29. package/dist/commands/serve.js +66 -44
  30. package/dist/commands/state-list.d.ts +2 -2
  31. package/dist/commands/state-list.js +10 -8
  32. package/dist/commands/state.d.ts +2 -2
  33. package/dist/commands/state.js +110 -103
  34. package/dist/commands/test.js +1 -1
  35. package/dist/commands/validate.js +4 -17
  36. package/dist/errors.d.ts +14 -0
  37. package/dist/errors.js +78 -2
  38. package/dist/index.d.ts +8 -1
  39. package/dist/index.js +60 -8
  40. package/dist/renderer.d.ts +3 -2
  41. package/dist/renderer.js +4 -19
  42. package/dist/services/config-merge.d.ts +6 -5
  43. package/dist/services/config-merge.js +10 -8
  44. package/dist/services/inspect.js +3 -1
  45. package/dist/standalone/index.d.ts +7 -11
  46. package/dist/standalone/index.js +8 -17
  47. package/dist/types.d.ts +7 -1
  48. package/dist/types.js +1 -1
  49. package/dist/utils/cert.js +1 -1
  50. package/dist/utils/duration.d.ts +1 -1
  51. package/dist/utils/duration.js +1 -1
  52. package/dist/utils/index.d.ts +1 -2
  53. package/dist/utils/index.js +1 -2
  54. package/dist/utils/input.d.ts +5 -42
  55. package/dist/utils/input.js +7 -84
  56. package/dist/utils/server-launch.d.ts +61 -0
  57. package/dist/utils/server-launch.js +114 -0
  58. package/dist/utils/target.d.ts +14 -13
  59. package/dist/utils/target.js +20 -39
  60. package/dist/utils/utils.d.ts +101 -1
  61. package/dist/utils/utils.js +97 -7
  62. package/package.json +5 -6
  63. package/dist/utils/bytes.d.ts +0 -1
  64. package/dist/utils/bytes.js +0 -1
  65. package/dist/utils/filter.d.ts +0 -1
  66. package/dist/utils/filter.js +0 -1
@@ -1,5 +1,7 @@
1
- import { createActionDockTarget, findProjectRoot, resolvePackageRoot, resolveTarget, } from "@actiondock/core";
2
- import { createNodePlatform } from "@actiondock/runtime-node";
1
+ import { connectActionDock, createActionDock, createNodePlatform, findProjectRoot, } from "@actiondock/core";
2
+ import { resolvePackageRoot, } from "@actiondock/core/registry";
3
+ import { resolveTarget, } from "@actiondock/core/profile";
4
+ import { ArgumentError } from "../errors.js";
3
5
  /**
4
6
  * 统一为 Commander 命令节点挂载目标环境解析相关选项(单一事实源)。
5
7
  * 包括:-p/--profile, -s/--server, -t/--token, -k/--insecure, --allow-insecure-http。
@@ -23,7 +25,7 @@ export function applyTargetOptions(command) {
23
25
  *
24
26
  * @param options 命令选项视图(支持直接传入 Commander 解析后的 options 对象)
25
27
  * @param context CLI 上下文
26
- * @returns 解析后的目标拓扑信息(仅信息解析,不创建 Target 实例)
28
+ * @returns 解析后的目标拓扑信息(仅信息解析,不创建 Service 实例)
27
29
  */
28
30
  export function resolveTargetFromOptions(options, context) {
29
31
  return resolveTarget({
@@ -35,10 +37,10 @@ export function resolveTargetFromOptions(options, context) {
35
37
  }, context?.customHome);
36
38
  }
37
39
  /**
38
- * 高阶目标执行辅助:统一封装「目标解析 → Target 创建 → 业务回调 → try/finally close」样板。
40
+ * 高阶服务执行辅助:统一封装「目标解析 → Service 创建 → 业务回调 → try/finally close」样板。
39
41
  *
40
- * 回调获得创建好的 target 与解析后的目标拓扑信息;无论回调成功或抛出,
41
- * 都保证 target 资源被正确释放,业务异常原样透传。
42
+ * 回调获得创建好的 service 与解析后的目标拓扑信息;无论回调成功或抛出,
43
+ * 都保证 service 资源被正确释放,业务异常原样透传。
42
44
  *
43
45
  * 默认旁观打开:内部创建的本地 Host 以非收割模式打开存储(不置 recoverOrphans),
44
46
  * 供 ad state / ad runs / ad config 等查询命令与运行中的 serve 进程并发访问同一库;
@@ -46,29 +48,28 @@ export function resolveTargetFromOptions(options, context) {
46
48
  *
47
49
  * @param options 命令选项视图(profile/server/token/package/dataDir/insecure/allowInsecureHttp)
48
50
  * @param context CLI 上下文
49
- * @param fn 业务回调(target 为已创建的门面实例,resolved 为拓扑解析结果)
51
+ * @param fn 业务回调(service 为已创建的服务端口实例,resolved 为拓扑解析结果)
50
52
  * @param localOptions 本地分支附加选项(如 scanLinkedPackages)与 localRoot 回退策略
51
53
  */
52
- export async function withTarget(options, context, fn, localOptions) {
54
+ export async function withService(options, context, fn, localOptions) {
53
55
  const resolved = resolveTargetFromOptions(options, context);
56
+ if (localOptions?.requireRemote && resolved.type === "local") {
57
+ throw new ArgumentError("'ad runs cancel' is only supported for remote execution targets. Use --profile <name> or --server <url>.");
58
+ }
54
59
  // localRoot 仅在 local 分支求值,避免远端模式下触发包寻址副作用
55
60
  const localRoot = resolved.type === "local"
56
61
  ? (typeof localOptions?.localRoot === "function" ? localOptions.localRoot() : localOptions?.localRoot) ??
57
62
  findProjectRoot() ??
58
63
  undefined
59
64
  : undefined;
60
- // 本地执行命令声明持有者身份时,向 App 层透传收割开关;
61
- // 查询命令保持缺省不传,存储以旁观模式打开
62
- const appRecoverOrphans = localOptions?.ownDataDir === true ? { recoverOrphans: true } : undefined;
63
- const target = await createActionDockTarget(resolved.type === "remote"
64
- ? {
65
- type: "remote",
65
+ const service = resolved.type === "remote"
66
+ ? await connectActionDock({
66
67
  serverUrl: resolved.serverUrl,
67
68
  token: resolved.token,
68
69
  insecure: resolved.insecure,
69
70
  allowInsecureHttp: resolved.allowInsecureHttp ?? options.allowInsecureHttp,
70
- }
71
- : {
71
+ })
72
+ : await createActionDock({
72
73
  type: "local",
73
74
  projectRoot: localRoot,
74
75
  customHome: context?.customHome,
@@ -81,33 +82,13 @@ export async function withTarget(options, context, fn, localOptions) {
81
82
  ...(localOptions?.scanLinkedPackages !== undefined
82
83
  ? { scanLinkedPackages: localOptions.scanLinkedPackages }
83
84
  : undefined),
84
- ...(appRecoverOrphans ? { recoverOrphans: true } : undefined),
85
+ ...(localOptions?.ownDataDir === true ? { recoverOrphans: true } : undefined),
85
86
  });
86
87
  try {
87
- await fn(target, resolved);
88
- }
89
- finally {
90
- await target.close();
91
- }
92
- }
93
- /**
94
- * 仅远端模式目标执行辅助:创建远端 Target 并保证资源释放。
95
- * 适用于 runs cancel 等明确要求远端目标的命令。
96
- */
97
- export async function withRemoteTarget(options, context, fn) {
98
- const resolved = resolveTargetFromOptions(options, context);
99
- const target = await createActionDockTarget({
100
- type: "remote",
101
- serverUrl: resolved.serverUrl,
102
- token: resolved.token,
103
- insecure: resolved.insecure,
104
- allowInsecureHttp: resolved.allowInsecureHttp ?? options.allowInsecureHttp,
105
- });
106
- try {
107
- await fn(target, resolved);
88
+ await fn(service, resolved);
108
89
  }
109
90
  finally {
110
- await target.close();
91
+ await service.close();
111
92
  }
112
93
  }
113
94
  /**
@@ -1,3 +1,35 @@
1
+ import { loadProjectConfig } from "@actiondock/core";
2
+ import { type ActionDockManifest, type ProjectTransaction } from "@actiondock/core/project";
3
+ /**
4
+ * 「未显式指定包且当前目录无工程」的统一补救提示(单一事实源)。
5
+ */
6
+ export declare const PACKAGE_HINT_MESSAGE = "Please specify -P, --package <id> or cd into a project directory.";
7
+ /**
8
+ * 远端目标拓扑的最小字段视图(与 core 的 ResolvedTarget 远端分支兼容)。
9
+ */
10
+ export interface RemoteTargetLike {
11
+ serverUrl?: string;
12
+ profileName?: string;
13
+ }
14
+ /**
15
+ * 拼接远端目标标题后缀(单一事实源)。
16
+ *
17
+ * 形如 `on remote server <url> (Profile: <name>)`,供列表类命令的
18
+ * 标题拼接复用(如 `Actions ${remoteTargetSuffix(target)}`),
19
+ * 消除五处同构模板漂移。
20
+ *
21
+ * @param resolved 目标拓扑解析结果(远端分支)
22
+ */
23
+ export declare function remoteTargetSuffix(resolved: RemoteTargetLike): string;
24
+ /**
25
+ * 拼接远端目标标题标签(单一事实源)。
26
+ *
27
+ * 形如 `Remote Server <url> (Profile: <name>)`,与 remoteTargetSuffix 共享
28
+ * 同一拼接实现,供 state、config 等直接以远端目标为标题主体的命令复用。
29
+ *
30
+ * @param resolved 目标拓扑解析结果(远端分支)
31
+ */
32
+ export declare function remoteTargetLabel(resolved: RemoteTargetLike): string;
1
33
  /**
2
34
  * 解析意图字符串(从显式 --intent 或位置模式参数聚合)。
3
35
  * 多个关键字使用 '|'(正则逻辑或)连接。
@@ -19,14 +51,82 @@ export declare function getTargetRoot(packageOption?: string, keyHint?: string):
19
51
  root: string;
20
52
  key: string;
21
53
  };
54
+ /**
55
+ * 包根目录寻址脚手架(单一事实源):显式指定包且寻址失败抛 packageNotFoundError,
56
+ * 未指定包且当前目录无工程抛 notInProjectError(附带 -P 补救提示)。
57
+ *
58
+ * 与 getTargetRoot 的差异:不消费 pkg/ 键前缀提示,寻址失败必抛错而非返回 null;
59
+ * 与 resolveLocalPackageRoot 的差异:后者保留 null 返回值供降级视图使用;
60
+ * 与 resolveLocalRunScope 的差异:后者在工程清单损坏时降级为链接包视图而非报错,语义不同不并入。
61
+ */
62
+ /** requirePackageRoot 的返回视图(未请求加载工程配置时仅含根目录)。 */
63
+ export interface PackageRootScope {
64
+ /** 目标包根目录 */
65
+ root: string;
66
+ }
67
+ /** requirePackageRoot 的返回视图(loadConfig 为真时附带非空工程配置)。 */
68
+ export interface PackageRootWithConfigScope {
69
+ /** 目标包根目录 */
70
+ root: string;
71
+ /** 目标工程配置(仅在 loadConfig 为真时返回,值恒存在) */
72
+ projConfig: ReturnType<typeof loadProjectConfig>;
73
+ }
74
+ /**
75
+ * 解析目标包根目录(重载入口:loadConfig 为真时一并返回工程配置)。
76
+ *
77
+ * @param packageOption 显式指定的包标识或路径(对应 -P, --package)
78
+ * @param options 可选项:loadConfig 请求加载工程配置;hint 覆盖无工程时的补救提示行
79
+ */
80
+ export declare function requirePackageRoot(packageOption: string | undefined, options: {
81
+ loadConfig: true;
82
+ hint?: string;
83
+ }): PackageRootWithConfigScope;
84
+ export declare function requirePackageRoot(packageOption: string | undefined, options?: {
85
+ loadConfig?: false;
86
+ hint?: string;
87
+ }): PackageRootScope;
88
+ /**
89
+ * 依赖类命令(ad add / ad remove)的工程根目录与清单解析脚手架(单一事实源)。
90
+ *
91
+ * 与 requirePackageRoot 的差异:-P 语义为工程目录路径而非包标识,
92
+ * 显式路径不做注册表寻址(不抛 packageNotFoundError,缺失清单由后续存在性检查报错)。
93
+ *
94
+ * @param packageOption 显式指定的工程目录路径(对应 -P, --package <path>)
95
+ * @returns 工程根目录与已验存的 actiondock.json 清单
96
+ */
97
+ export declare function requireProjectManifestRoot(packageOption: string | undefined): {
98
+ root: string;
99
+ manifest: ActionDockManifest;
100
+ };
101
+ /**
102
+ * 依赖事务失败回滚辅助(ad add / ad remove 共享):回滚事务后按统一规则透传异常。
103
+ *
104
+ * 回滚与包裹规则:
105
+ * - 先执行事务回滚快照,保留原始磁盘状态;
106
+ * - ActionDockError 与 CliError 原样透传(保留 code 与 details);
107
+ * - 其余包裹为 ExecutionError 并保留原始 code,缺省时回退 fallbackCode。
108
+ *
109
+ * @param tx 已开启的工程事务快照
110
+ * @param err 业务回调抛出的原始异常
111
+ * @param fallbackCode 包裹分支缺省错误码(命令专属,如 ADD_DEPENDENCY_FAILED)
112
+ */
113
+ export declare function rollbackAndRethrow(tx: ProjectTransaction, err: unknown, fallbackCode: string): Promise<never>;
22
114
  /**
23
115
  * 聚合命令自身选项与根程序全局选项(如 --json、--data-dir 等)。
24
116
  */
25
117
  export declare function getEffectiveOptions(rawOptions: any, cmd?: any): any;
26
118
  /**
27
119
  * 解析意图过滤回退策略。
28
- * 机器输出模式(--json)仅在显式传 --fallback 时回退,
120
+ *
121
+ * 统一事实源:机器输出模式(--json)仅在显式传 --fallback 时回退,
29
122
  * 人类交互模式默认回退(可被 --no-fallback 关闭)。
123
+ *
124
+ * 回退标志的显式性判定完全依据 Commander 解析结果(由调用方传入):
125
+ * 同时注册 --fallback 与 --no-fallback 的命令,未指定时 fallback 为
126
+ * undefined、显式 --fallback 为 true、--no-fallback 为 false,
127
+ * 不再直读 process.argv,消除隐藏的全局依赖。
128
+ *
129
+ * @param options 命令选项视图(含 fallback 与 json 字段)
30
130
  */
31
131
  export declare function resolveFallbackStrategy(options: {
32
132
  fallback?: boolean;
@@ -1,5 +1,36 @@
1
- import { resolvePackageRoot, findProjectRoot } from "@actiondock/core";
2
- import { ArgumentError, notInProjectError, packageNotFoundError } from "../errors.js";
1
+ import { resolvePackageRoot, } from "@actiondock/core/registry";
2
+ import { findProjectRoot, loadProjectConfig, } from "@actiondock/core";
3
+ import { loadManifest, } from "@actiondock/core/project";
4
+ import { resolve } from "node:path";
5
+ import { ArgumentError, ExecutionError, notInProjectError, packageNotFoundError, wrapAsExecutionError } from "../errors.js";
6
+ /**
7
+ * 「未显式指定包且当前目录无工程」的统一补救提示(单一事实源)。
8
+ */
9
+ export const PACKAGE_HINT_MESSAGE = "Please specify -P, --package <id> or cd into a project directory.";
10
+ /**
11
+ * 拼接远端目标标题后缀(单一事实源)。
12
+ *
13
+ * 形如 `on remote server <url> (Profile: <name>)`,供列表类命令的
14
+ * 标题拼接复用(如 `Actions ${remoteTargetSuffix(target)}`),
15
+ * 消除五处同构模板漂移。
16
+ *
17
+ * @param resolved 目标拓扑解析结果(远端分支)
18
+ */
19
+ export function remoteTargetSuffix(resolved) {
20
+ const profile = resolved.profileName ? ` (Profile: ${resolved.profileName})` : "";
21
+ return `on remote server ${resolved.serverUrl}${profile}`;
22
+ }
23
+ /**
24
+ * 拼接远端目标标题标签(单一事实源)。
25
+ *
26
+ * 形如 `Remote Server <url> (Profile: <name>)`,与 remoteTargetSuffix 共享
27
+ * 同一拼接实现,供 state、config 等直接以远端目标为标题主体的命令复用。
28
+ *
29
+ * @param resolved 目标拓扑解析结果(远端分支)
30
+ */
31
+ export function remoteTargetLabel(resolved) {
32
+ return `Remote Server ${resolved.serverUrl}${resolved.profileName ? ` (Profile: ${resolved.profileName})` : ""}`;
33
+ }
3
34
  /**
4
35
  * 解析意图字符串(从显式 --intent 或位置模式参数聚合)。
5
36
  * 多个关键字使用 '|'(正则逻辑或)连接。
@@ -81,11 +112,64 @@ export function getTargetRoot(packageOption, keyHint) {
81
112
  throw packageNotFoundError(targetPackage);
82
113
  }
83
114
  else {
84
- throw notInProjectError("Please specify -P, --package <id> or cd into a project directory.");
115
+ throw notInProjectError(PACKAGE_HINT_MESSAGE);
85
116
  }
86
117
  }
87
118
  return { root, key: effectiveKey };
88
119
  }
120
+ export function requirePackageRoot(packageOption, options) {
121
+ const root = packageOption ? resolvePackageRoot(packageOption) : findProjectRoot();
122
+ if (!root) {
123
+ if (packageOption) {
124
+ throw packageNotFoundError(packageOption);
125
+ }
126
+ throw notInProjectError(options?.hint ?? PACKAGE_HINT_MESSAGE);
127
+ }
128
+ return options?.loadConfig
129
+ ? { root, projConfig: loadProjectConfig(root) }
130
+ : { root };
131
+ }
132
+ /**
133
+ * 依赖类命令(ad add / ad remove)的工程根目录与清单解析脚手架(单一事实源)。
134
+ *
135
+ * 与 requirePackageRoot 的差异:-P 语义为工程目录路径而非包标识,
136
+ * 显式路径不做注册表寻址(不抛 packageNotFoundError,缺失清单由后续存在性检查报错)。
137
+ *
138
+ * @param packageOption 显式指定的工程目录路径(对应 -P, --package <path>)
139
+ * @returns 工程根目录与已验存的 actiondock.json 清单
140
+ */
141
+ export function requireProjectManifestRoot(packageOption) {
142
+ const root = packageOption ? resolve(packageOption) : findProjectRoot();
143
+ if (!root) {
144
+ throw notInProjectError("Please specify -P, --package <path> or cd into a project directory.");
145
+ }
146
+ const manifest = loadManifest(root);
147
+ if (!manifest) {
148
+ throw new ArgumentError(`actiondock.json not found in ${root}`);
149
+ }
150
+ return { root, manifest };
151
+ }
152
+ /**
153
+ * 依赖事务失败回滚辅助(ad add / ad remove 共享):回滚事务后按统一规则透传异常。
154
+ *
155
+ * 回滚与包裹规则:
156
+ * - 先执行事务回滚快照,保留原始磁盘状态;
157
+ * - ActionDockError 与 CliError 原样透传(保留 code 与 details);
158
+ * - 其余包裹为 ExecutionError 并保留原始 code,缺省时回退 fallbackCode。
159
+ *
160
+ * @param tx 已开启的工程事务快照
161
+ * @param err 业务回调抛出的原始异常
162
+ * @param fallbackCode 包裹分支缺省错误码(命令专属,如 ADD_DEPENDENCY_FAILED)
163
+ */
164
+ export async function rollbackAndRethrow(tx, err, fallbackCode) {
165
+ await tx.rollback({ frozenInstall: false });
166
+ const passthrough = wrapAsExecutionError(err);
167
+ if (passthrough !== err) {
168
+ const original = err;
169
+ throw new ExecutionError(original.message, err, original.code || fallbackCode);
170
+ }
171
+ throw passthrough;
172
+ }
89
173
  /**
90
174
  * 聚合命令自身选项与根程序全局选项(如 --json、--data-dir 等)。
91
175
  */
@@ -97,15 +181,21 @@ export function getEffectiveOptions(rawOptions, cmd) {
97
181
  }
98
182
  /**
99
183
  * 解析意图过滤回退策略。
100
- * 机器输出模式(--json)仅在显式传 --fallback 时回退,
184
+ *
185
+ * 统一事实源:机器输出模式(--json)仅在显式传 --fallback 时回退,
101
186
  * 人类交互模式默认回退(可被 --no-fallback 关闭)。
187
+ *
188
+ * 回退标志的显式性判定完全依据 Commander 解析结果(由调用方传入):
189
+ * 同时注册 --fallback 与 --no-fallback 的命令,未指定时 fallback 为
190
+ * undefined、显式 --fallback 为 true、--no-fallback 为 false,
191
+ * 不再直读 process.argv,消除隐藏的全局依赖。
192
+ *
193
+ * @param options 命令选项视图(含 fallback 与 json 字段)
102
194
  */
103
195
  export function resolveFallbackStrategy(options) {
104
196
  const isMachine = Boolean(options.json);
105
- const fallbackExplicit = options.fallback === true ||
106
- (Array.isArray(process.argv) && process.argv.includes("--fallback"));
107
197
  return {
108
198
  isMachine,
109
- shouldFallback: isMachine ? fallbackExplicit : options.fallback !== false,
199
+ shouldFallback: isMachine ? options.fallback === true : options.fallback !== false,
110
200
  };
111
201
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@actiondock/cli",
3
- "version": "2.6.0",
3
+ "version": "2.8.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,10 @@
34
34
  "test": "node ../../scripts/run-tests.ts"
35
35
  },
36
36
  "dependencies": {
37
- "@actiondock/builder": "^2.6.0",
38
- "@actiondock/core": "^2.6.0",
39
- "@actiondock/mcp": "^2.6.0",
40
- "@actiondock/runtime-node": "^2.6.0",
41
- "@actiondock/sdk": "^2.6.0",
37
+ "@actiondock/builder": "^2.8.0",
38
+ "@actiondock/core": "^2.8.0",
39
+ "@actiondock/mcp": "^2.8.0",
40
+ "@actiondock/sdk": "^2.8.0",
42
41
  "commander": "^13.1.0",
43
42
  "selfsigned": "^5.5.0"
44
43
  },
@@ -1 +0,0 @@
1
- export { parseByteSize } from "./utils.js";
@@ -1 +0,0 @@
1
- export { parseByteSize } from "./utils.js";
@@ -1 +0,0 @@
1
- export { resolveIntent } from "./utils.js";
@@ -1 +0,0 @@
1
- export { resolveIntent } from "./utils.js";