@actiondock/cli 2.0.11 → 2.2.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 +41 -21
- package/bin/ad.js +29 -31
- package/dist/commands/action/create.d.ts +10 -0
- package/dist/commands/action/create.js +120 -0
- package/dist/commands/add.d.ts +7 -0
- package/dist/commands/add.js +144 -0
- package/dist/commands/build.d.ts +3 -0
- package/dist/commands/build.js +83 -0
- package/dist/commands/config/delete.d.ts +9 -0
- package/dist/commands/config/delete.js +52 -0
- package/dist/commands/config/env.d.ts +9 -0
- package/dist/commands/config/env.js +85 -0
- package/dist/commands/config/get.d.ts +9 -0
- package/dist/commands/config/get.js +120 -0
- package/dist/commands/config/index.d.ts +9 -0
- package/dist/commands/config/index.js +23 -0
- package/dist/commands/config/list.d.ts +9 -0
- package/dist/commands/config/list.js +137 -0
- package/dist/commands/config/schema.d.ts +9 -0
- package/dist/commands/config/schema.js +121 -0
- package/dist/commands/config/set.d.ts +9 -0
- package/dist/commands/config/set.js +85 -0
- package/dist/commands/describe.d.ts +9 -0
- package/dist/commands/describe.js +68 -0
- package/dist/commands/doctor.d.ts +3 -0
- package/dist/commands/doctor.js +82 -0
- package/dist/commands/export.d.ts +3 -0
- package/dist/commands/export.js +212 -0
- package/dist/commands/generate.d.ts +9 -0
- package/dist/commands/generate.js +44 -0
- package/dist/commands/index.d.ts +32 -0
- package/dist/commands/index.js +111 -0
- package/dist/commands/info.d.ts +9 -0
- package/dist/commands/info.js +210 -0
- package/dist/commands/init.d.ts +2 -0
- package/dist/commands/init.js +24 -0
- package/dist/commands/link.d.ts +2 -0
- package/dist/commands/link.js +71 -0
- package/dist/commands/list.d.ts +9 -0
- package/dist/commands/list.js +77 -0
- package/dist/commands/mcp.d.ts +9 -0
- package/dist/commands/mcp.js +172 -0
- package/dist/commands/new.d.ts +9 -0
- package/dist/commands/new.js +33 -0
- package/dist/commands/pack.d.ts +3 -0
- package/dist/commands/pack.js +63 -0
- package/dist/commands/playbook.d.ts +10 -0
- package/dist/commands/playbook.js +433 -0
- package/dist/commands/profile.d.ts +2 -0
- package/dist/commands/profile.js +253 -0
- package/dist/commands/remove.d.ts +7 -0
- package/dist/commands/remove.js +118 -0
- package/dist/commands/run.d.ts +13 -0
- package/dist/commands/run.js +146 -0
- package/dist/commands/runs.d.ts +9 -0
- package/dist/commands/runs.js +245 -0
- package/dist/commands/serve.d.ts +9 -0
- package/dist/commands/serve.js +129 -0
- package/dist/commands/state-list.d.ts +24 -0
- package/dist/commands/state-list.js +82 -0
- package/dist/commands/state.d.ts +9 -0
- package/dist/commands/state.js +310 -0
- package/dist/commands/test.d.ts +2 -0
- package/dist/commands/test.js +44 -0
- package/dist/commands/validate.d.ts +9 -0
- package/dist/commands/validate.js +106 -0
- package/dist/errors.d.ts +43 -0
- package/dist/errors.js +103 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.js +47 -65969
- package/dist/prompt.d.ts +53 -0
- package/dist/prompt.js +192 -0
- package/dist/renderer.d.ts +197 -0
- package/dist/renderer.js +502 -0
- package/dist/services/index.d.ts +1 -0
- package/dist/services/index.js +1 -0
- package/dist/services/inspect.d.ts +23 -0
- package/dist/services/inspect.js +96 -0
- package/dist/standalone/index.d.ts +16 -0
- package/dist/standalone/index.js +22 -0
- package/dist/types.d.ts +132 -0
- package/dist/types.js +9 -0
- package/dist/utils/bytes.d.ts +1 -0
- package/dist/utils/bytes.js +1 -0
- package/dist/utils/duration.js +1 -0
- package/dist/utils/filter.d.ts +1 -0
- package/dist/utils/filter.js +1 -0
- package/dist/utils/index.d.ts +6 -0
- package/dist/utils/index.js +6 -0
- package/dist/utils/spawn.d.ts +27 -0
- package/dist/utils/spawn.js +35 -0
- package/dist/utils/target.d.ts +45 -0
- package/dist/utils/target.js +78 -0
- package/dist/utils/utils.d.ts +38 -0
- package/dist/utils/utils.js +111 -0
- package/package.json +20 -17
- package/src/commands/action/create.ts +0 -129
- package/src/commands/action/index.ts +0 -27
- package/src/commands/action/list.ts +0 -247
- package/src/commands/action/run.ts +0 -197
- package/src/commands/action/show.ts +0 -128
- package/src/commands/action/sync.ts +0 -76
- package/src/commands/action/validate.ts +0 -102
- package/src/commands/action.ts +0 -1
- package/src/commands/build.ts +0 -56
- package/src/commands/config.ts +0 -583
- package/src/commands/doctor.ts +0 -84
- package/src/commands/export.ts +0 -196
- package/src/commands/index.ts +0 -75
- package/src/commands/info.ts +0 -537
- package/src/commands/init.ts +0 -24
- package/src/commands/link.ts +0 -73
- package/src/commands/mcp.ts +0 -195
- package/src/commands/playbook.ts +0 -566
- package/src/commands/profile.ts +0 -296
- package/src/commands/runs.ts +0 -452
- package/src/commands/serve.ts +0 -132
- package/src/commands/state.ts +0 -590
- package/src/commands/test.ts +0 -48
- package/src/index.ts +0 -58
- package/src/utils/bytes.ts +0 -2
- package/src/utils/filter.ts +0 -2
- /package/{src/utils/duration.ts → dist/utils/duration.d.ts} +0 -0
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { ArgumentError, ExecutionError } from "../errors.js";
|
|
2
|
+
import { renderActionDetail, renderResult } from "../renderer.js";
|
|
3
|
+
import { getEffectiveOptions, resolveLocalPackageRoot, withTarget, } from "../utils/index.js";
|
|
4
|
+
/**
|
|
5
|
+
* 注册顶层统一 describe 命令:查询指定 Action 的规范结构与模式定义。
|
|
6
|
+
*
|
|
7
|
+
* @param program Commander 根程序对象
|
|
8
|
+
* @param context 命令行上下文
|
|
9
|
+
*/
|
|
10
|
+
export function registerDescribeCommand(program, context) {
|
|
11
|
+
program
|
|
12
|
+
.command("describe <id>")
|
|
13
|
+
.alias("show")
|
|
14
|
+
.description("Show action definition, schema, and description")
|
|
15
|
+
.option("-P, --package <id>", "Target package ID or path")
|
|
16
|
+
.option("-p, --profile <name>", "Query against a specific profile")
|
|
17
|
+
.option("-s, --server <url>", "Remote server URL")
|
|
18
|
+
.option("-t, --token <token>", "Auth token for remote server")
|
|
19
|
+
.option("--json", "Output as JSON")
|
|
20
|
+
.option("--envelope", "Wrap JSON output in standard envelope")
|
|
21
|
+
.option("--data-dir <path>", "Custom database storage directory")
|
|
22
|
+
.action(async (id, rawOptions, cmd) => {
|
|
23
|
+
const options = getEffectiveOptions(rawOptions, cmd);
|
|
24
|
+
if (!id) {
|
|
25
|
+
throw new ArgumentError("Action ID is required for describe");
|
|
26
|
+
}
|
|
27
|
+
// 目标拓扑解析(仅 local 分支需要包寻址)
|
|
28
|
+
const targetPackageRoot = resolveLocalPackageRoot(options.package);
|
|
29
|
+
if (options.package && !targetPackageRoot) {
|
|
30
|
+
throw new ArgumentError(`Package '${options.package}' not found in linked packages or path`);
|
|
31
|
+
}
|
|
32
|
+
let targetRef = id;
|
|
33
|
+
if (options.package && !id.includes("/") && !id.includes(":")) {
|
|
34
|
+
targetRef = `${options.package}/${id}`;
|
|
35
|
+
}
|
|
36
|
+
// 通过 Target 门面统一查询 Action 规范
|
|
37
|
+
await withTarget(options, context, async (target) => {
|
|
38
|
+
let spec;
|
|
39
|
+
try {
|
|
40
|
+
spec = await target.describeAction(targetRef);
|
|
41
|
+
}
|
|
42
|
+
catch (err) {
|
|
43
|
+
const msg = err?.message || String(err);
|
|
44
|
+
if (msg.includes("not found") || msg.includes("ACTION_NOT_FOUND")) {
|
|
45
|
+
throw new ArgumentError(msg);
|
|
46
|
+
}
|
|
47
|
+
throw new ExecutionError(msg);
|
|
48
|
+
}
|
|
49
|
+
const detail = {
|
|
50
|
+
id: spec.id,
|
|
51
|
+
description: spec.description,
|
|
52
|
+
inputSchema: spec.inputSchema,
|
|
53
|
+
outputSchema: spec.outputSchema,
|
|
54
|
+
tags: spec.tags,
|
|
55
|
+
annotations: spec.annotations,
|
|
56
|
+
uses: spec.uses,
|
|
57
|
+
entry: spec.entry,
|
|
58
|
+
filePath: spec.filePath,
|
|
59
|
+
};
|
|
60
|
+
renderResult(detail, {
|
|
61
|
+
json: options.json,
|
|
62
|
+
envelope: options.envelope,
|
|
63
|
+
humanFormatter: () => renderActionDetail(detail),
|
|
64
|
+
context,
|
|
65
|
+
});
|
|
66
|
+
}, { localRoot: targetPackageRoot || undefined, scanLinkedPackages: true });
|
|
67
|
+
});
|
|
68
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { fetchRemoteDoctor, resolveTarget, runDoctorChecks } from "@actiondock/core";
|
|
2
|
+
import { ExecutionError } from "../errors.js";
|
|
3
|
+
import { renderResult } from "../renderer.js";
|
|
4
|
+
import { getEffectiveOptions } from "../utils/index.js";
|
|
5
|
+
export function registerDoctorCommand(program, context) {
|
|
6
|
+
program
|
|
7
|
+
.command("doctor")
|
|
8
|
+
.description("Check ActionDock environment, registry health, and project diagnostics")
|
|
9
|
+
.option("-P, --package <id|path>", "Target package ID or directory path for project diagnostics")
|
|
10
|
+
.option("-p, --profile <name>", "Query doctor diagnostics on a remote target")
|
|
11
|
+
.option("-s, --server <url>", "Remote server URL")
|
|
12
|
+
.option("-t, --token <token>", "Auth token for remote server")
|
|
13
|
+
.option("--json", "Output diagnostics report in JSON format")
|
|
14
|
+
.option("--envelope", "Wrap JSON output in standard envelope")
|
|
15
|
+
.action(async (rawOptions, cmd) => {
|
|
16
|
+
try {
|
|
17
|
+
const options = getEffectiveOptions(rawOptions, cmd);
|
|
18
|
+
const target = resolveTarget({
|
|
19
|
+
profile: options.profile,
|
|
20
|
+
server: options.server,
|
|
21
|
+
token: options.token,
|
|
22
|
+
}, context?.customHome);
|
|
23
|
+
let report;
|
|
24
|
+
if (target.type === "remote") {
|
|
25
|
+
const remoteRes = await fetchRemoteDoctor(target.serverUrl, target.token, options.package);
|
|
26
|
+
report = remoteRes.report || remoteRes;
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
report = await runDoctorChecks({
|
|
30
|
+
packageIdOrPath: options.package,
|
|
31
|
+
customHome: context?.customHome,
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
renderResult(report, {
|
|
35
|
+
json: options.json,
|
|
36
|
+
envelope: options.envelope,
|
|
37
|
+
humanFormatter: () => {
|
|
38
|
+
const lines = [];
|
|
39
|
+
const title = target.type === "remote"
|
|
40
|
+
? `[DOCTOR] Remote ActionDock Server Diagnostics (${target.serverUrl}${target.profileName ? ` - Profile: ${target.profileName}` : ""})\n`
|
|
41
|
+
: "[DOCTOR] ActionDock System & Project Diagnostics\n";
|
|
42
|
+
lines.push(title);
|
|
43
|
+
// 1. Runtime & Environment Group
|
|
44
|
+
lines.push("[Runtime & Environment]");
|
|
45
|
+
const envChecks = (report.checks || []).filter((c) => c.category === "runtime" || c.category === "storage" || c.category === "registry");
|
|
46
|
+
for (const c of envChecks) {
|
|
47
|
+
const tag = c.status === "ok" ? "[OK]" : c.status === "warn" ? "[WARN]" : "[ERROR]";
|
|
48
|
+
lines.push(` ${tag} ${c.name}: ${c.message}`);
|
|
49
|
+
if (c.fix) {
|
|
50
|
+
lines.push(` Fix: ${c.fix}`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
// 2. Project Group
|
|
54
|
+
if (report.hasProject) {
|
|
55
|
+
lines.push(`\n[Project: ${report.packageId || "unknown"}] (${report.projectRoot})`);
|
|
56
|
+
const projChecks = (report.checks || []).filter((c) => c.category === "project");
|
|
57
|
+
for (const c of projChecks) {
|
|
58
|
+
const tag = c.status === "ok" ? "[OK]" : c.status === "warn" ? "[WARN]" : "[ERROR]";
|
|
59
|
+
lines.push(` ${tag} ${c.name}: ${c.message}`);
|
|
60
|
+
if (c.fix) {
|
|
61
|
+
lines.push(` Fix: ${c.fix}`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
lines.push("\n[Project Context]");
|
|
67
|
+
lines.push(" [INFO] Not inside an ActionDock project directory (skipped project checks)");
|
|
68
|
+
}
|
|
69
|
+
// 3. Summary
|
|
70
|
+
lines.push(`\n[Summary] ${report.summary.ok} passed, ${report.summary.warn} warning(s), ${report.summary.error} error(s)`);
|
|
71
|
+
return lines.join("\n");
|
|
72
|
+
},
|
|
73
|
+
});
|
|
74
|
+
if (!report.ok) {
|
|
75
|
+
process.exitCode = 1;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
catch (err) {
|
|
79
|
+
throw new ExecutionError(`Doctor failed to run diagnostics: ${err.message}`);
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
}
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { basename } from "node:path";
|
|
3
|
+
import { exportCompositeSkill, exportSkill, exportSkillBatch } from "@actiondock/builder";
|
|
4
|
+
import { discoverProjects, findProjectRoot, listLinkedPackages, resolvePackageRoot } from "@actiondock/core";
|
|
5
|
+
import { ExecutionError } from "../errors.js";
|
|
6
|
+
import { renderResult, writeStdout } from "../renderer.js";
|
|
7
|
+
import { getEffectiveOptions, parseListOption } from "../utils/index.js";
|
|
8
|
+
export function registerExportCommand(program, context) {
|
|
9
|
+
const exportCmd = program
|
|
10
|
+
.command("export")
|
|
11
|
+
.description("Export project artifacts");
|
|
12
|
+
exportCmd
|
|
13
|
+
.command("skill")
|
|
14
|
+
.description("Export Skill directory for AI Agents (default: source; use -m/--mode node for self-contained Node.js directory)")
|
|
15
|
+
.option("-P, --package <id...>", "Target package ID(s) or path(s) (can be specified multiple times or comma-separated)", parseListOption, [])
|
|
16
|
+
.option("--workspace", "Export all packages discovered in current workspace")
|
|
17
|
+
.option("--all", "Export all linked packages from global registry")
|
|
18
|
+
.option("--bundle [name]", "Export multiple packages as a unified composite Skill bundle (defaults to workspace directory name if omitted)")
|
|
19
|
+
.option("-m, --mode <mode>", "Skill export mode ('source' or 'node')", "source")
|
|
20
|
+
.option("-s, --standalone", "Export standalone binary skill (removed)")
|
|
21
|
+
.option("-t, --target <target>", "Target compilation platform (removed)")
|
|
22
|
+
.option("--bytecode", "Bytecode compilation (removed)")
|
|
23
|
+
.option("-o, --out <path>", "Output skill directory")
|
|
24
|
+
.option("-p, --playbook <playbooks...>", "Only export specific playbook(s) and their dependent actions", parseListOption)
|
|
25
|
+
.option("-a, --actions <actions...>", "Only export specific action(s)", parseListOption)
|
|
26
|
+
.option("-z, --archive", "Create a .zip archive of the exported skill")
|
|
27
|
+
.option("--skill-md <path>", "Use specified existing SKILL.md file instead of auto-generating")
|
|
28
|
+
.option("--custom-md <path>", "Custom skill declaration (SKILL.custom.md) with slot-marked sections and optional frontmatter description for composite bundles (auto-discovered at workspace root when omitted)")
|
|
29
|
+
.option("--skill-md-only", "Bundle mode only: regenerate only the composite SKILL.md in place (always regenerates, ignores any existing SKILL.md)")
|
|
30
|
+
.option("--vendor-deps", "Materialize locked production dependencies into the exported skill")
|
|
31
|
+
.option("--allow-install-scripts", "Allow lifecycle install scripts to run during dependency materialization")
|
|
32
|
+
.option("--require-reproducible", "Require reproducible build and fail if install scripts must run")
|
|
33
|
+
.action(async (rawOptions, cmd) => {
|
|
34
|
+
const options = getEffectiveOptions(rawOptions, cmd);
|
|
35
|
+
// 彻底删除 --standalone 单文件编译选项
|
|
36
|
+
if (options.standalone || options.target !== undefined || options.bytecode !== undefined) {
|
|
37
|
+
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");
|
|
38
|
+
}
|
|
39
|
+
const mode = options.mode === "node" ? "node" : "source";
|
|
40
|
+
if (options.bundle && mode === "node") {
|
|
41
|
+
throw new ExecutionError("Composite Skill export (--bundle) currently only supports source mode. Please use '--mode source' to export as a composite workspace Skill.");
|
|
42
|
+
}
|
|
43
|
+
if (options.skillMdOnly && options.bundle === undefined) {
|
|
44
|
+
throw new ExecutionError("Option --skill-md-only requires composite bundle mode (--bundle).");
|
|
45
|
+
}
|
|
46
|
+
const sourceCount = (options.all ? 1 : 0) +
|
|
47
|
+
(options.workspace ? 1 : 0) +
|
|
48
|
+
(options.package && options.package.length > 0 ? 1 : 0);
|
|
49
|
+
if (sourceCount > 1) {
|
|
50
|
+
throw new ExecutionError("Options -P/--package, --workspace, and --all are mutually exclusive. Please specify only one package selection mode.");
|
|
51
|
+
}
|
|
52
|
+
let roots = [];
|
|
53
|
+
if (options.all) {
|
|
54
|
+
const linked = listLinkedPackages();
|
|
55
|
+
roots = linked.map((p) => p.path).filter((p) => existsSync(p));
|
|
56
|
+
if (roots.length === 0) {
|
|
57
|
+
throw new ExecutionError("No linked packages found in global registry.");
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
else if (options.workspace) {
|
|
61
|
+
const cwd = process.cwd();
|
|
62
|
+
const discovered = discoverProjects(cwd);
|
|
63
|
+
roots = discovered.length > 0 ? discovered : (findProjectRoot(cwd) ? [findProjectRoot(cwd)] : []);
|
|
64
|
+
if (roots.length === 0) {
|
|
65
|
+
throw new ExecutionError(`No ActionDock packages found in workspace '${cwd}'.\nMake sure child directories contain actiondock.json.`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
else if (options.package && options.package.length > 0) {
|
|
69
|
+
for (const pkgIdOrPath of options.package) {
|
|
70
|
+
const root = resolvePackageRoot(pkgIdOrPath);
|
|
71
|
+
if (!root) {
|
|
72
|
+
throw new ExecutionError(`Package '${pkgIdOrPath}' not found in linked packages or path`);
|
|
73
|
+
}
|
|
74
|
+
if (!roots.includes(root)) {
|
|
75
|
+
roots.push(root);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
const root = findProjectRoot();
|
|
81
|
+
if (root) {
|
|
82
|
+
roots.push(root);
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
throw new ExecutionError("Not in an ActionDock project (actiondock.json not found).\nPlease specify -P, --package <id>, --workspace, --all, or cd into a project directory.");
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
if (roots.length > 1 && (options.actions || options.playbook)) {
|
|
89
|
+
throw new ExecutionError("Filtering options (--actions, --playbook) can only be used when exporting a single package.");
|
|
90
|
+
}
|
|
91
|
+
const isMachine = Boolean(options.json || options.envelope);
|
|
92
|
+
try {
|
|
93
|
+
if (options.bundle !== undefined) {
|
|
94
|
+
const bundleName = typeof options.bundle === "string" && options.bundle.trim()
|
|
95
|
+
? options.bundle.trim()
|
|
96
|
+
: basename(process.cwd());
|
|
97
|
+
if (!isMachine) {
|
|
98
|
+
writeStdout(`Exporting composite Skill bundle '${bundleName}' (${roots.length} package${roots.length > 1 ? "s" : ""})...`);
|
|
99
|
+
}
|
|
100
|
+
const result = await exportCompositeSkill({
|
|
101
|
+
bundleName,
|
|
102
|
+
projectRoots: roots,
|
|
103
|
+
outDir: options.out,
|
|
104
|
+
archive: options.archive,
|
|
105
|
+
workspaceRoot: options.workspace ? process.cwd() : undefined,
|
|
106
|
+
skillMdPath: options.skillMd,
|
|
107
|
+
customMdPath: options.customMd,
|
|
108
|
+
skillMdOnly: options.skillMdOnly,
|
|
109
|
+
});
|
|
110
|
+
renderResult(result, {
|
|
111
|
+
json: isMachine,
|
|
112
|
+
envelope: options.envelope,
|
|
113
|
+
humanFormatter: () => {
|
|
114
|
+
const lines = [];
|
|
115
|
+
lines.push(`[OK] Successfully exported Composite Skill: ${result.bundleName}`);
|
|
116
|
+
lines.push(` Packages: ${result.packagesCount}`);
|
|
117
|
+
lines.push(` Actions: ${result.actionsCount}`);
|
|
118
|
+
lines.push(` Playbooks: ${result.playbooksCount}`);
|
|
119
|
+
lines.push(` Skill Dir: ${result.skillDir}`);
|
|
120
|
+
if (result.skillMdFile) {
|
|
121
|
+
lines.push(` SKILL.md: Regenerated ${result.skillMdFile}`);
|
|
122
|
+
}
|
|
123
|
+
if (result.usedExistingSkillMd) {
|
|
124
|
+
lines.push(` SKILL.md: Reused existing file from ${result.usedExistingSkillMd}`);
|
|
125
|
+
}
|
|
126
|
+
if (result.archivePath) {
|
|
127
|
+
lines.push(` Archive: ${result.archivePath}`);
|
|
128
|
+
}
|
|
129
|
+
return lines.join("\n");
|
|
130
|
+
},
|
|
131
|
+
context,
|
|
132
|
+
});
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
if (roots.length > 1) {
|
|
136
|
+
if (!isMachine) {
|
|
137
|
+
writeStdout(`Batch exporting ${roots.length} Skill packages...`);
|
|
138
|
+
}
|
|
139
|
+
const batchRes = await exportSkillBatch({
|
|
140
|
+
projectRoots: roots,
|
|
141
|
+
mode,
|
|
142
|
+
outDir: options.out,
|
|
143
|
+
archive: options.archive,
|
|
144
|
+
playbooks: options.playbook,
|
|
145
|
+
actions: options.actions,
|
|
146
|
+
skillMdPath: options.skillMd,
|
|
147
|
+
vendorDeps: options.vendorDeps,
|
|
148
|
+
allowInstallScripts: options.allowInstallScripts,
|
|
149
|
+
requireReproducible: options.requireReproducible,
|
|
150
|
+
});
|
|
151
|
+
renderResult(batchRes, {
|
|
152
|
+
json: isMachine,
|
|
153
|
+
envelope: options.envelope,
|
|
154
|
+
humanFormatter: () => {
|
|
155
|
+
const lines = [];
|
|
156
|
+
lines.push(`[OK] Successfully batch exported ${batchRes.results.length} Skill packages to: ${batchRes.outDir}`);
|
|
157
|
+
for (const res of batchRes.results) {
|
|
158
|
+
lines.push(` - ${res.packageId} (v${res.version}): ${res.actionsCount} actions, ${res.playbooksCount} playbooks -> ${res.skillDir}`);
|
|
159
|
+
}
|
|
160
|
+
lines.push(` Total Actions: ${batchRes.totalActions}`);
|
|
161
|
+
lines.push(` Total Playbooks: ${batchRes.totalPlaybooks}`);
|
|
162
|
+
return lines.join("\n");
|
|
163
|
+
},
|
|
164
|
+
context,
|
|
165
|
+
});
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
const root = roots[0];
|
|
169
|
+
if (!isMachine) {
|
|
170
|
+
writeStdout(`Exporting ${mode === "node" ? "Node.js directory" : "source"} Skill artifact...`);
|
|
171
|
+
}
|
|
172
|
+
const result = await exportSkill({
|
|
173
|
+
projectRoot: root,
|
|
174
|
+
mode,
|
|
175
|
+
outDir: options.out,
|
|
176
|
+
archive: options.archive,
|
|
177
|
+
playbooks: options.playbook,
|
|
178
|
+
actions: options.actions,
|
|
179
|
+
skillMdPath: options.skillMd,
|
|
180
|
+
vendorDeps: options.vendorDeps,
|
|
181
|
+
allowInstallScripts: options.allowInstallScripts,
|
|
182
|
+
requireReproducible: options.requireReproducible,
|
|
183
|
+
});
|
|
184
|
+
renderResult(result, {
|
|
185
|
+
json: isMachine,
|
|
186
|
+
envelope: options.envelope,
|
|
187
|
+
humanFormatter: () => {
|
|
188
|
+
const lines = [];
|
|
189
|
+
lines.push(`[OK] Successfully exported ${result.mode === "node" ? "Node Directory" : "Source"} Skill: ${result.packageId} (v${result.version})`);
|
|
190
|
+
lines.push(` Mode: ${result.mode}`);
|
|
191
|
+
lines.push(` Actions: ${result.actionsCount}`);
|
|
192
|
+
lines.push(` Playbooks: ${result.playbooksCount}`);
|
|
193
|
+
lines.push(` Skill Dir: ${result.skillDir}`);
|
|
194
|
+
if (result.usedExistingSkillMd) {
|
|
195
|
+
lines.push(` SKILL.md: Reused existing file from ${result.usedExistingSkillMd}`);
|
|
196
|
+
}
|
|
197
|
+
if (result.archivePath) {
|
|
198
|
+
lines.push(` Archive: ${result.archivePath}`);
|
|
199
|
+
}
|
|
200
|
+
return lines.join("\n");
|
|
201
|
+
},
|
|
202
|
+
context,
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
catch (err) {
|
|
206
|
+
if (err?.code === "UNSUPPORTED_BUILD_MODE") {
|
|
207
|
+
throw new ExecutionError(err.message, undefined, "UNSUPPORTED_BUILD_MODE");
|
|
208
|
+
}
|
|
209
|
+
throw new ExecutionError(`Export failed: ${err.message}`);
|
|
210
|
+
}
|
|
211
|
+
});
|
|
212
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Command } from "commander";
|
|
2
|
+
import type { CliContext } from "../types.js";
|
|
3
|
+
/**
|
|
4
|
+
* 注册顶层 generate 代码与类型生成命令。
|
|
5
|
+
*
|
|
6
|
+
* @param program Commander 根程序对象
|
|
7
|
+
* @param context 命令行上下文
|
|
8
|
+
*/
|
|
9
|
+
export declare function registerGenerateCommands(program: Command, context?: CliContext): void;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { findProjectRoot, writeActionTypes } from "@actiondock/core";
|
|
2
|
+
import { ArgumentError, ExecutionError } from "../errors.js";
|
|
3
|
+
import { renderResult } from "../renderer.js";
|
|
4
|
+
import { getEffectiveOptions } from "../utils/index.js";
|
|
5
|
+
/**
|
|
6
|
+
* 注册顶层 generate 代码与类型生成命令。
|
|
7
|
+
*
|
|
8
|
+
* @param program Commander 根程序对象
|
|
9
|
+
* @param context 命令行上下文
|
|
10
|
+
*/
|
|
11
|
+
export function registerGenerateCommands(program, context) {
|
|
12
|
+
const generateCmd = program
|
|
13
|
+
.command("generate")
|
|
14
|
+
.description("Generate project artifacts such as TypeScript declarations");
|
|
15
|
+
generateCmd
|
|
16
|
+
.command("types")
|
|
17
|
+
.description("Generate .actiondock/generated/actions.d.ts from actiondock.json schema")
|
|
18
|
+
.option("--json", "Output as JSON")
|
|
19
|
+
.option("--envelope", "Wrap JSON output in standard envelope")
|
|
20
|
+
.action(async (rawOptions, cmd) => {
|
|
21
|
+
const options = getEffectiveOptions(rawOptions, cmd);
|
|
22
|
+
const root = findProjectRoot();
|
|
23
|
+
if (!root) {
|
|
24
|
+
throw new ArgumentError("Not in an ActionDock project (actiondock.json not found)");
|
|
25
|
+
}
|
|
26
|
+
try {
|
|
27
|
+
const { filePath, digest } = writeActionTypes(root);
|
|
28
|
+
const result = {
|
|
29
|
+
success: true,
|
|
30
|
+
filePath,
|
|
31
|
+
digest,
|
|
32
|
+
};
|
|
33
|
+
renderResult(result, {
|
|
34
|
+
json: options.json,
|
|
35
|
+
envelope: options.envelope,
|
|
36
|
+
humanFormatter: () => `[OK] Generated action types at ${filePath}\nManifest digest: ${digest}`,
|
|
37
|
+
context,
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
catch (err) {
|
|
41
|
+
throw new ExecutionError(`Failed to generate types: ${err.message}`);
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import type { CliContext } from "../types.js";
|
|
3
|
+
import { registerActionCommands } from "./action/create.js";
|
|
4
|
+
import { registerAddCommand } from "./add.js";
|
|
5
|
+
import { registerBuildCommand } from "./build.js";
|
|
6
|
+
import { registerConfigCommands } from "./config/index.js";
|
|
7
|
+
import { registerDescribeCommand } from "./describe.js";
|
|
8
|
+
import { registerDoctorCommand } from "./doctor.js";
|
|
9
|
+
import { registerExportCommand } from "./export.js";
|
|
10
|
+
import { registerGenerateCommands } from "./generate.js";
|
|
11
|
+
import { registerInfoCommand } from "./info.js";
|
|
12
|
+
import { registerInitCommand } from "./init.js";
|
|
13
|
+
import { registerLinkCommands } from "./link.js";
|
|
14
|
+
import { registerListCommand } from "./list.js";
|
|
15
|
+
import { registerMcpCommands } from "./mcp.js";
|
|
16
|
+
import { registerNewCommands } from "./new.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
|
+
/**
|
|
28
|
+
* CLI 版本号(来自 package.json 单一事实源)。
|
|
29
|
+
*/
|
|
30
|
+
export declare const CLI_VERSION: string;
|
|
31
|
+
export declare function createCliProgram(context?: CliContext): Command;
|
|
32
|
+
export { registerActionCommands, registerAddCommand, registerBuildCommand, registerConfigCommands, registerDescribeCommand, registerDoctorCommand, registerExportCommand, registerGenerateCommands, registerInfoCommand, registerInitCommand, registerLinkCommands, registerListCommand, registerMcpCommands, registerNewCommands, registerPackCommand, registerPlaybookCommands, registerProfileCommands, registerRemoveCommand, registerRunCommand, registerRunsCommands, registerServeCommand, registerStateCommands, registerTestCommand, registerValidateCommand, };
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { Command } from "commander";
|
|
4
|
+
import { registerActionCommands } from "./action/create.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 { registerNewCommands } from "./new.js";
|
|
18
|
+
import { registerPackCommand } from "./pack.js";
|
|
19
|
+
import { registerPlaybookCommands } from "./playbook.js";
|
|
20
|
+
import { registerProfileCommands } from "./profile.js";
|
|
21
|
+
import { registerRemoveCommand } from "./remove.js";
|
|
22
|
+
import { registerRunCommand } from "./run.js";
|
|
23
|
+
import { registerRunsCommands } from "./runs.js";
|
|
24
|
+
import { registerServeCommand } from "./serve.js";
|
|
25
|
+
import { registerStateCommands } from "./state.js";
|
|
26
|
+
import { registerTestCommand } from "./test.js";
|
|
27
|
+
import { registerValidateCommand } from "./validate.js";
|
|
28
|
+
/**
|
|
29
|
+
* 读取 CLI 自身 package.json 的版本号(单一事实源)。
|
|
30
|
+
* 兼容源码运行(src/commands)与构建产物运行(dist/commands)两种目录层级。
|
|
31
|
+
*/
|
|
32
|
+
function readCliVersion() {
|
|
33
|
+
try {
|
|
34
|
+
const pkgJson = JSON.parse(readFileSync(join(import.meta.dirname, "../../package.json"), "utf-8"));
|
|
35
|
+
return (pkgJson && pkgJson.version) || "0.0.0";
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
// package.json 缺失或损坏时回退占位版本,避免阻断启动
|
|
39
|
+
return "0.0.0";
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* CLI 版本号(来自 package.json 单一事实源)。
|
|
44
|
+
*/
|
|
45
|
+
export const CLI_VERSION = readCliVersion();
|
|
46
|
+
/**
|
|
47
|
+
* 递归注入全局通用选项。
|
|
48
|
+
*
|
|
49
|
+
* 输出纪律契约:--json/--envelope 对所有命令统一注入;已实现 renderResult
|
|
50
|
+
* 数据输出的命令会消费它们,未实现机器输出的命令(init、link、test、new、
|
|
51
|
+
* serve、mcp 等)将其作为无操作标志忽略,不影响人类输出行为。
|
|
52
|
+
* 错误信封由顶层 main 的 renderError 统一兜底,与命令实现解耦。
|
|
53
|
+
*/
|
|
54
|
+
function applyCommonOptions(cmd) {
|
|
55
|
+
const hasOpt = (flagName) => cmd.options.some((o) => o.name() === flagName || o.long === `--${flagName}`);
|
|
56
|
+
if (!hasOpt("json")) {
|
|
57
|
+
cmd.option("--json", "Output as JSON");
|
|
58
|
+
}
|
|
59
|
+
if (!hasOpt("envelope")) {
|
|
60
|
+
cmd.option("--envelope", "Wrap JSON output in standard envelope");
|
|
61
|
+
}
|
|
62
|
+
if (!hasOpt("dataDir") && !hasOpt("data-dir")) {
|
|
63
|
+
cmd.option("--data-dir <path>", "Custom database storage directory");
|
|
64
|
+
}
|
|
65
|
+
for (const sub of cmd.commands) {
|
|
66
|
+
applyCommonOptions(sub);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
export function createCliProgram(context) {
|
|
70
|
+
const program = new Command();
|
|
71
|
+
program
|
|
72
|
+
.name("ad")
|
|
73
|
+
.description("ActionDock (ad) 2.0 - Toolchain for building and shipping standalone AI Agent Actions & Skills")
|
|
74
|
+
.version(CLI_VERSION, "-v, --version");
|
|
75
|
+
program.option("-V", "output the version number");
|
|
76
|
+
program.on("option:V", () => {
|
|
77
|
+
program._outputConfiguration.writeOut(`${program.version()}\n`);
|
|
78
|
+
program._exit(0, "commander.version", program.version());
|
|
79
|
+
});
|
|
80
|
+
// 禁用 Commander 内部直接 process.exit,统一由顶层调度器管控退出码
|
|
81
|
+
program.exitOverride((err) => {
|
|
82
|
+
throw err;
|
|
83
|
+
});
|
|
84
|
+
registerInitCommand(program);
|
|
85
|
+
registerAddCommand(program, context);
|
|
86
|
+
registerRemoveCommand(program, context);
|
|
87
|
+
registerNewCommands(program, context);
|
|
88
|
+
registerActionCommands(program, context);
|
|
89
|
+
registerInfoCommand(program, context);
|
|
90
|
+
registerDoctorCommand(program, context);
|
|
91
|
+
registerListCommand(program, context);
|
|
92
|
+
registerDescribeCommand(program, context);
|
|
93
|
+
registerRunCommand(program, context);
|
|
94
|
+
registerValidateCommand(program, context);
|
|
95
|
+
registerGenerateCommands(program, context);
|
|
96
|
+
registerPlaybookCommands(program, context);
|
|
97
|
+
registerConfigCommands(program, context);
|
|
98
|
+
registerStateCommands(program, context);
|
|
99
|
+
registerRunsCommands(program, context);
|
|
100
|
+
registerTestCommand(program);
|
|
101
|
+
registerBuildCommand(program, context);
|
|
102
|
+
registerPackCommand(program, context);
|
|
103
|
+
registerExportCommand(program, context);
|
|
104
|
+
registerLinkCommands(program);
|
|
105
|
+
registerProfileCommands(program);
|
|
106
|
+
registerServeCommand(program, context);
|
|
107
|
+
registerMcpCommands(program, context);
|
|
108
|
+
applyCommonOptions(program);
|
|
109
|
+
return program;
|
|
110
|
+
}
|
|
111
|
+
export { registerActionCommands, registerAddCommand, registerBuildCommand, registerConfigCommands, registerDescribeCommand, registerDoctorCommand, registerExportCommand, registerGenerateCommands, registerInfoCommand, registerInitCommand, registerLinkCommands, registerListCommand, registerMcpCommands, registerNewCommands, registerPackCommand, registerPlaybookCommands, registerProfileCommands, registerRemoveCommand, registerRunCommand, registerRunsCommands, registerServeCommand, registerStateCommands, registerTestCommand, registerValidateCommand, };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import type { CliContext } from "../types.js";
|
|
3
|
+
/**
|
|
4
|
+
* 注册 info 命令。
|
|
5
|
+
*
|
|
6
|
+
* @param program Commander 实例
|
|
7
|
+
* @param context 命令行上下文
|
|
8
|
+
*/
|
|
9
|
+
export declare function registerInfoCommand(program: Command, context?: CliContext): void;
|