@actiondock/cli 2.13.0 → 2.15.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/bin/ad.js +0 -16
- package/dist/commands/config/delete.js +8 -19
- package/dist/commands/config/env.js +3 -2
- package/dist/commands/config/get.js +10 -17
- package/dist/commands/config/list.js +10 -16
- package/dist/commands/config/schema.js +7 -6
- package/dist/commands/config/set.js +12 -34
- package/dist/commands/describe.js +6 -9
- package/dist/commands/info.js +97 -18
- package/dist/commands/list.js +16 -16
- package/dist/commands/playbook.js +148 -105
- package/dist/commands/run.js +7 -20
- package/dist/commands/state.js +19 -2
- package/dist/renderers/project.d.ts +4 -0
- package/dist/renderers/project.js +16 -0
- package/dist/services/inspect.d.ts +14 -1
- package/dist/services/inspect.js +54 -12
- package/dist/utils/index.d.ts +0 -1
- package/dist/utils/index.js +0 -1
- package/dist/utils/target.d.ts +94 -4
- package/dist/utils/target.js +304 -26
- package/package.json +5 -5
- package/dist/utils/warning.d.ts +0 -4
- package/dist/utils/warning.js +0 -4
package/dist/utils/target.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { type ActionDockService } from "@actiondock/core";
|
|
1
|
+
import { loadProjectConfig, type ActionDockService, type LocalSkillDirectory } from "@actiondock/core";
|
|
2
2
|
import { type ResolvedTarget } from "@actiondock/core/profile";
|
|
3
|
+
import { type PackageGraph } from "@actiondock/core/graph";
|
|
3
4
|
import type { Command } from "commander";
|
|
4
5
|
import type { CliContext } from "../types.js";
|
|
5
6
|
/**
|
|
@@ -30,17 +31,106 @@ export interface TargetResolutionOptions {
|
|
|
30
31
|
/** 是否允许向非回环地址发送明文 HTTP 请求(对应 --allow-insecure-http) */
|
|
31
32
|
allowInsecureHttp?: boolean;
|
|
32
33
|
}
|
|
34
|
+
/** 仅供清单查询使用的内部解析策略;执行命令默认保持封闭校验。 */
|
|
35
|
+
export interface TargetResolutionStrategy {
|
|
36
|
+
readonly metadataOnly?: boolean;
|
|
37
|
+
}
|
|
33
38
|
/**
|
|
34
39
|
* 目标拓扑解析单一入口:从命令选项视图解析远端/本地目标拓扑信息。
|
|
35
40
|
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
41
|
+
* 显式路径与包标识符分类规则:
|
|
42
|
+
* - 显式路径形态(以 .、/、~ 开头或包含非 scoped 分隔符):
|
|
43
|
+
* 严格作为本地技能或包目录解析;禁止与显式远端选项(--server 或非 local 的 --profile)组合,违规抛出 ArgumentError;
|
|
44
|
+
* 不受隐式 Profile 或 ACTIONDOCK_SERVER_URL 环境变量改变目标,本地执行优先;
|
|
45
|
+
* 若本地目录不存在或不合法,抛出 packageNotFoundError;
|
|
46
|
+
* - 纯词法包标识符(如 pkg.a、@scope/pkg):
|
|
47
|
+
* 若存在远端目标(显式 --server、非 local profile 或默认远端环境),严格作为远端包标识解析,绝不因本地 cwd 存在同名目录而劫持为本地执行;
|
|
48
|
+
* 若无远端目标,正常按本地目标解析。
|
|
38
49
|
*
|
|
39
50
|
* @param options 命令选项视图(支持直接传入 Commander 解析后的 options 对象)
|
|
40
51
|
* @param context CLI 上下文
|
|
52
|
+
* @param strategy 内部解析策略;仅清单查询可跳过单包闭包校验
|
|
41
53
|
* @returns 解析后的目标拓扑信息(仅信息解析,不创建 Service 实例)
|
|
42
54
|
*/
|
|
43
|
-
export declare function resolveTargetFromOptions(options: TargetResolutionOptions, context?: CliContext): ResolvedTarget;
|
|
55
|
+
export declare function resolveTargetFromOptions(options: TargetResolutionOptions, context?: CliContext, strategy?: TargetResolutionStrategy): ResolvedTarget;
|
|
56
|
+
/**
|
|
57
|
+
* 统一计算目标资源引用(Action 或 Playbook)的辅助函数(单一事实源)。
|
|
58
|
+
*
|
|
59
|
+
* 规则:
|
|
60
|
+
* - 远端分支:options.package 存在且资源标识未限定时,前缀拼接 options.package;
|
|
61
|
+
* - 本地单包技能:资源标识未限定时,前缀拼接真实 packageId(而非路径目录名);
|
|
62
|
+
* - 本地复合技能:保持短名,供后续图解析裁决唯一匹配或多包歧义;完全限定名直接透传;
|
|
63
|
+
* - 普通工程包:非技能且 options.package 存在时,未限定则拼接 options.package。
|
|
64
|
+
*
|
|
65
|
+
* @param resourceId 资源标识符(动作名或规程名)
|
|
66
|
+
* @param options 命令选项视图
|
|
67
|
+
* @param localSkill 本地技能目录视图
|
|
68
|
+
*/
|
|
69
|
+
export declare function resolveResourceRef(resourceId: string, options: TargetResolutionOptions, localSkill?: LocalSkillDirectory | null): string;
|
|
70
|
+
/**
|
|
71
|
+
* 统一计算目标 Playbook 引用的辅助函数。
|
|
72
|
+
*/
|
|
73
|
+
export declare function resolvePlaybookRef(playbookId: string, options: TargetResolutionOptions, localSkill?: LocalSkillDirectory | null): string;
|
|
74
|
+
/**
|
|
75
|
+
* 构造与目标作用域严格对应的 PackageGraph(单一事实源)。
|
|
76
|
+
*
|
|
77
|
+
* 封闭保证:
|
|
78
|
+
* - 当目标为 LocalSkillDirectory 时,仅以 localSkill.packages 显式包集合构建封闭图;
|
|
79
|
+
* 绝不扫描 cwd 也不扫描全局 Registry/开发软链,防止外部同名包或污染泄漏;
|
|
80
|
+
* - 当目标为普通本地工程或包 ID 时,维持原有的基于项目根与全局链接表的拓扑图构建模式。
|
|
81
|
+
*/
|
|
82
|
+
export declare function buildScopedPackageGraph(target: CommandTargetResolution, context?: CliContext): PackageGraph;
|
|
83
|
+
/**
|
|
84
|
+
* 命令目标与动作引用解析结果。
|
|
85
|
+
*/
|
|
86
|
+
export interface CommandTargetResolution {
|
|
87
|
+
/** 目标拓扑信息 */
|
|
88
|
+
resolved: ResolvedTarget;
|
|
89
|
+
/** 是否为远端目标 */
|
|
90
|
+
isRemote: boolean;
|
|
91
|
+
/** 本地技能目录或单包元数据作用域(未寻址本地包时为 null) */
|
|
92
|
+
localSkill: LocalSkillDirectory | null;
|
|
93
|
+
/** 本地包根目录路径(远端分支为 undefined,未找到为 undefined) */
|
|
94
|
+
targetPackageRoot?: string;
|
|
95
|
+
/** 统一计算目标 Action 引用的辅助函数 */
|
|
96
|
+
resolveActionRef: (actionId: string) => string;
|
|
97
|
+
/** 统一计算目标 Playbook 引用的辅助函数 */
|
|
98
|
+
resolvePlaybookRef: (playbookId: string) => string;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* 统一解析 CLI 命令的目标拓扑与包作用域(run, describe, list 等命令的单一事实源)。
|
|
102
|
+
*
|
|
103
|
+
* 保证:
|
|
104
|
+
* - 优先判定目标拓扑;
|
|
105
|
+
* - 远端目标(remote)完全隔离:不执行任何本地目录探测、清单加载或包根寻址;
|
|
106
|
+
* - 远端目标动作与规程引用保持原始词法包 ID 拼接(${options.package}/${id}),绝不被本地同名目录或清单 ID 篡改;
|
|
107
|
+
* - 本地目标默认按封闭技能目录或工程包严格解析;元数据策略仅跳过单包闭包校验;
|
|
108
|
+
* - 显式目标不存在时透明抛出 packageNotFoundError。
|
|
109
|
+
*/
|
|
110
|
+
export declare function resolveCommandTarget(options: TargetResolutionOptions, context?: CliContext, strategy?: TargetResolutionStrategy): CommandTargetResolution;
|
|
111
|
+
/**
|
|
112
|
+
* 配置与状态管理目标作用域。
|
|
113
|
+
*/
|
|
114
|
+
export interface TargetPackageScope {
|
|
115
|
+
/** 解析后的目标拓扑 */
|
|
116
|
+
resolved: ResolvedTarget;
|
|
117
|
+
/** 是否为远端目标 */
|
|
118
|
+
isRemote: boolean;
|
|
119
|
+
/** 目标包标识(远端为 options.package 原值,本地为工程配置 id 或 "global") */
|
|
120
|
+
packageId: string;
|
|
121
|
+
/** 本地工程根目录(远端分支为 undefined) */
|
|
122
|
+
root?: string;
|
|
123
|
+
/** 本地工程配置(远端分支为 undefined) */
|
|
124
|
+
projConfig?: ReturnType<typeof loadProjectConfig>;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* 校验并拒绝复合技能目录用于配置或状态管理命令(单一事实源)。
|
|
128
|
+
*/
|
|
129
|
+
export declare function assertNotCompositeSkill(packageOption?: string): void;
|
|
130
|
+
/**
|
|
131
|
+
* 统一解析配置与状态命令的目标作用域(支持单包技能目录、本地工程、远端服务与 --profile local)。
|
|
132
|
+
*/
|
|
133
|
+
export declare function resolveTargetPackageScope(options: TargetResolutionOptions, context?: CliContext): TargetPackageScope;
|
|
44
134
|
/**
|
|
45
135
|
* 高阶服务执行辅助:统一封装「目标解析 → Service 创建 → 业务回调 → try/finally close」样板。
|
|
46
136
|
*
|
package/dist/utils/target.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { connectActionDock, createActionDock, createNodePlatform, findProjectRoot, } from "@actiondock/core";
|
|
1
|
+
import { connectActionDock, createActionDock, createNodePlatform, findProjectRoot, inspectLocalPackageDirectory, isExplicitPath, loadProjectConfig, queryLocalPackageDirectory, } from "@actiondock/core";
|
|
2
2
|
import { resolvePackageRoot, } from "@actiondock/core/registry";
|
|
3
3
|
import { resolveTarget, } from "@actiondock/core/profile";
|
|
4
|
-
import {
|
|
4
|
+
import { PackageGraphBuilder, } from "@actiondock/core/graph";
|
|
5
|
+
import { ArgumentError, packageNotFoundError } from "../errors.js";
|
|
5
6
|
/**
|
|
6
7
|
* 统一为 Commander 命令节点挂载目标环境解析相关选项(单一事实源)。
|
|
7
8
|
* 包括:-p/--profile, -s/--server, -t/--token, -k/--insecure, --allow-insecure-http。
|
|
@@ -17,24 +18,276 @@ export function applyTargetOptions(command) {
|
|
|
17
18
|
.option("-k, --insecure", "Allow insecure server connections (skip TLS certificate validation)")
|
|
18
19
|
.option("--allow-insecure-http", "Allow sending auth token over unencrypted HTTP to non-loopback hosts");
|
|
19
20
|
}
|
|
21
|
+
/** 本地寻址策略只有一个实现入口,查询与严格闭包均委托核心目录能力。 */
|
|
22
|
+
function inspectCommandDirectory(packageOption, context, strategy) {
|
|
23
|
+
if (!strategy?.metadataOnly)
|
|
24
|
+
return inspectLocalPackageDirectory(packageOption);
|
|
25
|
+
const directory = queryLocalPackageDirectory(packageOption);
|
|
26
|
+
if (directory)
|
|
27
|
+
return directory;
|
|
28
|
+
const root = resolvePackageRoot(packageOption, undefined, context?.customHome);
|
|
29
|
+
return root ? queryLocalPackageDirectory(root) : null;
|
|
30
|
+
}
|
|
20
31
|
/**
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
* 收拢全部解析字段(profile/server/token/insecure/allowInsecureHttp),
|
|
24
|
-
* 消除命令间逐字段内联复制导致的漂移(如漏传 allowInsecureHttp)。
|
|
25
|
-
*
|
|
26
|
-
* @param options 命令选项视图(支持直接传入 Commander 解析后的 options 对象)
|
|
27
|
-
* @param context CLI 上下文
|
|
28
|
-
* @returns 解析后的目标拓扑信息(仅信息解析,不创建 Service 实例)
|
|
32
|
+
* 内部统一解析目标拓扑与包作用域,单次调用闭包完成全部发现,无跨调用缓存。
|
|
29
33
|
*/
|
|
30
|
-
|
|
31
|
-
|
|
34
|
+
function resolveCommandTargetInternal(options, context, strategy) {
|
|
35
|
+
const isExplicit = options.package ? isExplicitPath(options.package) : false;
|
|
36
|
+
if (isExplicit) {
|
|
37
|
+
const hasExplicitServer = Boolean(options.server && options.server.trim());
|
|
38
|
+
const hasExplicitProfile = Boolean(options.profile && options.profile.trim() && options.profile.trim() !== "local");
|
|
39
|
+
if (hasExplicitServer || hasExplicitProfile) {
|
|
40
|
+
throw new ArgumentError("Cannot combine local package/skill directory with remote target options (--server or --profile). Specify a package ID for remote targets, or remove remote target options for local directory execution.");
|
|
41
|
+
}
|
|
42
|
+
const localSkill = inspectCommandDirectory(options.package, context, strategy);
|
|
43
|
+
if (!localSkill) {
|
|
44
|
+
throw packageNotFoundError(options.package);
|
|
45
|
+
}
|
|
46
|
+
return {
|
|
47
|
+
resolved: {
|
|
48
|
+
type: "local",
|
|
49
|
+
profileName: "local",
|
|
50
|
+
},
|
|
51
|
+
localSkill,
|
|
52
|
+
targetPackageRoot: localSkill.root,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
const resolved = resolveTarget({
|
|
32
56
|
profile: options.profile,
|
|
33
57
|
server: options.server,
|
|
34
58
|
token: options.token,
|
|
35
59
|
insecure: options.insecure,
|
|
36
60
|
allowInsecureHttp: options.allowInsecureHttp,
|
|
37
61
|
}, context?.customHome);
|
|
62
|
+
if (resolved.type === "remote") {
|
|
63
|
+
return {
|
|
64
|
+
resolved,
|
|
65
|
+
localSkill: null,
|
|
66
|
+
targetPackageRoot: undefined,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
// 本地分支(options.package 为短名或未传)
|
|
70
|
+
if (options.package) {
|
|
71
|
+
const localSkill = inspectCommandDirectory(options.package, context, strategy);
|
|
72
|
+
const targetPackageRoot = localSkill
|
|
73
|
+
? localSkill.root
|
|
74
|
+
: strategy?.metadataOnly
|
|
75
|
+
? resolvePackageRoot(options.package, undefined, context?.customHome)
|
|
76
|
+
: resolveLocalPackageRoot(options.package);
|
|
77
|
+
if (!targetPackageRoot) {
|
|
78
|
+
throw packageNotFoundError(options.package);
|
|
79
|
+
}
|
|
80
|
+
return {
|
|
81
|
+
resolved,
|
|
82
|
+
localSkill,
|
|
83
|
+
targetPackageRoot,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
const projectRoot = findProjectRoot();
|
|
87
|
+
return {
|
|
88
|
+
resolved,
|
|
89
|
+
localSkill: null,
|
|
90
|
+
targetPackageRoot: projectRoot || undefined,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* 目标拓扑解析单一入口:从命令选项视图解析远端/本地目标拓扑信息。
|
|
95
|
+
*
|
|
96
|
+
* 显式路径与包标识符分类规则:
|
|
97
|
+
* - 显式路径形态(以 .、/、~ 开头或包含非 scoped 分隔符):
|
|
98
|
+
* 严格作为本地技能或包目录解析;禁止与显式远端选项(--server 或非 local 的 --profile)组合,违规抛出 ArgumentError;
|
|
99
|
+
* 不受隐式 Profile 或 ACTIONDOCK_SERVER_URL 环境变量改变目标,本地执行优先;
|
|
100
|
+
* 若本地目录不存在或不合法,抛出 packageNotFoundError;
|
|
101
|
+
* - 纯词法包标识符(如 pkg.a、@scope/pkg):
|
|
102
|
+
* 若存在远端目标(显式 --server、非 local profile 或默认远端环境),严格作为远端包标识解析,绝不因本地 cwd 存在同名目录而劫持为本地执行;
|
|
103
|
+
* 若无远端目标,正常按本地目标解析。
|
|
104
|
+
*
|
|
105
|
+
* @param options 命令选项视图(支持直接传入 Commander 解析后的 options 对象)
|
|
106
|
+
* @param context CLI 上下文
|
|
107
|
+
* @param strategy 内部解析策略;仅清单查询可跳过单包闭包校验
|
|
108
|
+
* @returns 解析后的目标拓扑信息(仅信息解析,不创建 Service 实例)
|
|
109
|
+
*/
|
|
110
|
+
export function resolveTargetFromOptions(options, context, strategy) {
|
|
111
|
+
return resolveCommandTargetInternal(options, context, strategy).resolved;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* 统一计算目标资源引用(Action 或 Playbook)的辅助函数(单一事实源)。
|
|
115
|
+
*
|
|
116
|
+
* 规则:
|
|
117
|
+
* - 远端分支:options.package 存在且资源标识未限定时,前缀拼接 options.package;
|
|
118
|
+
* - 本地单包技能:资源标识未限定时,前缀拼接真实 packageId(而非路径目录名);
|
|
119
|
+
* - 本地复合技能:保持短名,供后续图解析裁决唯一匹配或多包歧义;完全限定名直接透传;
|
|
120
|
+
* - 普通工程包:非技能且 options.package 存在时,未限定则拼接 options.package。
|
|
121
|
+
*
|
|
122
|
+
* @param resourceId 资源标识符(动作名或规程名)
|
|
123
|
+
* @param options 命令选项视图
|
|
124
|
+
* @param localSkill 本地技能目录视图
|
|
125
|
+
*/
|
|
126
|
+
export function resolveResourceRef(resourceId, options, localSkill) {
|
|
127
|
+
if (!options.package)
|
|
128
|
+
return resourceId;
|
|
129
|
+
if (localSkill) {
|
|
130
|
+
if (localSkill.type === "single" && !resourceId.includes("/")) {
|
|
131
|
+
return `${localSkill.packages[0].packageId}/${resourceId}`;
|
|
132
|
+
}
|
|
133
|
+
// 复合技能短名不拼目录名,保持 resourceId 供后续裁决唯一匹配或多包歧义
|
|
134
|
+
return resourceId;
|
|
135
|
+
}
|
|
136
|
+
if (!resourceId.includes("/")) {
|
|
137
|
+
return `${options.package}/${resourceId}`;
|
|
138
|
+
}
|
|
139
|
+
return resourceId;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* 统一计算目标 Playbook 引用的辅助函数。
|
|
143
|
+
*/
|
|
144
|
+
export function resolvePlaybookRef(playbookId, options, localSkill) {
|
|
145
|
+
return resolveResourceRef(playbookId, options, localSkill);
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* 构造与目标作用域严格对应的 PackageGraph(单一事实源)。
|
|
149
|
+
*
|
|
150
|
+
* 封闭保证:
|
|
151
|
+
* - 当目标为 LocalSkillDirectory 时,仅以 localSkill.packages 显式包集合构建封闭图;
|
|
152
|
+
* 绝不扫描 cwd 也不扫描全局 Registry/开发软链,防止外部同名包或污染泄漏;
|
|
153
|
+
* - 当目标为普通本地工程或包 ID 时,维持原有的基于项目根与全局链接表的拓扑图构建模式。
|
|
154
|
+
*/
|
|
155
|
+
export function buildScopedPackageGraph(target, context) {
|
|
156
|
+
if (target.localSkill) {
|
|
157
|
+
const isSingle = target.localSkill.type === "single";
|
|
158
|
+
const discovered = target.localSkill.packages.map((pkg) => ({
|
|
159
|
+
id: pkg.packageId,
|
|
160
|
+
root: pkg.packageRoot,
|
|
161
|
+
manifest: pkg.projectConfig,
|
|
162
|
+
isCurrentProject: isSingle,
|
|
163
|
+
}));
|
|
164
|
+
return new PackageGraphBuilder({
|
|
165
|
+
packages: discovered,
|
|
166
|
+
root: isSingle ? target.localSkill.packages[0].packageId : undefined,
|
|
167
|
+
}).buildSync();
|
|
168
|
+
}
|
|
169
|
+
return new PackageGraphBuilder({
|
|
170
|
+
root: target.targetPackageRoot,
|
|
171
|
+
customHome: context?.customHome,
|
|
172
|
+
allowDevLinks: true,
|
|
173
|
+
}).buildSync();
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* 统一解析 CLI 命令的目标拓扑与包作用域(run, describe, list 等命令的单一事实源)。
|
|
177
|
+
*
|
|
178
|
+
* 保证:
|
|
179
|
+
* - 优先判定目标拓扑;
|
|
180
|
+
* - 远端目标(remote)完全隔离:不执行任何本地目录探测、清单加载或包根寻址;
|
|
181
|
+
* - 远端目标动作与规程引用保持原始词法包 ID 拼接(${options.package}/${id}),绝不被本地同名目录或清单 ID 篡改;
|
|
182
|
+
* - 本地目标默认按封闭技能目录或工程包严格解析;元数据策略仅跳过单包闭包校验;
|
|
183
|
+
* - 显式目标不存在时透明抛出 packageNotFoundError。
|
|
184
|
+
*/
|
|
185
|
+
export function resolveCommandTarget(options, context, strategy) {
|
|
186
|
+
const result = resolveCommandTargetInternal(options, context, strategy);
|
|
187
|
+
if (result.resolved.type === "remote") {
|
|
188
|
+
const resolveRemoteRef = (id) => {
|
|
189
|
+
if (options.package && !id.includes("/")) {
|
|
190
|
+
return `${options.package}/${id}`;
|
|
191
|
+
}
|
|
192
|
+
return id;
|
|
193
|
+
};
|
|
194
|
+
return {
|
|
195
|
+
resolved: result.resolved,
|
|
196
|
+
isRemote: true,
|
|
197
|
+
localSkill: null,
|
|
198
|
+
targetPackageRoot: undefined,
|
|
199
|
+
resolveActionRef: resolveRemoteRef,
|
|
200
|
+
resolvePlaybookRef: resolveRemoteRef,
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
return {
|
|
204
|
+
resolved: result.resolved,
|
|
205
|
+
isRemote: false,
|
|
206
|
+
localSkill: result.localSkill,
|
|
207
|
+
targetPackageRoot: result.targetPackageRoot,
|
|
208
|
+
resolveActionRef: (actionId) => resolveResourceRef(actionId, options, result.localSkill),
|
|
209
|
+
resolvePlaybookRef: (playbookId) => resolvePlaybookRef(playbookId, options, result.localSkill),
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* 校验并拒绝复合技能目录用于配置或状态管理命令(单一事实源)。
|
|
214
|
+
*/
|
|
215
|
+
export function assertNotCompositeSkill(packageOption) {
|
|
216
|
+
if (!packageOption)
|
|
217
|
+
return;
|
|
218
|
+
const localSkill = inspectLocalPackageDirectory(packageOption);
|
|
219
|
+
if (localSkill?.type === "composite") {
|
|
220
|
+
throw new ArgumentError("Multi-package entries do not support config/state management; configure actions using --config and --data-dir.");
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* 统一解析配置与状态命令的目标作用域(支持单包技能目录、本地工程、远端服务与 --profile local)。
|
|
225
|
+
*/
|
|
226
|
+
export function resolveTargetPackageScope(options, context) {
|
|
227
|
+
// 1. 目标拓扑解析
|
|
228
|
+
const resolved = resolveTargetFromOptions(options, context);
|
|
229
|
+
// 2. 远端分支:直接消费 options.package,不触碰本地文件系统
|
|
230
|
+
if (resolved.type === "remote") {
|
|
231
|
+
return {
|
|
232
|
+
resolved,
|
|
233
|
+
isRemote: true,
|
|
234
|
+
packageId: options.package || "",
|
|
235
|
+
root: undefined,
|
|
236
|
+
projConfig: undefined,
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
// 3. 复合技能目录守卫(单一事实源)仅在本地分支生效
|
|
240
|
+
assertNotCompositeSkill(options.package);
|
|
241
|
+
// 4. 本地分支:统一解析单包目录、工程包或全局作用域
|
|
242
|
+
if (options.package) {
|
|
243
|
+
const localSkill = inspectLocalPackageDirectory(options.package);
|
|
244
|
+
if (localSkill?.type === "single") {
|
|
245
|
+
const pkg = localSkill.packages[0];
|
|
246
|
+
return {
|
|
247
|
+
resolved,
|
|
248
|
+
isRemote: false,
|
|
249
|
+
packageId: pkg.packageId,
|
|
250
|
+
root: pkg.packageRoot,
|
|
251
|
+
projConfig: pkg.projectConfig,
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
const root = resolveLocalPackageRoot(options.package);
|
|
255
|
+
if (!root) {
|
|
256
|
+
throw packageNotFoundError(options.package);
|
|
257
|
+
}
|
|
258
|
+
const projConfig = loadProjectConfig(root);
|
|
259
|
+
return {
|
|
260
|
+
resolved,
|
|
261
|
+
isRemote: false,
|
|
262
|
+
packageId: projConfig.id,
|
|
263
|
+
root,
|
|
264
|
+
projConfig,
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
// 未指定 -P:当前目录工程探测
|
|
268
|
+
const root = findProjectRoot();
|
|
269
|
+
if (root) {
|
|
270
|
+
try {
|
|
271
|
+
const projConfig = loadProjectConfig(root);
|
|
272
|
+
return {
|
|
273
|
+
resolved,
|
|
274
|
+
isRemote: false,
|
|
275
|
+
packageId: projConfig.id,
|
|
276
|
+
root,
|
|
277
|
+
projConfig,
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
catch {
|
|
281
|
+
// 当前目录配置损坏时仍允许全局操作
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
return {
|
|
285
|
+
resolved,
|
|
286
|
+
isRemote: false,
|
|
287
|
+
packageId: "global",
|
|
288
|
+
root: undefined,
|
|
289
|
+
projConfig: undefined,
|
|
290
|
+
};
|
|
38
291
|
}
|
|
39
292
|
/**
|
|
40
293
|
* 高阶服务执行辅助:统一封装「目标解析 → Service 创建 → 业务回调 → try/finally close」样板。
|
|
@@ -56,10 +309,13 @@ export async function withService(options, context, fn, localOptions) {
|
|
|
56
309
|
if (localOptions?.requireRemote && resolved.type === "local") {
|
|
57
310
|
throw new ArgumentError("'ad runs cancel' is only supported for remote execution targets. Use --profile <name> or --server <url>.");
|
|
58
311
|
}
|
|
312
|
+
const localSkill = resolved.type === "local" && options.package
|
|
313
|
+
? inspectLocalPackageDirectory(options.package)
|
|
314
|
+
: null;
|
|
59
315
|
// localRoot 仅在 local 分支求值,避免远端模式下触发包寻址副作用
|
|
60
|
-
const localRoot = resolved.type === "local"
|
|
316
|
+
const localRoot = resolved.type === "local" && !localSkill
|
|
61
317
|
? (typeof localOptions?.localRoot === "function" ? localOptions.localRoot() : localOptions?.localRoot) ??
|
|
62
|
-
findProjectRoot() ??
|
|
318
|
+
(options.package ? resolveLocalPackageRoot(options.package) : findProjectRoot()) ??
|
|
63
319
|
undefined
|
|
64
320
|
: undefined;
|
|
65
321
|
const recoverOrphans = localOptions?.recoverOrphans ?? (localOptions?.ownDataDir === true);
|
|
@@ -70,20 +326,38 @@ export async function withService(options, context, fn, localOptions) {
|
|
|
70
326
|
insecure: resolved.insecure,
|
|
71
327
|
allowInsecureHttp: resolved.allowInsecureHttp ?? options.allowInsecureHttp,
|
|
72
328
|
})
|
|
73
|
-
:
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
329
|
+
: localSkill
|
|
330
|
+
? await createActionDock({
|
|
331
|
+
type: "local",
|
|
332
|
+
packages: localSkill.packages.map((pkg) => ({
|
|
333
|
+
packageRoot: pkg.packageRoot,
|
|
334
|
+
projectConfig: pkg.projectConfig,
|
|
335
|
+
dataDir: options.dataDir || context?.dataDir,
|
|
336
|
+
})),
|
|
337
|
+
customHome: context?.customHome,
|
|
338
|
+
dataDir: options.dataDir || context?.dataDir,
|
|
339
|
+
platform: createNodePlatform({
|
|
340
|
+
customHome: context?.customHome,
|
|
341
|
+
dataDir: options.dataDir || context?.dataDir,
|
|
342
|
+
}),
|
|
343
|
+
autoLoadCurrentProject: false,
|
|
344
|
+
scanLinkedPackages: false,
|
|
345
|
+
recoverOrphans,
|
|
346
|
+
})
|
|
347
|
+
: await createActionDock({
|
|
348
|
+
type: "local",
|
|
349
|
+
projectRoot: localRoot,
|
|
79
350
|
customHome: context?.customHome,
|
|
80
351
|
dataDir: options.dataDir || context?.dataDir,
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
352
|
+
platform: createNodePlatform({
|
|
353
|
+
customHome: context?.customHome,
|
|
354
|
+
dataDir: options.dataDir || context?.dataDir,
|
|
355
|
+
}),
|
|
356
|
+
...(localOptions?.scanLinkedPackages !== undefined
|
|
357
|
+
? { scanLinkedPackages: localOptions.scanLinkedPackages }
|
|
358
|
+
: undefined),
|
|
359
|
+
recoverOrphans,
|
|
360
|
+
});
|
|
87
361
|
try {
|
|
88
362
|
await fn(service, resolved);
|
|
89
363
|
}
|
|
@@ -97,6 +371,10 @@ export async function withService(options, context, fn, localOptions) {
|
|
|
97
371
|
*/
|
|
98
372
|
export function resolveLocalPackageRoot(pkgId) {
|
|
99
373
|
if (pkgId) {
|
|
374
|
+
const localSkill = inspectLocalPackageDirectory(pkgId);
|
|
375
|
+
if (localSkill) {
|
|
376
|
+
return localSkill.root;
|
|
377
|
+
}
|
|
100
378
|
return resolvePackageRoot(pkgId);
|
|
101
379
|
}
|
|
102
380
|
return findProjectRoot();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@actiondock/cli",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.15.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,10 +34,10 @@
|
|
|
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/sdk": "^2.
|
|
37
|
+
"@actiondock/builder": "^2.15.0",
|
|
38
|
+
"@actiondock/core": "^2.15.0",
|
|
39
|
+
"@actiondock/mcp": "^2.15.0",
|
|
40
|
+
"@actiondock/sdk": "^2.15.0",
|
|
41
41
|
"commander": "^13.1.0",
|
|
42
42
|
"selfsigned": "^5.5.0"
|
|
43
43
|
},
|
package/dist/utils/warning.d.ts
DELETED
package/dist/utils/warning.js
DELETED