Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/ISSUE_TEMPLATE/feature_request.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ assignees: ''
- [ ] Kiro
- [ ] OpenCode
- [ ] Qoder
- [ ] Mistral Vibe
- [ ] All providers

## Alternatives considered
Expand Down
2 changes: 1 addition & 1 deletion .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ This repo is issue-first for outside contributions. If you are not `pbakaus` or
- [ ] Source files updated in `source/`
- [ ] `bun run build` ran successfully
- [ ] `bun test` passes
- [ ] Tested with at least one provider (Cursor / Claude Code / Gemini CLI / Codex / Copilot / Kiro / OpenCode / Qoder)
- [ ] Tested with at least one provider (Cursor / Claude Code / Gemini CLI / Codex / Copilot / Kiro / OpenCode / Qoder / Mistral Vibe)
- [ ] README / DEVELOP.md updated if needed
- [ ] I reviewed the full diff myself before requesting human review
- [ ] I disclosed any AI assistance in this PR and related commits/comments, or no AI assistance was used
1 change: 1 addition & 0 deletions .github/workflows/sync-generated-output.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ env:
.rovodev
.trae
.trae-cn
.vibe
plugin

jobs:
Expand Down
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ Run `bun run build` after changing anything in `skill/`, transformer code, or us

## Generated Provider Output Policy

The root harness folders (`.agents/skills/`, `.claude/skills/`, `.cursor/skills/`, `.gemini/skills/`, `.github/skills/`, `.kiro/skills/`, `.opencode/skills/`, `.pi/skills/`, `.qoder/skills/`, `.rovodev/skills/`, `.trae*/skills/`) and `plugin/` stay tracked so `main` remains installable for direct GitHub, `npx skills`, and submodule users. They are still generated artifacts.
The root harness folders (`.agents/skills/`, `.claude/skills/`, `.cursor/skills/`, `.gemini/skills/`, `.github/skills/`, `.kiro/skills/`, `.opencode/skills/`, `.pi/skills/`, `.qoder/skills/`, `.rovodev/skills/`, `.trae*/skills/`, `.vibe/skills/`) and `plugin/` stay tracked so `main` remains installable for direct GitHub, `npx skills`, and submodule users. They are still generated artifacts.

Normal development should be source-first: stage changes in `skill/`, `scripts/`, `cli/`, `site/`, `extension/`, `functions/`, and `tests/`; leave generated harness churn unstaged unless the user asked for it. After source changes land on `main`, `.github/workflows/sync-generated-output.yml` runs `bun run build:release` and commits generated provider output directly back to `main`. Treat generated harness diffs as release artifacts and keep them out of feature PRs unless they are the point of the PR.

Expand Down
12 changes: 11 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ git add .gitmodules .impeccable .claude .cursor
git commit -m "Add Impeccable skills"
```

Use the providers your project needs, for example `claude`, `cursor`, `gemini`, `codex`, `github`, `opencode`, `pi`, `qoder`, `trae`, `trae-cn`, or `rovo-dev`. The command links individual skill folders from `.impeccable/dist/universal/` and leaves existing real skill directories untouched unless you pass `--force`.
Use the providers your project needs, for example `claude`, `cursor`, `gemini`, `codex`, `github`, `opencode`, `pi`, `qoder`, `trae`, `trae-cn`, `rovo-dev`, or `vibe`. The command links individual skill folders from `.impeccable/dist/universal/` and leaves existing real skill directories untouched unless you pass `--force`.

To update later:

Expand Down Expand Up @@ -250,6 +250,15 @@ cp -r dist/qoder/.qoder your-project/
cp -r dist/qoder/.qoder/skills/* ~/.qoder/skills/
```

**Mistral Vibe:**
```bash
# Project-specific
cp -r dist/vibe/.vibe your-project/

# Or global (applies to all projects)
cp -r dist/vibe/.vibe/skills/* ~/.vibe/skills/
```

## Usage

Once installed, every command runs through the single `/impeccable` skill:
Expand Down Expand Up @@ -379,6 +388,7 @@ Full detector docs: [impeccable.style/docs/detector](https://impeccable.style/do
- [Trae](https://trae.ai)
- [Rovo Dev](https://www.atlassian.com/software/rovo)
- [Qoder](https://qoder.com)
- [Mistral Vibe](https://docs.mistral.ai/vibe/code/overview)

## Community & Ecosystem

Expand Down
9 changes: 6 additions & 3 deletions cli/bin/commands/skills.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const __dirname = dirname(fileURLToPath(import.meta.url));
const API_BASE = 'https://impeccable.style';

// Provider folder names in project roots
const PROVIDER_DIRS = ['.claude', '.cursor', '.gemini', '.agents', '.github', '.kiro', '.opencode', '.pi', '.qoder', '.trae', '.trae-cn', '.rovodev'];
const PROVIDER_DIRS = ['.claude', '.cursor', '.gemini', '.agents', '.github', '.kiro', '.opencode', '.pi', '.qoder', '.trae', '.trae-cn', '.rovodev', '.vibe'];
const PROVIDER_ALIASES = {
agents: '.agents',
claude: '.claude',
Expand All @@ -41,6 +41,7 @@ const PROVIDER_ALIASES = {
rovodev: '.rovodev',
trae: '.trae',
'trae-cn': '.trae-cn',
vibe: '.vibe',
};

const PROVIDER_DISPLAY = {
Expand All @@ -56,8 +57,9 @@ const PROVIDER_DISPLAY = {
'.rovodev': { name: 'Rovo Dev', input: 'rovo-dev' },
'.trae': { name: 'Trae', input: 'trae' },
'.trae-cn': { name: 'Trae CN', input: 'trae-cn' },
'.vibe': { name: 'Mistral Vibe', input: 'vibe' },
};
const PROVIDER_INPUT_ORDER = ['claude', 'codex', 'cursor', 'gemini', 'github', 'kiro', 'opencode', 'pi', 'qoder', 'trae', 'trae-cn', 'rovo-dev'];
const PROVIDER_INPUT_ORDER = ['claude', 'codex', 'cursor', 'gemini', 'github', 'kiro', 'opencode', 'pi', 'qoder', 'trae', 'trae-cn', 'rovo-dev', 'vibe'];

// Providers whose GLOBAL (home) skills dir is not `<provider>/skills`.
// Pi discovers global skills from ~/.pi/agent/skills/; project scope
Expand All @@ -79,6 +81,7 @@ const GLOBAL_HARNESS_HINTS = [
{ home: '.pi', provider: '.pi' },
{ home: '.qoder', provider: '.qoder' },
{ home: '.rovodev', provider: '.rovodev' },
{ home: '.vibe', provider: '.vibe' },
];

// Last-resort default when nothing is detected: Claude Code + the universal
Expand Down Expand Up @@ -568,7 +571,7 @@ async function copyOrExtractLocalBundle(sourceValue) {
*/
function normalizeForHash(content) {
return content
.replace(/\.(claude|cursor|agents|github|gemini|codex|kiro|opencode|pi|qoder|trae|trae-cn|rovodev)\/skills\//g, '.PROVIDER/skills/');
.replace(/\.(claude|cursor|agents|github|gemini|codex|kiro|opencode|pi|qoder|trae|trae-cn|rovodev|vibe)\/skills\//g, '.PROVIDER/skills/');
}

function hashSkillFile(filePath) {
Expand Down
1 change: 1 addition & 0 deletions cli/lib/download-providers.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export const FILE_DOWNLOAD_PROVIDER_CONFIG_DIRS = Object.freeze({
opencode: '.opencode',
pi: '.pi',
qoder: '.qoder',
vibe: '.vibe',
});

export const FILE_DOWNLOAD_PROVIDERS = Object.freeze(
Expand Down
1 change: 1 addition & 0 deletions docs/DEVELOP.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ The skill-behavior suite runs three providers (claude-haiku-4-5, gpt-5.4-mini, g
- [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/overview)

## Repository Structure

Expand Down
36 changes: 19 additions & 17 deletions docs/HARNESSES.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
Source of truth for what each AI coding harness supports in terms of agent skills.
Used to inform provider configs in `scripts/lib/transformers/providers.js`.

Last verified: 2026-04-28 (subagent landscape spot-checked 2026-06-28)
Last verified: 2026-07-16 (subagent landscape spot-checked 2026-06-28)

> This file is point-in-time. Capabilities move fast; verify live before relying
> on any "only X supports Y" claim. Notably, the subagent table below lists
Expand All @@ -24,6 +24,7 @@ Last verified: 2026-04-28 (subagent landscape spot-checked 2026-06-28)
| Qoder | https://docs.qoder.com/extensions/skills |
| Trae | TBD (no official skills docs found yet) |
| Rovo Dev | https://support.atlassian.com/rovo/docs/extend-rovo-dev-cli-with-agent-skills |
| Mistral Vibe | https://docs.mistral.ai/vibe/code/overview |

## Spec Compliance

Expand All @@ -35,22 +36,22 @@ Provider-specific extensions beyond the spec: `user-invocable`, `argument-hint`,

Fields marked with * are spec-standard. Others are provider extensions.

| Field | Claude Code | Cursor | Gemini | Codex | Copilot | Kiro | OpenCode | Pi | Qoder | Rovo Dev |
|-------|:-----------:|:------:|:------:|:-----:|:-------:|:----:|:--------:|:--:|:-----:|:--------:|
| `name`* | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes |
| `description`* | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes |
| `license`* | Yes | Yes | Ignored | No | Yes | Yes | Yes | Yes | Yes | Yes |
| `compatibility`* | Yes | Yes | Ignored | No | Yes | Yes | Yes | Yes | Yes | Yes |
| `metadata`* | Yes | Yes | Ignored | No | Yes | Yes | Yes | Yes | Yes | Yes |
| `allowed-tools`* | Yes | No | Ignored | No | No | No | Yes | Yes | Yes | Yes |
| `user-invocable` | Yes | No | No | No | Yes | No | Yes | No | Yes | Yes |
| `argument-hint` | Yes | No | No | No | Yes | No | Yes | No | Yes | Yes |
| `disable-model-invocation` | Yes | Yes | No | No | Yes | No | Yes | Yes | TBD | TBD |
| `model` | Yes | No | No | No | No | No | Yes | No | No | No |
| `effort` | Yes | No | No | No | No | No | No | No | No | No |
| `context` | Yes | No | No | No | No | No | No | No | No | No |
| `agent` | Yes | No | No | No | No | No | Yes | No | No | No |
| `hooks` | Yes | No | No | Yes | No | No | No | No | No | No |
| Field | Claude Code | Cursor | Gemini | Codex | Copilot | Kiro | OpenCode | Pi | Qoder | Rovo Dev | Mistral Vibe |
|-------|:-----------:|:------:|:------:|:-----:|:-------:|:----:|:--------:|:--:|:-----:|:--------:|:------------:|
| `name`* | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes |
| `description`* | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes |
| `license`* | Yes | Yes | Ignored | No | Yes | Yes | Yes | Yes | Yes | Yes | Yes |
| `compatibility`* | Yes | Yes | Ignored | No | Yes | Yes | Yes | Yes | Yes | Yes | Yes |
| `metadata`* | Yes | Yes | Ignored | No | Yes | Yes | Yes | Yes | Yes | Yes | Yes |
| `allowed-tools`* | Yes | No | Ignored | No | No | No | Yes | Yes | Yes | Yes | Yes |
| `user-invocable` | Yes | No | No | No | Yes | No | Yes | No | Yes | Yes | Yes |
| `argument-hint` | Yes | No | No | No | Yes | No | Yes | No | Yes | Yes | No |
| `disable-model-invocation` | Yes | Yes | No | No | Yes | No | Yes | Yes | TBD | TBD | TBD |
| `model` | Yes | No | No | No | No | No | Yes | No | No | No | No |
| `effort` | Yes | No | No | No | No | No | No | No | No | No | No |
| `context` | Yes | No | No | No | No | No | No | No | No | No | No |
| `agent` | Yes | No | No | No | No | No | Yes | No | No | No | No |
| `hooks` | Yes | No | No | Yes | No | No | No | No | No | No | No |

Notes:
- Gemini CLI validates only `name` and `description`; other spec fields are parsed but ignored.
Expand Down Expand Up @@ -84,6 +85,7 @@ Notes:
| Trae China | `.trae-cn/skills/` | TBD |
| Trae International | `.trae/skills/` | TBD |
| Rovo Dev | `.rovodev/skills/` | `~/.rovodev/skills/` (user-level) |
| Mistral Vibe | `.vibe/skills/` | `~/.vibe/skills/`, `.agents/skills/` |

All harnesses support the `{skill-name}/SKILL.md` directory structure with optional `reference/`, `scripts/`, and `assets/` subdirectories.

Expand Down
1 change: 1 addition & 0 deletions scripts/lib/transformers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@ export const transformOpenCode = createTransformer(PROVIDERS.opencode);
export const transformPi = createTransformer(PROVIDERS.pi);
export const transformQoder = createTransformer(PROVIDERS.qoder);
export const transformRovoDev = createTransformer(PROVIDERS['rovo-dev']);
export const transformVibe = createTransformer(PROVIDERS.vibe);

export { createTransformer, PROVIDERS };
7 changes: 7 additions & 0 deletions scripts/lib/transformers/providers.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,4 +122,11 @@ export const PROVIDERS = {
displayName: 'Rovo Dev',
frontmatterFields: ['user-invocable', 'argument-hint', 'license', 'compatibility', 'metadata', 'allowed-tools'],
},
vibe: {
provider: 'vibe',
providerTags: ['vibe'],
configDir: '.vibe',
displayName: 'Mistral Vibe',
frontmatterFields: ['user-invocable', 'license', 'compatibility', 'metadata', 'allowed-tools'],
},
};
7 changes: 7 additions & 0 deletions scripts/lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -627,6 +627,12 @@ export const PROVIDER_PLACEHOLDERS = {
config_file: 'AGENTS.md',
ask_instruction: 'ask the user directly to clarify what you cannot infer.',
command_prefix: '/'
},
'vibe': {
model: 'the model',
config_file: 'AGENTS.md',
ask_instruction: 'ask the user directly to clarify what you cannot infer.',
command_prefix: '/'
}
};

Expand All @@ -645,6 +651,7 @@ export const PROVIDER_BLOCK_TAGS = new Set([
'rovo-dev',
'trae',
'trae-cn',
'vibe',
]);

/**
Expand Down