### ComfyUI CLI Quick Start Source: https://github.com/comfy-addons/comfyui-sdk/blob/main/README.md A quick start example demonstrating how to run a ComfyUI workflow using the CLI, specifying input values for nodes and prompts. ```bash cfli -f workflow.json \ -i 4.inputs.ckpt_name=SDXL/realvisxlV40_v40LightningBakedvae.safetensors \ -i 5.inputs.width=1024 \ -i 5.inputs.height=1024 \ -p 6.inputs.text="A picture of cute cat" ``` -------------------------------- ### Install ComfyUI SDK Source: https://github.com/comfy-addons/comfyui-sdk/wiki/ComfyPool-‐-Manager-multiple-API-instance Install the ComfyUI SDK using npm. This command is used for project setup. ```bash npm install @saintno/comfyui-sdk ``` -------------------------------- ### npm/npx Installation and Execution Flow Source: https://github.com/comfy-addons/comfyui-sdk/blob/main/plans/cli-plan.md Explains how npm and npx handle the installation and execution of the ComfyUI SDK CLI, demonstrating the symlinking process for global installs and the temporary download for npx. ```text npm install -g @saintno/comfyui-sdk ↓ npm reads package.json → sees "bin": { "cfli": "./dist/cli.js" } ↓ npm creates symlink: /usr/local/bin/cfli → /usr/local/lib/node_modules/@saintno/comfyui-sdk/dist/cli.js ↓ user runs: cfli -f workflow.json ↓ Node.js executes dist/cli.js (shebang: #!/usr/bin/env node) ``` ```text npx @saintno/comfyui-sdk -f workflow.json ↓ npx downloads @saintno/comfyui-sdk (if not cached) ↓ npx looks up "bin" field → finds "cfli" → ./dist/cli.js ↓ npx runs: node ./dist/cli.js -f workflow.json ``` -------------------------------- ### Install ComfyUI CLI Source: https://github.com/comfy-addons/comfyui-sdk/blob/main/plans/cli-plan.md Install the `cfli` tool globally using npm or run it directly with npx or bunx. Verify the installation by checking the version. ```bash npm install -g @saintno/comfyui-sdk ``` ```bash npx @saintno/comfyui-sdk -f workflow.json -i 6.inputs.text="hello" ``` ```bash bunx @saintno/comfyui-sdk -f workflow.json -i 6.inputs.text="hello" ``` ```bash cfli --version ``` -------------------------------- ### Install ComfyUI SDK Source: https://context7.com/comfy-addons/comfyui-sdk/llms.txt Install the ComfyUI SDK using npm or bun. ```bash npm install @saintno/comfyui-sdk ``` ```bash # or bun add @saintno/comfyui-sdk ``` -------------------------------- ### Installation Source: https://github.com/comfy-addons/comfyui-sdk/wiki/Home Install the ComfyUI SDK using npm or bun. ```APIDOC ## Installation Install the package using npm: ```bash npm install @saintno/comfyui-sdk ``` Or using bun: ```bash bun add @saintno/comfyui-sdk ``` ``` -------------------------------- ### CLI Build Script Example Source: https://github.com/comfy-addons/comfyui-sdk/blob/main/plans/cli-plan.md Example of a Bun build script configuration for the CLI, specifying target, format, and minification. It includes prepending a shebang and setting execute permissions. ```typescript Bun.build({ entrypoints: ["./cli/bin.ts"], outdir: "./dist", target: "bun", format: "esm", minify: true, }).then(output => { // Prepend shebang and set permissions const shebang = "#!/usr/bin/env node\n"; const filePath = "./dist/cli.js"; const fileContent = Bun.file(filePath).textSync(); Bun.write(filePath, shebang + fileContent); // Set execute permissions (0o755) // Note: Bun.file().chmodSync() is not available, manual chmod might be needed or handled by OS/deployment }); ``` -------------------------------- ### Install ComfyUI SDK with bun Source: https://github.com/comfy-addons/comfyui-sdk/wiki/Home Install the ComfyUI SDK package using bun. This is an alternative package manager. ```bash bun add @saintno/comfyui-sdk ``` -------------------------------- ### Install Shell Autocompletions Source: https://github.com/comfy-addons/comfyui-sdk/blob/main/plans/cli-plan.md Set up shell autocompletions for the `cfli` command. This is a one-time setup that enables tab completion for CLI arguments and workflow inputs. ```bash eval "$(cfli completions bash)" ``` ```bash cfli completions zsh > ~/.zfunc/_cfli ``` ```bash cfli completions fish > ~/.config/fish/completions/cfli.fish ``` -------------------------------- ### Install ComfyUI SDK with npm Source: https://github.com/comfy-addons/comfyui-sdk/blob/main/README.md Install the ComfyUI SDK using the npm package manager. ```bash npm i @saintno/comfyui-sdk ``` -------------------------------- ### Basic Usage Example Source: https://github.com/comfy-addons/comfyui-sdk/wiki/ComfyPool-‐-Manager-multiple-API-instance Illustrates how to initialize ComfyPool, set up event listeners, define a generation function, and run jobs in batch. ```APIDOC ## Usage Example ```typescript import { ComfyApi, ComfyPool, EQueueMode, PromptBuilder, CallWrapper } from '@saintno/comfyui-sdk'; // Define credentials for authentication const credentials = { type: "basic", username: "username", password: "password", }; // Create a pool of ComfyApi instances const ApiPool = new ComfyPool( [ new ComfyApi("http://localhost:8188", "node-1", { credentials }), new ComfyApi("http://localhost:8189", "node-2", { credentials }), ], EQueueMode.PICK_ZERO ); // Set up event listeners ApiPool.on("init", () => console.log("Pool is initializing")) .on("loading_client", (ev) => console.log("Loading client", ev.detail.clientIdx)) .on("add_job", (ev) => console.log("Job added", ev.detail.jobIdx)); // Define a workflow using PromptBuilder const Txt2ImgPrompt = new PromptBuilder(ExampleTxt2ImgWorkflow, [...]); // Define a generation function const generateFn = async (api: ComfyApi, clientIdx?: number) => { // Set up workflow inputs const workflow = Txt2ImgPrompt.input("checkpoint", "SDXL/realvisxlV40_v40LightningBakedvae.safetensors") .input("seed", seed()) .input("step", 6) // ... other inputs ... // Use CallWrapper to handle the API call return new Promise((resolve) => { new CallWrapper(api, workflow) .onPending((promptId) => console.log(`[${clientIdx}]`, `#${promptId}`, "Task is pending")) .onStart((promptId) => console.log(`[${clientIdx}]`, `#${promptId}`, "Task is started")) // ... other event handlers ... .run(); }); }; // Run multiple jobs using batch const output = await ApiPool.batch(Array(10).fill("").map(() => generateFn)); console.log(output.flat()); ``` ``` -------------------------------- ### Basic ComfyUI Workflow Execution Source: https://github.com/comfy-addons/comfyui-sdk/blob/main/README.md Use this to quickly get started with ComfyUI API. It initializes the API, defines a text-to-image workflow using PromptBuilder, sets input parameters, and runs the workflow. ```typescript import { ComfyApi, CallWrapper, PromptBuilder, TSamplerName, TSchedulerName, seed } from "@saintno/comfyui-sdk"; import ExampleTxt2ImgWorkflow from "./example-txt2img-workflow.json"; const api = new ComfyApi("http://localhost:8189").init(); const workflow = new PromptBuilder( ExampleTxt2ImgWorkflow, ["positive", "negative", "checkpoint", "seed", "batch", "step", "cfg", "sampler", "sheduler", "width", "height"], ["images"] ) .setInputNode("checkpoint", "4.inputs.ckpt_name") .setInputNode("seed", "3.inputs.seed") .setInputNode("batch", "5.inputs.batch_size") .setInputNode("negative", "7.inputs.text") .setInputNode("positive", "6.inputs.text") .setInputNode("cfg", "3.inputs.cfg") .setInputNode("sampler", "3.inputs.sampler_name") .setInputNode("sheduler", "3.inputs.scheduler") .setInputNode("step", "3.inputs.steps") .setInputNode("width", "5.inputs.width") .setInputNode("height", "5.inputs.height") .setOutputNode("images", "9") .input("checkpoint", "SDXL/realvisxlV40_v40LightningBakedvae.safetensors", api.osType) .input("seed", seed()) .input("step", 6) .input("cfg", 1) .input("sampler", "dpmpp_2m_sde_gpu") .input("sheduler", "sgm_uniform") .input("width", 1024) .input("height", 1024) .input("batch", 1) .input("positive", "A picture of cute dog on the street"); new CallWrapper(api, workflow) .onFinished((data) => console.log(data.images?.images.map((img: any) => api.getPathImage(img)))) .run(); ``` -------------------------------- ### Run ComfyUI Workflow with CLI (Install globally) Source: https://github.com/comfy-addons/comfyui-sdk/blob/main/README.md Install the ComfyUI SDK CLI globally to run workflows from the terminal. This command is included with the SDK installation. ```bash npm install -g @saintno/comfyui-sdk ``` -------------------------------- ### ComfyApi Client Initialization Source: https://github.com/comfy-addons/comfyui-sdk/blob/main/AGENTS.md Example of initializing the ComfyApi client, which is the main entry point for server communication and extends EventTarget. Ensure the host is correctly configured. ```typescript import { ComfyApi } from "@saintno/comfyui-sdk"; const api = new ComfyApi({ host: "http://127.0.0.1:8188", }); ``` -------------------------------- ### ComfyUI CLI List Samplers Source: https://github.com/comfy-addons/comfyui-sdk/blob/main/plans/cli-plan.md Example of using the `cfli list samplers` command to retrieve a list of available samplers and schedulers supported by the ComfyUI server. ```bash cfli list samplers # samplers: euler, euler_ancestral, dpmpp_2m_sde_gpu, ... # schedulers: normal, karras, sgm_uniform, ... ``` -------------------------------- ### ComfyApi - Server Information Methods Source: https://context7.com/comfy-addons/comfyui-sdk/llms.txt Provides examples for retrieving server statistics, available models (checkpoints, LoRAs), sampler/scheduler information, node definitions, extensions, and embeddings. ```APIDOC ## ComfyApi - Server Information Methods Methods to retrieve system information, available models, extensions, and node definitions from the ComfyUI server. ```typescript import { ComfyApi } from "@saintno/comfyui-sdk"; const api = new ComfyApi("http://localhost:8188").init(); await api.waitForReady(); // Get system stats (OS type, Python version, GPU info) const stats = await api.getSystemStats(); console.log("OS:", stats.system.os); console.log("Python:", stats.system.python_version); console.log("GPU VRAM:", stats.devices[0].vram_total); // Get available models const checkpoints = await api.getCheckpoints(); console.log("Available checkpoints:", checkpoints); const loras = await api.getLoras(); console.log("Available LoRAs:", loras); // Get sampler and scheduler info const samplerInfo = await api.getSamplerInfo(); console.log("Samplers:", samplerInfo.sampler); console.log("Schedulers:", samplerInfo.scheduler); // Get node definitions const nodeDefs = await api.getNodeDefs("KSampler"); console.log("KSampler inputs:", nodeDefs?.KSampler.input.required); // Get extensions and embeddings const extensions = await api.getExtensions(); const embeddings = await api.getEmbeddings(); ``` ``` -------------------------------- ### Manage User Data and Settings with ComfyApi Source: https://context7.com/comfy-addons/comfyui-sdk/llms.txt Shows how to get, store, and retrieve user settings and data files. Also includes methods for listing, moving, and deleting user data, and freeing GPU memory. Ensure the ComfyAPI is initialized and ready. ```typescript import { ComfyApi } from "@saintno/comfyui-sdk"; const api = new ComfyApi("http://localhost:8188").init(); await api.waitForReady(); // Get and store settings const settings = await api.getSettings(); console.log("Current settings:", settings); await api.storeSetting("my.custom.setting", "value"); const mySetting = await api.getSetting("my.custom.setting"); // Store user data files await api.storeUserData("my-workflow.json", { nodes: [], connections: [] }); // Retrieve user data const response = await api.getUserData("my-workflow.json"); const data = await response.json(); // List user data files const files = await api.listUserData("workflows", true, false); console.log("User workflows:", files); // List with metadata (v2 API) const filesV2 = await api.listUserDataV2("workflows"); filesV2.forEach(f => console.log(`${f.name}: ${f.size} bytes, modified: ${f.modified}`)); // Move and delete user data await api.moveUserData("old-workflow.json", "archived/old-workflow.json"); await api.deleteUserData("temp-file.json"); // Free GPU memory await api.freeMemory(true, true); // unload models and free memory ``` -------------------------------- ### ComfyUI CLI Workflow Execution Source: https://context7.com/comfy-addons/comfyui-sdk/llms.txt Install and use the `cfli` command-line tool to execute ComfyUI workflows directly from the terminal. ```bash # Install globally npm install -g @saintno/comfyui-sdk # Basic workflow execution cfli -f workflow.json ``` -------------------------------- ### Testing CLI Completions Source: https://github.com/comfy-addons/comfyui-sdk/blob/main/plans/cli-plan.md Example commands for testing the ComfyUI CLI tab completion functionality. Verifies node path and server-side value completion, including fallback behavior when the server is not running. ```bash # Test with no server running → falls back to workflow value # Test each shell: source completion script, verify TAB works cfli __complete --cursor "cfli -f sample.json -i 4.in" # → outputs node paths starting with 4.in cfli __complete --cursor "cfli -f sample.json -i 4.inputs.ckpt_name=" # → outputs checkpoint filenames ``` -------------------------------- ### ComfyUI SDK Configuration File Example Source: https://github.com/comfy-addons/comfyui-sdk/blob/main/plans/cli-plan.md This JSON configuration file can be used to set default parameters for the ComfyUI SDK CLI. CLI arguments will override these settings, which in turn override environment variables. ```json { "host": "http://192.168.14.93:8188", "timeout": 120000, "output": "./output", "download": true, "token": null } ``` -------------------------------- ### Run ComfyUI Workflow with CLI (npx) Source: https://github.com/comfy-addons/comfyui-sdk/blob/main/README.md Execute ComfyUI workflows directly from the terminal using npx without a global installation. ```bash npx @saintno/comfyui-sdk -f workflow.json --json ``` -------------------------------- ### ComfyUI CLI List Checkpoints Source: https://github.com/comfy-addons/comfyui-sdk/blob/main/plans/cli-plan.md Example of using the `cfli list checkpoints` command to query the server for available model checkpoints. The output lists filenames of compatible checkpoints. ```bash cfli list checkpoints # SDXL/realvisxlV40_v40LightningBakedvae.safetensors # v1-5-pruned-emaonly.ckpt # ... ``` -------------------------------- ### package.json bin Field Configuration Source: https://github.com/comfy-addons/comfyui-sdk/blob/main/plans/cli-plan.md Defines the 'cfli' command in package.json, enabling it to be linked globally via npm install -g or run using npx. ```json { "bin": { "cfli": "./dist/cli.js" } } ``` -------------------------------- ### ComfyApi - Queue Management Source: https://context7.com/comfy-addons/comfyui-sdk/llms.txt Illustrates how to manage the ComfyUI execution queue, including getting queue status, queuing prompts, retrieving history, interrupting executions, and clearing the queue or history. ```APIDOC ## ComfyApi - Queue Management Methods to manage the execution queue, retrieve history, and interrupt running prompts. ```typescript import { ComfyApi } from "@saintno/comfyui-sdk"; const api = new ComfyApi("http://localhost:8188").init(); await api.waitForReady(); // Get current queue state const queue = await api.getQueue(); console.log("Running:", queue.queue_running.length); console.log("Pending:", queue.queue_pending.length); // Queue a prompt (workflow JSON) const workflow = { /* your workflow JSON */ }; const response = await api.queuePrompt(null, workflow); // null = append to end console.log("Prompt ID:", response.prompt_id); // Queue with priority (-1 = front of queue) const urgentResponse = await api.queuePrompt(-1, workflow); // Get execution history const histories = await api.getHistories(50); // last 50 items const specificHistory = await api.getHistory(response.prompt_id); // Interrupt current execution await api.interrupt(); // Clear history or delete specific items await api.clearHistory({ clear: true }); // clear all await api.clearHistory({ delete: ["prompt-id-1", "prompt-id-2"] }); // Manage queue await api.manageQueue({ clear: true }); // clear pending await api.manageQueue({ delete: ["prompt-id-to-cancel"] }); ``` ``` -------------------------------- ### Build SDK and CLI Commands Source: https://github.com/comfy-addons/comfyui-sdk/blob/main/plans/cli-plan.md Commands to build the SDK, CLI, or both for publishing. ```bash # Build SDK only (existing, unchanged) bun run build # Build CLI only bun run build:cli # Build both (for publishing) bun run build:all ``` -------------------------------- ### Basic Usage: Setting up ComfyApi Source: https://github.com/comfy-addons/comfyui-sdk/wiki/Home Initialize a ComfyApi instance to connect to a single ComfyUI instance. ```APIDOC ## Basic Usage: Setting up a ComfyApi instance ```typescript import { ComfyApi } from "@saintno/comfyui-sdk"; const api = new ComfyApi("http://localhost:8188", "client-id"); ``` ``` -------------------------------- ### ComfyApi - Core Client Initialization and Event Handling Source: https://context7.com/comfy-addons/comfyui-sdk/llms.txt Demonstrates how to initialize the ComfyApi client, handle authentication, and set up event listeners for connection status and progress updates. ```APIDOC ## ComfyApi - Core Client The main client class for connecting to and interacting with a ComfyUI server instance. Handles WebSocket connections, authentication, and all API endpoints. ```typescript import { ComfyApi } from "@saintno/comfyui-sdk"; // Basic initialization const api = new ComfyApi("http://localhost:8188").init(); // With authentication options const apiWithAuth = new ComfyApi("http://localhost:8188", "my-client-id", { credentials: { type: "basic", username: "admin", password: "secret" }, wsTimeout: 15000, listenTerminal: true }).init(); // Wait for connection to be ready await api.waitForReady(); // Event listeners api.on("connected", () => console.log("Connected to ComfyUI")); api.on("disconnected", () => console.log("Disconnected")); api.on("progress", (ev) => console.log(`Progress: ${ev.detail.value}/${ev.detail.max}`)); api.on("status", (ev) => console.log("Queue remaining:", ev.detail.status.exec_info.queue_remaining)); // Cleanup when done api.destroy(); ``` ``` -------------------------------- ### Handle Start Events in CallWrapper Source: https://github.com/comfy-addons/comfyui-sdk/wiki/Home Register a callback function to be notified when a workflow execution starts. The callback receives an optional prompt ID. ```typescript callWrapper.onStart((promptId) => {}) ``` -------------------------------- ### PromptBuilder Constructor and Methods Source: https://github.com/comfy-addons/comfyui-sdk/blob/main/README.md Details on how to construct and manipulate PromptBuilder instances. ```APIDOC ## PromptBuilder ### Constructor ```typescript constructor(prompt: T, inputKeys: I[], outputKeys: O[]) ``` - `prompt`: The initial workflow data object. - `inputKeys`: An array of input node keys. - `outputKeys`: An array of output node keys. ### Methods - `clone()`: Creates a new `PromptBuilder` instance with the same configuration. - `bypass(node: keyof T | (keyof T)[])`: Marks node(s) to be bypassed at generation. - `reinstate(node: keyof T | (keyof T)[])`: Unmarks node(s) from bypass at generation. - `setInputNode(input: I, key: DeepKeys | Array>)`: Sets input node path for a key. - `setRawInputNode(input: I, key: string | string[])`: Sets raw input node path for a key. - `appendInputNode(input: I, key: DeepKeys | Array>)`: Appends a node to the input node path. - `appendRawInputNode(input: I, key: string | string[])`: Appends a node to the raw input node path. - `setOutputNode(output: O, key: DeepKeys)`: Sets output node path for a key. - `setRawOutputNode(output: O, key: string)`: Sets raw output node path for a key. - `input(key: I, value: V, encodeOs?: OSType)`: Sets an input value. - `inputRaw(key: string, value: V, encodeOs?: OSType)`: Sets a raw input value with dynamic key. - `get workflow`: Retrieves the workflow object. - `get caller`: Retrieves current `PromptBuilder` object. ``` -------------------------------- ### Manage ComfyUI Extensions Source: https://github.com/comfy-addons/comfyui-sdk/blob/main/README.md Use ManagerFeature to interact with ComfyUI Manager Extension. Ensure the extension is installed. This snippet retrieves and logs the list of installed extensions. ```typescript const api = new ComfyApi("http://localhost:8189").init(); await api.waitForReady(); if (api.ext.manager.isSupported) { await api.ext.manager.getExtensionList().then(console.log); // Check api.ext.manager for more methods } ``` -------------------------------- ### Build Standalone Binaries with Bun Source: https://github.com/comfy-addons/comfyui-sdk/blob/main/plans/cli-plan.md These commands demonstrate how to compile the ComfyUI SDK CLI into standalone binaries for different operating systems and architectures using Bun. This is an optional distribution method. ```bash bun build --compile cli/bin.ts --target=bun-linux-x64 --outfile cfli-linux ``` ```bash bun build --compile cli/bin.ts --target=bun-darwin-arm64 --outfile cfli-mac ``` -------------------------------- ### Get All Settings Source: https://github.com/comfy-addons/comfyui-sdk/wiki/ComfyApi-‐-Comfy-client-for-interact-with-ComfyUI-Web-instance Retrieves all setting values for the current user. ```typescript getSettings() ``` -------------------------------- ### Best Practices Source: https://github.com/comfy-addons/comfyui-sdk/wiki/Home Recommended practices for using the ComfyUI SDK effectively. ```APIDOC ## Best Practices ### Recommendations 1. Always use `PromptBuilder` to ensure type safety when constructing workflows. 2. Utilize `ComfyPool` for managing multiple ComfyUI instances to improve reliability and load distribution. 3. Implement proper error handling using the provided event callbacks. 4. Use the `batch` method of `ComfyPool` for parallel execution of multiple workflows. ``` -------------------------------- ### Get Checkpoints Source: https://github.com/comfy-addons/comfyui-sdk/wiki/ComfyApi-‐-Comfy-client-for-interact-with-ComfyUI-Web-instance Retrieves the available checkpoints from the Comfy server. ```typescript getCheckpoints() ``` -------------------------------- ### Get Specific Setting Source: https://github.com/comfy-addons/comfyui-sdk/wiki/ComfyApi-‐-Comfy-client-for-interact-with-ComfyUI-Web-instance Retrieves a specific user setting by its ID. ```typescript getSetting(id: string) ``` -------------------------------- ### Get Queue Status Source: https://github.com/comfy-addons/comfyui-sdk/wiki/ComfyApi-‐-Comfy-client-for-interact-with-ComfyUI-Web-instance Retrieves the current status of the prompt queue. ```typescript getQueue() ``` -------------------------------- ### Build and Test Commands Source: https://github.com/comfy-addons/comfyui-sdk/blob/main/CLAUDE.md Commands for building the SDK bundles and running unit or integration tests. Integration tests require the COMFYUI_HOST environment variable to be set. ```bash bun run build # Build dist bundles + types ``` ```bash bun test # Unit tests only (integration auto-skipped) ``` ```bash bun run test:integration # Full suite against http://192.168.14.93:8188 ``` ```bash COMFYUI_HOST=http://host:8188 bun test # Run with custom server ``` -------------------------------- ### Get User Configuration Source: https://github.com/comfy-addons/comfyui-sdk/wiki/ComfyApi-‐-Comfy-client-for-interact-with-ComfyUI-Web-instance Retrieves the user configuration data from the Comfy API. ```typescript getUserConfig() ``` -------------------------------- ### Initialize and Use ComfyPool for Multi-Instance Management Source: https://context7.com/comfy-addons/comfyui-sdk/llms.txt Demonstrates initializing ComfyPool with multiple ComfyAPI instances, setting up event listeners, defining a generation function, and running single or batch jobs. It also shows how to filter clients, pick specific clients, change queue modes, and manage clients dynamically. ```typescript import { ComfyApi, ComfyPool, EQueueMode, CallWrapper, PromptBuilder } from "@saintno/comfyui-sdk"; import workflow from "./workflow.json"; // Create pool with multiple instances const pool = new ComfyPool( [ new ComfyApi("http://localhost:8188"), new ComfyApi("http://localhost:8189"), new ComfyApi("http://192.168.1.100:8188") ], EQueueMode.PICK_ZERO // Pick clients with empty queue first ) .on("init", () => console.log("Pool initializing")) .on("added", (ev) => console.log(`Client ${ev.detail.clientIdx} added`)) .on("ready", (ev) => console.log(`Client ${ev.detail.clientIdx} ready`)) .on("connected", (ev) => console.log(`Client ${ev.detail.clientIdx} connected`)) .on("disconnected", (ev) => console.log(`Client ${ev.detail.clientIdx} disconnected`)) .on("idle", (ev) => console.log(`Client idle`)) .on("have_job", (ev) => console.log(`Jobs remaining: ${ev.detail.remain}`)) .on("add_job", (ev) => console.log(`Job added at index ${ev.detail.jobIdx}`)) .on("execution_error", (ev) => console.error(`Error on client ${ev.detail.clientIdx}:`, ev.detail.error)); // Define generation function const generateImage = async (api: ComfyApi, clientIdx?: number) => { const builder = new PromptBuilder(workflow, ["positive", "seed"], ["images"]) .setInputNode("positive", "6.inputs.text") .setInputNode("seed", "3.inputs.seed") .setOutputNode("images", "9") .input("positive", "A cute cat") .input("seed", Math.floor(Math.random() * 1000000000)); return new Promise((resolve, reject) => { new CallWrapper(api, builder) .onFinished((data) => { const urls = data.images?.images?.map((img: any) => api.getPathImage(img)) || []; resolve(urls); }) .onFailed((err) => reject(err)) .run(); }); }; // Run single job const singleResult = await pool.run(generateImage); console.log("Single result:", singleResult); // Run batch of jobs (distributed across available clients) const batchResults = await pool.batch( Array(10).fill(generateImage), 5 // weight (lower = higher priority) ); console.log("Batch results:", batchResults.flat()); // Filter which clients can handle jobs const filteredResult = await pool.run(generateImage, 0, { includeIds: ["client-id-1", "client-id-2"], // only use these excludeIds: ["slow-client-id"] }); // Pick specific client const client0 = pool.pick(0); const clientById = pool.pickById("my-client-id"); // Change queue mode pool.changeMode(EQueueMode.PICK_LOWEST); // Pick client with shortest queue pool.changeMode(EQueueMode.PICK_ROUTINE); // Round-robin // Manage clients dynamically pool.addClient(new ComfyApi("http://localhost:8190")); pool.removeClientByIndex(2); // Cleanup pool.destroy(); ``` -------------------------------- ### Get Sampler Information Source: https://github.com/comfy-addons/comfyui-sdk/wiki/ComfyApi-‐-Comfy-client-for-interact-with-ComfyUI-Web-instance Retrieves sampler and scheduler information from the Comfy API. ```typescript getSamplerInfo() ``` -------------------------------- ### Get LoRAs Source: https://github.com/comfy-addons/comfyui-sdk/wiki/ComfyApi-‐-Comfy-client-for-interact-with-ComfyUI-Web-instance Retrieves the LoRA models from the node definitions on the Comfy server. ```typescript getLoras() ``` -------------------------------- ### Initialize ComfyApi Instance Source: https://github.com/comfy-addons/comfyui-sdk/wiki/Home Set up a ComfyApi instance to interact with a single ComfyUI instance. Provide the host URL and a client ID. ```typescript import { ComfyApi } from "@saintno/comfyui-sdk"; const api = new ComfyApi("http://localhost:8188", "client-id"); ``` -------------------------------- ### Initialize and Use ComfyPool Source: https://github.com/comfy-addons/comfyui-sdk/wiki/ComfyPool-‐-Manager-multiple-API-instance Demonstrates initializing ComfyPool with multiple ComfyApi instances, setting up event listeners, defining a generation function with PromptBuilder and CallWrapper, and running batch jobs. ```typescript import { ComfyApi, ComfyPool, EQueueMode, PromptBuilder, CallWrapper } from '@saintno/comfyui-sdk'; // Define credentials for authentication const credentials = { type: "basic", username: "username", password: "password", }; // Create a pool of ComfyApi instances const ApiPool = new ComfyPool( [ new ComfyApi("http://localhost:8188", "node-1", { credentials }), new ComfyApi("http://localhost:8189", "node-2", { credentials }), ], EQueueMode.PICK_ZERO ); // Set up event listeners ApiPool.on("init", () => console.log("Pool is initializing")) .on("loading_client", (ev) => console.log("Loading client", ev.detail.clientIdx)) .on("add_job", (ev) => console.log("Job added", ev.detail.jobIdx)); // Define a workflow using PromptBuilder const Txt2ImgPrompt = new PromptBuilder(ExampleTxt2ImgWorkflow, [...]); // Define a generation function const generateFn = async (api: ComfyApi, clientIdx?: number) => { // Set up workflow inputs const workflow = Txt2ImgPrompt.input("checkpoint", "SDXL/realvisxlV40_v40LightningBakedvae.safetensors") .input("seed", seed()) .input("step", 6) // ... other inputs ... // Use CallWrapper to handle the API call return new Promise((resolve) => { new CallWrapper(api, workflow) .onPending((promptId) => console.log(`[${clientIdx}]`, `#${promptId}`, "Task is pending")) .onStart((promptId) => console.log(`[${clientIdx}]`, `#${promptId}`, "Task is started")) // ... other event handlers ... .run(); }); }; // Run multiple jobs using batch const output = await ApiPool.batch(Array(10).fill("").map(() => generateFn)); console.log(output.flat()); ``` -------------------------------- ### Get System Statistics Source: https://github.com/comfy-addons/comfyui-sdk/wiki/ComfyApi-‐-Comfy-client-for-interact-with-ComfyUI-Web-instance Retrieves system and device statistics from the Comfy API. ```typescript getSystemStats() ``` -------------------------------- ### Get User Data File Source: https://github.com/comfy-addons/comfyui-sdk/wiki/ComfyApi-‐-Comfy-client-for-interact-with-ComfyUI-Web-instance Retrieves a specific user data file by its path. ```typescript getUserData(file: string) ``` -------------------------------- ### Get Image Path Source: https://github.com/comfy-addons/comfyui-sdk/wiki/ComfyApi-‐-Comfy-client-for-interact-with-ComfyUI-Web-instance Returns the file path for a given image information object. ```typescript getPathImage(imageInfo: ImageInfo) ``` -------------------------------- ### Get Embeddings List Source: https://github.com/comfy-addons/comfyui-sdk/wiki/ComfyApi-‐-Comfy-client-for-interact-with-ComfyUI-Web-instance Retrieves a list of embedding names available on the Comfy server. ```typescript getEmbeddings() ``` -------------------------------- ### Configuration Source: https://github.com/comfy-addons/comfyui-sdk/wiki/Home Details on how to configure the ComfyUI SDK, including multiple instances and authentication. ```APIDOC ## Configuration ### Description The library supports various configuration options for managing ComfyUI instances and connections. ### Options - Setting up multiple ComfyUI instances. - Configuring authentication credentials. - Choosing execution modes for the connection pool. Refer to the individual class constructors for specific configuration options. ``` -------------------------------- ### Get Extensions List Source: https://github.com/comfy-addons/comfyui-sdk/wiki/ComfyApi-‐-Comfy-client-for-interact-with-ComfyUI-Web-instance Retrieves a list of available extension URLs from the Comfy API. ```typescript getExtensions() ``` -------------------------------- ### Get Prompt History Source: https://github.com/comfy-addons/comfyui-sdk/wiki/ComfyApi-‐-Comfy-client-for-interact-with-ComfyUI-Web-instance Retrieves the history of prompt executions, with an option to limit the number of items. ```typescript getHistories(maxItems: number = 200) ``` -------------------------------- ### CLI - Running Workflows from Terminal Source: https://context7.com/comfy-addons/comfyui-sdk/llms.txt Instructions for using the `cfli` command-line tool to execute ComfyUI workflows. ```APIDOC ## CLI - Running Workflows from Terminal The `cfli` command-line tool for executing workflows and generating typed builders. ### Installation Install the SDK globally to use the `cfli` command. ```bash npm install -g @saintno/comfyui-sdk ``` ### Basic Workflow Execution Execute a ComfyUI workflow defined in a JSON file. ```bash cfli -f workflow.json ``` ``` -------------------------------- ### Get Node Definitions Source: https://github.com/comfy-addons/comfyui-sdk/wiki/ComfyApi-‐-Comfy-client-for-interact-with-ComfyUI-Web-instance Retrieves node object definitions, optionally filtering by a specific node name. ```typescript getNodeDefs(nodeName?: string) ``` -------------------------------- ### ComfyApi Constructor Source: https://github.com/comfy-addons/comfyui-sdk/blob/main/README.md Initializes the ComfyApi client with host, client ID, and optional settings. ```APIDOC ## ComfyApi Constructor ### Description Initializes the ComfyApi client with the server host, a unique client ID for WebSocket communication, and optional configuration settings. ### Method `constructor(host: string, clientId: string, opts?: { forceWs?: boolean, wsTimeout?: number, credentials?: BasicCredentials | BearerTokenCredentials | CustomCredentials; }) ` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters Details - **host** (string) - Required - The base URL of your ComfyUI server. - **clientId** (string) - Optional - A unique ID for WebSocket communication. Defaults to a generated ID. - **opts** (object) - Optional - Optional settings: - **forceWs** (boolean) - Boolean to force WebSocket usage. - **wsTimeout** (number) - Timeout for WebSocket connections (milliseconds). - **credentials** (BasicCredentials | BearerTokenCredentials | CustomCredentials) - Optional authentication credentials. ``` -------------------------------- ### ComfyApi Get Histories Source: https://github.com/comfy-addons/comfyui-sdk/blob/main/README.md Retrieves the prompt execution history. An optional maximum number of items to fetch can be specified. ```typescript getHistories(maxItems?: number) ``` -------------------------------- ### Queueing a Prompt with ComfyApi Source: https://github.com/comfy-addons/comfyui-sdk/blob/main/AGENTS.md Demonstrates how to queue a prompt using the ComfyApi client. This method is used to run workflows on the ComfyUI server. ```typescript const prompt = { // ... your prompt JSON ... }; const response = await api.queuePrompt(prompt); console.log(response); ``` -------------------------------- ### Get Specific History Entry Source: https://github.com/comfy-addons/comfyui-sdk/wiki/ComfyApi-‐-Comfy-client-for-interact-with-ComfyUI-Web-instance Retrieves a specific prompt execution history entry using its unique ID. ```typescript getHistory(promptId: string) ``` -------------------------------- ### ComfyUI SDK Package Structure Source: https://github.com/comfy-addons/comfyui-sdk/blob/main/plans/cli-plan.md Illustrates the directory layout and key files within the @saintno/comfyui-sdk package, highlighting the SDK exports and CLI source. ```tree @saintno/comfyui-sdk (this package) ├── index.ts # SDK exports (ComfyApi, CallWrapper, etc.) ├── build/ # Bundled SDK (index.esm.js, index.cjs, index.d.ts) ├── cli/ # CLI source (built separately for bin entry) │ ├── bin.ts # thin shim: re-exports and calls main() │ ├── index.ts # entry point — arg parsing, dispatch │ ├── args.ts # CLI argument parser │ ├── runner.ts # Core execution: load workflow, apply overrides, run via SDK │ ├── renderer/ │ │ ├── index.ts # Renderer factory — picks json|terminal|quiet │ │ ├── json.ts # Raw JSON output renderer │ │ ├── terminal.ts # Rich terminal UI (Ink-based React components) │ │ └── quiet.ts # Silent renderer (errors only) │ ├── completions/ │ │ ├── index.ts # Completion engine │ │ ├── bash.ts # Bash completion script generator │ │ ├── zsh.ts # Zsh completion script generator │ │ ├── fish.ts # Fish completion script generator │ │ └── resolver.ts # Resolve completion candidates from workflow + server │ ├── commands/ │ │ ├── run.ts # `cfli run` (default) — execute workflow │ │ ├── inspect.ts # `cfli inspect` — show workflow nodes/inputs summary │ │ ├── queue.ts # `cfli queue` — show server queue status │ │ ├── list.ts # `cfli list checkpoints|loras|embeddings|samplers` │ │ └── download.ts # `cfli download ` — re-download outputs │ └── utils/ │ ├── fs.ts # Workflow loading, output directory creation │ ├── value-parser.ts # Parse `-i key=value` with type coercion │ └── progress.ts # Progress bar helpers └── package.json # exposes "bin": { "cfli": "./dist/cli.js" } ``` -------------------------------- ### ComfyApi init Method Source: https://github.com/comfy-addons/comfyui-sdk/blob/main/README.md Initializes the client and establishes a connection to the ComfyUI server. Supports retries with configurable maximum attempts and delay. ```typescript init(maxTries?: number, delayTime?: number) ``` -------------------------------- ### Execute Workflow with CallWrapper Source: https://github.com/comfy-addons/comfyui-sdk/wiki/Home Execute a constructed workflow using CallWrapper. Attach event listeners for start, progress, and completion. ```typescript import { CallWrapper } from "@saintno/comfyui-sdk"; const workflow = promptBuilder .input("positive", "A beautiful landscape") .input("negative", "blurry, text") .input("seed", 42) .input("steps", 20); new CallWrapper(api, workflow) .onStart((promptId) => console.log(`Task ${promptId} started`)) .onProgress((info, promptId) => console.log(`Task ${promptId} progress:`, info) ) .onFinished((data, promptId) => console.log(`Task ${promptId} finished:`, data) ) .run(); ``` -------------------------------- ### List Available Models on ComfyUI Server Source: https://context7.com/comfy-addons/comfyui-sdk/llms.txt List the available models on a specified ComfyUI server. ```bash cfli list -H http://localhost:8188 ``` -------------------------------- ### Manage Multiple ComfyUI Instances with ComfyPool Source: https://github.com/comfy-addons/comfyui-sdk/blob/main/README.md Demonstrates how to initialize a ComfyPool with multiple ComfyApi instances, set up event listeners, define a workflow generation function, and execute batches of jobs. ```typescript import { ComfyApi, CallWrapper, ComfyPool, EQueueMode, PromptBuilder, seed, TSamplerName, TSchedulerName } from "@saintno/comfyui-sdk"; import ExampleTxt2ImgWorkflow from "./example-txt2img-workflow.json"; const ApiPool = new ComfyPool( [new ComfyApi("http://localhost:8188"), new ComfyApi("http://localhost:8189")], EQueueMode.PICK_ZERO ) .on("init", () => console.log("Pool in initializing")) .on("add_job", (ev) => console.log("Job added at index", ev.detail.jobIdx, "weight:", ev.detail.weight)) .on("added", (ev) => console.log("Client added", ev.detail.clientIdx)); const generateFn = async (api: ComfyApi, clientIdx?: number) => { const workflow = new PromptBuilder( ExampleTxt2ImgWorkflow, ["positive", "negative", "checkpoint", "seed", "batch", "step", "cfg", "sampler", "sheduler", "width", "height"], ["images"] ) .setInputNode("checkpoint", "4.inputs.ckpt_name") .setInputNode("seed", "3.inputs.seed") .setInputNode("batch", "5.inputs.batch_size") .setInputNode("negative", "7.inputs.text") .setInputNode("positive", "6.inputs.text") .setInputNode("step", "3.inputs.steps") .setInputNode("width", "5.inputs.width") .setInputNode("height", "5.inputs.height") .setInputNode("cfg", "3.inputs.cfg") .setInputNode("sampler", "3.inputs.sampler_name") .setInputNode("scheduler", "3.inputs.scheduler") .setOutputNode("images", "9") .input("checkpoint", "SDXL/realvisxlV40_v40LightningBakedvae.safetensors", api.osType) .input("seed", seed()) .input("step", 6) .input("width", 512) .input("height", 512) .input("batch", 2) .input("cfg", 1) .input("sampler", "dpmpp_2m_sde_gpu") .input("scheduler", "sgm_uniform") .input("positive", "A close up picture of cute Cat") .input("negative", "text, blurry, bad picture, nsfw"); return new Promise((resolve) => { new CallWrapper(api, workflow) .onFinished((data) => { const url = data.images?.images.map((img: any) => api.getPathImage(img)); resolve(url as string[]); }) .run(); }); }; const jobA = ApiPool.batch(Array(5).fill(generateFn), 10).then((res) => { console.log("Batch A done"); return res.flat(); }); const jobB = ApiPool.batch(Array(5).fill(generateFn), 0).then((res) => { console.log("Batch B done"); return res.flat(); }); console.log(await Promise.all([jobA, jobB]).then((res) => res.flat())); ``` -------------------------------- ### Create PromptBuilder Instance Source: https://github.com/comfy-addons/comfyui-sdk/wiki/Home Construct a workflow with type-safe inputs and outputs using PromptBuilder. Load your workflow JSON and specify input/output keys. ```typescript import { PromptBuilder } from "@saintno/comfyui-sdk"; import workflowJson from "./workflow.json"; // Get from `Save (API Format)` or `Export (API Format)` from ComfyUI Web const promptBuilder = new PromptBuilder( workflowJson, ["positive", "negative", "seed", "steps"], // Input keys ["images"] // Output keys ) .setInputNode("positive", "6.inputs.text") .setInputNode("negative", "7.inputs.text") .setInputNode("seed", "3.inputs.seed") .setInputNode("steps", "3.inputs.steps") .setOutputNode("images", "9"); ``` -------------------------------- ### Connect to Custom ComfyUI Server Source: https://github.com/comfy-addons/comfyui-sdk/blob/main/plans/cli-plan.md Run a workflow against a ComfyUI server hosted at a custom URL, providing authentication using a bearer token. Ensure the host and token are correctly configured. ```bash cfli -f workflow.json --host https://comfy.example.com --token my-secret-token ``` -------------------------------- ### ComfyUI-Manager Extension Management Source: https://context7.com/comfy-addons/comfyui-sdk/llms.txt Interact with the ComfyUI-Manager extension to manage custom nodes and extensions. Supports checking version, listing extensions, and installing new ones. ```typescript import { ComfyApi } from "@saintno/comfyui-sdk"; const api = new ComfyApi("http://localhost:8188").init(); await api.waitForReady(); // Check if Manager extension is available if (api.ext.manager.isSupported) { // Get Manager version const version = await api.ext.manager.getVersion(); console.log("ComfyUI Manager version:", version); // List installed extensions const extensions = await api.ext.manager.getExtensionList("local", true); if (extensions) { console.log("Channel:", extensions.channel); extensions.custom_nodes.forEach(ext => { console.log(`- ${ext.title}: ${ext.installed ? "installed" : "not installed"}`); }); } // Get node mappings (find which extension provides a node) const nodeMaps = await api.ext.manager.getNodeMapList("local"); nodeMaps.forEach(item => { console.log(`${item.title}: ${item.nodeNames.join(", ")}`); }); // Check for extension updates const updateStatus = await api.ext.manager.checkExtensionUpdate(); console.log("Update available:", updateStatus); // Update all extensions const updateResult = await api.ext.manager.updataAllExtensions(); console.log("Update result:", updateResult); // Install extension from Git URL await api.ext.manager.installExtensionFromGit("https://github.com/user/comfyui-extension.git"); // Install pip packages await api.ext.manager.installPipPackages(["opencv-python", "numpy"]); // Reboot ComfyUI instance await api.ext.manager.rebootInstance(); // Set preview method await api.ext.manager.previewMethod("auto"); } ``` -------------------------------- ### Accessing Manager Feature Source: https://github.com/comfy-addons/comfyui-sdk/blob/main/AGENTS.md Shows how to access the ComfyUI-Manager extension via `api.ext.manager`. Always check `isSupported` before calling manager-specific methods, as the extension may not be installed. ```typescript if (api.ext.manager.isSupported) { const installed = await api.ext.manager.getExtensions(); console.log(installed); } ``` -------------------------------- ### ComfyUI SDK Build Pipeline Commands Source: https://github.com/comfy-addons/comfyui-sdk/blob/main/plans/cli-plan.md Shows the bash commands used to build the SDK and the CLI separately. The CLI is built into a self-contained JavaScript file. ```bash # 1. Build SDK (unchanged) bun run build # → build/index.esm.js, build/index.cjs, build/index.d.ts # 2. Build CLI (new) bun run build:cli # → dist/cli.js (self-contained, no external imports) ``` -------------------------------- ### CLI Main Entry Point Source: https://github.com/comfy-addons/comfyui-sdk/blob/main/plans/cli-plan.md The main entry point for the CLI application. It parses arguments, executes the workflow using the runner, extracts media URLs, and renders the result using the appropriate renderer. Exits the process upon completion. ```typescript import { parseArgs } from './args'; import { runWorkflow } from './runner'; import { createRenderer } from './renderer'; import { extractMediaFromOutputs } from './media'; async function main() { const args = parseArgs(process.argv.slice(2)); const renderer = createRenderer(args.outputFormat); try { const config = { workflowPath: args.filePath, host: args.host, // ... other config from args }; const callbacks = { onProgress: (progress: any) => renderer.onProgress(progress), onResult: (result: any) => { renderer.render(result, callbacks); // Extract and potentially download media if (args.downloadMedia && result._outputs) { extractMediaFromOutputs(config.host, result._outputs, args.outputDir); } }, onError: (error: any) => renderer.onFailed(error), }; await runWorkflow(config, callbacks); process.exit(0); } catch (error) { renderer.onFailed(error); process.exit(1); } } main(); ``` -------------------------------- ### PromptBuilder Constructor Source: https://github.com/comfy-addons/comfyui-sdk/blob/main/README.md Initializes a new PromptBuilder instance with the workflow data, input keys, and output keys. ```typescript constructor(prompt: T, inputKeys: I[], outputKeys: O[]) ```