vibe

Driver skill for Mistral Vibe CLI (headless) syntax. Load this before spawning any Vibe call. Use when other skills need fast Mistral/Codestral generation or user says "use Vibe".

Mistral Vibe CLI Driver

Encode the exact Mistral Vibe CLI invocation for code generation and review tasks. This is a utility skill — it provides command templates that other skills compose into their workflows.

PATH & Absolute Paths

run_in_background and subagent Bash calls spawn non-interactive subshells that do NOT source .zshrc/.zprofile. Custom PATH entries are missing.

Always resolve the path dynamically:

VIBE=$(command -v vibe 2>/dev/null)
test -x "$VIBE" || VIBE="$HOME/.local/bin/vibe"
test -x "$VIBE" || VIBE="/usr/local/bin/vibe"
test -x "$VIBE" || { echo "Mistral Vibe CLI unavailable — skipping"; exit 0; }

Use "$VIBE" in every invocation. Do not use bare vibe.

Timeout Binary (MANDATORY)

GTIMEOUT="/opt/homebrew/bin/gtimeout"
test -x "$GTIMEOUT" || GTIMEOUT="/opt/homebrew/bin/timeout"
test -x "$GTIMEOUT" || { echo "gtimeout not installed (brew install coreutils)"; exit 1; }

Every template below uses $GTIMEOUT. Do not use bare timeout.

Programmatic Mode (MANDATORY)

Without -p / --prompt, Vibe enters interactive TUI mode and hangs indefinitely in subshells. The -p flag is required for ALL automated invocations.

-p auto-approves all tool executions by default — no separate --auto-approve needed.

# Minimum viable programmatic invocation
$GTIMEOUT 120 "$VIBE" -p "PROMPT" --output text --max-turns 5 2>/dev/null

Do NOT use positional prompts (e.g., vibe "prompt") — those launch the interactive TUI.

Prompt Scoping (MANDATORY)

Vibe performs best when the prompt is narrow, concrete, and file/work-unit scoped. Do not ask it to "look around the repo", "analyze the whole project", or "figure out what to change." That pattern burns turns on exploration and often ends with no final answer.

Always give Vibe all 4 of these:

  1. Target — exact file(s), directory, or work unit ID
  2. Task — what to implement/review/summarize
  3. Output shape — patch, code block, bullets, test, etc.
  4. Success criteria — what "done" means for this prompt

Good prompt shape:

Read [specific file(s)].
Implement [specific change].
Return [specific output format].
Stay within [named files / single work unit].
Do not inspect unrelated parts of the project.

Good examples:

  • Read src/auth.ts and src/session.ts. Implement refresh-token rotation for WU-3. Return complete replacement code blocks for those files only. Do not inspect unrelated directories.
  • Read rules/general.md and references/cross-cutting-rules.md. Summarize the driver-skill boundary in 5 bullets. Do not scan the rest of the repo.

Bad examples:

  • Analyze the architecture of this project
  • Look through the repo and figure out what needs to change
  • Implement this feature however you think is best

CLI Flags Reference (v2.4.2)

FlagArgumentPurpose
-p / --promptTEXTProgrammatic mode: send prompt, auto-approve tools, output, exit
--outputtext|json|streamingOutput format (default: text)
--max-turnsNLimit assistant turns (programmatic mode only)
--max-priceDOLLARSCost cap — interrupts if exceeded
--enabled-toolsTOOLRestrict to specific tools; disables all others. Supports glob (bash*) and regex (re:^pattern$). Can repeat.
--agentNAMEAgent profile: default, plan, accept-edits, auto-approve, or custom
--workdirDIRSet working directory
-c / --continueResume most recent session
--resumeSESSION_IDResume specific session (partial ID match)
--setupConfigure API key
-v / --versionShow version

Flags that do NOT exist (despite appearing in some docs for other versions): --headless, --no-prompt, --model, --auto-approve, generate, review subcommands.

Task-Type Templates

Code Generation (Primary Use Case)

# Fast generation with devstral-2 (default model)
# Prompt should name the exact work unit and target files.
$GTIMEOUT 180 "$VIBE" \
  -p "$(cat /tmp/prompt.md)" \
  --output text \
  --max-turns 10 \
  --workdir /path/to/project \
  2>/dev/null > /tmp/vibe-generated.ts

Code Review

# Review a file — reference the exact file and review focus in the prompt
$GTIMEOUT 120 "$VIBE" \
  -p "Read src/complex-module.ts and analyze for security issues, performance bottlenecks, and code smells" \
  --output text \
  --max-turns 5 \
  --workdir /path/to/project \
  2>/dev/null > /tmp/vibe-review.md

Focused Read-Only Analysis

# Keep analysis narrow: name the files or directories you want summarized.
$GTIMEOUT 120 "$VIBE" \
  -p "Read rules/general.md and references/cross-cutting-rules.md, then summarize the external-agent driver boundary in 5 bullets." \
  --output text \
  --max-turns 10 \
  --enabled-tools "read_file" \
  --enabled-tools "grep" \
  --workdir /path/to/project \
  2>/dev/null > /tmp/vibe-analysis.md

--agent plan works in headless mode on Vibe 2.4.2, but it changes the response style toward planning-oriented output. Use it only when you want that planning stance; for concise one-shot analysis, the default agent is usually simpler.

Tool-Restricted Run

# Only allow bash and read_file (no writes)
$GTIMEOUT 120 "$VIBE" \
  -p "List all TODO comments in the project" \
  --output text \
  --max-turns 5 \
  --enabled-tools "bash" \
  --enabled-tools "read_file" \
  --enabled-tools "grep" \
  --workdir /path/to/project \
  2>/dev/null > /tmp/vibe-todos.md

JSON Output

--output json writes a single JSON array of chat messages, not JSONL. The final assistant response is usually the last object with "role": "assistant".

$GTIMEOUT 120 "$VIBE" \
  -p "Reply with OK only." \
  --output json \
  --max-turns 3 \
  --workdir /path/to/project \
  2>/dev/null > /tmp/vibe-out.json

jq -r 'map(select(.role == "assistant")) | last.content // empty' /tmp/vibe-out.json

Model Selection

Models are configured in ~/.vibe/config.toml, not via CLI flags:

active_model = "devstral-2"  # default
Model (alias)ProviderUse Case
devstral-2Mistral APICode generation (default)
devstral-smallMistral APILighter/cheaper tasks
localllamacppOffline/local inference

To use a different model, create a custom agent config at ~/.vibe/agents/NAME.toml:

active_model = "devstral-small"

Then invoke with --agent NAME.

Available Tools

Vibe has these built-in tools (use with --enabled-tools to restrict):

ToolPermissionPurpose
read_filealwaysRead file contents
grepalwaysRecursive code search (ripgrep)
bashask (auto in -p)Execute shell commands
write_fileask (auto in -p)Create/modify files
search_replaceask (auto in -p)Patch files with replacements
taskaskDelegate to subagents (explore built-in)
web_searchaskSearch the web
web_fetchaskFetch URL content
todoalwaysTrack work items
ask_user_questionalwaysPrompt user (no-op in -p mode)

Output Validation (MANDATORY)

Vibe produces concise output — smoke tests and exact-match prompts may be 2-20 characters, while substantive review/generation responses are usually 50+ characters. Validate based on task type, not a fixed global threshold.

# Validate output file
if [ ! -s /tmp/vibe-output.md ]; then
  echo "ERROR: Vibe produced empty output" >&2
  exit 1
fi

# Character-count heuristic:
# - Smoke tests / exact-match prompts: EXPECT_MIN_CHARS=1 (default)
# - Real review / generation tasks: EXPECT_MIN_CHARS=50
EXPECT_MIN_CHARS="${EXPECT_MIN_CHARS:-1}"
CHARS=$(wc -c < /tmp/vibe-output.md 2>/dev/null | tr -d ' ')
if [ "${CHARS:-0}" -lt "$EXPECT_MIN_CHARS" ]; then
  echo "ERROR: Vibe output too small (${CHARS} chars)" >&2
  exit 1
fi

Critical Gotchas

  1. -p is MANDATORY for automation — without it, CLI enters interactive TUI and hangs
  2. Always wrap with $GTIMEOUT — CLI can hang on tool call failures
  3. Character count > line count — Vibe produces compact, dense output
  4. No --model flag — model selection is config-only (~/.vibe/config.toml or --agent)
  5. 2>/dev/null recommended — stderr can contain progress/status noise
  6. Exit codes: 0 = success, 1 = error, 124 = timeout (from gtimeout)
  7. Concurrency: Max 3 simultaneous Vibe processes
  8. --workdir sets the project root — Vibe reads project context from this directory
  9. Positional prompt (without -p) enters interactive mode — never use in automation
  10. Broad repo-analysis prompts can hit turn limits — keep analysis prompts narrow, name the target files/directories, and prefer --enabled-tools for focused read-only runs.
  11. --agent plan changes response style rather than failing headless — on Vibe 2.4.2 it returned planning-oriented output in one-shot CLI calls. Use it only when you explicitly want that behavior.
  12. Code-generation prompts must name the exact coding scope — specify the work unit, target files, expected output format, and what not to touch. Do not ask Vibe to discover the scope itself.
  13. JSON mode is a single array, not JSONL--output json writes one JSON document containing all messages. Use jq over the full array, not tail -1.

Concurrency Limit (MANDATORY)

PID_FILE=/tmp/vibe-slots.pid

# Prune dead entries
if [ -f "$PID_FILE" ]; then
  while IFS= read -r pid; do
    ps -p "$pid" >/dev/null 2>&1 && echo "$pid"
  done < "$PID_FILE" > "${PID_FILE}.tmp"
  mv "${PID_FILE}.tmp" "$PID_FILE"
fi

# Check slot availability (max 3)
ACTIVE=$(wc -l < "$PID_FILE" 2>/dev/null || echo 0)
if [ "$ACTIVE" -ge 3 ]; then
  echo "All 3 Vibe slots occupied — queuing or skipping"
  # Queue or exit based on your workflow
fi

# After launching, append PID
echo $! >> /tmp/vibe-slots.pid

Fallback Behavior

Failure ModeFallback
CLI not installedTry Codex (/codex); then Claude direct generation
Timeout (exit 124)Retry once with 240s; then try Codex
Turn limit reached (exit 1 + vibe_stop_event)Tighten the prompt, name specific files, restrict tools, or switch to Cursor/Codex for repo-wide analysis
Empty outputRetry with more --max-turns; then try Codex
Rate limitQueue and retry after 60s; then try Codex

Real-World Examples (From meta-execute)

# Generation work unit (meta-execute pattern)
$GTIMEOUT 180 "$VIBE" \
  -p "$(cat /tmp/wu-feature-x-prompt.md)" \
  --output text \
  --max-turns 15 \
  --workdir /path/to/project \
  2>/dev/null > /tmp/wu-feature-x-vibe.md
# Parallel generation with Codex as second generator
# (Vibe invocation as above, background'd; then for Codex:)
# Load /codex for invocation syntax. Key params:
# --sandbox workspace-write, --ephemeral, --cd /path/to/project, 180s timeout.
# Prompt: $(cat /tmp/prompt.md). Output to /tmp/codex-output.md (background).
#
# wait for both PIDs, then compare /tmp/vibe-output.md and /tmp/codex-output.md

Before completing, read and follow ../references/cross-cutting-rules.md.