gaoding-cli 1.0.0-alpha.5
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 +88 -0
- package/LICENSE +21 -0
- package/README.md +136 -0
- package/SECURITY.md +34 -0
- package/dist/bin/gd-cli.d.ts +2 -0
- package/dist/bin/gd-cli.js +10 -0
- package/dist/src/api/app-runner.d.ts +33 -0
- package/dist/src/api/app-runner.js +1177 -0
- package/dist/src/api/dam-client.d.ts +111 -0
- package/dist/src/api/dam-client.js +897 -0
- package/dist/src/api/direct-auth.d.ts +3 -0
- package/dist/src/api/direct-auth.js +11 -0
- package/dist/src/api/direct-client.d.ts +27 -0
- package/dist/src/api/direct-client.js +151 -0
- package/dist/src/api/direct-tools.d.ts +43 -0
- package/dist/src/api/direct-tools.js +1155 -0
- package/dist/src/api/hub-client.d.ts +20 -0
- package/dist/src/api/hub-client.js +99 -0
- package/dist/src/api/sso-client.d.ts +60 -0
- package/dist/src/api/sso-client.js +140 -0
- package/dist/src/api/task-poller.d.ts +38 -0
- package/dist/src/api/task-poller.js +72 -0
- package/dist/src/api/tool-invoker.d.ts +12 -0
- package/dist/src/api/tool-invoker.js +11 -0
- package/dist/src/api/usage-client.d.ts +39 -0
- package/dist/src/api/usage-client.js +179 -0
- package/dist/src/auth/credential-store-v2.d.ts +12 -0
- package/dist/src/auth/credential-store-v2.js +59 -0
- package/dist/src/commands/auth.d.ts +2 -0
- package/dist/src/commands/auth.js +191 -0
- package/dist/src/commands/dam.d.ts +2 -0
- package/dist/src/commands/dam.js +293 -0
- package/dist/src/commands/models.d.ts +2 -0
- package/dist/src/commands/models.js +78 -0
- package/dist/src/commands/org.d.ts +2 -0
- package/dist/src/commands/org.js +137 -0
- package/dist/src/commands/skills.d.ts +2 -0
- package/dist/src/commands/skills.js +213 -0
- package/dist/src/commands/tools.d.ts +4 -0
- package/dist/src/commands/tools.js +383 -0
- package/dist/src/commands/update.d.ts +2 -0
- package/dist/src/commands/update.js +167 -0
- package/dist/src/commands/usage.d.ts +7 -0
- package/dist/src/commands/usage.js +43 -0
- package/dist/src/commands/workflows.d.ts +3 -0
- package/dist/src/commands/workflows.js +398 -0
- package/dist/src/core/auth/auth-provider.d.ts +8 -0
- package/dist/src/core/auth/auth-provider.js +12 -0
- package/dist/src/core/auth/device-oauth-provider.d.ts +12 -0
- package/dist/src/core/auth/device-oauth-provider.js +124 -0
- package/dist/src/core/auth/org-manager.d.ts +26 -0
- package/dist/src/core/auth/org-manager.js +224 -0
- package/dist/src/core/auth/signature.d.ts +19 -0
- package/dist/src/core/auth/signature.js +33 -0
- package/dist/src/core/auth/types.d.ts +52 -0
- package/dist/src/core/auth/types.js +3 -0
- package/dist/src/core/output/cli-error.d.ts +5 -0
- package/dist/src/core/output/cli-error.js +8 -0
- package/dist/src/core/output/detector.d.ts +5 -0
- package/dist/src/core/output/detector.js +14 -0
- package/dist/src/core/output/engine.d.ts +32 -0
- package/dist/src/core/output/engine.js +77 -0
- package/dist/src/core/output/envelope.d.ts +40 -0
- package/dist/src/core/output/envelope.js +119 -0
- package/dist/src/core/output/index.d.ts +4 -0
- package/dist/src/core/output/index.js +4 -0
- package/dist/src/core/output/live-display.d.ts +15 -0
- package/dist/src/core/output/live-display.js +111 -0
- package/dist/src/core/output/result-card.d.ts +18 -0
- package/dist/src/core/output/result-card.js +39 -0
- package/dist/src/core/prompt/index.d.ts +31 -0
- package/dist/src/core/prompt/index.js +36 -0
- package/dist/src/io.d.ts +14 -0
- package/dist/src/io.js +31 -0
- package/dist/src/middleware/auth.d.ts +3 -0
- package/dist/src/middleware/auth.js +74 -0
- package/dist/src/middleware/error-handler.d.ts +3 -0
- package/dist/src/middleware/error-handler.js +431 -0
- package/dist/src/middleware/interactive-params.d.ts +14 -0
- package/dist/src/middleware/interactive-params.js +53 -0
- package/dist/src/middleware/output.d.ts +14 -0
- package/dist/src/middleware/output.js +546 -0
- package/dist/src/models/model-catalog.d.ts +26 -0
- package/dist/src/models/model-catalog.js +216 -0
- package/dist/src/program.d.ts +2 -0
- package/dist/src/program.js +152 -0
- package/dist/src/registry/agent-contracts.d.ts +43 -0
- package/dist/src/registry/agent-contracts.js +483 -0
- package/dist/src/registry/app-loader.d.ts +2 -0
- package/dist/src/registry/app-loader.js +70 -0
- package/dist/src/registry/direct-registry.d.ts +11 -0
- package/dist/src/registry/direct-registry.js +234 -0
- package/dist/src/registry/registry-cache.d.ts +10 -0
- package/dist/src/registry/registry-cache.js +52 -0
- package/dist/src/registry/registry-client.d.ts +28 -0
- package/dist/src/registry/registry-client.js +50 -0
- package/dist/src/registry/types.d.ts +69 -0
- package/dist/src/registry/types.js +1 -0
- package/dist/src/tty/auth-presenter.d.ts +3 -0
- package/dist/src/tty/auth-presenter.js +21 -0
- package/dist/src/update/install-source.d.ts +19 -0
- package/dist/src/update/install-source.js +139 -0
- package/dist/src/update/notifier.d.ts +2 -0
- package/dist/src/update/notifier.js +59 -0
- package/dist/src/update/update-checker.d.ts +22 -0
- package/dist/src/update/update-checker.js +110 -0
- package/dist/src/update/version.d.ts +9 -0
- package/dist/src/update/version.js +52 -0
- package/dist/src/utils/agent-skill-installer.d.ts +57 -0
- package/dist/src/utils/agent-skill-installer.js +389 -0
- package/dist/src/utils/capability-metadata.d.ts +18 -0
- package/dist/src/utils/capability-metadata.js +88 -0
- package/dist/src/utils/capability-presenter.d.ts +4 -0
- package/dist/src/utils/capability-presenter.js +190 -0
- package/dist/src/utils/config.d.ts +16 -0
- package/dist/src/utils/config.js +54 -0
- package/dist/src/utils/credential-permissions.d.ts +2 -0
- package/dist/src/utils/credential-permissions.js +22 -0
- package/dist/src/utils/ecommerce-input-guidance.d.ts +15 -0
- package/dist/src/utils/ecommerce-input-guidance.js +85 -0
- package/dist/src/utils/endpoints.d.ts +52 -0
- package/dist/src/utils/endpoints.js +258 -0
- package/dist/src/utils/enrich-upload-params.d.ts +6 -0
- package/dist/src/utils/enrich-upload-params.js +11 -0
- package/dist/src/utils/entitlement.d.ts +17 -0
- package/dist/src/utils/entitlement.js +146 -0
- package/dist/src/utils/gd-home.d.ts +7 -0
- package/dist/src/utils/gd-home.js +26 -0
- package/dist/src/utils/help-verify.d.ts +9 -0
- package/dist/src/utils/help-verify.js +41 -0
- package/dist/src/utils/input-json.d.ts +3 -0
- package/dist/src/utils/input-json.js +61 -0
- package/dist/src/utils/list-output-format.d.ts +10 -0
- package/dist/src/utils/list-output-format.js +34 -0
- package/dist/src/utils/logger.d.ts +6 -0
- package/dist/src/utils/logger.js +19 -0
- package/dist/src/utils/matting-compose.d.ts +10 -0
- package/dist/src/utils/matting-compose.js +45 -0
- package/dist/src/utils/open-browser.d.ts +1 -0
- package/dist/src/utils/open-browser.js +4 -0
- package/dist/src/utils/output-path.d.ts +5 -0
- package/dist/src/utils/output-path.js +70 -0
- package/dist/src/utils/redact.d.ts +3 -0
- package/dist/src/utils/redact.js +96 -0
- package/dist/src/utils/reference-image.d.ts +8 -0
- package/dist/src/utils/reference-image.js +43 -0
- package/dist/src/utils/resolve-app-local-images.d.ts +8 -0
- package/dist/src/utils/resolve-app-local-images.js +84 -0
- package/dist/src/utils/sensitive-path.d.ts +6 -0
- package/dist/src/utils/sensitive-path.js +69 -0
- package/dist/src/utils/settings-store.d.ts +42 -0
- package/dist/src/utils/settings-store.js +50 -0
- package/dist/src/utils/sleep.d.ts +1 -0
- package/dist/src/utils/sleep.js +3 -0
- package/dist/src/utils/spinner.d.ts +2 -0
- package/dist/src/utils/spinner.js +4 -0
- package/dist/src/utils/static-help.d.ts +2 -0
- package/dist/src/utils/static-help.js +3 -0
- package/dist/src/utils/tool-display.d.ts +10 -0
- package/dist/src/utils/tool-display.js +55 -0
- package/dist/src/utils/transient-network-error.d.ts +4 -0
- package/dist/src/utils/transient-network-error.js +40 -0
- package/dist/src/utils/url-safety.d.ts +6 -0
- package/dist/src/utils/url-safety.js +67 -0
- package/dist/src/utils/write-app-deliverables.d.ts +18 -0
- package/dist/src/utils/write-app-deliverables.js +386 -0
- package/package.json +91 -0
- package/skills/gd-cli/SKILL.md +57 -0
- package/skills/gd-cli/references/auth.md +31 -0
- package/skills/gd-cli/references/deliverables.md +22 -0
- package/skills/gd-cli/references/entitlement.md +21 -0
- package/skills/gd-cli/references/errors.md +19 -0
- package/skills/gd-cli/references/org.md +18 -0
- package/skills/gd-cli/references/sop.md +25 -0
- package/skills/gd-cli/references/tools.md +29 -0
- package/skills/gd-cli/references/update.md +16 -0
- package/skills/gd-cli/references/workflows.md +22 -0
|
@@ -0,0 +1,383 @@
|
|
|
1
|
+
import { Option } from "commander";
|
|
2
|
+
import { ToolInvoker } from "../api/tool-invoker.js";
|
|
3
|
+
import { withAuth } from "../middleware/auth.js";
|
|
4
|
+
import { withErrorHandler } from "../middleware/error-handler.js";
|
|
5
|
+
import { formatOutput, rowsForToolList } from "../middleware/output.js";
|
|
6
|
+
import { resolveInvokeOutputFormat, resolveListOutputFormat, } from "../utils/list-output-format.js";
|
|
7
|
+
import { createSpinner } from "../utils/spinner.js";
|
|
8
|
+
import { resolveToolActivityLabel, toolActivityLabel, } from "../utils/tool-display.js";
|
|
9
|
+
import { enrichUploadParamsIfNeeded } from "../utils/enrich-upload-params.js";
|
|
10
|
+
import { appendToolQuickExample } from "../utils/help-verify.js";
|
|
11
|
+
import { emitJson, wrapEnvelope, shouldEmitEnvelope } from "../core/output/envelope.js";
|
|
12
|
+
import { PUBLIC_DIRECT_TOOLS, resolvePublicToolSpec, } from "../registry/direct-registry.js";
|
|
13
|
+
import { buildManifest, buildToolExamples, buildToolSchema, rowsForManifest, } from "../registry/agent-contracts.js";
|
|
14
|
+
import { applySetEntries, collectArg, readJsonInput } from "../utils/input-json.js";
|
|
15
|
+
import { setStaticHelp } from "../utils/static-help.js";
|
|
16
|
+
import { printCapabilityExamples, printCapabilitySchema, } from "../utils/capability-presenter.js";
|
|
17
|
+
import { capabilityMetadata } from "../utils/capability-metadata.js";
|
|
18
|
+
export function registerToolsCommand(program) {
|
|
19
|
+
const tools = program
|
|
20
|
+
.command("tools")
|
|
21
|
+
.usage("<command> [options]")
|
|
22
|
+
.description("单项 AI 创意能力 Tools")
|
|
23
|
+
.configureHelp({ showGlobalOptions: true });
|
|
24
|
+
setStaticHelp(tools, TOOLS_HELP);
|
|
25
|
+
tools
|
|
26
|
+
.command("list")
|
|
27
|
+
.alias("ls")
|
|
28
|
+
.description("列出内置 Tools")
|
|
29
|
+
.option("--category <cat>", "分类: image / text / video / infrastructure")
|
|
30
|
+
.action(withErrorHandler(async (options, command) => {
|
|
31
|
+
const opts = options;
|
|
32
|
+
const cmd = command;
|
|
33
|
+
let items = PUBLIC_DIRECT_TOOLS;
|
|
34
|
+
if (opts.category) {
|
|
35
|
+
const cat = String(opts.category);
|
|
36
|
+
items = items.filter((item) => item.category === cat);
|
|
37
|
+
}
|
|
38
|
+
const publicItems = items.map(toPublicToolPayload);
|
|
39
|
+
const format = resolveListOutputFormat(cmd);
|
|
40
|
+
if (shouldEmitEnvelope(format)) {
|
|
41
|
+
emitJson(wrapEnvelope({ tools: publicItems }, { command: "tools ls" }));
|
|
42
|
+
}
|
|
43
|
+
else if (format === "json") {
|
|
44
|
+
formatOutput(publicItems, format);
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
formatOutput(rowsForToolList(publicItems), format);
|
|
48
|
+
}
|
|
49
|
+
}));
|
|
50
|
+
tools
|
|
51
|
+
.command("info <tool-id>")
|
|
52
|
+
.description("查看工具详情")
|
|
53
|
+
.action(withErrorHandler(async (toolId, _opts, command) => {
|
|
54
|
+
const cmd = command;
|
|
55
|
+
const detail = resolvePublicToolSpec(String(toolId));
|
|
56
|
+
if (!detail)
|
|
57
|
+
throw new Error(`未找到工具: ${String(toolId)}`);
|
|
58
|
+
const payload = toPublicToolPayload(detail);
|
|
59
|
+
const format = cmd.parent?.parent?.opts().format ?? "json";
|
|
60
|
+
if (shouldEmitEnvelope(format)) {
|
|
61
|
+
emitJson(wrapEnvelope(payload, { command: "tools info", tool_id: toolId }));
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
formatOutput(payload, format);
|
|
65
|
+
}
|
|
66
|
+
}));
|
|
67
|
+
tools
|
|
68
|
+
.command("schema <tool-id>")
|
|
69
|
+
.description("查看输入/输出 JSON Schema")
|
|
70
|
+
.action(withErrorHandler(async (toolId, _opts, command) => {
|
|
71
|
+
const cmd = command;
|
|
72
|
+
const payload = buildToolSchema(String(toolId));
|
|
73
|
+
const format = resolveListOutputFormat(cmd);
|
|
74
|
+
if (format === "json") {
|
|
75
|
+
formatOutput(payload, "json");
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
printCapabilitySchema(payload);
|
|
79
|
+
}
|
|
80
|
+
}));
|
|
81
|
+
tools
|
|
82
|
+
.command("examples <tool-id>")
|
|
83
|
+
.description("查看调用示例")
|
|
84
|
+
.action(withErrorHandler(async (toolId, _opts, command) => {
|
|
85
|
+
const cmd = command;
|
|
86
|
+
const payload = buildToolExamples(String(toolId));
|
|
87
|
+
const format = resolveListOutputFormat(cmd);
|
|
88
|
+
if (format === "json") {
|
|
89
|
+
formatOutput(payload, "json");
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
printCapabilityExamples(payload);
|
|
93
|
+
}
|
|
94
|
+
}));
|
|
95
|
+
tools
|
|
96
|
+
.command("manifest")
|
|
97
|
+
.description("输出 Tools 机器可读能力清单")
|
|
98
|
+
.action((_opts, command) => {
|
|
99
|
+
const manifest = buildManifest("tools");
|
|
100
|
+
const format = resolveListOutputFormat(command);
|
|
101
|
+
formatOutput(format === "json" ? manifest : rowsForManifest(manifest), format);
|
|
102
|
+
});
|
|
103
|
+
const callCmd = tools
|
|
104
|
+
.command("call <tool-id> [input]")
|
|
105
|
+
.usage("<tool-id> [input] [options]")
|
|
106
|
+
.description("调用指定工具")
|
|
107
|
+
.option("--input <file>", "从 JSON 文件读取输入,使用 - 表示 stdin")
|
|
108
|
+
.option("--set <key=value>", "直接传入单个字段,可重复", collectArg)
|
|
109
|
+
.option("--asset <id-or-url>", "传入 DAM asset_id 或 CDN URL,可重复", collectArg)
|
|
110
|
+
.option("--prompt <text>", "文字提示词")
|
|
111
|
+
.option("--brief <text>", "业务 brief / 商品描述")
|
|
112
|
+
.option("--image <url>", "输入图片 URL")
|
|
113
|
+
.option("--image-url <url>", "输入图片 URL")
|
|
114
|
+
.option("--image-file <path>", "输入图片本地路径")
|
|
115
|
+
.option("--image-prompt <text>", "图片内容描述,不上传本地图片")
|
|
116
|
+
.option("--require-image", "要求必须提供真实参考图;缺图时不退化为文生", false)
|
|
117
|
+
.option("--video <url>", "输入视频 URL 或本地路径")
|
|
118
|
+
.option("--video-url <url>", "输入视频 URL")
|
|
119
|
+
.option("--video-file <path>", "输入视频本地路径")
|
|
120
|
+
.option("--style <code>", "风格代码")
|
|
121
|
+
.option("--style-code <code>", "风格/模型代码")
|
|
122
|
+
.option("--model <code-or-name>", "模型 code / 名称 / auto")
|
|
123
|
+
.option("--ratio <ratio>", "宽高比")
|
|
124
|
+
.option("--resolution <value>", "分辨率参数")
|
|
125
|
+
.option("--duration <value>", "视频时长参数")
|
|
126
|
+
.option("--content-id <id>", "指定后端 content_id;部分工具未传或非法时会自动生成")
|
|
127
|
+
.option("--mask <url>", "蒙版图 URL")
|
|
128
|
+
.option("--mask-url <url>", "蒙版图 URL")
|
|
129
|
+
.option("--mask-file <path>", "蒙版图本地路径")
|
|
130
|
+
.option("--compose-mask", "将后端 mask 与原图合成透明 PNG(默认开启)")
|
|
131
|
+
.option("--raw-mask", "仅返回后端 mask,不做合成", false)
|
|
132
|
+
.option("--width <n>", "目标宽度", parseInt)
|
|
133
|
+
.option("--height <n>", "目标高度", parseInt)
|
|
134
|
+
.option("--mode <mode>", "模式参数")
|
|
135
|
+
.option("--file <path>", "本地文件路径")
|
|
136
|
+
.option("--allow-sensitive-path", "确认上传默认受保护的本地路径", false)
|
|
137
|
+
.addOption(new Option("--arg <entry>", "内部调试参数 key=value,可重复").hideHelp().argParser(collectArg))
|
|
138
|
+
.option("--async", "异步模式", false)
|
|
139
|
+
.option("--timeout <seconds>", "超时秒数;未传时使用工具默认值")
|
|
140
|
+
.allowUnknownOption(true);
|
|
141
|
+
callCmd.action(withErrorHandler(async (toolName, input, options, command) => {
|
|
142
|
+
await withAuth(async () => {
|
|
143
|
+
await runToolCall(toolName, input, options, command);
|
|
144
|
+
})(toolName, input, options, command);
|
|
145
|
+
}));
|
|
146
|
+
loadDynamicToolAliases(tools);
|
|
147
|
+
callCmd.addHelpText("afterAll", TOOL_CALL_HELP);
|
|
148
|
+
}
|
|
149
|
+
export async function runToolCall(toolName, input, opts, cmd) {
|
|
150
|
+
const spec = resolvePublicToolSpec(toolName);
|
|
151
|
+
if (!spec) {
|
|
152
|
+
throw new Error(`未找到工具: ${toolName}。临时生成 CDN URL 可使用 gd-cli tools call upload --file <file>;DAM 入库请使用 gd-cli dam upload <file>`);
|
|
153
|
+
}
|
|
154
|
+
const inputOption = optionalString(opts.input);
|
|
155
|
+
const inputOptionIsJson = inputOption ? shouldReadJsonInput(inputOption) : false;
|
|
156
|
+
const inputArgIsJson = input ? shouldReadJsonInput(input) : false;
|
|
157
|
+
let params = {};
|
|
158
|
+
if (inputArgIsJson && input) {
|
|
159
|
+
params = { ...params, ...(await readJsonInput(input)) };
|
|
160
|
+
}
|
|
161
|
+
if (inputOptionIsJson && inputOption) {
|
|
162
|
+
params = { ...params, ...(await readJsonInput(inputOption)) };
|
|
163
|
+
}
|
|
164
|
+
if (input && !inputArgIsJson)
|
|
165
|
+
params.input = input;
|
|
166
|
+
if (inputOption && !inputOptionIsJson)
|
|
167
|
+
params.input = inputOption;
|
|
168
|
+
params = mergeToolCallOptions(params, opts);
|
|
169
|
+
applySetEntries(params, opts.set);
|
|
170
|
+
applyAssetEntries(params, opts.asset);
|
|
171
|
+
const canonicalToolName = spec?.name ?? toolName;
|
|
172
|
+
const merged = enrichUploadParamsIfNeeded(canonicalToolName, params);
|
|
173
|
+
const label = await resolveToolActivityLabel(canonicalToolName);
|
|
174
|
+
const spinner = createSpinner(`${label} · 处理中…`);
|
|
175
|
+
if (process.stderr.isTTY)
|
|
176
|
+
spinner.start();
|
|
177
|
+
const invoker = new ToolInvoker();
|
|
178
|
+
const result = await invoker.invoke(canonicalToolName, merged, {
|
|
179
|
+
async: !!opts.async,
|
|
180
|
+
timeout: resolveTimeoutSeconds(opts.timeout, spec.timeout),
|
|
181
|
+
});
|
|
182
|
+
if (process.stderr.isTTY) {
|
|
183
|
+
if (result.status === "completed")
|
|
184
|
+
spinner.succeed(`${label} · 已完成`);
|
|
185
|
+
else if (result.status === "failed")
|
|
186
|
+
spinner.fail(`${label} · 失败`);
|
|
187
|
+
else
|
|
188
|
+
spinner.stop();
|
|
189
|
+
}
|
|
190
|
+
const format = resolveInvokeOutputFormat(cmd);
|
|
191
|
+
if (shouldEmitEnvelope(format)) {
|
|
192
|
+
emitJson(wrapEnvelope(result, { command: "tools call", tool_id: canonicalToolName }));
|
|
193
|
+
}
|
|
194
|
+
else {
|
|
195
|
+
formatOutput(result, format, { activityLabel: label });
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
export function mergeToolCallOptions(base, opts) {
|
|
199
|
+
const params = { ...base };
|
|
200
|
+
const ignoredKeys = new Set(["async", "timeout", "input", "set", "asset"]);
|
|
201
|
+
const normalizedKeys = {
|
|
202
|
+
imageUrl: "image_url",
|
|
203
|
+
"image-url": "image_url",
|
|
204
|
+
imageFile: "image_file",
|
|
205
|
+
"image-file": "image_file",
|
|
206
|
+
imagePrompt: "image_prompt",
|
|
207
|
+
"image-prompt": "image_prompt",
|
|
208
|
+
maskUrl: "mask_url",
|
|
209
|
+
"mask-url": "mask_url",
|
|
210
|
+
maskFile: "mask_file",
|
|
211
|
+
"mask-file": "mask_file",
|
|
212
|
+
style: "style_code",
|
|
213
|
+
styleCode: "style_code",
|
|
214
|
+
requireImage: "require_image",
|
|
215
|
+
"require-image": "require_image",
|
|
216
|
+
videoUrl: "video_url",
|
|
217
|
+
"video-url": "video_url",
|
|
218
|
+
videoFile: "video_file",
|
|
219
|
+
"video-file": "video_file",
|
|
220
|
+
contentId: "content_id",
|
|
221
|
+
"content-id": "content_id",
|
|
222
|
+
allowSensitivePath: "allow_sensitive_path",
|
|
223
|
+
"allow-sensitive-path": "allow_sensitive_path",
|
|
224
|
+
composeMask: "compose_mask",
|
|
225
|
+
"compose-mask": "compose_mask",
|
|
226
|
+
rawMask: "raw_mask",
|
|
227
|
+
"raw-mask": "raw_mask",
|
|
228
|
+
};
|
|
229
|
+
for (const [key, value] of Object.entries(opts)) {
|
|
230
|
+
if (ignoredKeys.has(key) || value === undefined || value === false)
|
|
231
|
+
continue;
|
|
232
|
+
params[normalizedKeys[key] ?? key] = value;
|
|
233
|
+
}
|
|
234
|
+
return params;
|
|
235
|
+
}
|
|
236
|
+
function shouldReadJsonInput(value) {
|
|
237
|
+
return value === "-" || /\.json$/i.test(value);
|
|
238
|
+
}
|
|
239
|
+
function optionalString(value) {
|
|
240
|
+
if (typeof value !== "string")
|
|
241
|
+
return undefined;
|
|
242
|
+
const trimmed = value.trim();
|
|
243
|
+
return trimmed ? trimmed : undefined;
|
|
244
|
+
}
|
|
245
|
+
function applyAssetEntries(target, entries) {
|
|
246
|
+
if (!Array.isArray(entries) || entries.length === 0)
|
|
247
|
+
return;
|
|
248
|
+
const assets = entries.map(String).filter(Boolean);
|
|
249
|
+
if (assets.length === 0)
|
|
250
|
+
return;
|
|
251
|
+
target.assets = assets;
|
|
252
|
+
if (!target.image && assets.length === 1)
|
|
253
|
+
target.image = assets[0];
|
|
254
|
+
if (!target.images && assets.length > 1)
|
|
255
|
+
target.images = assets;
|
|
256
|
+
}
|
|
257
|
+
function resolveTimeoutSeconds(value, fallback) {
|
|
258
|
+
if (value === undefined || value === null || value === "")
|
|
259
|
+
return fallback;
|
|
260
|
+
const parsed = Number.parseInt(String(value), 10);
|
|
261
|
+
if (!Number.isFinite(parsed) || parsed <= 0)
|
|
262
|
+
return fallback;
|
|
263
|
+
return parsed;
|
|
264
|
+
}
|
|
265
|
+
async function loadDynamicToolAliases(toolsCmd) {
|
|
266
|
+
const seen = new Set();
|
|
267
|
+
const reserved = new Set([
|
|
268
|
+
"list",
|
|
269
|
+
"ls",
|
|
270
|
+
"search",
|
|
271
|
+
"info",
|
|
272
|
+
"schema",
|
|
273
|
+
"examples",
|
|
274
|
+
"manifest",
|
|
275
|
+
"call",
|
|
276
|
+
"install",
|
|
277
|
+
"uninstall",
|
|
278
|
+
]);
|
|
279
|
+
for (const spec of PUBLIC_DIRECT_TOOLS) {
|
|
280
|
+
for (const commandName of [spec.name, ...(spec.aliases ?? [])]) {
|
|
281
|
+
if (seen.has(commandName) || reserved.has(commandName)) {
|
|
282
|
+
continue;
|
|
283
|
+
}
|
|
284
|
+
seen.add(commandName);
|
|
285
|
+
registerDynamicToolAlias(toolsCmd, spec, commandName);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
function registerDynamicToolAlias(parent, spec, commandName = spec.name) {
|
|
290
|
+
const cmd = parent
|
|
291
|
+
.command(commandName, { hidden: true })
|
|
292
|
+
.description(spec.description)
|
|
293
|
+
.configureHelp({ showGlobalOptions: true });
|
|
294
|
+
for (const param of spec.input ?? []) {
|
|
295
|
+
const flag = param.cli_flag ?? `--${param.name}`;
|
|
296
|
+
const desc = param.description + (param.required ? " (必填)" : "");
|
|
297
|
+
if (param.type === "boolean") {
|
|
298
|
+
cmd.option(flag, desc, param.default);
|
|
299
|
+
}
|
|
300
|
+
else {
|
|
301
|
+
cmd.option(`${flag} <value>`, desc, param.default);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
cmd.action(withErrorHandler(async (...args) => {
|
|
305
|
+
await withAuth(async (options, command) => {
|
|
306
|
+
const opts = options;
|
|
307
|
+
const sub = command;
|
|
308
|
+
const label = toolActivityLabel(spec.name, spec);
|
|
309
|
+
const spinner = createSpinner(`${label} · 处理中…`);
|
|
310
|
+
if (process.stderr.isTTY)
|
|
311
|
+
spinner.start();
|
|
312
|
+
const merged = enrichUploadParamsIfNeeded(spec.name, opts);
|
|
313
|
+
const invoker = new ToolInvoker();
|
|
314
|
+
const result = await invoker.invoke(spec.name, merged, {
|
|
315
|
+
async: spec.async && !!opts.async,
|
|
316
|
+
timeout: spec.timeout,
|
|
317
|
+
});
|
|
318
|
+
if (process.stderr.isTTY) {
|
|
319
|
+
if (result.status === "completed")
|
|
320
|
+
spinner.succeed(`${label} · 已完成`);
|
|
321
|
+
else if (result.status === "failed")
|
|
322
|
+
spinner.fail(`${label} · 失败`);
|
|
323
|
+
else
|
|
324
|
+
spinner.stop();
|
|
325
|
+
}
|
|
326
|
+
const format = resolveInvokeOutputFormat(sub.parent ?? sub);
|
|
327
|
+
if (shouldEmitEnvelope(format)) {
|
|
328
|
+
emitJson(wrapEnvelope(result, { command: `tools ${commandName}`, tool_id: spec.name }));
|
|
329
|
+
}
|
|
330
|
+
else {
|
|
331
|
+
formatOutput(result, format, { activityLabel: label });
|
|
332
|
+
}
|
|
333
|
+
})(...args);
|
|
334
|
+
}));
|
|
335
|
+
appendToolQuickExample(cmd, spec.name);
|
|
336
|
+
}
|
|
337
|
+
const TOOLS_HELP = `
|
|
338
|
+
gd-cli tools <command> [options]
|
|
339
|
+
|
|
340
|
+
用于调用一个独立能力,例如图片生成、抠图、高清化、标题生成、提示词扩写、视频生成。
|
|
341
|
+
如果你要完成完整业务场景,请优先查看 workflows。
|
|
342
|
+
|
|
343
|
+
常用命令:
|
|
344
|
+
list/ls 列出内置 Tools
|
|
345
|
+
info <tool-id> 查看具体 Tool 详情
|
|
346
|
+
call <tool-id> 调用具体 Tool 能力
|
|
347
|
+
manifest 输出 Tools 能力清单
|
|
348
|
+
schema <tool-id> 查看输入/输出 Schema
|
|
349
|
+
examples <tool-id> 查看调用示例
|
|
350
|
+
|
|
351
|
+
分类:
|
|
352
|
+
image 生图、抠图、高清化、SVG
|
|
353
|
+
video 文生视频、图生视频
|
|
354
|
+
text 标题、提示词、文案
|
|
355
|
+
asset 临时上传、CDN URL
|
|
356
|
+
|
|
357
|
+
示例:
|
|
358
|
+
gd-cli tools list --category image
|
|
359
|
+
gd-cli tools info image.generate
|
|
360
|
+
gd-cli tools schema image.generate
|
|
361
|
+
gd-cli tools call image.generate --input prompt.json --format json
|
|
362
|
+
`;
|
|
363
|
+
function toPublicToolPayload(tool) {
|
|
364
|
+
const { endpoint: _endpoint, method: _method, runtime: _runtime, required_env: _requiredEnv, ...publicTool } = tool;
|
|
365
|
+
return {
|
|
366
|
+
...publicTool,
|
|
367
|
+
...capabilityMetadata("tool", tool.name),
|
|
368
|
+
canonical_command: `gd-cli tools call ${tool.name}`,
|
|
369
|
+
schema_command: `gd-cli tools schema ${tool.name} --format json`,
|
|
370
|
+
examples_command: `gd-cli tools examples ${tool.name} --format json`,
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
const TOOL_CALL_HELP = `
|
|
374
|
+
|
|
375
|
+
JSON 输入:
|
|
376
|
+
gd-cli tools call image.generate --input prompt.json --format json
|
|
377
|
+
cat prompt.json | gd-cli tools call image.generate - --format json
|
|
378
|
+
gd-cli tools call text.title --set brief="夏季防晒衣,轻薄透气" --format json
|
|
379
|
+
|
|
380
|
+
说明:
|
|
381
|
+
--input <file> 读取 JSON object;位置参数 - 从 stdin 读取 JSON。
|
|
382
|
+
命令行参数会覆盖 JSON 同名字段。
|
|
383
|
+
`;
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
import { confirm } from "@inquirer/prompts";
|
|
4
|
+
import { withErrorHandler } from "../middleware/error-handler.js";
|
|
5
|
+
import { buildUpdateCommand, detectInstallSource } from "../update/install-source.js";
|
|
6
|
+
import { checkForUpdate, clearUpdateCache } from "../update/update-checker.js";
|
|
7
|
+
import { AgentSkillInstaller } from "../utils/agent-skill-installer.js";
|
|
8
|
+
export function registerUpdateCommand(program) {
|
|
9
|
+
const update = program
|
|
10
|
+
.command("update")
|
|
11
|
+
.description("检查并升级 gd-cli")
|
|
12
|
+
.option("--channel <tag>", "npm dist-tag: latest / next / alpha", "latest")
|
|
13
|
+
.option("--manager <name>", "指定包管理器: npm / pnpm / yarn / brew")
|
|
14
|
+
.option("--dry-run", "只显示升级命令,不执行")
|
|
15
|
+
.option("-y, --yes", "跳过确认直接升级")
|
|
16
|
+
.action(withErrorHandler(async (options, command) => {
|
|
17
|
+
await runUpdate(options, command);
|
|
18
|
+
}));
|
|
19
|
+
update
|
|
20
|
+
.command("check")
|
|
21
|
+
.description("检查是否有新版本")
|
|
22
|
+
.option("--channel <tag>", "npm dist-tag: latest / next / alpha", "latest")
|
|
23
|
+
.option("--force", "忽略 24 小时缓存,强制请求 registry")
|
|
24
|
+
.action(withErrorHandler(async (options, command) => {
|
|
25
|
+
const info = await checkForUpdate({
|
|
26
|
+
channel: options.channel,
|
|
27
|
+
force: options.force,
|
|
28
|
+
});
|
|
29
|
+
printUpdateInfo(info, outputFormat(command));
|
|
30
|
+
}));
|
|
31
|
+
update
|
|
32
|
+
.command("clear-cache")
|
|
33
|
+
.description("清除本地升级检查缓存")
|
|
34
|
+
.action(withErrorHandler(async () => {
|
|
35
|
+
clearUpdateCache();
|
|
36
|
+
console.log(chalk.green("✓ 已清除升级检查缓存"));
|
|
37
|
+
}));
|
|
38
|
+
}
|
|
39
|
+
async function runUpdate(options, command) {
|
|
40
|
+
const info = await checkForUpdate({
|
|
41
|
+
channel: options.channel,
|
|
42
|
+
force: true,
|
|
43
|
+
});
|
|
44
|
+
const source = detectInstallSource(options.manager);
|
|
45
|
+
const updateCommand = buildUpdateCommand(info.latest_version, source);
|
|
46
|
+
const format = outputFormat(command);
|
|
47
|
+
if (!info.update_available) {
|
|
48
|
+
printUpdateInfo({ ...info, install_source: source }, format);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
if (source.kind !== "global") {
|
|
52
|
+
const payload = {
|
|
53
|
+
...info,
|
|
54
|
+
install_source: source,
|
|
55
|
+
update_command: updateCommand.display,
|
|
56
|
+
blocked: true,
|
|
57
|
+
reason: source.reason,
|
|
58
|
+
};
|
|
59
|
+
if (format === "json") {
|
|
60
|
+
console.log(JSON.stringify(payload, null, 2));
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
console.log(chalk.yellow(`${source.reason},gd-cli update 不会修改全局环境。`));
|
|
64
|
+
console.log(`如需升级全局安装,请手动执行: ${chalk.cyan(updateCommand.display)}`);
|
|
65
|
+
}
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
if (options.dryRun) {
|
|
69
|
+
printUpdateInfo({
|
|
70
|
+
...info,
|
|
71
|
+
install_source: source,
|
|
72
|
+
}, format, updateCommand.display);
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
if (!options.yes && process.stdin.isTTY) {
|
|
76
|
+
const ok = await confirm({
|
|
77
|
+
message: `将执行 ${updateCommand.display},是否继续?`,
|
|
78
|
+
default: true,
|
|
79
|
+
});
|
|
80
|
+
if (!ok) {
|
|
81
|
+
console.log("已取消升级。");
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
else if (!options.yes && !process.stdin.isTTY) {
|
|
86
|
+
throw new Error(`非交互环境请加 --yes,或手动执行: ${updateCommand.display}`);
|
|
87
|
+
}
|
|
88
|
+
const shouldRefreshAgentSkill = hasInstalledCanonicalSkill();
|
|
89
|
+
await spawnUpdate(updateCommand.command, updateCommand.args);
|
|
90
|
+
if (shouldRefreshAgentSkill) {
|
|
91
|
+
await refreshAgentSkillAfterUpdate();
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
function printUpdateInfo(info, format, updateCommand) {
|
|
95
|
+
if (format === "json") {
|
|
96
|
+
console.log(JSON.stringify({
|
|
97
|
+
...info,
|
|
98
|
+
update_command: updateCommand ?? buildUpdateCommand(info.latest_version, info.install_source).display,
|
|
99
|
+
}, null, 2));
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
console.log(chalk.bold("\ngd-cli 版本检查\n"));
|
|
103
|
+
console.log(` 当前版本: ${chalk.cyan(info.current_version)}`);
|
|
104
|
+
console.log(` 最新版本: ${chalk.cyan(info.latest_version)} (${info.channel})`);
|
|
105
|
+
console.log(` Registry: ${chalk.dim(info.registry)}`);
|
|
106
|
+
console.log(` 安装方式: ${info.install_source.manager} / ${info.install_source.kind}`);
|
|
107
|
+
if (info.unavailable_reason === "package_not_found") {
|
|
108
|
+
console.log(chalk.yellow("\n 当前 registry 暂未找到该包,已跳过自动升级检查"));
|
|
109
|
+
console.log("");
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
if (info.update_available) {
|
|
113
|
+
const cmd = updateCommand ?? buildUpdateCommand(info.latest_version, info.install_source).display;
|
|
114
|
+
console.log(chalk.yellow("\n 有新版本可用"));
|
|
115
|
+
console.log(` 升级命令: ${chalk.cyan(cmd)}`);
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
console.log(chalk.green("\n 已是最新版本"));
|
|
119
|
+
}
|
|
120
|
+
console.log("");
|
|
121
|
+
}
|
|
122
|
+
function outputFormat(command) {
|
|
123
|
+
return rootCommand(command).opts().format ?? "human";
|
|
124
|
+
}
|
|
125
|
+
function rootCommand(command) {
|
|
126
|
+
let cur = command;
|
|
127
|
+
while (cur.parent)
|
|
128
|
+
cur = cur.parent;
|
|
129
|
+
return cur;
|
|
130
|
+
}
|
|
131
|
+
function spawnUpdate(command, args) {
|
|
132
|
+
return new Promise((resolve, reject) => {
|
|
133
|
+
const child = spawn(command, args, {
|
|
134
|
+
stdio: "inherit",
|
|
135
|
+
});
|
|
136
|
+
child.on("error", reject);
|
|
137
|
+
child.on("exit", (code) => {
|
|
138
|
+
if (code === 0) {
|
|
139
|
+
resolve();
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
reject(new Error(`升级命令退出码: ${code}`));
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
async function refreshAgentSkillAfterUpdate() {
|
|
148
|
+
try {
|
|
149
|
+
await spawnUpdate("gd-cli", ["skills", "update"]);
|
|
150
|
+
}
|
|
151
|
+
catch (error) {
|
|
152
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
153
|
+
console.error(chalk.yellow(`gd-cli 已升级,但 Agent Skill 自动刷新失败:${message}`));
|
|
154
|
+
console.error(chalk.dim("可稍后手动执行: gd-cli skills update"));
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
function hasInstalledCanonicalSkill() {
|
|
158
|
+
try {
|
|
159
|
+
const canonical = new AgentSkillInstaller()
|
|
160
|
+
.status()
|
|
161
|
+
.targets.find((target) => target.agent === "universal");
|
|
162
|
+
return canonical?.status === "installed" || canonical?.status === "outdated";
|
|
163
|
+
}
|
|
164
|
+
catch {
|
|
165
|
+
return false;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Command } from "commander";
|
|
2
|
+
import { UsageClient } from "../api/usage-client.js";
|
|
3
|
+
interface UsageCommandDeps {
|
|
4
|
+
createClient?: () => Pick<UsageClient, "getCreditsOverview">;
|
|
5
|
+
}
|
|
6
|
+
export declare function registerUsageCommand(program: Command, deps?: UsageCommandDeps): void;
|
|
7
|
+
export {};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
import { UsageClient } from "../api/usage-client.js";
|
|
3
|
+
import { withErrorHandler } from "../middleware/error-handler.js";
|
|
4
|
+
import { formatOutput } from "../middleware/output.js";
|
|
5
|
+
export function registerUsageCommand(program, deps = {}) {
|
|
6
|
+
program
|
|
7
|
+
.command("usage", { hidden: true })
|
|
8
|
+
.description("Agent internal usage and entitlement probe")
|
|
9
|
+
.action(withErrorHandler(async (_options, command) => {
|
|
10
|
+
const client = deps.createClient?.() ?? new UsageClient();
|
|
11
|
+
const payload = await client.getCreditsOverview();
|
|
12
|
+
const format = outputFormat(command);
|
|
13
|
+
if (format === "json") {
|
|
14
|
+
formatOutput(payload, "json");
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
printUsageHuman(payload);
|
|
18
|
+
}));
|
|
19
|
+
}
|
|
20
|
+
function printUsageHuman(payload) {
|
|
21
|
+
const { organization, credits } = payload;
|
|
22
|
+
console.log(chalk.bold("稿豆余额"));
|
|
23
|
+
console.log(` 当前组织: ${organization.name ?? organization.id} (${organization.id})`);
|
|
24
|
+
console.log(` 剩余稿豆: ${credits.surplus}`);
|
|
25
|
+
console.log(` 总额: ${credits.total}`);
|
|
26
|
+
console.log(` 已使用: ${credits.used}`);
|
|
27
|
+
if (credits.wait)
|
|
28
|
+
console.log(` 待生效: ${credits.wait}`);
|
|
29
|
+
console.log("");
|
|
30
|
+
}
|
|
31
|
+
function outputFormat(command) {
|
|
32
|
+
const root = rootCommand(command);
|
|
33
|
+
const opts = root.opts();
|
|
34
|
+
if (opts.json)
|
|
35
|
+
return "json";
|
|
36
|
+
return opts.format ?? "human";
|
|
37
|
+
}
|
|
38
|
+
function rootCommand(command) {
|
|
39
|
+
let current = command;
|
|
40
|
+
while (current.parent)
|
|
41
|
+
current = current.parent;
|
|
42
|
+
return current;
|
|
43
|
+
}
|