diff --git a/docs/cli.md b/docs/cli.md index 7c260c0ea..b624c8667 100644 --- a/docs/cli.md +++ b/docs/cli.md @@ -745,7 +745,7 @@ spec-driven resolves from: package **Schema precedence:** 1. Project: `openspec/schemas//` -2. User: `~/.openspec/schemas//` +2. User: `~/.local/share/openspec/schemas//` 3. Package: Built-in schemas --- diff --git a/docs/customization.md b/docs/customization.md index cd64bb7fb..a99dbb424 100644 --- a/docs/customization.md +++ b/docs/customization.md @@ -1,29 +1,30 @@ # Customization -OpenSpec provides two levels of customization: +OpenSpec provides three levels of customization: -1. **Project Config** (`openspec/config.yaml`) - Lightweight per-project customization for default schemas, shared context, and per-artifact rules -2. **Schema Overrides** - Full schema and template customization via XDG directories +| Level | What it does | Best for | +|-------|--------------|----------| +| **Project Config** | Set defaults, inject context/rules | Most teams | +| **Custom Schemas** | Define your own workflow artifacts | Teams with unique processes | +| **Global Overrides** | Share schemas across all projects | Power users | --- ## Project Configuration -The `openspec/config.yaml` file provides a lightweight customization layer that lets teams: +The `openspec/config.yaml` file is the easiest way to customize OpenSpec for your team. It lets you: -- **Set a default schema** - New changes automatically use this schema instead of specifying `--schema` every time -- **Inject project context** - Shared context (tech stack, conventions) shown to AI when creating any artifact -- **Add per-artifact rules** - Custom rules that only apply to specific artifacts (e.g., proposal, specs) +- **Set a default schema** - Skip `--schema` on every command +- **Inject project context** - AI sees your tech stack, conventions, etc. +- **Add per-artifact rules** - Custom rules for specific artifacts -### Creating a Config - -You can create the config through the interactive setup: +### Quick Setup ```bash openspec init ``` -Or create it manually: +This walks you through creating a config interactively. Or create one manually: ```yaml # openspec/config.yaml @@ -44,26 +45,25 @@ rules: - Reference existing patterns before inventing new ones ``` -### How Config Affects Workflows +### How It Works -**Default schema selection:** +**Default schema:** ```bash -# Without config: must specify schema +# Without config openspec new change my-feature --schema spec-driven -# With config: schema is automatic +# With config - schema is automatic openspec new change my-feature ``` **Context and rules injection:** -When generating instructions for an artifact, context and rules are injected: +When generating any artifact, your context and rules are injected into the AI prompt: ```xml Tech stack: TypeScript, React, Node.js, PostgreSQL -API style: RESTful, documented in docs/api.md ... @@ -80,105 +80,261 @@ API style: RESTful, documented in docs/api.md - **Context** appears in ALL artifacts - **Rules** ONLY appear for the matching artifact -### Schema Resolution Precedence +### Schema Resolution Order + +When OpenSpec needs a schema, it checks in this order: -1. CLI flag wins: `openspec new change feature --schema tdd` -2. Change metadata (if `.openspec.yaml` specifies schema) +1. CLI flag: `--schema tdd` +2. Change metadata (`.openspec.yaml` in the change folder) 3. Project config (`openspec/config.yaml`) -4. Default schema (`spec-driven`) +4. Default (`spec-driven`) + +--- + +## Custom Schemas + +When project config isn't enough, create your own schema with a completely custom workflow. Custom schemas live in your project's `openspec/schemas/` directory and are version-controlled with your code. + +```text +your-project/ +├── openspec/ +│ ├── config.yaml # Project config +│ ├── schemas/ # Custom schemas live here +│ │ └── my-workflow/ +│ │ ├── schema.yaml +│ │ └── templates/ +│ └── changes/ # Your changes +└── src/ +``` -### Error Handling +### Fork an Existing Schema -The config provides graceful error handling: +The fastest way to customize is to fork a built-in schema: ```bash -# Typo in schema name - shows suggestions -# Schema 'spec-drivne' not found -# Did you mean: spec-driven (built-in) +openspec schema fork spec-driven my-workflow +``` + +This copies the entire `spec-driven` schema to `openspec/schemas/my-workflow/` where you can edit it freely. -# Unknown artifact ID in rules - warns but continues -# ⚠️ Unknown artifact ID in rules: "testplan". Valid IDs for schema "spec-driven": ... +**What you get:** + +```text +openspec/schemas/my-workflow/ +├── schema.yaml # Workflow definition +└── templates/ + ├── proposal.md # Template for proposal artifact + ├── spec.md # Template for specs + ├── design.md # Template for design + └── tasks.md # Template for tasks ``` ---- +Now edit `schema.yaml` to change the workflow, or edit templates to change what AI generates. + +### Create a Schema from Scratch + +For a completely fresh workflow: + +```bash +# Interactive +openspec schema init research-first + +# Non-interactive +openspec schema init tdd-lite \ + --description "Lightweight TDD workflow" \ + --artifacts "spec,tests,impl" \ + --default +``` + +### Schema Structure + +A schema defines the artifacts in your workflow and how they depend on each other: + +```yaml +# openspec/schemas/my-workflow/schema.yaml +name: my-workflow +version: 1 +description: My team's custom workflow + +artifacts: + - id: proposal + generates: proposal.md + description: Initial proposal document + template: proposal.md + instruction: | + Create a proposal that explains WHY this change is needed. + Focus on the problem, not the solution. + requires: [] -## Schema Overrides + - id: design + generates: design.md + description: Technical design + template: design.md + instruction: | + Create a design document explaining HOW to implement. + requires: + - proposal # Can't create design until proposal exists + + - id: tasks + generates: tasks.md + description: Implementation checklist + template: tasks.md + requires: + - design + +apply: + requires: [tasks] + tracks: tasks.md +``` + +**Key fields:** -For deeper customization, you can override entire schemas or templates. +| Field | Purpose | +|-------|---------| +| `id` | Unique identifier, used in commands and rules | +| `generates` | Output filename (supports globs like `specs/**/*.md`) | +| `template` | Template file in `templates/` directory | +| `instruction` | AI instructions for creating this artifact | +| `requires` | Dependencies - which artifacts must exist first | -### How Schema Resolution Works +### Templates -OpenSpec uses a 2-level schema resolution system following the XDG Base Directory Specification: +Templates are markdown files that guide the AI. They're injected into the prompt when creating that artifact. -1. **User override**: `${XDG_DATA_HOME}/openspec/schemas//` -2. **Package built-in**: `/schemas//` +```markdown + +## Why -When a schema is requested, the resolver checks the user directory first. If found, that entire schema directory is used. Otherwise, it falls back to the package's built-in schema. + -### Override Directories +## What Changes -| Platform | Path | -|----------|------| -| macOS/Linux | `~/.local/share/openspec/schemas/` | -| Windows | `%LOCALAPPDATA%\openspec\schemas\` | -| All (if set) | `$XDG_DATA_HOME/openspec/schemas/` | + -### Manual Schema Override +## Impact + + +``` -To override the default `spec-driven` schema: +Templates can include: +- Section headers the AI should fill in +- HTML comments with guidance for the AI +- Example formats showing expected structure -**1. Create the directory structure:** +### Validate Your Schema + +Before using a custom schema, validate it: + +```bash +openspec schema validate my-workflow +``` + +This checks: +- `schema.yaml` syntax is correct +- All referenced templates exist +- No circular dependencies +- Artifact IDs are valid + +### Use Your Custom Schema + +Once created, use your schema with: ```bash -# macOS/Linux -mkdir -p ~/.local/share/openspec/schemas/spec-driven/templates +# Specify on command +openspec new change feature --schema my-workflow + +# Or set as default in config.yaml +schema: my-workflow ``` -**2. Find and copy the default schema files:** +### Debug Schema Resolution + +Not sure which schema is being used? Check with: ```bash -# Find the package location -npm list -g openspec --parseable +# See where a specific schema resolves from +openspec schema which my-workflow + +# List all available schemas +openspec schema which --all +``` + +Output shows whether it's from your project, user directory, or the package: -# Copy files from the package's schemas/ directory -cp /schemas/spec-driven/schema.yaml ~/.local/share/openspec/schemas/spec-driven/ -cp /schemas/spec-driven/templates/*.md ~/.local/share/openspec/schemas/spec-driven/templates/ +```text +Schema: my-workflow +Source: project +Path: /path/to/project/openspec/schemas/my-workflow ``` -**3. Modify the copied files:** +--- + +> **Note:** OpenSpec also supports user-level schemas at `~/.local/share/openspec/schemas/` for sharing across projects, but project-level schemas in `openspec/schemas/` are recommended since they're version-controlled with your code. + +--- -Edit `schema.yaml` to change the workflow structure: +## Examples + +### Minimal TDD Workflow ```yaml -name: spec-driven +# openspec/schemas/tdd-minimal/schema.yaml +name: tdd-minimal version: 1 -description: My custom workflow +description: Write tests first, then implement + artifacts: - - id: proposal - generates: proposal.md - description: Initial proposal - template: proposal.md + - id: tests + generates: tests.md + description: Test cases to implement + template: tests.md + instruction: | + Define test cases for this feature. + Each test should be a clear Given/When/Then scenario. requires: [] - # Add, remove, or modify artifacts... + + - id: impl + generates: implementation.md + description: Implementation notes + template: impl.md + requires: [tests] + +apply: + requires: [impl] + tracks: implementation.md ``` -Edit templates in `templates/` to customize the content guidance. +### Adding a Review Artifact -### Current Limitations +Fork the default and add a review step: -| Issue | Impact | -|-------|--------| -| **Path discovery** | Users must know XDG conventions and platform-specific paths | -| **Package location** | Finding the npm package path varies by install method | -| **No scaffolding** | Users must manually create directories and copy files | -| **No verification** | No way to confirm which schema is actually being resolved | -| **Full copy required** | Must copy entire schema even to change one template | +```bash +openspec schema fork spec-driven with-review +``` + +Then edit `schema.yaml` to add: + +```yaml + - id: review + generates: review.md + description: Pre-implementation review checklist + template: review.md + instruction: | + Create a review checklist based on the design. + Include security, performance, and testing considerations. + requires: + - design + + - id: tasks + # ... existing tasks config ... + requires: + - specs + - design + - review # Now tasks require review too +``` + +--- -### Related Files +## See Also -| File | Purpose | -|------|---------| -| `src/core/artifact-graph/resolver.ts` | Schema resolution logic | -| `src/core/artifact-graph/instruction-loader.ts` | Template loading | -| `src/core/global-config.ts` | XDG path helpers | -| `schemas/spec-driven/` | Default schema and templates | +- [CLI Reference: Schema Commands](cli.md#schema-commands) - Full command documentation