@actiondock/cli 2.9.1 → 2.11.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 +3 -3
- package/bin/ad.js +225 -5
- package/dist/commands/action/create.d.ts +1 -1
- package/dist/commands/action/create.js +6 -14
- package/dist/commands/add.js +1 -1
- package/dist/commands/config/delete.js +3 -1
- package/dist/commands/config/env.js +2 -1
- package/dist/commands/config/get.js +3 -1
- package/dist/commands/config/list.js +6 -5
- package/dist/commands/config/schema.js +16 -10
- package/dist/commands/config/set.js +3 -1
- package/dist/commands/describe.js +6 -4
- package/dist/commands/export.js +34 -16
- package/dist/commands/index.d.ts +37 -24
- package/dist/commands/index.js +346 -48
- package/dist/commands/info.js +34 -9
- package/dist/commands/list.js +13 -2
- package/dist/commands/mcp.js +0 -1
- package/dist/commands/playbook.js +67 -52
- package/dist/commands/profile.js +2 -1
- package/dist/commands/remove.js +1 -1
- package/dist/commands/run.d.ts +2 -1
- package/dist/commands/run.js +19 -56
- package/dist/commands/runs.d.ts +6 -1
- package/dist/commands/runs.js +274 -11
- package/dist/commands/serve.js +5 -2
- package/dist/commands/state.js +84 -15
- package/dist/errors.d.ts +5 -3
- package/dist/errors.js +23 -7
- package/dist/index.d.ts +10 -2
- package/dist/index.js +15 -12
- package/dist/prompt.d.ts +3 -0
- package/dist/prompt.js +6 -14
- package/dist/renderer.d.ts +8 -151
- package/dist/renderer.js +17 -375
- package/dist/renderers/action.d.ts +51 -0
- package/dist/renderers/action.js +112 -0
- package/dist/renderers/config.d.ts +31 -0
- package/dist/renderers/config.js +93 -0
- package/dist/renderers/playbook.d.ts +19 -0
- package/dist/renderers/playbook.js +42 -0
- package/dist/renderers/project.d.ts +45 -0
- package/dist/renderers/project.js +196 -0
- package/dist/renderers/runs.d.ts +15 -0
- package/dist/renderers/runs.js +47 -0
- package/dist/renderers/state.d.ts +4 -0
- package/dist/renderers/state.js +19 -0
- package/dist/services/config-merge.js +1 -2
- package/dist/services/index.d.ts +1 -0
- package/dist/services/index.js +1 -0
- package/dist/services/run-watch.d.ts +156 -0
- package/dist/services/run-watch.js +395 -0
- package/dist/types.d.ts +37 -0
- package/dist/utils/cert.js +1 -1
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.js +1 -1
- package/dist/utils/input.d.ts +2 -1
- package/dist/utils/input.js +2 -1
- package/dist/utils/target.d.ts +6 -2
- package/dist/utils/target.js +4 -4
- package/dist/utils/utils.d.ts +1 -1
- package/dist/utils/utils.js +4 -12
- package/dist/utils/warning.d.ts +4 -0
- package/dist/utils/warning.js +4 -0
- package/package.json +5 -5
- package/dist/commands/state-list.d.ts +0 -24
- package/dist/commands/state-list.js +0 -81
- package/dist/standalone/index.d.ts +0 -12
- package/dist/standalone/index.js +0 -13
- package/dist/utils/duration.d.ts +0 -1
- package/dist/utils/duration.js +0 -1
package/dist/commands/index.js
CHANGED
|
@@ -1,29 +1,6 @@
|
|
|
1
|
-
import { readFileSync } from "node:fs";
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import { Command } from "commander";
|
|
4
|
-
import { registerActionCommands } from "./action/index.js";
|
|
5
|
-
import { registerAddCommand } from "./add.js";
|
|
6
|
-
import { registerBuildCommand } from "./build.js";
|
|
7
|
-
import { registerConfigCommands } from "./config/index.js";
|
|
8
|
-
import { registerDescribeCommand } from "./describe.js";
|
|
9
|
-
import { registerDoctorCommand } from "./doctor.js";
|
|
10
|
-
import { registerExportCommand } from "./export.js";
|
|
11
|
-
import { registerGenerateCommands } from "./generate.js";
|
|
12
|
-
import { registerInfoCommand } from "./info.js";
|
|
13
|
-
import { registerInitCommand } from "./init.js";
|
|
14
|
-
import { registerLinkCommands } from "./link.js";
|
|
15
|
-
import { registerListCommand } from "./list.js";
|
|
16
|
-
import { registerMcpCommands } from "./mcp.js";
|
|
17
|
-
import { registerPackCommand } from "./pack.js";
|
|
18
|
-
import { registerPlaybookCommands } from "./playbook.js";
|
|
19
|
-
import { registerProfileCommands } from "./profile.js";
|
|
20
|
-
import { registerRemoveCommand } from "./remove.js";
|
|
21
|
-
import { registerRunCommand } from "./run.js";
|
|
22
|
-
import { registerRunsCommands } from "./runs.js";
|
|
23
|
-
import { registerServeCommand } from "./serve.js";
|
|
24
|
-
import { registerStateCommands } from "./state.js";
|
|
25
|
-
import { registerTestCommand } from "./test.js";
|
|
26
|
-
import { registerValidateCommand } from "./validate.js";
|
|
27
4
|
/**
|
|
28
5
|
* 读取 CLI 自身 package.json 的版本号(单一事实源)。
|
|
29
6
|
* 兼容源码运行(src/commands)与构建产物运行(dist/commands)两种目录层级。
|
|
@@ -62,6 +39,288 @@ function applyCommonOptions(cmd) {
|
|
|
62
39
|
applyCommonOptions(sub);
|
|
63
40
|
}
|
|
64
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* 动态加载子命令实现模块(兼容构建产物 .js 与开发环境 .ts)。
|
|
44
|
+
*/
|
|
45
|
+
function importCommandModule(relativePath) {
|
|
46
|
+
const ext = existsSync(join(import.meta.dirname, "run.js")) ? ".js" : ".ts";
|
|
47
|
+
return import(`${relativePath}${ext}`);
|
|
48
|
+
}
|
|
49
|
+
const COMMAND_DECLARATIONS = [
|
|
50
|
+
{
|
|
51
|
+
name: "init",
|
|
52
|
+
spec: "init [directory]",
|
|
53
|
+
description: "Initialize a new ActionDock project",
|
|
54
|
+
loader: "./init",
|
|
55
|
+
registerFn: "registerInitCommand",
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
name: "add",
|
|
59
|
+
spec: "add <package>",
|
|
60
|
+
description: "Install and lock an Action package dependency into current project",
|
|
61
|
+
loader: "./add",
|
|
62
|
+
registerFn: "registerAddCommand",
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
name: "remove",
|
|
66
|
+
spec: "remove <package>",
|
|
67
|
+
description: "Remove an Action package dependency and update actiondock.lock.json",
|
|
68
|
+
loader: "./remove",
|
|
69
|
+
registerFn: "registerRemoveCommand",
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
name: "action",
|
|
73
|
+
spec: "action",
|
|
74
|
+
description: "Manage Action definitions and scaffolding (create)",
|
|
75
|
+
loader: "./action/create",
|
|
76
|
+
registerFn: "registerActionCommands",
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
name: "info",
|
|
80
|
+
spec: "info [patterns...]",
|
|
81
|
+
description: "Display information about current project, linked package, or remote target",
|
|
82
|
+
loader: "./info",
|
|
83
|
+
registerFn: "registerInfoCommand",
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
name: "doctor",
|
|
87
|
+
spec: "doctor",
|
|
88
|
+
description: "Check ActionDock environment, registry health, and project diagnostics",
|
|
89
|
+
loader: "./doctor",
|
|
90
|
+
registerFn: "registerDoctorCommand",
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
name: "list",
|
|
94
|
+
spec: "list [patterns...]",
|
|
95
|
+
description: "List actions in current project, linked packages, or remote profile",
|
|
96
|
+
loader: "./list",
|
|
97
|
+
registerFn: "registerListCommand",
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
name: "describe",
|
|
101
|
+
spec: "describe <id>",
|
|
102
|
+
description: "Show action definition, schema, and description",
|
|
103
|
+
loader: "./describe",
|
|
104
|
+
registerFn: "registerDescribeCommand",
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
name: "run",
|
|
108
|
+
spec: "run <id> [params...]",
|
|
109
|
+
description: "Execute an action (from current project, linked packages, or remote profile)",
|
|
110
|
+
loader: "./run",
|
|
111
|
+
registerFn: "registerRunCommand",
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
name: "validate",
|
|
115
|
+
spec: "validate [id]",
|
|
116
|
+
description: "Validate action schemas and definitions",
|
|
117
|
+
loader: "./validate",
|
|
118
|
+
registerFn: "registerValidateCommand",
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
name: "generate",
|
|
122
|
+
spec: "generate",
|
|
123
|
+
description: "Generate project artifacts such as TypeScript declarations",
|
|
124
|
+
loader: "./generate",
|
|
125
|
+
registerFn: "registerGenerateCommands",
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
name: "playbook",
|
|
129
|
+
spec: "playbook",
|
|
130
|
+
description: "Manage task Playbooks (Task SOPs for AI Agents)",
|
|
131
|
+
loader: "./playbook",
|
|
132
|
+
registerFn: "registerPlaybookCommands",
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
name: "config",
|
|
136
|
+
spec: "config",
|
|
137
|
+
description: "Manage runtime configuration store (Global & Project-level)",
|
|
138
|
+
loader: "./config/index",
|
|
139
|
+
registerFn: "registerConfigCommands",
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
name: "state",
|
|
143
|
+
spec: "state",
|
|
144
|
+
description: "Inspect and manage Shared State store",
|
|
145
|
+
loader: "./state",
|
|
146
|
+
registerFn: "registerStateCommands",
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
name: "runs",
|
|
150
|
+
spec: "runs",
|
|
151
|
+
description: "Inspect action execution history",
|
|
152
|
+
loader: "./runs",
|
|
153
|
+
registerFn: "registerRunsCommands",
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
name: "test",
|
|
157
|
+
spec: "test [pattern]",
|
|
158
|
+
description: "Run project tests using configured test runner (node:test or bun test)",
|
|
159
|
+
loader: "./test",
|
|
160
|
+
registerFn: "registerTestCommand",
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
name: "build",
|
|
164
|
+
spec: "build",
|
|
165
|
+
description: "Build project actions into a runnable Node.js delivery directory",
|
|
166
|
+
loader: "./build",
|
|
167
|
+
registerFn: "registerBuildCommand",
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
name: "pack",
|
|
171
|
+
spec: "pack",
|
|
172
|
+
description: "Pack Action package into a standard npm tarball (.tgz) for distribution",
|
|
173
|
+
loader: "./pack",
|
|
174
|
+
registerFn: "registerPackCommand",
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
name: "export",
|
|
178
|
+
spec: "export",
|
|
179
|
+
description: "Export project artifacts",
|
|
180
|
+
loader: "./export",
|
|
181
|
+
registerFn: "registerExportCommand",
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
name: "link",
|
|
185
|
+
spec: "link [path]",
|
|
186
|
+
description: "Link local Action package(s) or workspace directory into global registry for instant cross-directory execution",
|
|
187
|
+
loader: "./link",
|
|
188
|
+
registerFn: "registerLinkCommands",
|
|
189
|
+
linkedNames: ["link", "unlink"],
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
name: "unlink",
|
|
193
|
+
spec: "unlink [identifier]",
|
|
194
|
+
description: "Unlink a package, workspace, or prune stale entries from global developer registry",
|
|
195
|
+
loader: "./link",
|
|
196
|
+
registerFn: "registerLinkCommands",
|
|
197
|
+
linkedNames: ["link", "unlink"],
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
name: "profile",
|
|
201
|
+
spec: "profile",
|
|
202
|
+
description: "Manage multi-cloud and remote execution profiles",
|
|
203
|
+
loader: "./profile",
|
|
204
|
+
registerFn: "registerProfileCommands",
|
|
205
|
+
},
|
|
206
|
+
{
|
|
207
|
+
name: "serve",
|
|
208
|
+
spec: "serve",
|
|
209
|
+
description: "Start the ActionDock lightweight HTTP Runner server for remote execution",
|
|
210
|
+
loader: "./serve",
|
|
211
|
+
registerFn: "registerServeCommand",
|
|
212
|
+
},
|
|
213
|
+
{
|
|
214
|
+
name: "mcp",
|
|
215
|
+
spec: "mcp",
|
|
216
|
+
description: "Model Context Protocol (MCP) server for ActionDock Actions (STDIO default)",
|
|
217
|
+
loader: "./mcp",
|
|
218
|
+
registerFn: "registerMcpCommands",
|
|
219
|
+
},
|
|
220
|
+
];
|
|
221
|
+
const RUNTIME_EXECUTABLES = new Set(["node", "bun", "tsx", "deno"]);
|
|
222
|
+
/**
|
|
223
|
+
* 判断命令行参数数组是否以宿主运行环境(node、bun、tsx 等)及入口脚本为前置元素。
|
|
224
|
+
*/
|
|
225
|
+
export function isNodeArgv(argv) {
|
|
226
|
+
if (!Array.isArray(argv) || argv.length < 2)
|
|
227
|
+
return false;
|
|
228
|
+
const first = argv[0];
|
|
229
|
+
if (!first || first.startsWith("-"))
|
|
230
|
+
return false;
|
|
231
|
+
const base = first.split(/[/\\]/).pop()?.toLowerCase().replace(/\.exe$/i, "") ?? "";
|
|
232
|
+
if (RUNTIME_EXECUTABLES.has(base)) {
|
|
233
|
+
return true;
|
|
234
|
+
}
|
|
235
|
+
// 严格排除已知子命令与内置 help 命令,杜绝将纯用户子命令参数错误识别为运行时
|
|
236
|
+
if (COMMAND_DECLARATIONS.some((d) => d.name === first || d.alias === first) ||
|
|
237
|
+
first === "help") {
|
|
238
|
+
return false;
|
|
239
|
+
}
|
|
240
|
+
return false;
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* 从命令行参数数组中解析出目标子命令名称(跳过全局选项与启动包装参数)。
|
|
244
|
+
*
|
|
245
|
+
* @param argv 命令行原始参数数组
|
|
246
|
+
* @param parseOptions Commander 解析选项(如 { from: 'user' })
|
|
247
|
+
* @returns 目标子命令名称或 null
|
|
248
|
+
*/
|
|
249
|
+
export function resolveTargetSubcommand(argv, parseOptions) {
|
|
250
|
+
let startIndex = 0;
|
|
251
|
+
if (parseOptions?.from === "user") {
|
|
252
|
+
startIndex = 0;
|
|
253
|
+
}
|
|
254
|
+
else if (parseOptions?.from === "eval") {
|
|
255
|
+
startIndex = 1;
|
|
256
|
+
}
|
|
257
|
+
else if (parseOptions?.from === "node") {
|
|
258
|
+
startIndex = 2;
|
|
259
|
+
}
|
|
260
|
+
else if (isNodeArgv(argv)) {
|
|
261
|
+
startIndex = 2;
|
|
262
|
+
}
|
|
263
|
+
else {
|
|
264
|
+
startIndex = 0;
|
|
265
|
+
}
|
|
266
|
+
let i = startIndex;
|
|
267
|
+
while (i < argv.length) {
|
|
268
|
+
const arg = argv[i];
|
|
269
|
+
if (arg === "--data-dir") {
|
|
270
|
+
i += 2;
|
|
271
|
+
continue;
|
|
272
|
+
}
|
|
273
|
+
if (arg.startsWith("-")) {
|
|
274
|
+
i++;
|
|
275
|
+
continue;
|
|
276
|
+
}
|
|
277
|
+
// 特殊处理 Commander 内置 help 命令(如 ad help run)
|
|
278
|
+
if (arg === "help" && i + 1 < argv.length && !argv[i + 1].startsWith("-")) {
|
|
279
|
+
return argv[i + 1];
|
|
280
|
+
}
|
|
281
|
+
return arg;
|
|
282
|
+
}
|
|
283
|
+
return null;
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* 按需加载并挂载目标子命令模块。
|
|
287
|
+
* 基于 Promise 缓存机制消除并发调用时的竞态条件。
|
|
288
|
+
*/
|
|
289
|
+
async function loadAndAttachCommand(targetSubcommand, program, placeholders, loadingPromises, context) {
|
|
290
|
+
const decl = COMMAND_DECLARATIONS.find((d) => d.name === targetSubcommand || d.alias === targetSubcommand);
|
|
291
|
+
if (!decl)
|
|
292
|
+
return;
|
|
293
|
+
const existing = loadingPromises.get(decl.loader);
|
|
294
|
+
if (existing) {
|
|
295
|
+
return existing;
|
|
296
|
+
}
|
|
297
|
+
const loadPromise = (async () => {
|
|
298
|
+
// 移除对应的占位命令节点
|
|
299
|
+
const toRemove = decl.linkedNames || [decl.name];
|
|
300
|
+
for (const name of toRemove) {
|
|
301
|
+
const p = placeholders.get(name);
|
|
302
|
+
if (p) {
|
|
303
|
+
const idx = program.commands.indexOf(p);
|
|
304
|
+
if (idx !== -1) {
|
|
305
|
+
program.commands.splice(idx, 1);
|
|
306
|
+
}
|
|
307
|
+
placeholders.delete(name);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
// 动态导入实际命令模块并挂载真实命令
|
|
311
|
+
const mod = await importCommandModule(decl.loader);
|
|
312
|
+
const fn = mod[decl.registerFn];
|
|
313
|
+
if (typeof fn === "function") {
|
|
314
|
+
fn(program, context);
|
|
315
|
+
applyCommonOptions(program);
|
|
316
|
+
}
|
|
317
|
+
})();
|
|
318
|
+
loadingPromises.set(decl.loader, loadPromise);
|
|
319
|
+
loadPromise.catch(() => {
|
|
320
|
+
loadingPromises.delete(decl.loader);
|
|
321
|
+
});
|
|
322
|
+
return loadPromise;
|
|
323
|
+
}
|
|
65
324
|
export function createCliProgram(context) {
|
|
66
325
|
const program = new Command();
|
|
67
326
|
program
|
|
@@ -77,30 +336,69 @@ export function createCliProgram(context) {
|
|
|
77
336
|
program.exitOverride((err) => {
|
|
78
337
|
throw err;
|
|
79
338
|
});
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
339
|
+
if (context?.stdout || context?.stderr) {
|
|
340
|
+
program.configureOutput({
|
|
341
|
+
writeOut: (str) => {
|
|
342
|
+
if (context.stdout)
|
|
343
|
+
context.stdout(str);
|
|
344
|
+
else
|
|
345
|
+
process.stdout.write(str);
|
|
346
|
+
},
|
|
347
|
+
writeErr: (str) => {
|
|
348
|
+
if (context.stderr)
|
|
349
|
+
context.stderr(str);
|
|
350
|
+
else
|
|
351
|
+
process.stderr.write(str);
|
|
352
|
+
},
|
|
353
|
+
});
|
|
354
|
+
}
|
|
355
|
+
program.addHelpText("after", `
|
|
356
|
+
Workflow Guidance:
|
|
357
|
+
For multi-step workflows, run 'ad playbook list' before invoking atomic actions.
|
|
358
|
+
Run 'ad info [intent]' to discover packages and playbooks by keyword.`);
|
|
359
|
+
// 注册轻量级占位命令声明(零重型模块导入开销)
|
|
360
|
+
const placeholders = new Map();
|
|
361
|
+
for (const decl of COMMAND_DECLARATIONS) {
|
|
362
|
+
const cmd = program.command(decl.spec).description(decl.description);
|
|
363
|
+
if (decl.alias) {
|
|
364
|
+
cmd.alias(decl.alias);
|
|
365
|
+
}
|
|
366
|
+
placeholders.set(decl.name, cmd);
|
|
367
|
+
}
|
|
103
368
|
applyCommonOptions(program);
|
|
369
|
+
// 拦截 parseAsync 以在实际执行或具体帮助展示时按需动态加载真实子命令
|
|
370
|
+
const originalParseAsync = program.parseAsync.bind(program);
|
|
371
|
+
const loadingPromises = new Map();
|
|
372
|
+
program.parseAsync = async function (argv, parseOptions) {
|
|
373
|
+
const targetArgv = argv || process.argv;
|
|
374
|
+
const targetSubcommand = resolveTargetSubcommand(targetArgv, parseOptions);
|
|
375
|
+
if (targetSubcommand) {
|
|
376
|
+
await loadAndAttachCommand(targetSubcommand, program, placeholders, loadingPromises, context);
|
|
377
|
+
}
|
|
378
|
+
return originalParseAsync(argv, parseOptions);
|
|
379
|
+
};
|
|
104
380
|
return program;
|
|
105
381
|
}
|
|
106
|
-
export
|
|
382
|
+
export const registerActionCommands = (program, context) => importCommandModule("./action/create").then((m) => m.registerActionCommands(program, context));
|
|
383
|
+
export const registerAddCommand = (program, context) => importCommandModule("./add").then((m) => m.registerAddCommand(program, context));
|
|
384
|
+
export const registerBuildCommand = (program, context) => importCommandModule("./build").then((m) => m.registerBuildCommand(program, context));
|
|
385
|
+
export const registerConfigCommands = (program, context) => importCommandModule("./config/index").then((m) => m.registerConfigCommands(program, context));
|
|
386
|
+
export const registerDescribeCommand = (program, context) => importCommandModule("./describe").then((m) => m.registerDescribeCommand(program, context));
|
|
387
|
+
export const registerDoctorCommand = (program, context) => importCommandModule("./doctor").then((m) => m.registerDoctorCommand(program, context));
|
|
388
|
+
export const registerExportCommand = (program, context) => importCommandModule("./export").then((m) => m.registerExportCommand(program, context));
|
|
389
|
+
export const registerGenerateCommands = (program, context) => importCommandModule("./generate").then((m) => m.registerGenerateCommands(program, context));
|
|
390
|
+
export const registerInfoCommand = (program, context) => importCommandModule("./info").then((m) => m.registerInfoCommand(program, context));
|
|
391
|
+
export const registerInitCommand = (program) => importCommandModule("./init").then((m) => m.registerInitCommand(program));
|
|
392
|
+
export const registerLinkCommands = (program) => importCommandModule("./link").then((m) => m.registerLinkCommands(program));
|
|
393
|
+
export const registerListCommand = (program, context) => importCommandModule("./list").then((m) => m.registerListCommand(program, context));
|
|
394
|
+
export const registerMcpCommands = (program, context) => importCommandModule("./mcp").then((m) => m.registerMcpCommands(program, context));
|
|
395
|
+
export const registerPackCommand = (program, context) => importCommandModule("./pack").then((m) => m.registerPackCommand(program, context));
|
|
396
|
+
export const registerPlaybookCommands = (program, context) => importCommandModule("./playbook").then((m) => m.registerPlaybookCommands(program, context));
|
|
397
|
+
export const registerProfileCommands = (program) => importCommandModule("./profile").then((m) => m.registerProfileCommands(program));
|
|
398
|
+
export const registerRemoveCommand = (program, context) => importCommandModule("./remove").then((m) => m.registerRemoveCommand(program, context));
|
|
399
|
+
export const registerRunCommand = (program, context) => importCommandModule("./run").then((m) => m.registerRunCommand(program, context));
|
|
400
|
+
export const registerRunsCommands = (program, context) => importCommandModule("./runs").then((m) => m.registerRunsCommands(program, context));
|
|
401
|
+
export const registerServeCommand = (program, context) => importCommandModule("./serve").then((m) => m.registerServeCommand(program, context));
|
|
402
|
+
export const registerStateCommands = (program, context) => importCommandModule("./state").then((m) => m.registerStateCommands(program, context));
|
|
403
|
+
export const registerTestCommand = (program) => importCommandModule("./test").then((m) => m.registerTestCommand(program));
|
|
404
|
+
export const registerValidateCommand = (program, context) => importCommandModule("./validate").then((m) => m.registerValidateCommand(program, context));
|
package/dist/commands/info.js
CHANGED
|
@@ -9,6 +9,26 @@ import { applyTargetOptions, getEffectiveOptions, resolveFallbackStrategy, resol
|
|
|
9
9
|
* 将远端信息响应归一为本地工程详情视图。
|
|
10
10
|
*/
|
|
11
11
|
function remoteInfoToDetail(remoteInfo) {
|
|
12
|
+
const actionsMap = new Map();
|
|
13
|
+
const rawActions = remoteInfo.actionsDetail || remoteInfo.actions || [];
|
|
14
|
+
for (const a of rawActions) {
|
|
15
|
+
if (typeof a === "string") {
|
|
16
|
+
actionsMap.set(a, { id: a });
|
|
17
|
+
}
|
|
18
|
+
else if (a && typeof a === "object") {
|
|
19
|
+
actionsMap.set(a.id, { id: a.id, description: a.description });
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
const playbooksMap = new Map();
|
|
23
|
+
const rawPlaybooks = remoteInfo.playbooksDetail || remoteInfo.playbooks || [];
|
|
24
|
+
for (const pb of rawPlaybooks) {
|
|
25
|
+
if (typeof pb === "string") {
|
|
26
|
+
playbooksMap.set(pb, { id: pb });
|
|
27
|
+
}
|
|
28
|
+
else if (pb && typeof pb === "object") {
|
|
29
|
+
playbooksMap.set(pb.id, { id: pb.id, description: pb.description });
|
|
30
|
+
}
|
|
31
|
+
}
|
|
12
32
|
return {
|
|
13
33
|
id: remoteInfo.id,
|
|
14
34
|
name: remoteInfo.name || remoteInfo.id,
|
|
@@ -17,12 +37,14 @@ function remoteInfoToDetail(remoteInfo) {
|
|
|
17
37
|
projectRoot: remoteInfo.path || remoteInfo.projectRoot || "",
|
|
18
38
|
actionsDir: "remote",
|
|
19
39
|
playbooksDir: "remote",
|
|
20
|
-
actionsCount:
|
|
21
|
-
playbooksCount:
|
|
22
|
-
actions: (
|
|
23
|
-
playbooks: (
|
|
40
|
+
actionsCount: actionsMap.size,
|
|
41
|
+
playbooksCount: playbooksMap.size,
|
|
42
|
+
actions: Array.from(actionsMap.keys()),
|
|
43
|
+
playbooks: Array.from(playbooksMap.keys()),
|
|
24
44
|
configDeclared: Object.keys(remoteInfo.configDeclared || {}),
|
|
25
45
|
configDef: remoteInfo.configDeclared,
|
|
46
|
+
actionsMap,
|
|
47
|
+
playbooksMap,
|
|
26
48
|
};
|
|
27
49
|
}
|
|
28
50
|
/**
|
|
@@ -116,6 +138,9 @@ export function registerInfoCommand(program, context) {
|
|
|
116
138
|
}
|
|
117
139
|
// 扫描本地候选包(当前工程根目录 + 全局已链接包)
|
|
118
140
|
const { currentRoot, aggregated } = scanLocalAggregatedPackages(context);
|
|
141
|
+
const infoHints = [
|
|
142
|
+
"Tip: Run 'ad info <package-id>' to view detailed package configuration and schema.",
|
|
143
|
+
];
|
|
119
144
|
// 无关键字过滤场景
|
|
120
145
|
if (!effectiveIntent) {
|
|
121
146
|
if (currentRoot) {
|
|
@@ -130,7 +155,7 @@ export function registerInfoCommand(program, context) {
|
|
|
130
155
|
});
|
|
131
156
|
return;
|
|
132
157
|
}
|
|
133
|
-
renderResult({ linkedPackages: aggregated }, {
|
|
158
|
+
renderResult({ linkedPackages: aggregated, hints: infoHints }, {
|
|
134
159
|
...outOpts,
|
|
135
160
|
humanFormatter: () => renderAggregatedPackages(aggregated),
|
|
136
161
|
});
|
|
@@ -147,7 +172,7 @@ export function registerInfoCommand(program, context) {
|
|
|
147
172
|
}
|
|
148
173
|
if (aggregated.length === 0) {
|
|
149
174
|
if (isMachine) {
|
|
150
|
-
renderResult({ linkedPackages: [], matchedCount: 0, isFallback: false }, outOpts);
|
|
175
|
+
renderResult({ linkedPackages: [], matchedCount: 0, isFallback: false, hints: infoHints }, outOpts);
|
|
151
176
|
return;
|
|
152
177
|
}
|
|
153
178
|
throw new ExecutionError(`No ActionDock project or linked packages available to match '${effectiveIntent}'`);
|
|
@@ -164,14 +189,14 @@ export function registerInfoCommand(program, context) {
|
|
|
164
189
|
if (filterRes.matchedCount === 0) {
|
|
165
190
|
if (!filterRes.isFallback) {
|
|
166
191
|
if (isMachine) {
|
|
167
|
-
renderResult({ linkedPackages: [], matchedCount: 0, isFallback: false }, outOpts);
|
|
192
|
+
renderResult({ linkedPackages: [], matchedCount: 0, isFallback: false, hints: infoHints }, outOpts);
|
|
168
193
|
return;
|
|
169
194
|
}
|
|
170
195
|
throw new ExecutionError(`No packages matched intent '${effectiveIntent}'`);
|
|
171
196
|
}
|
|
172
197
|
// 回退模式:展示全部包并附带提示
|
|
173
198
|
if (isMachine) {
|
|
174
|
-
renderResult({ linkedPackages: filterRes.items, isFallback: true, matchedCount: 0 }, outOpts);
|
|
199
|
+
renderResult({ linkedPackages: filterRes.items, isFallback: true, matchedCount: 0, hints: infoHints }, outOpts);
|
|
175
200
|
return;
|
|
176
201
|
}
|
|
177
202
|
renderResult({ linkedPackages: filterRes.items, isFallback: true, matchedCount: 0 }, {
|
|
@@ -183,7 +208,7 @@ export function registerInfoCommand(program, context) {
|
|
|
183
208
|
}
|
|
184
209
|
// 机器模式下搜索:稳定返回列表结构,不因为 matchedCount === 1 突变为详情
|
|
185
210
|
if (isMachine) {
|
|
186
|
-
renderResult({ linkedPackages: filterRes.items, matchedCount: filterRes.matchedCount, isFallback: false }, outOpts);
|
|
211
|
+
renderResult({ linkedPackages: filterRes.items, matchedCount: filterRes.matchedCount, isFallback: false, hints: infoHints }, outOpts);
|
|
187
212
|
return;
|
|
188
213
|
}
|
|
189
214
|
// 人类终端交互:精确匹配单个包展开详情
|
package/dist/commands/list.js
CHANGED
|
@@ -63,8 +63,19 @@ export function attachListCommand(parent, context) {
|
|
|
63
63
|
};
|
|
64
64
|
});
|
|
65
65
|
const filterRes = filterWithFallbackInfo(rawList, effectiveIntent, [(a) => a.id, (a) => a.description], shouldFallback);
|
|
66
|
-
|
|
67
|
-
|
|
66
|
+
const hints = [
|
|
67
|
+
"Tip: For composite or multi-step tasks, check 'ad playbook list' for standard operating procedures.",
|
|
68
|
+
];
|
|
69
|
+
if (isMachine) {
|
|
70
|
+
if (filterRes.isFallback) {
|
|
71
|
+
renderResult({ items: filterRes.items, isFallback: true, matchedCount: 0, hints }, { json: options.json, context });
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
renderResult({
|
|
75
|
+
items: filterRes.items,
|
|
76
|
+
...(filterRes.matchedCount !== undefined ? { matchedCount: filterRes.matchedCount } : {}),
|
|
77
|
+
hints,
|
|
78
|
+
}, { json: options.json, context });
|
|
68
79
|
return;
|
|
69
80
|
}
|
|
70
81
|
const title = resolved.type === "remote"
|
package/dist/commands/mcp.js
CHANGED
|
@@ -116,7 +116,6 @@ export function registerMcpCommands(program, context) {
|
|
|
116
116
|
const platform = createNodePlatform({
|
|
117
117
|
customHome: context?.customHome,
|
|
118
118
|
dataDir: options.dataDir || context?.dataDir,
|
|
119
|
-
rootDir: projectRoots?.[0],
|
|
120
119
|
});
|
|
121
120
|
const { startMcpHttpServer } = await import("@actiondock/mcp");
|
|
122
121
|
const server = await startMcpHttpServer({
|