pluribus-context 0.2.0

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.
@@ -0,0 +1,356 @@
1
+ # Pluribus Context Format Spec
2
+
3
+ **Version:** 0.1.0-draft
4
+ **Status:** Draft
5
+ **Date:** 2026-03-08
6
+
7
+ ---
8
+
9
+ ## Overview
10
+
11
+ The Pluribus context format defines a single, human-readable Markdown file — `pluribus.md` — that serves as the authoritative source of truth for AI tool context in a project. From this one file, Pluribus generates all tool-specific files (CLAUDE.md, .cursorrules, AGENTS.md, etc.) without duplication or drift.
12
+
13
+ This spec defines the structure, sections, parsing rules, and conventions for `pluribus.md`.
14
+
15
+ ---
16
+
17
+ ## File Location
18
+
19
+ **Primary (flat):** `pluribus.md` in the project root.
20
+ **Structured (multi-file):** `pluribus/context.md`, `pluribus/identity.md`, `pluribus/skills.md`, `pluribus/rules.md`
21
+
22
+ When both exist, the structured form takes precedence. The flat form is recommended for single-developer projects; the structured form for teams with complex contexts.
23
+
24
+ This spec covers the flat form. The structured form follows the same section rules, distributed across files.
25
+
26
+ ---
27
+
28
+ ## Composable Contexts
29
+
30
+ A `pluribus.md` file may import other local Markdown context files with `# @import` directives:
31
+
32
+ ```markdown
33
+ # @import ./shared/team-context.md
34
+ # @import ./shared/security-constraints.md
35
+ ```
36
+
37
+ Imports are resolved during `pluribus sync` before the file is parsed into sections.
38
+
39
+ ### Import Rules
40
+
41
+ - Import paths are resolved relative to the file containing the directive.
42
+ - Imports are expanded before the importing file's own local content.
43
+ - Later duplicate top-level sections override earlier ones through the existing parser behavior, so project-local sections win over shared imported sections.
44
+ - Nested imports are allowed up to depth `5`.
45
+ - Cycles are rejected with the import path chain.
46
+ - Imports cannot escape the project/source root.
47
+ - Remote imports are refreshed only when sync is run with explicit network refresh (`pluribus sync --update-imports`).
48
+ - `github:owner/repo/path.md[@ref]` resolves to raw GitHub content; nested relative imports stay within the same repo/ref.
49
+ - Private `github:` imports may use existing `GH_TOKEN`/`GITHUB_TOKEN` or logged-in GitHub CLI credentials during explicit refresh only.
50
+ - Direct `https://...` Markdown/text imports are supported; `http://` and credential-bearing URLs are rejected.
51
+ - Remote fetches enforce timeout, redirect, UTF-8/text content, per-file size, and merged-size limits.
52
+ - Refresh writes `pluribus.lock.json` plus `.pluribus/cache/remote/<sha256>.md` entries for each fetched remote document.
53
+ - Tokens are never stored in lockfile or cache entries; the lockfile may be committed and the cache is local/regenerable.
54
+ - Later sync runs resolve remote imports from that lock/cache without network access and verify the cached bytes against the recorded SHA-256 digest.
55
+ - If a remote import is referenced but not yet locked/cached, sync fails closed and asks for `--update-imports`.
56
+ - Context files are never executed; imports only read Markdown text.
57
+
58
+ ### Example
59
+
60
+ ```markdown
61
+ # @import ./shared/base-context.md
62
+
63
+ # Goals
64
+ 1. Project-specific goals override the shared `# Goals` section.
65
+ ```
66
+
67
+ ---
68
+
69
+ ## Canonical Sections
70
+
71
+ A `pluribus.md` file is composed of top-level Markdown headings. Each heading is a **section**. Sections are case-sensitive and must be level-1 headings (`#`).
72
+
73
+ ### Required Sections
74
+
75
+ | Section | Purpose |
76
+ |---|---|
77
+ | `# Identity` | Who the project owner is; the agent/AI persona if applicable |
78
+ | `# Stack` | Technology stack: language, framework, tooling, infrastructure |
79
+ | `# Conventions` | Code style, patterns, naming rules, workflow expectations |
80
+ | `# Goals` | What this project is trying to achieve; what matters most |
81
+ | `# Constraints` | Hard rules — what the AI must never do |
82
+
83
+ All five required sections must be present for a valid `pluribus.md`.
84
+
85
+ ### Optional Sections
86
+
87
+ | Section | Purpose |
88
+ |---|---|
89
+ | `# Examples` | Concrete code snippets or interaction examples |
90
+ | `# Anti-patterns` | Patterns that look reasonable but should be avoided in this project |
91
+ | `# Workflow` | Development workflow: branching, PRs, testing, deployment |
92
+ | `# Context` | Background the AI needs to understand the project domain |
93
+ | `# Team` | Team members, roles, areas of ownership |
94
+
95
+ Optional sections may appear in any order after the required sections.
96
+
97
+ ---
98
+
99
+ ## Section Specification
100
+
101
+ ### `# Identity`
102
+
103
+ Who you are, what the project is, and (if applicable) the AI persona to adopt.
104
+
105
+ **Guidelines:**
106
+ - Keep this concise — 3–10 lines
107
+ - Include: your name or team name, the project name, the project's purpose in one sentence
108
+ - If the project uses an AI agent with a defined persona, describe it here
109
+
110
+ **Example:**
111
+ ```markdown
112
+ # Identity
113
+
114
+ I am Carlos, a solo developer building **Velo** — a lightweight task manager for developers who live in the terminal.
115
+
116
+ Velo is a TypeScript CLI tool. Users are developers. They value speed and simplicity over features.
117
+ ```
118
+
119
+ ---
120
+
121
+ ### `# Stack`
122
+
123
+ The full technical picture of the project.
124
+
125
+ **Guidelines:**
126
+ - List language + version, frameworks, key libraries, test tools, linter/formatter, infrastructure
127
+ - Be specific — "TypeScript 5.4" is better than "TypeScript"
128
+ - Include what is intentionally excluded (e.g., "no ORM — raw SQL via `postgres` driver")
129
+
130
+ **Example:**
131
+ ```markdown
132
+ # Stack
133
+
134
+ - **Language:** TypeScript 5.4 (strict mode)
135
+ - **Runtime:** Node.js 22 LTS
136
+ - **Framework:** None — pure Node CLI
137
+ - **Testing:** Jest 29 + ts-jest
138
+ - **Linting:** ESLint (flat config) + Prettier
139
+ - **Package manager:** pnpm
140
+ - **CI:** GitHub Actions
141
+ - **No ORM** — raw SQL via `postgres` driver
142
+ ```
143
+
144
+ ---
145
+
146
+ ### `# Conventions`
147
+
148
+ How code is written in this project. This section directly shapes AI behavior during code generation and review.
149
+
150
+ **Guidelines:**
151
+ - Be opinionated and explicit
152
+ - Cover: async patterns, error handling, naming conventions, file structure, forbidden patterns
153
+ - Prefer positive rules ("always X") over vague ones ("use good naming")
154
+
155
+ **Example:**
156
+ ```markdown
157
+ # Conventions
158
+
159
+ - Always use `async/await` — never `.then()/.catch()` chains
160
+ - No class-based code — use plain functions and closures
161
+ - Error handling: never swallow errors silently; always propagate or log
162
+ - File naming: `kebab-case.ts`
163
+ - Exports: named exports only — no default exports
164
+ - Tests: one `describe` block per module; test file lives next to the source file
165
+ - No `any` — use `unknown` and narrow types explicitly
166
+ - Prefer `const` over `let`; never `var`
167
+ ```
168
+
169
+ ---
170
+
171
+ ### `# Goals`
172
+
173
+ What this project is optimizing for. Helps the AI make trade-off decisions.
174
+
175
+ **Guidelines:**
176
+ - List 3–7 goals in priority order
177
+ - Be specific to this project — not generic engineering virtues
178
+ - Include product goals, not just technical goals
179
+
180
+ **Example:**
181
+ ```markdown
182
+ # Goals
183
+
184
+ 1. Ship fast — the project is pre-launch; velocity matters more than perfection
185
+ 2. Keep the codebase small and readable — a new contributor should understand the whole codebase in 30 minutes
186
+ 3. Zero runtime dependencies where possible — this is a CLI tool; bloat matters
187
+ 4. 100% type coverage — TypeScript strict mode, no escape hatches
188
+ 5. Developer experience over user customizability
189
+ ```
190
+
191
+ ---
192
+
193
+ ### `# Constraints`
194
+
195
+ Hard rules. What the AI must never do, regardless of context.
196
+
197
+ **Guidelines:**
198
+ - State constraints clearly and firmly
199
+ - Include security, architectural, and process constraints
200
+ - These map directly to AI tool guardrails
201
+
202
+ **Example:**
203
+ ```markdown
204
+ # Constraints
205
+
206
+ - Never introduce new dependencies without explicit confirmation
207
+ - Never use `eval`, `Function()`, or dynamic `require()`
208
+ - Never write to the filesystem outside of designated output directories
209
+ - Never delete or overwrite files without a dry-run option
210
+ - Never use class-based patterns — not even for error types (use plain objects + type guards)
211
+ - Do not modify `package.json` or lock files autonomously
212
+ ```
213
+
214
+ ---
215
+
216
+ ### `# Examples` (optional)
217
+
218
+ Concrete code that shows what "good" looks like in this project. The AI uses these as style references.
219
+
220
+ **Guidelines:**
221
+ - Include 1–3 representative examples
222
+ - Show the pattern, not just the syntax
223
+ - Label each example clearly
224
+
225
+ ---
226
+
227
+ ### `# Anti-patterns` (optional)
228
+
229
+ Patterns that look acceptable but should be avoided in this specific project.
230
+
231
+ **Guidelines:**
232
+ - Each entry: name the pattern, explain why it's banned here
233
+ - Keep it short — this is a warning list, not a tutorial
234
+
235
+ ---
236
+
237
+ ## Parsing Rules
238
+
239
+ Pluribus parses `pluribus.md` using the following rules:
240
+
241
+ 1. **Section detection:** A section starts at any level-1 heading (`# Heading`) and ends at the next level-1 heading or EOF.
242
+ 2. **Section content:** Everything between the heading and the next `#` heading is the section body. Subheadings (`##`, `###`) within a section are preserved as-is.
243
+ 3. **Unknown sections:** Any section not in the canonical list is preserved and passed to skills as `extra.<section-slug>`.
244
+ 4. **Whitespace:** Leading and trailing whitespace within a section body is trimmed.
245
+ 5. **No execution:** Pluribus never executes code blocks inside `pluribus.md`. They are treated as literal text.
246
+ 6. **Encoding:** UTF-8. Files with BOM are supported but the BOM is stripped.
247
+ 7. **Imports:** `# @import ./path.md` directives are resolved before section parsing. The directive itself is not preserved in generated tool output.
248
+
249
+ ---
250
+
251
+ ## Validation
252
+
253
+ A valid `pluribus.md` must:
254
+
255
+ - [ ] Contain all 5 required sections
256
+ - [ ] Have each required section non-empty (at least one non-whitespace line)
257
+ - [ ] Be valid UTF-8
258
+ - [ ] Have no duplicate top-level section names
259
+
260
+ Run `pluribus validate` to check your file.
261
+
262
+ ---
263
+
264
+ ## Full Example
265
+
266
+ Below is a complete, realistic `pluribus.md` for a Node.js TypeScript project.
267
+
268
+ ```markdown
269
+ # Identity
270
+
271
+ I am Ana, building **Conduit** — a background job runner for Node.js applications.
272
+
273
+ Conduit lets you schedule, retry, and monitor background jobs without a Redis dependency.
274
+ Target users: backend developers who want a simple, reliable job queue without infrastructure overhead.
275
+
276
+ # Stack
277
+
278
+ - **Language:** TypeScript 5.4 (strict mode, no `any`)
279
+ - **Runtime:** Node.js 22 LTS
280
+ - **Framework:** Fastify 4 (HTTP API for the dashboard)
281
+ - **Database:** SQLite via `better-sqlite3` (embedded; no external DB required)
282
+ - **Testing:** Jest 29 + ts-jest + Supertest
283
+ - **Linting:** ESLint (flat config) + Prettier (2-space indent, single quotes)
284
+ - **Package manager:** pnpm 9
285
+ - **CI:** GitHub Actions — lint + test on every PR
286
+ - **No Redis, no RabbitMQ, no external message broker**
287
+
288
+ # Conventions
289
+
290
+ - Always `async/await` — no `.then()/.catch()`
291
+ - No classes — all logic is plain functions; data is plain objects with explicit types
292
+ - Error handling: create typed error objects (`{ code, message, cause }`); never throw strings
293
+ - File structure: `src/core/` for domain logic, `src/api/` for HTTP handlers, `src/db/` for DB layer
294
+ - Named exports only — no default exports
295
+ - Test files: `*.test.ts` co-located with source; each test file has one top-level `describe`
296
+ - Database access: only through functions in `src/db/` — no raw SQL in core or API layers
297
+ - No `process.exit()` in library code — only in the CLI entrypoint
298
+
299
+ # Goals
300
+
301
+ 1. Zero external infrastructure — Conduit should work with just Node.js and a file path
302
+ 2. Type safety end-to-end — every public API is fully typed
303
+ 3. Readable codebase — optimized for new contributors to get up to speed in < 1 hour
304
+ 4. Reliable job delivery — retry logic and failure tracking are first-class, not afterthoughts
305
+ 5. Minimal API surface — fewer methods, more composable
306
+
307
+ # Constraints
308
+
309
+ - Never introduce a dependency that requires native compilation (no native addons)
310
+ - Never write to disk outside of the configured data directory
311
+ - Never skip tests for a PR — CI must pass; no `--no-verify`
312
+ - Do not use `any` — use `unknown` with type narrowing
313
+ - Do not use class syntax — not even for custom errors
314
+ - Never auto-migrate the database schema — migrations are explicit and versioned
315
+
316
+ # Examples
317
+
318
+ ## Defining a job handler
319
+
320
+ ```typescript
321
+ import type { JobHandler } from '../types.js'
322
+
323
+ export const sendWelcomeEmail: JobHandler<{ userId: string }> = async (job) => {
324
+ const user = await getUser(job.data.userId)
325
+ await emailService.send({
326
+ to: user.email,
327
+ template: 'welcome',
328
+ })
329
+ }
330
+ ```
331
+
332
+ ## Scheduling a job
333
+
334
+ ```typescript
335
+ const jobId = await queue.enqueue('send-welcome-email', {
336
+ data: { userId: 'usr_123' },
337
+ runAt: new Date(Date.now() + 5000),
338
+ maxRetries: 3,
339
+ })
340
+ ```
341
+
342
+ # Anti-patterns
343
+
344
+ - **God functions:** Functions > 50 lines are a sign something should be extracted
345
+ - **Implicit any via `JSON.parse`:** Always assert the shape with a type guard after parsing
346
+ - **Shared mutable state:** No module-level variables that accumulate state across requests
347
+ - **Catching and re-throwing without context:** Always add `cause` when wrapping errors
348
+ ```
349
+
350
+ ---
351
+
352
+ ## Changelog
353
+
354
+ | Version | Date | Notes |
355
+ |---|---|---|
356
+ | 0.1.0-draft | 2026-03-08 | Initial draft |
@@ -0,0 +1,325 @@
1
+ # Pluribus Skills Format Spec
2
+
3
+ **Version:** 0.1.0-draft
4
+ **Status:** Draft
5
+ **Date:** 2026-03-08
6
+
7
+ ---
8
+
9
+ ## Overview
10
+
11
+ A **skill** is a Pluribus adapter that defines how to transform a `pluribus.md` context into a tool-specific output file. Skills are what make Pluribus extensible: adding support for a new AI tool means writing a new skill — a single Markdown file with a defined structure.
12
+
13
+ This spec defines the skills file format, the built-in skills, and how to write a custom skill.
14
+
15
+ ---
16
+
17
+ ## Skills Directory
18
+
19
+ Skills live in the `pluribus/skills/` directory of the project:
20
+
21
+ ```
22
+ pluribus/
23
+ └── skills/
24
+ ├── claude.md ← built-in (can be overridden)
25
+ ├── cursor.md ← built-in (can be overridden)
26
+ ├── copilot.md ← built-in (can be overridden)
27
+ ├── openclaw.md ← built-in (can be overridden)
28
+ └── my-custom.md ← custom skill
29
+ ```
30
+
31
+ **Override behavior:** If a skill file exists in `pluribus/skills/`, it overrides the built-in with the same name. This allows teams to customize how their context is rendered for a specific tool without forking Pluribus.
32
+
33
+ **Built-in skills** ship with the Pluribus CLI and are used if no local override exists.
34
+
35
+ ---
36
+
37
+ ## Skill File Structure
38
+
39
+ A skill file is a Markdown file with three required top-level sections and one optional section.
40
+
41
+ ```
42
+ # Output
43
+ # Template
44
+ # Sections
45
+ ```
46
+
47
+ ### `# Output`
48
+
49
+ Declares what file(s) this skill generates. Each line is a target file path relative to the project root.
50
+
51
+ **Format:**
52
+ ```markdown
53
+ # Output
54
+
55
+ CLAUDE.md
56
+ ```
57
+
58
+ Multiple outputs are supported (e.g., when a tool expects files in multiple locations):
59
+
60
+ ```markdown
61
+ # Output
62
+
63
+ .github/copilot-instructions.md
64
+ .github/copilot-instructions-workspace.md
65
+ ```
66
+
67
+ **Rules:**
68
+ - Paths are relative to the project root
69
+ - Directories are created automatically if they don't exist
70
+ - Existing files are overwritten on each `pluribus sync` run
71
+ - File paths must be valid for the operating system
72
+
73
+ ---
74
+
75
+ ### `# Template`
76
+
77
+ Defines how the output file is rendered. The template uses **Pluribus Template Syntax (PTS)** — a minimal, Mustache-inspired syntax embedded in Markdown.
78
+
79
+ #### Variables
80
+
81
+ | Variable | Resolves to |
82
+ |---|---|
83
+ | `{{identity}}` | Full content of the `# Identity` section |
84
+ | `{{stack}}` | Full content of the `# Stack` section |
85
+ | `{{conventions}}` | Full content of the `# Conventions` section |
86
+ | `{{goals}}` | Full content of the `# Goals` section |
87
+ | `{{constraints}}` | Full content of the `# Constraints` section |
88
+ | `{{examples}}` | Full content of the `# Examples` section (empty string if absent) |
89
+ | `{{anti-patterns}}` | Full content of the `# Anti-patterns` section (empty string if absent) |
90
+ | `{{<section-slug>}}` | Content of any section, referenced by its slug (lowercase, hyphens) |
91
+ | `{{pluribus.version}}` | The Pluribus CLI version used to generate the file |
92
+ | `{{pluribus.date}}` | ISO 8601 date when the file was generated |
93
+ | `{{pluribus.source}}` | The source file path (`pluribus.md` or `pluribus/context.md`) |
94
+
95
+ #### Conditional Blocks
96
+
97
+ Optional sections can be conditionally included using `{{#if}}` blocks:
98
+
99
+ ```
100
+ {{#if examples}}
101
+ ## Examples
102
+
103
+ {{examples}}
104
+ {{/if}}
105
+ ```
106
+
107
+ The block renders only if the section is non-empty.
108
+
109
+ #### Literal Text
110
+
111
+ Everything outside of `{{ }}` tags is emitted literally into the output file. This includes any preamble, headings, or formatting that the tool expects.
112
+
113
+ #### Example Template
114
+
115
+ ```markdown
116
+ # Template
117
+
118
+ <!-- Generated by Pluribus {{pluribus.version}} on {{pluribus.date}} — do not edit manually -->
119
+ <!-- Source: {{pluribus.source}} -->
120
+
121
+ # Project Context
122
+
123
+ ## Who I Am
124
+
125
+ {{identity}}
126
+
127
+ ## Tech Stack
128
+
129
+ {{stack}}
130
+
131
+ ## How We Write Code
132
+
133
+ {{conventions}}
134
+
135
+ ## What We're Building Toward
136
+
137
+ {{goals}}
138
+
139
+ ## Hard Rules
140
+
141
+ {{constraints}}
142
+
143
+ {{#if examples}}
144
+ ## Code Examples
145
+
146
+ {{examples}}
147
+ {{/if}}
148
+
149
+ {{#if anti-patterns}}
150
+ ## What to Avoid
151
+
152
+ {{anti-patterns}}
153
+ {{/if}}
154
+ ```
155
+
156
+ ---
157
+
158
+ ### `# Sections`
159
+
160
+ Declares which sections from `pluribus.md` this skill uses, and in what order. This serves as both documentation and validation input — Pluribus can warn if a required section is missing.
161
+
162
+ **Format:**
163
+ ```markdown
164
+ # Sections
165
+
166
+ required: identity, stack, conventions, goals, constraints
167
+ optional: examples, anti-patterns
168
+ ```
169
+
170
+ **Rules:**
171
+ - `required` sections must all be present in `pluribus.md` for the skill to render
172
+ - `optional` sections are included if present; silently omitted if absent
173
+ - The order listed here is the recommended rendering order (but the Template controls actual order)
174
+
175
+ ---
176
+
177
+ ### `# Meta` (optional)
178
+
179
+ Optional metadata about the skill.
180
+
181
+ ```markdown
182
+ # Meta
183
+
184
+ name: Claude Code
185
+ tool: claude
186
+ description: Generates CLAUDE.md for use with Claude Code (Anthropic)
187
+ version: 1.0.0
188
+ author: Pluribus contributors
189
+ ```
190
+
191
+ ---
192
+
193
+ ## Built-in Skills
194
+
195
+ Pluribus ships with seven built-in skills. Their behavior is defined below. The full template source is available in the Pluribus source repository under `src/skills/`.
196
+
197
+ ### `claude`
198
+
199
+ - **Output:** `CLAUDE.md`
200
+ - **Target tool:** Claude Code (Anthropic)
201
+ - **Format:** A single Markdown file. Claude Code reads the full file before every session. Optimized for verbosity — Claude benefits from detailed conventions and constraints.
202
+ - **Sections used:** all required + examples + anti-patterns
203
+
204
+ ### `cursor`
205
+
206
+ - **Output:** `.cursorrules`
207
+ - **Target tool:** Cursor AI editor
208
+ - **Format:** Plain text rules file. Cursor reads this as AI instructions. More concise than Claude — strip headings, emit bullet points.
209
+ - **Sections used:** conventions, constraints, goals (identity and stack are condensed into a single preamble)
210
+
211
+ ### `copilot`
212
+
213
+ - **Output:** `.github/copilot-instructions.md`
214
+ - **Target tool:** GitHub Copilot
215
+ - **Format:** Markdown. Copilot uses this for inline code suggestions. Focus on conventions and stack; omit identity and goals (Copilot is suggestion-oriented, not context-oriented).
216
+ - **Sections used:** stack, conventions, constraints
217
+
218
+ ### `openclaw`
219
+
220
+ - **Output:** `AGENTS.md`
221
+ - **Target tool:** OpenClaw AI agent runner
222
+ - **Format:** Markdown with specific sections OpenClaw expects: `## Identity`, `## Role`, `## Stack`, `## Conventions`, `## Constraints`. OpenClaw also reads `SOUL.md` for tone — skills can optionally generate `SOUL.md` as a second output.
223
+ - **Sections used:** all required + examples
224
+
225
+ ### `windsurf`
226
+
227
+ - **Output:** `.windsurf/rules/pluribus.md`
228
+ - **Target tool:** Windsurf Cascade workspace rules
229
+ - **Format:** Markdown workspace rule with `trigger: always_on` frontmatter. Windsurf currently discovers workspace rules from `.windsurf/rules/*.md`; this keeps the generated Pluribus context version-controlled and shared with the project.
230
+ - **Sections used:** conventions, constraints + optional identity, stack, goals, workflow, anti-patterns, context
231
+
232
+ ### `continue`
233
+
234
+ - **Output:** `.continue/rules/pluribus.md`
235
+ - **Target tool:** Continue workspace rules
236
+ - **Format:** Markdown local rule with frontmatter (`name`, `alwaysApply: true`). Continue discovers project-specific rules from `.continue/rules/*.md` and includes always-apply rules in Agent, Chat, and Edit mode requests.
237
+ - **Sections used:** conventions, constraints + optional identity, stack, goals, workflow, anti-patterns, context
238
+
239
+ ### `zed`
240
+
241
+ - **Output:** `.rules`
242
+ - **Target tool:** Zed Editor
243
+ - **Format:** Markdown-style rules file for Zed AI. Focuses on conventions and constraints, with optional project identity, stack, goals, and anti-patterns when present.
244
+ - **Sections used:** conventions, constraints + optional identity, stack, goals, anti-patterns
245
+
246
+ ---
247
+
248
+ ## Writing a Custom Skill
249
+
250
+ To add support for a new AI tool:
251
+
252
+ 1. Create `pluribus/skills/<tool-name>.md` in your project.
253
+ 2. Add the three required sections: `# Output`, `# Template`, `# Sections`.
254
+ 3. Run `pluribus sync` — Pluribus will include your custom skill automatically.
255
+
256
+ **Example: a custom skill for a team-specific review bot**
257
+
258
+ ```markdown
259
+ # Meta
260
+
261
+ name: Review Bot
262
+ tool: reviewbot
263
+ description: Generates REVIEWBOT.md for a team-specific review assistant
264
+
265
+ # Output
266
+
267
+ REVIEWBOT.md
268
+
269
+ # Template
270
+
271
+ You are an expert reviewer for the following project.
272
+
273
+ **Stack:** {{stack}}
274
+
275
+ **Conventions:**
276
+ {{conventions}}
277
+
278
+ **Constraints:**
279
+ {{constraints}}
280
+
281
+ {{#if goals}}
282
+ **Goals:**
283
+ {{goals}}
284
+ {{/if}}
285
+
286
+ # Sections
287
+
288
+ required: stack, conventions, constraints
289
+ optional: goals, identity
290
+ ```
291
+
292
+ 4. Commit `pluribus/skills/reviewbot.md` to your repo. All team members get the same output on next sync.
293
+
294
+ ---
295
+
296
+ ## Skill Resolution Order
297
+
298
+ When `pluribus sync` runs, skill resolution follows this order:
299
+
300
+ 1. **Local skill file** in `pluribus/skills/<tool>.md` — if found, use it
301
+ 2. **Built-in skill** shipped with the CLI — if found, use it
302
+ 3. **Error** — skill not found; log a warning and skip
303
+
304
+ This allows overriding built-in skills without modifying the CLI.
305
+
306
+ ---
307
+
308
+ ## Validation
309
+
310
+ A valid skill file must:
311
+
312
+ - [ ] Contain `# Output` with at least one non-empty file path
313
+ - [ ] Contain `# Template` with at least one `{{variable}}` reference
314
+ - [ ] Contain `# Sections` with at least one `required:` entry
315
+ - [ ] Use only known variable names in the template (unknown variables emit a warning, not an error)
316
+
317
+ Skill-file validation is planned as a future extension to `pluribus validate`. The current `validate` command checks `pluribus.md` source/import health before sync.
318
+
319
+ ---
320
+
321
+ ## Changelog
322
+
323
+ | Version | Date | Notes |
324
+ |---|---|---|
325
+ | 0.1.0-draft | 2026-03-08 | Initial draft |