mirror of
https://github.com/pbakaus/impeccable.git
synced 2026-09-17 08:36:25 +03:00
* 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>
221 lines
9.0 KiB
Markdown
221 lines
9.0 KiB
Markdown
# 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](HARNESSES.md).
|
|
|
|
## Source Format
|
|
|
|
### Skill (`skill/SKILL.src.md`)
|
|
|
|
```yaml
|
|
---
|
|
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](https://agentskills.io/specification)):
|
|
- `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
|
|
|
|
```bash
|
|
# 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`:
|
|
```javascript
|
|
'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`:
|
|
```javascript
|
|
'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
|
|
|
|
```bash
|
|
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
|
|
|
|
- [Agent Skills Specification](https://agentskills.io/specification) - Open standard
|
|
- [HARNESSES.md](HARNESSES.md) - Provider capabilities matrix
|
|
- [Cursor Skills](https://cursor.com/docs/context/skills)
|
|
- [Claude Code Skills](https://code.claude.com/docs/en/skills)
|
|
- [Gemini CLI Skills](https://geminicli.com/docs/cli/skills/)
|
|
- [Codex CLI Skills](https://developers.openai.com/codex/skills/)
|
|
- [VS Code Copilot Skills](https://code.visualstudio.com/docs/copilot/customization/agent-skills)
|
|
- [Kiro Skills](https://kiro.dev/docs/skills/)
|
|
- [OpenCode Skills](https://opencode.ai/docs/skills/)
|
|
- [Pi Skills](https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/docs/skills.md)
|
|
- [Qoder Skills](https://docs.qoder.com/extensions/skills)
|
|
- [Mistral Vibe Skills](https://docs.mistral.ai/vibe/code/cli/skills)
|
|
|
|
## 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](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.
|