gaoding-cli 1.0.0-alpha.7 → 1.0.0-alpha.8
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 +20 -0
- package/README.md +18 -14
- package/dist/src/api/app-runner.js +1 -2
- package/dist/src/api/creative-client.d.ts +34 -0
- package/dist/src/api/creative-client.js +184 -0
- 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 +13 -13
- package/dist/src/commands/creative.d.ts +8 -0
- package/dist/src/commands/creative.js +186 -0
- package/dist/src/commands/dam.js +27 -22
- package/dist/src/commands/org.js +20 -14
- package/dist/src/commands/skills.js +9 -4
- package/dist/src/commands/update.js +6 -2
- package/dist/src/commands/usage.d.ts +1 -1
- package/dist/src/commands/usage.js +6 -4
- package/dist/src/commands/workflows.js +31 -13
- 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/creative/contract.d.ts +1112 -0
- package/dist/src/creative/contract.js +743 -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/middleware/auth.d.ts +6 -2
- package/dist/src/middleware/auth.js +25 -63
- package/dist/src/middleware/error-handler.d.ts +2 -0
- package/dist/src/middleware/error-handler.js +3 -4
- package/dist/src/program.js +7 -89
- package/dist/src/registry/agent-contracts.d.ts +3 -11
- package/dist/src/registry/agent-contracts.js +5 -243
- 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/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/package.json +3 -3
- package/skills/gd-cli/SKILL.md +10 -9
- package/skills/gd-cli/references/auth.md +6 -0
- package/skills/gd-cli/references/creative.md +47 -0
- package/skills/gd-cli/references/entitlement.md +2 -2
- package/skills/gd-cli/references/errors.md +7 -0
- package/skills/gd-cli/references/sop.md +4 -4
- package/skills/gd-cli/references/workflows.md +1 -1
- 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/skills/gd-cli/references/tools.md +0 -29
|
@@ -7,6 +7,7 @@ import { getIO } from "../io.js";
|
|
|
7
7
|
import { emitJson, wrapEnvelope } from "../core/output/envelope.js";
|
|
8
8
|
import { setStaticHelp } from "../utils/static-help.js";
|
|
9
9
|
import { resolveInvokeOutputFormat } from "../utils/list-output-format.js";
|
|
10
|
+
import { setAuthRequirement } from "../middleware/auth.js";
|
|
10
11
|
const loginAction = withErrorHandler(async (options) => {
|
|
11
12
|
if (isVerbose() || isDebug()) {
|
|
12
13
|
const ep = resolveEndpoints();
|
|
@@ -32,7 +33,7 @@ const loginAction = withErrorHandler(async (options) => {
|
|
|
32
33
|
}
|
|
33
34
|
console.log(chalk.green("\n✓ 授权成功,可以开始使用稿定能力进行创意生产\n"));
|
|
34
35
|
if (!result.org) {
|
|
35
|
-
console.log(chalk.yellow("
|
|
36
|
+
console.log(chalk.yellow(" 尚未选择当前组织,请执行 gd-cli org switch 后再调用 Creative / Workflows / DAM。"));
|
|
36
37
|
}
|
|
37
38
|
});
|
|
38
39
|
const statusAction = withErrorHandler(async (_opts, command) => {
|
|
@@ -78,19 +79,25 @@ export function registerAuthCommand(program) {
|
|
|
78
79
|
.command("auth")
|
|
79
80
|
.description("登录、退出、查看登录状态");
|
|
80
81
|
setStaticHelp(auth, AUTH_HELP);
|
|
81
|
-
auth
|
|
82
|
+
const login = auth
|
|
82
83
|
.command("login")
|
|
83
84
|
.description("浏览器/扫码授权登录")
|
|
84
|
-
.option("--org <org-id>", "
|
|
85
|
+
.option("--org <org-id>", "登录后直接选择当前组织")
|
|
85
86
|
.option("--env <env>", "环境标识 cursor / claude / ci")
|
|
86
87
|
.option("--scope <scope>", "授权范围,逗号分隔")
|
|
87
88
|
.option("--no-browser", "不自动打开浏览器")
|
|
88
89
|
.action(loginAction);
|
|
89
|
-
|
|
90
|
+
setAuthRequirement(login, "none");
|
|
91
|
+
const logout = auth
|
|
90
92
|
.command("logout")
|
|
91
93
|
.description("取消授权")
|
|
92
94
|
.action(logoutAction);
|
|
93
|
-
|
|
95
|
+
setAuthRequirement(logout, "none");
|
|
96
|
+
const status = auth
|
|
97
|
+
.command("status")
|
|
98
|
+
.description("查看授权状态")
|
|
99
|
+
.action(statusAction);
|
|
100
|
+
setAuthRequirement(status, "none");
|
|
94
101
|
}
|
|
95
102
|
const AUTH_HELP = `
|
|
96
103
|
Usage: gd-cli auth [options] [command]
|
|
@@ -105,15 +112,12 @@ Commands:
|
|
|
105
112
|
function buildStatusPayload(creds, store) {
|
|
106
113
|
const ep = resolveEndpoints();
|
|
107
114
|
const credentialExpired = store.isAkExpired();
|
|
108
|
-
const orgBindExpired = store.isBindExpired();
|
|
109
115
|
const envMatches = !creds.issued_for_env || creds.issued_for_env === ep.active_env;
|
|
110
116
|
const nextSteps = [];
|
|
111
117
|
if (credentialExpired)
|
|
112
118
|
nextSteps.push("gd-cli auth login");
|
|
113
119
|
if (!creds.current_org?.id)
|
|
114
120
|
nextSteps.push("gd-cli org list", "gd-cli org switch");
|
|
115
|
-
if (orgBindExpired)
|
|
116
|
-
nextSteps.push("gd-cli org switch");
|
|
117
121
|
if (!envMatches)
|
|
118
122
|
nextSteps.push("gd-cli auth login");
|
|
119
123
|
const payload = {
|
|
@@ -131,8 +135,6 @@ function buildStatusPayload(creds, store) {
|
|
|
131
135
|
? {
|
|
132
136
|
id: creds.current_org.id,
|
|
133
137
|
name: creds.current_org.name,
|
|
134
|
-
bind_expires_at: creds.current_org.bind_expires_at ?? null,
|
|
135
|
-
bind_valid: !orgBindExpired,
|
|
136
138
|
}
|
|
137
139
|
: null,
|
|
138
140
|
credential: {
|
|
@@ -170,12 +172,10 @@ function printStatusHuman(payload) {
|
|
|
170
172
|
console.log(` 用户: ${account.name ?? account.user_id}`);
|
|
171
173
|
}
|
|
172
174
|
if (organization) {
|
|
173
|
-
const valid = organization.bind_valid ? "有效" : "已过期";
|
|
174
175
|
console.log(` 当前组织: ${organization.name} (${organization.id})`);
|
|
175
|
-
console.log(` 组织绑定: ${valid}${organization.bind_expires_at ? `,至 ${organization.bind_expires_at}` : ""}`);
|
|
176
176
|
}
|
|
177
177
|
else {
|
|
178
|
-
console.log(chalk.yellow(" 当前组织:
|
|
178
|
+
console.log(chalk.yellow(" 当前组织: 未选择"));
|
|
179
179
|
}
|
|
180
180
|
console.log(` 凭证: AK/SK ${credential.ak_preview},${credential.valid ? "有效" : "已过期"}`);
|
|
181
181
|
console.log(` 过期时间: ${credential.expires_at}`);
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Command } from "commander";
|
|
2
|
+
import { CreativeClient } from "../api/creative-client.js";
|
|
3
|
+
export interface CreativeCommandDeps {
|
|
4
|
+
createClient?: () => Pick<CreativeClient, "run">;
|
|
5
|
+
readInput?: (ref: string) => Promise<Record<string, unknown>>;
|
|
6
|
+
}
|
|
7
|
+
export declare function registerCreativeCommand(program: Command, deps?: CreativeCommandDeps): void;
|
|
8
|
+
export declare function runCreative(options: Record<string, unknown>, command: Command, deps?: CreativeCommandDeps): Promise<void>;
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
import { CreativeClient } from "../api/creative-client.js";
|
|
3
|
+
import { CliUsageError } from "../core/output/cli-error.js";
|
|
4
|
+
import { formatOutput } from "../middleware/output.js";
|
|
5
|
+
import { toCliErrorBody } from "../middleware/error-handler.js";
|
|
6
|
+
import { getCreativeExamples, getCreativeSchema, validateCreativeInput, } from "../creative/contract.js";
|
|
7
|
+
import { resolveInvokeOutputFormat, resolveListOutputFormat } from "../utils/list-output-format.js";
|
|
8
|
+
import { readJsonInput } from "../utils/input-json.js";
|
|
9
|
+
import { setStaticHelp } from "../utils/static-help.js";
|
|
10
|
+
import { setAuthRequirement } from "../middleware/auth.js";
|
|
11
|
+
export function registerCreativeCommand(program, deps = {}) {
|
|
12
|
+
const creative = program
|
|
13
|
+
.command("creative")
|
|
14
|
+
.usage("<command> [options]")
|
|
15
|
+
.description("通过稿定 Creative 完成图片、视频和文本创作")
|
|
16
|
+
.configureHelp({ showGlobalOptions: true });
|
|
17
|
+
setStaticHelp(creative, CREATIVE_HELP);
|
|
18
|
+
const run = creative
|
|
19
|
+
.command("run")
|
|
20
|
+
.usage("[options]")
|
|
21
|
+
.description("发起创作、继续已有创作或回答追问")
|
|
22
|
+
.option("--prompt <text>", "详细描述期望的最终结果")
|
|
23
|
+
.option("--input <path>", "从 JSON 文件读取完整输入;传 - 表示读取 stdin")
|
|
24
|
+
.action(async (options, command) => {
|
|
25
|
+
await runCreative(options, command, deps);
|
|
26
|
+
});
|
|
27
|
+
setAuthRequirement(run, "current-org");
|
|
28
|
+
const schema = creative
|
|
29
|
+
.command("schema")
|
|
30
|
+
.description("查看 Creative 输入与输出 JSON Schema")
|
|
31
|
+
.action((_options, command) => {
|
|
32
|
+
const payload = getCreativeSchema();
|
|
33
|
+
const format = resolveListOutputFormat(command);
|
|
34
|
+
if (format === "json") {
|
|
35
|
+
formatOutput(payload, "json");
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
console.log("Creative Input Schema\n");
|
|
39
|
+
console.log(JSON.stringify(payload.input_schema, null, 2));
|
|
40
|
+
console.log("\nCreative Output Schema\n");
|
|
41
|
+
console.log(JSON.stringify(payload.output_schema, null, 2));
|
|
42
|
+
});
|
|
43
|
+
setAuthRequirement(schema, "none");
|
|
44
|
+
const examples = creative
|
|
45
|
+
.command("examples")
|
|
46
|
+
.description("查看 Creative 调用示例")
|
|
47
|
+
.action((_options, command) => {
|
|
48
|
+
const payload = getCreativeExamples();
|
|
49
|
+
const format = resolveListOutputFormat(command);
|
|
50
|
+
if (format === "json") {
|
|
51
|
+
formatOutput(payload, "json");
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
for (const [index, example] of payload.examples.entries()) {
|
|
55
|
+
console.log(`${index + 1}. ${example.description} (${example.name})`);
|
|
56
|
+
console.log(JSON.stringify(example.input, null, 2));
|
|
57
|
+
console.log("");
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
setAuthRequirement(examples, "none");
|
|
61
|
+
}
|
|
62
|
+
export async function runCreative(options, command, deps = {}) {
|
|
63
|
+
const format = resolveInvokeOutputFormat(command);
|
|
64
|
+
const meta = {
|
|
65
|
+
command: "creative run",
|
|
66
|
+
schema_version: "creative/v1",
|
|
67
|
+
};
|
|
68
|
+
try {
|
|
69
|
+
const input = await resolveCreativeInput(options, deps.readInput ?? readJsonInput);
|
|
70
|
+
const client = deps.createClient?.() ?? new CreativeClient();
|
|
71
|
+
const result = await client.run(validateCreativeInput(input));
|
|
72
|
+
const envelope = {
|
|
73
|
+
status: "completed",
|
|
74
|
+
data: result,
|
|
75
|
+
error: null,
|
|
76
|
+
meta,
|
|
77
|
+
};
|
|
78
|
+
renderCreativeEnvelope(envelope, format);
|
|
79
|
+
}
|
|
80
|
+
catch (error) {
|
|
81
|
+
const envelope = {
|
|
82
|
+
status: "failed",
|
|
83
|
+
data: null,
|
|
84
|
+
error: toCreativeError(error),
|
|
85
|
+
meta,
|
|
86
|
+
};
|
|
87
|
+
if (format === "json") {
|
|
88
|
+
formatOutput(envelope, "json");
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
printCreativeError(envelope.error);
|
|
92
|
+
}
|
|
93
|
+
process.exitCode = 1;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
async function resolveCreativeInput(options, readInput) {
|
|
97
|
+
const prompt = typeof options.prompt === "string" ? options.prompt : undefined;
|
|
98
|
+
const inputRef = typeof options.input === "string" ? options.input : undefined;
|
|
99
|
+
if (prompt !== undefined && inputRef !== undefined) {
|
|
100
|
+
throw new CliUsageError({
|
|
101
|
+
code: "PARAM_INVALID",
|
|
102
|
+
type: "validation",
|
|
103
|
+
message: "--prompt 与 --input 不能同时使用",
|
|
104
|
+
hint: "纯文本请求使用 --prompt;包含媒体、parameters 或连续会话信息时使用 --input",
|
|
105
|
+
retryable: false,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
if (prompt !== undefined)
|
|
109
|
+
return { prompt };
|
|
110
|
+
if (inputRef !== undefined)
|
|
111
|
+
return readInput(inputRef);
|
|
112
|
+
throw new CliUsageError({
|
|
113
|
+
code: "PARAM_MISSING",
|
|
114
|
+
type: "validation",
|
|
115
|
+
message: "Creative 请求必须提供 --prompt 或 --input",
|
|
116
|
+
hint: "执行 gd-cli creative --help 查看输入方式",
|
|
117
|
+
retryable: false,
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
function renderCreativeEnvelope(envelope, format) {
|
|
121
|
+
if (format === "json") {
|
|
122
|
+
formatOutput(envelope, "json");
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
if (!envelope.data)
|
|
126
|
+
return;
|
|
127
|
+
printCreativeResult(envelope.data, format);
|
|
128
|
+
}
|
|
129
|
+
function printCreativeResult(result, format) {
|
|
130
|
+
if (result.message)
|
|
131
|
+
console.log(result.message);
|
|
132
|
+
for (const output of result.outputs)
|
|
133
|
+
printCreativeOutput(output, format);
|
|
134
|
+
if (result.finish_reason === "requires_input" && result.questions) {
|
|
135
|
+
console.log(chalk.yellow(`\n${result.questions.title || "需要补充信息"}`));
|
|
136
|
+
for (const question of result.questions.questions) {
|
|
137
|
+
console.log(` ${question.question}`);
|
|
138
|
+
if (question.options.length > 0) {
|
|
139
|
+
console.log(` 可选: ${question.options.map((option) => option.label).join("、")}`);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
console.log(`\n conversation_id: ${result.conversation_id}`);
|
|
143
|
+
if (result.last_tool_message_id) {
|
|
144
|
+
console.log(` last_tool_message_id: ${result.last_tool_message_id}`);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
function printCreativeOutput(output, _format) {
|
|
149
|
+
if (output.type === "text") {
|
|
150
|
+
if (output.text)
|
|
151
|
+
console.log(output.text);
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
if (output.type === "json") {
|
|
155
|
+
console.log(JSON.stringify(output.value, null, 2));
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
console.log(`${output.type}: ${output.url}`);
|
|
159
|
+
}
|
|
160
|
+
function printCreativeError(error) {
|
|
161
|
+
console.error(chalk.red(`Error: ${error.message}`));
|
|
162
|
+
if (error.code)
|
|
163
|
+
console.error(` 错误码: ${error.code}`);
|
|
164
|
+
if (error.hint)
|
|
165
|
+
console.error(` 说明: ${error.hint}`);
|
|
166
|
+
}
|
|
167
|
+
function toCreativeError(error) {
|
|
168
|
+
const body = toCliErrorBody(error);
|
|
169
|
+
return {
|
|
170
|
+
code: body.code,
|
|
171
|
+
type: body.type,
|
|
172
|
+
message: body.message,
|
|
173
|
+
...(body.hint ? { hint: body.hint } : {}),
|
|
174
|
+
...(body.retryable !== undefined ? { retryable: body.retryable } : {}),
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
const CREATIVE_HELP = `
|
|
178
|
+
Usage: gd-cli creative <command> [options]
|
|
179
|
+
|
|
180
|
+
通过稿定 Creative 完成图片、视频和文本创作
|
|
181
|
+
|
|
182
|
+
常用命令:
|
|
183
|
+
run 发起创作、继续已有创作或回答追问
|
|
184
|
+
schema 查看输入与输出 JSON Schema
|
|
185
|
+
examples 查看调用示例
|
|
186
|
+
`;
|
package/dist/src/commands/dam.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { existsSync, statSync } from "node:fs";
|
|
2
2
|
import { basename, resolve } from "node:path";
|
|
3
|
-
import {
|
|
3
|
+
import { setAuthRequirement } from "../middleware/auth.js";
|
|
4
4
|
import { withErrorHandler } from "../middleware/error-handler.js";
|
|
5
5
|
import { DamClient } from "../api/dam-client.js";
|
|
6
6
|
import { formatOutput } from "../middleware/output.js";
|
|
@@ -15,7 +15,7 @@ export function registerDamCommand(program) {
|
|
|
15
15
|
.description("DAM 素材管理")
|
|
16
16
|
.configureHelp({ showGlobalOptions: true });
|
|
17
17
|
setStaticHelp(dam, DAM_HELP);
|
|
18
|
-
dam
|
|
18
|
+
const upload = dam
|
|
19
19
|
.command("upload <file>")
|
|
20
20
|
.description("上传本地文件并提交 DAM 入库,返回 DAM asset_id 与 CDN URL")
|
|
21
21
|
.option("--repository-id <id>", "DAM 资源库 ID,默认取个人库或 GD_DAM_REPOSITORY_ID")
|
|
@@ -29,7 +29,7 @@ export function registerDamCommand(program) {
|
|
|
29
29
|
.option("--wait-analysis", "等待 DAM 后端分析完成并返回封面", false)
|
|
30
30
|
.option("--analysis-timeout <ms>", "等待分析超时时间(毫秒)", parsePositiveInteger, 180000)
|
|
31
31
|
.option("--analysis-interval <ms>", "分析轮询间隔(毫秒)", parsePositiveInteger, 3000)
|
|
32
|
-
.action(withErrorHandler(
|
|
32
|
+
.action(withErrorHandler(async (file, options, command) => {
|
|
33
33
|
const opts = options;
|
|
34
34
|
const cmd = command;
|
|
35
35
|
const p = resolve(process.cwd(), String(file));
|
|
@@ -92,8 +92,9 @@ export function registerDamCommand(program) {
|
|
|
92
92
|
else {
|
|
93
93
|
formatOutput(payload, format);
|
|
94
94
|
}
|
|
95
|
-
}))
|
|
96
|
-
|
|
95
|
+
}));
|
|
96
|
+
setAuthRequirement(upload, "current-org");
|
|
97
|
+
const list = dam
|
|
97
98
|
.command("list")
|
|
98
99
|
.description("查看最近上传素材")
|
|
99
100
|
.option("--repository-id <id>", "DAM 资源库 ID,默认取个人库或 GD_DAM_REPOSITORY_ID")
|
|
@@ -102,13 +103,13 @@ export function registerDamCommand(program) {
|
|
|
102
103
|
.option("--include-child-folder", "包含子文件夹", true)
|
|
103
104
|
.option("--no-include-child-folder", "不包含子文件夹")
|
|
104
105
|
.option("--type <type>", "image/video/audio/font/template/file")
|
|
105
|
-
.option("--format <list>", "素材格式,逗号分隔,例如 png,jpg,mp4")
|
|
106
|
+
.option("--asset-format <list>", "素材格式,逗号分隔,例如 png,jpg,mp4")
|
|
106
107
|
.option("--tag-ids <list>", "标签 ID,逗号分隔")
|
|
107
108
|
.option("--page-size <n>", "每页数量,最大 100", parsePositiveInteger, 20)
|
|
108
109
|
.option("--page <n>", "页码", parsePositiveInteger, 1)
|
|
109
110
|
.option("--cursor <id>", "分页 cursor/query_id")
|
|
110
111
|
.option("--raw", "JSON 输出包含后端原始数据", false)
|
|
111
|
-
.action(withErrorHandler(
|
|
112
|
+
.action(withErrorHandler(async (options, command) => {
|
|
112
113
|
const opts = options;
|
|
113
114
|
const cmd = command;
|
|
114
115
|
const damClient = new DamClient();
|
|
@@ -117,8 +118,9 @@ export function registerDamCommand(program) {
|
|
|
117
118
|
allowEmptyKeyword: true,
|
|
118
119
|
});
|
|
119
120
|
outputDamSearch(data, resolveListOutputFormat(cmd), "list");
|
|
120
|
-
}))
|
|
121
|
-
|
|
121
|
+
}));
|
|
122
|
+
setAuthRequirement(list, "current-org");
|
|
123
|
+
const search = dam
|
|
122
124
|
.command("search <keyword>")
|
|
123
125
|
.description("搜索素材")
|
|
124
126
|
.option("--repository-id <id>", "DAM 资源库 ID,默认取个人库或 GD_DAM_REPOSITORY_ID")
|
|
@@ -127,23 +129,24 @@ export function registerDamCommand(program) {
|
|
|
127
129
|
.option("--include-child-folder", "包含子文件夹", true)
|
|
128
130
|
.option("--no-include-child-folder", "不包含子文件夹")
|
|
129
131
|
.option("--type <type>", "image/video/audio/font/template/file")
|
|
130
|
-
.option("--format <list>", "素材格式,逗号分隔,例如 png,jpg,mp4")
|
|
132
|
+
.option("--asset-format <list>", "素材格式,逗号分隔,例如 png,jpg,mp4")
|
|
131
133
|
.option("--tag-ids <list>", "标签 ID,逗号分隔")
|
|
132
134
|
.option("--page-size <n>", "每页数量,最大 100", parsePositiveInteger, 20)
|
|
133
135
|
.option("--page <n>", "页码", parsePositiveInteger, 1)
|
|
134
136
|
.option("--cursor <id>", "分页 cursor/query_id")
|
|
135
137
|
.option("--raw", "JSON 输出包含后端原始数据", false)
|
|
136
|
-
.action(withErrorHandler(
|
|
138
|
+
.action(withErrorHandler(async (keyword, options, command) => {
|
|
137
139
|
const opts = options;
|
|
138
140
|
const cmd = command;
|
|
139
141
|
const damClient = new DamClient();
|
|
140
142
|
const data = await damClient.searchAssets(String(keyword), buildDamSearchOptions(opts));
|
|
141
143
|
outputDamSearch(data, resolveListOutputFormat(cmd), "search");
|
|
142
|
-
}))
|
|
143
|
-
|
|
144
|
+
}));
|
|
145
|
+
setAuthRequirement(search, "current-org");
|
|
146
|
+
const get = dam
|
|
144
147
|
.command("get <id-or-url>")
|
|
145
148
|
.description("按 asset_id、CDN URL 或文件名查询素材(依赖 Hub DAM API)")
|
|
146
|
-
.action(withErrorHandler(
|
|
149
|
+
.action(withErrorHandler(async (idOrUrl, _opts, command) => {
|
|
147
150
|
const cmd = command;
|
|
148
151
|
const key = String(idOrUrl);
|
|
149
152
|
const damClient = new DamClient();
|
|
@@ -155,13 +158,14 @@ export function registerDamCommand(program) {
|
|
|
155
158
|
else {
|
|
156
159
|
formatOutput(data, format);
|
|
157
160
|
}
|
|
158
|
-
}))
|
|
159
|
-
|
|
161
|
+
}));
|
|
162
|
+
setAuthRequirement(get, "current-org");
|
|
163
|
+
const deleteCommand = dam
|
|
160
164
|
.command("delete <asset-id>")
|
|
161
165
|
.description("删除 DAM 素材")
|
|
162
166
|
.option("--repository-id <id>", "DAM 资源库 ID,默认取个人库或 GD_DAM_REPOSITORY_ID")
|
|
163
167
|
.option("--permanent", "进入回收站后继续永久删除", false)
|
|
164
|
-
.action(withErrorHandler(
|
|
168
|
+
.action(withErrorHandler(async (assetId, options, command) => {
|
|
165
169
|
const cmd = command;
|
|
166
170
|
const opts = options;
|
|
167
171
|
const id = String(assetId);
|
|
@@ -177,7 +181,8 @@ export function registerDamCommand(program) {
|
|
|
177
181
|
else {
|
|
178
182
|
formatOutput(data, format);
|
|
179
183
|
}
|
|
180
|
-
}))
|
|
184
|
+
}));
|
|
185
|
+
setAuthRequirement(deleteCommand, "current-org");
|
|
181
186
|
}
|
|
182
187
|
function buildDamSearchOptions(opts) {
|
|
183
188
|
return {
|
|
@@ -186,7 +191,7 @@ function buildDamSearchOptions(opts) {
|
|
|
186
191
|
folderId: optionalString(opts.folderId),
|
|
187
192
|
includeChildFolder: opts.includeChildFolder !== false,
|
|
188
193
|
type: optionalString(opts.type),
|
|
189
|
-
format: splitList(opts.
|
|
194
|
+
format: splitList(opts.assetFormat),
|
|
190
195
|
tagIds: splitList(opts.tagIds),
|
|
191
196
|
pageSize: numberOption(opts.pageSize),
|
|
192
197
|
page: numberOption(opts.page),
|
|
@@ -269,7 +274,7 @@ function quoteShell(value) {
|
|
|
269
274
|
const DAM_HELP = `Usage: gd-cli dam <command> [options]
|
|
270
275
|
|
|
271
276
|
用于把本地文件上传到稿定素材库,获得可复用的 asset_id 和 CDN URL。
|
|
272
|
-
适合在 Workflows
|
|
277
|
+
适合在 Creative、Workflows 和其他自动化流程中反复引用同一批商品图、Logo、参考图和交付文件。
|
|
273
278
|
|
|
274
279
|
常用命令:
|
|
275
280
|
upload <file> 上传文件并入库,返回 asset_id 与 CDN URL
|
|
@@ -282,12 +287,12 @@ const DAM_HELP = `Usage: gd-cli dam <command> [options]
|
|
|
282
287
|
--name <name> 指定素材名称
|
|
283
288
|
--folder <folder> 指定 DAM 文件夹
|
|
284
289
|
--tags <tags> 添加标签,逗号分隔
|
|
285
|
-
--format <list>
|
|
290
|
+
--asset-format <list> 在 dam search/list 中筛选素材格式,例如 png,jpg
|
|
286
291
|
--json 输出机器可读 JSON
|
|
287
292
|
|
|
288
293
|
示例:
|
|
289
294
|
gd-cli dam upload ./sku-001.png --tags product,shoe
|
|
290
295
|
gd-cli dam get ast_123
|
|
291
|
-
gd-cli dam search "white sneaker" --type image --format png,jpg
|
|
296
|
+
gd-cli dam search "white sneaker" --type image --asset-format png,jpg
|
|
292
297
|
gd-cli dam delete ast_123 --yes
|
|
293
298
|
`;
|
package/dist/src/commands/org.js
CHANGED
|
@@ -1,24 +1,25 @@
|
|
|
1
1
|
import chalk from "chalk";
|
|
2
2
|
import { withErrorHandler } from "../middleware/error-handler.js";
|
|
3
|
-
import {
|
|
3
|
+
import { setAuthRequirement } from "../middleware/auth.js";
|
|
4
4
|
import { OrgManager } from "../core/auth/org-manager.js";
|
|
5
5
|
import { formatOutput } from "../middleware/output.js";
|
|
6
6
|
import { resolveInvokeOutputFormat, resolveListOutputFormat, } from "../utils/list-output-format.js";
|
|
7
7
|
import { getIO } from "../io.js";
|
|
8
8
|
import { emitJson, wrapEnvelope } from "../core/output/envelope.js";
|
|
9
9
|
import { setStaticHelp } from "../utils/static-help.js";
|
|
10
|
+
import { registerUsageCommand } from "./usage.js";
|
|
10
11
|
export function registerOrgCommand(program) {
|
|
11
12
|
const org = program
|
|
12
13
|
.command("org")
|
|
13
14
|
.usage("<command> [options]")
|
|
14
|
-
.description("
|
|
15
|
+
.description("查看与切换当前组织")
|
|
15
16
|
.configureHelp({ showGlobalOptions: true });
|
|
16
17
|
setStaticHelp(org, ORG_HELP);
|
|
17
|
-
org
|
|
18
|
+
const list = org
|
|
18
19
|
.command("list")
|
|
19
20
|
.alias("ls")
|
|
20
|
-
.description("
|
|
21
|
-
.action(withErrorHandler(
|
|
21
|
+
.description("列出可用组织")
|
|
22
|
+
.action(withErrorHandler(async (_opts, command) => {
|
|
22
23
|
const cmd = command;
|
|
23
24
|
const manager = new OrgManager();
|
|
24
25
|
const orgs = await manager.listOrgs();
|
|
@@ -43,8 +44,9 @@ export function registerOrgCommand(program) {
|
|
|
43
44
|
else {
|
|
44
45
|
formatOutput(rows, format === "table" ? "table" : "text");
|
|
45
46
|
}
|
|
46
|
-
}))
|
|
47
|
-
|
|
47
|
+
}));
|
|
48
|
+
setAuthRequirement(list, "credential");
|
|
49
|
+
const current = org
|
|
48
50
|
.command("current")
|
|
49
51
|
.description("快速查询当前组织")
|
|
50
52
|
.action(withErrorHandler(async (_opts, command) => {
|
|
@@ -63,17 +65,18 @@ export function registerOrgCommand(program) {
|
|
|
63
65
|
return;
|
|
64
66
|
}
|
|
65
67
|
if (!current) {
|
|
66
|
-
console.log(chalk.yellow("
|
|
68
|
+
console.log(chalk.yellow("当前未选择组织"));
|
|
67
69
|
console.log(" gd-cli org list");
|
|
68
70
|
return;
|
|
69
71
|
}
|
|
70
72
|
console.log(`当前组织: ${current.name} (${current.id})`);
|
|
71
73
|
}));
|
|
72
|
-
|
|
74
|
+
setAuthRequirement(current, "none");
|
|
75
|
+
const switchCommand = org
|
|
73
76
|
.command("switch")
|
|
74
77
|
.description("切换当前 CLI 组织(TTY 下可交互选择)")
|
|
75
78
|
.option("--org <org-id>", "组织 ID")
|
|
76
|
-
.action(withErrorHandler(
|
|
79
|
+
.action(withErrorHandler(async (options, command) => {
|
|
77
80
|
const cmd = command;
|
|
78
81
|
const format = resolveListOutputFormat(cmd);
|
|
79
82
|
const manager = new OrgManager();
|
|
@@ -110,7 +113,9 @@ export function registerOrgCommand(program) {
|
|
|
110
113
|
}
|
|
111
114
|
console.log(chalk.green(`\n✓ 已切换到组织: ${result.name} (${result.id})`));
|
|
112
115
|
console.log(chalk.yellow("\n请 60s 后再调用能力,即可按新组织的权益执行~\n"));
|
|
113
|
-
}))
|
|
116
|
+
}));
|
|
117
|
+
setAuthRequirement(switchCommand, "credential");
|
|
118
|
+
registerUsageCommand(org);
|
|
114
119
|
}
|
|
115
120
|
const ORG_HELP = `
|
|
116
121
|
Usage: gd-cli org <command> [options]
|
|
@@ -118,9 +123,10 @@ Usage: gd-cli org <command> [options]
|
|
|
118
123
|
用于查看和切换当前组织
|
|
119
124
|
|
|
120
125
|
常用命令:
|
|
121
|
-
list/ls
|
|
122
|
-
current
|
|
123
|
-
switch
|
|
126
|
+
list/ls 列出可用组织
|
|
127
|
+
current 查询当前组织
|
|
128
|
+
switch 切换当前组织
|
|
129
|
+
credits 查询当前组织的稿豆余额
|
|
124
130
|
`;
|
|
125
131
|
function formatOrgChoice(org, currentOrgId) {
|
|
126
132
|
const product = org.product_name ? ` · ${org.product_name}` : "";
|
|
@@ -7,6 +7,7 @@ import { AgentSkillInstaller, AgentSkillOperationError, } from "../utils/agent-s
|
|
|
7
7
|
import { collectArg } from "../utils/input-json.js";
|
|
8
8
|
import { resolveInvokeOutputFormat } from "../utils/list-output-format.js";
|
|
9
9
|
import { setStaticHelp } from "../utils/static-help.js";
|
|
10
|
+
import { setAuthRequirement } from "../middleware/auth.js";
|
|
10
11
|
const TARGET_IDS = [
|
|
11
12
|
"universal",
|
|
12
13
|
"claude-code",
|
|
@@ -21,7 +22,7 @@ export function registerSkillsCommand(program) {
|
|
|
21
22
|
.command("skills")
|
|
22
23
|
.description("安装和管理 gd-cli Agent Skill");
|
|
23
24
|
setStaticHelp(skills, SKILLS_HELP);
|
|
24
|
-
skills
|
|
25
|
+
const install = skills
|
|
25
26
|
.command("install")
|
|
26
27
|
.description("安装 gd-cli Agent Skill")
|
|
27
28
|
.option("-a, --agent <id>", "目标 Agent,可重复", collectArg, [])
|
|
@@ -35,14 +36,16 @@ export function registerSkillsCommand(program) {
|
|
|
35
36
|
const result = runInstaller(() => installer.install(agents));
|
|
36
37
|
emitResult(result, command, "skills install");
|
|
37
38
|
}));
|
|
38
|
-
|
|
39
|
+
setAuthRequirement(install, "none");
|
|
40
|
+
const status = skills
|
|
39
41
|
.command("status")
|
|
40
42
|
.description("查看七个固定 Agent target 的安装状态")
|
|
41
43
|
.allowExcessArguments(false)
|
|
42
44
|
.action(withErrorHandler(async (_options, command) => {
|
|
43
45
|
emitResult(new AgentSkillInstaller().status(), command, "skills status");
|
|
44
46
|
}));
|
|
45
|
-
|
|
47
|
+
setAuthRequirement(status, "none");
|
|
48
|
+
const update = skills
|
|
46
49
|
.command("update")
|
|
47
50
|
.description("刷新已安装的 gd-cli Agent Skill")
|
|
48
51
|
.allowExcessArguments(false)
|
|
@@ -51,7 +54,8 @@ export function registerSkillsCommand(program) {
|
|
|
51
54
|
const result = runInstaller(() => installer.update());
|
|
52
55
|
emitResult(result, command, "skills update");
|
|
53
56
|
}));
|
|
54
|
-
|
|
57
|
+
setAuthRequirement(update, "none");
|
|
58
|
+
const uninstall = skills
|
|
55
59
|
.command("uninstall")
|
|
56
60
|
.description("卸载 gd-cli 托管的 Agent Skill")
|
|
57
61
|
.option("-a, --agent <id>", "目标 Agent,可重复", collectArg, [])
|
|
@@ -69,6 +73,7 @@ export function registerSkillsCommand(program) {
|
|
|
69
73
|
const result = runInstaller(() => installer.uninstall(agents));
|
|
70
74
|
emitResult(result, command, "skills uninstall");
|
|
71
75
|
}));
|
|
76
|
+
setAuthRequirement(uninstall, "none");
|
|
72
77
|
}
|
|
73
78
|
async function resolveMutationTargets(operation, installer, options, command) {
|
|
74
79
|
const explicit = Array.isArray(options.agent)
|
|
@@ -5,6 +5,7 @@ import { withErrorHandler } from "../middleware/error-handler.js";
|
|
|
5
5
|
import { buildUpdateCommand, detectInstallSource } from "../update/install-source.js";
|
|
6
6
|
import { checkForUpdate, clearUpdateCache } from "../update/update-checker.js";
|
|
7
7
|
import { AgentSkillInstaller } from "../utils/agent-skill-installer.js";
|
|
8
|
+
import { setAuthRequirement } from "../middleware/auth.js";
|
|
8
9
|
export function registerUpdateCommand(program) {
|
|
9
10
|
const update = program
|
|
10
11
|
.command("update")
|
|
@@ -16,7 +17,8 @@ export function registerUpdateCommand(program) {
|
|
|
16
17
|
.action(withErrorHandler(async (options, command) => {
|
|
17
18
|
await runUpdate(options, command);
|
|
18
19
|
}));
|
|
19
|
-
update
|
|
20
|
+
setAuthRequirement(update, "none");
|
|
21
|
+
const check = update
|
|
20
22
|
.command("check")
|
|
21
23
|
.description("检查是否有新版本")
|
|
22
24
|
.option("--channel <tag>", "npm dist-tag: latest / next / alpha", "latest")
|
|
@@ -28,13 +30,15 @@ export function registerUpdateCommand(program) {
|
|
|
28
30
|
});
|
|
29
31
|
printUpdateInfo(info, outputFormat(command));
|
|
30
32
|
}));
|
|
31
|
-
|
|
33
|
+
setAuthRequirement(check, "none");
|
|
34
|
+
const clearCache = update
|
|
32
35
|
.command("clear-cache")
|
|
33
36
|
.description("清除本地升级检查缓存")
|
|
34
37
|
.action(withErrorHandler(async () => {
|
|
35
38
|
clearUpdateCache();
|
|
36
39
|
console.log(chalk.green("✓ 已清除升级检查缓存"));
|
|
37
40
|
}));
|
|
41
|
+
setAuthRequirement(clearCache, "none");
|
|
38
42
|
}
|
|
39
43
|
async function runUpdate(options, command) {
|
|
40
44
|
const info = await checkForUpdate({
|
|
@@ -3,5 +3,5 @@ import { UsageClient } from "../api/usage-client.js";
|
|
|
3
3
|
interface UsageCommandDeps {
|
|
4
4
|
createClient?: () => Pick<UsageClient, "getCreditsOverview">;
|
|
5
5
|
}
|
|
6
|
-
export declare function registerUsageCommand(
|
|
6
|
+
export declare function registerUsageCommand(org: Command, deps?: UsageCommandDeps): void;
|
|
7
7
|
export {};
|
|
@@ -2,10 +2,11 @@ import chalk from "chalk";
|
|
|
2
2
|
import { UsageClient } from "../api/usage-client.js";
|
|
3
3
|
import { withErrorHandler } from "../middleware/error-handler.js";
|
|
4
4
|
import { formatOutput } from "../middleware/output.js";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
.
|
|
5
|
+
import { setAuthRequirement } from "../middleware/auth.js";
|
|
6
|
+
export function registerUsageCommand(org, deps = {}) {
|
|
7
|
+
const credits = org
|
|
8
|
+
.command("credits")
|
|
9
|
+
.description("查询当前组织的稿豆余额")
|
|
9
10
|
.action(withErrorHandler(async (_options, command) => {
|
|
10
11
|
const client = deps.createClient?.() ?? new UsageClient();
|
|
11
12
|
const payload = await client.getCreditsOverview();
|
|
@@ -16,6 +17,7 @@ export function registerUsageCommand(program, deps = {}) {
|
|
|
16
17
|
}
|
|
17
18
|
printUsageHuman(payload);
|
|
18
19
|
}));
|
|
20
|
+
setAuthRequirement(credits, "current-org");
|
|
19
21
|
}
|
|
20
22
|
function printUsageHuman(payload) {
|
|
21
23
|
const { organization, credits } = payload;
|