Vibe Orchestrator
/vibeon | /vibeoff | /vibestatus
Toggle auto-delegate mode — Vibe automatically handles coding tasks without requiring /vibe each time.
| Command | Action |
|---|---|
/vibeon | touch ~/.local/share/vibe-auto.flag → confirm "Auto-vibe ON" |
/vibeoff | rm -f ~/.local/share/vibe-auto.flag → confirm "Auto-vibe OFF" |
/vibestatus | report auto-mode (ON/OFF) and active model override |
For /vibestatus, run both checks and print two lines:
Auto-vibe: ON | OFF
Model: <alias> (override) OR Model: deepseek-flash (config default)
Auto-mode pre-filter (when flag is set)
When vibe-auto.flag exists, apply this gate before loading the full skill:
| Task signal | Action |
|---|---|
| 1 file, ≤10 lines, exact location already known | Edit directly — do NOT invoke the skill |
| Logic non-trivial, location unclear, multiple files, HTML/JS content, or >1 change | Invoke /vibe as normal |
/vibe-report
If the user invokes /vibe-report, run ~/tools/delegate-report with any flags
extracted from the arguments, display output verbatim, and stop.
| User says | Flag |
|---|---|
| "last 7 days", "7d" | --since 7 |
| "last 30 days", "30d" | --since 30 |
| "project foo" | --project foo |
| "only failures", "fails", "bugs" | --fails |
| (nothing) | (no flags — full report) |
/vibe-model-pick | /vibe-model-clear
Override the Vibe model for all subsequent delegations without touching ~/.vibe/config.toml.
Works via VIBE_ACTIVE_MODEL env var, which Vibe respects over the config file.
| Command | Action |
|---|---|
/vibe-model-pick <alias> | echo <alias> > ~/.local/share/vibe-model.flag → confirm |
/vibe-model-clear | rm -f ~/.local/share/vibe-model.flag → confirm "back to config default" |
Available aliases (from ~/.vibe/config.toml):
| Alias | Model | Provider | Notes |
|---|---|---|---|
deepseek-flash | deepseek-v4-flash | DeepSeek | Default — fast, cheap |
mistral-medium-3.5 | mistral-vibe-cli-latest | Mistral | Stronger reasoning |
devstral-small | devstral-small-latest | Mistral | Lighter Mistral model |
local | devstral (llamacpp) | Local | Requires local server on :8080 |
Run the bash command, print one confirmation line showing the active model, and stop.
When the user invokes /vibe <instruction>, Claude delegates the implementation
to Mistral Vibe via its programmatic mode, supervises in real time, and reports.
Known Limits
Hard constraints of Mistral Vibe CLI — not config options.
1. UTF-8 / special chars cause search_replace failures
Vibe's search_replace tool matches byte-for-byte. Accented chars, curly quotes,
or emoji in old_string → silent match failure, no write. Workaround: use
python3 str.replace() for those edits, or restructure the prompt to avoid them.
2. Code duplication bug
Vibe sometimes re-inserts a block it has already written (off-by-one in its diff logic). Check for duplicate function definitions or repeated class bodies after every run.
3. Orchestration chain has 6 independent failure points
The delegation pipeline is: vibe CLI → pseudo-TTY (script) → Python stream parser → TOML pricing lookup → git diff → JSON log. Each link can fail independently:
| Link | Failure mode | Symptom |
|---|---|---|
| Vibe CLI | Auth expired, update broke API | Immediate exit, no output |
pseudo-TTY (script) | Platform difference (GNU vs BSD flags) | Hangs silently or garbled output |
| Stream parser | Vibe changes its JSON schema | Tool calls not detected, wrong token count |
| TOML pricing | config.toml missing or renamed | Falls back to Mistral Medium 3.5 rates |
| git diff | Not a git repo, or Vibe committed mid-run | Wrong file count, misleading stat |
| JSON log | ~/.local/share/ not writable | Silent log skip, /vibe-report misses the run |
When a run produces unexpected results, check these links in order from top to bottom.
4. Never pass source code through a bash heredoc
Nested quotes, f-strings, or backslashes in inline bash << 'PYEOF' mangle escaping.
- ASCII code: use
search_replacedirectly. - Content too long for inline: ask Vibe to write to
/tmp/new.py, thensearch_replaceviaopen('/tmp/new.py').read(). - Never write a helper script whose sole job is
str.replace()on another file.
5. HTML tags in the prompt body cause shell redirect errors (exit 127)
<div>, </div>, <span> etc. embedded in the prompt string are interpreted by
bash as file redirections. div is not a command → "No such file or directory", exit 127.
Rule: if the prompt references or contains any HTML — even in a quoted description —
write the content to a temp file first:
cat > /tmp/new_block.html << 'EOF'
<div class="map-sidebar">...</div>
EOF
Then reference it in the prompt: "Replace the sidebar block in templates/map.html
with the content of /tmp/new_block.html." Vibe reads it with read_file, no shell parsing.
This also applies to JS files containing template literals (backticks) or JSX-like syntax.
Step 1 — Detect workdir
git rev-parse --show-toplevelin the current directory.- If ambiguous or no git repo → ask with
AskUserQuestion.
Step 2 — Decompose the task
Critical rule: Vibe is optimized for atomic, focused tasks. Its system prompt literally says "Most tasks need <150 words."
| Size | Definition | Max turns | Approach |
|---|---|---|---|
| Trivial | 1 file, change is obvious and located | — | Skip delegation — edit directly |
| Simple | 1 file, non-trivial logic or unknown location | 5–8 | 1 vibe call |
| Medium | 2–3 related files, 1 objective | 8–12 | 1 structured vibe call |
| Complex | >3 files OR business logic OR DB migrations | — | Break into sub-tasks |
Decomposition for complex tasks:
Sub-task 1: Explore / read relevant files (read-only, 5 turns)
Sub-task 2: Implement change A in file X (8 turns)
Sub-task 3: Implement change B in file Y (8 turns)
Sub-task 4: Verify / test (5 turns)
→ Check git diff between each sub-task before launching the next.
Step 3 — Write the Vibe prompt
Vibe has no context from the parent conversation. The prompt must be self-contained.
Structure of a good Vibe prompt:
Stack: Python/Flask, SQLAlchemy, SQLite
Key files: app.py (routes + fetch), models.py (Entry)
TASK: [one single thing to do, stated as an imperative]
CONSTRAINTS:
- [what must not break]
- [expected format if relevant]
VERIFY: grep for "def function_name" in file.py and confirm it exists.
Formulation rules:
- One task per prompt — never "also do X and Y"
- Name the exact files to modify
- Include a grep-based verification criterion (not a file re-read)
- Language: English (better Mistral performance)
⚠️ Shell safety: if the prompt contains UTF-8 accented chars, emojis,
:in Python/YAML code, or typographic apostrophes — the vibe-delegate script passes them safely via a temp file (printf %q). Never interpolate such a prompt directly into a bash heredoc.
Verification — always use grep, not file re-read:
VERIFY: grep for "def extract_labels" in app.py and confirm it exists.
A grep is reliable. A file re-read may miss content outside the read window.
Step 4 — Launch Vibe
~/tools/vibe-delegate "<workdir>" "<prompt>" [max-turns] [agent] [timeout-secs]
| Argument | Default | Notes |
|---|---|---|
workdir | — | Absolute path, must exist |
prompt | — | Self-contained task description |
max-turns | 10 | Mistral turn limit — hard cap at 12, never more |
agent | (none) | See agent t |