Files
pbakaus_impeccable/docs/DEVELOP.md
T
83c37e453a feat: add Mistral Vibe harness support (#373)
* feat: add Mistral Vibe harness support

Mistral Vibe is Mistral AI's open-source CLI coding assistant that ships an
Agent Skills system at .vibe/skills/{name}/SKILL.md with slash-command
invocation, mapping cleanly onto the existing transformer pipeline. Adds
Vibe as a 14th first-class harness:

- PROVIDER_PLACEHOLDERS entry in scripts/lib/utils.js (model, config_file
  = AGENTS.md, ask_instruction, command_prefix) mirroring the Qoder shape.
- PROVIDERS entry in scripts/lib/transformers/providers.js with configDir
  .vibe and frontmatterFields user-invocable, license, compatibility,
  metadata, allowed-tools (Vibe docs do not document argument-hint).
- transformVibe named export in scripts/lib/transformers/index.js for
  test-spy parity.
- vibe added to FILE_DOWNLOAD_PROVIDER_CONFIG_DIRS so the download
  endpoint accepts /api/download/skill/vibe/* and resolves to
  dist/vibe/.vibe/.
- .vibe added to PROVIDER_DIRS, PROVIDER_ALIASES, PROVIDER_DISPLAY,
  PROVIDER_INPUT_ORDER, GLOBAL_HARNESS_HINTS, and the normalizeForHash
  provider regex in cli/bin/commands/skills.mjs so the CLI detects
  existing Vibe installs.
- docs/HARNESSES.md updated: official docs row, frontmatter support
  column, directory structure row, and Last verified date bumped.
- docs/DEVELOP.md, README.md (install instructions, providers list,
  Supported Tools), .github issue/PR templates, sync-generated-output
  workflow, and AGENTS.md extended with Vibe.

The dynamic providers.test.js loop picks up Vibe automatically; all 160
provider tests pass including the 14 new Mistral Vibe cases. The build
regenerates dist/vibe/.vibe/skills/impeccable/ with correct frontmatter
and .vibe-substituted script paths. Generated harness output is left
unstaged per the source-first policy; the sync-generated-output workflow
(now listing .vibe) will commit it back to main after merge.

Co-Authored-By: Mistral Vibe <noreply@mistral.ai>

* Address review on Vibe harness support

Verified the Vibe claims against the docs and the mistralai/mistral-vibe
source, then tightened what the tables say.

- model placeholder: 'Mistral', not 'the model'. Vibe is Mistral's own
  first-party CLI, so it belongs with gemini -> Gemini and codex -> GPT
  rather than with the provider-agnostic harnesses. SKILL.src.md's one
  use of {{model}} now renders 'Mistral is capable of extraordinary
  work.' instead of a lowercase 'the model'.
- Docs links point at the skills page, not the product overview, matching
  every other row in both tables.
- disable-model-invocation is No, not TBD. The field appears nowhere in
  Vibe's source; unknown frontmatter keys are silently ignored.
- Split the directory row into project and global scopes the way the Pi
  row already does. Vibe reads .vibe/skills/ and .agents/skills/ at the
  project level and ~/.vibe/skills/ and ~/.agents/skills/ globally; the
  global .agents dir was missing, and project .agents/skills/ was sitting
  in the global column. Sources: vibe/core/paths/_local_config_files.py
  and vibe/core/config/harness_files/_paths.py.
- Restored 'Last verified' to 2026-04-28 and dated the Vibe row on its
  own. Only that row was checked, and this file warns against trusting
  stale claims, so a blanket re-date made ten other rows look fresher
  than they are.

AI assistance: written with Claude Code.

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Mistral Vibe <noreply@mistral.ai>
Co-authored-by: Paul Bakaus <paul.bakaus@gmail.com>
Co-authored-by: Claude <noreply@anthropic.com>
2026-07-20 14:50:32 -07:00

9.0 KiB

Developer Guide

Documentation for contributors to Impeccable.

Architecture

The skill at skill/ is transformed into provider-specific formats by a config-driven factory. Each provider is defined as a config object in scripts/lib/transformers/providers.js -- adding a new provider requires only a new config entry.

For detailed harness capabilities (which frontmatter fields each supports, placeholder systems, directory structures), see HARNESSES.md.

Source Format

Skill (skill/SKILL.src.md)

---
name: skill-name
description: What this skill provides
argument-hint: "[target]"
user-invocable: true
license: License info (optional)
compatibility: Environment requirements (optional)
---

Your skill instructions here...

Frontmatter fields (based on Agent Skills spec):

  • name (required): Skill identifier (1-64 chars, lowercase/numbers/hyphens)
  • description (required): What the skill provides (1-1024 chars)
  • user-invocable (optional): Boolean -- if true, the skill can be invoked as a slash command
  • argument-hint (optional): Hint shown during autocomplete (e.g., [target], [area (feature, page...)])
  • license (optional): License/attribution info
  • compatibility (optional): Environment requirements (1-500 chars)
  • metadata (optional): Arbitrary key-value pairs
  • allowed-tools (optional, experimental): Pre-approved tools list

Body placeholders (replaced per-provider during build):

  • {{model}} -- Provider-specific model name (e.g., "Claude", "Gemini", "GPT")
  • {{config_file}} -- Provider-specific config file (e.g., "CLAUDE.md", ".cursorrules")
  • {{ask_instruction}} -- How to ask the user for clarification
  • {{command_prefix}} -- Slash command prefix (/ for most, $ for Codex)
  • {{available_commands}} -- Comma-separated list of user-invocable commands

Building

Prerequisites

  • Bun (fast JavaScript runtime and package manager)
  • No external dependencies required

Commands

# Build all provider formats
bun run build

# Clean dist folder
bun run clean

# Rebuild from scratch
bun run rebuild

What Gets Generated

source/                          -> dist/
  skills/{name}/SKILL.md           {provider}/{configDir}/skills/{name}/SKILL.md

Each provider gets its own output directory.

Build System Details

The build system uses a factory pattern under scripts/:

scripts/
  build.js                        # Main orchestrator
  lib/
    utils.js                      # Frontmatter parsing, placeholder replacement, YAML generation
    zip.js                        # ZIP bundle generation
    transformers/
      factory.js                  # createTransformer() -- generates transformer functions from config
      providers.js                # PROVIDERS config map -- one entry per provider
      index.js                    # Re-exports factory-generated transformer functions

Adding a New Provider

  1. Add a placeholder config to PROVIDER_PLACEHOLDERS in scripts/lib/utils.js:

    'my-provider': {
      model: 'MyModel',
      config_file: 'CONFIG.md',
      ask_instruction: 'ask the user directly to clarify.',
      command_prefix: '/'
    }
    
  2. Add a provider config to PROVIDERS in scripts/lib/transformers/providers.js:

    'my-provider': {
      provider: 'my-provider',
      configDir: '.my-provider',
      displayName: 'My Provider',
      frontmatterFields: ['user-invocable', 'argument-hint', 'license'],
    }
    
  3. Run bun run build -- the provider is automatically picked up by the build loop.

  4. Update HARNESSES.md with the provider's capabilities.

Provider Config Options

Field Description
provider Key for output directory and placeholder lookup
configDir Dot-directory name (e.g., .claude)
displayName Human-readable name for build logs
frontmatterFields Which optional fields to emit (see factory.js FIELD_SPECS)
bodyTransform Optional (body, skill) => body function for post-processing
placeholderProvider Override which PROVIDER_PLACEHOLDERS key to use (for variants sharing config)

Key Functions

  • createTransformer(config): Factory that returns a transformer function from a provider config
  • parseFrontmatter(): Extracts YAML frontmatter and body from SKILL.md files
  • readSourceFiles(): Reads skill/SKILL.src.md plus its reference/ and scripts/ siblings
  • replacePlaceholders(): Substitutes {{model}}, {{config_file}}, etc. per provider
  • generateYamlFrontmatter(): Serializes objects to YAML frontmatter (auto-quotes values starting with [ or {)

Testing

bun run test                  # Default suite — unit + static fixtures (no API keys needed)
bun run test:live-e2e         # Opt-in — full-cycle live-mode E2E across framework fixtures (~2 min, needs `npx playwright install chromium` once)
bun run test:skill-behavior   # Opt-in — LLM-backed checks that the SKILL.md Setup flow actually drives the agent (~5 min, costs cents, needs `.env`)

The skill-behavior suite runs three providers (claude-haiku-4-5, gpt-5.4-mini, gemini-3.1-flash-lite — the cheapest tier of each, every run) with the source skill/SKILL.src.md inlined as the system prompt and a workspace-scoped bash/read/write/list tool set. It then asserts on the tool-call trace, not on free-form output. Use it whenever you edit skill/SKILL.src.md's Setup section, skill/scripts/context.mjs, or any Setup-touching reference (teach.md, document.md, brand.md, product.md, sub-command refs). Per-scenario assertions and the current baseline (21-22/24) live in tests/skill-behavior/README.md. Provider keys live in repo-root .env (gitignored); missing keys skip cleanly.

Best Practices

Skill Writing

  1. Focused scope: One clear domain per skill
  2. Clear descriptions: Make purpose obvious
  3. Clear instructions: LLM should understand exactly what to do
  4. Include examples: Where they clarify intent
  5. State constraints: What NOT to do as clearly as what to do
  6. Test across providers: Verify it works in multiple contexts. For Setup-related edits to skill/, bun run test:skill-behavior automates this across three providers.

Reference Documentation

Repository Structure

impeccable/
  source/                          # Edit these! Source of truth
    skills/                        # Skill definitions
      frontend-design/
        SKILL.md
        reference/*.md             # Domain-specific references
      audit/SKILL.md
      polish/SKILL.md
      ...
  dist/                            # Generated output (gitignored)
  scripts/
    build.js                       # Main orchestrator
    lib/
      utils.js                     # Shared utilities
      zip.js                       # ZIP generation
      transformers/
        factory.js                 # Config-driven transformer factory
        providers.js               # Provider config map
        index.js                   # Re-exports
  tests/                           # Bun test suite
  docs/
    HARNESSES.md                   # Provider capabilities reference
    STYLE.md                       # Editorial style guide
    adr-live-variant-mode.md       # Live mode architecture decision record
    DEVELOP.md                     # This file
  README.md                        # User documentation

Troubleshooting

Build fails with YAML parsing errors

  • Check frontmatter indentation (YAML is indent-sensitive)
  • Ensure --- delimiters are on their own lines
  • Values starting with [ or { are auto-quoted; other special YAML chars may need manual quoting

Output doesn't match expectations

  • Check the provider config in scripts/lib/transformers/providers.js
  • Verify source file has correct frontmatter structure
  • Run bun run rebuild to ensure clean build

Provider doesn't recognize the files

  • Check installation path for your provider
  • Verify file naming matches provider requirements
  • Consult HARNESSES.md for provider-specific details

Questions?

Open an issue first. If a maintainer approves the direction, offer to follow up with a PR. Regular contributors pbakaus and abdulwahabone may open PRs directly.