skiller 0.7.20 → 0.7.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +56 -990
- package/dist/agents/AiderAgent.js +2 -1
- package/dist/core/ClaudePluginSync.js +55 -5
- package/dist/core/apply-engine.js +6 -2
- package/package.json +76 -77
package/README.md
CHANGED
|
@@ -1,997 +1,63 @@
|
|
|
1
1
|
# `skiller`
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
## 1. Skills as Source of Truth
|
|
6
|
-
|
|
7
|
-
- `.claude/skills/` is the committed source of truth for skills
|
|
8
|
-
- **Bidirectional sync** between `.mdc` and `SKILL.md` (sibling pattern):
|
|
9
|
-
- Create `.claude/skills/foo/foo.mdc` → auto-generates `.claude/skills/foo/SKILL.md`
|
|
10
|
-
- Create `.claude/skills/foo/SKILL.md` → auto-generates `.claude/skills/foo/foo.mdc`
|
|
11
|
-
- Sync direction detected via `@reference` body pattern (SKILL.md with `@path` = .mdc is source)
|
|
12
|
-
- Edit either file, the other stays in sync on next `skiller apply`
|
|
13
|
-
- `.claude/rules/` contents are migrated to `.claude/skills/` and rules directory is deleted
|
|
14
|
-
|
|
15
|
-
## 2. CLAUDE.md @filename References
|
|
16
|
-
|
|
17
|
-
- Uses `@filename` syntax instead of merging content
|
|
18
|
-
- Claude Code auto-includes referenced files
|
|
19
|
-
- Reduces CLAUDE.md size and keeps sources separate
|
|
20
|
-
- Other agents still get merged content
|
|
21
|
-
|
|
22
|
-
## 3. MDC File Support
|
|
23
|
-
|
|
24
|
-
- Supports both `.md` and `.mdc` files (Nuxt Content, Vue)
|
|
25
|
-
- All patterns auto-expand: `"components"` → `"components/**/*.{md,mdc}"`
|
|
26
|
-
|
|
27
|
-
## 4. Rules Filtering
|
|
28
|
-
|
|
29
|
-
- `include`/`exclude` glob patterns in `[rules]`
|
|
30
|
-
- Directory names auto-expand to `directory/**/*.{md,mdc}`
|
|
31
|
-
- Organize by team/feature, exclude drafts/internal docs
|
|
32
|
-
|
|
33
|
-
## 5. Claude Root Folder
|
|
34
|
-
|
|
35
|
-
- Default directory is `.claude/` (no extra flags needed)
|
|
36
|
-
- Skills already in `.claude/skills` (no copying)
|
|
37
|
-
- Single directory for all Claude Code config
|
|
38
|
-
|
|
39
|
-
## 6. Cursor-style Rules
|
|
40
|
-
|
|
41
|
-
- `merge_strategy = "cursor"` parses `.mdc` frontmatter
|
|
42
|
-
- Only includes rules with `alwaysApply: true`
|
|
43
|
-
- Strips frontmatter, keeps body only
|
|
44
|
-
|
|
45
|
-
## 7. Backup Control
|
|
46
|
-
|
|
47
|
-
- `[backup].enabled = false` disables `.bak` files
|
|
48
|
-
|
|
49
|
-
## 8. Multi-Agent Skills Propagation
|
|
50
|
-
|
|
51
|
-
- `.claude/skills/` is the source of truth — skills are automatically copied to agent-specific directories on `skiller apply`
|
|
52
|
-
- Supported agent paths: `.codex/skills`, `.cursor/skills`, `.opencode/skill`, `.roo/skills`, `.gemini/skills`, `.agents/skills`
|
|
53
|
-
- Shared paths are deduplicated (Claude/Copilot/Kilo share `.claude/skills`, Goose/Amp share `.agents/skills`)
|
|
54
|
-
- Agent skills directories are auto-added to `.gitignore` (excluding `.claude/skills`)
|
|
55
|
-
- Validates skill structure — warns on missing `SKILL.md`
|
|
56
|
-
- Flattens nested skills into dash-separated names for agent skills dirs (e.g., `workflows/lfg` → `workflows-lfg`)
|
|
57
|
-
|
|
58
|
-
## 9. Claude Code Plugins → Skills
|
|
59
|
-
|
|
60
|
-
- Reads `.claude/settings.json` `enabledPlugins`
|
|
61
|
-
- Reads plugin content from `~/.claude/plugins/marketplaces` (never from `cache/`)
|
|
62
|
-
- Syncs enabled plugin `skills/` into agent skills directories on `skiller apply` (recursive, flattened names)
|
|
63
|
-
- Syncs enabled plugin `commands/**/*.md` as skills (`SKILL.md`) into agent skills directories (recursive, flattened names)
|
|
64
|
-
- Syncs enabled plugin `agents/**/*.md` as skills (`SKILL.md`) into agent skills directories
|
|
65
|
-
- Uses the skill/command/agent name by default (matches existing Codex skill names)
|
|
66
|
-
- If a name conflicts, local skills win and the plugin item is namespaced as `<pluginName>-<name>` (numeric suffix if multiple enabled plugins share the same name)
|
|
67
|
-
- Tracks plugin-managed items in `.claude/.skiller.json` (per project, grouped by agent skills dir)
|
|
68
|
-
- Removes stale plugin skills when plugins are disabled
|
|
69
|
-
|
|
70
|
-
## 10. Claude Commands/Agents → Skills
|
|
71
|
-
|
|
72
|
-
- Syncs `.claude/commands/**/*.md` as skills (`SKILL.md`) into agent skills directories
|
|
73
|
-
- Flattens nested commands into dash-separated names (e.g., `workflows/brainstorm.md` → `workflows-brainstorm`)
|
|
74
|
-
- Syncs `.claude/agents/**/*.md` as skills (`SKILL.md`) into agent skills directories
|
|
75
|
-
- Uses the command/agent name by default
|
|
76
|
-
- If a name conflicts, existing local/manual skills win and the project item is namespaced as `claude-<name>`
|
|
77
|
-
- Project items win over plugin skills/commands/agents on name conflicts
|
|
78
|
-
- Tracks project-managed items in `.claude/.skiller.json` (per project, grouped by agent skills dir)
|
|
79
|
-
|
|
80
|
-
---
|
|
81
|
-
|
|
82
|
-
# Skiller: Centralise Your AI Coding Assistant Instructions
|
|
83
|
-
|
|
84
|
-
> **Beta Research Preview**
|
|
85
|
-
>
|
|
86
|
-
> - Please test this version carefully in your environment
|
|
87
|
-
> - Report issues at https://github.com/udecode/skiller/issues
|
|
88
|
-
|
|
89
|
-
## Why Skiller?
|
|
90
|
-
|
|
91
|
-
Managing instructions across multiple AI coding tools becomes complex as your team grows. Different agents (GitHub Copilot, Claude, Cursor, Aider, etc.) require their own configuration files, leading to:
|
|
92
|
-
|
|
93
|
-
- **Inconsistent guidance** across AI tools
|
|
94
|
-
- **Duplicated effort** maintaining multiple config files
|
|
95
|
-
- **Context drift** as project requirements evolve
|
|
96
|
-
- **Onboarding friction** for new AI tools
|
|
97
|
-
- **Complex project structures** requiring context-specific instructions for different components
|
|
98
|
-
|
|
99
|
-
Skiller solves this by providing a **single source of truth** for all your AI agent instructions, automatically distributing them to the right configuration files. With support for **nested rule loading**, Skiller can handle complex project structures with context-specific instructions for different components.
|
|
100
|
-
|
|
101
|
-
## Core Features
|
|
102
|
-
|
|
103
|
-
- **Centralised Rule Management**: Store all AI instructions in a dedicated `.claude/` directory using Markdown files
|
|
104
|
-
- **Nested Rule Loading**: Support complex project structures with multiple `.claude/` directories for context-specific instructions
|
|
105
|
-
- **Automatic Distribution**: Skiller applies these rules to configuration files of supported AI agents
|
|
106
|
-
- **Targeted Agent Configuration**: Fine-tune which agents are affected and their specific output paths via `skiller.toml`
|
|
107
|
-
- **MCP Server Propagation**: Manage and distribute Model Context Protocol (MCP) server settings
|
|
108
|
-
- **`.gitignore` Automation**: Keeps generated agent config files out of version control automatically
|
|
109
|
-
- **Simple CLI**: Easy-to-use commands for initialising and applying configurations
|
|
110
|
-
|
|
111
|
-
## Supported AI Agents
|
|
112
|
-
|
|
113
|
-
| Agent | Rules File(s) | MCP Configuration / Notes | Skills Location |
|
|
114
|
-
| ---------------- | -------------------------------------------------- | ------------------------------------------------ | ------------------ |
|
|
115
|
-
| AGENTS.md | `AGENTS.md` | (pseudo-agent ensuring root `AGENTS.md` exists) | - |
|
|
116
|
-
| GitHub Copilot | `AGENTS.md` | `.vscode/mcp.json` | `.claude/skills/` |
|
|
117
|
-
| Claude Code | `CLAUDE.md` (@filename references) | `.mcp.json` | `.claude/skills/` |
|
|
118
|
-
| OpenAI Codex CLI | `AGENTS.md` | `.codex/config.toml` | `.codex/skills/` |
|
|
119
|
-
| Jules | `AGENTS.md` | - | - |
|
|
120
|
-
| Cursor | `AGENTS.md` | `.cursor/mcp.json` | `.cursor/skills/` |
|
|
121
|
-
| Windsurf | `AGENTS.md` | `.windsurf/mcp_config.json` | - |
|
|
122
|
-
| Cline | `.clinerules` | - | - |
|
|
123
|
-
| Crush | `CRUSH.md` | `.crush.json` | - |
|
|
124
|
-
| Amp | `AGENTS.md` | - | `.agents/skills/` |
|
|
125
|
-
| Amazon Q CLI | `.amazonq/rules/skiller_q_rules.md` | `.amazonq/mcp.json` | - |
|
|
126
|
-
| Aider | `AGENTS.md`, `.aider.conf.yml` | `.mcp.json` | - |
|
|
127
|
-
| Firebase Studio | `.idx/airules.md` | `.idx/mcp.json` | - |
|
|
128
|
-
| Open Hands | `.openhands/microagents/repo.md` | `config.toml` | - |
|
|
129
|
-
| Gemini CLI | `AGENTS.md` | `.gemini/settings.json` | `.gemini/skills/` |
|
|
130
|
-
| Junie | `.junie/guidelines.md` | - | - |
|
|
131
|
-
| AugmentCode | `.augment/rules/skiller_augment_instructions.md` | - | - |
|
|
132
|
-
| Kilo Code | `.kilocode/rules/skiller_kilocode_instructions.md` | `.kilocode/mcp.json` | `.claude/skills/` |
|
|
133
|
-
| OpenCode | `AGENTS.md` | `opencode.json` | `.opencode/skill/` |
|
|
134
|
-
| Goose | `.goosehints` | - | `.agents/skills/` |
|
|
135
|
-
| Qwen Code | `AGENTS.md` | `.qwen/settings.json` | - |
|
|
136
|
-
| RooCode | `AGENTS.md` | `.roo/mcp.json` | `.roo/skills/` |
|
|
137
|
-
| Zed | `AGENTS.md` | `.zed/settings.json` (project root, never $HOME) | - |
|
|
138
|
-
| Trae AI | `.trae/rules/project_rules.md` | - | - |
|
|
139
|
-
| Warp | `WARP.md` | - | - |
|
|
140
|
-
| Kiro | `.kiro/steering/skiller_kiro_instructions.md` | - | - |
|
|
141
|
-
| Firebender | `firebender.json` | `firebender.json` (rules and MCP in same file) | - |
|
|
142
|
-
|
|
143
|
-
## Getting Started
|
|
144
|
-
|
|
145
|
-
### Installation
|
|
146
|
-
|
|
147
|
-
**Using `npx` (for one-off commands):**
|
|
3
|
+
Apply the same rules (and skills) to multiple AI coding agents.
|
|
148
4
|
|
|
149
5
|
```bash
|
|
6
|
+
npx skiller@latest init
|
|
150
7
|
npx skiller@latest apply
|
|
151
8
|
```
|
|
152
9
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
**How it works:**
|
|
209
|
-
|
|
210
|
-
- Discover all `.claude/` directories in the project hierarchy
|
|
211
|
-
- Load and concatenate rules from each directory in order
|
|
212
|
-
- Decide whether nested mode is enabled using the following precedence:
|
|
213
|
-
1. `skiller apply --nested` (or `--no-nested`) takes top priority
|
|
214
|
-
2. `nested = true` in `skiller.toml`
|
|
215
|
-
3. Default to disabled when neither option is provided
|
|
216
|
-
- When a run is nested, downstream configs are forced to keep `nested = true`. If a child config attempts to disable it, Skiller keeps nested processing active and emits a warning in the logs.
|
|
217
|
-
- Nested processing carries forward each directory's own MCP bundle and configuration settings so that generated files remain scoped to their source directories while being normalized back to the project root.
|
|
218
|
-
|
|
219
|
-
> [!CAUTION]
|
|
220
|
-
> Nested mode is experimental and may change in future releases. The CLI logs this warning the first time a nested run is detected so you know the behavior may evolve.
|
|
221
|
-
|
|
222
|
-
**Perfect for:**
|
|
223
|
-
|
|
224
|
-
- Monorepos with multiple services
|
|
225
|
-
- Projects with distinct components (frontend/backend)
|
|
226
|
-
- Teams needing different instructions for different areas
|
|
227
|
-
- Complex codebases with varying standards
|
|
228
|
-
|
|
229
|
-
### Best Practices for Rule Files
|
|
230
|
-
|
|
231
|
-
**Granularity**: Break down complex instructions into focused `.md` files:
|
|
232
|
-
|
|
233
|
-
- `coding_style.md`
|
|
234
|
-
- `api_conventions.md`
|
|
235
|
-
- `project_architecture.md`
|
|
236
|
-
- `security_guidelines.md`
|
|
237
|
-
|
|
238
|
-
**Example rule file (`.claude/python_guidelines.md`):**
|
|
239
|
-
|
|
240
|
-
```markdown
|
|
241
|
-
# Python Project Guidelines
|
|
242
|
-
|
|
243
|
-
## General Style
|
|
244
|
-
|
|
245
|
-
- Follow PEP 8 for all Python code
|
|
246
|
-
- Use type hints for all function signatures and complex variables
|
|
247
|
-
- Keep functions short and focused on a single task
|
|
248
|
-
|
|
249
|
-
## Error Handling
|
|
250
|
-
|
|
251
|
-
- Use specific exception types rather than generic `Exception`
|
|
252
|
-
- Log errors effectively with context
|
|
253
|
-
|
|
254
|
-
## Security
|
|
255
|
-
|
|
256
|
-
- Always validate and sanitize user input
|
|
257
|
-
- Be mindful of potential injection vulnerabilities
|
|
258
|
-
```
|
|
259
|
-
|
|
260
|
-
## Usage: The `apply` Command
|
|
261
|
-
|
|
262
|
-
### Primary Command
|
|
263
|
-
|
|
264
|
-
```bash
|
|
265
|
-
skiller apply [options]
|
|
266
|
-
```
|
|
267
|
-
|
|
268
|
-
The `apply` command looks for `.claude/` in the current directory tree, reading the first match. If no such directory is found, it will look for a global configuration in `$XDG_CONFIG_HOME/skiller`.
|
|
269
|
-
|
|
270
|
-
### Options
|
|
271
|
-
|
|
272
|
-
| Option | Description |
|
|
273
|
-
| ------------------------------ | ---------------------------------------------------------------------- |
|
|
274
|
-
| `--project-root <path>` | Project root path (default: current directory). |
|
|
275
|
-
| `--agents <agent1,agent2,...>` | Comma-separated agent names to target (see supported list below). |
|
|
276
|
-
| `--config <path>` | Custom `skiller.toml` path. |
|
|
277
|
-
| `--mcp` / `--with-mcp` | Enable applying MCP server configurations (default: true). |
|
|
278
|
-
| `--no-mcp` | Disable applying MCP server configurations. |
|
|
279
|
-
| `--mcp-overwrite` | Overwrite native MCP config instead of merging. |
|
|
280
|
-
| `--gitignore` | Enable automatic .gitignore updates (default: true). |
|
|
281
|
-
| `--no-gitignore` | Disable automatic .gitignore updates. |
|
|
282
|
-
| `--nested` | Enable nested rule loading (default: inherit from config or disabled). |
|
|
283
|
-
| `--no-nested` | Disable nested rule loading even if `nested = true` in config. |
|
|
284
|
-
| `--backup` / `--no-backup` | Enable/disable creation of `.bak` backup files (default: enabled). |
|
|
285
|
-
| `--dry-run` | Preview changes without writing files. |
|
|
286
|
-
| `--local-only` | Skip `$XDG_CONFIG_HOME` when looking for configuration. |
|
|
287
|
-
| `--verbose` / `-v` | Display detailed output during execution. |
|
|
288
|
-
|
|
289
|
-
### Common Examples
|
|
290
|
-
|
|
291
|
-
**Apply rules to all configured agents:**
|
|
292
|
-
|
|
293
|
-
```bash
|
|
294
|
-
skiller apply
|
|
295
|
-
```
|
|
296
|
-
|
|
297
|
-
**Apply rules only to GitHub Copilot and Claude:**
|
|
298
|
-
|
|
299
|
-
```bash
|
|
300
|
-
skiller apply --agents copilot,claude
|
|
301
|
-
```
|
|
302
|
-
|
|
303
|
-
**Apply rules only to Firebase Studio:**
|
|
304
|
-
|
|
305
|
-
```bash
|
|
306
|
-
skiller apply --agents firebase
|
|
307
|
-
```
|
|
308
|
-
|
|
309
|
-
**Apply rules only to Warp:**
|
|
310
|
-
|
|
311
|
-
```bash
|
|
312
|
-
skiller apply --agents warp
|
|
313
|
-
```
|
|
314
|
-
|
|
315
|
-
**Apply rules only to Trae AI:**
|
|
316
|
-
|
|
317
|
-
```bash
|
|
318
|
-
skiller apply --agents trae
|
|
319
|
-
```
|
|
320
|
-
|
|
321
|
-
**Apply rules only to RooCode:**
|
|
322
|
-
|
|
323
|
-
```bash
|
|
324
|
-
skiller apply --agents roo
|
|
325
|
-
```
|
|
326
|
-
|
|
327
|
-
**Use a specific configuration file:**
|
|
328
|
-
|
|
329
|
-
```bash
|
|
330
|
-
skiller apply --config ./team-configs/skiller.frontend.toml
|
|
331
|
-
```
|
|
332
|
-
|
|
333
|
-
**Apply rules with verbose output:**
|
|
334
|
-
|
|
335
|
-
```bash
|
|
336
|
-
skiller apply --verbose
|
|
337
|
-
```
|
|
338
|
-
|
|
339
|
-
**Apply rules but skip MCP and .gitignore updates:**
|
|
340
|
-
|
|
341
|
-
```bash
|
|
342
|
-
skiller apply --no-mcp --no-gitignore
|
|
343
|
-
```
|
|
344
|
-
|
|
345
|
-
## Usage: The `revert` Command
|
|
346
|
-
|
|
347
|
-
The `revert` command safely undoes all changes made by `skiller apply`, restoring your project to its pre-skiller state. It intelligently restores files from backups (`.bak` files) when available, or removes generated files that didn't exist before.
|
|
348
|
-
|
|
349
|
-
### Why Revert is Needed
|
|
350
|
-
|
|
351
|
-
When experimenting with different rule configurations or switching between projects, you may want to:
|
|
352
|
-
|
|
353
|
-
- **Clean slate**: Remove all skiller-generated files to start fresh
|
|
354
|
-
- **Restore originals**: Revert modified files back to their original state
|
|
355
|
-
- **Selective cleanup**: Remove configurations for specific agents only
|
|
356
|
-
- **Safe experimentation**: Try skiller without fear of permanent changes
|
|
357
|
-
|
|
358
|
-
### Primary Command
|
|
359
|
-
|
|
360
|
-
```bash
|
|
361
|
-
skiller revert [options]
|
|
362
|
-
```
|
|
363
|
-
|
|
364
|
-
### Options
|
|
365
|
-
|
|
366
|
-
| Option | Description |
|
|
367
|
-
| ------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
368
|
-
| `--project-root <path>` | Path to your project's root (default: current directory) |
|
|
369
|
-
| `--agents <agent1,agent2,...>` | Comma-separated list of agent names to revert (agentsmd, aider, amazonqcli, amp, augmentcode, claude, cline, codex, copilot, crush, cursor, firebase, firebender, gemini-cli, goose, jules, junie, kilocode, kiro, opencode, openhands, qwen, roo, trae, warp, windsurf, zed) |
|
|
370
|
-
| `--config <path>` | Path to a custom `skiller.toml` configuration file |
|
|
371
|
-
| `--keep-backups` | Keep backup files (.bak) after restoration (default: false) |
|
|
372
|
-
| `--dry-run` | Preview changes without actually reverting files |
|
|
373
|
-
| `--verbose` / `-v` | Display detailed output during execution |
|
|
374
|
-
| `--local-only` | Only search for local .claude directories, ignore global config |
|
|
375
|
-
|
|
376
|
-
### Common Examples
|
|
377
|
-
|
|
378
|
-
**Revert all skiller changes:**
|
|
379
|
-
|
|
380
|
-
```bash
|
|
381
|
-
skiller revert
|
|
382
|
-
```
|
|
383
|
-
|
|
384
|
-
**Preview what would be reverted (dry-run):**
|
|
385
|
-
|
|
386
|
-
```bash
|
|
387
|
-
skiller revert --dry-run
|
|
388
|
-
```
|
|
389
|
-
|
|
390
|
-
**Revert only specific agents:**
|
|
391
|
-
|
|
392
|
-
```bash
|
|
393
|
-
skiller revert --agents claude,copilot
|
|
394
|
-
```
|
|
395
|
-
|
|
396
|
-
**Revert with detailed output:**
|
|
397
|
-
|
|
398
|
-
```bash
|
|
399
|
-
skiller revert --verbose
|
|
400
|
-
```
|
|
401
|
-
|
|
402
|
-
**Keep backup files after reverting:**
|
|
403
|
-
|
|
404
|
-
```bash
|
|
405
|
-
skiller revert --keep-backups
|
|
406
|
-
```
|
|
407
|
-
|
|
408
|
-
## Configuration (`skiller.toml`) in Detail
|
|
409
|
-
|
|
410
|
-
### Location
|
|
411
|
-
|
|
412
|
-
Defaults to `.claude/skiller.toml` in the project root. Override with `--config` CLI option.
|
|
413
|
-
|
|
414
|
-
### Complete Example
|
|
415
|
-
|
|
416
|
-
```toml
|
|
417
|
-
# Default agents to run when --agents is not specified
|
|
418
|
-
# Uses case-insensitive substring matching
|
|
419
|
-
default_agents = ["copilot", "claude", "aider"]
|
|
420
|
-
|
|
421
|
-
# --- Global MCP Server Configuration ---
|
|
422
|
-
[mcp]
|
|
423
|
-
# Enable/disable MCP propagation globally (default: true)
|
|
424
|
-
enabled = true
|
|
425
|
-
# Global merge strategy: 'merge' or 'overwrite' (default: 'merge')
|
|
426
|
-
merge_strategy = "merge"
|
|
427
|
-
|
|
428
|
-
# --- MCP Server Definitions ---
|
|
429
|
-
[mcp_servers.filesystem]
|
|
430
|
-
command = "npx"
|
|
431
|
-
args = ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/project"]
|
|
432
|
-
|
|
433
|
-
[mcp_servers.git]
|
|
434
|
-
command = "npx"
|
|
435
|
-
args = ["-y", "@modelcontextprotocol/server-git", "--repository", "."]
|
|
436
|
-
|
|
437
|
-
[mcp_servers.remote_api]
|
|
438
|
-
url = "https://api.example.com"
|
|
439
|
-
|
|
440
|
-
[mcp_servers.remote_api.headers]
|
|
441
|
-
Authorization = "Bearer your-token"
|
|
442
|
-
|
|
443
|
-
# --- Global .gitignore Configuration ---
|
|
444
|
-
[gitignore]
|
|
445
|
-
# Enable/disable automatic .gitignore updates (default: true)
|
|
446
|
-
enabled = true
|
|
447
|
-
|
|
448
|
-
# --- Backup Configuration ---
|
|
449
|
-
[backup]
|
|
450
|
-
# Enable/disable creation of .bak backup files (default: true)
|
|
451
|
-
enabled = false
|
|
452
|
-
|
|
453
|
-
# --- Agent-Specific Configurations ---
|
|
454
|
-
[agents.copilot]
|
|
455
|
-
enabled = true
|
|
456
|
-
|
|
457
|
-
[agents.claude]
|
|
458
|
-
enabled = true
|
|
459
|
-
output_path = "CLAUDE.md"
|
|
460
|
-
|
|
461
|
-
[agents.aider]
|
|
462
|
-
enabled = true
|
|
463
|
-
output_path_instructions = "AGENTS.md"
|
|
464
|
-
output_path_config = ".aider.conf.yml"
|
|
465
|
-
|
|
466
|
-
# OpenAI Codex CLI agent and MCP config
|
|
467
|
-
[agents.codex]
|
|
468
|
-
enabled = true
|
|
469
|
-
output_path = "AGENTS.md"
|
|
470
|
-
output_path_config = ".codex/config.toml"
|
|
471
|
-
|
|
472
|
-
# Agent-specific MCP configuration for Codex CLI
|
|
473
|
-
[agents.codex.mcp]
|
|
474
|
-
enabled = true
|
|
475
|
-
merge_strategy = "merge"
|
|
476
|
-
|
|
477
|
-
[agents.firebase]
|
|
478
|
-
enabled = true
|
|
479
|
-
output_path = ".idx/airules.md"
|
|
480
|
-
|
|
481
|
-
[agents.gemini-cli]
|
|
482
|
-
enabled = true
|
|
483
|
-
|
|
484
|
-
[agents.jules]
|
|
485
|
-
enabled = true
|
|
486
|
-
|
|
487
|
-
[agents.junie]
|
|
488
|
-
enabled = true
|
|
489
|
-
output_path = ".junie/guidelines.md"
|
|
490
|
-
|
|
491
|
-
# Agent-specific MCP configuration
|
|
492
|
-
[agents.cursor.mcp]
|
|
493
|
-
enabled = true
|
|
494
|
-
merge_strategy = "merge"
|
|
495
|
-
|
|
496
|
-
# Disable specific agents
|
|
497
|
-
[agents.windsurf]
|
|
498
|
-
enabled = false
|
|
499
|
-
|
|
500
|
-
[agents.kilocode]
|
|
501
|
-
enabled = true
|
|
502
|
-
output_path = ".kilocode/rules/skiller_kilocode_instructions.md"
|
|
503
|
-
|
|
504
|
-
[agents.warp]
|
|
505
|
-
enabled = true
|
|
506
|
-
output_path = "WARP.md"
|
|
507
|
-
```
|
|
508
|
-
|
|
509
|
-
### Configuration Precedence
|
|
510
|
-
|
|
511
|
-
1. **CLI flags** (e.g., `--agents`, `--no-mcp`, `--mcp-overwrite`, `--no-gitignore`)
|
|
512
|
-
2. **Settings in `skiller.toml`** (`default_agents`, specific agent settings, global sections)
|
|
513
|
-
3. **Skiller's built-in defaults** (all agents enabled, standard output paths, MCP enabled with 'merge')
|
|
514
|
-
|
|
515
|
-
## MCP (Model Context Protocol) Server Configuration
|
|
516
|
-
|
|
517
|
-
MCP provides broader context to AI models through server configurations. Skiller can manage and distribute these settings across compatible agents.
|
|
518
|
-
|
|
519
|
-
### TOML Configuration (Recommended)
|
|
520
|
-
|
|
521
|
-
You can now define MCP servers directly in `skiller.toml` using the `[mcp_servers.<name>]` syntax:
|
|
522
|
-
|
|
523
|
-
```toml
|
|
524
|
-
# Global MCP behavior
|
|
525
|
-
[mcp]
|
|
526
|
-
enabled = true
|
|
527
|
-
merge_strategy = "merge" # or "overwrite"
|
|
528
|
-
|
|
529
|
-
# Local (stdio) server
|
|
530
|
-
[mcp_servers.filesystem]
|
|
531
|
-
command = "npx"
|
|
532
|
-
args = ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/project"]
|
|
533
|
-
|
|
534
|
-
[mcp_servers.filesystem.env]
|
|
535
|
-
API_KEY = "your-api-key"
|
|
536
|
-
|
|
537
|
-
# Remote server
|
|
538
|
-
[mcp_servers.search]
|
|
539
|
-
url = "https://mcp.example.com"
|
|
540
|
-
|
|
541
|
-
[mcp_servers.search.headers]
|
|
542
|
-
Authorization = "Bearer your-token"
|
|
543
|
-
"X-API-Version" = "v1"
|
|
544
|
-
```
|
|
545
|
-
|
|
546
|
-
### Configuration Precedence
|
|
547
|
-
|
|
548
|
-
When both TOML and JSON configurations are present:
|
|
549
|
-
|
|
550
|
-
1. **TOML servers take precedence** over JSON servers with the same name
|
|
551
|
-
2. **Servers are merged** from both sources (unless using overwrite strategy)
|
|
552
|
-
3. **Deprecation warning** is shown encouraging migration to TOML (warning shown once per run)
|
|
553
|
-
|
|
554
|
-
### Server Types
|
|
555
|
-
|
|
556
|
-
**Local/stdio servers** require a `command` field:
|
|
557
|
-
|
|
558
|
-
```toml
|
|
559
|
-
[mcp_servers.local_server]
|
|
560
|
-
command = "node"
|
|
561
|
-
args = ["server.js"]
|
|
562
|
-
|
|
563
|
-
[mcp_servers.local_server.env]
|
|
564
|
-
DEBUG = "1"
|
|
565
|
-
```
|
|
566
|
-
|
|
567
|
-
**Remote servers** require a `url` field (headers optional; bearer Authorization token auto-extracted for OpenHands when possible):
|
|
568
|
-
|
|
569
|
-
```toml
|
|
570
|
-
[mcp_servers.remote_server]
|
|
571
|
-
url = "https://api.example.com"
|
|
572
|
-
|
|
573
|
-
[mcp_servers.remote_server.headers]
|
|
574
|
-
Authorization = "Bearer token"
|
|
575
|
-
```
|
|
576
|
-
|
|
577
|
-
Skiller uses this configuration with the `merge` (default) or `overwrite` strategy, controlled by `skiller.toml` or CLI flags.
|
|
578
|
-
|
|
579
|
-
**Home Directory Safety:** Skiller never writes MCP configuration files outside your project root. Any historical references to user home directories (e.g. `~/.codeium/windsurf/mcp_config.json` or `~/.zed/settings.json`) have been removed; only project-local paths are targeted.
|
|
580
|
-
|
|
581
|
-
**Note for OpenAI Codex CLI:** To apply the local Codex CLI MCP configuration, set the `CODEX_HOME` environment variable to your project’s `.codex` directory:
|
|
582
|
-
|
|
583
|
-
```bash
|
|
584
|
-
export CODEX_HOME="$(pwd)/.codex"
|
|
585
|
-
```
|
|
586
|
-
|
|
587
|
-
## Skills Support
|
|
588
|
-
|
|
589
|
-
Skiller can manage and propagate skills to supported AI agents. Skills are stored in `.claude/skills/` as the **committed source of truth** and automatically copied to agent-specific directories on `skiller apply`.
|
|
590
|
-
|
|
591
|
-
### How It Works
|
|
592
|
-
|
|
593
|
-
Skills are specialized knowledge packages that extend AI agent capabilities. Skiller discovers skills in your `.claude/skills/` directory, keeps them in sync via bidirectional `.mdc`/`SKILL.md` sync, and propagates them to all agents with native skills support:
|
|
594
|
-
|
|
595
|
-
- **Claude Code, GitHub Copilot, Kilo Code**: `.claude/skills/` (shared, source of truth)
|
|
596
|
-
- **OpenAI Codex CLI**: `.codex/skills/`
|
|
597
|
-
- **Cursor**: `.cursor/skills/`
|
|
598
|
-
- **OpenCode**: `.opencode/skill/`
|
|
599
|
-
- **Goose, Amp**: `.agents/skills/` (shared)
|
|
600
|
-
- **Roo Code**: `.roo/skills/`
|
|
601
|
-
- **Gemini CLI**: `.gemini/skills/`
|
|
602
|
-
|
|
603
|
-
Shared paths are deduplicated — agents sharing the same directory only trigger one copy operation.
|
|
604
|
-
|
|
605
|
-
### Claude Code Plugins
|
|
606
|
-
|
|
607
|
-
If your project enables Claude Code plugins in `.claude/settings.json`, Skiller also syncs plugin content into agent skills directories on `skiller apply`:
|
|
608
|
-
|
|
609
|
-
- Plugin `skills/` are copied as skills
|
|
610
|
-
- Plugin `commands/**/*.md` are converted into skills (`SKILL.md`)
|
|
611
|
-
- Plugin `agents/**/*.md` are converted into skills (`SKILL.md`)
|
|
612
|
-
- Plugin skills use their original skill/command name by default
|
|
613
|
-
- If a name conflicts, local skills win and the plugin item is namespaced as `<pluginName>-<name>` (numeric suffix if multiple enabled plugins share the same name)
|
|
614
|
-
- Plugin-managed items are tracked via `.claude/.skiller.json` (per project, grouped by agent skills dir)
|
|
615
|
-
|
|
616
|
-
### Skills Directory Structure
|
|
617
|
-
|
|
618
|
-
Skills can be organized flat or nested:
|
|
619
|
-
|
|
620
|
-
```
|
|
621
|
-
.claude/skills/
|
|
622
|
-
├── my-skill/
|
|
623
|
-
│ ├── my-skill.mdc # Skill content (body)
|
|
624
|
-
│ └── SKILL.md # @reference to my-skill.mdc (frontmatter here)
|
|
625
|
-
├── another-skill/
|
|
626
|
-
│ ├── another-skill.mdc # Generated from SKILL.md body
|
|
627
|
-
│ ├── SKILL.md # Manually created skill (now @reference)
|
|
628
|
-
│ ├── helper.py # Optional: additional resources (scripts)
|
|
629
|
-
│ └── reference.md # Optional: additional resources (docs)
|
|
630
|
-
```
|
|
631
|
-
|
|
632
|
-
Each skill can be defined in two ways:
|
|
633
|
-
|
|
634
|
-
1. **Standalone `.mdc` file** - Simple skills can be a single `.mdc` file at the skills root
|
|
635
|
-
2. **Skill folder with `SKILL.md`** - Complex skills with additional resources
|
|
636
|
-
|
|
637
|
-
### Bidirectional Sync
|
|
638
|
-
|
|
639
|
-
Skiller provides bidirectional sync between `.mdc` files and `SKILL.md` folders:
|
|
640
|
-
|
|
641
|
-
| Scenario | Sync Direction |
|
|
642
|
-
| ------------------------------- | ---------------------------------------------------------- |
|
|
643
|
-
| `.mdc` exists, no `SKILL.md` | → Generate `SKILL.md` with `@reference` to .mdc |
|
|
644
|
-
| `SKILL.md` body is `@reference` | .mdc is source of truth (frontmatter in SKILL.md) |
|
|
645
|
-
| `SKILL.md` has full content | → Generate .mdc from body, update SKILL.md to `@reference` |
|
|
646
|
-
|
|
647
|
-
The `@reference` body pattern indicates that the `.mdc` file contains the skill content:
|
|
648
|
-
|
|
649
|
-
```yaml
|
|
650
|
-
---
|
|
651
|
-
name: my-skill
|
|
652
|
-
description: My custom skill
|
|
653
|
-
---
|
|
654
|
-
|
|
655
|
-
@.claude/skills/my-skill/my-skill.mdc
|
|
656
|
-
```
|
|
657
|
-
|
|
658
|
-
### Rules Migration
|
|
659
|
-
|
|
660
|
-
Content from `.claude/rules/` is automatically migrated to `.claude/skills/` during `skiller apply`, then the rules directory is deleted:
|
|
661
|
-
|
|
662
|
-
```
|
|
663
|
-
.claude/rules/docx/
|
|
664
|
-
├── SKILL.md # Makes this a skill folder
|
|
665
|
-
├── script.sh # Helper script
|
|
666
|
-
└── templates/ # Subdirectory
|
|
667
|
-
└── default.docx # Template file
|
|
668
|
-
|
|
669
|
-
→ Migrated to:
|
|
670
|
-
|
|
671
|
-
.claude/skills/docx/
|
|
672
|
-
├── docx.mdc # Generated from SKILL.md body
|
|
673
|
-
├── SKILL.md # Updated to @reference
|
|
674
|
-
├── script.sh # Copied automatically
|
|
675
|
-
└── templates/ # Copied automatically
|
|
676
|
-
└── default.docx # Copied automatically
|
|
677
|
-
|
|
678
|
-
.claude/rules/ → Deleted after migration
|
|
679
|
-
```
|
|
680
|
-
|
|
681
|
-
### Configuration
|
|
682
|
-
|
|
683
|
-
Skills support is **enabled by default** but can be controlled via:
|
|
684
|
-
|
|
685
|
-
**CLI flags:**
|
|
686
|
-
|
|
687
|
-
```bash
|
|
688
|
-
# Enable skills (default)
|
|
689
|
-
skiller apply --skills
|
|
690
|
-
|
|
691
|
-
# Disable skills
|
|
692
|
-
skiller apply --no-skills
|
|
693
|
-
```
|
|
694
|
-
|
|
695
|
-
**Configuration in `skiller.toml`:**
|
|
696
|
-
|
|
697
|
-
```toml
|
|
698
|
-
[skills]
|
|
699
|
-
enabled = true # or false to disable
|
|
700
|
-
```
|
|
701
|
-
|
|
702
|
-
### Validation
|
|
703
|
-
|
|
704
|
-
Skiller validates discovered skills and issues warnings for:
|
|
705
|
-
|
|
706
|
-
- Missing required file (`SKILL.md`)
|
|
707
|
-
- Invalid directory structures (directories without `SKILL.md` and no sub-skills)
|
|
708
|
-
|
|
709
|
-
Warnings don't prevent propagation but help identify potential issues.
|
|
710
|
-
|
|
711
|
-
### `.gitignore` Integration
|
|
712
|
-
|
|
713
|
-
When skills propagation is enabled, agent skills directories are automatically added to `.gitignore` (excluding `.claude/skills/` which is the committed source of truth):
|
|
714
|
-
|
|
715
|
-
- `.codex/skills/`, `.cursor/skills/`, `.opencode/skill/`, `.agents/skills/`, `.roo/skills/`, `.gemini/skills/`
|
|
716
|
-
|
|
717
|
-
### Dry-Run Mode
|
|
718
|
-
|
|
719
|
-
Test skills propagation without making changes:
|
|
720
|
-
|
|
721
|
-
```bash
|
|
722
|
-
skiller apply --dry-run
|
|
723
|
-
```
|
|
724
|
-
|
|
725
|
-
This shows which skills would be synced, validated, and copied to each agent directory.
|
|
726
|
-
|
|
727
|
-
### Example Workflow
|
|
728
|
-
|
|
729
|
-
```bash
|
|
730
|
-
# 1. Create a skill folder
|
|
731
|
-
mkdir -p .claude/skills/my-skill
|
|
732
|
-
cat > .claude/skills/my-skill/SKILL.md << 'EOF'
|
|
733
|
-
---
|
|
734
|
-
name: my-skill
|
|
735
|
-
description: My custom skill
|
|
736
|
-
---
|
|
737
|
-
|
|
738
|
-
# My Custom Skill
|
|
739
|
-
|
|
740
|
-
This skill provides specialized knowledge for...
|
|
741
|
-
EOF
|
|
742
|
-
|
|
743
|
-
# 2. Apply to sync and propagate skills
|
|
744
|
-
skiller apply
|
|
745
|
-
|
|
746
|
-
# 3. Skills are now available to all compatible agents:
|
|
747
|
-
# - Claude Code, Copilot, Kilo Code: .claude/skills/my-skill/
|
|
748
|
-
# - Codex CLI: .codex/skills/my-skill/
|
|
749
|
-
# - Cursor: .cursor/skills/my-skill/
|
|
750
|
-
# - OpenCode: .opencode/skill/my-skill/
|
|
751
|
-
# - Goose, Amp: .agents/skills/my-skill/
|
|
752
|
-
# - Roo Code: .roo/skills/my-skill/
|
|
753
|
-
# - Gemini CLI: .gemini/skills/my-skill/
|
|
754
|
-
```
|
|
755
|
-
|
|
756
|
-
## `.gitignore` Integration
|
|
757
|
-
|
|
758
|
-
Skiller automatically manages your `.gitignore` file to keep generated agent configuration files out of version control.
|
|
759
|
-
|
|
760
|
-
### How it Works
|
|
761
|
-
|
|
762
|
-
- Creates or updates `.gitignore` in your project root
|
|
763
|
-
- Adds paths to a managed block marked with `# START Skiller Generated Files` and `# END Skiller Generated Files`
|
|
764
|
-
- Preserves existing content outside this block
|
|
765
|
-
- Sorts paths alphabetically and uses relative POSIX-style paths
|
|
766
|
-
|
|
767
|
-
### Example `.gitignore` Section (sample - actual list depends on enabled agents)
|
|
768
|
-
|
|
769
|
-
```gitignore
|
|
770
|
-
# Your existing rules
|
|
771
|
-
node_modules/
|
|
772
|
-
*.log
|
|
773
|
-
|
|
774
|
-
# START Skiller Generated Files
|
|
775
|
-
.aider.conf.yml
|
|
776
|
-
.clinerules
|
|
777
|
-
AGENTS.md
|
|
778
|
-
CLAUDE.md
|
|
779
|
-
# END Skiller Generated Files
|
|
780
|
-
|
|
781
|
-
dist/
|
|
782
|
-
```
|
|
783
|
-
|
|
784
|
-
### Control Options
|
|
785
|
-
|
|
786
|
-
- **CLI flags**: `--gitignore` or `--no-gitignore`
|
|
787
|
-
- **Configuration**: `[gitignore].enabled` in `skiller.toml`
|
|
788
|
-
- **Default**: enabled
|
|
789
|
-
|
|
790
|
-
## Practical Usage Scenarios
|
|
791
|
-
|
|
792
|
-
### Scenario 1: Getting Started Quickly
|
|
793
|
-
|
|
794
|
-
```bash
|
|
795
|
-
# Initialize Skiller in your project
|
|
796
|
-
cd your-project
|
|
797
|
-
skiller init
|
|
798
|
-
|
|
799
|
-
# Edit the generated files
|
|
800
|
-
# - Add your coding guidelines to .claude/AGENTS.md (or keep adding additional .md files)
|
|
801
|
-
# - Customize .claude/skiller.toml if needed
|
|
802
|
-
|
|
803
|
-
# Apply rules to all AI agents
|
|
804
|
-
skiller apply
|
|
805
|
-
```
|
|
806
|
-
|
|
807
|
-
### Scenario 2: Complex Projects with Nested Rules
|
|
808
|
-
|
|
809
|
-
For large projects with multiple components or services, enable nested rule loading so each directory keeps its own rules and MCP bundle:
|
|
810
|
-
|
|
811
|
-
```bash
|
|
812
|
-
# Set up nested .claude directories
|
|
813
|
-
mkdir -p src/.claude tests/.claude docs/.claude
|
|
814
|
-
|
|
815
|
-
# Add component-specific instructions
|
|
816
|
-
echo "# API Design Guidelines" > src/.claude/api_rules.md
|
|
817
|
-
echo "# Testing Best Practices" > tests/.claude/test_rules.md
|
|
818
|
-
echo "# Documentation Standards" > docs/.claude/docs_rules.md
|
|
819
|
-
```
|
|
820
|
-
|
|
821
|
-
```toml
|
|
822
|
-
# .claude/skiller.toml
|
|
823
|
-
nested = true
|
|
824
|
-
```
|
|
825
|
-
|
|
826
|
-
```bash
|
|
827
|
-
# The CLI inherits nested mode from skiller.toml
|
|
828
|
-
skiller apply --verbose
|
|
829
|
-
|
|
830
|
-
# Override from the CLI at any time
|
|
831
|
-
skiller apply --no-nested
|
|
832
|
-
```
|
|
833
|
-
|
|
834
|
-
This creates context-specific instructions for different parts of your project while maintaining global rules in the root `.claude/` directory. Nested runs automatically keep every nested config enabled even if a child tries to disable it.
|
|
835
|
-
|
|
836
|
-
> [!NOTE]
|
|
837
|
-
> The CLI prints "Nested mode is experimental and may change in future releases." the first time nested processing runs. Expect refinements in future versions.
|
|
838
|
-
|
|
839
|
-
### Scenario 3: Team Standardization
|
|
840
|
-
|
|
841
|
-
1. Create `.claude/coding_standards.md`, `.claude/api_usage.md`
|
|
842
|
-
2. Commit the `.claude` directory to your repository
|
|
843
|
-
3. Team members pull changes and run `skiller apply` to update their local AI agent configurations
|
|
844
|
-
|
|
845
|
-
### Scenario 4: Project-Specific Context for AI
|
|
846
|
-
|
|
847
|
-
1. Detail your project's architecture in `.claude/project_overview.md`
|
|
848
|
-
2. Describe primary data structures in `.claude/data_models.md`
|
|
849
|
-
3. Run `skiller apply` to help AI tools provide more relevant suggestions
|
|
850
|
-
|
|
851
|
-
### Integration with NPM Scripts
|
|
852
|
-
|
|
853
|
-
```json
|
|
854
|
-
{
|
|
855
|
-
"scripts": {
|
|
856
|
-
"skiller:apply": "skiller apply",
|
|
857
|
-
"dev": "npm run skiller:apply && your_dev_command",
|
|
858
|
-
"precommit": "npm run skiller:apply"
|
|
859
|
-
}
|
|
860
|
-
}
|
|
861
|
-
```
|
|
862
|
-
|
|
863
|
-
### Integration with GitHub Actions
|
|
864
|
-
|
|
865
|
-
```yaml
|
|
866
|
-
# .github/workflows/skiller-check.yml
|
|
867
|
-
name: Check Skiller Configuration
|
|
868
|
-
on:
|
|
869
|
-
pull_request:
|
|
870
|
-
paths: ['.claude/**']
|
|
871
|
-
|
|
872
|
-
jobs:
|
|
873
|
-
check-skiller:
|
|
874
|
-
runs-on: ubuntu-latest
|
|
875
|
-
steps:
|
|
876
|
-
- uses: actions/checkout@v4
|
|
877
|
-
- uses: actions/setup-node@v4
|
|
878
|
-
with:
|
|
879
|
-
node-version: '18'
|
|
880
|
-
cache: 'npm'
|
|
881
|
-
|
|
882
|
-
- name: Install Skiller
|
|
883
|
-
run: npm install -g skiller
|
|
884
|
-
|
|
885
|
-
- name: Apply Skiller configuration
|
|
886
|
-
run: skiller apply --no-gitignore
|
|
887
|
-
|
|
888
|
-
- name: Check for uncommitted changes
|
|
889
|
-
run: |
|
|
890
|
-
if [[ -n $(git status --porcelain) ]]; then
|
|
891
|
-
echo "::error::Skiller configuration is out of sync!"
|
|
892
|
-
echo "Please run 'skiller apply' locally and commit the changes."
|
|
893
|
-
exit 1
|
|
894
|
-
fi
|
|
895
|
-
```
|
|
896
|
-
|
|
897
|
-
## Troubleshooting
|
|
898
|
-
|
|
899
|
-
### Common Issues
|
|
900
|
-
|
|
901
|
-
**"Cannot find module" errors:**
|
|
902
|
-
|
|
903
|
-
- Ensure Skiller is installed globally: `npm install -g skiller`
|
|
904
|
-
- Or use `npx skiller@latest`
|
|
905
|
-
|
|
906
|
-
**Permission denied errors:**
|
|
907
|
-
|
|
908
|
-
- On Unix systems, you may need `sudo` for global installation
|
|
909
|
-
|
|
910
|
-
**Agent files not updating:**
|
|
911
|
-
|
|
912
|
-
- Check if the agent is enabled in `skiller.toml`
|
|
913
|
-
- Verify agent isn't excluded by `--agents` flag
|
|
914
|
-
- Use `--verbose` to see detailed execution logs
|
|
915
|
-
|
|
916
|
-
**Configuration validation errors:**
|
|
917
|
-
|
|
918
|
-
- Skiller now validates `skiller.toml` format and will show specific error details
|
|
919
|
-
- Check that all configuration values match the expected types and formats
|
|
920
|
-
|
|
921
|
-
### Debug Mode
|
|
922
|
-
|
|
923
|
-
Use `--verbose` flag to see detailed execution logs:
|
|
924
|
-
|
|
925
|
-
```bash
|
|
926
|
-
skiller apply --verbose
|
|
927
|
-
```
|
|
928
|
-
|
|
929
|
-
This shows:
|
|
930
|
-
|
|
931
|
-
- Configuration loading details
|
|
932
|
-
- Agent selection logic
|
|
933
|
-
- File processing information
|
|
934
|
-
- MCP configuration steps
|
|
935
|
-
|
|
936
|
-
## FAQ
|
|
937
|
-
|
|
938
|
-
**Q: Can I use different rules for different agents?**
|
|
939
|
-
A: Currently, all agents receive the same concatenated rules. For agent-specific instructions, include sections in your rule files like "## GitHub Copilot Specific" or "## Aider Configuration".
|
|
940
|
-
|
|
941
|
-
**Q: How do I set up different instructions for different parts of my project?**
|
|
942
|
-
A: Enable nested mode either by setting `nested = true` in `skiller.toml` or by passing `skiller apply --nested`. The CLI inherits the config setting by default, but `--no-nested` always wins if you need to opt out for a run. Nested mode keeps loading rules (and MCP settings) from every `.claude/` directory in the hierarchy, forces child configs to remain nested, and logs "Nested mode is experimental and may change in future releases." if any nested processing occurs.
|
|
943
|
-
|
|
944
|
-
**Q: How do I temporarily disable Skiller for an agent?**
|
|
945
|
-
A: Set `enabled = false` in `skiller.toml` under `[agents.agentname]`, or use `--agents` flag to specify only the agents you want.
|
|
946
|
-
|
|
947
|
-
**Q: What happens to my existing agent configuration files?**
|
|
948
|
-
A: Skiller creates backups with `.bak` extension before overwriting any existing files.
|
|
949
|
-
|
|
950
|
-
**Q: Can I run Skiller in CI/CD pipelines?**
|
|
951
|
-
A: Yes! Use `skiller apply --no-gitignore` in CI to avoid modifying `.gitignore`. See the GitHub Actions example above.
|
|
952
|
-
|
|
953
|
-
**Q: How does OpenHands MCP propagation classify servers?**
|
|
954
|
-
A: Local stdio servers become `stdio_servers`. Remote URLs containing `/sse` are classified as `sse_servers`; others become `shttp_servers`. Bearer tokens in an `Authorization` header are extracted into `api_key` where possible.
|
|
955
|
-
|
|
956
|
-
**Q: Where is Zed configuration written now?**
|
|
957
|
-
A: Skiller writes a `settings.json` in the project root (not the user home dir) and transforms MCP server definitions to Zed's `context_servers` format including `source: "custom"`.
|
|
958
|
-
|
|
959
|
-
**Q: What changed about MCP initialization?**
|
|
960
|
-
A: `skiller init` now only adds example MCP server sections to `skiller.toml` instead of creating `.claude/mcp.json`. The JSON file is still consumed if present, but TOML servers win on name conflicts.
|
|
961
|
-
|
|
962
|
-
**Q: Is Kiro supported?**
|
|
963
|
-
A: Yes. Kiro receives concatenated rules at `.kiro/steering/skiller_kiro_instructions.md`.
|
|
964
|
-
|
|
965
|
-
## Development
|
|
966
|
-
|
|
967
|
-
### Setup
|
|
968
|
-
|
|
969
|
-
```bash
|
|
970
|
-
git clone https://github.com/udecode/skiller.git
|
|
971
|
-
cd skiller
|
|
972
|
-
npm install
|
|
973
|
-
npm run build
|
|
974
|
-
```
|
|
975
|
-
|
|
976
|
-
### Testing
|
|
977
|
-
|
|
978
|
-
```bash
|
|
979
|
-
# Run all tests
|
|
980
|
-
npm test
|
|
981
|
-
|
|
982
|
-
# Run tests with coverage
|
|
983
|
-
npm run test:coverage
|
|
984
|
-
|
|
985
|
-
# Run tests in watch mode
|
|
986
|
-
npm run test:watch
|
|
987
|
-
```
|
|
988
|
-
|
|
989
|
-
### Code Quality
|
|
990
|
-
|
|
991
|
-
```bash
|
|
992
|
-
# Run linting
|
|
993
|
-
npm run lint
|
|
994
|
-
|
|
995
|
-
# Run formatting
|
|
996
|
-
npm run format
|
|
997
|
-
```
|
|
10
|
+
## Skills
|
|
11
|
+
|
|
12
|
+
- `.claude/skills/` is the committed source of truth
|
|
13
|
+
- On `apply`, skills are synced to all agents' native skill directories
|
|
14
|
+
- Claude Code plugins, commands, and agents are also synced as skills to other agents
|
|
15
|
+
- See [docs/skills.md](docs/skills.md)
|
|
16
|
+
|
|
17
|
+
## MCP
|
|
18
|
+
|
|
19
|
+
- Define MCP servers once in `skiller.toml`
|
|
20
|
+
- On `apply`, servers are propagated to all agents that support MCP
|
|
21
|
+
- See [docs/mcp.md](docs/mcp.md)
|
|
22
|
+
|
|
23
|
+
## Docs
|
|
24
|
+
|
|
25
|
+
- [docs/cli.md](docs/cli.md) — commands and flags
|
|
26
|
+
- [docs/config.md](docs/config.md) — `skiller.toml` reference
|
|
27
|
+
- [docs/skills.md](docs/skills.md) — skills, propagation, plugin sync
|
|
28
|
+
- [docs/mcp.md](docs/mcp.md) — MCP server config and propagation
|
|
29
|
+
- [docs/troubleshooting.md](docs/troubleshooting.md) — common failures and fixes
|
|
30
|
+
- [docs/development.md](docs/development.md) — dev workflow
|
|
31
|
+
- [docs/migration-from-ruler.md](docs/migration-from-ruler.md) — notes for `ruler` users
|
|
32
|
+
|
|
33
|
+
## Supported agents
|
|
34
|
+
|
|
35
|
+
| Identifier | Agent | Rules | MCP | Skills |
|
|
36
|
+
| ------------- | ----------------- | -------------------------------------------------------- | ------------------------------ | ----------------- |
|
|
37
|
+
| `agentsmd` | AgentsMd (pseudo) | `AGENTS.md` | - | - |
|
|
38
|
+
| `copilot` | GitHub Copilot | `AGENTS.md` | `.vscode/mcp.json` (`servers`) | `.claude/skills` |
|
|
39
|
+
| `claude` | Claude Code | `CLAUDE.md` (`@file` refs) | `.mcp.json` | `.claude/skills` |
|
|
40
|
+
| `codex` | OpenAI Codex CLI | `AGENTS.md`, `.codex/config.toml` | `.codex/config.toml` | `.codex/skills` |
|
|
41
|
+
| `cursor` | Cursor | `AGENTS.md` | `.cursor/mcp.json` | `.cursor/skills` |
|
|
42
|
+
| `windsurf` | Windsurf | `AGENTS.md` | `.windsurf/mcp_config.json` | - |
|
|
43
|
+
| `cline` | Cline | `.clinerules` | - | - |
|
|
44
|
+
| `aider` | Aider | `AGENTS.md`, `.aider.conf.yml` | `.mcp.json` | - |
|
|
45
|
+
| `firebase` | Firebase Studio | `.idx/airules.md` | `.idx/mcp.json` | - |
|
|
46
|
+
| `openhands` | Open Hands | `.openhands/microagents/repo.md` | `config.toml` | - |
|
|
47
|
+
| `gemini-cli` | Gemini CLI | `AGENTS.md`, `.gemini/settings.json` | `.gemini/settings.json` | `.gemini/skills` |
|
|
48
|
+
| `jules` | Jules | `AGENTS.md` | - | - |
|
|
49
|
+
| `junie` | Junie | `.junie/guidelines.md` | - | - |
|
|
50
|
+
| `augmentcode` | AugmentCode | `.augment/rules/skiller_augment_instructions.md` | - | - |
|
|
51
|
+
| `kilocode` | Kilo Code | `.kilocode/rules/skiller_kilocode_instructions.md` | `.kilocode/mcp.json` | `.claude/skills` |
|
|
52
|
+
| `opencode` | OpenCode | `AGENTS.md`, `opencode.json` | `opencode.json` | `.opencode/skill` |
|
|
53
|
+
| `goose` | Goose | `.goosehints` | - | `.agents/skills` |
|
|
54
|
+
| `crush` | Crush | `CRUSH.md`, `.crush.json` | `.crush.json` | - |
|
|
55
|
+
| `amp` | Amp | `AGENTS.md` | - | `.agents/skills` |
|
|
56
|
+
| `zed` | Zed | `AGENTS.md`, `.zed/settings.json` | `.zed/settings.json` | - |
|
|
57
|
+
| `qwen` | Qwen Code | `AGENTS.md`, `.qwen/settings.json` | `.qwen/settings.json` | - |
|
|
58
|
+
| `kiro` | Kiro | `.kiro/steering/skiller_kiro_instructions.md` | - | - |
|
|
59
|
+
| `warp` | Warp | `WARP.md` | - | - |
|
|
60
|
+
| `roo` | RooCode | `AGENTS.md`, `.roo/mcp.json` | `.roo/mcp.json` | `.roo/skills` |
|
|
61
|
+
| `trae` | Trae AI | `.trae/rules/project_rules.md` | - | - |
|
|
62
|
+
| `amazonqcli` | Amazon Q CLI | `.amazonq/rules/skiller_q_rules.md`, `.amazonq/mcp.json` | `.amazonq/mcp.json` | - |
|
|
63
|
+
| `firebender` | Firebender | `firebender.json` | `firebender.json` | - |
|
|
@@ -143,6 +143,50 @@ async function resolvePluginMarketplaceRoot(pluginId, claudeDir) {
|
|
|
143
143
|
}
|
|
144
144
|
return null;
|
|
145
145
|
}
|
|
146
|
+
async function hasPluginContent(root) {
|
|
147
|
+
const candidates = [
|
|
148
|
+
path.join(root, 'skills'),
|
|
149
|
+
path.join(root, 'commands'),
|
|
150
|
+
path.join(root, 'agents'),
|
|
151
|
+
];
|
|
152
|
+
for (const candidate of candidates) {
|
|
153
|
+
if (await dirExists(candidate))
|
|
154
|
+
return true;
|
|
155
|
+
}
|
|
156
|
+
return false;
|
|
157
|
+
}
|
|
158
|
+
async function readPluginPackageManifestEntries(installPath) {
|
|
159
|
+
const packageJsonPath = path.join(installPath, 'package.json');
|
|
160
|
+
try {
|
|
161
|
+
const raw = JSON.parse(await fs.readFile(packageJsonPath, 'utf8'));
|
|
162
|
+
if (!Array.isArray(raw.plugins))
|
|
163
|
+
return [];
|
|
164
|
+
return raw.plugins.filter((entry) => Boolean(entry) && typeof entry === 'object');
|
|
165
|
+
}
|
|
166
|
+
catch {
|
|
167
|
+
return [];
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
async function resolveInstalledPluginSourceRoot(pluginId, installPath) {
|
|
171
|
+
const manifestEntries = await readPluginPackageManifestEntries(installPath);
|
|
172
|
+
const parsedPluginId = parsePluginId(pluginId);
|
|
173
|
+
const matchingEntry = manifestEntries.find((entry) => entry.name === parsedPluginId?.pluginName) ?? (manifestEntries.length === 1 ? manifestEntries[0] : null);
|
|
174
|
+
const rawSource = typeof matchingEntry?.source === 'string' &&
|
|
175
|
+
matchingEntry.source.trim() !== ''
|
|
176
|
+
? matchingEntry.source
|
|
177
|
+
: '.';
|
|
178
|
+
const sourceRoot = path.resolve(installPath, rawSource);
|
|
179
|
+
const normalizedInstallPath = path.resolve(installPath);
|
|
180
|
+
const isWithinInstallPath = sourceRoot === normalizedInstallPath ||
|
|
181
|
+
sourceRoot.startsWith(normalizedInstallPath + path.sep);
|
|
182
|
+
if (isWithinInstallPath && (await hasPluginContent(sourceRoot))) {
|
|
183
|
+
return sourceRoot;
|
|
184
|
+
}
|
|
185
|
+
if (await hasPluginContent(installPath)) {
|
|
186
|
+
return installPath;
|
|
187
|
+
}
|
|
188
|
+
return null;
|
|
189
|
+
}
|
|
146
190
|
function resolvePluginInstall(pluginId, projectRoot, index) {
|
|
147
191
|
const entries = index.plugins?.[pluginId];
|
|
148
192
|
if (!entries || !Array.isArray(entries) || entries.length === 0)
|
|
@@ -622,21 +666,27 @@ async function syncClaudePluginsToSkillsDirs(args) {
|
|
|
622
666
|
const resolvedSources = [];
|
|
623
667
|
const unresolvedEnabled = new Set();
|
|
624
668
|
for (const pluginId of enabledPlugins) {
|
|
625
|
-
const
|
|
669
|
+
const resolved = index
|
|
670
|
+
? resolvePluginInstall(pluginId, projectRoot, index)
|
|
671
|
+
: null;
|
|
672
|
+
const marketplaceRoot = await resolvePluginMarketplaceRoot(pluginId, claudeDir);
|
|
673
|
+
const pluginRoot = (marketplaceRoot && (await hasPluginContent(marketplaceRoot))
|
|
674
|
+
? marketplaceRoot
|
|
675
|
+
: null) ??
|
|
676
|
+
(resolved
|
|
677
|
+
? await resolveInstalledPluginSourceRoot(pluginId, resolved.installPath)
|
|
678
|
+
: null);
|
|
626
679
|
if (!pluginRoot) {
|
|
627
680
|
unresolvedEnabled.add(pluginId);
|
|
628
681
|
const hasIndexEntry = Boolean(index?.plugins?.[pluginId]?.length);
|
|
629
682
|
if (hasIndexEntry) {
|
|
630
|
-
(0, constants_1.logVerboseInfo)(`[plugins] Enabled plugin has no
|
|
683
|
+
(0, constants_1.logVerboseInfo)(`[plugins] Enabled plugin has no syncable content, skipping: ${pluginId}`, verbose, dryRun);
|
|
631
684
|
}
|
|
632
685
|
else {
|
|
633
686
|
(0, constants_1.logWarn)(`[plugins] Enabled plugin not installed: ${pluginId}`, dryRun);
|
|
634
687
|
}
|
|
635
688
|
continue;
|
|
636
689
|
}
|
|
637
|
-
const resolved = index
|
|
638
|
-
? resolvePluginInstall(pluginId, projectRoot, index)
|
|
639
|
-
: null;
|
|
640
690
|
resolvedSources.push({
|
|
641
691
|
pluginId,
|
|
642
692
|
pluginRoot,
|
|
@@ -512,9 +512,13 @@ async function applyStandardMcpConfiguration(agent, filteredMcpJson, dest, agent
|
|
|
512
512
|
(0, constants_1.logVerbose)(`DRY RUN: Would apply MCP config to: ${dest}`, verbose);
|
|
513
513
|
}
|
|
514
514
|
else {
|
|
515
|
-
// Transform MCP config for
|
|
515
|
+
// Transform MCP config for compatibility.
|
|
516
|
+
//
|
|
517
|
+
// `.mcp.json` is shared (Claude Code + others). Keep it Claude-compatible
|
|
518
|
+
// so later agents don't overwrite `http|sse` back to legacy `remote`.
|
|
516
519
|
let mcpToMerge = filteredMcpJson;
|
|
517
|
-
if (agent.getIdentifier() === 'claude'
|
|
520
|
+
if (agent.getIdentifier() === 'claude' ||
|
|
521
|
+
path.basename(dest) === '.mcp.json') {
|
|
518
522
|
mcpToMerge = transformMcpForClaude(filteredMcpJson);
|
|
519
523
|
}
|
|
520
524
|
else if (agent.getIdentifier() === 'kilocode') {
|
package/package.json
CHANGED
|
@@ -1,79 +1,78 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
}
|
|
2
|
+
"name": "skiller",
|
|
3
|
+
"version": "0.7.22",
|
|
4
|
+
"description": "Skiller — apply the same rules to all coding agents",
|
|
5
|
+
"main": "dist/lib.js",
|
|
6
|
+
"publishConfig": {
|
|
7
|
+
"access": "public"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"lint": "eslint \"src/**/*.{ts,tsx}\"",
|
|
11
|
+
"lint:fix": "eslint \"src/**/*.{ts,tsx}\" --fix",
|
|
12
|
+
"format": "prettier --write \"src/**/*.{ts,tsx,json,md}\"",
|
|
13
|
+
"test": "jest",
|
|
14
|
+
"test:watch": "jest --watch",
|
|
15
|
+
"test:coverage": "jest --coverage",
|
|
16
|
+
"test:integration": "jest tests/e2e/skiller.integration.test.ts --verbose",
|
|
17
|
+
"build": "tsc",
|
|
18
|
+
"release": "pnpm build && pnpm changeset publish"
|
|
19
|
+
},
|
|
20
|
+
"repository": {
|
|
21
|
+
"type": "git",
|
|
22
|
+
"url": "git+https://github.com/udecode/skiller.git"
|
|
23
|
+
},
|
|
24
|
+
"keywords": [
|
|
25
|
+
"ai",
|
|
26
|
+
"developer-tools",
|
|
27
|
+
"copilot",
|
|
28
|
+
"codex",
|
|
29
|
+
"claude",
|
|
30
|
+
"cursor",
|
|
31
|
+
"aider",
|
|
32
|
+
"config",
|
|
33
|
+
"rules",
|
|
34
|
+
"automation"
|
|
35
|
+
],
|
|
36
|
+
"author": "Eleanor Berger",
|
|
37
|
+
"license": "MIT",
|
|
38
|
+
"bugs": {
|
|
39
|
+
"url": "https://github.com/udecode/skiller/issues"
|
|
40
|
+
},
|
|
41
|
+
"engines": {
|
|
42
|
+
"node": ">=18"
|
|
43
|
+
},
|
|
44
|
+
"files": [
|
|
45
|
+
"dist",
|
|
46
|
+
"README.md",
|
|
47
|
+
"LICENSE"
|
|
48
|
+
],
|
|
49
|
+
"bin": {
|
|
50
|
+
"skiller": "dist/cli/index.js"
|
|
51
|
+
},
|
|
52
|
+
"devDependencies": {
|
|
53
|
+
"@changesets/changelog-github": "^0.5.2",
|
|
54
|
+
"@changesets/cli": "2.29.8",
|
|
55
|
+
"@eslint/js": "^9.39.1",
|
|
56
|
+
"@types/iarna__toml": "^2.0.5",
|
|
57
|
+
"@types/jest": "^29.5.14",
|
|
58
|
+
"@types/js-yaml": "^4.0.9",
|
|
59
|
+
"@types/node": "^24.9.2",
|
|
60
|
+
"@types/yargs": "^17.0.34",
|
|
61
|
+
"@typescript-eslint/eslint-plugin": "^8.46.2",
|
|
62
|
+
"@typescript-eslint/parser": "^8.46.2",
|
|
63
|
+
"eslint": "^9.38.0",
|
|
64
|
+
"eslint-config-prettier": "^10.1.8",
|
|
65
|
+
"eslint-plugin-prettier": "^5.5.4",
|
|
66
|
+
"jest": "^29.7.0",
|
|
67
|
+
"prettier": "^3.6.2",
|
|
68
|
+
"ts-jest": "^29.4.5",
|
|
69
|
+
"typescript": "^5.9.3",
|
|
70
|
+
"typescript-eslint": "^8.46.2"
|
|
71
|
+
},
|
|
72
|
+
"dependencies": {
|
|
73
|
+
"@iarna/toml": "^2.2.5",
|
|
74
|
+
"js-yaml": "^4.1.0",
|
|
75
|
+
"yargs": "^18.0.0",
|
|
76
|
+
"zod": "^4.1.12"
|
|
77
|
+
}
|
|
79
78
|
}
|