@actiondock/cli 2.7.0 → 2.8.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.
Files changed (65) hide show
  1. package/README.md +4 -6
  2. package/dist/commands/action/create.js +4 -5
  3. package/dist/commands/add.js +9 -17
  4. package/dist/commands/build.js +3 -18
  5. package/dist/commands/config/delete.js +8 -7
  6. package/dist/commands/config/env.js +7 -11
  7. package/dist/commands/config/get.js +8 -5
  8. package/dist/commands/config/list.js +16 -22
  9. package/dist/commands/config/schema.d.ts +7 -1
  10. package/dist/commands/config/schema.js +44 -67
  11. package/dist/commands/config/set.js +9 -7
  12. package/dist/commands/describe.js +10 -9
  13. package/dist/commands/doctor.js +4 -3
  14. package/dist/commands/export.js +5 -13
  15. package/dist/commands/generate.js +4 -3
  16. package/dist/commands/info.js +3 -1
  17. package/dist/commands/init.js +3 -3
  18. package/dist/commands/link.js +4 -4
  19. package/dist/commands/list.js +19 -10
  20. package/dist/commands/mcp.js +27 -66
  21. package/dist/commands/pack.js +3 -12
  22. package/dist/commands/playbook.js +30 -10
  23. package/dist/commands/profile.js +10 -19
  24. package/dist/commands/remove.js +5 -14
  25. package/dist/commands/run.d.ts +5 -2
  26. package/dist/commands/run.js +19 -20
  27. package/dist/commands/runs.js +26 -35
  28. package/dist/commands/serve.js +66 -44
  29. package/dist/commands/state-list.d.ts +2 -2
  30. package/dist/commands/state-list.js +10 -8
  31. package/dist/commands/state.d.ts +2 -2
  32. package/dist/commands/state.js +110 -103
  33. package/dist/commands/test.js +1 -1
  34. package/dist/commands/validate.js +4 -17
  35. package/dist/errors.d.ts +14 -0
  36. package/dist/errors.js +46 -2
  37. package/dist/index.d.ts +2 -2
  38. package/dist/index.js +3 -3
  39. package/dist/renderer.d.ts +1 -1
  40. package/dist/renderer.js +1 -1
  41. package/dist/services/config-merge.d.ts +6 -5
  42. package/dist/services/config-merge.js +10 -8
  43. package/dist/services/inspect.js +3 -1
  44. package/dist/standalone/index.d.ts +4 -14
  45. package/dist/standalone/index.js +5 -44
  46. package/dist/types.d.ts +2 -1
  47. package/dist/types.js +1 -1
  48. package/dist/utils/cert.js +1 -1
  49. package/dist/utils/duration.d.ts +1 -1
  50. package/dist/utils/duration.js +1 -1
  51. package/dist/utils/index.d.ts +1 -2
  52. package/dist/utils/index.js +1 -2
  53. package/dist/utils/input.d.ts +9 -1
  54. package/dist/utils/input.js +12 -1
  55. package/dist/utils/server-launch.d.ts +61 -0
  56. package/dist/utils/server-launch.js +114 -0
  57. package/dist/utils/target.d.ts +14 -13
  58. package/dist/utils/target.js +20 -39
  59. package/dist/utils/utils.d.ts +101 -1
  60. package/dist/utils/utils.js +97 -7
  61. package/package.json +5 -6
  62. package/dist/utils/bytes.d.ts +0 -1
  63. package/dist/utils/bytes.js +0 -1
  64. package/dist/utils/filter.d.ts +0 -1
  65. package/dist/utils/filter.js +0 -1
@@ -1,7 +1,9 @@
1
- import { filterWithFallbackInfo, findProjectRoot, listLinkedPackages, loadProjectConfig, resolvePackageRoot, } from "@actiondock/core";
2
- import { ArgumentError, ExecutionError, NO_PROJECT_NO_LINKED_MESSAGE, notInProjectError, packageNotFoundError, } from "../errors.js";
1
+ import { findProjectRoot, loadProjectConfig, } from "@actiondock/core";
2
+ import { filterWithFallbackInfo, } from "@actiondock/core/project";
3
+ import { listLinkedPackages, resolvePackageRoot, } from "@actiondock/core/registry";
4
+ import { ArgumentError, ExecutionError, NO_PROJECT_NO_LINKED_MESSAGE, packageNotFoundError, } from "../errors.js";
3
5
  import { renderResult, renderRunDetail, renderRunsList } from "../renderer.js";
4
- import { applyTargetOptions, getEffectiveOptions, resolveIntent, resolveTargetFromOptions, withRemoteTarget, withTarget, } from "../utils/index.js";
6
+ import { applyTargetOptions, getEffectiveOptions, remoteTargetSuffix, requirePackageRoot, resolveFallbackStrategy, resolveIntent, withService, } from "../utils/index.js";
5
7
  /**
6
8
  * 解析本地目标包根目录与工程配置(仅在 local 分支调用)。
7
9
  * 显式指定包且寻址失败时抛出参数错误;工程清单损坏时降级为链接包视图。
@@ -50,21 +52,26 @@ export function registerRunsCommands(program, context) {
50
52
  .option("-i, --intent <pattern>", "Regex or fuzzy intent filter; falls back to full list when no match")
51
53
  .option("-a, --action <actionId>", "Filter by action ID")
52
54
  .option("-n, --limit <count>", "Maximum number of records to return", "20"))
55
+ .option("--fallback", "Enable fallback to full list when no items match intent")
53
56
  .option("--no-fallback", "Disable fallback to full list when no items match intent")
54
57
  .option("--data-dir <path>", "Custom database storage directory")
55
58
  .option("--json", "Output as JSON")
56
59
  .action(async (patterns = [], rawOptions, cmd) => {
57
60
  const options = getEffectiveOptions(rawOptions, cmd);
58
61
  const effectiveIntent = resolveIntent(options.intent, patterns);
59
- const shouldFallback = options.fallback !== false;
62
+ const { shouldFallback } = resolveFallbackStrategy(options);
60
63
  const limit = Number.parseInt(options.limit, 10) || 20;
61
64
  const scope = resolveLocalRunScope(options.package);
62
- // 通过 Target 门面统一访问
63
- await withTarget(options, context, async (target, resolved) => {
64
- const records = await target.listRuns({
65
+ // 通过 Service 门面统一访问
66
+ await withService(options, context, async (service, resolved) => {
67
+ // limit 下推查询层:intent 过滤发生在内存(过滤后仍需截断到用户值),
68
+ // 下推时附加合理裕量,保证过滤后可截断数量不少于用户请求
69
+ const FETCH_HEADROOM = 200;
70
+ const queryLimit = effectiveIntent ? limit + FETCH_HEADROOM : limit;
71
+ const records = await service.runs.list({
65
72
  packageId: options.package,
66
73
  actionId: options.action,
67
- limit: 500,
74
+ limit: queryLimit,
68
75
  });
69
76
  // 若处于本地无项目环境且无任何软链接包,则直接输出友好提示
70
77
  if (resolved.type === "local" && !scope.targetPackageRoot) {
@@ -85,7 +92,7 @@ export function registerRunsCommands(program, context) {
85
92
  humanFormatter: () => {
86
93
  let title = "Execution Runs";
87
94
  if (resolved.type === "remote") {
88
- title = `Execution Runs on remote server ${resolved.serverUrl}${resolved.profileName ? ` (Profile: ${resolved.profileName})` : ""}`;
95
+ title = `Execution Runs ${remoteTargetSuffix(resolved)}`;
89
96
  }
90
97
  else if (scope.projConfig) {
91
98
  title = `Execution Runs in ${scope.projConfig.name} (${scope.projConfig.id})`;
@@ -112,9 +119,9 @@ export function registerRunsCommands(program, context) {
112
119
  throw new ArgumentError("Run ID is required");
113
120
  }
114
121
  const scope = resolveLocalRunScope(options.package);
115
- // 通过 Target 门面统一查询
116
- await withTarget(options, context, async (target, resolved) => {
117
- const run = await target.getRun(id);
122
+ // 通过 Service 门面统一查询
123
+ await withService(options, context, async (service, resolved) => {
124
+ const run = await service.runs.get(id);
118
125
  if (!run) {
119
126
  if (resolved.type === "remote") {
120
127
  throw new ExecutionError(`Run record '${id}' not found on remote server`);
@@ -144,12 +151,8 @@ export function registerRunsCommands(program, context) {
144
151
  if (!id) {
145
152
  throw new ArgumentError("Run ID is required for cancel");
146
153
  }
147
- const resolved = resolveTargetFromOptions(options, context);
148
- if (resolved.type === "local") {
149
- throw new ArgumentError("'ad runs cancel' is only supported for remote execution targets. Use --profile <name> or --server <url>.");
150
- }
151
- await withRemoteTarget(options, context, async (target) => {
152
- const result = await target.cancelRun(id, options.reason);
154
+ await withService(options, context, async (service) => {
155
+ const result = await service.runs.cancel(id, options.reason);
153
156
  const isErrorOutcome = result.outcome === "not_found" || result.outcome === "not_owner";
154
157
  renderResult(result, {
155
158
  json: options.json,
@@ -167,7 +170,7 @@ export function registerRunsCommands(program, context) {
167
170
  if (isErrorOutcome) {
168
171
  process.exitCode = 1;
169
172
  }
170
- });
173
+ }, { requireRemote: true });
171
174
  });
172
175
  // runs clear
173
176
  applyTargetOptions(runsCmd
@@ -182,19 +185,7 @@ export function registerRunsCommands(program, context) {
182
185
  let targetPackageRoot;
183
186
  let packageId = options.package;
184
187
  if (!options.profile && !options.server) {
185
- if (options.package) {
186
- const root = resolvePackageRoot(options.package);
187
- if (!root) {
188
- throw packageNotFoundError(options.package);
189
- }
190
- targetPackageRoot = root;
191
- }
192
- else {
193
- targetPackageRoot = findProjectRoot() || undefined;
194
- if (!targetPackageRoot) {
195
- throw notInProjectError("Please specify -P, --package <id> or cd into a project directory.");
196
- }
197
- }
188
+ targetPackageRoot = requirePackageRoot(options.package).root;
198
189
  try {
199
190
  packageId = loadProjectConfig(targetPackageRoot).id;
200
191
  }
@@ -202,9 +193,9 @@ export function registerRunsCommands(program, context) {
202
193
  // 清单损坏时保留原始 -P 参数作为包标识
203
194
  }
204
195
  }
205
- await withTarget(options, context, async (target, resolved) => {
206
- const count = target.clearRuns
207
- ? await target.clearRuns({ packageId, actionId: options.action })
196
+ await withService(options, context, async (service, resolved) => {
197
+ const count = service.runs.clear
198
+ ? await service.runs.clear({ packageId, actionId: options.action })
208
199
  : 0;
209
200
  const payload = { ok: true, clearedCount: count };
210
201
  renderResult(payload, {
@@ -1,10 +1,11 @@
1
1
  import { readFileSync } from "node:fs";
2
2
  import { resolve } from "node:path";
3
- import { createActionDockTarget, findProjectRoot, formatHostForUrl, loadProjectConfig, startActionDockServer, } from "@actiondock/core";
4
- import { createNodePlatform } from "@actiondock/runtime-node";
5
- import { ArgumentError, ExecutionError } from "../errors.js";
3
+ import { createActionDock, createNodePlatform, findProjectRoot, loadProjectConfig, startActionDockServer, } from "@actiondock/core";
4
+ import { resolvePackageRoot } from "@actiondock/core/registry";
5
+ import { formatHostForUrl, } from "@actiondock/core/server";
6
+ import { ArgumentError, ExecutionError, packageNotFoundError } from "../errors.js";
6
7
  import { writeStderr, writeStdout } from "../renderer.js";
7
- import { ensureSelfSignedCertificate, getEffectiveOptions, parseByteSize } from "../utils/index.js";
8
+ import { ensureSelfSignedCertificate, getEffectiveOptions, normalizeCorsOrigins, registerStopSignalHandler, printServerBanner, resolveMaxBodyBytes, resolveServerHost, resolveServerPort, resolveServerToken, parseListOption, } from "../utils/index.js";
8
9
  /**
9
10
  * 注册 serve HTTP 服务启动命令。
10
11
  *
@@ -31,17 +32,17 @@ export function registerServeCommand(program, context) {
31
32
  .option("--tls-ca <path>", "Path to TLS CA certificate file (or set ACTIONDOCK_TLS_CA)")
32
33
  .option("--tls-passphrase <passphrase>", "Passphrase for TLS private key (or set ACTIONDOCK_TLS_PASSPHRASE)")
33
34
  .option("-d, --dir <path>", "Project root directory (default: current working directory)")
35
+ .option("-P, --package <package-id>", "Specific package ID(s) to serve (can be specified multiple times or comma-separated)", parseListOption, [])
34
36
  .option("--data-dir <path>", "Custom database storage directory")
35
37
  .action(async (rawOptions, cmd) => {
36
38
  const options = getEffectiveOptions(rawOptions, cmd);
37
- const parsedPort = parseInt(options.port, 10);
38
- const port = Number.isNaN(parsedPort) ? 5177 : parsedPort;
39
- const host = options.host || "127.0.0.1";
40
- const token = options.token || (typeof process !== "undefined" ? process.env?.ACTIONDOCK_TOKEN : undefined);
39
+ const port = resolveServerPort(options.port, 5177);
40
+ const host = resolveServerHost(options.host);
41
+ const token = resolveServerToken(options.token);
41
42
  const allowInsecureNoAuth = Boolean(options.allowInsecureNoAuth);
42
43
  const allowQueryToken = Boolean(options.allowQueryToken);
43
44
  const enableManagement = Boolean(options.management);
44
- const corsOrigins = options.corsOrigin && options.corsOrigin.length > 0 ? options.corsOrigin : undefined;
45
+ const corsOrigins = normalizeCorsOrigins(options.corsOrigin);
45
46
  const exposeDebugInfo = Boolean(options.exposeDebugInfo);
46
47
  const httpsEnabled = Boolean(options.https ||
47
48
  options.tlsCert ||
@@ -82,18 +83,46 @@ export function registerServeCommand(program, context) {
82
83
  };
83
84
  }
84
85
  }
85
- let maxBodyBytes;
86
- if (options.maxBody) {
87
- try {
88
- maxBodyBytes = parseByteSize(options.maxBody);
89
- }
90
- catch (err) {
91
- throw new ArgumentError(`Invalid max-body format: ${err.message}`);
92
- }
93
- }
86
+ const maxBodyBytes = resolveMaxBodyBytes(options.maxBody);
94
87
  const projectRoot = options.dir
95
88
  ? resolve(options.dir)
96
89
  : findProjectRoot(process.cwd());
90
+ const rawPackages = options.package || [];
91
+ const packageAllowlist = rawPackages.length > 0 ? [] : undefined;
92
+ const resolvedPackageIds = [];
93
+ const explicitPackages = [];
94
+ if (rawPackages.length > 0) {
95
+ for (const pkgId of rawPackages) {
96
+ const root = resolvePackageRoot(pkgId, projectRoot || undefined, context?.customHome);
97
+ if (!root) {
98
+ throw packageNotFoundError(pkgId);
99
+ }
100
+ if (!projectRoot || root !== projectRoot) {
101
+ if (!explicitPackages.some((p) => p.packageRoot === root)) {
102
+ explicitPackages.push({ packageRoot: root });
103
+ }
104
+ }
105
+ let resolvedId = pkgId;
106
+ try {
107
+ const config = loadProjectConfig(root);
108
+ if (config.id) {
109
+ resolvedId = config.id;
110
+ if (!packageAllowlist.includes(config.id)) {
111
+ packageAllowlist.push(config.id);
112
+ }
113
+ }
114
+ }
115
+ catch {
116
+ // 降级使用原始标识符
117
+ }
118
+ if (!packageAllowlist.includes(pkgId)) {
119
+ packageAllowlist.push(pkgId);
120
+ }
121
+ if (!resolvedPackageIds.includes(resolvedId)) {
122
+ resolvedPackageIds.push(resolvedId);
123
+ }
124
+ }
125
+ }
97
126
  let projectName = "Global Registry Mode";
98
127
  if (projectRoot) {
99
128
  try {
@@ -109,13 +138,14 @@ export function registerServeCommand(program, context) {
109
138
  dataDir: options.dataDir || context?.dataDir,
110
139
  rootDir: projectRoot || undefined,
111
140
  });
112
- const target = await createActionDockTarget({
141
+ const service = await createActionDock({
113
142
  type: "local",
114
143
  projectRoot: projectRoot || undefined,
144
+ packages: explicitPackages.length > 0 ? explicitPackages : undefined,
115
145
  customHome: context?.customHome,
116
146
  dataDir: options.dataDir || context?.dataDir,
117
147
  platform,
118
- scanLinkedPackages: !projectRoot,
148
+ scanLinkedPackages: !projectRoot || rawPackages.length > 0,
119
149
  });
120
150
  let mcpHandler;
121
151
  const enableMcp = options.mcp !== false;
@@ -128,7 +158,9 @@ export function registerServeCommand(program, context) {
128
158
  ]);
129
159
  const handler = createMcpHandler(() => {
130
160
  return createActionDockMcpServer({
131
- target,
161
+ service,
162
+ packageAllowlist,
163
+ packageIds: packageAllowlist,
132
164
  });
133
165
  }, {
134
166
  onerror: (err) => {
@@ -140,7 +172,7 @@ export function registerServeCommand(program, context) {
140
172
  };
141
173
  }
142
174
  catch (err) {
143
- await target.close().catch(() => { });
175
+ await service.close().catch(() => { });
144
176
  throw new ExecutionError(`Failed to initialize MCP endpoint: ${err?.message || String(err)}`, err);
145
177
  }
146
178
  }
@@ -159,16 +191,19 @@ export function registerServeCommand(program, context) {
159
191
  mcpHandler,
160
192
  tls,
161
193
  projectRoot: projectRoot || undefined,
162
- target,
194
+ service,
195
+ packageAllowlist,
163
196
  });
164
197
  const displayHost = formatHostForUrl(host);
165
198
  const actualEndpointHost = formatHostForUrl(host === "0.0.0.0" ? "127.0.0.1" : host);
166
199
  const scheme = tls ? "https" : "http";
167
- writeStdout(`\n======================================================`, context);
168
- writeStdout(` ActionDock 2.0 HTTP Runner Server`, context);
169
- writeStdout(`======================================================`, context);
170
- writeStdout(` * Listening on: ${scheme}://${displayHost}:${server.port}`, context);
171
- writeStdout(` * Project: ${projectName}`, context);
200
+ printServerBanner(`ActionDock 2.0 HTTP Runner Server`, scheme, displayHost, server.port, context);
201
+ if (resolvedPackageIds.length > 0) {
202
+ writeStdout(` * Packages: ${resolvedPackageIds.join(", ")}`, context);
203
+ }
204
+ else {
205
+ writeStdout(` * Project: ${projectName}`, context);
206
+ }
172
207
  if (projectRoot && exposeDebugInfo) {
173
208
  writeStdout(` * Root Path: ${projectRoot}`, context);
174
209
  }
@@ -183,30 +218,17 @@ export function registerServeCommand(program, context) {
183
218
  writeStdout(` * Management APIs: ${enableManagement ? "Enabled" : "Disabled (Default)"}`, context);
184
219
  writeStdout(` * CORS Origins: ${corsOrigins ? corsOrigins.join(", ") : "Disabled (Default)"}`, context);
185
220
  writeStdout(` * Max Body Size: ${options.maxBody || "1mb"}`, context);
186
- writeStdout(` * Health Endpoint: ${scheme}://${actualEndpointHost}:${server.port}/api/v1/health`, context);
221
+ writeStdout(` * Health Endpoint: ${scheme}://${actualEndpointHost}:${server.port}/api/v2/health`, context);
187
222
  if (enableMcp) {
188
223
  writeStdout(` * MCP Endpoint: ${scheme}://${actualEndpointHost}:${server.port}/mcp`, context);
189
224
  }
190
225
  writeStdout(`======================================================\n`, context);
191
226
  writeStdout(`Server is ready to accept remote requests.`, context);
192
227
  writeStdout(`Press Ctrl+C to terminate.\n`, context);
193
- const stopSignalHandler = () => {
194
- writeStdout("\nStopping ActionDock server...", context);
195
- Promise.resolve(server.stop())
196
- .catch((err) => {
197
- // 停止失败必须可见:写入 stderr 一行并标记失败退出码
198
- writeStderr(`[ERROR] Failed to stop ActionDock server gracefully: ${err instanceof Error ? err.message : String(err)}`, context);
199
- process.exitCode = 1;
200
- })
201
- .finally(() => {
202
- process.exit(typeof process.exitCode === "number" ? process.exitCode : 0);
203
- });
204
- };
205
- process.once("SIGINT", stopSignalHandler);
206
- process.once("SIGTERM", stopSignalHandler);
228
+ registerStopSignalHandler(server, `ActionDock server`, context);
207
229
  }
208
230
  catch (err) {
209
- await target.close().catch(() => { });
231
+ await service.close().catch(() => { });
210
232
  throw new ExecutionError(`Failed to start ActionDock server: ${err.message}`, err);
211
233
  }
212
234
  });
@@ -1,10 +1,10 @@
1
- import type { ActionDockTarget } from "@actiondock/core";
1
+ import { type ActionDockService } from "@actiondock/core";
2
2
  import type { CliContext } from "../types.js";
3
3
  /**
4
4
  * 状态键列表渲染参数视图。
5
5
  */
6
6
  export interface StateListRenderArgs {
7
- target: ActionDockTarget;
7
+ service: ActionDockService;
8
8
  actionId: string;
9
9
  prefix: string;
10
10
  options: any;
@@ -1,4 +1,6 @@
1
- import { filterWithFallbackInfo, listLinkedPackages, loadProjectConfig, } from "@actiondock/core";
1
+ import { loadProjectConfig, } from "@actiondock/core";
2
+ import { filterWithFallbackInfo, } from "@actiondock/core/project";
3
+ import { listLinkedPackages, } from "@actiondock/core/registry";
2
4
  import { existsSync } from "node:fs";
3
5
  import { NO_PROJECT_NO_LINKED_MESSAGE } from "../errors.js";
4
6
  import { renderResult, renderStateList } from "../renderer.js";
@@ -6,16 +8,16 @@ import { renderResult, renderStateList } from "../renderer.js";
6
8
  * 渲染单个项目作用域的状态键列表(含 --detail JSON 明细分支)。
7
9
  */
8
10
  export async function renderProjectScopedStateList(args) {
9
- const { target, targetRoot, actionId, prefix, options, effectiveIntent, shouldFallback, context } = args;
11
+ const { service, targetRoot, actionId, prefix, options, effectiveIntent, shouldFallback, context } = args;
10
12
  const projConfig = loadProjectConfig(targetRoot);
11
- const allKeys = await target.listStateKeys(projConfig.id, actionId, {
13
+ const allKeys = (await service.management?.state.list(projConfig.id, actionId, {
12
14
  namespace: options.namespace !== undefined ? options.namespace : null,
13
15
  prefix,
14
- });
16
+ })) ?? [];
15
17
  if (options.detail && options.json) {
16
18
  const entries = [];
17
19
  for (const k of allKeys) {
18
- const entry = await target.getState(projConfig.id, actionId, k, {
20
+ const entry = await service.management?.state.get(projConfig.id, actionId, k, {
19
21
  namespace: options.namespace,
20
22
  detail: true,
21
23
  });
@@ -41,7 +43,7 @@ export async function renderProjectScopedStateList(args) {
41
43
  * 渲染全部链接包聚合的状态键列表(跳过磁盘失效与清单损坏的链接项)。
42
44
  */
43
45
  export async function renderLinkedPackagesStateList(args) {
44
- const { target, actionId, prefix, options, effectiveIntent, shouldFallback, context } = args;
46
+ const { service, actionId, prefix, options, effectiveIntent, shouldFallback, context } = args;
45
47
  // 扫描所有链接的包状态
46
48
  const linked = listLinkedPackages();
47
49
  if (linked.length === 0) {
@@ -58,10 +60,10 @@ export async function renderLinkedPackagesStateList(args) {
58
60
  continue;
59
61
  try {
60
62
  const config = loadProjectConfig(pkg.path);
61
- const keys = await target.listStateKeys(config.id, actionId, {
63
+ const keys = (await service.management?.state.list(config.id, actionId, {
62
64
  namespace: options.namespace !== undefined ? options.namespace : null,
63
65
  prefix,
64
- });
66
+ })) ?? [];
65
67
  for (const k of keys) {
66
68
  aggregatedKeys.push(`${config.id}/${k}`);
67
69
  }
@@ -3,7 +3,7 @@ import type { CliContext } from "../types.js";
3
3
  /**
4
4
  * 注册 state 状态管理命令(get、set、delete、clear、keys、list)。
5
5
  *
6
- * @param program Commander 实例
7
- * @param context 命令行上下文
6
+ * @param program Commander 根程序对象
7
+ * @param context CLI 上下文
8
8
  */
9
9
  export declare function registerStateCommands(program: Command, context?: CliContext): void;