@actiondock/cli 2.0.0 → 2.0.2

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 CHANGED
@@ -6,20 +6,19 @@ The official Command Line Interface (CLI) toolchain for ActionDock 2.0.
6
6
  [![TypeScript](https://img.shields.io/badge/TypeScript-5.0+-blue?logo=typescript)](https://www.typescriptlang.org/)
7
7
  [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
8
8
 
9
- > **Runtime requirement**: [Bun](https://bun.sh/) >= 1.2.0 is required.
10
- > *(ActionDock CLI relies natively on Bun. Even if you install via `npm install -g @actiondock/cli`, Bun must be installed on your machine as the executable shebang runs via `#!/usr/bin/env bun`.)*
9
+ > **Runtime requirement**: [Bun](https://bun.sh/) >= 1.2.0.
11
10
 
12
- `@actiondock/cli` provides the `ac` command to develop, test, build, deploy, and export AI Agent Actions and Skills across MCP, HTTP, CLI, and standalone executables.
11
+ `@actiondock/cli` provides the `ad` command to develop, test, build, deploy, and export AI Agent Actions and Skills across MCP, HTTP, CLI, and standalone executables.
13
12
 
14
13
  ---
15
14
 
16
15
  ## Installation
17
16
 
18
17
  ```bash
19
- # Global installation via Bun
20
- bun add -g @actiondock/cli
18
+ # 1. Install Bun runtime (if not already installed)
19
+ npm install -g bun
21
20
 
22
- # Or via npm
21
+ # 2. Install ActionDock CLI
23
22
  npm install -g @actiondock/cli
24
23
  ```
25
24
 
@@ -29,20 +28,20 @@ npm install -g @actiondock/cli
29
28
 
30
29
  ```bash
31
30
  # 1. Initialize a new Action package scaffold
32
- ac init my-tools
31
+ ad init my-tools
33
32
  cd my-tools
34
33
 
35
34
  # 2. Run an Action locally (outputs standard JSON envelope)
36
- ac run sample.greet --input '{"name": "Alice"}'
35
+ ad run sample.greet --input '{"name": "Alice"}'
37
36
 
38
37
  # 3. Run in-memory unit tests
39
- ac test
38
+ ad test
40
39
 
41
40
  # 4. Compile into a single standalone binary
42
- ac build
41
+ ad build
43
42
 
44
43
  # 5. Export as a portable Agent Skill (with SOPs)
45
- ac export skill
44
+ ad export skill
46
45
  ```
47
46
 
48
47
  ---
@@ -51,35 +50,35 @@ ac export skill
51
50
 
52
51
  | Command | Purpose |
53
52
  |---|---|
54
- | `ac init [dir]` | Initialize an Action package scaffold |
55
- | `ac info [patterns...]` | Explore capabilities and display metadata (supports fuzzy matching and `--tree`) |
56
- | `ac doctor` | Run environment, global registry health, and project diagnostics |
57
- | `ac action list` / `ac run <id>` | List and execute Actions |
58
- | `ac playbook list` / `show` | Inspect agent task SOP Playbooks |
59
- | `ac config list` / `get` / `set` | Manage runtime configurations |
60
- | `ac state list` / `get` / `set` / `delete` / `clear` | Inspect and manage persistent state (with namespaces, TTL, and clear) |
61
- | `ac runs list` / `show` | Inspect execution history and traces |
62
- | `ac test` | Run fast unit tests |
63
- | `ac build` | Compile into a zero-dependency standalone binary |
64
- | `ac export skill` | Export Skill bundle for AI Agent platforms |
65
- | `ac link` / `unlink` | Manage global router (with live subproject auto-discovery and prune) |
66
- | `ac profile` / `ac serve` | Manage remote node profiles and start HTTP Runner |
67
- | `ac mcp` | Start ActionDock as STDIO or HTTP MCP server |
53
+ | `ad init [dir]` | Initialize an Action package scaffold |
54
+ | `ad info [patterns...]` | Explore capabilities and display metadata (supports fuzzy matching and `--tree`) |
55
+ | `ad doctor` | Run environment, global registry health, and project diagnostics |
56
+ | `ad action list` / `ad run <id>` | List and execute Actions |
57
+ | `ad playbook list` / `show` | Inspect agent task SOP Playbooks |
58
+ | `ad config list` / `get` / `set` | Manage runtime configurations |
59
+ | `ad state list` / `get` / `set` / `delete` / `clear` | Inspect and manage persistent state (with namespaces, TTL, and clear) |
60
+ | `ad runs list` / `show` | Inspect execution history and traces |
61
+ | `ad test` | Run fast unit tests |
62
+ | `ad build` | Compile into a zero-dependency standalone binary |
63
+ | `ad export skill` | Export Skill bundle for AI Agent platforms |
64
+ | `ad link` / `unlink` | Manage global router (with live subproject auto-discovery and prune) |
65
+ | `ad profile` / `ad serve` | Manage remote node profiles and start HTTP Runner |
66
+ | `ad mcp` | Start ActionDock as STDIO or HTTP MCP server |
68
67
 
69
68
  ---
70
69
 
71
70
  ## 📖 Complete Documentation
72
71
 
73
- For the full list of flags, options, remote profiles, and advanced usage, refer to the [ActionDock Documentation Center](https://github.com/team4u/actiondock#readme):
72
+ For the full list of flags, options, remote profiles, and advanced usage, refer to the [ActionDock Documentation Center](../../docs/README.md):
74
73
 
75
- - [CLI Reference Manual](https://github.com/team4u/actiondock/blob/main/docs/reference/cli.md)
76
- - [Quick Start Guide](https://github.com/team4u/actiondock/blob/main/docs/getting-started/quick-start.md)
77
- - [MCP Integration Guide](https://github.com/team4u/actiondock/blob/main/docs/guides/mcp.md)
78
- - [Standalone Binary Build Guide](https://github.com/team4u/actiondock/blob/main/docs/guides/standalone-build.md)
79
- - [Skill Export Guide](https://github.com/team4u/actiondock/blob/main/docs/guides/skill-export.md)
74
+ - [CLI Reference Manual](../../docs/reference/cli.md)
75
+ - [Quick Start Guide](../../docs/developer/quick-start.md)
76
+ - [MCP Integration Guide](../../docs/consumer/use-as-mcp.md)
77
+ - [Standalone Binary Build Guide](../../docs/developer/build-and-export.md)
78
+ - [Agent Skill Usage Guide](../../docs/consumer/use-as-skill.md)
80
79
 
81
80
  ---
82
81
 
83
82
  ## License
84
83
 
85
- [Apache-2.0](LICENSE) © team4u
84
+ [Apache-2.0](../../LICENSE) © team4u
package/package.json CHANGED
@@ -1,10 +1,11 @@
1
1
  {
2
2
  "name": "@actiondock/cli",
3
- "version": "2.0.0",
3
+ "version": "2.0.2",
4
4
  "description": "ActionDock CLI facade for developing, testing, building, and exporting standalone Agent Actions and Skills",
5
5
  "type": "module",
6
6
  "bin": {
7
- "ac": "./bin/ac.js"
7
+ "ad": "./bin/ad.js",
8
+ "actiondock": "./bin/ad.js"
8
9
  },
9
10
  "main": "./src/index.ts",
10
11
  "module": "./src/index.ts",
@@ -36,7 +37,7 @@
36
37
  "@types/bun": "latest",
37
38
  "typescript": "^5.7.0"
38
39
  },
39
- "keywords": ["actiondock", "ac", "agent", "cli", "skill", "builder", "mcp"],
40
+ "keywords": ["actiondock", "ad", "agent", "cli", "skill", "builder", "mcp"],
40
41
  "author": "team4u",
41
42
  "license": "Apache-2.0",
42
43
  "repository": {
@@ -113,7 +113,7 @@ export function registerActionCommands(program: Command): void {
113
113
  const linkedList = listLinkedPackages();
114
114
  if (linkedList.length === 0) {
115
115
  console.log("No ActionDock project in current directory, and no packages linked.");
116
- console.log("Run 'ac link' inside an Action package to register it.");
116
+ console.log("Run 'ad link' inside an Action package to register it.");
117
117
  return;
118
118
  }
119
119
 
@@ -283,7 +283,7 @@ export default defineAction<Input, Output>({
283
283
  writeFileSync(targetFullFile, template, "utf-8");
284
284
  console.log(`[OK] Created Action '${id}' at ${targetFullFile}`);
285
285
  console.log(`\nTo run this action:`);
286
- console.log(` ac action run ${id} --input '{"exampleParam": "hello"}'`);
286
+ console.log(` ad action run ${id} --input '{"exampleParam": "hello"}'`);
287
287
  } catch (err: any) {
288
288
  console.error(`Error: ${err.message}`);
289
289
  process.exit(1);
@@ -454,10 +454,10 @@ export default defineAction<Input, Output>({
454
454
  await executeAction(id, options);
455
455
  });
456
456
 
457
- // Root level alias: ac run <id>
457
+ // Root level alias: ad run <id>
458
458
  program
459
459
  .command("run <id>")
460
- .description("Alias for 'ac action run <id>'")
460
+ .description("Alias for 'ad action run <id>'")
461
461
  .option("-i, --input <json>", "Input as JSON string")
462
462
  .option("-f, --input-file <path>", "Input from JSON file")
463
463
  .option("-c, --config <key=value...>", "Temporary config override")
@@ -551,7 +551,7 @@ async function executeAction(id: string, options: any): Promise<void> {
551
551
  // Local execution
552
552
  if (options.async) {
553
553
  console.error(
554
- "Error: Async execution requires a long-running ActionDock server.\nUse --profile, --server, or start `ac serve`."
554
+ "Error: Async execution requires a long-running ActionDock server.\nUse --profile, --server, or start `ad serve`."
555
555
  );
556
556
  process.exit(1);
557
557
  }
@@ -1,11 +1,15 @@
1
1
  import {
2
2
  createGlobalStorage,
3
3
  createStorage,
4
+ deleteRemoteConfig,
5
+ fetchRemoteConfig,
4
6
  filterWithFallbackInfo,
5
7
  isSecretConfigKey,
6
8
  loadProjectConfig,
7
9
  maskSecretValue,
8
10
  resolvePackageRoot,
11
+ resolveTarget,
12
+ setRemoteConfig,
9
13
  type ConfigItemDefinition,
10
14
  } from "@actiondock/core";
11
15
  import { Command } from "commander";
@@ -28,7 +32,7 @@ export function registerConfigCommands(program: Command): void {
28
32
  const root = resolvePackageRoot(identifier || options.package);
29
33
  if (!root) {
30
34
  console.error(
31
- "Error: Not in an ActionDock project.\nUsage: ac config schema [package-id] or cd into a project directory."
35
+ "Error: Not in an ActionDock project.\nUsage: ad config schema [package-id] or cd into a project directory."
32
36
  );
33
37
  process.exit(1);
34
38
  }
@@ -69,18 +73,17 @@ export function registerConfigCommands(program: Command): void {
69
73
  resolvedValue = itemDef.default;
70
74
  source = "default";
71
75
  status = "DEFAULT";
72
- } else {
73
- status = "MISSING";
74
76
  }
75
77
 
78
+ const displayValue = isSecret && resolvedValue !== undefined ? maskSecretValue(resolvedValue) : resolvedValue;
79
+
76
80
  return {
77
81
  key,
78
- description: itemDef.description || "",
79
- secret: isSecret,
80
- default: itemDef.default,
82
+ value: displayValue,
81
83
  status,
82
84
  source,
83
- value: isSecret && resolvedValue !== undefined ? maskSecretValue(resolvedValue) : resolvedValue,
85
+ secret: isSecret,
86
+ description: itemDef.description || "",
84
87
  required: itemDef.default === undefined,
85
88
  };
86
89
  });
@@ -123,7 +126,7 @@ export function registerConfigCommands(program: Command): void {
123
126
  if (missingRequired.length > 0) {
124
127
  console.log(`\n[WARNING] ${missingRequired.length} required config(s) not set:`);
125
128
  for (const m of missingRequired) {
126
- console.log(` - ${m.key}: Run 'ac config set ${m.key} <value>' to configure.`);
129
+ console.log(` - ${m.key}: Run 'ad config set ${m.key} <value>' to configure.`);
127
130
  }
128
131
  } else {
129
132
  console.log("\n[OK] All configuration dependencies are satisfied.");
@@ -141,16 +144,45 @@ export function registerConfigCommands(program: Command): void {
141
144
  .description("List configuration entries (Global & Project)")
142
145
  .option("-P, --package <id>", "Target package ID or path")
143
146
  .option("-g, --global", "Show only global configurations")
147
+ .option("-p, --profile <name>", "Query config on a remote target")
148
+ .option("-s, --server <url>", "Remote server URL")
149
+ .option("-t, --token <token>", "Auth token for remote server")
144
150
  .option("-i, --intent <pattern>", "Regex or fuzzy intent filter; falls back to full list when no match")
145
151
  .option("--reveal, --show-secrets", "Reveal plain text values for secrets")
146
152
  .option("--no-fallback", "Disable fallback to full list when no items match intent")
147
153
  .option("--json", "Output as JSON")
148
- .action((patterns, options) => {
154
+ .action(async (patterns, options) => {
149
155
  try {
150
156
  const effectiveIntent = resolveIntent(options.intent, patterns);
151
157
  const shouldFallback = options.fallback !== false;
152
158
  const reveal = options.reveal || options.showSecrets;
153
159
 
160
+ const target = resolveTarget({
161
+ profile: options.profile,
162
+ server: options.server,
163
+ token: options.token,
164
+ });
165
+
166
+ if (target.type === "remote") {
167
+ const res = await fetchRemoteConfig(target.serverUrl!, target.token, options.package);
168
+ if (options.json) {
169
+ console.log(JSON.stringify(res, null, 2));
170
+ return;
171
+ }
172
+ console.log(
173
+ `Config on remote server ${target.serverUrl}${target.profileName ? ` (Profile: ${target.profileName})` : ""}:\n`
174
+ );
175
+ const entries = Object.entries(res.values || {});
176
+ if (entries.length === 0) {
177
+ console.log(" (No config entries stored)");
178
+ } else {
179
+ for (const [k, v] of entries) {
180
+ console.log(` ${k.padEnd(24)} = ${JSON.stringify(v)}`);
181
+ }
182
+ }
183
+ return;
184
+ }
185
+
154
186
  const globalStorage = createGlobalStorage();
155
187
  const globalConfig = globalStorage.listConfig();
156
188
 
@@ -246,10 +278,30 @@ export function registerConfigCommands(program: Command): void {
246
278
  .description("Get a configuration value")
247
279
  .option("-P, --package <id>", "Target package ID or path")
248
280
  .option("-g, --global", "Get from global configuration only")
281
+ .option("-p, --profile <name>", "Query config on a remote target")
282
+ .option("-s, --server <url>", "Remote server URL")
283
+ .option("-t, --token <token>", "Auth token for remote server")
249
284
  .option("--reveal, --show-secrets", "Reveal plain text value for secret")
250
285
  .option("--json", "Output as JSON")
251
- .action((key, options) => {
286
+ .action(async (key, options) => {
252
287
  try {
288
+ const target = resolveTarget({
289
+ profile: options.profile,
290
+ server: options.server,
291
+ token: options.token,
292
+ });
293
+
294
+ if (target.type === "remote") {
295
+ const res = await fetchRemoteConfig(target.serverUrl!, target.token, options.package);
296
+ const val = res.values?.[key];
297
+ if (options.json) {
298
+ console.log(JSON.stringify({ key, value: val }, null, 2));
299
+ } else {
300
+ console.log(val !== undefined ? JSON.stringify(val) : "undefined");
301
+ }
302
+ return;
303
+ }
304
+
253
305
  const reveal = options.reveal || options.showSecrets;
254
306
  const globalStorage = createGlobalStorage();
255
307
  const globalVal = globalStorage.getConfig(key);
@@ -326,7 +378,10 @@ export function registerConfigCommands(program: Command): void {
326
378
  .description("Set a configuration value (Global by default outside project, or use -g for global)")
327
379
  .option("-P, --package <id>", "Target package ID or path")
328
380
  .option("-g, --global", "Set globally across all packages")
329
- .action((key, rawValue, options) => {
381
+ .option("-p, --profile <name>", "Set config on a remote target")
382
+ .option("-s, --server <url>", "Remote server URL")
383
+ .option("-t, --token <token>", "Auth token for remote server")
384
+ .action(async (key, rawValue, options) => {
330
385
  try {
331
386
  let parsed: unknown = rawValue;
332
387
  try {
@@ -335,6 +390,18 @@ export function registerConfigCommands(program: Command): void {
335
390
  parsed = rawValue;
336
391
  }
337
392
 
393
+ const target = resolveTarget({
394
+ profile: options.profile,
395
+ server: options.server,
396
+ token: options.token,
397
+ });
398
+
399
+ if (target.type === "remote") {
400
+ await setRemoteConfig(target.serverUrl!, key, parsed, target.token, options.package);
401
+ console.log(`[OK] Remote config '${key}' updated on ${target.serverUrl}`);
402
+ return;
403
+ }
404
+
338
405
  const projectRoot = !options.global ? resolvePackageRoot(options.package) : null;
339
406
  const isSecret = isSecretConfigKey(key);
340
407
  const displayVal = isSecret ? maskSecretValue(parsed) : JSON.stringify(parsed);
@@ -366,8 +433,27 @@ export function registerConfigCommands(program: Command): void {
366
433
  .description("Delete a configuration value")
367
434
  .option("-P, --package <id>", "Target package ID or path")
368
435
  .option("-g, --global", "Delete from global configuration")
369
- .action((key, options) => {
436
+ .option("-p, --profile <name>", "Delete config on a remote target")
437
+ .option("-s, --server <url>", "Remote server URL")
438
+ .option("-t, --token <token>", "Auth token for remote server")
439
+ .action(async (key, options) => {
370
440
  try {
441
+ const target = resolveTarget({
442
+ profile: options.profile,
443
+ server: options.server,
444
+ token: options.token,
445
+ });
446
+
447
+ if (target.type === "remote") {
448
+ const res = await deleteRemoteConfig(target.serverUrl!, key, target.token, options.package);
449
+ if (res.deleted) {
450
+ console.log(`[OK] Remote config '${key}' deleted from ${target.serverUrl}`);
451
+ } else {
452
+ console.log(`Remote config '${key}' not found on ${target.serverUrl}`);
453
+ }
454
+ return;
455
+ }
456
+
371
457
  const projectRoot = !options.global ? resolvePackageRoot(options.package) : null;
372
458
 
373
459
  if (options.global || !projectRoot) {
@@ -1,4 +1,4 @@
1
- import { runDoctorChecks } from "@actiondock/core";
1
+ import { fetchRemoteDoctor, resolveTarget, runDoctorChecks } from "@actiondock/core";
2
2
  import { Command } from "commander";
3
3
 
4
4
  export function registerDoctorCommand(program: Command): void {
@@ -6,13 +6,28 @@ export function registerDoctorCommand(program: Command): void {
6
6
  .command("doctor")
7
7
  .description("Check ActionDock environment, registry health, and project diagnostics")
8
8
  .option("-P, --package <id|path>", "Target package ID or directory path for project diagnostics")
9
+ .option("-p, --profile <name>", "Query doctor diagnostics on a remote target")
10
+ .option("-s, --server <url>", "Remote server URL")
11
+ .option("-t, --token <token>", "Auth token for remote server")
9
12
  .option("--json", "Output diagnostics report in JSON format")
10
13
  .action(async (options) => {
11
14
  try {
12
- const report = await runDoctorChecks({
13
- packageIdOrPath: options.package,
15
+ const target = resolveTarget({
16
+ profile: options.profile,
17
+ server: options.server,
18
+ token: options.token,
14
19
  });
15
20
 
21
+ let report;
22
+ if (target.type === "remote") {
23
+ const remoteRes = await fetchRemoteDoctor(target.serverUrl!, target.token, options.package);
24
+ report = remoteRes.report || remoteRes;
25
+ } else {
26
+ report = await runDoctorChecks({
27
+ packageIdOrPath: options.package,
28
+ });
29
+ }
30
+
16
31
  if (options.json) {
17
32
  console.log(JSON.stringify(report, null, 2));
18
33
  if (!report.ok) {
@@ -21,11 +36,14 @@ export function registerDoctorCommand(program: Command): void {
21
36
  return;
22
37
  }
23
38
 
24
- console.log("[DOCTOR] ActionDock System & Project Diagnostics\n");
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
+ console.log(title);
25
43
 
26
44
  // 1. Runtime & Environment Group
27
45
  console.log("[Runtime & Environment]");
28
- const envChecks = report.checks.filter((c) => c.category === "runtime" || c.category === "storage" || c.category === "registry");
46
+ const envChecks = (report.checks || []).filter((c: any) => c.category === "runtime" || c.category === "storage" || c.category === "registry");
29
47
  for (const c of envChecks) {
30
48
  const tag = c.status === "ok" ? "[OK]" : c.status === "warn" ? "[WARN]" : "[ERROR]";
31
49
  console.log(` ${tag} ${c.name}: ${c.message}`);
@@ -37,7 +55,7 @@ export function registerDoctorCommand(program: Command): void {
37
55
  // 2. Project Group
38
56
  if (report.hasProject) {
39
57
  console.log(`\n[Project: ${report.packageId || "unknown"}] (${report.projectRoot})`);
40
- const projChecks = report.checks.filter((c) => c.category === "project");
58
+ const projChecks = (report.checks || []).filter((c: any) => c.category === "project");
41
59
  for (const c of projChecks) {
42
60
  const tag = c.status === "ok" ? "[OK]" : c.status === "warn" ? "[WARN]" : "[ERROR]";
43
61
  console.log(` ${tag} ${c.name}: ${c.message}`);
@@ -19,9 +19,9 @@ export function createCliProgram(): Command {
19
19
  const program = new Command();
20
20
 
21
21
  program
22
- .name("ac")
23
- .description("ActionDock (ac) 2.0 - Toolchain for building and shipping standalone AI Agent Actions & Skills")
24
- .version("2.0.0");
22
+ .name("ad")
23
+ .description("ActionDock (ad) 2.0 - Toolchain for building and shipping standalone AI Agent Actions & Skills")
24
+ .version("2.0.2");
25
25
 
26
26
  registerInitCommand(program);
27
27
  registerInfoCommand(program);