gaoding-cli 1.0.0-alpha.7 → 1.0.0-alpha.9
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/CHANGELOG.md +38 -0
- package/README.md +47 -60
- package/dist/bin/gd-cli.js +2 -2
- package/dist/src/api/app-runner.d.ts +1 -4
- package/dist/src/api/app-runner.js +11 -44
- package/dist/src/api/creative-client.d.ts +34 -0
- package/dist/src/api/creative-client.js +184 -0
- package/dist/src/api/dam-client.d.ts +0 -7
- package/dist/src/api/dam-client.js +0 -17
- package/dist/src/api/direct-client.d.ts +9 -2
- package/dist/src/api/direct-client.js +45 -18
- package/dist/src/api/hub-client.d.ts +11 -8
- package/dist/src/api/hub-client.js +17 -18
- package/dist/src/api/usage-client.d.ts +4 -4
- package/dist/src/api/usage-client.js +9 -49
- package/dist/src/auth/credential-store-v2.d.ts +0 -1
- package/dist/src/auth/credential-store-v2.js +0 -6
- package/dist/src/commands/auth.js +17 -53
- package/dist/src/commands/creative.d.ts +8 -0
- package/dist/src/commands/creative.js +178 -0
- package/dist/src/commands/dam.js +270 -127
- package/dist/src/commands/org.js +31 -47
- package/dist/src/commands/skills.js +33 -118
- package/dist/src/commands/update.js +11 -82
- package/dist/src/commands/usage.d.ts +1 -1
- package/dist/src/commands/usage.js +10 -21
- package/dist/src/commands/workflows.d.ts +1 -1
- package/dist/src/commands/workflows.js +299 -197
- package/dist/src/core/auth/auth-guard.d.ts +21 -0
- package/dist/src/core/auth/auth-guard.js +121 -0
- package/dist/src/core/auth/org-manager.d.ts +2 -1
- package/dist/src/core/auth/org-manager.js +61 -6
- package/dist/src/core/output/envelope.d.ts +1 -0
- package/dist/src/core/output/envelope.js +76 -6
- package/dist/src/creative/contract.d.ts +1060 -0
- package/dist/src/creative/contract.js +722 -0
- package/dist/src/creative/media.d.ts +19 -0
- package/dist/src/creative/media.js +83 -0
- package/dist/src/creative/protocol.d.ts +60 -0
- package/dist/src/creative/protocol.js +337 -0
- package/dist/src/io.d.ts +0 -2
- package/dist/src/io.js +0 -8
- package/dist/src/middleware/auth.d.ts +6 -2
- package/dist/src/middleware/auth.js +25 -63
- package/dist/src/middleware/error-handler.d.ts +8 -0
- package/dist/src/middleware/error-handler.js +61 -57
- package/dist/src/program.d.ts +1 -0
- package/dist/src/program.js +137 -122
- package/dist/src/registry/agent-contracts.d.ts +14 -34
- package/dist/src/registry/agent-contracts.js +209 -297
- package/dist/src/registry/direct-registry.d.ts +0 -5
- package/dist/src/registry/direct-registry.js +0 -19
- package/dist/src/registry/registry-client.d.ts +0 -21
- package/dist/src/registry/registry-client.js +1 -40
- package/dist/src/utils/capability-presenter.js +6 -29
- package/dist/src/utils/config.d.ts +2 -2
- package/dist/src/utils/config.js +1 -1
- package/dist/src/utils/help-verify.d.ts +1 -3
- package/dist/src/utils/help-verify.js +1 -25
- package/dist/src/utils/sensitive-path.js +1 -4
- package/package.json +4 -3
- package/skills/gd-cli/SKILL.md +13 -12
- package/skills/gd-cli/references/auth.md +9 -10
- package/skills/gd-cli/references/creative.md +47 -0
- package/skills/gd-cli/references/entitlement.md +3 -3
- package/skills/gd-cli/references/errors.md +10 -3
- package/skills/gd-cli/references/org.md +3 -3
- package/skills/gd-cli/references/sop.md +8 -8
- package/skills/gd-cli/references/update.md +4 -3
- package/skills/gd-cli/references/workflows.md +7 -6
- package/dist/src/commands/models.d.ts +0 -2
- package/dist/src/commands/models.js +0 -78
- package/dist/src/commands/tools.d.ts +0 -4
- package/dist/src/commands/tools.js +0 -383
- package/dist/src/utils/list-output-format.d.ts +0 -10
- package/dist/src/utils/list-output-format.js +0 -34
- package/skills/gd-cli/references/tools.md +0 -29
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
import { ApiError } from "../api/hub-client.js";
|
|
2
2
|
import { DirectApiError } from "../api/direct-client.js";
|
|
3
|
-
import { failedEnvelope, emitJson } from "../core/output/envelope.js";
|
|
3
|
+
import { failedEnvelope, emitJson, publicCliErrorBody, } from "../core/output/envelope.js";
|
|
4
4
|
import { CliUsageError } from "../core/output/cli-error.js";
|
|
5
5
|
import { isVerbose, isDebug } from "../utils/config.js";
|
|
6
6
|
import { isTransientNetworkError } from "../utils/transient-network-error.js";
|
|
7
7
|
import { detectEntitlementIssue, entitlementCliError, ENTITLEMENT_PRICING_URL, resolveEntitlementPricingUrl, } from "../utils/entitlement.js";
|
|
8
8
|
import { redactSensitiveText, redactSensitiveValue } from "../utils/redact.js";
|
|
9
|
+
const jsonFailureProjectors = new WeakMap();
|
|
9
10
|
const ERROR_GUIDES = {
|
|
10
11
|
AUTH_MISSING: "请先登录:\n gd-cli auth login",
|
|
11
12
|
AUTH_EXPIRED: "凭证已过期,请重新登录:\n gd-cli auth login",
|
|
12
13
|
AUTH_REFRESH_FAILED: "凭证刷新失败:\n gd-cli auth login",
|
|
13
14
|
AUTH_SCOPE_DENIED: "权限不足,请重新授权",
|
|
14
|
-
ORG_BIND_EXPIRED: "组织绑定已过期:\n gd-cli org switch",
|
|
15
15
|
ORG_INVALID: "当前组织无效:\n gd-cli org list",
|
|
16
16
|
PARAM_MISSING: "查看命令帮助:\n gd-cli <command> --help",
|
|
17
17
|
PARAM_INVALID: "参数值不合法,请检查参数格式",
|
|
18
|
-
TOOL_NOT_FOUND: "
|
|
18
|
+
TOOL_NOT_FOUND: "能力路由不存在,请检查输入或重试当前命令",
|
|
19
19
|
APP_NOT_FOUND: "Workflow 不存在:\n gd-cli workflows list",
|
|
20
20
|
TASK_NOT_FOUND: "任务不存在或已过期",
|
|
21
21
|
RATE_LIMITED: "请求过于频繁,请稍后重试",
|
|
@@ -29,7 +29,7 @@ export function withErrorHandler(handler) {
|
|
|
29
29
|
}
|
|
30
30
|
catch (error) {
|
|
31
31
|
if (shouldEmitJsonError(args)) {
|
|
32
|
-
|
|
32
|
+
emitJsonFailure(commandFromArgs(args), error);
|
|
33
33
|
process.exit(1);
|
|
34
34
|
}
|
|
35
35
|
if (error instanceof CliUsageError) {
|
|
@@ -81,22 +81,26 @@ export function withErrorHandler(handler) {
|
|
|
81
81
|
}
|
|
82
82
|
};
|
|
83
83
|
}
|
|
84
|
-
function shouldEmitJsonError(args) {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
84
|
+
export function shouldEmitJsonError(args) {
|
|
85
|
+
const command = commandFromArgs(args);
|
|
86
|
+
return command?.opts().json === true;
|
|
87
|
+
}
|
|
88
|
+
export function setJsonFailureProjector(command, projector) {
|
|
89
|
+
jsonFailureProjectors.set(command, projector);
|
|
90
|
+
}
|
|
91
|
+
export function jsonFailureEnvelopeFor(command, error) {
|
|
92
|
+
const body = redactSensitiveValue(toCliErrorBody(error));
|
|
93
|
+
const projector = command ? jsonFailureProjectors.get(command) : undefined;
|
|
94
|
+
if (projector)
|
|
95
|
+
return projector(body);
|
|
96
|
+
const commandName = command ? publicCommandName(command) : "";
|
|
97
|
+
return failedEnvelope(body, commandName ? { command: commandName } : undefined);
|
|
98
|
+
}
|
|
99
|
+
export function emitJsonFailure(command, error) {
|
|
100
|
+
emitJson(jsonFailureEnvelopeFor(command, error));
|
|
101
|
+
}
|
|
102
|
+
function commandFromArgs(args) {
|
|
103
|
+
return [...args].reverse().find(isCommandLike);
|
|
100
104
|
}
|
|
101
105
|
function isCommandLike(value) {
|
|
102
106
|
return (!!value &&
|
|
@@ -104,7 +108,10 @@ function isCommandLike(value) {
|
|
|
104
108
|
"opts" in value &&
|
|
105
109
|
typeof value.opts === "function");
|
|
106
110
|
}
|
|
107
|
-
function toCliErrorBody(error) {
|
|
111
|
+
export function toCliErrorBody(error) {
|
|
112
|
+
return publicCliErrorBody(toCliErrorBodyInternal(error));
|
|
113
|
+
}
|
|
114
|
+
function toCliErrorBodyInternal(error) {
|
|
108
115
|
if (error instanceof CliUsageError) {
|
|
109
116
|
return error.body;
|
|
110
117
|
}
|
|
@@ -128,38 +135,40 @@ function toCliErrorBody(error) {
|
|
|
128
135
|
});
|
|
129
136
|
if (entitlement)
|
|
130
137
|
return redactSensitiveValue(entitlementCliError(entitlement, error.body));
|
|
131
|
-
if (
|
|
132
|
-
return toolRouteUnavailableCliError(parsed.message
|
|
138
|
+
if (parsed.message && isToolRouteUnavailableMessage(parsed.message)) {
|
|
139
|
+
return toolRouteUnavailableCliError(parsed.message, redactSensitiveValue(error.body));
|
|
133
140
|
}
|
|
134
141
|
return {
|
|
135
142
|
code: parsed.code ?? `HTTP_${error.statusCode}`,
|
|
136
143
|
type: error.statusCode === 401 ? "auth" : "business",
|
|
137
144
|
message: parsed.message
|
|
138
145
|
? normalizeBusinessMessage(parsed.message)
|
|
139
|
-
:
|
|
146
|
+
: publicApiFailureMessage(error.statusCode),
|
|
140
147
|
hint: redactSensitiveText(parsed.hint ?? directApiHint(parsed, error.url) ?? ""),
|
|
141
148
|
retryable: false,
|
|
142
149
|
detail: redactSensitiveValue(error.body),
|
|
143
150
|
};
|
|
144
151
|
}
|
|
145
152
|
if (error instanceof ApiError) {
|
|
146
|
-
const
|
|
147
|
-
const
|
|
148
|
-
const
|
|
153
|
+
const parsedBody = parseJsonObject(error.body);
|
|
154
|
+
const parsed = parseDirectApiErrorBody(parsedBody ?? error.body);
|
|
155
|
+
const code = parsed.code ?? "API_ERROR";
|
|
156
|
+
const message = parsed.message ?? publicApiFailureMessage(error.statusCode);
|
|
149
157
|
const entitlement = detectEntitlementIssue({
|
|
150
158
|
code,
|
|
151
159
|
message,
|
|
152
|
-
detail:
|
|
160
|
+
detail: parsedBody ?? error.body,
|
|
153
161
|
});
|
|
154
|
-
if (entitlement)
|
|
155
|
-
return redactSensitiveValue(entitlementCliError(entitlement,
|
|
162
|
+
if (entitlement) {
|
|
163
|
+
return redactSensitiveValue(entitlementCliError(entitlement, parsedBody ?? error.body));
|
|
164
|
+
}
|
|
156
165
|
return {
|
|
157
166
|
code,
|
|
158
167
|
type: code.startsWith("AUTH") ? "auth" : "business",
|
|
159
168
|
message: redactSensitiveText(message),
|
|
160
|
-
hint: redactSensitiveText(
|
|
169
|
+
hint: redactSensitiveText(parsed.hint ?? errorGuide(code) ?? ""),
|
|
161
170
|
retryable: false,
|
|
162
|
-
detail: redactSensitiveValue(
|
|
171
|
+
detail: redactSensitiveValue(parsedBody ?? error.body),
|
|
163
172
|
};
|
|
164
173
|
}
|
|
165
174
|
if (error instanceof Error) {
|
|
@@ -210,32 +219,10 @@ function printCliUsageError(body) {
|
|
|
210
219
|
console.error(`\n 错误码: ${body.code}`);
|
|
211
220
|
if (body.reason)
|
|
212
221
|
console.error(` 原因: ${body.reason}`);
|
|
213
|
-
const detail = body.detail && typeof body.detail === "object" && !Array.isArray(body.detail)
|
|
214
|
-
? body.detail
|
|
215
|
-
: undefined;
|
|
216
|
-
const appId = body.app_id ?? stringField(detail, "app_id");
|
|
217
|
-
const toolId = body.tool_id ?? stringField(detail, "tool_id");
|
|
218
|
-
if (appId)
|
|
219
|
-
console.error(` Workflow: ${appId}`);
|
|
220
|
-
if (toolId)
|
|
221
|
-
console.error(` Tool: ${toolId}`);
|
|
222
|
-
const missingTools = Array.isArray(body.missing_tools)
|
|
223
|
-
? body.missing_tools
|
|
224
|
-
.map((item) => typeof item === "string"
|
|
225
|
-
? item
|
|
226
|
-
: stringField(item, "id") ?? "")
|
|
227
|
-
.filter(Boolean)
|
|
228
|
-
: [];
|
|
229
|
-
if (missingTools.length > 0) {
|
|
230
|
-
console.error(` 缺失 Tool: ${missingTools.join(", ")}`);
|
|
231
|
-
}
|
|
232
222
|
if (body.hint)
|
|
233
223
|
console.error(`\n 说明: ${body.hint}`);
|
|
234
224
|
if (body.next_command)
|
|
235
225
|
console.error(`\n 下一步: ${body.next_command}`);
|
|
236
|
-
const listCommand = stringField(detail, "list_command");
|
|
237
|
-
if (listCommand)
|
|
238
|
-
console.error(` 查看状态: ${listCommand}`);
|
|
239
226
|
console.error("");
|
|
240
227
|
}
|
|
241
228
|
function parseDirectApiErrorBody(body) {
|
|
@@ -250,12 +237,29 @@ function parseDirectApiErrorBody(body) {
|
|
|
250
237
|
code: stringField(nestedError, "error_code") ??
|
|
251
238
|
stringField(nestedError, "code") ??
|
|
252
239
|
stringField(value, "error_code") ??
|
|
253
|
-
stringField(value, "code")
|
|
240
|
+
stringField(value, "code") ??
|
|
241
|
+
stringField(value, "error"),
|
|
254
242
|
errorName: stringField(nestedError, "error_name") ??
|
|
255
243
|
stringField(value, "error_name"),
|
|
256
244
|
message: stringField(nestedError, "message") ?? stringField(value, "message"),
|
|
245
|
+
hint: stringField(nestedError, "suggestion") ??
|
|
246
|
+
stringField(nestedError, "hint") ??
|
|
247
|
+
stringField(value, "suggestion") ??
|
|
248
|
+
stringField(value, "hint"),
|
|
257
249
|
};
|
|
258
250
|
}
|
|
251
|
+
function publicApiFailureMessage(statusCode) {
|
|
252
|
+
return `业务请求失败(HTTP ${statusCode})`;
|
|
253
|
+
}
|
|
254
|
+
function publicCommandName(command) {
|
|
255
|
+
const names = [];
|
|
256
|
+
let current = command;
|
|
257
|
+
while (current.parent) {
|
|
258
|
+
names.unshift(current.name());
|
|
259
|
+
current = current.parent;
|
|
260
|
+
}
|
|
261
|
+
return names.join(" ");
|
|
262
|
+
}
|
|
259
263
|
function parseJsonObject(value) {
|
|
260
264
|
try {
|
|
261
265
|
const parsed = JSON.parse(value);
|
|
@@ -367,7 +371,7 @@ function toolRouteUnavailableCliError(message, detail) {
|
|
|
367
371
|
type: "business",
|
|
368
372
|
message: normalizeToolRouteUnavailableMessage(message),
|
|
369
373
|
reason: "tool-route-unavailable",
|
|
370
|
-
hint: "
|
|
374
|
+
hint: "当前能力的生成路由不可用。请停止重试,不要切换模型、环境或团队;请保留本次输入并联系平台确认能力配置。",
|
|
371
375
|
retryable: false,
|
|
372
376
|
detail,
|
|
373
377
|
};
|
|
@@ -386,7 +390,7 @@ function isToolRouteUnavailableMessage(message) {
|
|
|
386
390
|
function normalizeToolRouteUnavailableMessage(message) {
|
|
387
391
|
const normalized = normalizeBusinessMessage(message);
|
|
388
392
|
if (/没有可用的工具|tool-intent 没有返回|tool intent 没有返回/i.test(normalized)) {
|
|
389
|
-
return "
|
|
393
|
+
return "当前能力的生成路由不可用,未发起生成任务。";
|
|
390
394
|
}
|
|
391
395
|
return normalized;
|
|
392
396
|
}
|
package/dist/src/program.d.ts
CHANGED
package/dist/src/program.js
CHANGED
|
@@ -1,152 +1,167 @@
|
|
|
1
|
-
import { Command,
|
|
1
|
+
import { Command, CommanderError } from "commander";
|
|
2
2
|
import { CLI_VERSION } from "./utils/config.js";
|
|
3
3
|
import { registerAuthCommand } from "./commands/auth.js";
|
|
4
4
|
import { registerOrgCommand } from "./commands/org.js";
|
|
5
5
|
import { registerWorkflowsCommand } from "./commands/workflows.js";
|
|
6
|
-
import {
|
|
6
|
+
import { registerCreativeCommand } from "./commands/creative.js";
|
|
7
7
|
import { registerDamCommand } from "./commands/dam.js";
|
|
8
|
-
import { registerModelsCommand } from "./commands/models.js";
|
|
9
8
|
import { registerUpdateCommand } from "./commands/update.js";
|
|
10
9
|
import { registerSkillsCommand } from "./commands/skills.js";
|
|
11
|
-
import { registerUsageCommand } from "./commands/usage.js";
|
|
12
10
|
import { maybeNotifyUpdate } from "./update/notifier.js";
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import { setStaticHelp } from "./utils/static-help.js";
|
|
11
|
+
import { installAuthPreflight } from "./middleware/auth.js";
|
|
12
|
+
import { CliUsageError } from "./core/output/cli-error.js";
|
|
13
|
+
import { emitJsonFailure } from "./middleware/error-handler.js";
|
|
17
14
|
export async function createProgram() {
|
|
18
15
|
const program = new Command();
|
|
19
16
|
program
|
|
20
17
|
.name("gd-cli")
|
|
21
18
|
.usage("<command> [options]")
|
|
22
19
|
.description("GD CLI — 让稿定成为 Agent 的创意生产引擎")
|
|
23
|
-
.version(CLI_VERSION)
|
|
24
|
-
.addOption(new Option("-f, --format <format>", "输出格式: human / table / json / text").choices(["json", "human", "table", "text"]))
|
|
25
|
-
.addOption(new Option("--json", "等同于 --format json,推荐 Agent 和脚本使用"))
|
|
26
|
-
.addOption(new Option("--no-input", "禁止交互,适合 CI / Agent"))
|
|
27
|
-
.addOption(new Option("--yes", "跳过确认"))
|
|
28
|
-
.addOption(new Option("--verbose", "输出详细日志").hideHelp().default(false));
|
|
29
|
-
setStaticHelp(program, TOP_LEVEL_HELP);
|
|
30
|
-
program
|
|
31
|
-
.command("manifest")
|
|
32
|
-
.description("输出 Agent 可解析的 gd-cli 能力清单")
|
|
33
|
-
.action((_opts, command) => {
|
|
34
|
-
const manifest = buildManifest("all");
|
|
35
|
-
const format = resolveListOutputFormat(command);
|
|
36
|
-
formatOutput(format === "json" ? manifest : rowsForManifest(manifest), format);
|
|
37
|
-
});
|
|
38
|
-
program
|
|
39
|
-
.command("examples")
|
|
40
|
-
.description("查看常用场景示例")
|
|
41
|
-
.action((_opts, command) => {
|
|
42
|
-
const examples = buildTopExamples();
|
|
43
|
-
const format = resolveExplicitExamplesFormat(command);
|
|
44
|
-
if (format === "json") {
|
|
45
|
-
formatOutput(examples, "json");
|
|
46
|
-
}
|
|
47
|
-
else {
|
|
48
|
-
printExamples(examples);
|
|
49
|
-
}
|
|
50
|
-
});
|
|
51
|
-
const agent = program
|
|
52
|
-
.command("agent", { hidden: true })
|
|
53
|
-
.description("Agent 调用 gd-cli 的机器可读入口说明")
|
|
54
|
-
.action(() => {
|
|
55
|
-
console.log(AGENT_HELP.trim());
|
|
56
|
-
});
|
|
57
|
-
agent.addHelpText("afterAll", `\n${AGENT_HELP}`);
|
|
20
|
+
.version(CLI_VERSION);
|
|
58
21
|
registerAuthCommand(program);
|
|
59
22
|
registerOrgCommand(program);
|
|
23
|
+
registerCreativeCommand(program);
|
|
60
24
|
registerWorkflowsCommand(program);
|
|
61
|
-
registerToolsCommand(program);
|
|
62
25
|
registerSkillsCommand(program);
|
|
63
|
-
registerModelsCommand(program);
|
|
64
26
|
registerDamCommand(program);
|
|
65
27
|
registerUpdateCommand(program);
|
|
66
|
-
|
|
28
|
+
installAuthPreflight(program);
|
|
67
29
|
program.hook("postAction", async (_thisCommand, actionCommand) => {
|
|
68
30
|
await maybeNotifyUpdate(actionCommand);
|
|
69
31
|
});
|
|
70
32
|
return program;
|
|
71
33
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
调用规则:
|
|
115
|
-
1. 优先用 --format json 或 --json。
|
|
116
|
-
2. 复杂输入用 --input <json-file> 或 stdin: cat input.json | gd-cli tools call <tool-id> - --json。
|
|
117
|
-
3. 完整业务场景优先选 workflows;单项能力选 tools;素材复用选 dam。
|
|
118
|
-
4. Agent 不切换模型、环境或组织;这些由 CLI 配置和用户显式命令管理。
|
|
119
|
-
`;
|
|
120
|
-
function resolveExplicitExamplesFormat(command) {
|
|
121
|
-
const root = command.parent;
|
|
122
|
-
const opts = (root?.opts() ?? {});
|
|
123
|
-
if (opts.json)
|
|
124
|
-
return "json";
|
|
125
|
-
const source = root?.getOptionValueSource("format");
|
|
126
|
-
return source && source !== "default" && source !== "implied"
|
|
127
|
-
? opts.format ?? "human"
|
|
128
|
-
: "human";
|
|
129
|
-
}
|
|
130
|
-
function printExamples(payload) {
|
|
131
|
-
const examples = Array.isArray(payload.examples) ? payload.examples : [];
|
|
132
|
-
console.log("常用场景示例\n");
|
|
133
|
-
examples.forEach((item, index) => {
|
|
134
|
-
const record = item;
|
|
135
|
-
console.log(`${index + 1}. ${String(record.title ?? "")}`);
|
|
136
|
-
const description = record.description;
|
|
137
|
-
if (typeof description === "string" && description.trim()) {
|
|
138
|
-
console.log(` ${description.trim()}`);
|
|
34
|
+
export async function parseProgram(program, argv = process.argv) {
|
|
35
|
+
const userArgs = argv.slice(2);
|
|
36
|
+
const jsonLeaf = resolveExplicitJsonLeaf(program, userArgs);
|
|
37
|
+
const capturedErrors = [];
|
|
38
|
+
const configuredCommands = allCommands(program).map((command) => {
|
|
39
|
+
const output = command.configureOutput();
|
|
40
|
+
const writeErr = output.writeErr ?? ((text) => process.stderr.write(text));
|
|
41
|
+
command.configureOutput({
|
|
42
|
+
writeErr: (text) => capturedErrors.push({ text, write: writeErr }),
|
|
43
|
+
});
|
|
44
|
+
command.exitOverride();
|
|
45
|
+
return { command, writeErr };
|
|
46
|
+
});
|
|
47
|
+
let actionStarted = false;
|
|
48
|
+
program.hook("preAction", () => {
|
|
49
|
+
actionStarted = true;
|
|
50
|
+
});
|
|
51
|
+
try {
|
|
52
|
+
await program.parseAsync([...argv]);
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
if (error instanceof CommanderError && error.exitCode === 0)
|
|
56
|
+
return;
|
|
57
|
+
if (!actionStarted && jsonLeaf) {
|
|
58
|
+
emitJsonFailure(jsonLeaf, parseFailure(error, jsonLeaf));
|
|
59
|
+
process.exitCode = error instanceof CommanderError
|
|
60
|
+
? Math.max(1, error.exitCode)
|
|
61
|
+
: 1;
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
for (const captured of capturedErrors)
|
|
65
|
+
captured.write(captured.text);
|
|
66
|
+
if (error instanceof CommanderError) {
|
|
67
|
+
process.exitCode = error.exitCode;
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
throw error;
|
|
71
|
+
}
|
|
72
|
+
finally {
|
|
73
|
+
for (const { command, writeErr } of configuredCommands) {
|
|
74
|
+
command.configureOutput({ writeErr });
|
|
139
75
|
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
function resolveExplicitJsonLeaf(program, args) {
|
|
79
|
+
let current = program;
|
|
80
|
+
let index = 0;
|
|
81
|
+
let commandIndex = -1;
|
|
82
|
+
while (current.commands.length > 0) {
|
|
83
|
+
let nextCommand;
|
|
84
|
+
while (index < args.length) {
|
|
85
|
+
const token = args[index];
|
|
86
|
+
if (token === "--")
|
|
87
|
+
return undefined;
|
|
88
|
+
if (token.startsWith("-")) {
|
|
89
|
+
index += optionWidth(current, args, index);
|
|
90
|
+
continue;
|
|
148
91
|
}
|
|
92
|
+
nextCommand = current.commands.find((candidate) => candidate.name() === token || candidate.aliases().includes(token));
|
|
93
|
+
if (!nextCommand)
|
|
94
|
+
return undefined;
|
|
95
|
+
commandIndex = index;
|
|
96
|
+
index += 1;
|
|
97
|
+
break;
|
|
149
98
|
}
|
|
150
|
-
|
|
99
|
+
if (!nextCommand)
|
|
100
|
+
return undefined;
|
|
101
|
+
current = nextCommand;
|
|
102
|
+
}
|
|
103
|
+
if (commandIndex < 0 ||
|
|
104
|
+
!current.options.some((option) => option.long === "--json")) {
|
|
105
|
+
return undefined;
|
|
106
|
+
}
|
|
107
|
+
return hasExplicitJsonOption(current, args.slice(commandIndex + 1))
|
|
108
|
+
? current
|
|
109
|
+
: undefined;
|
|
110
|
+
}
|
|
111
|
+
function hasExplicitJsonOption(command, args) {
|
|
112
|
+
for (let index = 0; index < args.length;) {
|
|
113
|
+
const token = args[index];
|
|
114
|
+
if (token === "--")
|
|
115
|
+
return false;
|
|
116
|
+
if (token === "--json")
|
|
117
|
+
return true;
|
|
118
|
+
index += optionWidth(command, args, index);
|
|
119
|
+
}
|
|
120
|
+
return false;
|
|
121
|
+
}
|
|
122
|
+
function optionWidth(command, args, index) {
|
|
123
|
+
const token = args[index];
|
|
124
|
+
const flag = token.includes("=") ? token.slice(0, token.indexOf("=")) : token;
|
|
125
|
+
const option = command.options.find((candidate) => candidate.long === flag || candidate.short === flag);
|
|
126
|
+
if (!option || token.includes("="))
|
|
127
|
+
return 1;
|
|
128
|
+
if (option.required)
|
|
129
|
+
return index + 1 < args.length ? 2 : 1;
|
|
130
|
+
if (option.optional &&
|
|
131
|
+
index + 1 < args.length &&
|
|
132
|
+
!args[index + 1].startsWith("-")) {
|
|
133
|
+
return 2;
|
|
134
|
+
}
|
|
135
|
+
return 1;
|
|
136
|
+
}
|
|
137
|
+
function parseFailure(error, command) {
|
|
138
|
+
const missingCodes = new Set([
|
|
139
|
+
"commander.missingArgument",
|
|
140
|
+
"commander.optionMissingArgument",
|
|
141
|
+
"commander.missingMandatoryOptionValue",
|
|
142
|
+
]);
|
|
143
|
+
const code = error instanceof CommanderError && missingCodes.has(error.code)
|
|
144
|
+
? "PARAM_MISSING"
|
|
145
|
+
: "PARAM_INVALID";
|
|
146
|
+
const rawMessage = error instanceof Error ? error.message : String(error);
|
|
147
|
+
const message = rawMessage.replace(/^error:\s*/i, "").trim() || "参数不合法";
|
|
148
|
+
return new CliUsageError({
|
|
149
|
+
code,
|
|
150
|
+
type: "validation",
|
|
151
|
+
message,
|
|
152
|
+
hint: `运行 gd-cli ${publicCommandName(command)} --help 查看参数说明。`,
|
|
153
|
+
retryable: false,
|
|
151
154
|
});
|
|
152
155
|
}
|
|
156
|
+
function publicCommandName(command) {
|
|
157
|
+
const names = [];
|
|
158
|
+
let current = command;
|
|
159
|
+
while (current.parent) {
|
|
160
|
+
names.unshift(current.name());
|
|
161
|
+
current = current.parent;
|
|
162
|
+
}
|
|
163
|
+
return names.join(" ");
|
|
164
|
+
}
|
|
165
|
+
function allCommands(root) {
|
|
166
|
+
return [root, ...root.commands.flatMap(allCommands)];
|
|
167
|
+
}
|
|
@@ -1,43 +1,23 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import type { ParamSpec } from "./types.js";
|
|
2
|
+
export declare const PUBLIC_WORKFLOW_MEDIA_PATTERN = "^kv_\\d+_\\d+$";
|
|
3
|
+
export interface PublicWorkflowOutputDefinition {
|
|
4
|
+
textFields: readonly string[];
|
|
5
|
+
mediaFields: readonly string[];
|
|
6
|
+
overlayFields: readonly string[];
|
|
7
|
+
ratioFields: readonly string[];
|
|
8
|
+
ratios: "record" | "array";
|
|
9
|
+
sellingPoints?: boolean;
|
|
10
|
+
mediaPattern?: string;
|
|
11
|
+
}
|
|
5
12
|
export interface JsonSchemaObject {
|
|
6
13
|
type: "object";
|
|
7
14
|
properties: Record<string, Record<string, unknown>>;
|
|
8
15
|
required: string[];
|
|
9
16
|
additionalProperties?: boolean;
|
|
10
|
-
|
|
11
|
-
export interface CapabilityManifestCommand {
|
|
12
|
-
id: string;
|
|
13
|
-
type: CapabilityKind | "dam" | "org";
|
|
14
|
-
category: string;
|
|
15
|
-
title: string;
|
|
16
|
-
description: string;
|
|
17
|
-
canonical_command: string;
|
|
18
|
-
input_schema_command?: string;
|
|
19
|
-
examples_command?: string;
|
|
20
|
-
output: "json";
|
|
21
|
-
safe_for_agent: boolean;
|
|
22
|
-
source: CapabilitySource;
|
|
23
|
-
status: CapabilityStatus;
|
|
24
|
-
policy: CapabilityPolicy;
|
|
25
|
-
dependency_tools?: string[];
|
|
26
|
-
affected_workflows?: string[];
|
|
27
|
-
}
|
|
28
|
-
export interface CapabilityManifest {
|
|
29
|
-
name: "gd-cli";
|
|
30
|
-
version: string;
|
|
31
|
-
description: string;
|
|
32
|
-
commands: CapabilityManifestCommand[];
|
|
17
|
+
patternProperties?: Record<string, Record<string, unknown>>;
|
|
33
18
|
}
|
|
34
19
|
export declare function buildInputJsonSchema(params: ParamSpec[], extraProperties?: Record<string, Record<string, unknown>>): JsonSchemaObject;
|
|
35
|
-
export declare function
|
|
36
|
-
export declare function
|
|
20
|
+
export declare function resolvePublicWorkflowOutputDefinition(appId: string): PublicWorkflowOutputDefinition;
|
|
21
|
+
export declare function buildOutputJsonSchema(appId: string): JsonSchemaObject;
|
|
37
22
|
export declare function buildWorkflowSchema(appId: string): Record<string, unknown>;
|
|
38
|
-
export declare function buildToolExamples(toolId: string): Record<string, unknown>;
|
|
39
23
|
export declare function buildWorkflowExamples(appId: string): Record<string, unknown>;
|
|
40
|
-
export declare function buildManifest(scope?: ManifestScope): CapabilityManifest;
|
|
41
|
-
export declare function rowsForManifest(manifest: CapabilityManifest): Record<string, string>[];
|
|
42
|
-
export declare function buildTopExamples(): Record<string, unknown>;
|
|
43
|
-
export {};
|