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,546 @@
1
+ import Table from "cli-table3";
2
+ import chalk from "chalk";
3
+ import { capabilityMetadata, statusLabel, } from "../utils/capability-metadata.js";
4
+ import { isDebug, isVerbose } from "../utils/config.js";
5
+ export function formatOutput(data, format = "json", humanCtx) {
6
+ switch (format) {
7
+ case "json":
8
+ console.log(JSON.stringify(data, null, 2));
9
+ break;
10
+ case "human":
11
+ printHumanTaskResult(data, humanCtx);
12
+ break;
13
+ case "text":
14
+ case "pretty":
15
+ printPretty(data);
16
+ break;
17
+ case "table":
18
+ printTable(data);
19
+ break;
20
+ default:
21
+ console.log(JSON.stringify(data, null, 2));
22
+ }
23
+ }
24
+ /** TTY 默认:展示任务/工具结果中的链接与交付物说明,非原始 JSON */
25
+ export function printHumanTaskResult(data, ctx) {
26
+ if (typeof data !== "object" || data === null) {
27
+ console.log(String(data));
28
+ return;
29
+ }
30
+ const r = data;
31
+ const status = String(r.status ?? "");
32
+ const taskId = r.task_id != null ? String(r.task_id) : "";
33
+ const label = ctx?.activityLabel?.trim();
34
+ if (status === "failed") {
35
+ printFailedTaskResult(r, ctx, label, taskId);
36
+ return;
37
+ }
38
+ if (status === "submitted" ||
39
+ status === "running" ||
40
+ status === "pending") {
41
+ console.log(chalk.cyan(label ? `\n⏳ ${label} · 进行中` : "\n⏳ 任务进行中"));
42
+ if (taskId)
43
+ console.log(` 任务 ID: ${taskId}`);
44
+ if (r.message)
45
+ console.log(` ${String(r.message)}`);
46
+ if (taskId) {
47
+ console.log(chalk.dim(` 任务 ID: ${taskId}`));
48
+ }
49
+ console.log("");
50
+ return;
51
+ }
52
+ if (status === "completed" && r.outputs != null) {
53
+ if (label) {
54
+ console.log(chalk.green(`\n── ${label} · 结果 ──\n`));
55
+ }
56
+ else {
57
+ console.log(chalk.green("\n✓ 已完成\n"));
58
+ }
59
+ printOutputsDeliverables(r.outputs, ctx);
60
+ const zipPath = typeof r.deliverable_zip === "string" ? r.deliverable_zip.trim() : "";
61
+ if (zipPath) {
62
+ const who = label ? `「${label}」` : "本次";
63
+ console.log(chalk.green(`\n📦 此次${who}交付物已打包:${zipPath}\n 可直接下载使用(内含 Markdown 与各步骤图片)。`));
64
+ }
65
+ if (taskId) {
66
+ console.log(chalk.dim(`\n 任务编号(排错时可提供): ${taskId}`));
67
+ }
68
+ console.log("");
69
+ return;
70
+ }
71
+ if (printAgentSkillResult(r))
72
+ return;
73
+ // 注册表详情、列表包装等
74
+ if (r.tasks != null && Array.isArray(r.tasks)) {
75
+ printPretty(data);
76
+ return;
77
+ }
78
+ printPretty(data);
79
+ }
80
+ function printFailedTaskResult(r, ctx, label, taskId) {
81
+ console.log(chalk.red(label ? `\n✗ ${label} · 处理失败` : "\n✗ 任务失败"));
82
+ const err = objectRecord(r.error);
83
+ const outputs = objectRecord(r.outputs);
84
+ const failedStep = objectRecord(err?.step) ?? objectRecord(outputs?.failed_step);
85
+ const message = stringField(err, "message") ??
86
+ (r.error == null ? "" : String(r.error)) ??
87
+ "任务执行失败";
88
+ console.log(` ${message}`);
89
+ if (failedStep) {
90
+ const order = stringField(failedStep, "step_order");
91
+ const stepName = stringField(failedStep, "step_name") ?? "未知步骤";
92
+ const tool = stringField(failedStep, "tool");
93
+ const prefix = order ? `${order}. ` : "";
94
+ console.log(` 失败步骤: ${prefix}${stepName}${tool ? `(${tool})` : ""}`);
95
+ }
96
+ const reason = stringField(err, "reason");
97
+ if (reason)
98
+ console.log(` 原因: ${reason}`);
99
+ const hint = stringField(err, "hint");
100
+ if (hint)
101
+ console.log(chalk.yellow(`\n 建议: ${hint}`));
102
+ const nextSteps = Array.isArray(err?.next_steps)
103
+ ? err.next_steps.map(String).filter(Boolean)
104
+ : [];
105
+ if (nextSteps.length > 0) {
106
+ console.log(chalk.bold("\n 下一步"));
107
+ for (const item of nextSteps)
108
+ console.log(` - ${item}`);
109
+ }
110
+ const completedSteps = Array.isArray(outputs?.completed_steps)
111
+ ? outputs.completed_steps.map(objectRecord).filter((item) => !!item)
112
+ : [];
113
+ if (completedSteps.length > 0) {
114
+ console.log(chalk.bold("\n 已完成步骤"));
115
+ for (const step of completedSteps) {
116
+ const order = stringField(step, "step_order");
117
+ const name = stringField(step, "step_name") ?? "";
118
+ const tool = stringField(step, "tool");
119
+ console.log(` - ${order ? `${order}. ` : ""}${name}${tool ? `(${tool})` : ""}`);
120
+ }
121
+ }
122
+ if (outputs) {
123
+ const assets = collectSemanticAssets(outputs);
124
+ const textBlocks = collectTextBlocks(outputs);
125
+ if (assets.length > 0 || textBlocks.length > 0) {
126
+ console.log(chalk.bold("\n 已生成内容"));
127
+ printOutputsDeliverables(outputs, ctx);
128
+ }
129
+ }
130
+ const rawMessage = stringField(err, "raw_message");
131
+ if ((isVerbose() || isDebug()) && rawMessage && rawMessage !== message) {
132
+ console.log(chalk.dim(`\n 原始错误: ${rawMessage}`));
133
+ }
134
+ if (taskId)
135
+ console.log(chalk.dim(`\n 任务编号(排错时可提供): ${taskId}`));
136
+ console.log("");
137
+ }
138
+ function guessMediaKind(url, mime) {
139
+ const m = String(mime ?? "").toLowerCase();
140
+ if (m.startsWith("video/"))
141
+ return "video";
142
+ if (m.startsWith("image/"))
143
+ return "image";
144
+ const u = url.split("?")[0].toLowerCase();
145
+ if (/\.(mp4|webm|mov|mkv)$/.test(u))
146
+ return "video";
147
+ if (/\.(png|jpe?g|gif|webp|svg)$/.test(u))
148
+ return "image";
149
+ return "file";
150
+ }
151
+ function labelForKind(k) {
152
+ if (k === "image")
153
+ return "图片";
154
+ if (k === "video")
155
+ return "视频";
156
+ return "文件";
157
+ }
158
+ function extractUrlsDeep(val, acc) {
159
+ if (val == null)
160
+ return;
161
+ if (typeof val === "string" && /^https?:\/\//.test(val)) {
162
+ acc.add(val);
163
+ return;
164
+ }
165
+ if (Array.isArray(val)) {
166
+ for (const x of val)
167
+ extractUrlsDeep(x, acc);
168
+ return;
169
+ }
170
+ if (typeof val === "object") {
171
+ const o = val;
172
+ for (const k of ["url", "uri"]) {
173
+ const v = o[k];
174
+ if (typeof v === "string" && /^https?:\/\//.test(v))
175
+ acc.add(v);
176
+ }
177
+ for (const v of Object.values(o))
178
+ extractUrlsDeep(v, acc);
179
+ }
180
+ }
181
+ function orderedUrls(outputs) {
182
+ const set = new Set();
183
+ extractUrlsDeep(outputs, set);
184
+ const all = [...set];
185
+ if (typeof outputs === "object" &&
186
+ outputs !== null &&
187
+ !Array.isArray(outputs)) {
188
+ const o = outputs;
189
+ if (typeof o.url === "string" && all.includes(o.url)) {
190
+ return [o.url, ...all.filter((u) => u !== o.url)];
191
+ }
192
+ }
193
+ return all;
194
+ }
195
+ function assetLabelFromKey(key) {
196
+ const normalized = key.toLowerCase();
197
+ const map = {
198
+ product: "原始商品图 / CDN 素材",
199
+ source: "原始素材",
200
+ input: "输入素材",
201
+ cutout: "抠图后图片",
202
+ matting: "抠图后图片",
203
+ hero: "生成主图",
204
+ scene: "生成场景图",
205
+ title: "标题文案",
206
+ prompt: "提示词",
207
+ video: "生成视频",
208
+ uploaded: "上传后的素材",
209
+ };
210
+ return map[normalized] ?? key;
211
+ }
212
+ function normalizeSemanticAsset(item, fallbackLabel) {
213
+ if (!item || typeof item !== "object")
214
+ return null;
215
+ const o = item;
216
+ const url = typeof o.url === "string" && /^https?:\/\//.test(o.url) ? o.url : "";
217
+ if (!url)
218
+ return null;
219
+ const type = o.type === "image" || o.type === "video" || o.type === "file"
220
+ ? o.type
221
+ : guessMediaKind(url, o.mime_type);
222
+ return {
223
+ label: typeof o.label === "string" && o.label.trim() ? o.label.trim() : fallbackLabel,
224
+ role: typeof o.role === "string" ? o.role : undefined,
225
+ url,
226
+ type,
227
+ };
228
+ }
229
+ function collectSemanticAssets(outputs) {
230
+ if (!outputs || typeof outputs !== "object" || Array.isArray(outputs))
231
+ return [];
232
+ const o = outputs;
233
+ const out = [];
234
+ const seen = new Set();
235
+ const push = (asset) => {
236
+ if (!asset || seen.has(asset.url))
237
+ return;
238
+ seen.add(asset.url);
239
+ out.push(asset);
240
+ };
241
+ const explicitAssets = o.assets;
242
+ if (Array.isArray(explicitAssets)) {
243
+ for (const item of explicitAssets) {
244
+ push(normalizeSemanticAsset(item, "资源"));
245
+ }
246
+ if (out.length)
247
+ return out;
248
+ }
249
+ for (const [key, value] of Object.entries(o)) {
250
+ if (!value || typeof value !== "object" || Array.isArray(value))
251
+ continue;
252
+ const asset = normalizeSemanticAsset(value, assetLabelFromKey(key));
253
+ if (asset)
254
+ push(asset);
255
+ }
256
+ if (out.length)
257
+ return out;
258
+ if (typeof o.url === "string" && /^https?:\/\//.test(o.url)) {
259
+ push({
260
+ label: assetLabelFromKey(String(o.role ?? "结果")),
261
+ url: o.url,
262
+ type: guessMediaKind(o.url, o.mime_type),
263
+ });
264
+ }
265
+ return out;
266
+ }
267
+ function collectTextBlocks(outputs) {
268
+ if (!outputs || typeof outputs !== "object" || Array.isArray(outputs))
269
+ return [];
270
+ const o = outputs;
271
+ const blocks = [];
272
+ const push = (label, value) => {
273
+ if (typeof value !== "string")
274
+ return;
275
+ const text = value.trim();
276
+ if (!text)
277
+ return;
278
+ blocks.push({ label, text });
279
+ };
280
+ push("标题", o.title_text);
281
+ push("小红书种草文案", o.xhs_caption);
282
+ push("交付说明", o.delivery_copy);
283
+ push("文案模式", formatObjectText(o.copy_plan));
284
+ push("图上/后期文案建议", formatObjectText(o.overlay_copy));
285
+ if (blocks.length === 0) {
286
+ push("文案与说明", o.text);
287
+ }
288
+ return blocks;
289
+ }
290
+ function formatObjectText(value) {
291
+ if (!value || typeof value !== "object" || Array.isArray(value))
292
+ return undefined;
293
+ const entries = Object.entries(value)
294
+ .filter(([, item]) => item !== undefined && item !== null && String(item).trim())
295
+ .map(([key, item]) => `- ${key}: ${String(item)}`);
296
+ return entries.length > 0 ? entries.join("\n") : undefined;
297
+ }
298
+ function printTextBlocks(blocks) {
299
+ if (blocks.length === 0)
300
+ return;
301
+ console.log(chalk.bold("\n 文案\n"));
302
+ for (const block of blocks) {
303
+ console.log(` 【${block.label}】`);
304
+ for (const line of block.text.split("\n")) {
305
+ console.log(` ${line}`);
306
+ }
307
+ console.log("");
308
+ }
309
+ }
310
+ function printOutputsDeliverables(outputs, ctx) {
311
+ const assets = collectSemanticAssets(outputs);
312
+ const textBlocks = collectTextBlocks(outputs);
313
+ if (assets.length > 0) {
314
+ const hint = ctx?.activityLabel
315
+ ? " 本次生成的资源如下:\n"
316
+ : " 交付物(链接可复制到浏览器打开)\n";
317
+ console.log(chalk.bold(hint));
318
+ for (const asset of assets) {
319
+ const k = asset.type ?? guessMediaKind(asset.url, undefined);
320
+ console.log(` 【${asset.label || labelForKind(k)}】`);
321
+ console.log(` ${labelForKind(k)}链接:${asset.url}\n`);
322
+ }
323
+ printTextBlocks(textBlocks);
324
+ return;
325
+ }
326
+ const urls = orderedUrls(outputs);
327
+ if (urls.length === 0) {
328
+ if (textBlocks.length > 0) {
329
+ printTextBlocks(textBlocks);
330
+ return;
331
+ }
332
+ if (typeof outputs === "object" && outputs !== null) {
333
+ console.log(` ${JSON.stringify(outputs, null, 2)}`);
334
+ }
335
+ else {
336
+ console.log(` ${String(outputs)}`);
337
+ }
338
+ return;
339
+ }
340
+ const hint = ctx?.activityLabel
341
+ ? " 在浏览器中打开下方链接即可查看或下载:\n"
342
+ : " 交付物(链接可复制到浏览器打开)\n";
343
+ console.log(chalk.bold(hint));
344
+ for (const u of urls) {
345
+ const k = guessMediaKind(u, undefined);
346
+ console.log(` 【${labelForKind(k)}】`);
347
+ console.log(` ${u}\n`);
348
+ }
349
+ printTextBlocks(textBlocks);
350
+ }
351
+ function printPretty(data) {
352
+ const printable = stripCapabilityMetadataForHuman(data);
353
+ if (Array.isArray(printable)) {
354
+ if (printable.length === 0) {
355
+ console.log("(empty)");
356
+ return;
357
+ }
358
+ const first = printable[0];
359
+ if (typeof first === "object" && first !== null && !Array.isArray(first)) {
360
+ const keys = Object.keys(first);
361
+ for (const row of printable) {
362
+ console.log(keys.map((k) => `${k}: ${row[k] ?? ""}`).join(" "));
363
+ }
364
+ return;
365
+ }
366
+ }
367
+ if (typeof printable !== "object" || printable === null) {
368
+ console.log(String(printable));
369
+ return;
370
+ }
371
+ const obj = printable;
372
+ const maxKeyLen = Math.max(...Object.keys(obj).map((k) => k.length));
373
+ for (const [key, value] of Object.entries(obj)) {
374
+ const label = key.padEnd(maxKeyLen);
375
+ if (Array.isArray(value)) {
376
+ console.log(` ${label} ${value.length} items`);
377
+ for (const item of value) {
378
+ console.log(` - ${JSON.stringify(item)}`);
379
+ }
380
+ }
381
+ else if (typeof value === "object" && value !== null) {
382
+ console.log(` ${label} ${JSON.stringify(value)}`);
383
+ }
384
+ else {
385
+ console.log(` ${label} ${String(value)}`);
386
+ }
387
+ }
388
+ }
389
+ const CAPABILITY_HUMAN_HIDDEN_KEYS = new Set([
390
+ "source",
391
+ "status",
392
+ "policy",
393
+ ]);
394
+ function stripCapabilityMetadataForHuman(value) {
395
+ if (Array.isArray(value))
396
+ return value.map(stripCapabilityMetadataForHuman);
397
+ if (!value || typeof value !== "object")
398
+ return value;
399
+ const obj = value;
400
+ const isCapabilityMetadataCarrier = typeof obj.source === "string" &&
401
+ typeof obj.status === "string" &&
402
+ typeof obj.policy === "string";
403
+ const out = {};
404
+ for (const [key, child] of Object.entries(obj)) {
405
+ if (isCapabilityMetadataCarrier && CAPABILITY_HUMAN_HIDDEN_KEYS.has(key)) {
406
+ continue;
407
+ }
408
+ out[key] = stripCapabilityMetadataForHuman(child);
409
+ }
410
+ return out;
411
+ }
412
+ function printAgentSkillResult(r) {
413
+ if (r.skill !== "gd-cli" || !Array.isArray(r.targets))
414
+ return false;
415
+ const targets = r.targets
416
+ .map(objectRecord)
417
+ .filter((target) => !!target);
418
+ const changed = r.changed === true;
419
+ console.log(chalk.bold("\ngd-cli Agent Skill\n"));
420
+ for (const target of targets) {
421
+ const agent = String(target.agent ?? "");
422
+ const status = agentSkillStatusLabel(String(target.status ?? ""));
423
+ const mode = typeof target.mode === "string" ? ` · ${target.mode}` : "";
424
+ const changedLabel = target.changed === true ? " · 已变更" : "";
425
+ console.log(` ${agent}: ${status}${mode}${changedLabel}`);
426
+ console.log(chalk.dim(` ${String(target.path ?? "")}`));
427
+ if (target.reason)
428
+ console.log(chalk.yellow(` ${String(target.reason)}`));
429
+ }
430
+ if (targets.length === 0)
431
+ console.log(" 无需变更");
432
+ console.log(changed
433
+ ? chalk.green("\nAgent Skill 文件已变更。")
434
+ : chalk.dim("\nAgent Skill 文件没有变化。"));
435
+ if (r.restart_required === true) {
436
+ console.log("请重启 Agent 或开启新会话以加载最新 Skill。\n");
437
+ }
438
+ else {
439
+ console.log("");
440
+ }
441
+ return true;
442
+ }
443
+ function agentSkillStatusLabel(status) {
444
+ const labels = {
445
+ installed: "已安装",
446
+ outdated: "需更新",
447
+ missing: "未安装",
448
+ broken: "链接损坏",
449
+ conflict: "路径冲突",
450
+ };
451
+ return labels[status] ?? status;
452
+ }
453
+ function objectRecord(value) {
454
+ return value && typeof value === "object" && !Array.isArray(value)
455
+ ? value
456
+ : undefined;
457
+ }
458
+ function stringField(value, key) {
459
+ const field = value?.[key];
460
+ if (typeof field === "number" && Number.isFinite(field))
461
+ return String(field);
462
+ return typeof field === "string" && field.trim() ? field.trim() : undefined;
463
+ }
464
+ const TABLE_DESC_MAX = 72;
465
+ function truncateCell(s, max) {
466
+ if (s.length <= max)
467
+ return s;
468
+ return `${s.slice(0, max - 1)}…`;
469
+ }
470
+ function printTable(data) {
471
+ if (!Array.isArray(data)) {
472
+ printPretty(data);
473
+ return;
474
+ }
475
+ if (data.length === 0) {
476
+ console.log("(empty)");
477
+ return;
478
+ }
479
+ const keys = Object.keys(data[0]);
480
+ const table = new Table({ head: keys });
481
+ for (const row of data) {
482
+ const r = row;
483
+ table.push(keys.map((k) => {
484
+ const v = r[k];
485
+ const cell = v === null || v === undefined
486
+ ? ""
487
+ : typeof v === "object"
488
+ ? JSON.stringify(v)
489
+ : String(v);
490
+ const key = k.toLowerCase();
491
+ if (key === "description" || key === "desc" || k === "描述") {
492
+ return truncateCell(cell, TABLE_DESC_MAX);
493
+ }
494
+ return cell;
495
+ }));
496
+ }
497
+ console.log(table.toString());
498
+ }
499
+ /** 工具列表:扁平列,避免把整份 spec 打进表格 */
500
+ export function rowsForToolList(items) {
501
+ return items.map((item) => {
502
+ const i = item;
503
+ const spec = i.spec;
504
+ const id = String(i.id ?? i.name ?? spec?.name ?? "");
505
+ const desc = String(i.description ?? spec?.description ?? "");
506
+ const meta = capabilityMetadata("tool", id);
507
+ return {
508
+ id,
509
+ 名称: String(i.display_name ?? i.name ?? spec?.display_name ?? ""),
510
+ 分类: String(i.category ?? spec?.category ?? ""),
511
+ 状态: statusLabel(i.status ?? meta.status),
512
+ 描述: desc,
513
+ };
514
+ });
515
+ }
516
+ /** 应用列表 */
517
+ export function rowsForAppList(items) {
518
+ return items.map((item) => {
519
+ const i = item;
520
+ const spec = i.spec;
521
+ const id = String(i.id ?? spec?.id ?? "");
522
+ const desc = String(i.description ?? spec?.description ?? "");
523
+ const meta = capabilityMetadata("app", id);
524
+ return {
525
+ id,
526
+ 名称: String(i.display_name ?? i.name ?? spec?.name ?? ""),
527
+ 分类: String(i.category ?? spec?.category ?? ""),
528
+ 状态: statusLabel(i.status ?? meta.status),
529
+ 描述: desc,
530
+ };
531
+ });
532
+ }
533
+ /** 搜索结果(Tool + App 混合) */
534
+ export function rowsForSearchList(items) {
535
+ return items.map((item) => {
536
+ const i = item;
537
+ const spec = i.spec;
538
+ const desc = String(i.description ?? spec?.description ?? "");
539
+ return {
540
+ id: String(i.id ?? ""),
541
+ type: String(i.type ?? ""),
542
+ name: String(i.display_name ?? spec?.display_name ?? spec?.name ?? ""),
543
+ description: desc,
544
+ };
545
+ });
546
+ }
@@ -0,0 +1,26 @@
1
+ export type ModelType = "image" | "video";
2
+ export type ModelCostLevel = "低" | "中" | "高";
3
+ export interface ModelCatalogEntry {
4
+ type: ModelType;
5
+ name: string;
6
+ code: string;
7
+ description: string;
8
+ cost_level: ModelCostLevel;
9
+ aliases?: string[];
10
+ }
11
+ export interface PublicModelEntry {
12
+ name: string;
13
+ code: string;
14
+ description: string;
15
+ cost_level: ModelCostLevel;
16
+ }
17
+ export declare function parseModelType(value: unknown): ModelType;
18
+ export declare function listModels(type: ModelType): PublicModelEntry[];
19
+ export declare function modelEntriesForType(type: ModelType): ModelCatalogEntry[];
20
+ export declare function getDefaultModelOrder(type: ModelType): string[];
21
+ export declare function getConfiguredModel(type: ModelType): string;
22
+ export declare function setConfiguredModel(type: ModelType, model: string): string;
23
+ export declare function resolveModelOrder(type: ModelType, explicitModel?: string): string[];
24
+ export declare function resolveModelEntry(type: ModelType, value: string): ModelCatalogEntry;
25
+ export declare function publicModelByCode(type: ModelType, code: string): PublicModelEntry | undefined;
26
+ export declare function toPublicModelEntry(entry: ModelCatalogEntry): PublicModelEntry;