@optima-chat/comfy-cli 0.9.8 → 0.9.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.
@@ -72,7 +72,25 @@
72
72
  "Bash(infisical secrets:*)",
73
73
  "Bash(git status:*)",
74
74
  "Bash(gh pr:*)",
75
- "Bash(git merge:*)"
75
+ "Bash(git merge:*)",
76
+ "WebFetch(domain:docs.fashn.ai)",
77
+ "WebFetch(domain:fashn.ai)",
78
+ "Bash(head -50 /Users/verypro/comfy-cli/tests/*.test.ts)",
79
+ "Bash(curl -s https://raw.githubusercontent.com/fashn-AI/tryon-nextjs-app/main/README.md)",
80
+ "Bash(curl -s https://raw.githubusercontent.com/fashn-AI/tryon-gradio-app/main/README.md)",
81
+ "Bash(curl -s https://api.github.com/repos/fashn-AI/tryon-nextjs-app/contents/)",
82
+ "Bash(curl -s https://api.github.com/repos/fashn-AI/tryon-gradio-app/contents/)",
83
+ "Bash(curl -s https://api.github.com/repos/fashn-AI/tryon-nextjs-app/contents/public)",
84
+ "Bash(curl -s https://api.github.com/repos/fashn-AI/tryon-nextjs-app/contents/src)",
85
+ "Bash(curl -s https://api.github.com/repos/fashn-AI/tryon-gradio-app/contents/assets)",
86
+ "Bash(curl -s https://api.github.com/repos/fashn-AI/tryon-nextjs-app/contents/public/models)",
87
+ "Bash(curl -s https://api.github.com/repos/fashn-AI/tryon-nextjs-app/contents/public/garments)",
88
+ "Bash(curl -s https://api.github.com/repos/fashn-AI/tryon-gradio-app/contents/assets/models)",
89
+ "Bash(curl -s https://api.github.com/repos/fashn-AI/tryon-gradio-app/contents/assets/garments)",
90
+ "Bash(curl -sL \"https://raw.githubusercontent.com/fashn-AI/tryon-gradio-app/master/assets/models/fashn-ai-model.jpeg\" -o /tmp/tryon_model.jpeg)",
91
+ "Bash(curl -sL \"https://raw.githubusercontent.com/fashn-AI/tryon-gradio-app/master/assets/garments/fashn-ai-t.png\" -o /tmp/tryon_garment.png)",
92
+ "Bash(magick /tmp/tryon_model.jpeg /tmp/tryon_garment.png /Users/verypro/comfy-cli/comfy-output/tryon_1773922873475_0.png -resize x800 +append /tmp/tryon_comparison.png)",
93
+ "Bash(open /tmp/tryon_comparison.png)"
76
94
  ],
77
95
  "deny": [],
78
96
  "ask": []
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare function registerTryonCommand(program: Command): void;
3
+ //# sourceMappingURL=tryon.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tryon.d.ts","sourceRoot":"","sources":["../../src/commands/tryon.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AASpC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,QA6KpD"}
@@ -0,0 +1,170 @@
1
+ import * as path from 'path';
2
+ import ora from 'ora';
3
+ import { success, info } from '../utils/logger.js';
4
+ import { outputSuccess, outputError, isPrettyMode } from '../utils/output.js';
5
+ import { addEnhancedHelp } from '../utils/helpText.js';
6
+ import { getConfigValue } from '../services/config.js';
7
+ import { FashnClient } from '../services/fashn-api.js';
8
+ export function registerTryonCommand(program) {
9
+ const cmd = program
10
+ .command('tryon')
11
+ .description('虚拟试穿 (Virtual Try-On) - 使用 FASHN AI tryon-v1.6')
12
+ .argument('<model_image>', '人物照片路径或 URL')
13
+ .argument('<garment_image>', '服装照片路径或 URL')
14
+ .option('-o, --output <path>', '输出文件路径', '')
15
+ .option('-c, --category <type>', '服装类别: auto, tops, bottoms, one-pieces', 'auto')
16
+ .option('-m, --mode <mode>', '生成模式: performance (~7s), balanced (~9s), quality (~13s)', 'quality')
17
+ .option('--garment-type <type>', '服装照片类型: auto, flat-lay, model', 'auto')
18
+ .option('-n, --num-samples <n>', '生成数量 (1-4)', '1')
19
+ .option('--format <fmt>', '输出格式: png, jpeg', 'png')
20
+ .option('--seed <n>', '随机种子(用于复现)')
21
+ .action(async (modelImage, garmentImage, options) => {
22
+ const pretty = isPrettyMode(options);
23
+ try {
24
+ // 获取 API Key
25
+ const apiKey = process.env.FASHN_API_KEY || getConfigValue('fashn.apiKey');
26
+ if (!apiKey) {
27
+ outputError('API_KEY_MISSING', '请设置 FASHN_API_KEY 环境变量或运行: comfy config set fashn.apiKey <key>', options);
28
+ return;
29
+ }
30
+ const client = new FashnClient(apiKey);
31
+ // 处理图像输入:本地文件转 base64,URL 直接使用
32
+ const resolveImage = async (input) => {
33
+ if (input.startsWith('http://') || input.startsWith('https://')) {
34
+ return input;
35
+ }
36
+ return client.imageToBase64(input);
37
+ };
38
+ const [modelImg, garmentImg] = await Promise.all([
39
+ resolveImage(modelImage),
40
+ resolveImage(garmentImage),
41
+ ]);
42
+ const numSamples = parseInt(options.numSamples, 10);
43
+ const outputDir = getConfigValue('outputDir') || './comfy-output';
44
+ const startTime = Date.now();
45
+ if (pretty) {
46
+ const spinner = ora(`正在提交虚拟试穿任务 (${options.mode} 模式)...`).start();
47
+ try {
48
+ const runResult = await client.run({
49
+ model_image: modelImg,
50
+ garment_image: garmentImg,
51
+ category: options.category,
52
+ mode: options.mode,
53
+ garment_photo_type: options.garmentType,
54
+ num_samples: numSamples,
55
+ output_format: options.format,
56
+ seed: options.seed ? parseInt(options.seed, 10) : undefined,
57
+ });
58
+ spinner.text = `任务已提交 (${runResult.id}),等待生成...`;
59
+ const result = await client.poll(runResult.id, {
60
+ onProgress: (status) => {
61
+ spinner.text = `状态: ${status}...`;
62
+ },
63
+ });
64
+ // 下载输出图像
65
+ const outputs = [];
66
+ if (result.output) {
67
+ spinner.text = '正在下载结果图像...';
68
+ for (let i = 0; i < result.output.length; i++) {
69
+ const outputPath = options.output && result.output.length === 1
70
+ ? path.resolve(options.output)
71
+ : path.resolve(outputDir, `tryon_${Date.now()}_${i}.${options.format}`);
72
+ const saved = await client.downloadImage(result.output[i], path.dirname(outputPath), path.basename(outputPath));
73
+ outputs.push(saved);
74
+ }
75
+ }
76
+ const durationMs = Date.now() - startTime;
77
+ spinner.succeed('虚拟试穿完成!');
78
+ for (const out of outputs) {
79
+ success(`输出文件: ${out}`);
80
+ }
81
+ info(`模式: ${options.mode}, 类别: ${options.category}, 耗时: ${(durationMs / 1000).toFixed(1)}s`);
82
+ }
83
+ catch (err) {
84
+ spinner.fail(`试穿失败: ${err?.message || err}`);
85
+ throw err;
86
+ }
87
+ }
88
+ else {
89
+ const runResult = await client.run({
90
+ model_image: modelImg,
91
+ garment_image: garmentImg,
92
+ category: options.category,
93
+ mode: options.mode,
94
+ garment_photo_type: options.garmentType,
95
+ num_samples: numSamples,
96
+ output_format: options.format,
97
+ seed: options.seed ? parseInt(options.seed, 10) : undefined,
98
+ });
99
+ const result = await client.poll(runResult.id);
100
+ // 下载输出图像
101
+ const outputs = [];
102
+ if (result.output) {
103
+ for (let i = 0; i < result.output.length; i++) {
104
+ const outputPath = options.output && result.output.length === 1
105
+ ? path.resolve(options.output)
106
+ : path.resolve(outputDir, `tryon_${Date.now()}_${i}.${options.format}`);
107
+ const saved = await client.downloadImage(result.output[i], path.dirname(outputPath), path.basename(outputPath));
108
+ outputs.push(saved);
109
+ }
110
+ }
111
+ const durationMs = Date.now() - startTime;
112
+ outputSuccess({
113
+ id: runResult.id,
114
+ outputs,
115
+ mode: options.mode,
116
+ category: options.category,
117
+ numSamples,
118
+ durationMs,
119
+ });
120
+ }
121
+ }
122
+ catch (err) {
123
+ outputError('TRYON_FAILED', `虚拟试穿失败: ${err}`, options);
124
+ }
125
+ });
126
+ addEnhancedHelp(cmd, {
127
+ examples: [
128
+ '# 基本用法 - 本地图片试穿',
129
+ '$ comfy tryon person.jpg garment.jpg',
130
+ '',
131
+ '# 使用 URL 图片',
132
+ '$ comfy tryon https://example.com/model.jpg https://example.com/dress.jpg',
133
+ '',
134
+ '# 指定服装类别和生成模式',
135
+ '$ comfy tryon person.jpg top.jpg -c tops -m performance',
136
+ '',
137
+ '# 生成多张结果',
138
+ '$ comfy tryon person.jpg dress.jpg -n 4 -c one-pieces',
139
+ '',
140
+ '# 指定输出路径',
141
+ '$ comfy tryon person.jpg garment.jpg -o result.png',
142
+ '',
143
+ '# 使用种子复现结果',
144
+ '$ comfy tryon person.jpg garment.jpg --seed 42',
145
+ ],
146
+ outputJson: `{
147
+ "success": true,
148
+ "data": {
149
+ "id": "abc123",
150
+ "outputs": ["./comfy-output/tryon_1234567890_0.png"],
151
+ "mode": "quality",
152
+ "category": "auto",
153
+ "numSamples": 1,
154
+ "durationMs": 13000
155
+ }
156
+ }`,
157
+ relatedCommands: [
158
+ { command: 'image generate <prompt>', description: '文本生成图像' },
159
+ { command: 'config set fashn.apiKey <key>', description: '设置 FASHN API Key' },
160
+ ],
161
+ notes: [
162
+ '使用 FASHN AI tryon-v1.6 模型',
163
+ '支持本地图片路径和 URL',
164
+ '服装类别: auto (自动检测), tops (上装), bottoms (下装), one-pieces (连体)',
165
+ '生成模式: performance (~7s), balanced (~9s), quality (~13s)',
166
+ '设置 FASHN_API_KEY 环境变量或 comfy config set fashn.apiKey',
167
+ ],
168
+ });
169
+ }
170
+ //# sourceMappingURL=tryon.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tryon.js","sourceRoot":"","sources":["../../src/commands/tryon.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -19,6 +19,7 @@ import { registerInterruptCommand } from './commands/interrupt.js';
19
19
  import { registerInitCommand } from './commands/init.js';
20
20
  import { registerTtsCommand } from './commands/tts.js';
21
21
  import { registerAsrCommand } from './commands/asr.js';
22
+ import { registerTryonCommand } from './commands/tryon.js';
22
23
  const __filename = fileURLToPath(import.meta.url);
23
24
  const __dirname = dirname(__filename);
24
25
  const packageJson = JSON.parse(readFileSync(join(__dirname, '../package.json'), 'utf-8'));
@@ -68,6 +69,7 @@ registerEditCommand(program);
68
69
  registerVideoCommand(program);
69
70
  registerTtsCommand(program);
70
71
  registerAsrCommand(program);
72
+ registerTryonCommand(program);
71
73
  registerDownloadCommand(program);
72
74
  // 注册核心命令
73
75
  registerWorkflowCommand(program);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -15,6 +15,9 @@ export interface DashScopeConfig {
15
15
  export interface GroqConfig {
16
16
  apiKey?: string;
17
17
  }
18
+ export interface FashnConfig {
19
+ apiKey?: string;
20
+ }
18
21
  export interface ComfyConfig {
19
22
  server: string;
20
23
  timeout: number;
@@ -23,6 +26,7 @@ export interface ComfyConfig {
23
26
  bfl: BFLConfig;
24
27
  dashscope: DashScopeConfig;
25
28
  groq: GroqConfig;
29
+ fashn: FashnConfig;
26
30
  preferBackend: 'auto' | 'bfl' | 'comfyui';
27
31
  preferVideoBackend: 'auto' | 'dashscope' | 'comfyui';
28
32
  }
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/services/config.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,MAAM,WAAW,SAAS;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,GAAG,KAAK,CAAC;CAC9B;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC;IAC7B,QAAQ,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC;IACtB,YAAY,EAAE,OAAO,CAAC;IACtB,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC;CAC9B;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,OAAO,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,SAAS,CAAC;IACf,SAAS,EAAE,eAAe,CAAC;IAC3B,IAAI,EAAE,UAAU,CAAC;IACjB,aAAa,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS,CAAC;IAC1C,kBAAkB,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAAC;CACtD;AAuBD,eAAO,MAAM,MAAM,mBAGjB,CAAC;AAEH,wBAAgB,SAAS,IAAI,WAAW,CAEvC;AAGD,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,IAAI,CAEvD;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAE/C;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAE9C;AAED,wBAAgB,WAAW,IAAI,IAAI,CAElC;AAGD,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAoBrD"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/services/config.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,MAAM,WAAW,SAAS;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,GAAG,KAAK,CAAC;CAC9B;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC;IAC7B,QAAQ,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC;IACtB,YAAY,EAAE,OAAO,CAAC;IACtB,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC;CAC9B;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,OAAO,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,SAAS,CAAC;IACf,SAAS,EAAE,eAAe,CAAC;IAC3B,IAAI,EAAE,UAAU,CAAC;IACjB,KAAK,EAAE,WAAW,CAAC;IACnB,aAAa,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS,CAAC;IAC1C,kBAAkB,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAAC;CACtD;AAwBD,eAAO,MAAM,MAAM,mBAGjB,CAAC;AAEH,wBAAgB,SAAS,IAAI,WAAW,CAEvC;AAGD,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,IAAI,CAEvD;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAE/C;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAE9C;AAED,wBAAgB,WAAW,IAAI,IAAI,CAElC;AAGD,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAqBrD"}
@@ -16,6 +16,7 @@ const defaultConfig = {
16
16
  shotType: 'single',
17
17
  },
18
18
  groq: {},
19
+ fashn: {},
19
20
  preferBackend: 'auto',
20
21
  preferVideoBackend: 'auto',
21
22
  };
@@ -56,6 +57,7 @@ export function isValidConfigKey(key) {
56
57
  'dashscope.audio',
57
58
  'dashscope.shotType',
58
59
  'groq.apiKey',
60
+ 'fashn.apiKey',
59
61
  'preferBackend',
60
62
  'preferVideoBackend',
61
63
  ];
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/services/config.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AAiCxB,MAAM,aAAa,GAAgB;IACjC,MAAM,EAAE,6BAA6B;IACrC,OAAO,EAAE,MAAM;IACf,WAAW,EAAE,IAAI;IACjB,SAAS,EAAE,gBAAgB;IAC3B,GAAG,EAAE;QACH,eAAe,EAAE,CAAC;QAClB,YAAY,EAAE,KAAK;KACpB;IACD,SAAS,EAAE;QACT,UAAU,EAAE,OAAO;QACnB,QAAQ,EAAE,CAAC;QACX,YAAY,EAAE,IAAI;QAClB,KAAK,EAAE,IAAI;QACX,QAAQ,EAAE,QAAQ;KACnB;IACD,IAAI,EAAE,EAAE;IACR,aAAa,EAAE,MAAM;IACrB,kBAAkB,EAAE,MAAM;CAC3B,CAAC;AAEF,MAAM,CAAC,MAAM,MAAM,GAAG,IAAI,IAAI,CAAc;IAC1C,WAAW,EAAE,WAAW;IACxB,QAAQ,EAAE,aAAa;CACxB,CAAC,CAAC;AAEH,MAAM,UAAU,SAAS;IACvB,OAAO,MAAM,CAAC,KAAK,CAAC;AACtB,CAAC;AAED,uBAAuB;AACvB,MAAM,UAAU,SAAS,CAAC,GAAW,EAAE,KAAU;IAC/C,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;AACzB,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,GAAW;IACxC,OAAO,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AACzB,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,GAAW;IACtC,MAAM,CAAC,MAAM,CAAC,GAAwB,CAAC,CAAC;AAC1C,CAAC;AAED,MAAM,UAAU,WAAW;IACzB,MAAM,CAAC,KAAK,EAAE,CAAC;AACjB,CAAC;AAED,YAAY;AACZ,MAAM,UAAU,gBAAgB,CAAC,GAAW;IAC1C,MAAM,SAAS,GAAG;QAChB,QAAQ;QACR,SAAS;QACT,aAAa;QACb,WAAW;QACX,YAAY;QACZ,qBAAqB;QACrB,kBAAkB;QAClB,kBAAkB;QAClB,sBAAsB;QACtB,oBAAoB;QACpB,wBAAwB;QACxB,iBAAiB;QACjB,oBAAoB;QACpB,aAAa;QACb,eAAe;QACf,oBAAoB;KACrB,CAAC;IACF,OAAO,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;AACjC,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/services/config.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AAsCxB,MAAM,aAAa,GAAgB;IACjC,MAAM,EAAE,6BAA6B;IACrC,OAAO,EAAE,MAAM;IACf,WAAW,EAAE,IAAI;IACjB,SAAS,EAAE,gBAAgB;IAC3B,GAAG,EAAE;QACH,eAAe,EAAE,CAAC;QAClB,YAAY,EAAE,KAAK;KACpB;IACD,SAAS,EAAE;QACT,UAAU,EAAE,OAAO;QACnB,QAAQ,EAAE,CAAC;QACX,YAAY,EAAE,IAAI;QAClB,KAAK,EAAE,IAAI;QACX,QAAQ,EAAE,QAAQ;KACnB;IACD,IAAI,EAAE,EAAE;IACR,KAAK,EAAE,EAAE;IACT,aAAa,EAAE,MAAM;IACrB,kBAAkB,EAAE,MAAM;CAC3B,CAAC;AAEF,MAAM,CAAC,MAAM,MAAM,GAAG,IAAI,IAAI,CAAc;IAC1C,WAAW,EAAE,WAAW;IACxB,QAAQ,EAAE,aAAa;CACxB,CAAC,CAAC;AAEH,MAAM,UAAU,SAAS;IACvB,OAAO,MAAM,CAAC,KAAK,CAAC;AACtB,CAAC;AAED,uBAAuB;AACvB,MAAM,UAAU,SAAS,CAAC,GAAW,EAAE,KAAU;IAC/C,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;AACzB,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,GAAW;IACxC,OAAO,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AACzB,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,GAAW;IACtC,MAAM,CAAC,MAAM,CAAC,GAAwB,CAAC,CAAC;AAC1C,CAAC;AAED,MAAM,UAAU,WAAW;IACzB,MAAM,CAAC,KAAK,EAAE,CAAC;AACjB,CAAC;AAED,YAAY;AACZ,MAAM,UAAU,gBAAgB,CAAC,GAAW;IAC1C,MAAM,SAAS,GAAG;QAChB,QAAQ;QACR,SAAS;QACT,aAAa;QACb,WAAW;QACX,YAAY;QACZ,qBAAqB;QACrB,kBAAkB;QAClB,kBAAkB;QAClB,sBAAsB;QACtB,oBAAoB;QACpB,wBAAwB;QACxB,iBAAiB;QACjB,oBAAoB;QACpB,aAAa;QACb,cAAc;QACd,eAAe;QACf,oBAAoB;KACrB,CAAC;IACF,OAAO,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;AACjC,CAAC"}
@@ -0,0 +1,57 @@
1
+ export type TryonCategory = 'auto' | 'tops' | 'bottoms' | 'one-pieces';
2
+ export type TryonMode = 'performance' | 'balanced' | 'quality';
3
+ export type TryonGarmentPhotoType = 'auto' | 'flat-lay' | 'model';
4
+ export interface TryonParams {
5
+ model_image: string;
6
+ garment_image: string;
7
+ category?: TryonCategory;
8
+ mode?: TryonMode;
9
+ garment_photo_type?: TryonGarmentPhotoType;
10
+ num_samples?: number;
11
+ output_format?: 'png' | 'jpeg';
12
+ seed?: number;
13
+ }
14
+ export interface FashnRunResponse {
15
+ id: string;
16
+ status: string;
17
+ }
18
+ export interface FashnStatusResponse {
19
+ id: string;
20
+ status: 'starting' | 'processing' | 'completed' | 'failed';
21
+ output?: string[];
22
+ error?: {
23
+ name: string;
24
+ message: string;
25
+ };
26
+ }
27
+ export interface PollOptions {
28
+ interval?: number;
29
+ timeout?: number;
30
+ onProgress?: (status: string) => void;
31
+ }
32
+ export declare class FashnClient {
33
+ private client;
34
+ constructor(apiKey: string);
35
+ /**
36
+ * 提交虚拟试穿任务
37
+ */
38
+ run(params: TryonParams): Promise<FashnRunResponse>;
39
+ /**
40
+ * 获取任务状态
41
+ */
42
+ getStatus(id: string): Promise<FashnStatusResponse>;
43
+ /**
44
+ * 轮询等待结果
45
+ */
46
+ poll(id: string, options?: PollOptions): Promise<FashnStatusResponse>;
47
+ /**
48
+ * 将本地图像转换为 base64 data URL
49
+ */
50
+ imageToBase64(filePath: string): Promise<string>;
51
+ /**
52
+ * 下载图像到本地
53
+ */
54
+ downloadImage(url: string, outputDir: string, filename?: string): Promise<string>;
55
+ private sleep;
56
+ }
57
+ //# sourceMappingURL=fashn-api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fashn-api.d.ts","sourceRoot":"","sources":["../../src/services/fashn-api.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,GAAG,YAAY,CAAC;AACvE,MAAM,MAAM,SAAS,GAAG,aAAa,GAAG,UAAU,GAAG,SAAS,CAAC;AAC/D,MAAM,MAAM,qBAAqB,GAAG,MAAM,GAAG,UAAU,GAAG,OAAO,CAAC;AAElE,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,kBAAkB,CAAC,EAAE,qBAAqB,CAAC;IAC3C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,UAAU,GAAG,YAAY,GAAG,WAAW,GAAG,QAAQ,CAAC;IAC3D,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,KAAK,CAAC,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;CACH;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CACvC;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAAgB;gBAElB,MAAM,EAAE,MAAM;IAW1B;;OAEG;IACG,GAAG,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAQzD;;OAEG;IACG,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAKzD;;OAEG;IACG,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IA8B/E;;OAEG;IACG,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAStD;;OAEG;IACG,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAevF,OAAO,CAAC,KAAK;CAGd"}
@@ -0,0 +1,84 @@
1
+ import axios from 'axios';
2
+ import * as fs from 'fs/promises';
3
+ import * as path from 'path';
4
+ export class FashnClient {
5
+ client;
6
+ constructor(apiKey) {
7
+ this.client = axios.create({
8
+ baseURL: 'https://api.fashn.ai/v1',
9
+ headers: {
10
+ 'Authorization': `Bearer ${apiKey}`,
11
+ 'Content-Type': 'application/json',
12
+ },
13
+ timeout: 120000,
14
+ });
15
+ }
16
+ /**
17
+ * 提交虚拟试穿任务
18
+ */
19
+ async run(params) {
20
+ const response = await this.client.post('/run', {
21
+ model_name: 'tryon-v1.6',
22
+ inputs: params,
23
+ });
24
+ return response.data;
25
+ }
26
+ /**
27
+ * 获取任务状态
28
+ */
29
+ async getStatus(id) {
30
+ const response = await this.client.get(`/status/${id}`);
31
+ return response.data;
32
+ }
33
+ /**
34
+ * 轮询等待结果
35
+ */
36
+ async poll(id, options = {}) {
37
+ const { interval = 2000, timeout = 300000, onProgress, } = options;
38
+ const startTime = Date.now();
39
+ while (true) {
40
+ if (Date.now() - startTime > timeout) {
41
+ throw new Error('FASHN polling timeout exceeded');
42
+ }
43
+ const result = await this.getStatus(id);
44
+ onProgress?.(result.status);
45
+ if (result.status === 'completed') {
46
+ return result;
47
+ }
48
+ if (result.status === 'failed') {
49
+ const errMsg = result.error ? `${result.error.name}: ${result.error.message}` : 'Unknown error';
50
+ throw new Error(`FASHN try-on failed: ${errMsg}`);
51
+ }
52
+ await this.sleep(interval);
53
+ }
54
+ }
55
+ /**
56
+ * 将本地图像转换为 base64 data URL
57
+ */
58
+ async imageToBase64(filePath) {
59
+ const absolutePath = path.resolve(filePath);
60
+ const buffer = await fs.readFile(absolutePath);
61
+ const base64 = buffer.toString('base64');
62
+ const ext = path.extname(filePath).toLowerCase();
63
+ const mimeType = ext === '.png' ? 'image/png' : 'image/jpeg';
64
+ return `data:${mimeType};base64,${base64}`;
65
+ }
66
+ /**
67
+ * 下载图像到本地
68
+ */
69
+ async downloadImage(url, outputDir, filename) {
70
+ await fs.mkdir(outputDir, { recursive: true });
71
+ const response = await axios.get(url, {
72
+ responseType: 'arraybuffer',
73
+ timeout: 120000,
74
+ });
75
+ const finalFilename = filename || `tryon_${Date.now()}.png`;
76
+ const outputPath = path.join(outputDir, finalFilename);
77
+ await fs.writeFile(outputPath, response.data);
78
+ return outputPath;
79
+ }
80
+ sleep(ms) {
81
+ return new Promise(resolve => setTimeout(resolve, ms));
82
+ }
83
+ }
84
+ //# sourceMappingURL=fashn-api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fashn-api.js","sourceRoot":"","sources":["../../src/services/fashn-api.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@optima-chat/comfy-cli",
3
- "version": "0.9.8",
3
+ "version": "0.9.9",
4
4
  "description": "A CLI tool for ComfyUI designed for LLM interactions",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",