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.
Files changed (177) hide show
  1. package/CHANGELOG.md +88 -0
  2. package/LICENSE +21 -0
  3. package/README.md +136 -0
  4. package/SECURITY.md +34 -0
  5. package/dist/bin/gd-cli.d.ts +2 -0
  6. package/dist/bin/gd-cli.js +10 -0
  7. package/dist/src/api/app-runner.d.ts +33 -0
  8. package/dist/src/api/app-runner.js +1177 -0
  9. package/dist/src/api/dam-client.d.ts +111 -0
  10. package/dist/src/api/dam-client.js +897 -0
  11. package/dist/src/api/direct-auth.d.ts +3 -0
  12. package/dist/src/api/direct-auth.js +11 -0
  13. package/dist/src/api/direct-client.d.ts +27 -0
  14. package/dist/src/api/direct-client.js +151 -0
  15. package/dist/src/api/direct-tools.d.ts +43 -0
  16. package/dist/src/api/direct-tools.js +1155 -0
  17. package/dist/src/api/hub-client.d.ts +20 -0
  18. package/dist/src/api/hub-client.js +99 -0
  19. package/dist/src/api/sso-client.d.ts +60 -0
  20. package/dist/src/api/sso-client.js +140 -0
  21. package/dist/src/api/task-poller.d.ts +38 -0
  22. package/dist/src/api/task-poller.js +72 -0
  23. package/dist/src/api/tool-invoker.d.ts +12 -0
  24. package/dist/src/api/tool-invoker.js +11 -0
  25. package/dist/src/api/usage-client.d.ts +39 -0
  26. package/dist/src/api/usage-client.js +179 -0
  27. package/dist/src/auth/credential-store-v2.d.ts +12 -0
  28. package/dist/src/auth/credential-store-v2.js +59 -0
  29. package/dist/src/commands/auth.d.ts +2 -0
  30. package/dist/src/commands/auth.js +191 -0
  31. package/dist/src/commands/dam.d.ts +2 -0
  32. package/dist/src/commands/dam.js +293 -0
  33. package/dist/src/commands/models.d.ts +2 -0
  34. package/dist/src/commands/models.js +78 -0
  35. package/dist/src/commands/org.d.ts +2 -0
  36. package/dist/src/commands/org.js +137 -0
  37. package/dist/src/commands/skills.d.ts +2 -0
  38. package/dist/src/commands/skills.js +213 -0
  39. package/dist/src/commands/tools.d.ts +4 -0
  40. package/dist/src/commands/tools.js +383 -0
  41. package/dist/src/commands/update.d.ts +2 -0
  42. package/dist/src/commands/update.js +167 -0
  43. package/dist/src/commands/usage.d.ts +7 -0
  44. package/dist/src/commands/usage.js +43 -0
  45. package/dist/src/commands/workflows.d.ts +3 -0
  46. package/dist/src/commands/workflows.js +398 -0
  47. package/dist/src/core/auth/auth-provider.d.ts +8 -0
  48. package/dist/src/core/auth/auth-provider.js +12 -0
  49. package/dist/src/core/auth/device-oauth-provider.d.ts +12 -0
  50. package/dist/src/core/auth/device-oauth-provider.js +124 -0
  51. package/dist/src/core/auth/org-manager.d.ts +26 -0
  52. package/dist/src/core/auth/org-manager.js +224 -0
  53. package/dist/src/core/auth/signature.d.ts +19 -0
  54. package/dist/src/core/auth/signature.js +33 -0
  55. package/dist/src/core/auth/types.d.ts +52 -0
  56. package/dist/src/core/auth/types.js +3 -0
  57. package/dist/src/core/output/cli-error.d.ts +5 -0
  58. package/dist/src/core/output/cli-error.js +8 -0
  59. package/dist/src/core/output/detector.d.ts +5 -0
  60. package/dist/src/core/output/detector.js +14 -0
  61. package/dist/src/core/output/engine.d.ts +32 -0
  62. package/dist/src/core/output/engine.js +77 -0
  63. package/dist/src/core/output/envelope.d.ts +40 -0
  64. package/dist/src/core/output/envelope.js +119 -0
  65. package/dist/src/core/output/index.d.ts +4 -0
  66. package/dist/src/core/output/index.js +4 -0
  67. package/dist/src/core/output/live-display.d.ts +15 -0
  68. package/dist/src/core/output/live-display.js +111 -0
  69. package/dist/src/core/output/result-card.d.ts +18 -0
  70. package/dist/src/core/output/result-card.js +39 -0
  71. package/dist/src/core/prompt/index.d.ts +31 -0
  72. package/dist/src/core/prompt/index.js +36 -0
  73. package/dist/src/io.d.ts +14 -0
  74. package/dist/src/io.js +31 -0
  75. package/dist/src/middleware/auth.d.ts +3 -0
  76. package/dist/src/middleware/auth.js +74 -0
  77. package/dist/src/middleware/error-handler.d.ts +3 -0
  78. package/dist/src/middleware/error-handler.js +431 -0
  79. package/dist/src/middleware/interactive-params.d.ts +14 -0
  80. package/dist/src/middleware/interactive-params.js +53 -0
  81. package/dist/src/middleware/output.d.ts +14 -0
  82. package/dist/src/middleware/output.js +546 -0
  83. package/dist/src/models/model-catalog.d.ts +26 -0
  84. package/dist/src/models/model-catalog.js +216 -0
  85. package/dist/src/program.d.ts +2 -0
  86. package/dist/src/program.js +152 -0
  87. package/dist/src/registry/agent-contracts.d.ts +43 -0
  88. package/dist/src/registry/agent-contracts.js +483 -0
  89. package/dist/src/registry/app-loader.d.ts +2 -0
  90. package/dist/src/registry/app-loader.js +70 -0
  91. package/dist/src/registry/direct-registry.d.ts +11 -0
  92. package/dist/src/registry/direct-registry.js +234 -0
  93. package/dist/src/registry/registry-cache.d.ts +10 -0
  94. package/dist/src/registry/registry-cache.js +52 -0
  95. package/dist/src/registry/registry-client.d.ts +28 -0
  96. package/dist/src/registry/registry-client.js +50 -0
  97. package/dist/src/registry/types.d.ts +69 -0
  98. package/dist/src/registry/types.js +1 -0
  99. package/dist/src/tty/auth-presenter.d.ts +3 -0
  100. package/dist/src/tty/auth-presenter.js +21 -0
  101. package/dist/src/update/install-source.d.ts +19 -0
  102. package/dist/src/update/install-source.js +139 -0
  103. package/dist/src/update/notifier.d.ts +2 -0
  104. package/dist/src/update/notifier.js +59 -0
  105. package/dist/src/update/update-checker.d.ts +22 -0
  106. package/dist/src/update/update-checker.js +110 -0
  107. package/dist/src/update/version.d.ts +9 -0
  108. package/dist/src/update/version.js +52 -0
  109. package/dist/src/utils/agent-skill-installer.d.ts +57 -0
  110. package/dist/src/utils/agent-skill-installer.js +389 -0
  111. package/dist/src/utils/capability-metadata.d.ts +18 -0
  112. package/dist/src/utils/capability-metadata.js +88 -0
  113. package/dist/src/utils/capability-presenter.d.ts +4 -0
  114. package/dist/src/utils/capability-presenter.js +190 -0
  115. package/dist/src/utils/config.d.ts +16 -0
  116. package/dist/src/utils/config.js +54 -0
  117. package/dist/src/utils/credential-permissions.d.ts +2 -0
  118. package/dist/src/utils/credential-permissions.js +22 -0
  119. package/dist/src/utils/ecommerce-input-guidance.d.ts +15 -0
  120. package/dist/src/utils/ecommerce-input-guidance.js +85 -0
  121. package/dist/src/utils/endpoints.d.ts +52 -0
  122. package/dist/src/utils/endpoints.js +258 -0
  123. package/dist/src/utils/enrich-upload-params.d.ts +6 -0
  124. package/dist/src/utils/enrich-upload-params.js +11 -0
  125. package/dist/src/utils/entitlement.d.ts +17 -0
  126. package/dist/src/utils/entitlement.js +146 -0
  127. package/dist/src/utils/gd-home.d.ts +7 -0
  128. package/dist/src/utils/gd-home.js +26 -0
  129. package/dist/src/utils/help-verify.d.ts +9 -0
  130. package/dist/src/utils/help-verify.js +41 -0
  131. package/dist/src/utils/input-json.d.ts +3 -0
  132. package/dist/src/utils/input-json.js +61 -0
  133. package/dist/src/utils/list-output-format.d.ts +10 -0
  134. package/dist/src/utils/list-output-format.js +34 -0
  135. package/dist/src/utils/logger.d.ts +6 -0
  136. package/dist/src/utils/logger.js +19 -0
  137. package/dist/src/utils/matting-compose.d.ts +10 -0
  138. package/dist/src/utils/matting-compose.js +45 -0
  139. package/dist/src/utils/open-browser.d.ts +1 -0
  140. package/dist/src/utils/open-browser.js +4 -0
  141. package/dist/src/utils/output-path.d.ts +5 -0
  142. package/dist/src/utils/output-path.js +70 -0
  143. package/dist/src/utils/redact.d.ts +3 -0
  144. package/dist/src/utils/redact.js +96 -0
  145. package/dist/src/utils/reference-image.d.ts +8 -0
  146. package/dist/src/utils/reference-image.js +43 -0
  147. package/dist/src/utils/resolve-app-local-images.d.ts +8 -0
  148. package/dist/src/utils/resolve-app-local-images.js +84 -0
  149. package/dist/src/utils/sensitive-path.d.ts +6 -0
  150. package/dist/src/utils/sensitive-path.js +69 -0
  151. package/dist/src/utils/settings-store.d.ts +42 -0
  152. package/dist/src/utils/settings-store.js +50 -0
  153. package/dist/src/utils/sleep.d.ts +1 -0
  154. package/dist/src/utils/sleep.js +3 -0
  155. package/dist/src/utils/spinner.d.ts +2 -0
  156. package/dist/src/utils/spinner.js +4 -0
  157. package/dist/src/utils/static-help.d.ts +2 -0
  158. package/dist/src/utils/static-help.js +3 -0
  159. package/dist/src/utils/tool-display.d.ts +10 -0
  160. package/dist/src/utils/tool-display.js +55 -0
  161. package/dist/src/utils/transient-network-error.d.ts +4 -0
  162. package/dist/src/utils/transient-network-error.js +40 -0
  163. package/dist/src/utils/url-safety.d.ts +6 -0
  164. package/dist/src/utils/url-safety.js +67 -0
  165. package/dist/src/utils/write-app-deliverables.d.ts +18 -0
  166. package/dist/src/utils/write-app-deliverables.js +386 -0
  167. package/package.json +91 -0
  168. package/skills/gd-cli/SKILL.md +57 -0
  169. package/skills/gd-cli/references/auth.md +31 -0
  170. package/skills/gd-cli/references/deliverables.md +22 -0
  171. package/skills/gd-cli/references/entitlement.md +21 -0
  172. package/skills/gd-cli/references/errors.md +19 -0
  173. package/skills/gd-cli/references/org.md +18 -0
  174. package/skills/gd-cli/references/sop.md +25 -0
  175. package/skills/gd-cli/references/tools.md +29 -0
  176. package/skills/gd-cli/references/update.md +16 -0
  177. package/skills/gd-cli/references/workflows.md +22 -0
@@ -0,0 +1,483 @@
1
+ import { CLI_VERSION } from "../utils/config.js";
2
+ import { DIRECT_APPS, PUBLIC_DIRECT_TOOLS, appToolDependencies, appsDependingOnTool, resolveAppSpec, resolvePublicToolSpec, } from "./direct-registry.js";
3
+ import { capabilityMetadata, } from "../utils/capability-metadata.js";
4
+ export function buildInputJsonSchema(params, extraProperties = {}) {
5
+ const properties = { ...extraProperties };
6
+ const required = [];
7
+ for (const param of params) {
8
+ const prop = {
9
+ type: param.type === "file" ? "string" : param.type,
10
+ description: param.description,
11
+ "x-cli-flag": param.cli_flag,
12
+ };
13
+ if (param.type === "file")
14
+ prop.format = "uri-reference";
15
+ if (param.default !== undefined)
16
+ prop.default = param.default;
17
+ if (param.enum)
18
+ prop.enum = param.enum;
19
+ properties[param.name] = prop;
20
+ if (param.required)
21
+ required.push(param.name);
22
+ }
23
+ return {
24
+ type: "object",
25
+ properties,
26
+ required,
27
+ additionalProperties: true,
28
+ };
29
+ }
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
+ };
37
+ }
38
+ return {
39
+ type: "object",
40
+ properties,
41
+ required: [],
42
+ additionalProperties: true,
43
+ };
44
+ }
45
+ export function buildToolSchema(toolId) {
46
+ const spec = resolvePublicToolSpec(toolId);
47
+ if (!spec)
48
+ throw new Error(`未找到工具: ${toolId}`);
49
+ const input = sampleInput(spec.input ?? []);
50
+ return {
51
+ id: spec.name,
52
+ type: "tool",
53
+ category: spec.category,
54
+ title: spec.display_name,
55
+ description: spec.description,
56
+ canonical_command: `gd-cli tools call ${spec.name}`,
57
+ schema_command: `gd-cli tools schema ${spec.name} --format json`,
58
+ examples_command: `gd-cli tools examples ${spec.name} --format json`,
59
+ input_schema: buildInputJsonSchema(spec.input ?? []),
60
+ output_schema: buildOutputJsonSchema(spec.output),
61
+ sample_input: input,
62
+ stdin: {
63
+ supported: true,
64
+ command: `cat input.json | gd-cli tools call ${spec.name} - --format json`,
65
+ content_type: "application/json",
66
+ },
67
+ };
68
+ }
69
+ export function buildWorkflowSchema(appId) {
70
+ const spec = resolveAppSpec(appId);
71
+ if (!spec)
72
+ throw new Error(`未找到应用: ${appId}`);
73
+ const input = sampleInput(spec.input ?? []);
74
+ return {
75
+ id: spec.id,
76
+ type: "workflow",
77
+ category: spec.category,
78
+ title: spec.name,
79
+ description: spec.description,
80
+ canonical_command: `gd-cli workflows run ${spec.id}`,
81
+ schema_command: `gd-cli workflows schema ${spec.id} --format json`,
82
+ examples_command: `gd-cli workflows examples ${spec.id} --format json`,
83
+ input_schema: buildInputJsonSchema(spec.input ?? []),
84
+ output_schema: buildOutputJsonSchema(spec.output),
85
+ sample_input: input,
86
+ deliverables: spec.outputs ?? ["manifest.json", "README.md", "assets/"],
87
+ stdin: {
88
+ supported: true,
89
+ command: `cat brief.json | gd-cli workflows run ${spec.id} - --format json`,
90
+ content_type: "application/json",
91
+ },
92
+ };
93
+ }
94
+ export function buildToolExamples(toolId) {
95
+ const spec = resolvePublicToolSpec(toolId);
96
+ if (!spec)
97
+ throw new Error(`未找到工具: ${toolId}`);
98
+ const input = sampleInput(spec.input ?? []);
99
+ const curatedExamples = curatedToolExamples(spec.name);
100
+ const agentInput = firstExampleInput(curatedExamples) ?? input;
101
+ return {
102
+ id: spec.name,
103
+ type: "tool",
104
+ category: spec.category,
105
+ title: spec.display_name,
106
+ description: spec.description,
107
+ examples: [
108
+ ...(curatedExamples.length > 0
109
+ ? curatedExamples
110
+ : [
111
+ scenarioExample(spec.description, buildFlagCommand("gd-cli tools call", spec.name, spec.input ?? []), input),
112
+ ]),
113
+ {
114
+ description: "Agent / 脚本推荐:stdin JSON",
115
+ command: `cat input.json | gd-cli tools call ${spec.name} - --format json`,
116
+ input_json: agentInput,
117
+ },
118
+ {
119
+ description: "Agent / 脚本推荐:JSON 文件",
120
+ command: `gd-cli tools call ${spec.name} --input input.json --format json`,
121
+ input_json: agentInput,
122
+ },
123
+ ],
124
+ };
125
+ }
126
+ export function buildWorkflowExamples(appId) {
127
+ const spec = resolveAppSpec(appId);
128
+ if (!spec)
129
+ throw new Error(`未找到应用: ${appId}`);
130
+ const input = sampleInput(spec.input ?? []);
131
+ const curatedExamples = curatedAppExamples(spec.id);
132
+ const agentInput = firstExampleInput(curatedExamples) ?? input;
133
+ const examples = [
134
+ ...(curatedExamples.length > 0
135
+ ? curatedExamples
136
+ : [
137
+ scenarioExample(spec.description, spec.examples?.[0] ?? buildFlagCommand("gd-cli workflows run", spec.id, spec.input ?? []), input),
138
+ ]),
139
+ {
140
+ description: "Agent / 脚本推荐:stdin JSON",
141
+ command: `cat brief.json | gd-cli workflows run ${spec.id} - --format json`,
142
+ input_json: agentInput,
143
+ },
144
+ {
145
+ description: "Agent / 脚本推荐:JSON 文件",
146
+ command: `gd-cli workflows run ${spec.id} --input brief.json --format json`,
147
+ input_json: agentInput,
148
+ },
149
+ ];
150
+ if (spec.supports_batch) {
151
+ examples.push({
152
+ description: "批量任务 dry-run 预检",
153
+ command: `gd-cli workflows run ${spec.id} --input ./products.csv --assets-dir ./images --dry-run --format json`,
154
+ });
155
+ }
156
+ return {
157
+ id: spec.id,
158
+ type: "workflow",
159
+ category: spec.category,
160
+ title: spec.name,
161
+ description: spec.description,
162
+ examples,
163
+ };
164
+ }
165
+ export function buildManifest(scope = "all") {
166
+ const commands = [];
167
+ if (scope === "all" || scope === "tools") {
168
+ commands.push(...PUBLIC_DIRECT_TOOLS.map(toolManifestCommand));
169
+ }
170
+ if (scope === "all" || scope === "workflows") {
171
+ commands.push(...DIRECT_APPS.map(workflowManifestCommand));
172
+ }
173
+ if (scope === "all") {
174
+ commands.push({
175
+ id: "dam.upload",
176
+ type: "dam",
177
+ category: "asset",
178
+ title: "DAM 素材上传",
179
+ description: "上传本地文件到 DAM,返回可复用 asset_id 与 CDN URL",
180
+ canonical_command: "gd-cli dam upload <file>",
181
+ output: "json",
182
+ safe_for_agent: true,
183
+ ...capabilityMetadata("dam", "dam.upload"),
184
+ }, {
185
+ id: "dam.search",
186
+ type: "dam",
187
+ category: "asset",
188
+ title: "DAM 素材搜索",
189
+ description: "按关键词、资源库、文件夹、类型、格式或标签搜索素材",
190
+ canonical_command: "gd-cli dam search <keyword>",
191
+ output: "json",
192
+ safe_for_agent: true,
193
+ ...capabilityMetadata("dam", "dam.search"),
194
+ }, {
195
+ id: "org.current",
196
+ type: "org",
197
+ category: "account",
198
+ title: "当前组织",
199
+ description: "查询当前绑定团队,便于 Agent 确认执行上下文",
200
+ canonical_command: "gd-cli org current",
201
+ output: "json",
202
+ safe_for_agent: true,
203
+ ...capabilityMetadata("org", "org.current"),
204
+ });
205
+ }
206
+ return {
207
+ name: "gd-cli",
208
+ version: CLI_VERSION,
209
+ description: "Gaoding creative production CLI for agents",
210
+ commands,
211
+ };
212
+ }
213
+ export function rowsForManifest(manifest) {
214
+ return manifest.commands.map((command) => ({
215
+ id: command.id,
216
+ type: command.type,
217
+ 分类: command.category,
218
+ 名称: command.title,
219
+ command: command.canonical_command,
220
+ }));
221
+ }
222
+ export function buildTopExamples() {
223
+ return {
224
+ examples: [
225
+ {
226
+ title: "生成商品图库素材包",
227
+ description: "完整 Workflow:上传商品图,自动完成抠图、提示词优化、多图生成和标题卖点整理,适合要一组可上架 Listing 图库时使用。",
228
+ command: "gd-cli workflows run listing-gallery --image ./sku_001.jpg --brief \"夏季轻薄防晒衣,透气面料,适合户外通勤;卖点图短文案:轻薄防晒 通勤无负担\" --copy-mode render-text --ratio 1:1 -f json",
229
+ input_json: {
230
+ image: "./sku_001.jpg",
231
+ brief: "夏季轻薄防晒衣,透气面料,适合户外通勤;卖点图短文案:轻薄防晒 通勤无负担",
232
+ copy_mode: "render-text",
233
+ ratio: "1:1",
234
+ },
235
+ },
236
+ {
237
+ title: "单项 AI 生图",
238
+ description: "只调用生图 Tool,不编排完整 Workflow;适合已有明确画面提示词,只需要一张图时使用。",
239
+ command: "gd-cli tools call image.generate --prompt \"电商主图,白底,突出夏季轻薄防晒衣的透气面料,干净高级\" --image ./sku_001.jpg --ratio 1:1 -f json",
240
+ input_json: {
241
+ prompt: "电商主图,白底,突出夏季轻薄防晒衣的透气面料,干净高级",
242
+ image: "./sku_001.jpg",
243
+ ratio: "1:1",
244
+ },
245
+ },
246
+ {
247
+ title: "生成商品标题",
248
+ description: "轻量文本 Tool;适合脚本或 Agent 批量根据 brief 生成标题。",
249
+ command: "gd-cli tools call text.title --brief \"夏季轻薄防晒衣,防晒透气,户外通勤,女款\" -f json",
250
+ input_json: {
251
+ brief: "夏季轻薄防晒衣,防晒透气,户外通勤,女款",
252
+ },
253
+ },
254
+ {
255
+ title: "生成商品短视频",
256
+ description: "文生视频;适合没有参考图、先用文字描述生成短视频镜头。",
257
+ command: "gd-cli tools call video.generate --prompt \"商品短视频,展示夏季轻薄防晒衣的透气面料和户外通勤场景,镜头缓慢推进\" --duration 5 -f json",
258
+ input_json: {
259
+ prompt: "商品短视频,展示夏季轻薄防晒衣的透气面料和户外通勤场景,镜头缓慢推进",
260
+ duration: "5",
261
+ },
262
+ },
263
+ {
264
+ title: "参考图生成商品短视频",
265
+ description: "图生视频;适合以商品图作为首帧或视觉参考,保持商品主体一致。",
266
+ command: "gd-cli tools call video.generate --prompt \"以参考图为首帧,展示防晒衣面料细节,轻微镜头推进,自然光\" --image ./sku_001.jpg --duration 5 -f json",
267
+ input_json: {
268
+ prompt: "以参考图为首帧,展示防晒衣面料细节,轻微镜头推进,自然光",
269
+ image: "./sku_001.jpg",
270
+ duration: "5",
271
+ },
272
+ },
273
+ {
274
+ title: "查找 DAM 里的商品素材",
275
+ description: "搜索已入库素材,返回 asset_id、URL、封面和文件信息,适合后续 Workflow / Tool 复用素材。",
276
+ command: "gd-cli dam search \"防晒衣\" --type image --format jpg,png -f json",
277
+ },
278
+ {
279
+ title: "Agent 读取能力清单",
280
+ description: "机器可读入口;Agent 应优先读取 manifest,再按 schema/examples 选择能力和拼装参数。",
281
+ command: "gd-cli manifest -f json",
282
+ },
283
+ ],
284
+ };
285
+ }
286
+ function toolManifestCommand(spec) {
287
+ return {
288
+ id: spec.name,
289
+ type: "tool",
290
+ category: spec.category,
291
+ title: spec.display_name,
292
+ description: spec.description,
293
+ canonical_command: `gd-cli tools call ${spec.name}`,
294
+ input_schema_command: `gd-cli tools schema ${spec.name}`,
295
+ examples_command: `gd-cli tools examples ${spec.name}`,
296
+ output: "json",
297
+ safe_for_agent: true,
298
+ ...capabilityMetadata("tool", spec.name),
299
+ affected_workflows: appsDependingOnTool(spec.name).map((app) => app.id),
300
+ };
301
+ }
302
+ function workflowManifestCommand(spec) {
303
+ return {
304
+ id: spec.id,
305
+ type: "workflow",
306
+ category: spec.category,
307
+ title: spec.name,
308
+ description: spec.description,
309
+ canonical_command: `gd-cli workflows run ${spec.id}`,
310
+ input_schema_command: `gd-cli workflows schema ${spec.id}`,
311
+ examples_command: `gd-cli workflows examples ${spec.id}`,
312
+ output: "json",
313
+ safe_for_agent: true,
314
+ ...capabilityMetadata("app", spec.id),
315
+ dependency_tools: appToolDependencies(spec),
316
+ };
317
+ }
318
+ function buildFlagCommand(prefix, id, params) {
319
+ const pieces = [prefix, id];
320
+ for (const param of params) {
321
+ if (!param.required)
322
+ continue;
323
+ pieces.push(param.cli_flag, quoteShell(String(sampleValue(param))));
324
+ }
325
+ pieces.push("--format", "json");
326
+ return pieces.join(" ");
327
+ }
328
+ function sampleInput(params) {
329
+ const out = {};
330
+ for (const param of params) {
331
+ if (!param.required && param.default === undefined)
332
+ continue;
333
+ out[param.name] = sampleValue(param);
334
+ }
335
+ return out;
336
+ }
337
+ function sampleValue(param) {
338
+ if (param.default !== undefined)
339
+ return param.default;
340
+ const name = param.name.toLowerCase();
341
+ if (param.type === "boolean")
342
+ return true;
343
+ if (param.type === "number")
344
+ return 1;
345
+ if (name.includes("image"))
346
+ return "./sku.png";
347
+ if (name.includes("assets_dir"))
348
+ return "./images";
349
+ if (name === "input")
350
+ return "./products.csv";
351
+ if (name.includes("duration"))
352
+ return "5";
353
+ if (name.includes("ratio"))
354
+ return "1:1";
355
+ if (name.includes("brief"))
356
+ return "夏季防晒衣,轻薄透气,适合户外通勤";
357
+ if (name.includes("prompt"))
358
+ return "生成一张干净高级的电商商品主图";
359
+ if (name.includes("file"))
360
+ return "./image.png";
361
+ return "value";
362
+ }
363
+ function curatedToolExamples(toolId) {
364
+ if (toolId === "asset.upload") {
365
+ return [
366
+ scenarioExample("上传本地商品图到临时 CDN,返回可传给后续 Tool/App 的 URL。", "gd-cli tools call asset.upload --file ./sku_001.jpg -f json", { file: "./sku_001.jpg" }),
367
+ ];
368
+ }
369
+ if (toolId === "text.title") {
370
+ return [
371
+ scenarioExample("根据商品卖点生成适合电商或社媒使用的标题。", "gd-cli tools call text.title --brief \"夏季轻薄防晒衣,防晒透气,户外通勤,女款\" -f json", { brief: "夏季轻薄防晒衣,防晒透气,户外通勤,女款" }),
372
+ ];
373
+ }
374
+ if (toolId === "text.prompt") {
375
+ return [
376
+ scenarioExample("把简短商品需求扩写成更适合生图模型的提示词。", "gd-cli tools call text.prompt --prompt \"防晒衣电商主图,突出轻薄透气\" --image ./sku_001.jpg -f json", {
377
+ prompt: "防晒衣电商主图,突出轻薄透气",
378
+ image: "./sku_001.jpg",
379
+ }),
380
+ ];
381
+ }
382
+ if (toolId === "image.cutout") {
383
+ return [
384
+ scenarioExample("商品图抠图,输出透明背景 PNG,适合后续主图或海报合成。", "gd-cli tools call image.cutout --image ./sku_001.jpg --mode product -f json", { image: "./sku_001.jpg", mode: "product" }),
385
+ ];
386
+ }
387
+ if (toolId === "image.generate") {
388
+ return [
389
+ scenarioExample("不带参考图,直接根据文字提示词生成一张电商海报。", "gd-cli tools call image.generate --prompt \"夏季轻薄防晒衣电商海报,清爽户外通勤场景,自然光,干净高级,突出轻薄透气面料\" --ratio 1:1 -f json", {
390
+ prompt: "夏季轻薄防晒衣电商海报,清爽户外通勤场景,自然光,干净高级,突出轻薄透气面料",
391
+ ratio: "1:1",
392
+ }),
393
+ scenarioExample("带参考图,根据商品图和提示词生成一张干净高级的电商主图。", "gd-cli tools call image.generate --prompt \"电商主图,白底,突出夏季轻薄防晒衣的透气面料,干净高级\" --image ./sku_001.jpg --ratio 1:1 -f json", {
394
+ prompt: "电商主图,白底,突出夏季轻薄防晒衣的透气面料,干净高级",
395
+ image: "./sku_001.jpg",
396
+ ratio: "1:1",
397
+ }),
398
+ ];
399
+ }
400
+ if (toolId === "image.svg") {
401
+ return [
402
+ scenarioExample("把 Logo 或图形素材转成 SVG,适合后续编辑或排版。", "gd-cli tools call image.svg --image ./logo.png --mode auto -f json", { image: "./logo.png", mode: "auto" }),
403
+ ];
404
+ }
405
+ if (toolId === "image.super-res") {
406
+ return [
407
+ scenarioExample("提升商品图清晰度,适合上架前处理低清素材。", "gd-cli tools call image.super-res --image ./sku_001.jpg --mode hd -f json", { image: "./sku_001.jpg", mode: "hd" }),
408
+ ];
409
+ }
410
+ if (toolId === "video.generate") {
411
+ return [
412
+ scenarioExample("文生视频:没有参考图时,直接用镜头描述生成商品短视频。", "gd-cli tools call video.generate --prompt \"商品短视频,展示夏季轻薄防晒衣的透气面料和户外通勤场景,镜头缓慢推进\" --duration 5 -f json", {
413
+ prompt: "商品短视频,展示夏季轻薄防晒衣的透气面料和户外通勤场景,镜头缓慢推进",
414
+ duration: "5",
415
+ }),
416
+ scenarioExample("图生视频:以商品图为首帧或视觉参考,保持商品主体一致。", "gd-cli tools call video.generate --prompt \"以参考图为首帧,展示防晒衣面料细节,轻微镜头推进,自然光\" --image ./sku_001.jpg --duration 5 -f json", {
417
+ prompt: "以参考图为首帧,展示防晒衣面料细节,轻微镜头推进,自然光",
418
+ image: "./sku_001.jpg",
419
+ duration: "5",
420
+ }),
421
+ ];
422
+ }
423
+ return [];
424
+ }
425
+ function curatedAppExamples(appId) {
426
+ if (appId === "listing-gallery") {
427
+ return [
428
+ scenarioExample("生成一套可上架的商品图库素材,包含白底主图、卖点图、细节图和生活方式图。", "gd-cli workflows run listing-gallery --image ./sku_001.jpg --brief \"夏季轻薄防晒衣,透气面料,适合户外通勤;卖点图短文案:轻薄防晒 通勤无负担\" --copy-mode render-text --ratio 1:1 -f json", {
429
+ image: "./sku_001.jpg",
430
+ brief: "夏季轻薄防晒衣,透气面料,适合户外通勤;卖点图短文案:轻薄防晒 通勤无负担",
431
+ copy_mode: "render-text",
432
+ ratio: "1:1",
433
+ }),
434
+ ];
435
+ }
436
+ if (appId === "pdp-a-plus") {
437
+ return [
438
+ scenarioExample("生成详情页/A+模块素材,按购买疑虑组织首屏、痛点、结构、使用和规格模块。", "gd-cli workflows run pdp-a-plus --image ./air-purifier.jpg --brief \"桌面空气净化器,静音,滤芯可更换,适合卧室;首屏短文案:静音净化 安心入睡\" --copy-mode render-text --ratio 4:5 -f json", {
439
+ image: "./air-purifier.jpg",
440
+ brief: "桌面空气净化器,静音,滤芯可更换,适合卧室;首屏短文案:静音净化 安心入睡",
441
+ copy_mode: "render-text",
442
+ ratio: "4:5",
443
+ }),
444
+ ];
445
+ }
446
+ if (appId === "social-seeding-pack") {
447
+ return [
448
+ scenarioExample("生成小红书种草图文素材,包含封面图、场景图、标题、正文和标签。", "gd-cli workflows run social-seeding-pack --image ./serum.jpg --brief \"屏障修护精华,清爽不黏,适合通勤包分享;封面短文案:通勤包里的清爽修护\" --copy-mode render-text --ratio 3:4 -f json", {
449
+ image: "./serum.jpg",
450
+ brief: "屏障修护精华,清爽不黏,适合通勤包分享;封面短文案:通勤包里的清爽修护",
451
+ copy_mode: "render-text",
452
+ ratio: "3:4",
453
+ }),
454
+ ];
455
+ }
456
+ if (appId === "campaign-kv-pack") {
457
+ return [
458
+ 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", {
459
+ image: "./running-shoes.jpg",
460
+ brief: "城市跑鞋新品 Campaign,轻量缓震,面向通勤跑者;主标题:轻跑进城",
461
+ copy_mode: "render-text",
462
+ ratios: "16:9,1:1,4:5",
463
+ }),
464
+ ];
465
+ }
466
+ return [];
467
+ }
468
+ function scenarioExample(description, command, inputJson) {
469
+ return {
470
+ description,
471
+ command,
472
+ ...(inputJson ? { input_json: inputJson } : {}),
473
+ };
474
+ }
475
+ function firstExampleInput(examples) {
476
+ const input = examples.find((item) => item.input_json)?.input_json;
477
+ return input && typeof input === "object" && !Array.isArray(input)
478
+ ? input
479
+ : undefined;
480
+ }
481
+ function quoteShell(value) {
482
+ return /^[\w./:=,-]+$/.test(value) ? value : `"${value.replace(/"/g, '\\"')}"`;
483
+ }
@@ -0,0 +1,2 @@
1
+ import { Command } from "commander";
2
+ export declare function loadDynamicAppCommands(appCmd: Command): Promise<void>;
@@ -0,0 +1,70 @@
1
+ import { RegistryCache } from "./registry-cache.js";
2
+ import { RegistryClient } from "./registry-client.js";
3
+ import { HubClient } from "../api/hub-client.js";
4
+ import { AppRunner } from "../api/app-runner.js";
5
+ import { withAuth } from "../middleware/auth.js";
6
+ import { withErrorHandler } from "../middleware/error-handler.js";
7
+ import { formatOutput } from "../middleware/output.js";
8
+ import { resolveInvokeOutputFormat } from "../utils/list-output-format.js";
9
+ import { appActivityLabel } from "../utils/tool-display.js";
10
+ import { createSpinner } from "../utils/spinner.js";
11
+ import { logger } from "../utils/logger.js";
12
+ export async function loadDynamicAppCommands(appCmd) {
13
+ const client = new HubClient();
14
+ const registryClient = new RegistryClient(client);
15
+ const cache = new RegistryCache(registryClient);
16
+ let registry;
17
+ try {
18
+ registry = await cache.get();
19
+ }
20
+ catch {
21
+ logger.debug("Registry 缓存不可用,跳过动态 APP 命令注册");
22
+ return;
23
+ }
24
+ const apps = registry.apps ?? [];
25
+ for (const app of apps) {
26
+ registerAppSubcommand(appCmd, app);
27
+ }
28
+ }
29
+ function registerAppSubcommand(parent, spec) {
30
+ const cmd = parent
31
+ .command(spec.id)
32
+ .description(spec.description);
33
+ for (const param of spec.input ?? []) {
34
+ const flag = param.cli_flag ?? `--${param.name}`;
35
+ const desc = param.description + (param.required ? " (必填)" : "");
36
+ cmd.option(`${flag} <value>`, desc);
37
+ }
38
+ cmd
39
+ .option("--async", "异步模式", false)
40
+ .option("--timeout <seconds>", "超时时间(秒)", String(spec.estimated_duration * 2))
41
+ .action(withErrorHandler(withAuth(async (...args) => {
42
+ const opts = args[0];
43
+ const cmd = args[1];
44
+ const params = {};
45
+ for (const [k, v] of Object.entries(opts)) {
46
+ if (k !== "async" && k !== "timeout" && v !== undefined && v !== false) {
47
+ params[k] = v;
48
+ }
49
+ }
50
+ const label = appActivityLabel(spec.id, spec.name);
51
+ const spinner = createSpinner(`${label} · 处理中…`);
52
+ if (process.stderr.isTTY)
53
+ spinner.start();
54
+ const runner = new AppRunner();
55
+ const result = await runner.run(spec.id, params, {
56
+ async: !!opts.async,
57
+ timeout: parseInt(String(opts.timeout)),
58
+ });
59
+ if (process.stderr.isTTY) {
60
+ if (result.status === "completed")
61
+ spinner.succeed(`${label} · 已完成`);
62
+ else if (result.status === "failed")
63
+ spinner.fail(`${label} · 失败`);
64
+ else
65
+ spinner.stop();
66
+ }
67
+ const format = resolveInvokeOutputFormat(cmd);
68
+ formatOutput(result, format, { activityLabel: label });
69
+ })));
70
+ }
@@ -0,0 +1,11 @@
1
+ import type { AppSpec, RegistryResponse, ToolSpec } from "./types.js";
2
+ export declare const DIRECT_TOOLS: ToolSpec[];
3
+ export declare const PUBLIC_DIRECT_TOOLS: ToolSpec[];
4
+ export declare const DIRECT_APPS: AppSpec[];
5
+ export declare const DIRECT_REGISTRY: RegistryResponse;
6
+ export declare function resolveToolSpec(id: string): ToolSpec | undefined;
7
+ export declare function resolvePublicToolSpec(id: string): ToolSpec | undefined;
8
+ export declare function isPublicToolSpec(tool: ToolSpec): boolean;
9
+ export declare function resolveAppSpec(id: string): AppSpec | undefined;
10
+ export declare function appToolDependencies(app: AppSpec): string[];
11
+ export declare function appsDependingOnTool(toolId: string): AppSpec[];