@actiondock/cli 2.9.1 → 2.11.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 +3 -3
- package/bin/ad.js +225 -5
- package/dist/commands/action/create.d.ts +1 -1
- package/dist/commands/action/create.js +6 -14
- package/dist/commands/add.js +1 -1
- package/dist/commands/config/delete.js +3 -1
- package/dist/commands/config/env.js +2 -1
- package/dist/commands/config/get.js +3 -1
- package/dist/commands/config/list.js +6 -5
- package/dist/commands/config/schema.js +16 -10
- package/dist/commands/config/set.js +3 -1
- package/dist/commands/describe.js +6 -4
- package/dist/commands/export.js +34 -16
- package/dist/commands/index.d.ts +37 -24
- package/dist/commands/index.js +346 -48
- package/dist/commands/info.js +34 -9
- package/dist/commands/list.js +13 -2
- package/dist/commands/mcp.js +0 -1
- package/dist/commands/playbook.js +67 -52
- package/dist/commands/profile.js +2 -1
- package/dist/commands/remove.js +1 -1
- package/dist/commands/run.d.ts +2 -1
- package/dist/commands/run.js +19 -56
- package/dist/commands/runs.d.ts +6 -1
- package/dist/commands/runs.js +274 -11
- package/dist/commands/serve.js +5 -2
- package/dist/commands/state.js +84 -15
- package/dist/errors.d.ts +5 -3
- package/dist/errors.js +23 -7
- package/dist/index.d.ts +10 -2
- package/dist/index.js +15 -12
- package/dist/prompt.d.ts +3 -0
- package/dist/prompt.js +6 -14
- package/dist/renderer.d.ts +8 -151
- package/dist/renderer.js +17 -375
- package/dist/renderers/action.d.ts +51 -0
- package/dist/renderers/action.js +112 -0
- package/dist/renderers/config.d.ts +31 -0
- package/dist/renderers/config.js +93 -0
- package/dist/renderers/playbook.d.ts +19 -0
- package/dist/renderers/playbook.js +42 -0
- package/dist/renderers/project.d.ts +45 -0
- package/dist/renderers/project.js +196 -0
- package/dist/renderers/runs.d.ts +15 -0
- package/dist/renderers/runs.js +47 -0
- package/dist/renderers/state.d.ts +4 -0
- package/dist/renderers/state.js +19 -0
- package/dist/services/config-merge.js +1 -2
- package/dist/services/index.d.ts +1 -0
- package/dist/services/index.js +1 -0
- package/dist/services/run-watch.d.ts +156 -0
- package/dist/services/run-watch.js +395 -0
- package/dist/types.d.ts +37 -0
- package/dist/utils/cert.js +1 -1
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.js +1 -1
- package/dist/utils/input.d.ts +2 -1
- package/dist/utils/input.js +2 -1
- package/dist/utils/target.d.ts +6 -2
- package/dist/utils/target.js +4 -4
- package/dist/utils/utils.d.ts +1 -1
- package/dist/utils/utils.js +4 -12
- package/dist/utils/warning.d.ts +4 -0
- package/dist/utils/warning.js +4 -0
- package/package.json +5 -5
- package/dist/commands/state-list.d.ts +0 -24
- package/dist/commands/state-list.js +0 -81
- package/dist/standalone/index.d.ts +0 -12
- package/dist/standalone/index.js +0 -13
- package/dist/utils/duration.d.ts +0 -1
- package/dist/utils/duration.js +0 -1
|
@@ -3,11 +3,11 @@ import { dirname, isAbsolute, relative, resolve } from "node:path";
|
|
|
3
3
|
import { assertPathWithinRoot, loadActions, loadManifest, loadPlaybooks, saveManifest, filterWithFallbackInfo, } from "@actiondock/core/project";
|
|
4
4
|
import { DefaultActionCatalog, PackageGraphBuilder, resolveAction, resolvePlaybook, } from "@actiondock/core/graph";
|
|
5
5
|
import { fetchRemotePlaybooks, fetchRemotePlaybookShow, } from "@actiondock/core/profile";
|
|
6
|
-
import {
|
|
7
|
-
import { listLinkedPackages,
|
|
8
|
-
import { ArgumentError, CliError, ExecutionError, NO_PROJECT_NO_LINKED_MESSAGE,
|
|
6
|
+
import { loadProjectConfig, } from "@actiondock/core";
|
|
7
|
+
import { listLinkedPackages, } from "@actiondock/core/registry";
|
|
8
|
+
import { ArgumentError, CliError, ExecutionError, NO_PROJECT_NO_LINKED_MESSAGE, wrapAsExecutionError, } from "../errors.js";
|
|
9
9
|
import { renderPlaybookDetail, renderPlaybookList, renderResult, writeStdout, } from "../renderer.js";
|
|
10
|
-
import { applyTargetOptions, getEffectiveOptions, remoteTargetSuffix, resolveFallbackStrategy, resolveIntent, resolveTargetFromOptions, } from "../utils/index.js";
|
|
10
|
+
import { applyTargetOptions, getEffectiveOptions, remoteTargetSuffix, requirePackageRoot, resolveFallbackStrategy, resolveIntent, resolveLocalPackageRoot, resolveTargetFromOptions, } from "../utils/index.js";
|
|
11
11
|
/**
|
|
12
12
|
* 注册 Playbook 命令集合(list, show, validate, create)。
|
|
13
13
|
*
|
|
@@ -31,6 +31,9 @@ export function registerPlaybookCommands(program, context) {
|
|
|
31
31
|
const options = getEffectiveOptions(rawOptions, cmd);
|
|
32
32
|
const effectiveIntent = resolveIntent(options.intent, patterns);
|
|
33
33
|
const { shouldFallback, isMachine } = resolveFallbackStrategy(options);
|
|
34
|
+
const hints = [
|
|
35
|
+
"Tip: Run 'ad playbook show <id>' to inspect procedure steps before execution.",
|
|
36
|
+
];
|
|
34
37
|
// 1. 远端服务分支
|
|
35
38
|
const target = resolveTargetFromOptions(options, context);
|
|
36
39
|
if (target.type === "remote") {
|
|
@@ -40,6 +43,10 @@ export function registerPlaybookCommands(program, context) {
|
|
|
40
43
|
allowInsecureHttp: Boolean(options.allowInsecureHttp),
|
|
41
44
|
insecure: target.insecure,
|
|
42
45
|
});
|
|
46
|
+
if (isMachine) {
|
|
47
|
+
renderResult({ items: remotePbs, hints }, { json: options.json, context });
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
43
50
|
renderResult(remotePbs, {
|
|
44
51
|
json: options.json,
|
|
45
52
|
humanFormatter: () => renderPlaybookList(remotePbs, `Playbooks ${remoteTargetSuffix(target)}`, false, effectiveIntent),
|
|
@@ -48,16 +55,9 @@ export function registerPlaybookCommands(program, context) {
|
|
|
48
55
|
return;
|
|
49
56
|
}
|
|
50
57
|
// 2. 本地工程模式
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
if (!targetRoot) {
|
|
55
|
-
throw packageNotFoundError(options.package);
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
else {
|
|
59
|
-
targetRoot = findProjectRoot();
|
|
60
|
-
}
|
|
58
|
+
const targetRoot = options.package
|
|
59
|
+
? requirePackageRoot(options.package).root
|
|
60
|
+
: resolveLocalPackageRoot();
|
|
61
61
|
if (targetRoot) {
|
|
62
62
|
const config = loadProjectConfig(targetRoot);
|
|
63
63
|
const playbooks = loadPlaybooks(targetRoot, config.playbooksDir);
|
|
@@ -67,8 +67,16 @@ export function registerPlaybookCommands(program, context) {
|
|
|
67
67
|
packageId: config.id,
|
|
68
68
|
}));
|
|
69
69
|
const filterRes = filterWithFallbackInfo(rawList, effectiveIntent, [(p) => p.id, (p) => p.description], shouldFallback);
|
|
70
|
-
if (
|
|
71
|
-
|
|
70
|
+
if (isMachine) {
|
|
71
|
+
if (filterRes.isFallback) {
|
|
72
|
+
renderResult({ items: filterRes.items, isFallback: true, matchedCount: 0, hints }, { json: options.json, context });
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
renderResult({
|
|
76
|
+
items: filterRes.items,
|
|
77
|
+
...(filterRes.matchedCount !== undefined ? { matchedCount: filterRes.matchedCount } : {}),
|
|
78
|
+
hints,
|
|
79
|
+
}, { json: options.json, context });
|
|
72
80
|
return;
|
|
73
81
|
}
|
|
74
82
|
renderResult(filterRes.items, {
|
|
@@ -81,6 +89,10 @@ export function registerPlaybookCommands(program, context) {
|
|
|
81
89
|
// 3. 扫描所有已链接的外部包
|
|
82
90
|
const linkedList = listLinkedPackages(context?.customHome);
|
|
83
91
|
if (linkedList.length === 0) {
|
|
92
|
+
if (isMachine) {
|
|
93
|
+
renderResult({ packages: [], hints }, { json: options.json, context });
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
84
96
|
renderResult([], {
|
|
85
97
|
json: options.json,
|
|
86
98
|
humanFormatter: () => NO_PROJECT_NO_LINKED_MESSAGE,
|
|
@@ -136,8 +148,12 @@ export function registerPlaybookCommands(program, context) {
|
|
|
136
148
|
isFallback = true;
|
|
137
149
|
}
|
|
138
150
|
}
|
|
139
|
-
if (
|
|
140
|
-
|
|
151
|
+
if (isMachine) {
|
|
152
|
+
if (isFallback) {
|
|
153
|
+
renderResult({ packages: filteredPackages, isFallback: true, matchedCount: 0, hints }, { json: options.json, context });
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
renderResult({ packages: filteredPackages, hints }, { json: options.json, context });
|
|
141
157
|
return;
|
|
142
158
|
}
|
|
143
159
|
renderResult(filteredPackages, {
|
|
@@ -150,6 +166,7 @@ export function registerPlaybookCommands(program, context) {
|
|
|
150
166
|
lines.push(` - ${pb.id.padEnd(26)} ${pb.description || ""}`);
|
|
151
167
|
}
|
|
152
168
|
}
|
|
169
|
+
lines.push("\nTip: Run 'ad playbook show <id>' to inspect procedure steps before execution.");
|
|
153
170
|
return lines.join("\n");
|
|
154
171
|
},
|
|
155
172
|
context,
|
|
@@ -169,39 +186,46 @@ export function registerPlaybookCommands(program, context) {
|
|
|
169
186
|
// 1. 远端服务分支
|
|
170
187
|
const target = resolveTargetFromOptions(options, context);
|
|
171
188
|
if (target.type === "remote") {
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
189
|
+
try {
|
|
190
|
+
const detail = await fetchRemotePlaybookShow(target.serverUrl, id, target.token, {
|
|
191
|
+
allowInsecureHttp: Boolean(options.allowInsecureHttp),
|
|
192
|
+
insecure: target.insecure,
|
|
193
|
+
});
|
|
194
|
+
renderResult(detail, {
|
|
195
|
+
json: options.json,
|
|
196
|
+
humanFormatter: () => renderPlaybookDetail(detail),
|
|
197
|
+
context,
|
|
198
|
+
});
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
catch (err) {
|
|
202
|
+
const hint = "Tip: Run 'ad playbook list' to discover available playbooks.";
|
|
203
|
+
throw new ArgumentError(`${err.message}\n${hint}`, err?.details, err?.code, hint);
|
|
204
|
+
}
|
|
182
205
|
}
|
|
183
206
|
// 2. 本地项目模式
|
|
184
207
|
let showTarget = id;
|
|
185
208
|
if (options.package && !id.includes("/")) {
|
|
186
|
-
|
|
187
|
-
if (!pkgRoot) {
|
|
188
|
-
throw packageNotFoundError(options.package);
|
|
189
|
-
}
|
|
209
|
+
requirePackageRoot(options.package);
|
|
190
210
|
showTarget = `${options.package}/${id}`;
|
|
191
211
|
}
|
|
192
212
|
let resolved;
|
|
193
213
|
try {
|
|
194
214
|
const graph = new PackageGraphBuilder({
|
|
195
|
-
root:
|
|
215
|
+
root: resolveLocalPackageRoot() || undefined,
|
|
196
216
|
customHome: context?.customHome,
|
|
197
217
|
allowDevLinks: true,
|
|
198
218
|
}).buildSync();
|
|
199
219
|
resolved = resolvePlaybook(showTarget, { graph });
|
|
200
220
|
}
|
|
201
221
|
catch (err) {
|
|
202
|
-
|
|
222
|
+
const hint = "Tip: Run 'ad playbook list' to discover available playbooks.";
|
|
223
|
+
throw new ArgumentError(`${err.message}\n${hint}`, err?.details, err?.code, hint);
|
|
203
224
|
}
|
|
204
225
|
const pb = resolved.playbook;
|
|
226
|
+
const hints = [
|
|
227
|
+
"Tip: Follow steps sequentially. Invoke constituent actions using 'ad run <action> [options] -- <assignments...>'.",
|
|
228
|
+
];
|
|
205
229
|
const detail = {
|
|
206
230
|
id: pb.id,
|
|
207
231
|
packageId: resolved.packageId,
|
|
@@ -209,6 +233,7 @@ export function registerPlaybookCommands(program, context) {
|
|
|
209
233
|
actions: pb.actions,
|
|
210
234
|
filePath: pb.filePath,
|
|
211
235
|
content: pb.content,
|
|
236
|
+
hints,
|
|
212
237
|
};
|
|
213
238
|
renderResult(detail, {
|
|
214
239
|
json: options.json,
|
|
@@ -224,16 +249,9 @@ export function registerPlaybookCommands(program, context) {
|
|
|
224
249
|
.option("--json", "Output as JSON")
|
|
225
250
|
.action(async (id, rawOptions, cmd) => {
|
|
226
251
|
const options = getEffectiveOptions(rawOptions, cmd);
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
if (!root) {
|
|
231
|
-
throw packageNotFoundError(options.package);
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
else {
|
|
235
|
-
root = findProjectRoot();
|
|
236
|
-
}
|
|
252
|
+
const root = options.package
|
|
253
|
+
? requirePackageRoot(options.package).root
|
|
254
|
+
: resolveLocalPackageRoot();
|
|
237
255
|
const targets = [];
|
|
238
256
|
if (root) {
|
|
239
257
|
const config = loadProjectConfig(root);
|
|
@@ -253,7 +271,7 @@ export function registerPlaybookCommands(program, context) {
|
|
|
253
271
|
let resolved;
|
|
254
272
|
try {
|
|
255
273
|
const graph = new PackageGraphBuilder({
|
|
256
|
-
root:
|
|
274
|
+
root: resolveLocalPackageRoot() || undefined,
|
|
257
275
|
customHome: context?.customHome,
|
|
258
276
|
allowDevLinks: true,
|
|
259
277
|
}).buildSync();
|
|
@@ -292,7 +310,7 @@ export function registerPlaybookCommands(program, context) {
|
|
|
292
310
|
}
|
|
293
311
|
const results = [];
|
|
294
312
|
const graph = new PackageGraphBuilder({
|
|
295
|
-
root:
|
|
313
|
+
root: resolveLocalPackageRoot() || undefined,
|
|
296
314
|
customHome: context?.customHome,
|
|
297
315
|
allowDevLinks: true,
|
|
298
316
|
}).buildSync();
|
|
@@ -317,14 +335,14 @@ export function registerPlaybookCommands(program, context) {
|
|
|
317
335
|
resolveAction(actRef, { graph, catalog, caller: target.packageId });
|
|
318
336
|
}
|
|
319
337
|
catch (e) {
|
|
320
|
-
errors.push(`Referenced cross-package action '${actRef}' not resolvable: ${e.message}
|
|
338
|
+
errors.push(`Referenced cross-package action '${actRef}' not resolvable: ${e.message}. Hint: Action '${actRef}' not found. Run 'ad action create ${actRef}' to create local action, or 'ad add <pkg>' to install external dependency.`);
|
|
321
339
|
}
|
|
322
340
|
}
|
|
323
341
|
else {
|
|
324
342
|
const foundInActions = actions.has(actRef);
|
|
325
343
|
const foundInManifest = Boolean(manifest?.actions?.[actRef]);
|
|
326
344
|
if (!foundInActions && !foundInManifest) {
|
|
327
|
-
errors.push(`Referenced action '${actRef}' not found in project actions
|
|
345
|
+
errors.push(`Referenced action '${actRef}' not found in project actions. Hint: Action '${actRef}' not found. Run 'ad action create ${actRef}' to create local action, or 'ad add <pkg>' to install external dependency.`);
|
|
328
346
|
}
|
|
329
347
|
}
|
|
330
348
|
}
|
|
@@ -374,10 +392,7 @@ export function registerPlaybookCommands(program, context) {
|
|
|
374
392
|
});
|
|
375
393
|
}
|
|
376
394
|
export function handlePlaybookCreate(id, options, context) {
|
|
377
|
-
const root =
|
|
378
|
-
if (!root) {
|
|
379
|
-
throw notInProjectError();
|
|
380
|
-
}
|
|
395
|
+
const { root } = requirePackageRoot(undefined);
|
|
381
396
|
try {
|
|
382
397
|
const config = loadProjectConfig(root);
|
|
383
398
|
const pbDir = resolve(root, config.playbooksDir || "playbooks");
|
package/dist/commands/profile.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { addProfile, checkRemoteHealth, getProfile, listProfiles, loadProfiles, removeProfile, resolveProfileToken, resolveTarget,
|
|
1
|
+
import { addProfile, checkRemoteHealth, getProfile, listProfiles, loadProfiles, removeProfile, resolveProfileToken, resolveTarget, updateProfile, useProfile, } from "@actiondock/core/profile";
|
|
2
|
+
import { toSnakeUpperCase } from "@actiondock/core";
|
|
2
3
|
import { filterWithFallbackInfo, maskSecretValue, } from "@actiondock/core/project";
|
|
3
4
|
import { ArgumentError, ExecutionError, wrapAsExecutionError, } from "../errors.js";
|
|
4
5
|
import { renderResult, writeStderr, writeStdout } from "../renderer.js";
|
package/dist/commands/remove.js
CHANGED
|
@@ -79,7 +79,7 @@ export function registerRemoveCommand(program, context) {
|
|
|
79
79
|
}
|
|
80
80
|
// 调用包管理器执行卸载(说明符白名单校验,消除 win32 shell 拼接注入面)
|
|
81
81
|
assertSafePackageSpec(npmPackageName);
|
|
82
|
-
const installCmd = getInstallCommand(root);
|
|
82
|
+
const installCmd = await getInstallCommand(root);
|
|
83
83
|
const pm = installCmd[0];
|
|
84
84
|
const args = pm === "bun" ? ["remove", npmPackageName] : ["uninstall", npmPackageName, "--ignore-scripts"];
|
|
85
85
|
const uninstallProc = await spawnAsync(pm, args, {
|
package/dist/commands/run.d.ts
CHANGED
|
@@ -6,7 +6,8 @@ import type { CliContext } from "../types.js";
|
|
|
6
6
|
* 以原始纯文本形式渲染 Action 执行终态结果(默认纯文本模式)。
|
|
7
7
|
*
|
|
8
8
|
* 设计契约:
|
|
9
|
-
*
|
|
9
|
+
* - 通用纯文本透传:标量直接输出,结构化对象按标准规范呈现,杜绝私有业务字段嗅探。
|
|
10
|
+
* - 标准输出仅承载业务有效载荷,保持原生排版与真实换行,供用户调阅或下游管道消费。
|
|
10
11
|
*/
|
|
11
12
|
export declare function renderRawExecutionResult(targetRef: string, result: ExecutionResult, context?: CliContext): void;
|
|
12
13
|
/**
|
package/dist/commands/run.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { validateActionInputValue, mapInputValidationFailure, } from "@actiondock/core/project";
|
|
2
2
|
import { resolveTarget, } from "@actiondock/core/profile";
|
|
3
|
+
import { resolveExecutionHint } from "@actiondock/core";
|
|
3
4
|
import { ArgumentError, ExecutionError, SigintError, packageNotFoundError } from "../errors.js";
|
|
4
5
|
import { writeStderr, writeStdout } from "../renderer.js";
|
|
5
6
|
import { applyTargetOptions, getEffectiveOptions, resolveActionInput, resolveLocalPackageRoot, resolveTimeoutMs, withService, } from "../utils/index.js";
|
|
@@ -7,44 +8,18 @@ import { applyTargetOptions, getEffectiveOptions, resolveActionInput, resolveLoc
|
|
|
7
8
|
* 以原始纯文本形式渲染 Action 执行终态结果(默认纯文本模式)。
|
|
8
9
|
*
|
|
9
10
|
* 设计契约:
|
|
10
|
-
*
|
|
11
|
+
* - 通用纯文本透传:标量直接输出,结构化对象按标准规范呈现,杜绝私有业务字段嗅探。
|
|
12
|
+
* - 标准输出仅承载业务有效载荷,保持原生排版与真实换行,供用户调阅或下游管道消费。
|
|
11
13
|
*/
|
|
12
14
|
export function renderRawExecutionResult(targetRef, result, context) {
|
|
13
15
|
if (result.ok) {
|
|
14
16
|
const data = result.data;
|
|
15
17
|
let rawText;
|
|
16
|
-
let metaInfo;
|
|
17
18
|
if (typeof data === "string") {
|
|
18
19
|
rawText = data;
|
|
19
20
|
}
|
|
20
21
|
else if (data !== null && typeof data === "object") {
|
|
21
|
-
|
|
22
|
-
rawText =
|
|
23
|
-
typeof data.content === "object" && data.content !== null
|
|
24
|
-
? JSON.stringify(data.content, null, 2)
|
|
25
|
-
: String(data.content);
|
|
26
|
-
const { content, ...rest } = data;
|
|
27
|
-
if (Object.keys(rest).length > 0) {
|
|
28
|
-
metaInfo = rest;
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
else if ("text" in data && typeof data.text === "string") {
|
|
32
|
-
rawText = data.text;
|
|
33
|
-
const { text, ...rest } = data;
|
|
34
|
-
if (Object.keys(rest).length > 0) {
|
|
35
|
-
metaInfo = rest;
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
else if ("message" in data && typeof data.message === "string") {
|
|
39
|
-
rawText = data.message;
|
|
40
|
-
const { message, ...rest } = data;
|
|
41
|
-
if (Object.keys(rest).length > 0) {
|
|
42
|
-
metaInfo = rest;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
else {
|
|
46
|
-
rawText = JSON.stringify(data, null, 2);
|
|
47
|
-
}
|
|
22
|
+
rawText = JSON.stringify(data, null, 2);
|
|
48
23
|
}
|
|
49
24
|
else if (data !== undefined) {
|
|
50
25
|
rawText = String(data);
|
|
@@ -52,32 +27,6 @@ export function renderRawExecutionResult(targetRef, result, context) {
|
|
|
52
27
|
else {
|
|
53
28
|
rawText = "";
|
|
54
29
|
}
|
|
55
|
-
if (metaInfo) {
|
|
56
|
-
const parts = [];
|
|
57
|
-
const title = metaInfo.path ? String(metaInfo.path) : targetRef;
|
|
58
|
-
parts.push(title);
|
|
59
|
-
if (metaInfo.startLine !== undefined && metaInfo.endLine !== undefined) {
|
|
60
|
-
parts.push(`lines ${metaInfo.startLine}-${metaInfo.endLine}`);
|
|
61
|
-
}
|
|
62
|
-
else if (metaInfo.line !== undefined) {
|
|
63
|
-
parts.push(`line ${metaInfo.line}`);
|
|
64
|
-
}
|
|
65
|
-
if (metaInfo.hasMore !== undefined) {
|
|
66
|
-
parts.push(`hasMore: ${metaInfo.hasMore}`);
|
|
67
|
-
}
|
|
68
|
-
if (metaInfo.truncated) {
|
|
69
|
-
parts.push("truncated: true");
|
|
70
|
-
}
|
|
71
|
-
const handled = new Set(["path", "startLine", "endLine", "line", "hasMore", "truncated"]);
|
|
72
|
-
for (const [k, v] of Object.entries(metaInfo)) {
|
|
73
|
-
if (!handled.has(k) && v !== undefined) {
|
|
74
|
-
parts.push(`${k}: ${typeof v === "object" ? JSON.stringify(v) : v}`);
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
if (parts.length > 0) {
|
|
78
|
-
writeStderr(`[${parts.join(" | ")}]`, context);
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
30
|
writeStdout(rawText, context);
|
|
82
31
|
}
|
|
83
32
|
else {
|
|
@@ -87,6 +36,10 @@ export function renderRawExecutionResult(targetRef, result, context) {
|
|
|
87
36
|
? result.error.details
|
|
88
37
|
: JSON.stringify(result.error.details, null, 2), context);
|
|
89
38
|
}
|
|
39
|
+
const hint = resolveExecutionHint(targetRef, result.error);
|
|
40
|
+
if (hint) {
|
|
41
|
+
writeStderr(hint, context);
|
|
42
|
+
}
|
|
90
43
|
if (context) {
|
|
91
44
|
context.exitCode = 1;
|
|
92
45
|
}
|
|
@@ -189,7 +142,14 @@ export async function executeAction(id, options, context, flatArgs, control) {
|
|
|
189
142
|
throw new SigintError();
|
|
190
143
|
}
|
|
191
144
|
if (isMachine) {
|
|
192
|
-
|
|
145
|
+
if (!result.ok) {
|
|
146
|
+
const hint = resolveExecutionHint(targetRef, result.error);
|
|
147
|
+
const machineOutput = hint !== undefined ? { ...result, hint } : result;
|
|
148
|
+
writeStdout(JSON.stringify(machineOutput, null, 2), context);
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
writeStdout(JSON.stringify(result, null, 2), context);
|
|
152
|
+
}
|
|
193
153
|
}
|
|
194
154
|
else {
|
|
195
155
|
renderRawExecutionResult(targetRef, result, context);
|
|
@@ -260,6 +220,9 @@ export function attachRunCommand(parent, context) {
|
|
|
260
220
|
.option("-i, --input <json>", "Action input as inline JSON")
|
|
261
221
|
.option("-f, --input-file <path>", "Action input from JSON file, or '-' for stdin")
|
|
262
222
|
.option("-c, --config <key=value...>", "Temporary config override (repeatable)");
|
|
223
|
+
cmd.unknownOption = function (flag) {
|
|
224
|
+
this.error(`unknown option '${flag}'\nHint: Separate action inputs from CLI options using '--', e.g.: ad run <id> [options] -- <param>=<val> or <param>:=<json>.`, { code: "commander.unknownOption" });
|
|
225
|
+
};
|
|
263
226
|
return applyTargetOptions(cmd)
|
|
264
227
|
.option("--timeout <duration>", "Execution timeout (e.g. 30s, 5m, 500ms)")
|
|
265
228
|
.option("--request-id <id>", "Idempotency request ID for deduplication")
|
package/dist/commands/runs.d.ts
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
import { Command } from "commander";
|
|
2
2
|
import type { CliContext } from "../types.js";
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
4
|
+
* 归一化 requestId 选项值为去重后的非空原样字符串数组。
|
|
5
|
+
* 将 requestId 作为不作解释的原样字符串,不拆分逗号、不剔除首尾空白,只做非空有效字符串检查与去重。
|
|
6
|
+
*/
|
|
7
|
+
export declare function normalizeRequestIds(raw: unknown): string[];
|
|
8
|
+
/**
|
|
9
|
+
* 注册 runs 动作执行历史管理命令(list、show、watch、clear、cancel)。
|
|
5
10
|
*
|
|
6
11
|
* @param program Commander 实例
|
|
7
12
|
* @param context 命令行上下文
|