@optima-chat/comfy-cli 0.1.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 +20 -0
- package/LICENSE +21 -0
- package/README.md +228 -0
- package/dist/commands/config.d.ts +3 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +87 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/edit.d.ts +3 -0
- package/dist/commands/edit.d.ts.map +1 -0
- package/dist/commands/edit.js +63 -0
- package/dist/commands/edit.js.map +1 -0
- package/dist/commands/generate.d.ts +3 -0
- package/dist/commands/generate.d.ts.map +1 -0
- package/dist/commands/generate.js +51 -0
- package/dist/commands/generate.js.map +1 -0
- package/dist/commands/interrupt.d.ts +3 -0
- package/dist/commands/interrupt.d.ts.map +1 -0
- package/dist/commands/interrupt.js +19 -0
- package/dist/commands/interrupt.js.map +1 -0
- package/dist/commands/model.d.ts +3 -0
- package/dist/commands/model.d.ts.map +1 -0
- package/dist/commands/model.js +44 -0
- package/dist/commands/model.js.map +1 -0
- package/dist/commands/node.d.ts +3 -0
- package/dist/commands/node.d.ts.map +1 -0
- package/dist/commands/node.js +70 -0
- package/dist/commands/node.js.map +1 -0
- package/dist/commands/queue.d.ts +3 -0
- package/dist/commands/queue.d.ts.map +1 -0
- package/dist/commands/queue.js +97 -0
- package/dist/commands/queue.js.map +1 -0
- package/dist/commands/system.d.ts +3 -0
- package/dist/commands/system.d.ts.map +1 -0
- package/dist/commands/system.js +47 -0
- package/dist/commands/system.js.map +1 -0
- package/dist/commands/video.d.ts +3 -0
- package/dist/commands/video.d.ts.map +1 -0
- package/dist/commands/video.js +79 -0
- package/dist/commands/video.js.map +1 -0
- package/dist/commands/workflow.d.ts +3 -0
- package/dist/commands/workflow.d.ts.map +1 -0
- package/dist/commands/workflow.js +131 -0
- package/dist/commands/workflow.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +31 -0
- package/dist/index.js.map +1 -0
- package/dist/services/api.d.ts +17 -0
- package/dist/services/api.d.ts.map +1 -0
- package/dist/services/api.js +62 -0
- package/dist/services/api.js.map +1 -0
- package/dist/services/config.d.ts +12 -0
- package/dist/services/config.d.ts.map +1 -0
- package/dist/services/config.js +21 -0
- package/dist/services/config.js.map +1 -0
- package/dist/utils/logger.d.ts +5 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +14 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/workflow.d.ts +17 -0
- package/dist/utils/workflow.d.ts.map +1 -0
- package/dist/utils/workflow.js +78 -0
- package/dist/utils/workflow.js.map +1 -0
- package/package.json +64 -0
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { ComfyAPIClient } from '../services/api';
|
|
2
|
+
import { error, info } from '../utils/logger';
|
|
3
|
+
import Table from 'cli-table3';
|
|
4
|
+
export function registerNodeCommand(program) {
|
|
5
|
+
const nodeCmd = program
|
|
6
|
+
.command('node')
|
|
7
|
+
.description('节点信息查询');
|
|
8
|
+
// comfy node list
|
|
9
|
+
nodeCmd
|
|
10
|
+
.command('list')
|
|
11
|
+
.description('列出所有节点类型')
|
|
12
|
+
.option('--filter <text>', '过滤节点名称')
|
|
13
|
+
.option('--json', '输出 JSON 格式')
|
|
14
|
+
.action(async (options) => {
|
|
15
|
+
try {
|
|
16
|
+
const client = new ComfyAPIClient();
|
|
17
|
+
const nodeInfo = await client.getObjectInfo();
|
|
18
|
+
let nodeList = Object.keys(nodeInfo);
|
|
19
|
+
if (options.filter) {
|
|
20
|
+
nodeList = nodeList.filter((name) => name.toLowerCase().includes(options.filter.toLowerCase()));
|
|
21
|
+
}
|
|
22
|
+
if (options.json) {
|
|
23
|
+
console.log(JSON.stringify(nodeList, null, 2));
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
if (nodeList.length === 0) {
|
|
27
|
+
info('未找到节点');
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
const table = new Table({
|
|
31
|
+
head: ['序号', '节点类型'],
|
|
32
|
+
colWidths: [8, 70],
|
|
33
|
+
});
|
|
34
|
+
nodeList.forEach((nodeName, index) => {
|
|
35
|
+
table.push([index + 1, nodeName]);
|
|
36
|
+
});
|
|
37
|
+
console.log(table.toString());
|
|
38
|
+
info(`共 ${nodeList.length} 个节点类型`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
catch (err) {
|
|
42
|
+
error(`获取节点列表失败: ${err}`);
|
|
43
|
+
process.exit(1);
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
// comfy node info
|
|
47
|
+
nodeCmd
|
|
48
|
+
.command('info')
|
|
49
|
+
.description('查看节点详情')
|
|
50
|
+
.argument('<class>', '节点类名')
|
|
51
|
+
.option('--json', '输出 JSON 格式')
|
|
52
|
+
.action(async (nodeClass, options) => {
|
|
53
|
+
try {
|
|
54
|
+
const client = new ComfyAPIClient();
|
|
55
|
+
const nodeInfo = await client.getObjectInfo(nodeClass);
|
|
56
|
+
if (options.json) {
|
|
57
|
+
console.log(JSON.stringify(nodeInfo, null, 2));
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
console.log(`\n📦 节点: ${nodeClass}\n`);
|
|
61
|
+
console.log(JSON.stringify(nodeInfo, null, 2));
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
catch (err) {
|
|
65
|
+
error(`获取节点信息失败: ${err}`);
|
|
66
|
+
process.exit(1);
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=node.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node.js","sourceRoot":"","sources":["../../src/commands/node.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queue.d.ts","sourceRoot":"","sources":["../../src/commands/queue.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,QAqGpD"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { ComfyAPIClient } from '../services/api';
|
|
2
|
+
import { success, error, info } from '../utils/logger';
|
|
3
|
+
import Table from 'cli-table3';
|
|
4
|
+
export function registerQueueCommand(program) {
|
|
5
|
+
const queueCmd = program
|
|
6
|
+
.command('queue')
|
|
7
|
+
.description('队列管理');
|
|
8
|
+
// comfy queue status
|
|
9
|
+
queueCmd
|
|
10
|
+
.command('status')
|
|
11
|
+
.description('查看队列状态')
|
|
12
|
+
.option('--json', '输出 JSON 格式')
|
|
13
|
+
.action(async (options) => {
|
|
14
|
+
try {
|
|
15
|
+
const client = new ComfyAPIClient();
|
|
16
|
+
const queue = await client.getQueue();
|
|
17
|
+
if (options.json) {
|
|
18
|
+
console.log(JSON.stringify(queue, null, 2));
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
const running = queue.queue_running || [];
|
|
22
|
+
const pending = queue.queue_pending || [];
|
|
23
|
+
console.log(`\n📊 队列状态\n`);
|
|
24
|
+
if (running.length > 0) {
|
|
25
|
+
info('🏃 正在执行:');
|
|
26
|
+
const table = new Table({
|
|
27
|
+
head: ['位置', 'Prompt ID', '节点数'],
|
|
28
|
+
colWidths: [8, 40, 12],
|
|
29
|
+
});
|
|
30
|
+
running.forEach((item, index) => {
|
|
31
|
+
table.push([index + 1, item[1] || '-', item[2]?.length || 0]);
|
|
32
|
+
});
|
|
33
|
+
console.log(table.toString());
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
info('✓ 当前无正在执行的任务');
|
|
37
|
+
}
|
|
38
|
+
console.log('');
|
|
39
|
+
if (pending.length > 0) {
|
|
40
|
+
info(`⏳ 等待中: ${pending.length} 个任务`);
|
|
41
|
+
const table = new Table({
|
|
42
|
+
head: ['位置', 'Prompt ID', '节点数'],
|
|
43
|
+
colWidths: [8, 40, 12],
|
|
44
|
+
});
|
|
45
|
+
pending.forEach((item, index) => {
|
|
46
|
+
table.push([index + 1, item[1] || '-', item[2]?.length || 0]);
|
|
47
|
+
});
|
|
48
|
+
console.log(table.toString());
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
info('✓ 无等待任务');
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
catch (err) {
|
|
56
|
+
error(`获取队列状态失败: ${err}`);
|
|
57
|
+
process.exit(1);
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
// comfy queue clear
|
|
61
|
+
queueCmd
|
|
62
|
+
.command('clear')
|
|
63
|
+
.description('清空队列')
|
|
64
|
+
.option('--confirm', '确认清空')
|
|
65
|
+
.action(async (options) => {
|
|
66
|
+
try {
|
|
67
|
+
if (!options.confirm) {
|
|
68
|
+
error('请使用 --confirm 确认清空操作');
|
|
69
|
+
process.exit(1);
|
|
70
|
+
}
|
|
71
|
+
const client = new ComfyAPIClient();
|
|
72
|
+
await client.clearQueue();
|
|
73
|
+
success('队列已清空');
|
|
74
|
+
}
|
|
75
|
+
catch (err) {
|
|
76
|
+
error(`清空队列失败: ${err}`);
|
|
77
|
+
process.exit(1);
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
// comfy queue delete
|
|
81
|
+
queueCmd
|
|
82
|
+
.command('delete')
|
|
83
|
+
.description('删除指定队列项')
|
|
84
|
+
.argument('<item_id>', '队列项 ID')
|
|
85
|
+
.action(async (itemId) => {
|
|
86
|
+
try {
|
|
87
|
+
const client = new ComfyAPIClient();
|
|
88
|
+
await client.deleteQueueItem(itemId);
|
|
89
|
+
success(`已删除队列项: ${itemId}`);
|
|
90
|
+
}
|
|
91
|
+
catch (err) {
|
|
92
|
+
error(`删除失败: ${err}`);
|
|
93
|
+
process.exit(1);
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=queue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queue.js","sourceRoot":"","sources":["../../src/commands/queue.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"system.d.ts","sourceRoot":"","sources":["../../src/commands/system.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,QA8CrD"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { ComfyAPIClient } from '../services/api';
|
|
2
|
+
import { error, info } from '../utils/logger';
|
|
3
|
+
import Table from 'cli-table3';
|
|
4
|
+
export function registerSystemCommand(program) {
|
|
5
|
+
const systemCmd = program
|
|
6
|
+
.command('system')
|
|
7
|
+
.description('系统信息');
|
|
8
|
+
// comfy system stats
|
|
9
|
+
systemCmd
|
|
10
|
+
.command('stats')
|
|
11
|
+
.description('查看系统统计信息')
|
|
12
|
+
.option('--json', '输出 JSON 格式')
|
|
13
|
+
.action(async (options) => {
|
|
14
|
+
try {
|
|
15
|
+
const client = new ComfyAPIClient();
|
|
16
|
+
const stats = await client.getSystemStats();
|
|
17
|
+
if (options.json) {
|
|
18
|
+
console.log(JSON.stringify(stats, null, 2));
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
console.log(`\n💻 系统状态\n`);
|
|
22
|
+
if (stats.system) {
|
|
23
|
+
const table = new Table({
|
|
24
|
+
head: ['指标', '值'],
|
|
25
|
+
colWidths: [30, 50],
|
|
26
|
+
});
|
|
27
|
+
Object.entries(stats.system).forEach(([key, value]) => {
|
|
28
|
+
table.push([key, String(value)]);
|
|
29
|
+
});
|
|
30
|
+
console.log(table.toString());
|
|
31
|
+
}
|
|
32
|
+
if (stats.devices) {
|
|
33
|
+
console.log('\n🎮 设备信息:\n');
|
|
34
|
+
stats.devices.forEach((device, index) => {
|
|
35
|
+
info(`设备 ${index + 1}:`);
|
|
36
|
+
console.log(JSON.stringify(device, null, 2));
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
catch (err) {
|
|
42
|
+
error(`获取系统信息失败: ${err}`);
|
|
43
|
+
process.exit(1);
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=system.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"system.js","sourceRoot":"","sources":["../../src/commands/system.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAW,MAAM,iBAAiB,CAAC;AACvD,OAAO,KAAK,MAAM,YAAY,CAAC;AAE/B,MAAM,UAAU,qBAAqB,CAAC,OAAgB;IACpD,MAAM,SAAS,GAAG,OAAO;SACtB,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,MAAM,CAAC,CAAC;IAEvB,qBAAqB;IACrB,SAAS;SACN,OAAO,CAAC,OAAO,CAAC;SAChB,WAAW,CAAC,UAAU,CAAC;SACvB,MAAM,CAAC,QAAQ,EAAE,YAAY,CAAC;SAC9B,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;QACxB,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,cAAc,EAAE,CAAC;YACpC,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,cAAc,EAAE,CAAC;YAE5C,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;gBACjB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;YAC9C,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;gBAE3B,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;oBACjB,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC;wBACtB,IAAI,EAAE,CAAC,IAAI,EAAE,GAAG,CAAC;wBACjB,SAAS,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC;qBACpB,CAAC,CAAC;oBAEH,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE;wBACpD,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;oBACnC,CAAC,CAAC,CAAC;oBAEH,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;gBAChC,CAAC;gBAED,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;oBAClB,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;oBAC5B,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,MAAW,EAAE,KAAa,EAAE,EAAE;wBACnD,IAAI,CAAC,MAAM,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC;wBACzB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;oBAC/C,CAAC,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,KAAK,CAAC,aAAa,GAAG,EAAE,CAAC,CAAC;YAC1B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"video.d.ts","sourceRoot":"","sources":["../../src/commands/video.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOpC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,QA6EpD"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import * as path from 'path';
|
|
2
|
+
import * as fs from 'fs';
|
|
3
|
+
import { ComfyAPIClient } from '../services/api';
|
|
4
|
+
import { loadWorkflow, getBuiltinWorkflowPath, replaceVariables } from '../utils/workflow';
|
|
5
|
+
import { success, error, info } from '../utils/logger';
|
|
6
|
+
export function registerVideoCommand(program) {
|
|
7
|
+
program
|
|
8
|
+
.command('video')
|
|
9
|
+
.description('生成视频(图生视频)')
|
|
10
|
+
.argument('<image>', '输入图像路径')
|
|
11
|
+
.option('-p, --prompt <text>', '运动描述提示词', '')
|
|
12
|
+
.option('-n, --negative <text>', '负向提示词', '')
|
|
13
|
+
.option('-o, --output <dir>', '输出目录', './output')
|
|
14
|
+
.option('--width <number>', '视频宽度', '512')
|
|
15
|
+
.option('--height <number>', '视频高度', '512')
|
|
16
|
+
.option('--frames <number>', '帧数', '60')
|
|
17
|
+
.option('--fps <number>', '帧率', '30')
|
|
18
|
+
.option('--steps <number>', '采样步数', '20')
|
|
19
|
+
.option('--cfg <number>', 'CFG scale', '7.0')
|
|
20
|
+
.option('--seed <number>', '随机种子', String(Math.floor(Math.random() * 1000000)))
|
|
21
|
+
.option('--json', '输出 JSON 格式')
|
|
22
|
+
.action(async (image, options) => {
|
|
23
|
+
try {
|
|
24
|
+
// 检查图像文件是否存在
|
|
25
|
+
const imagePath = path.resolve(image);
|
|
26
|
+
if (!fs.existsSync(imagePath)) {
|
|
27
|
+
error(`图像文件不存在: ${imagePath}`);
|
|
28
|
+
process.exit(1);
|
|
29
|
+
}
|
|
30
|
+
info(`正在生成视频: "${path.basename(image)}"`);
|
|
31
|
+
// 先上传图像
|
|
32
|
+
const client = new ComfyAPIClient();
|
|
33
|
+
const imageBuffer = fs.readFileSync(imagePath);
|
|
34
|
+
const uploadResult = await client.uploadImage(imageBuffer, path.basename(imagePath));
|
|
35
|
+
// 加载内置 workflow
|
|
36
|
+
const workflowPath = getBuiltinWorkflowPath('wan_image_to_video.json');
|
|
37
|
+
const workflow = loadWorkflow(workflowPath);
|
|
38
|
+
// 准备参数
|
|
39
|
+
const params = {
|
|
40
|
+
input_image: uploadResult.name,
|
|
41
|
+
prompt: options.prompt,
|
|
42
|
+
negative_prompt: options.negative,
|
|
43
|
+
width: parseInt(options.width),
|
|
44
|
+
height: parseInt(options.height),
|
|
45
|
+
frames: parseInt(options.frames),
|
|
46
|
+
fps: parseInt(options.fps),
|
|
47
|
+
steps: parseInt(options.steps),
|
|
48
|
+
cfg_scale: parseFloat(options.cfg),
|
|
49
|
+
seed: parseInt(options.seed),
|
|
50
|
+
sampler: 'euler',
|
|
51
|
+
scheduler: 'normal',
|
|
52
|
+
unet_model: 'wan_unet.safetensors',
|
|
53
|
+
clip_model: 'clip_l.safetensors',
|
|
54
|
+
clip_vision_model: 'sigclip_vision_patch14_384.safetensors',
|
|
55
|
+
vae_model: 'wan_vae.safetensors',
|
|
56
|
+
shift: 1.0,
|
|
57
|
+
filename_prefix: 'video',
|
|
58
|
+
};
|
|
59
|
+
// 替换变量
|
|
60
|
+
const processedWorkflow = replaceVariables(workflow, params);
|
|
61
|
+
// 提交到 ComfyUI
|
|
62
|
+
const result = await client.submitWorkflow(processedWorkflow);
|
|
63
|
+
if (options.json) {
|
|
64
|
+
console.log(JSON.stringify(result, null, 2));
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
success(`视频生成任务已提交`);
|
|
68
|
+
info(`Prompt ID: ${result.prompt_id}`);
|
|
69
|
+
info(`帧数: ${params.frames}, FPS: ${params.fps}, 时长: ${(params.frames / params.fps).toFixed(1)}秒`);
|
|
70
|
+
info(`使用 'comfy workflow get ${result.prompt_id}' 查看结果`);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
catch (err) {
|
|
74
|
+
error(`生成失败: ${err}`);
|
|
75
|
+
process.exit(1);
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=video.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"video.js","sourceRoot":"","sources":["../../src/commands/video.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow.d.ts","sourceRoot":"","sources":["../../src/commands/workflow.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOpC,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,QA0IvD"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { ComfyAPIClient } from '../services/api';
|
|
2
|
+
import { loadWorkflow, extractVariables } from '../utils/workflow';
|
|
3
|
+
import { success, error, info } from '../utils/logger';
|
|
4
|
+
import Table from 'cli-table3';
|
|
5
|
+
export function registerWorkflowCommand(program) {
|
|
6
|
+
const workflowCmd = program
|
|
7
|
+
.command('workflow')
|
|
8
|
+
.description('工作流管理');
|
|
9
|
+
// comfy workflow submit
|
|
10
|
+
workflowCmd
|
|
11
|
+
.command('submit')
|
|
12
|
+
.description('提交工作流')
|
|
13
|
+
.argument('<file>', 'workflow JSON 文件路径')
|
|
14
|
+
.option('--json', '输出 JSON 格式')
|
|
15
|
+
.option('--wait', '等待执行完成')
|
|
16
|
+
.action(async (file, options) => {
|
|
17
|
+
try {
|
|
18
|
+
info(`正在加载工作流: ${file}`);
|
|
19
|
+
// 加载 workflow
|
|
20
|
+
const workflow = loadWorkflow(file);
|
|
21
|
+
// 提取变量
|
|
22
|
+
const variables = extractVariables(workflow);
|
|
23
|
+
if (variables.length > 0) {
|
|
24
|
+
info(`检测到 ${variables.length} 个变量: ${variables.join(', ')}`);
|
|
25
|
+
info('提示: 使用 generate/edit/video 命令可以自动填充这些变量');
|
|
26
|
+
}
|
|
27
|
+
// 提交到 ComfyUI
|
|
28
|
+
const client = new ComfyAPIClient();
|
|
29
|
+
const result = await client.submitWorkflow(workflow);
|
|
30
|
+
if (options.json) {
|
|
31
|
+
console.log(JSON.stringify(result, null, 2));
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
success(`工作流已提交`);
|
|
35
|
+
info(`Prompt ID: ${result.prompt_id}`);
|
|
36
|
+
if (options.wait) {
|
|
37
|
+
info('等待执行完成...');
|
|
38
|
+
// TODO: 实现 WebSocket 监控
|
|
39
|
+
info('WebSocket 监控功能即将推出');
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
info(`使用 'comfy workflow get ${result.prompt_id}' 查看结果`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
catch (err) {
|
|
47
|
+
error(`提交失败: ${err}`);
|
|
48
|
+
process.exit(1);
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
// comfy workflow list
|
|
52
|
+
workflowCmd
|
|
53
|
+
.command('list')
|
|
54
|
+
.description('列出工作流历史')
|
|
55
|
+
.option('--limit <number>', '限制数量', '10')
|
|
56
|
+
.option('--json', '输出 JSON 格式')
|
|
57
|
+
.action(async (options) => {
|
|
58
|
+
try {
|
|
59
|
+
const client = new ComfyAPIClient();
|
|
60
|
+
const history = await client.getHistory();
|
|
61
|
+
const historyArray = Object.entries(history).slice(0, parseInt(options.limit));
|
|
62
|
+
if (options.json) {
|
|
63
|
+
console.log(JSON.stringify(historyArray, null, 2));
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
if (historyArray.length === 0) {
|
|
67
|
+
info('暂无历史记录');
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
const table = new Table({
|
|
71
|
+
head: ['Prompt ID', '状态', '时间'],
|
|
72
|
+
colWidths: [40, 15, 25],
|
|
73
|
+
});
|
|
74
|
+
historyArray.forEach(([promptId, data]) => {
|
|
75
|
+
const status = data.status?.completed ? '✓ 完成' : '✗ 失败';
|
|
76
|
+
const timestamp = data.status?.status_str || '-';
|
|
77
|
+
table.push([promptId, status, timestamp]);
|
|
78
|
+
});
|
|
79
|
+
console.log(table.toString());
|
|
80
|
+
info(`共 ${historyArray.length} 条记录`);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
catch (err) {
|
|
84
|
+
error(`获取历史失败: ${err}`);
|
|
85
|
+
process.exit(1);
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
// comfy workflow get
|
|
89
|
+
workflowCmd
|
|
90
|
+
.command('get')
|
|
91
|
+
.description('获取工作流结果')
|
|
92
|
+
.argument('<prompt_id>', 'Prompt ID')
|
|
93
|
+
.option('--json', '输出 JSON 格式')
|
|
94
|
+
.option('--download', '下载输出图像')
|
|
95
|
+
.option('--output <dir>', '输出目录', './output')
|
|
96
|
+
.action(async (promptId, options) => {
|
|
97
|
+
try {
|
|
98
|
+
const client = new ComfyAPIClient();
|
|
99
|
+
const result = await client.getHistory(promptId);
|
|
100
|
+
if (!result[promptId]) {
|
|
101
|
+
error(`未找到 Prompt ID: ${promptId}`);
|
|
102
|
+
process.exit(1);
|
|
103
|
+
}
|
|
104
|
+
const data = result[promptId];
|
|
105
|
+
if (options.json) {
|
|
106
|
+
console.log(JSON.stringify(data, null, 2));
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
success(`Prompt ID: ${promptId}`);
|
|
110
|
+
if (data.status) {
|
|
111
|
+
info(`状态: ${data.status.completed ? '✓ 完成' : '✗ 失败'}`);
|
|
112
|
+
if (data.status.status_str) {
|
|
113
|
+
info(`消息: ${data.status.status_str}`);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
if (data.outputs) {
|
|
117
|
+
info('输出:');
|
|
118
|
+
console.log(JSON.stringify(data.outputs, null, 2));
|
|
119
|
+
}
|
|
120
|
+
if (options.download) {
|
|
121
|
+
info('下载功能即将推出');
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
catch (err) {
|
|
126
|
+
error(`获取结果失败: ${err}`);
|
|
127
|
+
process.exit(1);
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=workflow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow.js","sourceRoot":"","sources":["../../src/commands/workflow.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Command } from 'commander';
|
|
3
|
+
import { registerGenerateCommand } from './commands/generate';
|
|
4
|
+
import { registerEditCommand } from './commands/edit';
|
|
5
|
+
import { registerVideoCommand } from './commands/video';
|
|
6
|
+
import { registerWorkflowCommand } from './commands/workflow';
|
|
7
|
+
import { registerQueueCommand } from './commands/queue';
|
|
8
|
+
import { registerModelCommand } from './commands/model';
|
|
9
|
+
import { registerNodeCommand } from './commands/node';
|
|
10
|
+
import { registerSystemCommand } from './commands/system';
|
|
11
|
+
import { registerConfigCommand } from './commands/config';
|
|
12
|
+
import { registerInterruptCommand } from './commands/interrupt';
|
|
13
|
+
const program = new Command();
|
|
14
|
+
program
|
|
15
|
+
.name('comfy')
|
|
16
|
+
.description('A CLI tool for ComfyUI designed for LLM interactions')
|
|
17
|
+
.version('0.1.0');
|
|
18
|
+
// 注册功能命令
|
|
19
|
+
registerGenerateCommand(program);
|
|
20
|
+
registerEditCommand(program);
|
|
21
|
+
registerVideoCommand(program);
|
|
22
|
+
// 注册核心命令
|
|
23
|
+
registerWorkflowCommand(program);
|
|
24
|
+
registerQueueCommand(program);
|
|
25
|
+
registerModelCommand(program);
|
|
26
|
+
registerNodeCommand(program);
|
|
27
|
+
registerSystemCommand(program);
|
|
28
|
+
registerConfigCommand(program);
|
|
29
|
+
registerInterruptCommand(program);
|
|
30
|
+
program.parse();
|
|
31
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAC9D,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAC9D,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AAEhE,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,OAAO,CAAC;KACb,WAAW,CAAC,sDAAsD,CAAC;KACnE,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,SAAS;AACT,uBAAuB,CAAC,OAAO,CAAC,CAAC;AACjC,mBAAmB,CAAC,OAAO,CAAC,CAAC;AAC7B,oBAAoB,CAAC,OAAO,CAAC,CAAC;AAE9B,SAAS;AACT,uBAAuB,CAAC,OAAO,CAAC,CAAC;AACjC,oBAAoB,CAAC,OAAO,CAAC,CAAC;AAC9B,oBAAoB,CAAC,OAAO,CAAC,CAAC;AAC9B,mBAAmB,CAAC,OAAO,CAAC,CAAC;AAC7B,qBAAqB,CAAC,OAAO,CAAC,CAAC;AAC/B,qBAAqB,CAAC,OAAO,CAAC,CAAC;AAC/B,wBAAwB,CAAC,OAAO,CAAC,CAAC;AAElC,OAAO,CAAC,KAAK,EAAE,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export declare class ComfyAPIClient {
|
|
2
|
+
private client;
|
|
3
|
+
constructor();
|
|
4
|
+
getSystemStats(): Promise<any>;
|
|
5
|
+
getQueue(): Promise<any>;
|
|
6
|
+
submitWorkflow(workflow: any): Promise<any>;
|
|
7
|
+
getHistory(promptId?: string): Promise<any>;
|
|
8
|
+
clearQueue(): Promise<any>;
|
|
9
|
+
deleteQueueItem(itemId: string): Promise<any>;
|
|
10
|
+
interrupt(): Promise<any>;
|
|
11
|
+
listModels(folder?: string): Promise<any>;
|
|
12
|
+
getObjectInfo(nodeClass?: string): Promise<any>;
|
|
13
|
+
uploadImage(file: Buffer, filename: string): Promise<{
|
|
14
|
+
name: string;
|
|
15
|
+
}>;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/services/api.ts"],"names":[],"mappings":"AAIA,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAgB;;IAUxB,cAAc;IAKd,QAAQ;IAKR,cAAc,CAAC,QAAQ,EAAE,GAAG;IAK5B,UAAU,CAAC,QAAQ,CAAC,EAAE,MAAM;IAM5B,UAAU;IAKV,eAAe,CAAC,MAAM,EAAE,MAAM;IAK9B,SAAS;IAKT,UAAU,CAAC,MAAM,CAAC,EAAE,MAAM;IAM1B,aAAa,CAAC,SAAS,CAAC,EAAE,MAAM;IAMhC,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CAU7E"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import axios from 'axios';
|
|
2
|
+
import FormData from 'form-data';
|
|
3
|
+
import { getConfig } from './config';
|
|
4
|
+
export class ComfyAPIClient {
|
|
5
|
+
client;
|
|
6
|
+
constructor() {
|
|
7
|
+
const config = getConfig();
|
|
8
|
+
this.client = axios.create({
|
|
9
|
+
baseURL: config.server,
|
|
10
|
+
timeout: config.timeout,
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
async getSystemStats() {
|
|
14
|
+
const response = await this.client.get('/system_stats');
|
|
15
|
+
return response.data;
|
|
16
|
+
}
|
|
17
|
+
async getQueue() {
|
|
18
|
+
const response = await this.client.get('/queue');
|
|
19
|
+
return response.data;
|
|
20
|
+
}
|
|
21
|
+
async submitWorkflow(workflow) {
|
|
22
|
+
const response = await this.client.post('/prompt', { prompt: workflow });
|
|
23
|
+
return response.data;
|
|
24
|
+
}
|
|
25
|
+
async getHistory(promptId) {
|
|
26
|
+
const url = promptId ? `/history/${promptId}` : '/history';
|
|
27
|
+
const response = await this.client.get(url);
|
|
28
|
+
return response.data;
|
|
29
|
+
}
|
|
30
|
+
async clearQueue() {
|
|
31
|
+
const response = await this.client.post('/queue', { clear: true });
|
|
32
|
+
return response.data;
|
|
33
|
+
}
|
|
34
|
+
async deleteQueueItem(itemId) {
|
|
35
|
+
const response = await this.client.post('/queue', { delete: [itemId] });
|
|
36
|
+
return response.data;
|
|
37
|
+
}
|
|
38
|
+
async interrupt() {
|
|
39
|
+
const response = await this.client.post('/interrupt');
|
|
40
|
+
return response.data;
|
|
41
|
+
}
|
|
42
|
+
async listModels(folder) {
|
|
43
|
+
const url = folder ? `/models/${folder}` : '/models';
|
|
44
|
+
const response = await this.client.get(url);
|
|
45
|
+
return response.data;
|
|
46
|
+
}
|
|
47
|
+
async getObjectInfo(nodeClass) {
|
|
48
|
+
const url = nodeClass ? `/object_info/${nodeClass}` : '/object_info';
|
|
49
|
+
const response = await this.client.get(url);
|
|
50
|
+
return response.data;
|
|
51
|
+
}
|
|
52
|
+
async uploadImage(file, filename) {
|
|
53
|
+
const formData = new FormData();
|
|
54
|
+
formData.append('image', file, filename);
|
|
55
|
+
formData.append('overwrite', 'true');
|
|
56
|
+
const response = await this.client.post('/upload/image', formData, {
|
|
57
|
+
headers: formData.getHeaders(),
|
|
58
|
+
});
|
|
59
|
+
return response.data;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/services/api.ts"],"names":[],"mappings":"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"}
|