gaoding-cli 1.0.0-alpha.6 → 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.
Files changed (61) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/README.md +18 -14
  3. package/dist/src/api/app-runner.js +1 -2
  4. package/dist/src/api/creative-client.d.ts +34 -0
  5. package/dist/src/api/creative-client.js +184 -0
  6. package/dist/src/api/direct-client.d.ts +9 -2
  7. package/dist/src/api/direct-client.js +45 -18
  8. package/dist/src/api/hub-client.d.ts +11 -8
  9. package/dist/src/api/hub-client.js +17 -18
  10. package/dist/src/api/usage-client.d.ts +4 -4
  11. package/dist/src/api/usage-client.js +9 -49
  12. package/dist/src/auth/credential-store-v2.d.ts +0 -1
  13. package/dist/src/auth/credential-store-v2.js +0 -6
  14. package/dist/src/commands/auth.js +13 -13
  15. package/dist/src/commands/creative.d.ts +8 -0
  16. package/dist/src/commands/creative.js +186 -0
  17. package/dist/src/commands/dam.js +27 -22
  18. package/dist/src/commands/org.js +20 -14
  19. package/dist/src/commands/skills.js +9 -4
  20. package/dist/src/commands/update.js +6 -2
  21. package/dist/src/commands/usage.d.ts +1 -1
  22. package/dist/src/commands/usage.js +6 -4
  23. package/dist/src/commands/workflows.js +31 -13
  24. package/dist/src/core/auth/auth-guard.d.ts +21 -0
  25. package/dist/src/core/auth/auth-guard.js +121 -0
  26. package/dist/src/core/auth/org-manager.d.ts +2 -1
  27. package/dist/src/core/auth/org-manager.js +61 -6
  28. package/dist/src/creative/contract.d.ts +1112 -0
  29. package/dist/src/creative/contract.js +743 -0
  30. package/dist/src/creative/media.d.ts +19 -0
  31. package/dist/src/creative/media.js +83 -0
  32. package/dist/src/creative/protocol.d.ts +60 -0
  33. package/dist/src/creative/protocol.js +337 -0
  34. package/dist/src/middleware/auth.d.ts +6 -2
  35. package/dist/src/middleware/auth.js +25 -63
  36. package/dist/src/middleware/error-handler.d.ts +2 -0
  37. package/dist/src/middleware/error-handler.js +3 -4
  38. package/dist/src/program.js +7 -89
  39. package/dist/src/registry/agent-contracts.d.ts +3 -11
  40. package/dist/src/registry/agent-contracts.js +5 -243
  41. package/dist/src/registry/direct-registry.d.ts +0 -5
  42. package/dist/src/registry/direct-registry.js +0 -19
  43. package/dist/src/registry/registry-client.d.ts +0 -21
  44. package/dist/src/registry/registry-client.js +1 -40
  45. package/dist/src/utils/config.d.ts +2 -2
  46. package/dist/src/utils/config.js +1 -1
  47. package/dist/src/utils/help-verify.d.ts +1 -3
  48. package/dist/src/utils/help-verify.js +1 -25
  49. package/package.json +3 -3
  50. package/skills/gd-cli/SKILL.md +10 -9
  51. package/skills/gd-cli/references/auth.md +6 -0
  52. package/skills/gd-cli/references/creative.md +47 -0
  53. package/skills/gd-cli/references/entitlement.md +2 -2
  54. package/skills/gd-cli/references/errors.md +7 -0
  55. package/skills/gd-cli/references/sop.md +4 -4
  56. package/skills/gd-cli/references/workflows.md +1 -1
  57. package/dist/src/commands/models.d.ts +0 -2
  58. package/dist/src/commands/models.js +0 -78
  59. package/dist/src/commands/tools.d.ts +0 -4
  60. package/dist/src/commands/tools.js +0 -383
  61. 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(" 未获取到授权团队,请执行 gd-cli org switch 后再调用 Workflows / Tools / DAM。"));
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
- auth
90
+ setAuthRequirement(login, "none");
91
+ const logout = auth
90
92
  .command("logout")
91
93
  .description("取消授权")
92
94
  .action(logoutAction);
93
- auth.command("status").description("查看授权状态").action(statusAction);
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
+ `;
@@ -1,6 +1,6 @@
1
1
  import { existsSync, statSync } from "node:fs";
2
2
  import { basename, resolve } from "node:path";
3
- import { withAuth } from "../middleware/auth.js";
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(withAuth(async (file, options, command) => {
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
- dam
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(withAuth(async (options, command) => {
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
- dam
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(withAuth(async (keyword, options, command) => {
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
- dam
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(withAuth(async (idOrUrl, _opts, command) => {
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
- dam
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(withAuth(async (assetId, options, command) => {
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.format),
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 / Tools / Agent 工作流中反复引用同一批商品图、Logo、参考图和交付文件。
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> 在 dam search/list 中表示素材格式过滤,例如 png,jpg
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
  `;
@@ -1,24 +1,25 @@
1
1
  import chalk from "chalk";
2
2
  import { withErrorHandler } from "../middleware/error-handler.js";
3
- import { withAuth } from "../middleware/auth.js";
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("查看与切换当前 CLI 团队")
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(withAuth(async (_opts, command) => {
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
- org
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
- org
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(withAuth(async (options, command) => {
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
- skills
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
- skills
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
- skills
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
- update
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(program: Command, deps?: UsageCommandDeps): void;
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
- export function registerUsageCommand(program, deps = {}) {
6
- program
7
- .command("usage", { hidden: true })
8
- .description("Agent internal usage and entitlement probe")
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;