Update BossAI workflow and workspace experience

This commit is contained in:
boos
2026-05-28 10:32:20 +08:00
parent e0bd9b4194
commit 931bcf3fb9
39 changed files with 7791 additions and 1328 deletions
@@ -0,0 +1,147 @@
#!/usr/bin/env node
import fs from 'fs/promises';
const DEFAULT_PACKS = [
['ComfyUI-Manager', 'https://github.com/Comfy-Org/ComfyUI-Manager.git'],
['christian-byrne/audio-separation-nodes-comfyui', 'https://github.com/christian-byrne/audio-separation-nodes-comfyui.git'],
['yvann-ba/ComfyUI_Yvann-Nodes', 'https://github.com/yvann-ba/ComfyUI_Yvann-Nodes.git'],
['yolain/ComfyUI-Easy-Use', 'https://github.com/yolain/ComfyUI-Easy-Use.git'],
['wildminder/ComfyUI-VoxCPM', 'https://github.com/wildminder/ComfyUI-VoxCPM.git'],
['kijai/ComfyUI-WanVideoWrapper', 'https://github.com/kijai/ComfyUI-WanVideoWrapper.git'],
['civen-cn/ComfyUI-Whisper-Translator', 'https://github.com/civen-cn/ComfyUI-Whisper-Translator.git'],
['kijai/ComfyUI-KJNodes', 'https://github.com/kijai/ComfyUI-KJNodes.git'],
];
const args = new Set(process.argv.slice(2));
const configPath = valueArg('--config') || 'config.toml';
const baseUrl = trimSlash(
process.env.BOOSAPI_COMFYUI__BASE_URL
|| process.env.COMFYUI_CLOUD_BASE_URL
|| (await readComfyConfig(configPath)).base_url
|| 'https://cloud.comfy.org'
);
const apiKey = process.env.BOOSAPI_COMFYUI__API_KEY
|| process.env.COMFYUI_CLOUD_API_KEY
|| (await readComfyConfig(configPath)).api_key
|| '';
const dryRun = args.has('--dry-run');
if (!baseUrl) {
fail('Missing Cloud base URL. Set BOOSAPI_COMFYUI__BASE_URL or [comfyui].base_url.');
}
if (!apiKey) {
fail('Missing Cloud API key. Set BOOSAPI_COMFYUI__API_KEY or [comfyui].api_key.');
}
console.log(`Cloud backend: ${baseUrl}`);
console.log(`Packs: ${DEFAULT_PACKS.length}`);
if (dryRun) {
for (const [id, repository] of DEFAULT_PACKS) {
console.log(`[dry-run] ${id} <- ${repository}`);
}
process.exit(0);
}
await request('GET', '/api/manager/queue/start').catch((error) => {
console.warn(`manager queue start warning: ${error.message}`);
});
const results = [];
for (const [id, repository] of DEFAULT_PACKS) {
const payload = {
id,
version: 'nightly',
selected_version: 'nightly',
repository,
mode: 'remote',
channel: 'default',
skip_post_install: false,
};
try {
await request('POST', '/api/manager/queue/install', payload);
console.log(`queued: ${id}`);
results.push({ id, ok: true });
} catch (error) {
console.error(`failed: ${id}: ${error.message}`);
results.push({ id, ok: false, error: error.message });
}
}
await request('GET', '/api/manager/queue/status')
.then((status) => console.log(`queue status: ${JSON.stringify(status)}`))
.catch((error) => console.warn(`queue status warning: ${error.message}`));
const failed = results.filter((item) => !item.ok);
if (failed.length > 0) {
console.error(`\n${failed.length} pack(s) failed to queue. If Cloud returned 403/404, the hosted backend does not allow Manager installs for this workspace/API key.`);
process.exit(1);
}
console.log('\nAll install jobs were queued. Restart the Cloud ComfyUI runtime if Manager asks for it.');
async function request(method, path, body) {
const response = await fetch(`${baseUrl}${path}`, {
method,
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': `Bearer ${apiKey}`,
'X-API-Key': apiKey,
},
body: body ? JSON.stringify(body) : undefined,
});
const text = await response.text();
const data = text ? safeJson(text) : null;
if (!response.ok) {
throw new Error(`${response.status} ${response.statusText}: ${text.slice(0, 500)}`);
}
return data;
}
function safeJson(text) {
try {
return JSON.parse(text);
} catch {
return { body: text };
}
}
async function readComfyConfig(path) {
const result = {};
let section = '';
let text = '';
try {
text = await fs.readFile(path, 'utf8');
} catch {
return result;
}
for (const rawLine of text.split(/\r?\n/)) {
const line = rawLine.trim();
if (!line || line.startsWith('#')) continue;
const sectionMatch = line.match(/^\[([^\]]+)\]$/);
if (sectionMatch) {
section = sectionMatch[1];
continue;
}
if (section !== 'comfyui') continue;
const match = line.match(/^([A-Za-z0-9_]+)\s*=\s*"(.*)"\s*$/);
if (match) result[match[1]] = match[2];
}
return result;
}
function trimSlash(value) {
return String(value || '').trim().replace(/\/+$/, '');
}
function valueArg(name) {
const prefix = `${name}=`;
const found = process.argv.slice(2).find((arg) => arg.startsWith(prefix));
return found ? found.slice(prefix.length) : '';
}
function fail(message) {
console.error(message);
process.exit(2);
}
+85
View File
@@ -0,0 +1,85 @@
#!/usr/bin/env bash
set -euo pipefail
COMFYUI_DIR="${COMFYUI_DIR:-/workspace/ComfyUI}"
CUSTOM_NODES_DIR="${CUSTOM_NODES_DIR:-$COMFYUI_DIR/custom_nodes}"
PYTHON_BIN="${PYTHON_BIN:-$COMFYUI_DIR/venv/bin/python}"
if [ ! -d "$COMFYUI_DIR" ]; then
echo "ComfyUI directory not found: $COMFYUI_DIR" >&2
exit 1
fi
if [ ! -x "$PYTHON_BIN" ]; then
if command -v python3 >/dev/null 2>&1; then
PYTHON_BIN="$(command -v python3)"
else
echo "Python not found. Set PYTHON_BIN=/path/to/python" >&2
exit 1
fi
fi
mkdir -p "$CUSTOM_NODES_DIR"
install_node() {
local name="$1"
local repo="$2"
local ref="${3:-}"
local dir="$CUSTOM_NODES_DIR/$name"
if [ -d "$dir/.git" ]; then
echo "==> Updating $name"
git -C "$dir" fetch --depth 1 origin "${ref:-HEAD}" || git -C "$dir" fetch origin
else
echo "==> Installing $name"
git clone --depth 1 "$repo" "$dir"
fi
if [ -n "$ref" ]; then
git -C "$dir" checkout --quiet "$ref"
fi
if [ -f "$dir/requirements.txt" ]; then
echo "==> Installing Python requirements for $name"
if command -v uv >/dev/null 2>&1; then
UV_INDEX_URL="${UV_INDEX_URL:-https://pypi.tuna.tsinghua.edu.cn/simple}" \
uv pip install --python "$PYTHON_BIN" -r "$dir/requirements.txt"
else
"$PYTHON_BIN" -m pip install -r "$dir/requirements.txt"
fi
fi
if [ -f "$dir/install.py" ]; then
echo "==> Running install.py for $name"
"$PYTHON_BIN" "$dir/install.py" || true
fi
}
# ComfyUI-Manager backend API. The v1.46.x cloud frontend already contains the
# Manager UI; this backend node provides /manager/* and /customnode/* endpoints
# for local/docker/external ComfyUI instances.
install_node "ComfyUI-Manager" "https://github.com/Comfy-Org/ComfyUI-Manager.git"
# Nodes used by common RunningHub digital-human / video templates.
install_node "audio-separation-nodes-comfyui" "https://github.com/christian-byrne/audio-separation-nodes-comfyui.git"
install_node "ComfyUI_Yvann-Nodes" "https://github.com/yvann-ba/ComfyUI_Yvann-Nodes.git"
install_node "ComfyUI-Easy-Use" "https://github.com/yolain/ComfyUI-Easy-Use.git"
install_node "ComfyUI-VoxCPM" "https://github.com/wildminder/ComfyUI-VoxCPM.git"
install_node "ComfyUI-WanVideoWrapper" "https://github.com/kijai/ComfyUI-WanVideoWrapper.git"
install_node "ComfyUI-Whisper-Translator" "https://github.com/civen-cn/ComfyUI-Whisper-Translator.git"
install_node "ComfyUI-KJNodes" "https://github.com/kijai/ComfyUI-KJNodes.git"
cat <<'EOF'
RunningHub template nodes installed.
Notes:
- Install system packages such as ffmpeg/libsndfile/rubberband separately if a
node requires them at runtime.
- The screenshot also references a "soundflow" package. I did not find a stable
public repository for that exact package name; install it through
ComfyUI-Manager or add its repository manually when you have the source URL.
- Missing model files, for example Wan/InfiniteTalk checkpoints, are not custom
nodes. Put those models into the matching ComfyUI models folders or use a
backend where RunningHub/Cloud already provides them.
EOF