@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.
Files changed (64) hide show
  1. package/.claude/settings.local.json +20 -0
  2. package/LICENSE +21 -0
  3. package/README.md +228 -0
  4. package/dist/commands/config.d.ts +3 -0
  5. package/dist/commands/config.d.ts.map +1 -0
  6. package/dist/commands/config.js +87 -0
  7. package/dist/commands/config.js.map +1 -0
  8. package/dist/commands/edit.d.ts +3 -0
  9. package/dist/commands/edit.d.ts.map +1 -0
  10. package/dist/commands/edit.js +63 -0
  11. package/dist/commands/edit.js.map +1 -0
  12. package/dist/commands/generate.d.ts +3 -0
  13. package/dist/commands/generate.d.ts.map +1 -0
  14. package/dist/commands/generate.js +51 -0
  15. package/dist/commands/generate.js.map +1 -0
  16. package/dist/commands/interrupt.d.ts +3 -0
  17. package/dist/commands/interrupt.d.ts.map +1 -0
  18. package/dist/commands/interrupt.js +19 -0
  19. package/dist/commands/interrupt.js.map +1 -0
  20. package/dist/commands/model.d.ts +3 -0
  21. package/dist/commands/model.d.ts.map +1 -0
  22. package/dist/commands/model.js +44 -0
  23. package/dist/commands/model.js.map +1 -0
  24. package/dist/commands/node.d.ts +3 -0
  25. package/dist/commands/node.d.ts.map +1 -0
  26. package/dist/commands/node.js +70 -0
  27. package/dist/commands/node.js.map +1 -0
  28. package/dist/commands/queue.d.ts +3 -0
  29. package/dist/commands/queue.d.ts.map +1 -0
  30. package/dist/commands/queue.js +97 -0
  31. package/dist/commands/queue.js.map +1 -0
  32. package/dist/commands/system.d.ts +3 -0
  33. package/dist/commands/system.d.ts.map +1 -0
  34. package/dist/commands/system.js +47 -0
  35. package/dist/commands/system.js.map +1 -0
  36. package/dist/commands/video.d.ts +3 -0
  37. package/dist/commands/video.d.ts.map +1 -0
  38. package/dist/commands/video.js +79 -0
  39. package/dist/commands/video.js.map +1 -0
  40. package/dist/commands/workflow.d.ts +3 -0
  41. package/dist/commands/workflow.d.ts.map +1 -0
  42. package/dist/commands/workflow.js +131 -0
  43. package/dist/commands/workflow.js.map +1 -0
  44. package/dist/index.d.ts +3 -0
  45. package/dist/index.d.ts.map +1 -0
  46. package/dist/index.js +31 -0
  47. package/dist/index.js.map +1 -0
  48. package/dist/services/api.d.ts +17 -0
  49. package/dist/services/api.d.ts.map +1 -0
  50. package/dist/services/api.js +62 -0
  51. package/dist/services/api.js.map +1 -0
  52. package/dist/services/config.d.ts +12 -0
  53. package/dist/services/config.d.ts.map +1 -0
  54. package/dist/services/config.js +21 -0
  55. package/dist/services/config.js.map +1 -0
  56. package/dist/utils/logger.d.ts +5 -0
  57. package/dist/utils/logger.d.ts.map +1 -0
  58. package/dist/utils/logger.js +14 -0
  59. package/dist/utils/logger.js.map +1 -0
  60. package/dist/utils/workflow.d.ts +17 -0
  61. package/dist/utils/workflow.d.ts.map +1 -0
  62. package/dist/utils/workflow.js +78 -0
  63. package/dist/utils/workflow.js.map +1 -0
  64. 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,3 @@
1
+ import { Command } from 'commander';
2
+ export declare function registerQueueCommand(program: Command): void;
3
+ //# sourceMappingURL=queue.d.ts.map
@@ -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,3 @@
1
+ import { Command } from 'commander';
2
+ export declare function registerSystemCommand(program: Command): void;
3
+ //# sourceMappingURL=system.d.ts.map
@@ -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,3 @@
1
+ import { Command } from 'commander';
2
+ export declare function registerVideoCommand(program: Command): void;
3
+ //# sourceMappingURL=video.d.ts.map
@@ -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,3 @@
1
+ import { Command } from 'commander';
2
+ export declare function registerWorkflowCommand(program: Command): void;
3
+ //# sourceMappingURL=workflow.d.ts.map
@@ -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":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAoB,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrF,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,KAAK,MAAM,YAAY,CAAC;AAG/B,MAAM,UAAU,uBAAuB,CAAC,OAAgB;IACtD,MAAM,WAAW,GAAG,OAAO;SACxB,OAAO,CAAC,UAAU,CAAC;SACnB,WAAW,CAAC,OAAO,CAAC,CAAC;IAExB,wBAAwB;IACxB,WAAW;SACR,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,OAAO,CAAC;SACpB,QAAQ,CAAC,QAAQ,EAAE,oBAAoB,CAAC;SACxC,MAAM,CAAC,QAAQ,EAAE,YAAY,CAAC;SAC9B,MAAM,CAAC,QAAQ,EAAE,QAAQ,CAAC;SAC1B,MAAM,CAAC,KAAK,EAAE,IAAY,EAAE,OAAO,EAAE,EAAE;QACtC,IAAI,CAAC;YACH,IAAI,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC;YAEzB,cAAc;YACd,MAAM,QAAQ,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;YAEpC,OAAO;YACP,MAAM,SAAS,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;YAE7C,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACzB,IAAI,CAAC,OAAO,SAAS,CAAC,MAAM,SAAS,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBAC7D,IAAI,CAAC,yCAAyC,CAAC,CAAC;YAClD,CAAC;YAED,cAAc;YACd,MAAM,MAAM,GAAG,IAAI,cAAc,EAAE,CAAC;YACpC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;YAErD,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;gBACjB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;YAC/C,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,QAAQ,CAAC,CAAC;gBAClB,IAAI,CAAC,cAAc,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC;gBAEvC,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;oBACjB,IAAI,CAAC,WAAW,CAAC,CAAC;oBAClB,wBAAwB;oBACxB,IAAI,CAAC,oBAAoB,CAAC,CAAC;gBAC7B,CAAC;qBAAM,CAAC;oBACN,IAAI,CAAC,0BAA0B,MAAM,CAAC,SAAS,QAAQ,CAAC,CAAC;gBAC3D,CAAC;YACH,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,KAAK,CAAC,SAAS,GAAG,EAAE,CAAC,CAAC;YACtB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;IAEL,sBAAsB;IACtB,WAAW;SACR,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,SAAS,CAAC;SACtB,MAAM,CAAC,kBAAkB,EAAE,MAAM,EAAE,IAAI,CAAC;SACxC,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,OAAO,GAAG,MAAM,MAAM,CAAC,UAAU,EAAE,CAAC;YAE1C,MAAM,YAAY,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;YAE/E,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;gBACjB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;YACrD,CAAC;iBAAM,CAAC;gBACN,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBAC9B,IAAI,CAAC,QAAQ,CAAC,CAAC;oBACf,OAAO;gBACT,CAAC;gBAED,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC;oBACtB,IAAI,EAAE,CAAC,WAAW,EAAE,IAAI,EAAE,IAAI,CAAC;oBAC/B,SAAS,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC;iBACxB,CAAC,CAAC;gBAEH,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,EAAE,IAAI,CAAgB,EAAE,EAAE;oBACvD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC;oBACxD,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,EAAE,UAAU,IAAI,GAAG,CAAC;oBACjD,KAAK,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;gBAC5C,CAAC,CAAC,CAAC;gBAEH,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;gBAC9B,IAAI,CAAC,KAAK,YAAY,CAAC,MAAM,MAAM,CAAC,CAAC;YACvC,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,KAAK,CAAC,WAAW,GAAG,EAAE,CAAC,CAAC;YACxB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;IAEL,qBAAqB;IACrB,WAAW;SACR,OAAO,CAAC,KAAK,CAAC;SACd,WAAW,CAAC,SAAS,CAAC;SACtB,QAAQ,CAAC,aAAa,EAAE,WAAW,CAAC;SACpC,MAAM,CAAC,QAAQ,EAAE,YAAY,CAAC;SAC9B,MAAM,CAAC,YAAY,EAAE,QAAQ,CAAC;SAC9B,MAAM,CAAC,gBAAgB,EAAE,MAAM,EAAE,UAAU,CAAC;SAC5C,MAAM,CAAC,KAAK,EAAE,QAAgB,EAAE,OAAO,EAAE,EAAE;QAC1C,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,cAAc,EAAE,CAAC;YACpC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;YAEjD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACtB,KAAK,CAAC,kBAAkB,QAAQ,EAAE,CAAC,CAAC;gBACpC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;YAED,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;YAE9B,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;gBACjB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;YAC7C,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,cAAc,QAAQ,EAAE,CAAC,CAAC;gBAElC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;oBAChB,IAAI,CAAC,OAAO,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;oBACvD,IAAI,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;wBAC3B,IAAI,CAAC,OAAO,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC;oBACxC,CAAC;gBACH,CAAC;gBAED,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;oBACjB,IAAI,CAAC,KAAK,CAAC,CAAC;oBACZ,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;gBACrD,CAAC;gBAED,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;oBACrB,IAAI,CAAC,UAAU,CAAC,CAAC;gBACnB,CAAC;YACH,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,KAAK,CAAC,WAAW,GAAG,EAAE,CAAC,CAAC;YACxB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -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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"}