gaoding-cli 1.0.0-alpha.8 → 1.0.0-alpha.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/README.md +47 -64
  3. package/dist/bin/gd-cli.js +2 -2
  4. package/dist/src/api/app-runner.d.ts +1 -4
  5. package/dist/src/api/app-runner.js +10 -42
  6. package/dist/src/api/dam-client.d.ts +0 -7
  7. package/dist/src/api/dam-client.js +0 -17
  8. package/dist/src/commands/auth.js +5 -41
  9. package/dist/src/commands/creative.js +37 -45
  10. package/dist/src/commands/dam.js +248 -110
  11. package/dist/src/commands/org.js +17 -39
  12. package/dist/src/commands/skills.js +24 -114
  13. package/dist/src/commands/update.js +10 -85
  14. package/dist/src/commands/usage.js +4 -17
  15. package/dist/src/commands/workflows.d.ts +1 -1
  16. package/dist/src/commands/workflows.js +283 -199
  17. package/dist/src/core/output/envelope.d.ts +1 -0
  18. package/dist/src/core/output/envelope.js +76 -6
  19. package/dist/src/creative/contract.d.ts +28 -80
  20. package/dist/src/creative/contract.js +23 -44
  21. package/dist/src/creative/protocol.js +6 -6
  22. package/dist/src/io.d.ts +0 -2
  23. package/dist/src/io.js +0 -8
  24. package/dist/src/middleware/error-handler.d.ts +7 -1
  25. package/dist/src/middleware/error-handler.js +59 -54
  26. package/dist/src/program.d.ts +1 -0
  27. package/dist/src/program.js +138 -41
  28. package/dist/src/registry/agent-contracts.d.ts +14 -26
  29. package/dist/src/registry/agent-contracts.js +214 -64
  30. package/dist/src/utils/capability-presenter.js +6 -29
  31. package/dist/src/utils/config.d.ts +2 -2
  32. package/dist/src/utils/config.js +1 -1
  33. package/dist/src/utils/sensitive-path.js +1 -4
  34. package/package.json +2 -1
  35. package/skills/gd-cli/SKILL.md +6 -6
  36. package/skills/gd-cli/references/auth.md +3 -10
  37. package/skills/gd-cli/references/creative.md +11 -11
  38. package/skills/gd-cli/references/entitlement.md +2 -2
  39. package/skills/gd-cli/references/errors.md +4 -4
  40. package/skills/gd-cli/references/org.md +3 -3
  41. package/skills/gd-cli/references/sop.md +5 -5
  42. package/skills/gd-cli/references/update.md +4 -3
  43. package/skills/gd-cli/references/workflows.md +6 -5
  44. package/dist/src/utils/list-output-format.d.ts +0 -10
  45. package/dist/src/utils/list-output-format.js +0 -34
@@ -1,4 +1,4 @@
1
- import { Command, Option } from "commander";
1
+ import { Command, CommanderError } from "commander";
2
2
  import { CLI_VERSION } from "./utils/config.js";
3
3
  import { registerAuthCommand } from "./commands/auth.js";
4
4
  import { registerOrgCommand } from "./commands/org.js";
@@ -8,21 +8,16 @@ import { registerDamCommand } from "./commands/dam.js";
8
8
  import { registerUpdateCommand } from "./commands/update.js";
9
9
  import { registerSkillsCommand } from "./commands/skills.js";
10
10
  import { maybeNotifyUpdate } from "./update/notifier.js";
11
- import { setStaticHelp } from "./utils/static-help.js";
12
11
  import { installAuthPreflight } from "./middleware/auth.js";
12
+ import { CliUsageError } from "./core/output/cli-error.js";
13
+ import { emitJsonFailure } from "./middleware/error-handler.js";
13
14
  export async function createProgram() {
14
15
  const program = new Command();
15
16
  program
16
17
  .name("gd-cli")
17
18
  .usage("<command> [options]")
18
19
  .description("GD CLI — 让稿定成为 Agent 的创意生产引擎")
19
- .version(CLI_VERSION)
20
- .addOption(new Option("-f, --format <format>", "输出格式: human / table / json / text").choices(["json", "human", "table", "text"]))
21
- .addOption(new Option("--json", "等同于 --format json,推荐 Agent 和脚本使用"))
22
- .addOption(new Option("--no-input", "禁止交互,适合 CI / Agent"))
23
- .addOption(new Option("--yes", "跳过确认"))
24
- .addOption(new Option("--verbose", "输出详细日志").hideHelp().default(false));
25
- setStaticHelp(program, TOP_LEVEL_HELP);
20
+ .version(CLI_VERSION);
26
21
  registerAuthCommand(program);
27
22
  registerOrgCommand(program);
28
23
  registerCreativeCommand(program);
@@ -36,35 +31,137 @@ export async function createProgram() {
36
31
  });
37
32
  return program;
38
33
  }
39
- const TOP_LEVEL_HELP = `
40
- Usage: gd-cli <command> [options]
41
-
42
- GD CLI 让稿定成为 Agent 的创意生产引擎
43
-
44
- 核心命令:
45
- auth 登录、退出、查看登录状态
46
- org 查看和切换当前组织
47
- creative 通过统一创作入口生成图片、视频和文本
48
- workflows 运行完整创意场景任务,例如商品上新、批量海报、内容矩阵
49
- skills 安装和管理 gd-cli Agent Skill
50
- dam 素材管理,上传、查询、删除素材
51
- update 检查并升级 gd-cli
52
-
53
- 常用流程:
54
- gd-cli auth login 登录稿定账号
55
- gd-cli org list 查看可用组织
56
- gd-cli org switch 切换当前组织
57
- gd-cli creative schema --format json 查看 Creative 输入输出结构
58
- gd-cli creative examples --format json 查看 Creative 调用示例
59
- gd-cli workflows list 查看完整创意场景
60
- gd-cli dam upload ./image.png 上传素材到 DAM
61
-
62
- 常用选项:
63
- -V, --version output the version number
64
- -f, --format <format> 输出格式: human / table / json / text
65
- --json 等同于 --format json,推荐 Agent 和脚本使用
66
- --no-input 禁止交互,适合 CI / Agent
67
- --yes 跳过确认
68
- -h, --help display help for command
69
-
70
- `;
34
+ export async function parseProgram(program, argv = process.argv) {
35
+ const userArgs = argv.slice(2);
36
+ const jsonLeaf = resolveExplicitJsonLeaf(program, userArgs);
37
+ const capturedErrors = [];
38
+ const configuredCommands = allCommands(program).map((command) => {
39
+ const output = command.configureOutput();
40
+ const writeErr = output.writeErr ?? ((text) => process.stderr.write(text));
41
+ command.configureOutput({
42
+ writeErr: (text) => capturedErrors.push({ text, write: writeErr }),
43
+ });
44
+ command.exitOverride();
45
+ return { command, writeErr };
46
+ });
47
+ let actionStarted = false;
48
+ program.hook("preAction", () => {
49
+ actionStarted = true;
50
+ });
51
+ try {
52
+ await program.parseAsync([...argv]);
53
+ }
54
+ catch (error) {
55
+ if (error instanceof CommanderError && error.exitCode === 0)
56
+ return;
57
+ if (!actionStarted && jsonLeaf) {
58
+ emitJsonFailure(jsonLeaf, parseFailure(error, jsonLeaf));
59
+ process.exitCode = error instanceof CommanderError
60
+ ? Math.max(1, error.exitCode)
61
+ : 1;
62
+ return;
63
+ }
64
+ for (const captured of capturedErrors)
65
+ captured.write(captured.text);
66
+ if (error instanceof CommanderError) {
67
+ process.exitCode = error.exitCode;
68
+ return;
69
+ }
70
+ throw error;
71
+ }
72
+ finally {
73
+ for (const { command, writeErr } of configuredCommands) {
74
+ command.configureOutput({ writeErr });
75
+ }
76
+ }
77
+ }
78
+ function resolveExplicitJsonLeaf(program, args) {
79
+ let current = program;
80
+ let index = 0;
81
+ let commandIndex = -1;
82
+ while (current.commands.length > 0) {
83
+ let nextCommand;
84
+ while (index < args.length) {
85
+ const token = args[index];
86
+ if (token === "--")
87
+ return undefined;
88
+ if (token.startsWith("-")) {
89
+ index += optionWidth(current, args, index);
90
+ continue;
91
+ }
92
+ nextCommand = current.commands.find((candidate) => candidate.name() === token || candidate.aliases().includes(token));
93
+ if (!nextCommand)
94
+ return undefined;
95
+ commandIndex = index;
96
+ index += 1;
97
+ break;
98
+ }
99
+ if (!nextCommand)
100
+ return undefined;
101
+ current = nextCommand;
102
+ }
103
+ if (commandIndex < 0 ||
104
+ !current.options.some((option) => option.long === "--json")) {
105
+ return undefined;
106
+ }
107
+ return hasExplicitJsonOption(current, args.slice(commandIndex + 1))
108
+ ? current
109
+ : undefined;
110
+ }
111
+ function hasExplicitJsonOption(command, args) {
112
+ for (let index = 0; index < args.length;) {
113
+ const token = args[index];
114
+ if (token === "--")
115
+ return false;
116
+ if (token === "--json")
117
+ return true;
118
+ index += optionWidth(command, args, index);
119
+ }
120
+ return false;
121
+ }
122
+ function optionWidth(command, args, index) {
123
+ const token = args[index];
124
+ const flag = token.includes("=") ? token.slice(0, token.indexOf("=")) : token;
125
+ const option = command.options.find((candidate) => candidate.long === flag || candidate.short === flag);
126
+ if (!option || token.includes("="))
127
+ return 1;
128
+ if (option.required)
129
+ return index + 1 < args.length ? 2 : 1;
130
+ if (option.optional &&
131
+ index + 1 < args.length &&
132
+ !args[index + 1].startsWith("-")) {
133
+ return 2;
134
+ }
135
+ return 1;
136
+ }
137
+ function parseFailure(error, command) {
138
+ const missingCodes = new Set([
139
+ "commander.missingArgument",
140
+ "commander.optionMissingArgument",
141
+ "commander.missingMandatoryOptionValue",
142
+ ]);
143
+ const code = error instanceof CommanderError && missingCodes.has(error.code)
144
+ ? "PARAM_MISSING"
145
+ : "PARAM_INVALID";
146
+ const rawMessage = error instanceof Error ? error.message : String(error);
147
+ const message = rawMessage.replace(/^error:\s*/i, "").trim() || "参数不合法";
148
+ return new CliUsageError({
149
+ code,
150
+ type: "validation",
151
+ message,
152
+ hint: `运行 gd-cli ${publicCommandName(command)} --help 查看参数说明。`,
153
+ retryable: false,
154
+ });
155
+ }
156
+ function publicCommandName(command) {
157
+ const names = [];
158
+ let current = command;
159
+ while (current.parent) {
160
+ names.unshift(current.name());
161
+ current = current.parent;
162
+ }
163
+ return names.join(" ");
164
+ }
165
+ function allCommands(root) {
166
+ return [root, ...root.commands.flatMap(allCommands)];
167
+ }
@@ -1,35 +1,23 @@
1
- import type { OutputSpec, ParamSpec } from "./types.js";
2
- import { type CapabilityPolicy, type CapabilitySource, type CapabilityStatus } from "../utils/capability-metadata.js";
1
+ import type { ParamSpec } from "./types.js";
2
+ export declare const PUBLIC_WORKFLOW_MEDIA_PATTERN = "^kv_\\d+_\\d+$";
3
+ export interface PublicWorkflowOutputDefinition {
4
+ textFields: readonly string[];
5
+ mediaFields: readonly string[];
6
+ overlayFields: readonly string[];
7
+ ratioFields: readonly string[];
8
+ ratios: "record" | "array";
9
+ sellingPoints?: boolean;
10
+ mediaPattern?: string;
11
+ }
3
12
  export interface JsonSchemaObject {
4
13
  type: "object";
5
14
  properties: Record<string, Record<string, unknown>>;
6
15
  required: string[];
7
16
  additionalProperties?: boolean;
8
- }
9
- export interface CapabilityManifestCommand {
10
- id: string;
11
- type: "workflow";
12
- category: string;
13
- title: string;
14
- description: string;
15
- canonical_command: string;
16
- input_schema_command?: string;
17
- examples_command?: string;
18
- output: "json";
19
- safe_for_agent: boolean;
20
- source: CapabilitySource;
21
- status: CapabilityStatus;
22
- policy: CapabilityPolicy;
23
- }
24
- export interface CapabilityManifest {
25
- name: "gd-cli";
26
- version: string;
27
- description: string;
28
- commands: CapabilityManifestCommand[];
17
+ patternProperties?: Record<string, Record<string, unknown>>;
29
18
  }
30
19
  export declare function buildInputJsonSchema(params: ParamSpec[], extraProperties?: Record<string, Record<string, unknown>>): JsonSchemaObject;
31
- export declare function buildOutputJsonSchema(output: OutputSpec): JsonSchemaObject;
20
+ export declare function resolvePublicWorkflowOutputDefinition(appId: string): PublicWorkflowOutputDefinition;
21
+ export declare function buildOutputJsonSchema(appId: string): JsonSchemaObject;
32
22
  export declare function buildWorkflowSchema(appId: string): Record<string, unknown>;
33
23
  export declare function buildWorkflowExamples(appId: string): Record<string, unknown>;
34
- export declare function buildWorkflowManifest(): CapabilityManifest;
35
- export declare function rowsForWorkflowManifest(manifest: CapabilityManifest): Record<string, string>[];
@@ -1,6 +1,75 @@
1
- import { CLI_VERSION } from "../utils/config.js";
2
- import { DIRECT_APPS, resolveAppSpec, } from "./direct-registry.js";
3
- import { capabilityMetadata, } from "../utils/capability-metadata.js";
1
+ import { resolveAppSpec } from "./direct-registry.js";
2
+ export const PUBLIC_WORKFLOW_MEDIA_PATTERN = "^kv_\\d+_\\d+$";
3
+ const PUBLIC_WORKFLOW_OUTPUT_DEFINITIONS = {
4
+ "listing-gallery": {
5
+ textFields: ["text", "title_text", "delivery_copy", "prompt_plan"],
6
+ mediaFields: [
7
+ "main_image",
8
+ "selling_point_image",
9
+ "detail_image",
10
+ "lifestyle_image",
11
+ ],
12
+ overlayFields: [
13
+ "selling_point_image",
14
+ "detail_image",
15
+ "lifestyle_image",
16
+ ],
17
+ ratioFields: [
18
+ "main_image",
19
+ "selling_point_image",
20
+ "detail_image",
21
+ "lifestyle_image",
22
+ ],
23
+ ratios: "record",
24
+ },
25
+ "pdp-a-plus": {
26
+ textFields: ["text", "title_text", "delivery_copy", "prompt_plan"],
27
+ mediaFields: [
28
+ "hero_module",
29
+ "pain_point_module",
30
+ "structure_module",
31
+ "usage_module",
32
+ "comparison_module",
33
+ ],
34
+ overlayFields: [
35
+ "hero_module",
36
+ "pain_point_module",
37
+ "structure_module",
38
+ "usage_module",
39
+ "comparison_module",
40
+ ],
41
+ ratioFields: [
42
+ "hero_module",
43
+ "pain_point_module",
44
+ "structure_module",
45
+ "usage_module",
46
+ "comparison_module",
47
+ ],
48
+ ratios: "record",
49
+ sellingPoints: true,
50
+ },
51
+ "social-seeding-pack": {
52
+ textFields: [
53
+ "text",
54
+ "title_text",
55
+ "xhs_caption",
56
+ "cover_prompt",
57
+ "scene_prompt",
58
+ ],
59
+ mediaFields: ["cover_image", "scene_image"],
60
+ overlayFields: ["cover_image", "scene_image"],
61
+ ratioFields: ["cover_image", "scene_image"],
62
+ ratios: "record",
63
+ },
64
+ "campaign-kv-pack": {
65
+ textFields: ["text", "title_text", "delivery_copy", "prompt_plan"],
66
+ mediaFields: [],
67
+ overlayFields: [],
68
+ ratioFields: [],
69
+ ratios: "array",
70
+ mediaPattern: PUBLIC_WORKFLOW_MEDIA_PATTERN,
71
+ },
72
+ };
4
73
  export function buildInputJsonSchema(params, extraProperties = {}) {
5
74
  const properties = { ...extraProperties };
6
75
  const required = [];
@@ -24,28 +93,52 @@ export function buildInputJsonSchema(params, extraProperties = {}) {
24
93
  type: "object",
25
94
  properties,
26
95
  required,
27
- additionalProperties: true,
96
+ additionalProperties: false,
28
97
  };
29
98
  }
30
- export function buildOutputJsonSchema(output) {
31
- const properties = {};
32
- for (const [key, prop] of Object.entries(output.properties ?? {})) {
33
- properties[key] = {
34
- type: prop.type,
35
- description: prop.description,
36
- };
99
+ export function resolvePublicWorkflowOutputDefinition(appId) {
100
+ const definition = PUBLIC_WORKFLOW_OUTPUT_DEFINITIONS[appId];
101
+ if (!definition)
102
+ throw new Error(`未找到 Workflow 输出契约: ${appId}`);
103
+ return definition;
104
+ }
105
+ export function buildOutputJsonSchema(appId) {
106
+ const definition = resolvePublicWorkflowOutputDefinition(appId);
107
+ const properties = Object.fromEntries(definition.textFields.map((field) => [
108
+ field,
109
+ stringSchema(workflowTextDescription(field)),
110
+ ]));
111
+ properties.copy_plan = copyPlanSchema();
112
+ properties.overlay_copy = namedStringRecordSchema(definition.overlayFields, definition.mediaPattern);
113
+ properties.category_profile = categoryProfileSchema();
114
+ properties.ratios = definition.ratios === "array"
115
+ ? stringArraySchema("本次生成的画面比例列表", "^\\d+:\\d+$")
116
+ : namedStringRecordSchema(definition.ratioFields);
117
+ properties.assets = workflowAssetsSchema();
118
+ if (definition.sellingPoints) {
119
+ properties.selling_points = stringArraySchema("从 brief 提取的公开卖点列表");
120
+ }
121
+ for (const field of definition.mediaFields) {
122
+ properties[field] = workflowMediaSchema(`${field} 生成结果`);
37
123
  }
38
124
  return {
39
125
  type: "object",
40
126
  properties,
41
127
  required: [],
42
- additionalProperties: true,
128
+ additionalProperties: false,
129
+ ...(definition.mediaPattern
130
+ ? {
131
+ patternProperties: {
132
+ [definition.mediaPattern]: workflowMediaSchema("Campaign KV 生成结果"),
133
+ },
134
+ }
135
+ : {}),
43
136
  };
44
137
  }
45
138
  export function buildWorkflowSchema(appId) {
46
139
  const spec = resolveAppSpec(appId);
47
140
  if (!spec)
48
- throw new Error(`未找到应用: ${appId}`);
141
+ throw new Error(`未找到 Workflow: ${appId}`);
49
142
  const input = sampleInput(spec.input ?? []);
50
143
  return {
51
144
  id: spec.id,
@@ -54,23 +147,119 @@ export function buildWorkflowSchema(appId) {
54
147
  title: spec.name,
55
148
  description: spec.description,
56
149
  canonical_command: `gd-cli workflows run ${spec.id}`,
57
- schema_command: `gd-cli workflows schema ${spec.id} --format json`,
58
- examples_command: `gd-cli workflows examples ${spec.id} --format json`,
150
+ schema_command: `gd-cli workflows schema ${spec.id} --json`,
151
+ examples_command: `gd-cli workflows examples ${spec.id}`,
59
152
  input_schema: buildInputJsonSchema(spec.input ?? []),
60
- output_schema: buildOutputJsonSchema(spec.output),
153
+ output_schema: buildOutputJsonSchema(spec.id),
61
154
  sample_input: input,
62
155
  deliverables: spec.outputs ?? ["manifest.json", "README.md", "assets/"],
63
156
  stdin: {
64
157
  supported: true,
65
- command: `cat brief.json | gd-cli workflows run ${spec.id} - --format json`,
158
+ command: `cat brief.json | gd-cli workflows run ${spec.id} --input - --json`,
66
159
  content_type: "application/json",
67
160
  },
68
161
  };
69
162
  }
163
+ function workflowMediaSchema(description) {
164
+ return {
165
+ type: "object",
166
+ description,
167
+ properties: {
168
+ url: stringSchema("主结果 URL"),
169
+ mime_type: stringSchema("主结果 MIME 类型"),
170
+ urls: stringArraySchema("全部结果 URL"),
171
+ },
172
+ required: [],
173
+ additionalProperties: false,
174
+ };
175
+ }
176
+ function workflowAssetsSchema() {
177
+ return {
178
+ type: "array",
179
+ description: "按语义角色汇总的公开图片清单",
180
+ items: {
181
+ type: "object",
182
+ properties: {
183
+ label: stringSchema("交付物显示名称"),
184
+ role: stringSchema("交付物语义角色"),
185
+ type: { type: "string", enum: ["image"], description: "媒体类型" },
186
+ url: stringSchema("交付物 URL"),
187
+ },
188
+ required: ["label", "role", "type", "url"],
189
+ additionalProperties: false,
190
+ },
191
+ };
192
+ }
193
+ function copyPlanSchema() {
194
+ return {
195
+ type: "object",
196
+ description: "本次 Workflow 使用的画内文案策略",
197
+ properties: {
198
+ mode: {
199
+ type: "string",
200
+ enum: ["layout-copy", "render-text", "no-text"],
201
+ description: "最终文案模式",
202
+ },
203
+ render_text: { type: "boolean", description: "是否生成画内文字" },
204
+ image_model: stringSchema("显式选择的生图模型"),
205
+ },
206
+ required: ["mode", "render_text"],
207
+ additionalProperties: false,
208
+ };
209
+ }
210
+ function categoryProfileSchema() {
211
+ return {
212
+ type: "object",
213
+ description: "根据 brief 推断的公开品类策略",
214
+ properties: {
215
+ id: stringSchema("品类策略 ID"),
216
+ label: stringSchema("品类显示名称"),
217
+ guidance: stringSchema("品类创作指导"),
218
+ },
219
+ required: ["id", "label", "guidance"],
220
+ additionalProperties: false,
221
+ };
222
+ }
223
+ function namedStringRecordSchema(fields, pattern) {
224
+ return {
225
+ type: "object",
226
+ properties: Object.fromEntries(fields.map((field) => [field, stringSchema(`${field} 对应值`)])),
227
+ required: [],
228
+ additionalProperties: false,
229
+ ...(pattern
230
+ ? { patternProperties: { [pattern]: stringSchema("比例对应值") } }
231
+ : {}),
232
+ };
233
+ }
234
+ function stringArraySchema(description, pattern) {
235
+ return {
236
+ type: "array",
237
+ description,
238
+ items: {
239
+ type: "string",
240
+ ...(pattern ? { pattern } : {}),
241
+ },
242
+ };
243
+ }
244
+ function stringSchema(description) {
245
+ return { type: "string", description };
246
+ }
247
+ function workflowTextDescription(field) {
248
+ const descriptions = {
249
+ text: "面向用户的 Workflow 总说明",
250
+ title_text: "生成标题",
251
+ delivery_copy: "交付说明或渠道文案",
252
+ prompt_plan: "公开素材或主视觉规划",
253
+ xhs_caption: "小红书正文与标签",
254
+ cover_prompt: "封面图提示词",
255
+ scene_prompt: "场景图提示词",
256
+ };
257
+ return descriptions[field] ?? field;
258
+ }
70
259
  export function buildWorkflowExamples(appId) {
71
260
  const spec = resolveAppSpec(appId);
72
261
  if (!spec)
73
- throw new Error(`未找到应用: ${appId}`);
262
+ throw new Error(`未找到 Workflow: ${appId}`);
74
263
  const input = sampleInput(spec.input ?? []);
75
264
  const curatedExamples = curatedAppExamples(spec.id);
76
265
  const agentInput = firstExampleInput(curatedExamples) ?? input;
@@ -82,21 +271,15 @@ export function buildWorkflowExamples(appId) {
82
271
  ]),
83
272
  {
84
273
  description: "Agent / 脚本推荐:stdin JSON",
85
- command: `cat brief.json | gd-cli workflows run ${spec.id} - --format json`,
274
+ command: `cat brief.json | gd-cli workflows run ${spec.id} --input - --json`,
86
275
  input_json: agentInput,
87
276
  },
88
277
  {
89
278
  description: "Agent / 脚本推荐:JSON 文件",
90
- command: `gd-cli workflows run ${spec.id} --input brief.json --format json`,
279
+ command: `gd-cli workflows run ${spec.id} --input brief.json --json`,
91
280
  input_json: agentInput,
92
281
  },
93
282
  ];
94
- if (spec.supports_batch) {
95
- examples.push({
96
- description: "批量任务 dry-run 预检",
97
- command: `gd-cli workflows run ${spec.id} --input ./products.csv --assets-dir ./images --dry-run --format json`,
98
- });
99
- }
100
283
  return {
101
284
  id: spec.id,
102
285
  type: "workflow",
@@ -106,39 +289,6 @@ export function buildWorkflowExamples(appId) {
106
289
  examples,
107
290
  };
108
291
  }
109
- export function buildWorkflowManifest() {
110
- const commands = DIRECT_APPS.map(workflowManifestCommand);
111
- return {
112
- name: "gd-cli",
113
- version: CLI_VERSION,
114
- description: "Gaoding Workflow capabilities for agents",
115
- commands,
116
- };
117
- }
118
- export function rowsForWorkflowManifest(manifest) {
119
- return manifest.commands.map((command) => ({
120
- id: command.id,
121
- type: command.type,
122
- 分类: command.category,
123
- 名称: command.title,
124
- command: command.canonical_command,
125
- }));
126
- }
127
- function workflowManifestCommand(spec) {
128
- return {
129
- id: spec.id,
130
- type: "workflow",
131
- category: spec.category,
132
- title: spec.name,
133
- description: spec.description,
134
- canonical_command: `gd-cli workflows run ${spec.id}`,
135
- input_schema_command: `gd-cli workflows schema ${spec.id}`,
136
- examples_command: `gd-cli workflows examples ${spec.id}`,
137
- output: "json",
138
- safe_for_agent: true,
139
- ...capabilityMetadata("app", spec.id),
140
- };
141
- }
142
292
  function buildFlagCommand(prefix, id, params) {
143
293
  const pieces = [prefix, id];
144
294
  for (const param of params) {
@@ -146,7 +296,7 @@ function buildFlagCommand(prefix, id, params) {
146
296
  continue;
147
297
  pieces.push(param.cli_flag, quoteShell(String(sampleValue(param))));
148
298
  }
149
- pieces.push("--format", "json");
299
+ pieces.push("--json");
150
300
  return pieces.join(" ");
151
301
  }
152
302
  function sampleInput(params) {
@@ -187,7 +337,7 @@ function sampleValue(param) {
187
337
  function curatedAppExamples(appId) {
188
338
  if (appId === "listing-gallery") {
189
339
  return [
190
- scenarioExample("生成一套可上架的商品图库素材,包含白底主图、卖点图、细节图和生活方式图。", "gd-cli workflows run listing-gallery --image ./sku_001.jpg --brief \"夏季轻薄防晒衣,透气面料,适合户外通勤;卖点图短文案:轻薄防晒 通勤无负担\" --copy-mode render-text --ratio 1:1 -f json", {
340
+ scenarioExample("生成一套可上架的商品图库素材,包含白底主图、卖点图、细节图和生活方式图。", "gd-cli workflows run listing-gallery --image ./sku_001.jpg --brief \"夏季轻薄防晒衣,透气面料,适合户外通勤;卖点图短文案:轻薄防晒 通勤无负担\" --copy-mode render-text --ratio 1:1 --json", {
191
341
  image: "./sku_001.jpg",
192
342
  brief: "夏季轻薄防晒衣,透气面料,适合户外通勤;卖点图短文案:轻薄防晒 通勤无负担",
193
343
  copy_mode: "render-text",
@@ -197,7 +347,7 @@ function curatedAppExamples(appId) {
197
347
  }
198
348
  if (appId === "pdp-a-plus") {
199
349
  return [
200
- scenarioExample("生成详情页/A+模块素材,按购买疑虑组织首屏、痛点、结构、使用和规格模块。", "gd-cli workflows run pdp-a-plus --image ./air-purifier.jpg --brief \"桌面空气净化器,静音,滤芯可更换,适合卧室;首屏短文案:静音净化 安心入睡\" --copy-mode render-text --ratio 4:5 -f json", {
350
+ scenarioExample("生成详情页/A+模块素材,按购买疑虑组织首屏、痛点、结构、使用和规格模块。", "gd-cli workflows run pdp-a-plus --image ./air-purifier.jpg --brief \"桌面空气净化器,静音,滤芯可更换,适合卧室;首屏短文案:静音净化 安心入睡\" --copy-mode render-text --ratio 4:5 --json", {
201
351
  image: "./air-purifier.jpg",
202
352
  brief: "桌面空气净化器,静音,滤芯可更换,适合卧室;首屏短文案:静音净化 安心入睡",
203
353
  copy_mode: "render-text",
@@ -207,7 +357,7 @@ function curatedAppExamples(appId) {
207
357
  }
208
358
  if (appId === "social-seeding-pack") {
209
359
  return [
210
- scenarioExample("生成小红书种草图文素材,包含封面图、场景图、标题、正文和标签。", "gd-cli workflows run social-seeding-pack --image ./serum.jpg --brief \"屏障修护精华,清爽不黏,适合通勤包分享;封面短文案:通勤包里的清爽修护\" --copy-mode render-text --ratio 3:4 -f json", {
360
+ scenarioExample("生成小红书种草图文素材,包含封面图、场景图、标题、正文和标签。", "gd-cli workflows run social-seeding-pack --image ./serum.jpg --brief \"屏障修护精华,清爽不黏,适合通勤包分享;封面短文案:通勤包里的清爽修护\" --copy-mode render-text --ratio 3:4 --json", {
211
361
  image: "./serum.jpg",
212
362
  brief: "屏障修护精华,清爽不黏,适合通勤包分享;封面短文案:通勤包里的清爽修护",
213
363
  copy_mode: "render-text",
@@ -217,7 +367,7 @@ function curatedAppExamples(appId) {
217
367
  }
218
368
  if (appId === "campaign-kv-pack") {
219
369
  return [
220
- scenarioExample("生成 Campaign KV 多渠道素材,包含横版、方图、竖图和渠道裁切建议。", "gd-cli workflows run campaign-kv-pack --image ./running-shoes.jpg --brief \"城市跑鞋新品 Campaign,轻量缓震,面向通勤跑者;主标题:轻跑进城\" --copy-mode render-text --ratios 16:9,1:1,4:5 -f json", {
370
+ scenarioExample("生成 Campaign KV 多渠道素材,包含横版、方图、竖图和渠道裁切建议。", "gd-cli workflows run campaign-kv-pack --image ./running-shoes.jpg --brief \"城市跑鞋新品 Campaign,轻量缓震,面向通勤跑者;主标题:轻跑进城\" --copy-mode render-text --ratios 16:9,1:1,4:5 --json", {
221
371
  image: "./running-shoes.jpg",
222
372
  brief: "城市跑鞋新品 Campaign,轻量缓震,面向通勤跑者;主标题:轻跑进城",
223
373
  copy_mode: "render-text",