agentsclimarketplace

Visual in the loop

Skill taniiicom/visual-in-the-loop/skills/visual-in-the-loop

Generate a single diagram (Nano Banana Pro / Gemini 3 Pro Image) of whatever you are about to ask the user to review or decide, and show it BEFORE you ask. USE PROACTIVELY whenever you are about to call AskUserQuestion, ExitPlanMode, or otherwise request a human decision on a multi-step plan, an ambiguous spec, an architecture choice, a UI mockup, or a set of options. Pipe the ACTUAL text of the plan or question into the skill verbatim — do not rewrite, summarize, split, or art-direct it; the model turns the real text into one diagram. Call this FIRST, then present the question. Humans review decisions far faster with a picture — do not just describe a diagram in text and skip this skill.From its SKILL.md

Install
npx -y skills add taniiicom/visual-in-the-loop --skill visual-in-the-loop

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its file declares

Copied from the file, not written here

The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.

SKILL.md

8.2 KB, ~2.0k tokens by cl100k_base, as published. Nobody here has run it

visual-in-the-loop

When you are about to pull the user's attention to make a decision, give them a picture of it first. A single 1-page diagram cuts review time massively compared to a wall of text.

When to use (read this first)

USE this skill PROACTIVELY in every one of these moments:

  • Right before calling AskUserQuestion to ask the user a non-trivial decision
  • Right before calling ExitPlanMode to confirm a multi-step plan
  • During clarify / spec-kit style questioning when the user is asked to choose between approaches, architectures, UIs, or flows
  • Any time you would otherwise write "let me describe the diagram in text"

If a question is genuinely trivial (yes/no on a 1-line change, simple typo fix, etc.) you can skip. Default to invoking the skill.

How to use

One step. Pipe the actual text of what you are about to ask the user to review or decide into run.sh via stdin. For a multi-line plan, use a heredoc:

cat <<'EOF' | bash "${CLAUDE_PLUGIN_ROOT}/scripts/run.sh" --trigger plan --lang Japanese
<the full plan text, exactly as you would present it to the user>
EOF

For a short question:

echo "<the question and all of its options>" \
  | bash "${CLAUDE_PLUGIN_ROOT}/scripts/run.sh" --trigger clarify --lang English

Pipe the real text, verbatim — this is the one thing that matters. For ExitPlanMode, that is the full plan you are about to present. For AskUserQuestion, that is the question together with all of its options. Do NOT rewrite it, summarize it, split it into pieces, or describe scenes / art-direct the image. The skill wraps your text in a single one-line instruction and the model turns the actual content into one diagram. If you paraphrase the plan into your own words, the model draws your paraphrase, not the plan — the result is markedly worse.

The skill produces exactly one image.

Trigger flag. --trigger <type> lets the user scope when the skill fires (optional, fail-safe if omitted):

  • --trigger plan — before ExitPlanMode
  • --trigger clarify — before AskUserQuestion
  • --trigger decision — any other significant decision moment

Language flag. Pass --lang <language> set to the language this conversation is being held in (e.g. --lang Japanese, --lang English) so the diagram's labels and text are written in the user's language. Determine it from the conversation and pass it every time. If omitted, the model uses whatever language the plan text happens to be in.

${CLAUDE_PLUGIN_ROOT} is set by Claude Code to this skill's root directory. For a directly-installed skill, substitute the absolute path to this skill dir.

The script is synchronous. It returns only after the image has been rendered to the user's environment. Only then should you call AskUserQuestion / ExitPlanMode and pull the user's attention.

What happens

  1. generate.mjs reads the plan text from stdin, wraps it with the one-line instruction in references/prompt-template.md, and calls the configured provider once. The PNG is saved to $TMPDIR/visual-in-the-loop/<ts>.png.
  2. show.sh detects the environment and uses ONE of:
    • tmux + chafa: a side pane, real graphics (chafa auto-detects the terminal's protocol — Kitty graphics, sixel, etc.), sized to fit the pane. Enter closes. Re-renders on resize.
    • VS Code / Cursor / Windsurf: a temp markdown tab with the image.
    • macOS: open (Preview).
    • Linux desktop: xdg-open.
  3. run.sh prints [visual-in-the-loop] rendered: <path> to stdout.

Failure mode

If the skill returns non-zero or the visual cannot be generated (no API key, network error, model returns no image, no display path available, etc.), proceed with the question anyway without the visual. The skill is a UX enhancement — it must not block the conversation.

run.sh is designed to always exit 0 unless there is an unexpected bash error, so failures normally surface as a stderr WARN line and a missing image rather than a thrown error.

Setup

  • Node.js 18+ (uses the built-in fetch). No npm install required.
  • Set the API key for whichever provider you use (see Configuration below).
  • Optional, picked up automatically if present:
    • tmux + chafa — enables the in-terminal side-pane preview
    • code CLI — enables the VS Code markdown preview path

Configuration

All configuration is through environment variables. Set them in your shell or in ~/.claude/settings.json under the env key.

Env varValuesDefaultNotes
VITL_ENABLED1 / 0 (also true/false/yes/no/on/off, case-insensitive)unset (= enabled)Master switch. Only disables on 0/false/no/off; any other value (including unset) is enabled.
VITL_PROVIDERgemini / vertexai / openai / azuregeminiWhich API to call.
VITL_MODELprovider-specific model idprovider defaultE.g. gemini-2.5-flash-image for free-tier on Gemini.
VITL_ASPECT_RATIOa W:H ratio — 2:3, 3:4, 4:5, 9:16, 1:1, 4:3, 3:2, 16:92:3 (portrait)Shape of the generated image. Gemini / Vertex AI use it directly; OpenAI / Azure map it to the nearest portrait / landscape / square size.
VITL_LANGa language name (e.g. Japanese, English)unsetDefault language for the diagram's text. The agent's --lang argument overrides it per call. If neither is set, the model uses the plan text's own language.
VITL_DISPLAYauto / tmux / vscode / open / noneautoForce a display path, or none to suppress display. Unavailable choices fall back to auto.
VITL_TRIGGERcomma-separated list (e.g. plan,clarify) or allallRestricts which --trigger <type> values actually fire generation.

Provider-specific env

VITL_PROVIDERRequired envDefault VITL_MODEL
geminiGEMINI_API_KEY or GOOGLE_API_KEYgemini-3-pro-image-preview
vertexaiVITL_VERTEX_PROJECT + VITL_VERTEX_LOCATION (auth via gcloud auth application-default login)gemini-3-pro-image-preview
openaiOPENAI_API_KEYgpt-image-1
azureAZURE_OPENAI_API_KEY + AZURE_OPENAI_ENDPOINT + AZURE_OPENAI_DEPLOYMENT (optional AZURE_OPENAI_API_VERSION)deployment-specific (VITL_MODEL ignored)

Do NOT

  • Do NOT rewrite, summarize, split, or art-direct the plan before piping it in. Pipe the real text verbatim — the model needs the actual plan, not your paraphrase of it. This is the single most common way to make the output bad.
  • Do NOT fall back to a Mermaid / ASCII / textual description of the diagram. The whole point is the model's open-ended image generation.
  • Do NOT call AskUserQuestion or ExitPlanMode first and then run this skill. The order is: generate visual → then ask.
  • Do NOT run this skill in the background and let the question display immediately. Run it synchronously.
  • Do NOT add caching, thresholds, or "should I generate?" logic in front of the skill. Keep this path simple.

Tuning

If diagrams come out off-target, edit references/prompt-template.md — that one-line instruction is the only knob. It has two placeholders: {plan} (required — the piped text) and {language} (optional — replaced with a language clause when --lang / VITL_LANG is set, or with nothing). Do not pile on heuristics in generate.mjs, and do not pre-process the plan text upstream.

What ships with it: 10 files

18.2 KB alongside SKILL.md, 8 of them executable

scripts/

Keep looking

Skills are one crate of 326,367. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.