@optima-chat/comfy-cli 0.7.2 → 0.9.0
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/.claude/settings.local.json +5 -1
- package/dist/backends/bfl.d.ts +18 -0
- package/dist/backends/bfl.d.ts.map +1 -0
- package/dist/backends/bfl.js +115 -0
- package/dist/backends/bfl.js.map +1 -0
- package/dist/backends/comfyui.d.ts +10 -0
- package/dist/backends/comfyui.d.ts.map +1 -0
- package/dist/backends/comfyui.js +108 -0
- package/dist/backends/comfyui.js.map +1 -0
- package/dist/backends/index.d.ts +24 -0
- package/dist/backends/index.d.ts.map +1 -0
- package/dist/backends/index.js +59 -0
- package/dist/backends/index.js.map +1 -0
- package/dist/backends/types.d.ts +97 -0
- package/dist/backends/types.d.ts.map +1 -0
- package/dist/backends/types.js +2 -0
- package/dist/backends/types.js.map +1 -0
- package/dist/backends/video-dashscope.d.ts +10 -0
- package/dist/backends/video-dashscope.d.ts.map +1 -0
- package/dist/backends/video-dashscope.js +94 -0
- package/dist/backends/video-dashscope.js.map +1 -0
- package/dist/backends/video-index.d.ts +23 -0
- package/dist/backends/video-index.d.ts.map +1 -0
- package/dist/backends/video-index.js +57 -0
- package/dist/backends/video-index.js.map +1 -0
- package/dist/commands/config.d.ts.map +1 -1
- package/dist/commands/config.js +22 -17
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/image.d.ts +3 -0
- package/dist/commands/image.d.ts.map +1 -0
- package/dist/commands/image.js +148 -0
- package/dist/commands/image.js.map +1 -0
- package/dist/commands/video.d.ts.map +1 -1
- package/dist/commands/video.js +205 -119
- package/dist/commands/video.js.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/services/bfl-api.d.ts +67 -0
- package/dist/services/bfl-api.d.ts.map +1 -0
- package/dist/services/bfl-api.js +99 -0
- package/dist/services/bfl-api.js.map +1 -0
- package/dist/services/config.d.ts +21 -1
- package/dist/services/config.d.ts.map +1 -1
- package/dist/services/config.js +41 -0
- package/dist/services/config.js.map +1 -1
- package/dist/services/dashscope-api.d.ts +69 -0
- package/dist/services/dashscope-api.d.ts.map +1 -0
- package/dist/services/dashscope-api.js +134 -0
- package/dist/services/dashscope-api.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { getConfig } from '../services/config.js';
|
|
2
|
+
import { DashScopeVideoBackend } from './video-dashscope.js';
|
|
3
|
+
export { DashScopeVideoBackend } from './video-dashscope.js';
|
|
4
|
+
/**
|
|
5
|
+
* 获取 DashScope API Key(优先环境变量,其次配置文件)
|
|
6
|
+
*/
|
|
7
|
+
export function getDashScopeApiKey() {
|
|
8
|
+
return process.env.DASHSCOPE_API_KEY || getConfig().dashscope?.apiKey;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* 获取视频生成后端
|
|
12
|
+
*
|
|
13
|
+
* - auto: 有 DashScope API Key 则用 DashScope,否则用 ComfyUI
|
|
14
|
+
* - dashscope: 强制使用 DashScope(需要 API Key)
|
|
15
|
+
* - comfyui: 强制使用 ComfyUI
|
|
16
|
+
*
|
|
17
|
+
* API Key 优先级: 环境变量 DASHSCOPE_API_KEY > 配置文件 dashscope.apiKey
|
|
18
|
+
*/
|
|
19
|
+
export function getVideoBackend(type) {
|
|
20
|
+
const cfg = getConfig();
|
|
21
|
+
const backendType = type || cfg.preferVideoBackend || 'auto';
|
|
22
|
+
// 强制使用 DashScope
|
|
23
|
+
if (backendType === 'dashscope') {
|
|
24
|
+
const apiKey = getDashScopeApiKey();
|
|
25
|
+
if (!apiKey) {
|
|
26
|
+
throw new Error('DashScope API key not configured. Set DASHSCOPE_API_KEY env or run: comfy config set dashscope.apiKey <key>');
|
|
27
|
+
}
|
|
28
|
+
return new DashScopeVideoBackend(apiKey);
|
|
29
|
+
}
|
|
30
|
+
// 强制使用 ComfyUI(返回 null,由调用方处理)
|
|
31
|
+
if (backendType === 'comfyui') {
|
|
32
|
+
return null; // ComfyUI 视频后端由 video.ts 原有逻辑处理
|
|
33
|
+
}
|
|
34
|
+
// 自动选择:优先 DashScope
|
|
35
|
+
const apiKey = getDashScopeApiKey();
|
|
36
|
+
if (apiKey) {
|
|
37
|
+
return new DashScopeVideoBackend(apiKey);
|
|
38
|
+
}
|
|
39
|
+
return null; // 回退到 ComfyUI
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* 获取当前会使用的视频后端名称
|
|
43
|
+
*/
|
|
44
|
+
export function getCurrentVideoBackendName(type) {
|
|
45
|
+
const cfg = getConfig();
|
|
46
|
+
const backendType = type || cfg.preferVideoBackend || 'auto';
|
|
47
|
+
if (backendType === 'dashscope') {
|
|
48
|
+
return 'dashscope';
|
|
49
|
+
}
|
|
50
|
+
if (backendType === 'comfyui') {
|
|
51
|
+
return 'comfyui';
|
|
52
|
+
}
|
|
53
|
+
// auto
|
|
54
|
+
const apiKey = getDashScopeApiKey();
|
|
55
|
+
return apiKey ? 'dashscope' : 'comfyui';
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=video-index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"video-index.js","sourceRoot":"","sources":["../../src/backends/video-index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAM7D,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAE7D;;GAEG;AACH,MAAM,UAAU,kBAAkB;IAChC,OAAO,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,SAAS,EAAE,CAAC,SAAS,EAAE,MAAM,CAAC;AACxE,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,eAAe,CAAC,IAAuB;IACrD,MAAM,GAAG,GAAG,SAAS,EAAE,CAAC;IACxB,MAAM,WAAW,GAAG,IAAI,IAAI,GAAG,CAAC,kBAAkB,IAAI,MAAM,CAAC;IAE7D,iBAAiB;IACjB,IAAI,WAAW,KAAK,WAAW,EAAE,CAAC;QAChC,MAAM,MAAM,GAAG,kBAAkB,EAAE,CAAC;QACpC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,6GAA6G,CAAC,CAAC;QACjI,CAAC;QACD,OAAO,IAAI,qBAAqB,CAAC,MAAM,CAAC,CAAC;IAC3C,CAAC;IAED,+BAA+B;IAC/B,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;QAC9B,OAAO,IAAW,CAAC,CAAC,gCAAgC;IACtD,CAAC;IAED,oBAAoB;IACpB,MAAM,MAAM,GAAG,kBAAkB,EAAE,CAAC;IACpC,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,IAAI,qBAAqB,CAAC,MAAM,CAAC,CAAC;IAC3C,CAAC;IAED,OAAO,IAAW,CAAC,CAAC,cAAc;AACpC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,0BAA0B,CAAC,IAAuB;IAChE,MAAM,GAAG,GAAG,SAAS,EAAE,CAAC;IACxB,MAAM,WAAW,GAAG,IAAI,IAAI,GAAG,CAAC,kBAAkB,IAAI,MAAM,CAAC;IAE7D,IAAI,WAAW,KAAK,WAAW,EAAE,CAAC;QAChC,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;QAC9B,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,OAAO;IACP,MAAM,MAAM,GAAG,kBAAkB,EAAE,CAAC;IACpC,OAAO,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC;AAC1C,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOpC,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOpC,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,QA+MrD"}
|
package/dist/commands/config.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { config, getConfig, setConfig, resetConfig } from '../services/config.js';
|
|
1
|
+
import { config, getConfig, setConfig, resetConfig, isValidConfigKey } from '../services/config.js';
|
|
2
2
|
import { success, info } from '../utils/logger.js';
|
|
3
3
|
import { outputSuccess, outputError, isPrettyMode } from '../utils/output.js';
|
|
4
4
|
import { addEnhancedHelp } from '../utils/helpText.js';
|
|
@@ -10,21 +10,23 @@ export function registerConfigCommand(program) {
|
|
|
10
10
|
// comfy config set
|
|
11
11
|
const setCmd = configCmd
|
|
12
12
|
.command('set')
|
|
13
|
-
.description('设置配置项 - 配置 ComfyUI
|
|
14
|
-
.argument('<key>', '配置键
|
|
13
|
+
.description('设置配置项 - 配置 ComfyUI/BFL 服务器和其他选项')
|
|
14
|
+
.argument('<key>', '配置键')
|
|
15
15
|
.argument('<value>', '配置值')
|
|
16
16
|
.action((key, value, options) => {
|
|
17
17
|
const pretty = isPrettyMode(options);
|
|
18
18
|
try {
|
|
19
|
-
if (!
|
|
19
|
+
if (!isValidConfigKey(key)) {
|
|
20
20
|
outputError('INVALID_CONFIG_KEY', `无效的配置键: ${key}`, options);
|
|
21
|
+
return;
|
|
21
22
|
}
|
|
22
23
|
let parsedValue = value;
|
|
23
24
|
// 类型转换
|
|
24
|
-
if (key === 'timeout') {
|
|
25
|
+
if (key === 'timeout' || key === 'bfl.safetyTolerance') {
|
|
25
26
|
parsedValue = parseInt(value);
|
|
26
27
|
if (isNaN(parsedValue)) {
|
|
27
|
-
outputError('INVALID_VALUE',
|
|
28
|
+
outputError('INVALID_VALUE', `${key} 必须是数字`, options);
|
|
29
|
+
return;
|
|
28
30
|
}
|
|
29
31
|
}
|
|
30
32
|
else if (key === 'autoConnect') {
|
|
@@ -49,11 +51,14 @@ export function registerConfigCommand(program) {
|
|
|
49
51
|
// Add enhanced help for set command
|
|
50
52
|
addEnhancedHelp(setCmd, {
|
|
51
53
|
examples: [
|
|
52
|
-
'# 设置 ComfyUI
|
|
54
|
+
'# 设置 ComfyUI 服务器地址',
|
|
53
55
|
'$ comfy config set server http://localhost:8188',
|
|
54
56
|
'',
|
|
55
|
-
'#
|
|
56
|
-
'$ comfy config set
|
|
57
|
+
'# 设置 BFL API Key(启用云端 FLUX.2 Pro)',
|
|
58
|
+
'$ comfy config set bfl.apiKey your-api-key',
|
|
59
|
+
'',
|
|
60
|
+
'# 设置默认后端偏好',
|
|
61
|
+
'$ comfy config set preferBackend auto',
|
|
57
62
|
'',
|
|
58
63
|
'# 设置输出目录',
|
|
59
64
|
'$ comfy config set outputDir ./my-outputs',
|
|
@@ -62,8 +67,8 @@ export function registerConfigCommand(program) {
|
|
|
62
67
|
"success": true,
|
|
63
68
|
"data": {
|
|
64
69
|
"message": "配置已更新",
|
|
65
|
-
"key": "
|
|
66
|
-
"value": "
|
|
70
|
+
"key": "bfl.apiKey",
|
|
71
|
+
"value": "your-api-key"
|
|
67
72
|
}
|
|
68
73
|
}`,
|
|
69
74
|
relatedCommands: [
|
|
@@ -71,10 +76,10 @@ export function registerConfigCommand(program) {
|
|
|
71
76
|
{ command: 'config reset --confirm', description: '重置为默认配置' },
|
|
72
77
|
],
|
|
73
78
|
notes: [
|
|
74
|
-
'
|
|
75
|
-
'
|
|
76
|
-
'
|
|
77
|
-
'
|
|
79
|
+
'基础配置: server, timeout, autoConnect, outputDir',
|
|
80
|
+
'BFL 配置: bfl.apiKey, bfl.safetyTolerance, bfl.outputFormat',
|
|
81
|
+
'后端偏好: preferBackend (auto | bfl | comfyui)',
|
|
82
|
+
'设置 bfl.apiKey 后会自动使用 BFL 云端 API',
|
|
78
83
|
],
|
|
79
84
|
});
|
|
80
85
|
// comfy config list
|
|
@@ -88,9 +93,9 @@ export function registerConfigCommand(program) {
|
|
|
88
93
|
if (pretty) {
|
|
89
94
|
const table = new Table({
|
|
90
95
|
head: ['配置项', '值'],
|
|
91
|
-
colWidths: [
|
|
96
|
+
colWidths: [25, 55],
|
|
92
97
|
});
|
|
93
|
-
table.push(['Server', cfg.server], ['Timeout', `${cfg.timeout}ms`], ['Auto Connect', cfg.autoConnect ? '✓' : '✗'], ['Output Dir', cfg.outputDir]);
|
|
98
|
+
table.push(['Server', cfg.server], ['Timeout', `${cfg.timeout}ms`], ['Auto Connect', cfg.autoConnect ? '✓' : '✗'], ['Output Dir', cfg.outputDir], ['Prefer Backend', cfg.preferBackend], ['─── BFL ───', '───────────'], ['BFL API Key', cfg.bfl?.apiKey ? '******' + cfg.bfl.apiKey.slice(-4) : '(未设置)'], ['BFL Safety', cfg.bfl?.safetyTolerance ?? 2], ['BFL Format', cfg.bfl?.outputFormat ?? 'png']);
|
|
94
99
|
console.log(table.toString());
|
|
95
100
|
info(`配置文件位置: ${config.path}`);
|
|
96
101
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"image.d.ts","sourceRoot":"","sources":["../../src/commands/image.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAyBpC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,QA+IpD"}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import ora from 'ora';
|
|
2
|
+
import { getBackend, getCurrentBackendName } from '../backends/index.js';
|
|
3
|
+
import { outputSuccess, outputError, isPrettyMode } from '../utils/output.js';
|
|
4
|
+
import { info, warning } from '../utils/logger.js';
|
|
5
|
+
import { addEnhancedHelp } from '../utils/helpText.js';
|
|
6
|
+
// 收集多个 -i 参数
|
|
7
|
+
function collect(value, previous) {
|
|
8
|
+
return previous.concat([value]);
|
|
9
|
+
}
|
|
10
|
+
export function registerImageCommand(program) {
|
|
11
|
+
const cmd = program
|
|
12
|
+
.command('image')
|
|
13
|
+
.description('生成或编辑图像 - 统一的图像命令,自动选择 BFL 或 ComfyUI 后端')
|
|
14
|
+
.argument('<prompt>', '图像描述提示词')
|
|
15
|
+
.option('-i, --input <path>', '输入图像路径(可多次使用,最多 8 个)', collect, [])
|
|
16
|
+
.option('-w, --width <px>', '输出宽度 (默认: 1024)')
|
|
17
|
+
.option('-h, --height <px>', '输出高度 (默认: 1024)')
|
|
18
|
+
.option('-s, --seed <number>', '随机种子')
|
|
19
|
+
.option('-f, --format <fmt>', '输出格式: jpeg | png (默认: png)')
|
|
20
|
+
.option('-o, --output <path>', '输出目录')
|
|
21
|
+
.option('--safety <level>', '安全等级 0-5 (仅 BFL)')
|
|
22
|
+
.option('--backend <name>', '强制指定后端: bfl | comfyui | auto (默认: auto)')
|
|
23
|
+
.option('--no-wait', '提交后不等待结果')
|
|
24
|
+
.action(async (prompt, options) => {
|
|
25
|
+
const pretty = isPrettyMode(options);
|
|
26
|
+
try {
|
|
27
|
+
// 确定后端类型
|
|
28
|
+
const backendType = options.backend || 'auto';
|
|
29
|
+
const backendName = getCurrentBackendName(backendType);
|
|
30
|
+
// 多图检查
|
|
31
|
+
if (options.input && options.input.length > 1 && backendName === 'comfyui') {
|
|
32
|
+
if (pretty) {
|
|
33
|
+
warning('ComfyUI 只支持单张输入图像,将使用第一张');
|
|
34
|
+
}
|
|
35
|
+
options.input = [options.input[0]];
|
|
36
|
+
}
|
|
37
|
+
if (options.input && options.input.length > 8) {
|
|
38
|
+
outputError('TOO_MANY_INPUTS', '最多支持 8 张输入图像', options);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
// 获取后端
|
|
42
|
+
const backend = getBackend(backendType);
|
|
43
|
+
// 显示信息
|
|
44
|
+
const spinner = pretty ? ora(`使用 ${backend.name.toUpperCase()} 后端...`).start() : null;
|
|
45
|
+
if (pretty) {
|
|
46
|
+
spinner.text = options.input?.length
|
|
47
|
+
? `正在编辑图像: "${prompt}"`
|
|
48
|
+
: `正在生成图像: "${prompt}"`;
|
|
49
|
+
}
|
|
50
|
+
// 执行生成
|
|
51
|
+
const result = await backend.generate({
|
|
52
|
+
prompt,
|
|
53
|
+
inputImages: options.input?.length ? options.input : undefined,
|
|
54
|
+
width: options.width ? parseInt(options.width) : undefined,
|
|
55
|
+
height: options.height ? parseInt(options.height) : undefined,
|
|
56
|
+
seed: options.seed ? parseInt(options.seed) : undefined,
|
|
57
|
+
outputFormat: options.format,
|
|
58
|
+
safetyTolerance: options.safety ? parseInt(options.safety) : undefined,
|
|
59
|
+
wait: options.wait !== false,
|
|
60
|
+
});
|
|
61
|
+
// 输出结果
|
|
62
|
+
if (pretty) {
|
|
63
|
+
if (result.status === 'completed') {
|
|
64
|
+
spinner.succeed('图像生成完成!');
|
|
65
|
+
info(`输出文件: ${result.output}`);
|
|
66
|
+
if (result.seed !== undefined) {
|
|
67
|
+
info(`Seed: ${result.seed}`);
|
|
68
|
+
}
|
|
69
|
+
if (result.durationMs !== undefined) {
|
|
70
|
+
info(`耗时: ${(result.durationMs / 1000).toFixed(1)}s`);
|
|
71
|
+
}
|
|
72
|
+
if (result.cost !== undefined) {
|
|
73
|
+
info(`费用: $${result.cost.toFixed(4)}`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
spinner.info(`任务已提交,ID: ${result.id}`);
|
|
78
|
+
info(`使用 'comfy workflow get ${result.id}' 查看状态`);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
outputSuccess({
|
|
83
|
+
id: result.id,
|
|
84
|
+
backend: result.backend,
|
|
85
|
+
status: result.status,
|
|
86
|
+
output: result.output,
|
|
87
|
+
output_url: result.outputUrl,
|
|
88
|
+
seed: result.seed,
|
|
89
|
+
duration_ms: result.durationMs,
|
|
90
|
+
cost: result.cost,
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
catch (err) {
|
|
95
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
96
|
+
outputError('IMAGE_ERROR', message, options);
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
// Add enhanced help
|
|
100
|
+
addEnhancedHelp(cmd, {
|
|
101
|
+
examples: [
|
|
102
|
+
'# 文生图(自动选择后端)',
|
|
103
|
+
'$ comfy image "a cute cat sitting on a sofa"',
|
|
104
|
+
'',
|
|
105
|
+
'# 单图编辑',
|
|
106
|
+
'$ comfy image "make it look like watercolor" -i photo.png',
|
|
107
|
+
'',
|
|
108
|
+
'# 多图风格融合(BFL 专属)',
|
|
109
|
+
'$ comfy image "combine styles" -i style.png -i content.png',
|
|
110
|
+
'',
|
|
111
|
+
'# 指定尺寸',
|
|
112
|
+
'$ comfy image "landscape" -w 1920 -h 1080',
|
|
113
|
+
'',
|
|
114
|
+
'# 强制使用特定后端',
|
|
115
|
+
'$ comfy image "a cat" --backend comfyui',
|
|
116
|
+
'$ comfy image "a cat" --backend bfl',
|
|
117
|
+
'',
|
|
118
|
+
'# 非阻塞模式',
|
|
119
|
+
'$ comfy image "sunset" --no-wait',
|
|
120
|
+
],
|
|
121
|
+
outputJson: `{
|
|
122
|
+
"success": true,
|
|
123
|
+
"data": {
|
|
124
|
+
"id": "abc-123-xyz",
|
|
125
|
+
"backend": "bfl",
|
|
126
|
+
"status": "completed",
|
|
127
|
+
"output": "./comfy-output/bfl_abc-123-xyz.png",
|
|
128
|
+
"seed": 12345,
|
|
129
|
+
"duration_ms": 12500,
|
|
130
|
+
"cost": 0.03
|
|
131
|
+
}
|
|
132
|
+
}`,
|
|
133
|
+
relatedCommands: [
|
|
134
|
+
{ command: 'config set bfl.apiKey <key>', description: '设置 BFL API Key' },
|
|
135
|
+
{ command: 'config list', description: '查看当前配置和后端' },
|
|
136
|
+
{ command: 'generate <prompt>', description: '生成图像(别名)' },
|
|
137
|
+
{ command: 'edit <image> <prompt>', description: '编辑图像(别名)' },
|
|
138
|
+
],
|
|
139
|
+
notes: [
|
|
140
|
+
'自动选择后端: 有 BFL API Key 用 BFL,否则用 ComfyUI',
|
|
141
|
+
'BFL 云端 API: 高质量、支持多图参考、按量付费',
|
|
142
|
+
'ComfyUI 本地: 免费、支持自定义工作流',
|
|
143
|
+
'多图参考(-i 多次)仅 BFL 支持,ComfyUI 只用第一张',
|
|
144
|
+
'使用 --backend 可强制指定后端',
|
|
145
|
+
],
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
//# sourceMappingURL=image.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"image.js","sourceRoot":"","sources":["../../src/commands/image.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"video.d.ts","sourceRoot":"","sources":["../../src/commands/video.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"video.d.ts","sourceRoot":"","sources":["../../src/commands/video.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAYpC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,QA+FpD"}
|