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.
- package/CHANGELOG.md +18 -0
- package/README.md +47 -64
- package/dist/bin/gd-cli.js +2 -2
- package/dist/src/api/app-runner.d.ts +1 -4
- package/dist/src/api/app-runner.js +10 -42
- package/dist/src/api/dam-client.d.ts +0 -7
- package/dist/src/api/dam-client.js +0 -17
- package/dist/src/commands/auth.js +5 -41
- package/dist/src/commands/creative.js +37 -45
- package/dist/src/commands/dam.js +248 -110
- package/dist/src/commands/org.js +17 -39
- package/dist/src/commands/skills.js +24 -114
- package/dist/src/commands/update.js +10 -85
- package/dist/src/commands/usage.js +4 -17
- package/dist/src/commands/workflows.d.ts +1 -1
- package/dist/src/commands/workflows.js +283 -199
- package/dist/src/core/output/envelope.d.ts +1 -0
- package/dist/src/core/output/envelope.js +76 -6
- package/dist/src/creative/contract.d.ts +28 -80
- package/dist/src/creative/contract.js +23 -44
- package/dist/src/creative/protocol.js +6 -6
- package/dist/src/io.d.ts +0 -2
- package/dist/src/io.js +0 -8
- package/dist/src/middleware/error-handler.d.ts +7 -1
- package/dist/src/middleware/error-handler.js +59 -54
- package/dist/src/program.d.ts +1 -0
- package/dist/src/program.js +138 -41
- package/dist/src/registry/agent-contracts.d.ts +14 -26
- package/dist/src/registry/agent-contracts.js +214 -64
- package/dist/src/utils/capability-presenter.js +6 -29
- package/dist/src/utils/config.d.ts +2 -2
- package/dist/src/utils/config.js +1 -1
- package/dist/src/utils/sensitive-path.js +1 -4
- package/package.json +2 -1
- package/skills/gd-cli/SKILL.md +6 -6
- package/skills/gd-cli/references/auth.md +3 -10
- package/skills/gd-cli/references/creative.md +11 -11
- package/skills/gd-cli/references/entitlement.md +2 -2
- package/skills/gd-cli/references/errors.md +4 -4
- package/skills/gd-cli/references/org.md +3 -3
- package/skills/gd-cli/references/sop.md +5 -5
- package/skills/gd-cli/references/update.md +4 -3
- package/skills/gd-cli/references/workflows.md +6 -5
- package/dist/src/utils/list-output-format.d.ts +0 -10
- package/dist/src/utils/list-output-format.js +0 -34
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,24 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/).
|
|
7
7
|
|
|
8
|
+
## [1.0.0-alpha.9] - 2026-08-01
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
|
|
12
|
+
- 根命令仅保留 `--version` 和 `--help`,机器可读的 `--json` 收敛到确有脚本消费价值的叶子命令。
|
|
13
|
+
- `skills install` 与 `skills uninstall` 在未指定目标时默认处理全部 Agent,且不再二次确认;`update` 收敛为无选项动作。
|
|
14
|
+
- Creative 使用语义化的 `question_message_id`,并收紧输入、输出 Schema 与错误响应契约。
|
|
15
|
+
- Workflow 固定内部并发为 2,并由 CLI 选项显式授权敏感路径。
|
|
16
|
+
|
|
17
|
+
### Removed
|
|
18
|
+
|
|
19
|
+
- 删除根级 `--format`、`--json`、`--no-input` 和 `--yes`,以及不再具有明确语义的重复输出选项。
|
|
20
|
+
|
|
21
|
+
### Security
|
|
22
|
+
|
|
23
|
+
- DAM 公开结果改为白名单 DTO,并过滤私网地址、危险协议、userinfo 与敏感查询参数。
|
|
24
|
+
- 公共错误响应改为字段白名单,不再透传后端 `detail` 或内部 Tool/App 路由信息。
|
|
25
|
+
|
|
8
26
|
## [1.0.0-alpha.8] - 2026-08-01
|
|
9
27
|
|
|
10
28
|
### Added
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# gaoding-cli
|
|
2
2
|
|
|
3
|
-
GD CLI 是稿定设计能力的命令行入口,为用户、脚本、CI 和 Agent
|
|
3
|
+
GD CLI 是稿定设计能力的命令行入口,为用户、脚本、CI 和 Agent 提供认证、组织切换、统一 Creative 创作、多步骤 Workflow 和 DAM 素材管理。
|
|
4
4
|
|
|
5
5
|
## Requirements
|
|
6
6
|
|
|
@@ -9,95 +9,91 @@ GD CLI 是稿定设计能力的命令行入口,为用户、脚本、CI 和 Age
|
|
|
9
9
|
|
|
10
10
|
## Installation
|
|
11
11
|
|
|
12
|
-
默认使用全局安装:
|
|
13
|
-
|
|
14
12
|
```bash
|
|
15
13
|
npm install -g gaoding-cli
|
|
16
14
|
gd-cli skills install
|
|
17
15
|
gd-cli auth login
|
|
18
16
|
```
|
|
19
17
|
|
|
20
|
-
Agent
|
|
18
|
+
`npm install -g gaoding-cli` 只安装 CLI。执行 `gd-cli skills install` 才会安装 Agent Skill;不传参数时安装到全部已知 Agent target。详细规则见[官方 Agent 安装文档](https://www.gaoding.com/cli/install.md)。
|
|
21
19
|
|
|
22
|
-
|
|
20
|
+
在 Agent 或 CI 中,可指定一个或多个 target;安装和卸载均为人类可读输出,用 `skills status --json` 检查机器状态:
|
|
23
21
|
|
|
24
22
|
```bash
|
|
25
|
-
gd-cli skills install --agent codex
|
|
26
|
-
gd-cli
|
|
23
|
+
gd-cli skills install --agent codex
|
|
24
|
+
gd-cli skills status --json
|
|
25
|
+
gd-cli auth login --no-browser
|
|
27
26
|
```
|
|
28
27
|
|
|
29
|
-
`npm install -g gaoding-cli` 只安装 CLI,不会修改任何 Agent 目录。只有显式执行 `gd-cli skills install` 才会安装 Agent Skill。
|
|
30
|
-
|
|
31
28
|
## Quick Start
|
|
32
29
|
|
|
33
30
|
```bash
|
|
34
|
-
gd-cli auth status
|
|
35
|
-
|
|
36
|
-
gd-cli org list
|
|
31
|
+
gd-cli auth status --json
|
|
32
|
+
gd-cli org list --json
|
|
37
33
|
gd-cli org switch --org <org-id>
|
|
38
34
|
|
|
39
|
-
gd-cli creative schema --
|
|
40
|
-
gd-cli creative examples
|
|
41
|
-
gd-cli creative run --prompt "为夏季运动鞋生成一张户外通勤广告图" --
|
|
35
|
+
gd-cli creative schema --json
|
|
36
|
+
gd-cli creative examples
|
|
37
|
+
gd-cli creative run --prompt "为夏季运动鞋生成一张户外通勤广告图" --json
|
|
42
38
|
|
|
43
|
-
gd-cli workflows list
|
|
39
|
+
gd-cli workflows list --json
|
|
44
40
|
gd-cli workflows run listing-gallery \
|
|
45
41
|
--image ./product.jpg \
|
|
46
|
-
--brief "夏季运动鞋,轻量缓震,适合通勤"
|
|
42
|
+
--brief "夏季运动鞋,轻量缓震,适合通勤" \
|
|
43
|
+
--json
|
|
47
44
|
|
|
48
|
-
gd-cli dam upload ./product.jpg
|
|
45
|
+
gd-cli dam upload ./product.jpg --json
|
|
49
46
|
```
|
|
50
47
|
|
|
51
48
|
## Commands
|
|
52
49
|
|
|
50
|
+
使用 `gd-cli --help` 查看一级命令,再使用 `gd-cli <command> --help` 查看子命令和选项。
|
|
51
|
+
|
|
53
52
|
| Command | Purpose |
|
|
54
53
|
| --- | --- |
|
|
55
|
-
| `auth` |
|
|
56
|
-
| `
|
|
57
|
-
| `
|
|
58
|
-
| `
|
|
59
|
-
| `
|
|
60
|
-
| `
|
|
61
|
-
| `
|
|
62
|
-
| `
|
|
54
|
+
| `auth login [--no-browser]` | 登录;输出面向人 |
|
|
55
|
+
| `auth logout` | 退出登录;输出面向人 |
|
|
56
|
+
| `auth status --json` | 查询认证状态 |
|
|
57
|
+
| `org list/current/credits --json` | 查询组织和稿豆余额 |
|
|
58
|
+
| `org switch [--org]` | 切换组织;输出面向人 |
|
|
59
|
+
| `creative run [--prompt|--input] [--json]` | 发起或继续创作 |
|
|
60
|
+
| `creative schema [--json]` | 查看创作 Schema |
|
|
61
|
+
| `creative examples` | 查看完整可运行示例 |
|
|
62
|
+
| `workflows list [--json]` | 列出 Workflow |
|
|
63
|
+
| `workflows schema <workflow-id> [--json]` | 查看 Workflow Schema |
|
|
64
|
+
| `workflows examples <workflow-id>` | 查看完整可运行示例 |
|
|
65
|
+
| `workflows run <workflow-id> [--json]` | 执行 Workflow |
|
|
66
|
+
| `skills install/uninstall [--agent <id> | --all]` | 管理 Agent Skill |
|
|
67
|
+
| `skills status --json` | 查询 Skill 状态 |
|
|
68
|
+
| `skills update` | 刷新已安装 Skill |
|
|
69
|
+
| `dam upload/list/search/get --json` | 管理和查询素材 |
|
|
70
|
+
| `dam delete` | 删除素材;输出面向人 |
|
|
71
|
+
| `update` | 检查并升级全局 CLI |
|
|
72
|
+
|
|
73
|
+
默认不会因为 stdin/stdout 不是 TTY 而切换为 JSON。只有支持 `--json` 的叶命令在显式传入该选项时才输出机器可读结果。
|
|
63
74
|
|
|
64
75
|
## Agent And Script Usage
|
|
65
76
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
Creative 的完整输入和输出结构使用本地静态 Schema 发现:
|
|
77
|
+
Creative 使用 `--prompt` 或 `--input`。媒体、结构化约束或连续会话输入使用 JSON 文件或 stdin:
|
|
69
78
|
|
|
70
79
|
```bash
|
|
71
|
-
gd-cli creative
|
|
72
|
-
gd-cli creative
|
|
80
|
+
gd-cli creative run --prompt "为夏季运动鞋生成三条简洁的电商标题" --json
|
|
81
|
+
gd-cli creative run --input creative-request.json --json
|
|
82
|
+
cat creative-request.json | gd-cli creative run --input - --json
|
|
73
83
|
```
|
|
74
84
|
|
|
75
|
-
|
|
85
|
+
遇到 `finish_reason=requires_input` 时,回传结果中的 `conversation_id`、`question_message_id` 和 `answers`。完整字段由 `gd-cli creative schema --json` 定义。
|
|
76
86
|
|
|
77
|
-
|
|
78
|
-
gd-cli creative run --prompt "为夏季运动鞋生成三条简洁的电商标题" --format json
|
|
79
|
-
gd-cli creative run --input creative-request.json --format json
|
|
80
|
-
cat creative-request.json | gd-cli creative run --input - --format json
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
多步骤交付使用 `workflows run`:
|
|
84
|
-
|
|
85
|
-
```bash
|
|
86
|
-
gd-cli workflows run listing-gallery \
|
|
87
|
-
--image ./product.jpg \
|
|
88
|
-
--brief "运动鞋上架素材包" \
|
|
89
|
-
--output-dir ./output \
|
|
90
|
-
--format json
|
|
91
|
-
```
|
|
87
|
+
Workflow 的可用场景可通过 `gd-cli workflows list --json` 查看;特定输入/输出通过 `gd-cli workflows schema <workflow-id> --json` 查看。
|
|
92
88
|
|
|
93
89
|
## Agent Skill
|
|
94
90
|
|
|
95
|
-
`gd-cli skills install` 将静态 Skill 安装到 `~/.agents/skills/gd-cli
|
|
91
|
+
`gd-cli skills install` 将静态 Skill 安装到 `~/.agents/skills/gd-cli`,并为选择的 Agent 创建链接。常用维护命令:
|
|
96
92
|
|
|
97
93
|
```bash
|
|
98
|
-
gd-cli skills status --
|
|
94
|
+
gd-cli skills status --json
|
|
99
95
|
gd-cli skills update
|
|
100
|
-
gd-cli skills uninstall --all
|
|
96
|
+
gd-cli skills uninstall --all
|
|
101
97
|
```
|
|
102
98
|
|
|
103
99
|
CLI 全局升级后,只在 canonical Skill 已安装时自动刷新它;本地项目安装、`npm link` 和 `npx` 运行不会修改全局 CLI。
|
|
@@ -109,23 +105,10 @@ npm install
|
|
|
109
105
|
npm run build
|
|
110
106
|
npm test
|
|
111
107
|
npm run start -- --help
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
本地开发使用独立的 `gd-cli-dev`:
|
|
115
|
-
|
|
116
|
-
```bash
|
|
117
|
-
npm run dev:setup
|
|
118
|
-
npm run dev
|
|
119
|
-
gd-cli-dev --help
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
默认 smoke test 不登录、不调用付费生成能力:
|
|
123
|
-
|
|
124
|
-
```bash
|
|
125
108
|
npm run smoke:cli
|
|
126
109
|
```
|
|
127
110
|
|
|
128
|
-
|
|
111
|
+
真实接口 smoke 会使用本机登录凭证,并可能消耗额度:
|
|
129
112
|
|
|
130
113
|
```bash
|
|
131
114
|
gd-cli auth login
|
package/dist/bin/gd-cli.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { createProgram } from "../src/program.js";
|
|
2
|
+
import { createProgram, parseProgram } from "../src/program.js";
|
|
3
3
|
async function main() {
|
|
4
4
|
const program = await createProgram();
|
|
5
|
-
await program
|
|
5
|
+
await parseProgram(program, process.argv);
|
|
6
6
|
}
|
|
7
7
|
main().catch((err) => {
|
|
8
8
|
console.error(err.message);
|
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
import { HubClient } from "./hub-client.js";
|
|
2
2
|
import type { TaskResult } from "./task-poller.js";
|
|
3
3
|
interface RunOptions {
|
|
4
|
-
|
|
5
|
-
timeout?: number;
|
|
6
|
-
outputDir?: string;
|
|
7
|
-
concurrency?: number;
|
|
4
|
+
allowSensitivePath?: boolean;
|
|
8
5
|
onStepStart?: (step: AppStepPublicRecord) => void;
|
|
9
6
|
onStepComplete?: (step: AppStepPublicRecord, result?: TaskResult) => void;
|
|
10
7
|
}
|
|
@@ -1,23 +1,5 @@
|
|
|
1
1
|
import { DirectToolInvoker } from "./direct-tools.js";
|
|
2
2
|
import { DirectApiError } from "./direct-client.js";
|
|
3
|
-
/** 多步 App 含多次生图/对话,默认至少等待 10 分钟 */
|
|
4
|
-
const APP_RUN_MIN_WAIT_SEC = 600;
|
|
5
|
-
function resolveAppWaitTimeout(explicit, estimatedSeconds) {
|
|
6
|
-
if (explicit !== undefined && Number.isFinite(explicit) && explicit > 0) {
|
|
7
|
-
return Math.floor(explicit);
|
|
8
|
-
}
|
|
9
|
-
const est = Number(estimatedSeconds);
|
|
10
|
-
if (Number.isFinite(est) && est > APP_RUN_MIN_WAIT_SEC) {
|
|
11
|
-
return Math.ceil(est);
|
|
12
|
-
}
|
|
13
|
-
return APP_RUN_MIN_WAIT_SEC;
|
|
14
|
-
}
|
|
15
|
-
function resolveConcurrency(value) {
|
|
16
|
-
const numeric = Number(value);
|
|
17
|
-
if (!Number.isFinite(numeric) || numeric <= 0)
|
|
18
|
-
return 2;
|
|
19
|
-
return Math.max(1, Math.min(4, Math.floor(numeric)));
|
|
20
|
-
}
|
|
21
3
|
async function mapWithConcurrency(items, concurrency, worker) {
|
|
22
4
|
let next = 0;
|
|
23
5
|
const runners = Array.from({ length: Math.min(concurrency, items.length) }, async () => {
|
|
@@ -170,15 +152,6 @@ export class AppRunner {
|
|
|
170
152
|
void client;
|
|
171
153
|
}
|
|
172
154
|
async run(appId, params, options = {}) {
|
|
173
|
-
if (options.async) {
|
|
174
|
-
return {
|
|
175
|
-
task_id: `app-${appId}-${Date.now()}`,
|
|
176
|
-
status: "failed",
|
|
177
|
-
message: "本地 App workflow 暂不支持 --async,请去掉 --async 直接运行。",
|
|
178
|
-
};
|
|
179
|
-
}
|
|
180
|
-
void resolveAppWaitTimeout(options.timeout, undefined);
|
|
181
|
-
void options.outputDir;
|
|
182
155
|
try {
|
|
183
156
|
if (appId === "listing-gallery")
|
|
184
157
|
return await this.runListingGallery(params, options);
|
|
@@ -208,7 +181,7 @@ export class AppRunner {
|
|
|
208
181
|
detail_image: "4:5",
|
|
209
182
|
lifestyle_image: "4:5",
|
|
210
183
|
});
|
|
211
|
-
const prepared = await this.prepareProduct(ctx, image, allowSensitivePath
|
|
184
|
+
const prepared = await this.prepareProduct(ctx, image, options.allowSensitivePath === true);
|
|
212
185
|
const title = await this.generateTitle(ctx, brief);
|
|
213
186
|
const titleText = outputString(title, "text", false) || brief;
|
|
214
187
|
const promptPlan = await this.optimizePrompt(ctx, "prompt_plan", "生成图库素材规划", `为电商 Listing 图库生成素材规划:${brief}。品类判断:${profile.label}。需要覆盖白底主图、单卖点证明图、材质/结构细节图、生活方式图;${copyPlanningGuidance(copyPlan)}每张图只回答一个购买问题,不生成假认证和不可验证参数。`, prepared.cutoutUrl, `Listing 图库素材规划:主图、卖点图、细节图、生活方式图。品类:${profile.label}。商品卖点:${brief}`);
|
|
@@ -310,7 +283,7 @@ export class AppRunner {
|
|
|
310
283
|
overlayCopy: overlayCopy.lifestyle_image,
|
|
311
284
|
}),
|
|
312
285
|
},
|
|
313
|
-
]
|
|
286
|
+
]);
|
|
314
287
|
return ctx.completed();
|
|
315
288
|
}
|
|
316
289
|
async runPdpAPlus(params, options) {
|
|
@@ -326,7 +299,7 @@ export class AppRunner {
|
|
|
326
299
|
usage_module: "4:5",
|
|
327
300
|
comparison_module: "1:1",
|
|
328
301
|
});
|
|
329
|
-
const prepared = await this.prepareProduct(ctx, image, allowSensitivePath
|
|
302
|
+
const prepared = await this.prepareProduct(ctx, image, options.allowSensitivePath === true);
|
|
330
303
|
const title = await this.generateTitle(ctx, brief);
|
|
331
304
|
const titleText = outputString(title, "text", false) || brief;
|
|
332
305
|
const promptPlan = await this.optimizePrompt(ctx, "prompt_plan", "生成详情页模块规划", `为电商详情页/A+模块生成购买说服顺序:${brief}。品类判断:${profile.label}。模块包含首屏、痛点解决、结构/细节证明、真实使用场景、对比规格;${copyPlanningGuidance(copyPlan)}不编造参数和认证。`, prepared.cutoutUrl, `详情页模块规划:首屏、痛点、结构细节、使用场景、对比规格。品类:${profile.label}。商品信息:${brief}`);
|
|
@@ -451,7 +424,7 @@ export class AppRunner {
|
|
|
451
424
|
overlayCopy: overlayCopy.comparison_module,
|
|
452
425
|
}),
|
|
453
426
|
},
|
|
454
|
-
]
|
|
427
|
+
]);
|
|
455
428
|
return ctx.completed();
|
|
456
429
|
}
|
|
457
430
|
async runSocialSeedingPack(params, options) {
|
|
@@ -464,7 +437,7 @@ export class AppRunner {
|
|
|
464
437
|
cover_image: "3:4",
|
|
465
438
|
scene_image: "9:16",
|
|
466
439
|
});
|
|
467
|
-
const prepared = await this.prepareProduct(ctx, image, allowSensitivePath
|
|
440
|
+
const prepared = await this.prepareProduct(ctx, image, options.allowSensitivePath === true);
|
|
468
441
|
const title = await this.generateTitle(ctx, brief);
|
|
469
442
|
const titleText = outputString(title, "text", false) || brief;
|
|
470
443
|
const xhsCaption = buildXhsCaption(titleText, brief);
|
|
@@ -534,7 +507,7 @@ export class AppRunner {
|
|
|
534
507
|
overlayCopy: overlayCopy.scene_image,
|
|
535
508
|
}),
|
|
536
509
|
},
|
|
537
|
-
]
|
|
510
|
+
]);
|
|
538
511
|
return ctx.completed();
|
|
539
512
|
}
|
|
540
513
|
async runCampaignKvPack(params, options) {
|
|
@@ -544,7 +517,7 @@ export class AppRunner {
|
|
|
544
517
|
const ratios = parseRatioList(params.ratios ?? params.ratio, ["16:9", "1:1", "4:5"]);
|
|
545
518
|
const profile = inferProductCategoryProfile(brief);
|
|
546
519
|
const copyPlan = resolveCopyPlan(params, brief);
|
|
547
|
-
const prepared = await this.prepareProduct(ctx, image, allowSensitivePath
|
|
520
|
+
const prepared = await this.prepareProduct(ctx, image, options.allowSensitivePath === true);
|
|
548
521
|
const title = await this.generateTitle(ctx, brief);
|
|
549
522
|
const titleText = outputString(title, "text", false) || brief;
|
|
550
523
|
const promptPlan = await this.optimizePrompt(ctx, "prompt_plan", "生成 Campaign KV 主视觉提示词", `为新品 Campaign KV 生成${copyPlan.mode === "no-text" ? "无字主视觉" : "可直接投放主视觉"}提示词:${brief}。品类判断:${profile.label}。要求一个清晰记忆符号,可裁切到官网、社媒、电商活动和投放;${copyPlanningGuidance(copyPlan)}不改 logo、不生成假促销标。`, prepared.cutoutUrl, copyPlan.mode === "no-text"
|
|
@@ -595,11 +568,11 @@ export class AppRunner {
|
|
|
595
568
|
overlayCopy: String(overlayCopy[key] ?? ""),
|
|
596
569
|
}),
|
|
597
570
|
};
|
|
598
|
-
})
|
|
571
|
+
}));
|
|
599
572
|
return ctx.completed();
|
|
600
573
|
}
|
|
601
|
-
async generateImageJobs(ctx, jobs
|
|
602
|
-
await mapWithConcurrency(jobs,
|
|
574
|
+
async generateImageJobs(ctx, jobs) {
|
|
575
|
+
await mapWithConcurrency(jobs, 2, async (job) => {
|
|
603
576
|
const result = await this.generateImage(ctx, job.key, job.stepName, job.prompt, job.image, job.ratio, job.model);
|
|
604
577
|
ctx.outputs[job.key] = result.outputs;
|
|
605
578
|
ctx.addAsset(job.label, job.key, result);
|
|
@@ -1159,11 +1132,6 @@ function optionalString(value) {
|
|
|
1159
1132
|
const normalized = value.trim();
|
|
1160
1133
|
return normalized ? normalized : undefined;
|
|
1161
1134
|
}
|
|
1162
|
-
function allowSensitivePath(params) {
|
|
1163
|
-
return (params.allow_sensitive_path === true ||
|
|
1164
|
-
params.allowSensitivePath === true ||
|
|
1165
|
-
params["allow-sensitive-path"] === true);
|
|
1166
|
-
}
|
|
1167
1135
|
function outputString(result, key, required = true) {
|
|
1168
1136
|
const outputs = result.outputs;
|
|
1169
1137
|
const value = outputs?.[key];
|
|
@@ -42,7 +42,6 @@ export interface DamSearchOptions {
|
|
|
42
42
|
pageSize?: number;
|
|
43
43
|
page?: number;
|
|
44
44
|
cursor?: string;
|
|
45
|
-
raw?: boolean;
|
|
46
45
|
allowEmptyKeyword?: boolean;
|
|
47
46
|
}
|
|
48
47
|
export interface DamSearchAsset {
|
|
@@ -74,12 +73,6 @@ export interface DamSearchResult {
|
|
|
74
73
|
finish: boolean;
|
|
75
74
|
next_cursor?: string;
|
|
76
75
|
assets: DamSearchAsset[];
|
|
77
|
-
debug?: {
|
|
78
|
-
source: {
|
|
79
|
-
endpoint: string;
|
|
80
|
-
raw?: unknown;
|
|
81
|
-
};
|
|
82
|
-
};
|
|
83
76
|
}
|
|
84
77
|
interface DamCover {
|
|
85
78
|
url?: string;
|
|
@@ -4,7 +4,6 @@ import { basename, extname, resolve } from "node:path";
|
|
|
4
4
|
import OSS from "ali-oss";
|
|
5
5
|
import sharp from "sharp";
|
|
6
6
|
import { DirectApiClient, DirectApiError, unwrapEnvelope } from "./direct-client.js";
|
|
7
|
-
import { isDebug, isVerbose } from "../utils/config.js";
|
|
8
7
|
import { assertSafeUploadPath } from "../utils/sensitive-path.js";
|
|
9
8
|
import { assertSafeHttpUrl } from "../utils/url-safety.js";
|
|
10
9
|
import { redactSensitiveText } from "../utils/redact.js";
|
|
@@ -140,12 +139,9 @@ export class DamClient {
|
|
|
140
139
|
try {
|
|
141
140
|
const response = await this.client.post("/dam/asset/v2/search/simple", payload);
|
|
142
141
|
return normalizeSearchResponse(response, {
|
|
143
|
-
endpoint: "/dam/asset/v2/search/simple",
|
|
144
142
|
query,
|
|
145
143
|
repositoryIds,
|
|
146
144
|
payload,
|
|
147
|
-
includeDebug: options.raw === true || isVerbose() || isDebug(),
|
|
148
|
-
includeRaw: options.raw === true,
|
|
149
145
|
});
|
|
150
146
|
}
|
|
151
147
|
catch (error) {
|
|
@@ -153,12 +149,9 @@ export class DamClient {
|
|
|
153
149
|
throw error;
|
|
154
150
|
const response = await this.client.post("/dam/asset/search", payload);
|
|
155
151
|
return normalizeSearchResponse(response, {
|
|
156
|
-
endpoint: "/dam/asset/search",
|
|
157
152
|
query,
|
|
158
153
|
repositoryIds,
|
|
159
154
|
payload,
|
|
160
|
-
includeDebug: options.raw === true || isVerbose() || isDebug(),
|
|
161
|
-
includeRaw: options.raw === true,
|
|
162
155
|
});
|
|
163
156
|
}
|
|
164
157
|
}
|
|
@@ -307,16 +300,6 @@ function normalizeSearchResponse(response, context) {
|
|
|
307
300
|
finish,
|
|
308
301
|
next_cursor: nextCursor,
|
|
309
302
|
assets: rawItems.map(normalizeSearchAsset).filter((item) => item.asset_id),
|
|
310
|
-
...(context.includeDebug
|
|
311
|
-
? {
|
|
312
|
-
debug: {
|
|
313
|
-
source: {
|
|
314
|
-
endpoint: context.endpoint,
|
|
315
|
-
...(context.includeRaw ? { raw: response } : {}),
|
|
316
|
-
},
|
|
317
|
-
},
|
|
318
|
-
}
|
|
319
|
-
: {}),
|
|
320
303
|
};
|
|
321
304
|
}
|
|
322
305
|
function extractSearchContainer(value) {
|
|
@@ -3,10 +3,7 @@ import { withErrorHandler } from "../middleware/error-handler.js";
|
|
|
3
3
|
import { createAuthProvider } from "../core/auth/auth-provider.js";
|
|
4
4
|
import { CredentialStoreV2 } from "../auth/credential-store-v2.js";
|
|
5
5
|
import { resolveEndpoints, isVerbose, isDebug } from "../utils/config.js";
|
|
6
|
-
import { getIO } from "../io.js";
|
|
7
6
|
import { emitJson, wrapEnvelope } from "../core/output/envelope.js";
|
|
8
|
-
import { setStaticHelp } from "../utils/static-help.js";
|
|
9
|
-
import { resolveInvokeOutputFormat } from "../utils/list-output-format.js";
|
|
10
7
|
import { setAuthRequirement } from "../middleware/auth.js";
|
|
11
8
|
const loginAction = withErrorHandler(async (options) => {
|
|
12
9
|
if (isVerbose() || isDebug()) {
|
|
@@ -15,22 +12,8 @@ const loginAction = withErrorHandler(async (options) => {
|
|
|
15
12
|
}
|
|
16
13
|
const provider = await createAuthProvider();
|
|
17
14
|
const result = await provider.login({
|
|
18
|
-
|
|
19
|
-
noBrowser: !!options.noBrowser,
|
|
20
|
-
scope: options.scope,
|
|
21
|
-
env: options.env,
|
|
15
|
+
noBrowser: options.browser === false,
|
|
22
16
|
});
|
|
23
|
-
const io = getIO();
|
|
24
|
-
if (io.prefersJsonOutput()) {
|
|
25
|
-
emitJson(wrapEnvelope({
|
|
26
|
-
mode: provider.mode,
|
|
27
|
-
logged_in: true,
|
|
28
|
-
user: result.credentials.user,
|
|
29
|
-
org: result.org,
|
|
30
|
-
next_steps: result.org ? [] : ["gd-cli org switch"],
|
|
31
|
-
}, { command: "auth login" }));
|
|
32
|
-
return;
|
|
33
|
-
}
|
|
34
17
|
console.log(chalk.green("\n✓ 授权成功,可以开始使用稿定能力进行创意生产\n"));
|
|
35
18
|
if (!result.org) {
|
|
36
19
|
console.log(chalk.yellow(" 尚未选择当前组织,请执行 gd-cli org switch 后再调用 Creative / Workflows / DAM。"));
|
|
@@ -38,13 +21,12 @@ const loginAction = withErrorHandler(async (options) => {
|
|
|
38
21
|
});
|
|
39
22
|
const statusAction = withErrorHandler(async (_opts, command) => {
|
|
40
23
|
const cmd = command;
|
|
41
|
-
const
|
|
42
|
-
const io = getIO();
|
|
24
|
+
const json = cmd.opts().json === true;
|
|
43
25
|
const store = new CredentialStoreV2();
|
|
44
26
|
const creds = store.read();
|
|
45
27
|
const ep = resolveEndpoints();
|
|
46
28
|
if (!creds) {
|
|
47
|
-
if (
|
|
29
|
+
if (json) {
|
|
48
30
|
emitJson(wrapEnvelope({
|
|
49
31
|
logged_in: false,
|
|
50
32
|
environment: { active: ep.active_env },
|
|
@@ -57,7 +39,7 @@ const statusAction = withErrorHandler(async (_opts, command) => {
|
|
|
57
39
|
return;
|
|
58
40
|
}
|
|
59
41
|
const payload = buildStatusPayload(creds, store);
|
|
60
|
-
if (
|
|
42
|
+
if (json) {
|
|
61
43
|
emitJson(wrapEnvelope(payload, { command: "auth status" }));
|
|
62
44
|
return;
|
|
63
45
|
}
|
|
@@ -67,24 +49,15 @@ const logoutAction = withErrorHandler(async () => {
|
|
|
67
49
|
const provider = await createAuthProvider();
|
|
68
50
|
await provider.logout();
|
|
69
51
|
new CredentialStoreV2().delete();
|
|
70
|
-
const io = getIO();
|
|
71
|
-
if (io.prefersJsonOutput()) {
|
|
72
|
-
emitJson(wrapEnvelope({ logged_out: true }, { command: "auth logout" }));
|
|
73
|
-
return;
|
|
74
|
-
}
|
|
75
52
|
console.log(chalk.green("✓ 已取消授权,可以重新执行 gd-cli auth login 进行授权。\n"));
|
|
76
53
|
});
|
|
77
54
|
export function registerAuthCommand(program) {
|
|
78
55
|
const auth = program
|
|
79
56
|
.command("auth")
|
|
80
57
|
.description("登录、退出、查看登录状态");
|
|
81
|
-
setStaticHelp(auth, AUTH_HELP);
|
|
82
58
|
const login = auth
|
|
83
59
|
.command("login")
|
|
84
60
|
.description("浏览器/扫码授权登录")
|
|
85
|
-
.option("--org <org-id>", "登录后直接选择当前组织")
|
|
86
|
-
.option("--env <env>", "环境标识 cursor / claude / ci")
|
|
87
|
-
.option("--scope <scope>", "授权范围,逗号分隔")
|
|
88
61
|
.option("--no-browser", "不自动打开浏览器")
|
|
89
62
|
.action(loginAction);
|
|
90
63
|
setAuthRequirement(login, "none");
|
|
@@ -96,19 +69,10 @@ export function registerAuthCommand(program) {
|
|
|
96
69
|
const status = auth
|
|
97
70
|
.command("status")
|
|
98
71
|
.description("查看授权状态")
|
|
72
|
+
.option("--json", "输出机器可读 JSON")
|
|
99
73
|
.action(statusAction);
|
|
100
74
|
setAuthRequirement(status, "none");
|
|
101
75
|
}
|
|
102
|
-
const AUTH_HELP = `
|
|
103
|
-
Usage: gd-cli auth [options] [command]
|
|
104
|
-
|
|
105
|
-
登录、退出、查看登录状态
|
|
106
|
-
|
|
107
|
-
Commands:
|
|
108
|
-
login 浏览器/扫码授权登录
|
|
109
|
-
logout 取消授权
|
|
110
|
-
status 查看授权状态
|
|
111
|
-
`;
|
|
112
76
|
function buildStatusPayload(creds, store) {
|
|
113
77
|
const ep = resolveEndpoints();
|
|
114
78
|
const credentialExpired = store.isAkExpired();
|