anthropics/skills180kwebapp-testing
Toolkit for interacting with and testing local web applications using Playwright. Supports verifying frontend functionality, debugging UI behavior, capturing browser screenshots, and viewing browser logs.
浏览器自动化
On-demand procedures for the ComfyUI sidebar panel agent that are too long to sit in the system prompt. Read it when a task lands in one of these areas. subgraph boundary rails and blueprint reuse, merging or composing workflows across tabs, pinning your edits to one workflow, opening staged or downloaded workflow files, untangling Get/Set-bus and rgthree toggle-heavy graphs, authoring rgthree Fast Groups nodes, the LoRA Manager autocomplete-node limitation, the CivitAI browser flow, downloading model weights, reading hardware and runtime stats, Prompt Director audits, custom-node crash recovery, run-to-node render debugging, and multi-stage pipeline chaining. Each section is a lookup, not background reading. Reach for the one you need instead of guessing, and follow the tool's own description for parameter detail.
把这段话发给 Claude Code、Codex 或 Cursor。智能体会先检查安全性,你确认后才安装。
读取 https://funcoding.ai/skills/artokun/comfyui-mcp/panel-operations/install.md ,按里面的步骤帮我安装这个 Skill。
These are the procedures the panel system prompt points at rather than carries. Each tool named here also has its own full MCP description — that description is the authority on parameters and edge cases. This file is the procedure: the order of calls, and the traps that only show up when you string them together.
Jump to the section you need:
Refactor a big graph into toggleable units. Do not reconstruct group membership by
hand. panel_query_graph reports every group with its member node_ids on each
result's groups — groups are geometric and do not own nodes, so trust that list, not
coordinates. To make a region readable and switchable as a UNIT (e.g. a "REPLACEMENT
MODE" group), call panel_subgraph_group(group:<title or id>): it wraps that group's
nodes into one subgraph node in a single step. Then toggle the whole region with
panel_set_node_mode(<subgraph node id>, 'bypass' to turn it OFF / 'active' to turn
it ON). To compare variants, queue it twice — panel_run with the subgraph active,
then bypass and panel_run again. For an arbitrary node set that is not a group, use
panel_create_subgraph with explicit node_ids.
Reading and editing inside one. Call panel_enter_subgraph(node_id) first — then
panel_query_graph / panel_graph_outline and the panel_* edit tools operate on the
subgraph's inner nodes — and panel_exit_subgraph when you are done.
Exposing interior nodes to the boundary. To wire an interior node to the subgraph's
boundary from INSIDE it, do NOT panel_connect to a guessed rail node id — that is the
rail and you will get it wrong. Use:
panel_expose_subgraph_output(from_node_id, from_output) to expose an interior OUTPUT
on the output rail, so the parent graph can wire the subgraph node's new output.panel_expose_subgraph_input(to_node_id, to_input) to expose an interior INPUT on the
input rail.Read panel_query_graph's rails field (present when viewing a subgraph) to see the
current boundary slots — what is already exposed and what still needs it.
Unexposing a boundary slot. panel_unexpose_subgraph_input / _output remove a
named rail slot. Host SubgraphNode slots are positional: removing a slot that is not
last shifts every later host link. panel_query_graph and panel_graph_outline will
still show those later host links as connected (same positional lens); panel_run can
then fail with Required input is missing (#2437). The unexpose reply only warns
when a later slot remains and the panel did not already reindex (host_links_reindexed);
removing the last slot, or a panel ≥0.15.120 that reports reindexed, is not that hazard.
Do not trust that connectedness.
Repair: panel_exit_subgraph, then disconnect and reconnect each remaining later host
link by NAME (not index). Reconnecting by name re-resolves the index. Then re-enter
if you still need the interior. Do not invent a reindex via panel_disconnect on a
guessed index — a SubgraphNode disconnect can cascade into deleting unrelated nodes.
Dissolving one. panel_unpack_subgraph(node_id) inlines the inner nodes back into
the parent graph and rewires external links, removing the wrapper — the inverse of
panel_create_subgraph. All of these are undoable with Ctrl+Z.
To bring nodes from ONE workflow into ANOTHER (combine two graphs, copy a section across tabs, reuse part of a saved workflow), use copy/paste:
panel_open_workflow — the source.panel_select_nodes — the section you want, or select all the ids from
panel_query_graph {fields:'ids'}.panel_copy_nodes.panel_open_workflow or panel_new_workflow — the destination.panel_paste_nodes — returns the new node ids.workflow-layout skill so the merged result is
clean with no overlaps.The clipboard SURVIVES the workflow switch, so the copied nodes carry across tabs. Use
connect_inputs only when you want the pasted nodes to auto-reconnect to matching
existing nodes; the default (false) drops a clean disconnected copy you wire yourself.
When the user builds a useful subgraph and wants to reuse it — now or in other
workflows — SAVE it: panel_create_subgraph to group the nodes (if not already a
subgraph), then panel_save_subgraph(node_id, name) publishes it to their library
programmatically (no dialog). To drop a saved one into ANY workflow later, list them
with panel_list_subgraphs and add with panel_add_subgraph(name).
This is the durable way to reuse a building block across projects — distinct from copy/paste, which is a one-off merge of the current clipboard.
By default your panel_* graph edits follow whichever workflow tab the user is
currently viewing. The panel can only read or edit the workflow currently IN VIEW, so
to work on a specific open workflow, make it the active canvas first with
panel_open_workflow, then call
panel_set_workflow_target(mode:"pinned", path:<from panel_list_workflows>) to bind
your edits to it. panel_get_workflow_target shows the current binding.
Pinning to a background (open but not active) workflow is REJECTED at pin time — it
cannot route edits to a tab that is not in view. A pin does NOT switch what the user
sees; it binds your edits to that workflow so that if the user later switches away,
your next graph call fails loudly instead of silently editing the wrong graph. Set
mode:"current" to follow the user's active tab again.
Tabs are managed with panel_list_workflows / panel_open_workflow /
panel_rename_workflow / panel_close_workflow. To label, move, resize, recolor,
collapse, or pin a node for presentation, use panel_edit_node.
When you have saved or downloaded a workflow .json into the user's ComfyUI workflows
folder (e.g. an example you fetched), open it with
panel_open_workflow(path:<name-or-path>) — it REFRESHES the frontend's cached
workflow list before searching, so a just-staged file is found and opened natively in
its own tab.
For a workflow .json that lives OUTSIDE the workflows folder (any absolute path on
the ComfyUI machine, or a downloaded example you did not move into workflows/), load
it directly onto the live canvas with panel_load_workflow(path:<file>) — the
orchestrator reads and parses the JSON server-side and drops it on the canvas in one
shot, so even a large (100KB+) workflow never has to shuttle through the chat. Prefer
panel_load_workflow(path:<file>) over pasting a big workflow JSON inline as the
graph argument.
Expert and community graphs are often thick with VIRTUAL WIRING — GetNode/SetNode buses and Reroutes that hide the real connections — and rgthree "Fast Groups Bypasser/Muter" TOGGLED PIPELINES (one graph holding several pipelines, only one active at a time). Do NOT hand-trace GetNode to SetNode links or guess which branches are live.
panel_strip_workflow(path:<file> | pack:<name> | graph:<json>), or with no argument to read the LIVE canvas. It resolves Get/Set
buses, Reroutes, subgraph definitions, and bypassed/muted nodes into REAL connections
and returns the flat, runnable graph (read server-side, never shuttled through chat).panel_slice_workflow(path:<file>, groups:[<group-title substrings>]) to carve that
pipeline into a standalone activated graph — it seeds from the output nodes in those
groups, takes their backward closure through links and Set/Get buses, and un-bypasses
the kept nodes — THEN panel_strip_workflow to flatten the buses.Reach for panel_strip_workflow whenever a graph is too tangled to read directly or
you need to UNDERSTAND or REBUILD its actual wiring; reach for panel_slice_workflow
when an ULTRA-style monolith bundles several toggled pipelines and you want just one.
The same two exist as get_workflow (action:"strip") and get_workflow (action:"slice") for non-panel sessions.
The counterpart to reading them, above. Fast Groups Bypasser/Muter are FRONTEND-ONLY —
registered by the pack's JS and absent from /object_info BY DESIGN, so their absence
there is NOT evidence they are unavailable. panel_add_node adds them: it exempts a
small allowlist of genuinely frontend-only types covering the Fast (Groups)
Bypasser/Muter, Label, Reroute and Node Collector — but NOT Bookmark, the Mute/Bypass
Relay/Repeater, Fast Actions Button or Random Unmuter, which it refuses fail-closed.
Procedure and traps:
panel_set_property, NOT panel_set_widget — matchTitle,
matchColors, sort and toggleRestriction are node PROPERTIES, and
panel_set_widget refuses them.matchTitle or the node lists every group in the workflow.matchTitle immediately after adding the node, then re-read the node. Fast Groups
do NOT implement onPropertyChanged, so the first write stores the filter but may
leave leftover Enable rows or widgets:{} (unbuilt, not "no matches"). If the list is
wrong, set matchTitle AGAIN — do NOT delete and re-add the node.panel_create_group returns extra_node_ids / missing_node_ids and a warning, FIX
IT before toggling, or a toggle disables part of the wrong stage.Load the rgthree skill (list_packs (action:"skill_read", name:"rgthree")) before
configuring these.
panel_add_node cannot add "Lora Loader (LoraManager)", "Lora Stacker (LoraManager)",
or other LoRA Manager nodes whose required input is AUTOCOMPLETE_TEXT_LORAS /
AUTOCOMPLETE_TEXT_PROMPT — the add waits 5s and refuses even when the pack and its UI
are healthy. That is NOT a missing extension: reloading, panel_refresh_nodes, and
retrying will keep failing.
Use "LoRA Text Loader (LoraManager)" instead (lora_syntax is a STRING socket you can
drive) or the core LoraLoader. Load the lora-manager skill (list_packs (action:"skill_read", name:"lora-manager")) before authoring these.
SHOW, don't just tell. When the user asks about — or you are recommending — specific CivitAI resources (a "good relight LoRA?", "which Flux checkpoint?", "find me an anime style"), LEAN TOWARD opening the docked CivitAI browser and highlighting your picks rather than answering with only a text table:
panel_open_civitai — docked, with a matched query/tab/filters.panel_civitai_search — refine.panel_civitai_results — read the metadata and URLs.panel_civitai_highlight — the one(s) you recommend, with a BRIEF text summary of
why each fits.This docks beside the chat so both stay visible, and lets the user SEE the actual cards. You read metadata and URLs only, not the images. It is a nudge, not a mandate — a quick factual answer, or a resource the user already named, is fine as text; reach for the browser when they are choosing between options or exploring.
Use download_model (action:"download"), or action:"download_civitai" for CivitAI —
NOT a raw shell download. It streams the file into the correct ComfyUI models/
subfolder AND surfaces live progress in the panel's download tray so the user can watch
it. Pass target_subfolder to land the file exactly where it belongs (e.g. loras,
checkpoints, vae, text_encoders, or a nested path like loras/<subdir>).
Do NOT shell out to curl/wget/aria2 for model files — a raw shell download has no
progress in the panel and can drop the file in the wrong place. Reserve the shell for
things download_model cannot do.
For GPU / VRAM / CPU / RAM, CUDA/torch/python versions, and ComfyUI runtime stats, call
get_system_stats (raw /system_stats) or install_comfyui (action:"environment") (a
summarized snapshot). Both read the CONNECTED ComfyUI's /system_stats and work for
LOCAL and REMOTE targets alike.
Do NOT shell out (nvidia-smi, PowerShell, wmic, python) for hardware info: the managed shell is sandboxed and read-only, rejects multi-line scripts, and only ever reaches the orchestrator host — not a remote ComfyUI. The startup ENVIRONMENT line already summarizes the machine; when you need current or more detail, these two tools are the source of truth.
When the graph contains PromptDirector, PromptDirectorAuto, PromptDirectorContext,
PromptProducer, or PromptDirectorResultCritic nodes, call
panel_audit_prompt_director BEFORE declaring that the prompt/model/LoRA setup is
correct, or diagnosing a failed edit.
The audit correlates live wiring and loader widgets with the nodes' resolved Model
Explorer metadata, edit plan, LoRA compatibility and strengths, the exact final prompt,
warnings, and the critic verdict. Surface concise, useful observations proactively —
including when the configuration is coherent. Its recommendations are READ-ONLY
proposals: ask before applying panel_set_widget / panel_connect changes unless the
user already explicitly asked you to fix the workflow.
If your turn begins with a "⚠️ ComfyUI crashed …" note — it names the fatal log block
and the most likely culprit custom node plus file:line — or a run dies with a
node-level error you can pin to one pack, do NOT just re-run the same graph. ESCALATE
to actually fix that node, narrating each step to the user as you go:
panel_update_node with the culprit's id, or
the comfyui MCP install_custom_node with action:"update" / action:"fix". Try
version nightly to grab a just-landed upstream fix. Poll
panel_node_queue_status, then panel_restart_comfyui — you resume and RETRY the
action to see if the crash is gone.COMFYUI_PATH/custom_nodes/<NodeDir> with your shell. If it is a git repo (a .git
dir), run git fetch && git pull, or check out the nightly branch, to force the
latest; reinstall its requirements if needed; then restart and retry.file:line, then VERIFY the fix actually resolves the crash —
restart and retry the same action, confirming it no longer faults.This combines cleanly with the normal install → restart → continue flow: a fresh install that crashes on first use is the same loop — update or patch the just-installed node, do not abandon it.
For a render that COMPLETES but comes out WRONG — artifacts, wrong subject, pose,
composition or colour, blur, a ControlNet/IPAdapter/mask/LoRA not taking, a refiner or
upscale stage degrading it. (For runs that FAIL with an error, OOM, or a missing node,
use the troubleshooting skill instead.)
Do NOT just re-roll the whole graph. LOCALIZE the fault — render only up to one stage and LOOK at what that stage produces:
panel_run takes to_node_id to run ONE output branch (ComfyUI partial execution).
Only that output node plus everything upstream of it renders; the rest is skipped, so
it is fast and cheap, and the result is delivered to you automatically like any run.to_node_id MUST be an OUTPUT node (is_output:true in panel_query_graph detail
rows).PreviewImage on an IMAGE wire, or
VAEDecode → PreviewImage on a LATENT, or MaskToImage → PreviewImage on a
MASK. Then panel_run(to_node_id=that preview), read the delivered image, and
panel_remove_node the tap when done.For the full method (probe recipes, symptom-to-probe map) read the debug-render skill
via list_packs (action:"skill_read").
For example Krea2 image → LTX video → WAN extend, all built on one canvas.
Chain a stage's output into the next stage's loader. When the next stage's loader
(LoadImage / VHS_LoadVideo / LoadAudio) needs the previous stage's OUTPUT, call
upload_image (action:"stage") with the output's { filename, subfolder?, type? } and
drop the returned input filename into the loader's image/video/audio widget. For a file
already on disk, use upload_image (action:"image") / (action:"video") /
(action:"audio") instead.
NEVER copy the output file into, or guess, a filesystem input/ path: ComfyUI's input
AND output directories may be CUSTOM (launched with --input-directory /
--output-directory), so a guessed path makes LoadImage reject the file ("Invalid
image file") and wastes the render. upload_image (action:"stage") goes through the
server API (/view then /upload/image), which resolves the real directories
correctly every time.
Verify a video render via the filesystem, not /history. VHS_VideoCombine and
similar video nodes write the .mp4 but frequently do NOT register an output in
ComfyUI's /history — the prompt shows done with no output and no error. So do NOT
conclude a clip "silently dropped" from get_history or queue (action:"status").
Confirm it with get_image (action:"list_outputs"), which lists videos each tagged
kind:"video", by filename/prefix plus a fresh mtime — then chain it forward with
upload_image (action:"stage").
Bypass completed stages before queuing the next one. Once a stage has RUN and you
have captured/staged its output, BYPASS that stage's nodes with
panel_set_node_mode(mode:"bypass") BEFORE you queue the next stage — so panel_run
does not re-execute (and make the user pay for and wait on) work that is already done.
Re-running the whole graph because an earlier stage was left active is a real, costly
failure mode: explicitly bypass each finished stage and keep only the ACTIVE stage live.
panel_list_mcp lists the MCP servers in the user's Claude config, panel_add_mcp
writes a new one there, and panel_remove_mcp removes one.
Only the Claude backend is handed those servers. Every other backend
(codex, gemini, grok, antigravity, qwen, the ollama family) is spawned with exactly two
MCP servers — the headless comfyui one and the live-canvas panel one — so on those,
the user's Claude config is their configuration and not your toolset. panel_reload
does not change that; switching the panel to the Claude backend is what would.
So panel_list_mcp answers PER SERVER with declared_to_this_spawn, and that field is
what you read before saying a capability is connected. Two things to know about it:
false on a non-Claude backend is settled — we handed you nothing. (Your own CLI
config may separately provide a server of the same name; that one is not this one.)true means we handed it to this session at spawn. It is not proof you have the
tools: a session that RESUMED after a restart keeps the MCP set recorded with it
rather than the one we just read, and a declared server can still fail to start. The
only proof is calling one of its tools and having it work.panel_add_mcp and panel_remove_mcp are still worth offering on any backend — they
edit the user's real Claude config, so the change reaches their own claude sessions
and this panel's Claude backend. Say that is what you are doing, rather than that you
are gaining the capability.
For example, if a task needs CivitAI model search and it is not connected, offer to add
the official CivitAI MCP (transport http, url https://mcp.civitai.com/mcp). ALWAYS
ask the user before connecting a remote MCP — it is an external service connection. On
the Claude backend, panel_reload then loads it into this session (it restarts you and
resumes automatically).
After panel frontend or comfyui-tool code changes you can also call panel_reload to
pick them up without a ComfyUI restart. But changes to the orchestrator process itself
— the panel_* tools and the services they use — only take effect when the user
restarts that process, so never claim such a change is live after a panel_reload.
anthropics/skills180kToolkit for interacting with and testing local web applications using Playwright. Supports verifying frontend functionality, debugging UI behavior, capturing browser screenshots, and viewing browser logs.
浏览器自动化
addyosmani/agent-skills103kTests in real browsers via Chrome DevTools MCP. Use when building or debugging anything that runs in a browser. Use when you need to inspect the DOM, capture console errors, analyze network requests, profile performance, or verify visual output with real runtime data. Requires the chrome-devtools MCP server to be configured.
浏览器自动化
ComposioHQ/awesome-claude-skills77kToolkit for interacting with and testing local web applications using Playwright. Supports verifying frontend functionality, debugging UI behavior, capturing browser screenshots, and viewing browser logs.
浏览器自动化
code-yeongyu/oh-my-openagent70kDrives a real browser through the omowright library from the js eval kernel: sites the user is already signed into, forms and clicks, JS-rendered pages, screenshots, web QA, extension popups, a human handoff for login, CAPTCHA or OTP, and a browser you own for scraping, bot-scored targets, network capture and QA traces. Use for any interactive browser task; not for a plain search or an unblocked static fetch.
浏览器自动化
shanraisshan/claude-code-best-practice67kBrowser automation CLI for AI agents. Use when the user needs to interact with websites, including navigating pages, filling forms, clicking buttons, taking screenshots, extracting data, testing web apps, or automating any browser task. Triggers include requests to "open a website", "fill out a form", "click a button", "take a screenshot", "scrape data from a page", "test this web app", "login to a site", "automate browser actions", or any task requiring programmatic web interaction.
浏览器自动化
CherryHQ/cherry-studio52kRun Cherry Studio critical-path system regression tasks through the repository-owned Playwright E2E workflow. Use for full regression, release acceptance, development-branch system validation, or a named cherry-regression-test task on GitHub-hosted macOS and Windows runners.
浏览器自动化