@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,53 @@
1
+ import type { CliContext } from "./types.js";
2
+ /**
3
+ * 密码输入提示配置选项。
4
+ */
5
+ export interface PromptPasswordOptions {
6
+ /** 掩码字符,默认为 '*';若传入空字符串则为完全无回显静默模式 */
7
+ mask?: string;
8
+ /** 自定义输入流,默认为 process.stdin */
9
+ inputStream?: NodeJS.ReadableStream;
10
+ /** 自定义输出流,默认为 process.stdout */
11
+ outputStream?: NodeJS.WritableStream;
12
+ }
13
+ /**
14
+ * 在终端中安全交互式读取用户输入的密码或敏感信息。
15
+ * 处于 TTY 交互终端时,自动进入原始模式并打印掩码字符;退出时确保恢复终端回显。
16
+ *
17
+ * @param promptText 提示文案,例如 "Enter value: "
18
+ * @param options 配置选项
19
+ */
20
+ export declare function promptPassword(promptText: string, options?: PromptPasswordOptions): Promise<string>;
21
+ /**
22
+ * 在终端中常规交互式读取一行文本输入。
23
+ *
24
+ * @param promptText 提示文案
25
+ * @param options 配置选项
26
+ */
27
+ export declare function promptText(promptText: string, options?: {
28
+ inputStream?: NodeJS.ReadableStream;
29
+ outputStream?: NodeJS.WritableStream;
30
+ }): Promise<string>;
31
+ /**
32
+ * 从可读流中读取单行内容。
33
+ */
34
+ export declare function readStreamLine(stream: NodeJS.ReadableStream): Promise<string>;
35
+ /**
36
+ * 从流中完整读取所有数据,并移除末尾的换行符。
37
+ */
38
+ export declare function readEntireStdin(stream?: NodeJS.ReadableStream): Promise<string>;
39
+ /**
40
+ * 解析并获取配置项的具体输入值。
41
+ * 优先顺序:
42
+ * - context.promptInput(测试或宿主环境注入)
43
+ * - --stdin / context.stdin(标准输入流读取)
44
+ * - 终端交互式输入(区分 secret 掩码模式与普通文本模式)
45
+ * - 管道非 TTY 降级读取
46
+ */
47
+ export declare function resolveConfigValueInput(options: {
48
+ promptText: string;
49
+ secret?: boolean;
50
+ mask?: string;
51
+ context?: CliContext;
52
+ useStdin?: boolean;
53
+ }): Promise<string>;
package/dist/prompt.js ADDED
@@ -0,0 +1,192 @@
1
+ import { createInterface } from "node:readline";
2
+ import { ArgumentError, SigintError } from "./errors.js";
3
+ /**
4
+ * 在终端中安全交互式读取用户输入的密码或敏感信息。
5
+ * 处于 TTY 交互终端时,自动进入原始模式并打印掩码字符;退出时确保恢复终端回显。
6
+ *
7
+ * @param promptText 提示文案,例如 "Enter value: "
8
+ * @param options 配置选项
9
+ */
10
+ export async function promptPassword(promptText, options = {}) {
11
+ const mask = options.mask ?? "*";
12
+ const stdin = (options.inputStream || process.stdin);
13
+ const stdout = (options.outputStream || process.stdout);
14
+ // 如果并非处于交互式终端或不支持原始模式,降级为普通流式单行读取
15
+ if (!stdin.isTTY || typeof stdin.setRawMode !== "function") {
16
+ return readStreamLine(stdin);
17
+ }
18
+ return new Promise((resolve, reject) => {
19
+ stdout.write(promptText);
20
+ let password = "";
21
+ stdin.setRawMode(true);
22
+ stdin.resume();
23
+ stdin.setEncoding("utf-8");
24
+ let isCleanedUp = false;
25
+ const cleanup = () => {
26
+ if (isCleanedUp)
27
+ return;
28
+ isCleanedUp = true;
29
+ try {
30
+ stdin.setRawMode(false);
31
+ }
32
+ catch {
33
+ // 忽略可能存在的终端模式恢复异常
34
+ }
35
+ stdin.pause();
36
+ stdin.removeListener("data", onData);
37
+ };
38
+ const onData = (chunk) => {
39
+ const str = typeof chunk === "string" ? chunk : chunk.toString("utf-8");
40
+ for (const char of str) {
41
+ switch (char) {
42
+ case "\n":
43
+ case "\r":
44
+ case "\u0004": // Ctrl+D
45
+ cleanup();
46
+ stdout.write("\n");
47
+ resolve(password);
48
+ return;
49
+ case "\u0003": // Ctrl+C
50
+ cleanup();
51
+ stdout.write("\n");
52
+ reject(new SigintError("User cancelled input"));
53
+ return;
54
+ case "\u0008": // Backspace
55
+ case "\x7f": // Delete
56
+ if (password.length > 0) {
57
+ password = password.slice(0, -1);
58
+ if (mask) {
59
+ stdout.write("\b \b");
60
+ }
61
+ }
62
+ break;
63
+ case "\u001b": // Escape sequence
64
+ break;
65
+ default:
66
+ // 过滤不可见控制字符,只追加可打印字符
67
+ if (char.charCodeAt(0) >= 32) {
68
+ password += char;
69
+ if (mask) {
70
+ stdout.write(mask);
71
+ }
72
+ }
73
+ break;
74
+ }
75
+ }
76
+ };
77
+ stdin.on("data", onData);
78
+ });
79
+ }
80
+ /**
81
+ * 在终端中常规交互式读取一行文本输入。
82
+ *
83
+ * @param promptText 提示文案
84
+ * @param options 配置选项
85
+ */
86
+ export async function promptText(promptText, options) {
87
+ const input = options?.inputStream || process.stdin;
88
+ const output = options?.outputStream || process.stdout;
89
+ const rl = createInterface({ input, output });
90
+ return new Promise((resolve, reject) => {
91
+ rl.question(promptText, (answer) => {
92
+ rl.close();
93
+ resolve(answer);
94
+ });
95
+ rl.on("SIGINT", () => {
96
+ rl.close();
97
+ reject(new SigintError("User cancelled input"));
98
+ });
99
+ });
100
+ }
101
+ /**
102
+ * 从可读流中读取单行内容。
103
+ */
104
+ export async function readStreamLine(stream) {
105
+ return new Promise((resolve, reject) => {
106
+ const rl = createInterface({
107
+ input: stream,
108
+ crlfDelay: Infinity,
109
+ });
110
+ let resolved = false;
111
+ rl.once("line", (line) => {
112
+ resolved = true;
113
+ rl.close();
114
+ resolve(line);
115
+ });
116
+ rl.once("close", () => {
117
+ if (!resolved) {
118
+ resolve("");
119
+ }
120
+ });
121
+ rl.once("error", (err) => {
122
+ rl.close();
123
+ reject(err);
124
+ });
125
+ });
126
+ }
127
+ /**
128
+ * 从流中完整读取所有数据,并移除末尾的换行符。
129
+ */
130
+ export async function readEntireStdin(stream = process.stdin) {
131
+ return new Promise((resolve, reject) => {
132
+ const chunks = [];
133
+ stream.on("data", (chunk) => {
134
+ chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
135
+ });
136
+ stream.once("end", () => {
137
+ const content = Buffer.concat(chunks).toString("utf-8");
138
+ resolve(content.replace(/[\r\n]+$/, ""));
139
+ });
140
+ stream.once("error", reject);
141
+ if ("resume" in stream && typeof stream.resume === "function") {
142
+ stream.resume();
143
+ }
144
+ });
145
+ }
146
+ /**
147
+ * 解析并获取配置项的具体输入值。
148
+ * 优先顺序:
149
+ * - context.promptInput(测试或宿主环境注入)
150
+ * - --stdin / context.stdin(标准输入流读取)
151
+ * - 终端交互式输入(区分 secret 掩码模式与普通文本模式)
152
+ * - 管道非 TTY 降级读取
153
+ */
154
+ export async function resolveConfigValueInput(options) {
155
+ const { promptText: queryText, secret, mask, context, useStdin } = options;
156
+ const effectiveMask = mask ?? (secret ? "*" : undefined);
157
+ // 1. 如果上下文注入了自定义输入函数(如测试隔离环境),优先调用
158
+ if (context?.promptInput) {
159
+ return await context.promptInput(queryText, { secret, mask: effectiveMask });
160
+ }
161
+ // 2. 如果显式指定了 --stdin 选项
162
+ if (useStdin) {
163
+ const stream = context?.stdin || process.stdin;
164
+ const val = await readEntireStdin(stream);
165
+ if (!val) {
166
+ throw new ArgumentError("No data received from standard input");
167
+ }
168
+ return val;
169
+ }
170
+ // 3. 如果上下文提供了自定义 stdin 流
171
+ if (context?.stdin) {
172
+ const val = await readEntireStdin(context.stdin);
173
+ if (!val) {
174
+ throw new ArgumentError("Value is required for config set. Omit value in an interactive terminal to enter securely, or pass via stdin.");
175
+ }
176
+ return val;
177
+ }
178
+ // 4. 判断是否处于交互式终端设备
179
+ const isTty = Boolean(process.stdin.isTTY && typeof process.stdin.setRawMode === "function");
180
+ if (isTty) {
181
+ if (secret) {
182
+ return await promptPassword(queryText, { mask: effectiveMask });
183
+ }
184
+ return await promptText(queryText);
185
+ }
186
+ // 5. 非交互式终端环境(例如管道输入 echo "val" | ad config set key)
187
+ const val = await readEntireStdin(process.stdin);
188
+ if (!val) {
189
+ throw new ArgumentError("Value is required for config set. Omit value in an interactive terminal to enter securely, or pass via stdin.");
190
+ }
191
+ return val;
192
+ }
@@ -0,0 +1,197 @@
1
+ import type { RunRecord } from "@actiondock/sdk";
2
+ import type { RegistryStatusReport } from "@actiondock/core";
3
+ import type { Envelope, ProjectDetailInfo, AggregatedPackage, EnvCheckItem, CliContext } from "./types.js";
4
+ /**
5
+ * 构造标准成功结果信封。
6
+ *
7
+ * @param data 业务数据载荷
8
+ * @param meta 附加元数据
9
+ */
10
+ export declare function createSuccessEnvelope<T>(data: T, meta?: Record<string, unknown>): Envelope<T>;
11
+ /**
12
+ * 构造标准失败结果信封。
13
+ *
14
+ * @param code 错误码
15
+ * @param message 错误描述信息
16
+ * @param details 附加错误细节
17
+ * @param meta 附加元数据
18
+ */
19
+ export declare function createErrorEnvelope(code: string, message: string, details?: unknown, meta?: Record<string, unknown>): Envelope<never>;
20
+ /**
21
+ * 序列化数据为格式化 JSON 字符串。
22
+ *
23
+ * @param data 待序列化数据
24
+ * @param pretty 是否美化格式
25
+ */
26
+ export declare function formatJson(data: unknown, pretty?: boolean): string;
27
+ /**
28
+ * 标准输出写入辅助方法。
29
+ */
30
+ export declare function writeStdout(message: string, context?: CliContext): void;
31
+ /**
32
+ * 标准错误写入辅助方法。
33
+ */
34
+ export declare function writeStderr(message: string, context?: CliContext): void;
35
+ /**
36
+ * 统一根据输出模式进行渲染输出。
37
+ */
38
+ export declare function renderResult<T>(data: T, options: {
39
+ json?: boolean;
40
+ envelope?: boolean;
41
+ humanFormatter?: () => string;
42
+ context?: CliContext;
43
+ }): void;
44
+ /**
45
+ * 统一渲染异常输出。
46
+ */
47
+ export declare function renderError(err: unknown, options: {
48
+ json?: boolean;
49
+ envelope?: boolean;
50
+ context?: CliContext;
51
+ }): void;
52
+ /**
53
+ * 将工程详情信息转换为机器输出视图(剔除 Map 明细与定义字典)。
54
+ */
55
+ export declare function projectDetailToJson(info: ProjectDetailInfo): {
56
+ id: string;
57
+ name: string;
58
+ version: string;
59
+ description: string | undefined;
60
+ projectRoot: string;
61
+ actionsDir: string;
62
+ playbooksDir: string;
63
+ actionsCount: number;
64
+ playbooksCount: number;
65
+ actions: string[];
66
+ playbooks: string[];
67
+ configDeclared: string[];
68
+ };
69
+ /**
70
+ * 格式化渲染单个项目的元数据与详情信息。
71
+ */
72
+ export declare function renderProjectDetail(info: ProjectDetailInfo): string;
73
+ /**
74
+ * 格式化渲染已链接的多个 Package 摘要信息。
75
+ */
76
+ export declare function renderAggregatedPackages(packages: AggregatedPackage[], options?: {
77
+ header?: string;
78
+ showTip?: boolean;
79
+ }): string;
80
+ /**
81
+ * 远端 info 接口返回的注册表树视图(与 RegistryStatusReport 字段兼容的宽松结构)。
82
+ */
83
+ export type RegistryTreeView = RegistryStatusReport | (Record<string, unknown> & {
84
+ workspaces?: Array<{
85
+ id?: string;
86
+ path: string;
87
+ status: string;
88
+ packagesCount?: number;
89
+ children?: Array<{
90
+ id: string;
91
+ version?: string;
92
+ path: string;
93
+ }>;
94
+ }>;
95
+ packages?: Array<{
96
+ id: string;
97
+ version?: string;
98
+ path: string;
99
+ status: string;
100
+ }>;
101
+ totalPackagesCount?: number;
102
+ staleCount?: number;
103
+ });
104
+ /**
105
+ * 格式化渲染注册表层级树结构。
106
+ */
107
+ export declare function renderRegistryTree(status: RegistryTreeView): string;
108
+ /**
109
+ * 格式化渲染 Action 列表。
110
+ */
111
+ export declare function renderActionList(items: Array<{
112
+ id: string;
113
+ description: string;
114
+ packageId?: string;
115
+ }>, title?: string, isFallback?: boolean, intent?: string): string;
116
+ /**
117
+ * 格式化渲染 Action 详情。
118
+ */
119
+ export declare function renderActionDetail(action: {
120
+ id: string;
121
+ packageId?: string;
122
+ projectRoot?: string;
123
+ description?: string;
124
+ inputSchema?: unknown;
125
+ outputSchema?: unknown;
126
+ }): string;
127
+ /**
128
+ * 格式化渲染 Action 校验结果。
129
+ */
130
+ export declare function renderActionValidation(results: Array<{
131
+ id: string;
132
+ valid: boolean;
133
+ errors: string[];
134
+ }>): string;
135
+ /**
136
+ * 格式化渲染 Playbook 列表。
137
+ */
138
+ export declare function renderPlaybookList(items: Array<{
139
+ id: string;
140
+ description?: string;
141
+ packageId?: string;
142
+ }>, title?: string, isFallback?: boolean, intent?: string): string;
143
+ /**
144
+ * 格式化渲染 Playbook 详情。
145
+ */
146
+ export declare function renderPlaybookDetail(pb: {
147
+ id: string;
148
+ packageId?: string;
149
+ description?: string;
150
+ actions?: string[];
151
+ filePath?: string;
152
+ content?: string;
153
+ }): string;
154
+ /**
155
+ * 格式化渲染配置项列表。
156
+ * 掩码决策收敛在命令层(传入的 value 已完成是否打码处理),
157
+ * 此处仅负责值的字符串格式化:字符串原样输出,其余类型 JSON 序列化。
158
+ */
159
+ export declare function renderConfigList(items: Array<{
160
+ key: string;
161
+ value: unknown;
162
+ source: string;
163
+ secret: boolean;
164
+ description?: string;
165
+ }>, scopeLabel?: string, isFallback?: boolean, intent?: string): string;
166
+ /**
167
+ * 格式化渲染配置依赖规范检查。
168
+ */
169
+ export declare function renderConfigSchema(items: Array<{
170
+ key: string;
171
+ status: string;
172
+ source: string;
173
+ secret: boolean;
174
+ description: string;
175
+ }>, packageId: string, root: string): string;
176
+ /**
177
+ * 格式化渲染环境变量满足率诊断。
178
+ */
179
+ export declare function renderConfigEnv(checks: EnvCheckItem[], packageId?: string): string;
180
+ /**
181
+ * 格式化渲染状态键列表。
182
+ */
183
+ export declare function renderStateList(keys: string[], scopeLabel?: string, isFallback?: boolean, intent?: string): string;
184
+ /**
185
+ * 格式化渲染执行记录列表。
186
+ */
187
+ export declare function renderRunsList(items: Array<{
188
+ id: string;
189
+ actionId: string;
190
+ packageId?: string;
191
+ status: string;
192
+ startedAt: string;
193
+ }>, scopeLabel?: string, isFallback?: boolean, intent?: string): string;
194
+ /**
195
+ * 格式化渲染单次执行记录详情。
196
+ */
197
+ export declare function renderRunDetail(run: RunRecord): string;