@actiondock/cli 2.0.12 → 2.2.1

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 (100) hide show
  1. package/README.md +41 -34
  2. package/bin/ad.js +28 -41
  3. package/dist/commands/action/create.d.ts +9 -1
  4. package/dist/commands/action/create.js +120 -0
  5. package/dist/commands/add.d.ts +7 -0
  6. package/dist/commands/add.js +144 -0
  7. package/dist/commands/build.d.ts +2 -1
  8. package/dist/commands/build.js +83 -0
  9. package/dist/commands/config/delete.d.ts +9 -0
  10. package/dist/commands/config/delete.js +52 -0
  11. package/dist/commands/config/env.d.ts +9 -0
  12. package/dist/commands/config/env.js +85 -0
  13. package/dist/commands/config/get.d.ts +9 -0
  14. package/dist/commands/config/get.js +120 -0
  15. package/dist/commands/config/index.d.ts +9 -0
  16. package/dist/commands/config/index.js +23 -0
  17. package/dist/commands/config/list.d.ts +9 -0
  18. package/dist/commands/config/list.js +137 -0
  19. package/dist/commands/config/schema.d.ts +9 -0
  20. package/dist/commands/config/schema.js +121 -0
  21. package/dist/commands/config/set.d.ts +9 -0
  22. package/dist/commands/config/set.js +85 -0
  23. package/dist/commands/describe.d.ts +9 -0
  24. package/dist/commands/describe.js +68 -0
  25. package/dist/commands/doctor.d.ts +2 -1
  26. package/dist/commands/doctor.js +82 -0
  27. package/dist/commands/export.d.ts +2 -1
  28. package/dist/commands/export.js +212 -0
  29. package/dist/commands/generate.d.ts +9 -0
  30. package/dist/commands/generate.js +44 -0
  31. package/dist/commands/index.d.ts +31 -1
  32. package/dist/commands/index.js +111 -0
  33. package/dist/commands/info.d.ts +9 -2
  34. package/dist/commands/info.js +210 -0
  35. package/dist/commands/init.js +24 -0
  36. package/dist/commands/link.js +71 -0
  37. package/dist/commands/list.d.ts +9 -0
  38. package/dist/commands/list.js +77 -0
  39. package/dist/commands/mcp.d.ts +9 -2
  40. package/dist/commands/mcp.js +173 -0
  41. package/dist/commands/new.d.ts +9 -0
  42. package/dist/commands/new.js +33 -0
  43. package/dist/commands/pack.d.ts +3 -0
  44. package/dist/commands/pack.js +63 -0
  45. package/dist/commands/playbook.d.ts +7 -3
  46. package/dist/commands/playbook.js +433 -0
  47. package/dist/commands/profile.js +253 -0
  48. package/dist/commands/remove.d.ts +7 -0
  49. package/dist/commands/remove.js +118 -0
  50. package/dist/commands/run.d.ts +13 -0
  51. package/dist/commands/run.js +146 -0
  52. package/dist/commands/runs.d.ts +9 -2
  53. package/dist/commands/runs.js +245 -0
  54. package/dist/commands/serve.d.ts +9 -2
  55. package/dist/commands/serve.js +135 -0
  56. package/dist/commands/state-list.d.ts +24 -0
  57. package/dist/commands/state-list.js +82 -0
  58. package/dist/commands/state.d.ts +9 -2
  59. package/dist/commands/state.js +310 -0
  60. package/dist/commands/test.js +44 -0
  61. package/dist/commands/validate.d.ts +9 -0
  62. package/dist/commands/validate.js +106 -0
  63. package/dist/errors.d.ts +43 -0
  64. package/dist/errors.js +103 -0
  65. package/dist/index.d.ts +8 -1
  66. package/dist/index.js +41 -1000
  67. package/dist/prompt.d.ts +53 -0
  68. package/dist/prompt.js +192 -0
  69. package/dist/renderer.d.ts +197 -0
  70. package/dist/renderer.js +502 -0
  71. package/dist/services/index.d.ts +1 -0
  72. package/dist/services/index.js +1 -0
  73. package/dist/services/inspect.d.ts +23 -0
  74. package/dist/services/inspect.js +96 -0
  75. package/dist/standalone/index.d.ts +16 -0
  76. package/dist/standalone/index.js +22 -0
  77. package/dist/types.d.ts +132 -0
  78. package/dist/types.js +9 -0
  79. package/dist/utils/bytes.d.ts +1 -1
  80. package/dist/utils/bytes.js +1 -0
  81. package/dist/utils/duration.js +1 -0
  82. package/dist/utils/filter.d.ts +1 -1
  83. package/dist/utils/filter.js +1 -0
  84. package/dist/utils/index.d.ts +6 -0
  85. package/dist/utils/index.js +6 -0
  86. package/dist/utils/spawn.d.ts +27 -0
  87. package/dist/utils/spawn.js +35 -0
  88. package/dist/utils/target.d.ts +45 -0
  89. package/dist/utils/target.js +78 -0
  90. package/dist/utils/utils.d.ts +38 -0
  91. package/dist/utils/utils.js +111 -0
  92. package/package.json +10 -12
  93. package/dist/commands/action/index.d.ts +0 -16
  94. package/dist/commands/action/list.d.ts +0 -5
  95. package/dist/commands/action/run.d.ts +0 -4
  96. package/dist/commands/action/show.d.ts +0 -5
  97. package/dist/commands/action/sync.d.ts +0 -2
  98. package/dist/commands/action/validate.d.ts +0 -5
  99. package/dist/commands/action.d.ts +0 -1
  100. package/dist/commands/config.d.ts +0 -2
@@ -0,0 +1,173 @@
1
+ import { resolve } from "node:path";
2
+ import { findProjectRoot, formatHostForUrl, loadProjectConfig, parseDuration } from "@actiondock/core";
3
+ import { ArgumentError, ExecutionError } from "../errors.js";
4
+ import { writeStdout } from "../renderer.js";
5
+ import { getEffectiveOptions, parseByteSize, parseListOption } from "../utils/index.js";
6
+ /**
7
+ * 注册 mcp 命令(STDIO 与 HTTP 传输服务模式)。
8
+ *
9
+ * @param program Commander 实例
10
+ * @param context 命令行上下文
11
+ */
12
+ export function registerMcpCommands(program, context) {
13
+ const mcpCommand = program
14
+ .command("mcp")
15
+ .description("Model Context Protocol (MCP) server for ActionDock Actions (STDIO default)")
16
+ .option("-d, --dir <path>", "Project root directory or directories (can be specified multiple times or comma-separated)", parseListOption, [])
17
+ .option("--package <package-id>", "Specific linked package ID(s) to serve (can be specified multiple times or comma-separated)", parseListOption, [])
18
+ .option("--all", "Serve all linked packages from global registry")
19
+ .option("--timeout <duration>", "Execution timeout (e.g. 30s, 5m, 500ms)")
20
+ .option("--allow-insecure-http", "Allow insecure HTTP connections with auth token (INSECURE)")
21
+ .action(async (rawOptions, cmd) => {
22
+ const options = getEffectiveOptions(rawOptions, cmd);
23
+ let timeoutMs;
24
+ if (options.timeout) {
25
+ try {
26
+ timeoutMs = parseDuration(options.timeout);
27
+ }
28
+ catch (err) {
29
+ throw new ArgumentError(`Invalid timeout format: ${err.message}`);
30
+ }
31
+ }
32
+ const projectRoots = options.dir && options.dir.length > 0
33
+ ? options.dir.map((d) => resolve(d))
34
+ : undefined;
35
+ const packageIds = options.package && options.package.length > 0 ? options.package : undefined;
36
+ const all = Boolean(options.all);
37
+ try {
38
+ const { startMcpStdio } = await import("@actiondock/mcp");
39
+ await startMcpStdio({
40
+ projectRoots,
41
+ packageIds,
42
+ all,
43
+ timeoutMs,
44
+ });
45
+ }
46
+ catch (err) {
47
+ throw new ExecutionError(`Failed to start MCP STDIO server: ${err.message}`, err);
48
+ }
49
+ });
50
+ mcpCommand
51
+ .command("serve")
52
+ .description("Start the ActionDock MCP server over HTTP transport")
53
+ .option("-p, --port <port>", "Port to listen on (default: 5178)", "5178")
54
+ .option("-H, --host <host>", "Host address to bind to (default: 127.0.0.1)", "127.0.0.1")
55
+ .option("-t, --token <token>", "Authentication token for securing the endpoint (or set ACTIONDOCK_TOKEN)")
56
+ .option("--token-env <env>", "Environment variable name containing the authentication token")
57
+ .option("--allow-insecure-no-auth", "Allow non-loopback host binding without authentication token (INSECURE)")
58
+ .option("--allow-insecure-http", "Allow insecure HTTP connections with auth token (INSECURE)")
59
+ .option("--allow-query-token", "Allow passing authentication token via URL query parameter (INSECURE)")
60
+ .option("--cors-origin <origin>", "Allowed CORS origin (can be specified multiple times)", (val, prev = []) => [...prev, val], [])
61
+ .option("--max-body <size>", "Maximum allowed JSON request body size (e.g. 1mb, 500kb)", "1mb")
62
+ .option("-d, --dir <path>", "Project root directory or directories (can be specified multiple times or comma-separated)", parseListOption, [])
63
+ .option("--package <package-id>", "Specific linked package ID(s) to serve (can be specified multiple times or comma-separated)", parseListOption, [])
64
+ .option("--all", "Serve all linked packages from global registry")
65
+ .option("--timeout <duration>", "Execution timeout (e.g. 30s, 5m, 500ms)")
66
+ .action(async (rawOptions, cmd) => {
67
+ const options = getEffectiveOptions(rawOptions, cmd);
68
+ const port = parseInt(options.port, 10) || 5178;
69
+ const host = options.host || "127.0.0.1";
70
+ const token = options.token ||
71
+ (options.tokenEnv && typeof process !== "undefined" ? process.env?.[options.tokenEnv] : undefined) ||
72
+ (typeof process !== "undefined" ? process.env?.ACTIONDOCK_TOKEN : undefined);
73
+ const allowInsecureNoAuth = Boolean(options.allowInsecureNoAuth);
74
+ const allowInsecureHttp = Boolean(options.allowInsecureHttp);
75
+ const allowQueryToken = Boolean(options.allowQueryToken);
76
+ const corsOrigins = options.corsOrigin && options.corsOrigin.length > 0 ? options.corsOrigin : undefined;
77
+ let maxBodyBytes;
78
+ if (options.maxBody) {
79
+ try {
80
+ maxBodyBytes = parseByteSize(options.maxBody);
81
+ }
82
+ catch (err) {
83
+ throw new ArgumentError(`Invalid max-body format: ${err.message}`);
84
+ }
85
+ }
86
+ let timeoutMs;
87
+ if (options.timeout) {
88
+ try {
89
+ timeoutMs = parseDuration(options.timeout);
90
+ }
91
+ catch (err) {
92
+ throw new ArgumentError(`Invalid timeout format: ${err.message}`);
93
+ }
94
+ }
95
+ const projectRoots = options.dir && options.dir.length > 0
96
+ ? options.dir.map((d) => resolve(d))
97
+ : undefined;
98
+ const packageIds = options.package && options.package.length > 0 ? options.package : undefined;
99
+ const all = Boolean(options.all);
100
+ let targetDescription = "ActionDock MCP Server";
101
+ if (all) {
102
+ targetDescription = "All Linked Packages (Global Registry Mode)";
103
+ }
104
+ else if (packageIds && packageIds.length > 1) {
105
+ targetDescription = `Packages: ${packageIds.join(", ")}`;
106
+ }
107
+ else if (projectRoots && projectRoots.length > 1) {
108
+ targetDescription = `Directories: ${projectRoots.join(", ")}`;
109
+ }
110
+ else if (projectRoots && projectRoots.length === 1) {
111
+ try {
112
+ const config = loadProjectConfig(projectRoots[0]);
113
+ targetDescription = `${config.name} (${config.id})`;
114
+ }
115
+ catch {
116
+ targetDescription = projectRoots[0];
117
+ }
118
+ }
119
+ else if (packageIds && packageIds.length === 1) {
120
+ targetDescription = `Package: ${packageIds[0]}`;
121
+ }
122
+ else {
123
+ const currentRoot = findProjectRoot(process.cwd());
124
+ if (currentRoot) {
125
+ try {
126
+ const config = loadProjectConfig(currentRoot);
127
+ targetDescription = `${config.name} (${config.id})`;
128
+ }
129
+ catch {
130
+ targetDescription = currentRoot;
131
+ }
132
+ }
133
+ }
134
+ try {
135
+ const { startMcpHttpServer } = await import("@actiondock/mcp");
136
+ const server = await startMcpHttpServer({
137
+ port,
138
+ host,
139
+ token,
140
+ allowInsecureNoAuth,
141
+ allowInsecureHttp,
142
+ allowQueryToken,
143
+ corsOrigins,
144
+ maxBodyBytes,
145
+ projectRoots,
146
+ packageIds,
147
+ all,
148
+ timeoutMs,
149
+ });
150
+ const displayHost = formatHostForUrl(host);
151
+ const actualMcpHost = formatHostForUrl(host === "0.0.0.0" ? "127.0.0.1" : host);
152
+ writeStdout(`\n======================================================`, context);
153
+ writeStdout(` ActionDock 2.0 MCP HTTP Server`, context);
154
+ writeStdout(`======================================================`, context);
155
+ writeStdout(` * Listening on: http://${displayHost}:${server.port}`, context);
156
+ writeStdout(` * MCP Endpoint: http://${actualMcpHost}:${server.port}/mcp`, context);
157
+ writeStdout(` * Target: ${targetDescription}`, context);
158
+ writeStdout(` * Authentication: ${token ? "Bearer Token Enabled" : "Disabled (Local)"}`, context);
159
+ writeStdout(` * CORS Origins: ${corsOrigins ? corsOrigins.join(", ") : "Disabled (Default)"}`, context);
160
+ writeStdout(`======================================================\n`, context);
161
+ writeStdout(`Press Ctrl+C to terminate.\n`, context);
162
+ const stopSignalHandler = () => {
163
+ writeStdout("\nStopping MCP HTTP server...", context);
164
+ server.stop();
165
+ };
166
+ process.once("SIGINT", stopSignalHandler);
167
+ process.once("SIGTERM", stopSignalHandler);
168
+ }
169
+ catch (err) {
170
+ throw new ExecutionError(`Failed to start ActionDock MCP HTTP server: ${err.message}`, err);
171
+ }
172
+ });
173
+ }
@@ -0,0 +1,9 @@
1
+ import type { Command } from "commander";
2
+ import type { CliContext } from "../types.js";
3
+ /**
4
+ * 注册顶层 new 脚手架命令(new action, new playbook)。
5
+ *
6
+ * @param program Commander 根程序对象
7
+ * @param context 命令行上下文
8
+ */
9
+ export declare function registerNewCommands(program: Command, context?: CliContext): void;
@@ -0,0 +1,33 @@
1
+ import { handleActionCreate } from "./action/create.js";
2
+ import { handlePlaybookCreate } from "./playbook.js";
3
+ /**
4
+ * 注册顶层 new 脚手架命令(new action, new playbook)。
5
+ *
6
+ * @param program Commander 根程序对象
7
+ * @param context 命令行上下文
8
+ */
9
+ export function registerNewCommands(program, context) {
10
+ const newCmd = program
11
+ .command("new")
12
+ .description("Scaffold a new Action or Playbook in current project");
13
+ // new action <id>
14
+ newCmd
15
+ .command("action <id>")
16
+ .alias("create")
17
+ .description("Scaffold a new Action definition file")
18
+ .option("-d, --desc <description>", "Action description")
19
+ .option("-f, --file <filePath>", "Target file path relative to actions dir")
20
+ .action(async (id, options) => {
21
+ await handleActionCreate(id, options, context);
22
+ });
23
+ // new playbook <id>
24
+ newCmd
25
+ .command("playbook <id>")
26
+ .description("Scaffold a new Playbook markdown file")
27
+ .option("-d, --desc <description>", "Playbook description")
28
+ .option("-a, --actions <actions...>", "Referenced action IDs")
29
+ .option("-f, --file <filePath>", "Target file path relative to playbooks dir")
30
+ .action((id, options) => {
31
+ handlePlaybookCreate(id, options, context);
32
+ });
33
+ }
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ import type { CliContext } from "../types.js";
3
+ export declare function registerPackCommand(program: Command, context?: CliContext): void;
@@ -0,0 +1,63 @@
1
+ import { findProjectRoot, resolvePackageRoot } from "@actiondock/core";
2
+ import { ExecutionError } from "../errors.js";
3
+ import { renderResult, writeStdout } from "../renderer.js";
4
+ import { getEffectiveOptions } from "../utils/index.js";
5
+ export function registerPackCommand(program, context) {
6
+ program
7
+ .command("pack")
8
+ .description("Pack Action package into a standard npm tarball (.tgz) for distribution")
9
+ .option("-P, --package <id>", "Target package ID or path")
10
+ .option("-o, --out <path>", "Output directory for the .tgz package")
11
+ .option("--dry-run", "Validate and show package summary without creating .tgz")
12
+ .option("--json", "Output as JSON")
13
+ .action(async (rawOptions, cmd) => {
14
+ const options = getEffectiveOptions(rawOptions, cmd);
15
+ const root = options.package
16
+ ? resolvePackageRoot(options.package)
17
+ : findProjectRoot();
18
+ if (!root) {
19
+ if (options.package) {
20
+ throw new ExecutionError(`Package '${options.package}' not found in linked packages or path`);
21
+ }
22
+ throw new ExecutionError("Not in an ActionDock project (actiondock.json not found).\nPlease specify -P, --package <id> or cd into a project directory.");
23
+ }
24
+ const isMachine = Boolean(options.json || options.envelope);
25
+ if (!isMachine && !options.dryRun) {
26
+ writeStdout("Packing Action package...");
27
+ }
28
+ let result;
29
+ try {
30
+ const { packProject } = await import("@actiondock/builder");
31
+ result = await packProject({
32
+ projectRoot: root,
33
+ outDir: options.out,
34
+ dryRun: options.dryRun,
35
+ });
36
+ }
37
+ catch (err) {
38
+ throw new ExecutionError(`Pack failed: ${err.message}`);
39
+ }
40
+ renderResult(result, {
41
+ json: isMachine,
42
+ envelope: options.envelope,
43
+ humanFormatter: () => {
44
+ const lines = [];
45
+ if (options.dryRun) {
46
+ lines.push(`[OK] Pack dry-run passed for ${result.packageId} (v${result.version})`);
47
+ lines.push(` Tarball Name: ${result.tarballName}`);
48
+ lines.push(` Actions: ${result.manifestSummary.actions.join(", ")}`);
49
+ lines.push(` Files Count: ${result.manifestSummary.filesCount}`);
50
+ lines.push(" Notice: Dry-run mode enabled, no tarball was generated.");
51
+ return lines.join("\n");
52
+ }
53
+ lines.push(`[OK] Successfully packed ${result.packageId} (v${result.version})`);
54
+ lines.push(` Tarball: ${result.tarballPath}`);
55
+ lines.push(` Size: ${result.sizeBytes} bytes`);
56
+ lines.push(` SHA-256: ${result.sha256}`);
57
+ lines.push(` Actions: ${result.manifestSummary.actions.join(", ")}`);
58
+ return lines.join("\n");
59
+ },
60
+ context,
61
+ });
62
+ });
63
+ }
@@ -1,6 +1,10 @@
1
1
  import { Command } from "commander";
2
+ import type { CliContext } from "../types.js";
2
3
  /**
3
- * 注册 Playbook 命令集合。
4
- * 委托 list, show, validate 至 @actiondock/runtime-cli,保留开发者专用的 create 命令。
4
+ * 注册 Playbook 命令集合(list, show, validate, create)。
5
+ *
6
+ * @param program Commander 根程序对象
7
+ * @param context 命令行上下文
5
8
  */
6
- export declare function registerPlaybookCommands(program: Command): void;
9
+ export declare function registerPlaybookCommands(program: Command, context?: CliContext): void;
10
+ export declare function handlePlaybookCreate(id: string, options: any, context?: CliContext): void;