# opencode Spec-Driven Development Boilerplate A spec-driven development boilerplate for [opencode](https://opencode.ai), converted from the [Claude Code boilerplate](https://git.yasue.org/ken/claudecode-boilerplate) that accompanies the book *"Practical Claude Code Introduction."* It gives opencode a structured workflow for turning ideas into production code through persistent design documents, per-task steering files, AI skills, subagents, and slash commands. --- ## Development Workflow (Step by Step) How a project goes from idea to working code with this boilerplate: ``` Idea → /setup-project → /define-design → refine design → /plan-milestones → /execute-milestones (phase by phase; milestone 01 generates the app) ``` ### Step 1 — Write down your idea Put your brainstorming notes, requirements, and constraints into `docs/ideas/initial-requirements.md` (free-form; replace the sample content with your own). ### Step 2 — Create the specification: `/setup-project` Automatically creates the six persistent documents that define **what to build**: PRD, functional design, architecture, repository structure, development guidelines, and glossary (all under `docs/`). Review them and request edits in normal conversation if needed. ### Step 3 — Define the UI/UX design: `/define-design` First builds an **exhaustive screen inventory** (`screen-inventory.md`) from the PRD and functional design — every user story walked end-to-end, plus list/detail/create/edit/delete coverage for every entity — so no screen gets skipped. Then creates the design specification under `docs/design/`: design brief, design tokens, **`ui-blueprint.json` (the source of truth for UI generation, one entry per inventory screen)**, platform mapping, and SVG wireframes (visual references only). You'll be asked once about platform, style, screens, navigation, branding, and accessibility. ### Step 4 — Review and refine the design **before writing any code** This is the key design-decision gate: iterate on the design while it is still cheap to change. - `/update-design ` — targeted refinements (e.g. `add a profile screen`) - Re-run `/define-design` — change the overall direction - Repeat until you approve the design (especially `ui-blueprint.json`) ### Step 5 — Plan milestones: `/plan-milestones` Breaks the product into **phases** and milestones, and generates `docs/milestones/`: a `roadmap.md` overview plus **one file per phase** (`phase1-milestones.md`, `phase2-milestones.md`, …). Each phase file lists its milestones and **the features they contain** — each feature sized for exactly one `/add-feature` run, with acceptance criteria and a ready-to-run command. **Milestone 01 is always "App Shell Generation"**: it scaffolds the initial app from the approved design (theme from tokens, one screen per blueprint entry, routes, reusable components — no feature logic) plus the Playwright smoke spec; there is no separate generate-app step. Phase 1 delivers the MVP; later phases build on it by priority and dependency. ### Step 6 — Implement the milestones Two ways to work through the plan: **Option A — execute a phase file: `/execute-milestones `** Requires the phase file to execute, e.g. `/execute-milestones phase1-milestones.md`. Runs that phase's milestones **one by one, autonomously**. For each milestone it creates a **separate steering directory** (`.steering/[date]-milestone-[NN]-[name]/`), divides the milestone's features into concrete tasks grouped by feature, implements them all, validates, tests, reconciles the docs, and marks the milestone completed — then immediately starts the next milestone in the file. When the phase completes, run it again with the next phase file. **Option B — one feature at a time: `/add-feature `** A fully autonomous loop, one feature per run. Each run: 1. Creates `.steering/[YYYYMMDD]-[feature]/` (requirements, design, tasklist) 2. Reads the feature's entry in its phase file and the design spec first — and updates the design first if the feature changes the UI 3. Implements every task in `tasklist.md`, checking items off as it goes 4. Validates quality with the `implementation-validator` subagent 5. Writes Playwright E2E tests for the feature's acceptance criteria, then runs `npm test`, `npm run lint`, `npm run typecheck`, and `npm run test:e2e` until green 6. Records a retrospective, reconciles all six `docs/` documents, and checks the feature off in its phase file ### Step 7 — Repeat and maintain - Remaining phases → `/execute-milestones `, or feature by feature with `/add-feature ` - UI changes → `/update-design ` first, then `/add-feature` - Re-planning → re-run `/plan-milestones` or edit `docs/milestones/` in conversation - Document quality checks → `/review-docs ` **A feature is "done" when**: all tasks in its tasklist are `[x]`, validation passes, test/lint/typecheck and the Playwright E2E suite succeed, and the persistent documents are back in sync with the code. --- ## Table of Contents - [Development Workflow (Step by Step)](#development-workflow-step-by-step) - [What Is Spec-Driven Development?](#what-is-spec-driven-development) - [Conversion Summary (Claude Code → opencode)](#conversion-summary-claude-code--opencode) - [Prerequisites](#prerequisites) - [Quick Start](#quick-start) - [Directory Structure](#directory-structure) - [Configuration Overview](#configuration-overview) - [Usage Workflow](#usage-workflow) - [Design & App Generation](#design--app-generation) - [E2E Testing (Playwright)](#e2e-testing-playwright) - [Commands Reference](#commands-reference) - [Skills Reference](#skills-reference) - [Agents Reference](#agents-reference) - [Customizing the Boilerplate](#customizing-the-boilerplate) - [Troubleshooting](#troubleshooting) - [License](#license) --- ## What Is Spec-Driven Development? Spec-driven development separates **"what to build"** from **"how to build it"**: 1. **Persistent documents** (`docs/`) — the north-star design (PRD, functional design, architecture, etc.) 2. **Steering files** (`.steering/`) — per-task plans created fresh for each piece of work 3. **Implementation** — the agent follows `tasklist.md`, updating progress as it goes 4. **Verification** — tests, lint, typecheck, and a retrospective opencode loads the right skill automatically based on what you're doing, so you don't have to think about the process — just describe what you want. --- ## Conversion Summary (Claude Code → opencode) | Claude Code | opencode | Notes | |---|---|---| | `CLAUDE.md` | `AGENTS.md` | Referenced via `instructions` in `opencode.json` | | `.claude/settings.json` | `opencode.json` | Permissions converted to opencode's `permission` schema | | `.claude/agents/*.md` | `.opencode/agent/*.md` | Added `mode: subagent`; `model: sonnet` removed (inherits default) | | `.claude/commands/*.md` | `.opencode/command/*.md` | Tool-call syntax (`Bash()`, `Grep()`, `Skill()`) converted to natural instructions; `$ARGUMENTS` added | | `.claude/skills/*/SKILL.md` | `.opencode/skills/*/SKILL.md` | `allowed-tools` frontmatter removed (not an opencode field) | | `Skill('steering')` calls | Auto-loaded by description | opencode surfaces skills via `description` matching | | `TodoWrite` / `Edit` tool refs | `todowrite` / `edit` | Lowercased to match opencode tool names | | Claude Code devcontainer feature | `curl … opencode.ai/install` | Replaced Anthropic feature with opencode install script | All skill templates and guides were preserved verbatim except for `.claude/` path references and "Claude Code" mentions, which were updated to `.opencode/` and "opencode" respectively. --- ## Prerequisites - **Node.js** v18+ (v24.11.0 recommended) - **npm** - **opencode** — install with: ```bash curl -fsSL https://opencode.ai/install | bash ``` See for alternatives (npm, Homebrew, etc.) - **Docker** (only if using the Dev Container) --- ## Quick Start ### Option A — Dev Container (recommended) 1. Open this folder in **VS Code**. 2. When prompted, click **"Reopen in Container"** (or run the command *Dev Containers: Reopen in Container*). 3. The container automatically: - Installs Node.js LTS - Runs `npm install` - Installs opencode 4. Open a terminal and start opencode: ```bash opencode ``` ### Option B — Manual setup ```bash # 1. Install dependencies npm install # 2. Set up Git hooks npm run prepare # 3. Start opencode opencode ``` --- ## Directory Structure ``` . ├── opencode.json # opencode config (permissions, instructions) ├── AGENTS.md # Project instructions (loaded into every session) ├── package.json # Node.js project + scripts ├── tsconfig.json # TypeScript config ├── eslint.config.js # ESLint flat config ├── vitest.config.ts # Vitest config (80% coverage threshold) ├── .prettierrc / .prettierignore ├── .gitignore ├── .husky/pre-commit # Runs lint-staged + typecheck before commit ├── .devcontainer/devcontainer.json ├── prompt.md # Example MVP prompt │ ├── src/ # Source code │ ├── example.ts │ └── example.test.ts │ ├── docs/ # Persistent design documents │ ├── ideas/ │ │ └── initial-requirements.md # Brainstorming notes (pre-PRD) │ ├── design/ # UI/UX design spec (created by /define-design) │ │ ├── screen-inventory.md # exhaustive screen checklist (from the PRD) │ │ ├── design-brief.md │ │ ├── design-tokens.json │ │ ├── ui-blueprint.json # source of truth for UI │ │ ├── platform-mapping.md │ │ └── screens/*.svg # visual references only │ └── milestones/ # Milestone plan (created by /plan-milestones) │ ├── roadmap.md # overview + status │ └── phaseN-milestones.md # one per phase: milestones + features │ ├── .steering/ # Per-task steering files (created by /add-feature) │ └── .gitkeep │ └── .opencode/ # opencode configuration ├── agent/ # Subagent definitions │ ├── doc-reviewer.md │ └── implementation-validator.md ├── command/ # Slash commands │ ├── setup-project.md │ ├── define-design.md │ ├── update-design.md │ ├── plan-milestones.md │ ├── execute-milestones.md │ ├── add-feature.md │ └── review-docs.md └── skills/ # Task-specific skills ├── prd-writing/ (SKILL.md + template.md) ├── functional-design/ (SKILL.md + template.md + guide.md) ├── architecture-design/ (SKILL.md + template.md + guide.md) ├── repository-structure/ (SKILL.md + template.md + guide.md) ├── development-guidelines/(SKILL.md + template.md + guides/) ├── glossary-creation/ (SKILL.md + template.md + guide.md) ├── ui-design/ (SKILL.md) ├── design-tokens/ (SKILL.md) ├── platform-ui-generation/(SKILL.md) ├── milestone-planning/ (SKILL.md + template.md) ├── milestone-execution/ (SKILL.md) ├── e2e-testing/ (SKILL.md) └── steering/ (SKILL.md + templates/) ``` --- ## Configuration Overview ### `opencode.json` The main configuration file. Key sections: ```jsonc { "$schema": "https://opencode.ai/config.json", "instructions": ["AGENTS.md"], // Loaded into every session "permission": { "skill": "allow", // Skills are auto-available "bash": { // Common dev commands pre-approved "*": "ask", "npm *": "allow", "npx *": "allow", "git *": "allow", // ... } } } ``` > **After editing `opencode.json`, quit and restart opencode** — config is loaded once at startup. ### `AGENTS.md` The project memory file. opencode reads it on every session. It defines: - The technology stack - The spec-driven development principles - The directory structure - The development process and workflow ### Agents (`.opencode/agent/`) Subagents run in isolated contexts via the `task` tool. They don't consume the main session's context. ### Commands (`.opencode/command/`) Slash commands invoked in the opencode TUI with `/command-name`. Each command is a prompt template that opencode executes. ### Skills (`.opencode/skills/`) Skills are loaded automatically based on their `description` field. You don't invoke them by name — opencode surfaces the right skill when the task matches. --- ## Usage Workflow ### 1. Initial project setup Run the setup command to automatically create all six persistent design documents: ``` > /setup-project ``` This creates (automatically, end-to-end): 1. `docs/product-requirements.md` (PRD) 2. `docs/functional-design.md` 3. `docs/architecture.md` 4. `docs/repository-structure.md` 5. `docs/development-guidelines.md` 6. `docs/glossary.md` The PRD is based on the brainstorming notes in `docs/ideas/initial-requirements.md`. Edit that file first if you have your own idea, or replace it. ### 2. Define the UI/UX design ``` > /define-design ``` First builds an exhaustive screen inventory (`screen-inventory.md`) from the PRD and functional design — every user story walked end-to-end, with list/detail/create/edit/delete coverage per entity — then creates the design specification under `docs/design/` (design brief, design tokens, UI blueprint with one entry per inventory screen, platform mapping, and SVG wireframes). You'll be asked about target platform, visual style, main screens, navigation, branding, and accessibility; if you don't specify, sensible defaults are proposed. Review and refine the UI/UX **before** generating the app — it is far easier to iterate on the design than on generated code: - Re-run `/define-design` to change the overall direction. - Run `/update-design ` for targeted refinements (e.g. `/update-design make the home screen denser`). - Iterate until the design — especially `docs/design/ui-blueprint.json` — is approved. **The design source of truth is `docs/design/ui-blueprint.json`.** SVG files are visual references only. ### 3. Plan milestones ``` > /plan-milestones > /plan-milestones 2 phases, MVP first ``` Breaks the product into phases and milestones and generates `docs/milestones/`: a `roadmap.md` overview plus one file per phase (`phase1-milestones.md`, `phase2-milestones.md`, …) listing its milestones and their features — each feature sized for one `/add-feature` run, with acceptance criteria and a ready-to-run command. **Milestone 01 is always "App Shell Generation"**: executed like any other milestone, it scaffolds the initial app from the design spec (theme from tokens, one screen per blueprint entry, routes, reusable components — no feature logic) plus the Playwright smoke spec. Phase 1 delivers the MVP. You'll be asked once about target platform, phase count, MVP scope, priorities, and constraints; sensible defaults are proposed from the PRD. ### 4. Add a feature ``` > /add-feature User authentication ``` This fully autonomous workflow: 1. Creates `.steering/[YYYYMMDD]-[feature-name]/` with `requirements.md`, `design.md`, `tasklist.md` 2. Reads the feature's milestone document (`docs/milestones/`) for scope and acceptance criteria 3. Reads the design spec (`docs/design/`) and updates it first if the feature changes the UI 4. Generates the steering files (planning mode of the steering skill) 5. Implements every task in `tasklist.md`, marking each `[ ]` → `[x]` as it goes 6. Launches the `implementation-validator` subagent for quality review 7. Writes Playwright E2E tests for the acceptance criteria, then runs `npm test`, `npm run lint`, `npm run typecheck`, `npm run test:e2e` 8. Records a retrospective, reconciles all six persistent docs with the feature, and checks the feature off in its phase file ### 5. Execute a phase file (alternative to per-feature runs) ``` > /execute-milestones phase1-milestones.md > /execute-milestones docs/milestones/phase2-milestones.md > /execute-milestones 1 # shorthand for phase1-milestones.md ``` **The phase file argument is required** — without it the command lists the available phase files and stops. It then works through that phase's milestones autonomously, one at a time. For each milestone it creates a **separate steering directory** (`.steering/[date]-milestone-[NN]-[name]/`), divides the milestone's features into tasks grouped by feature, implements everything, validates, runs the test suite, reconciles the docs, marks the milestone `Completed` — and immediately starts the next one. When the last milestone finishes, the phase is marked `Completed` in the roadmap. It only stops early on a genuine external blocker, which it records in the roadmap. ### 6. Review a document ``` > /review-docs docs/product-requirements.md ``` Launches the `doc-reviewer` subagent to evaluate the document from five perspectives: completeness, clarity, consistency, implementability, and measurability. ### 7. Day-to-day editing You don't always need a command — just ask in normal conversation: ``` > Add a new feature to the PRD > Review the performance requirements in architecture.md > Add a new domain term to glossary.md ``` opencode loads the appropriate skill automatically. --- ## Design & App Generation Recommended workflow: 1. Run `/setup-project` 2. Run `/define-design` 3. Review `docs/design/` and refine the UI/UX until approved: - Re-run `/define-design` to change direction, or - Run `/update-design ` for targeted refinements 4. Run `/plan-milestones` to break the product into phases and milestones (one `phaseN-milestones.md` per phase; milestone 01 = App Shell Generation for the chosen platform) 5. Use `/execute-milestones phase1-milestones.md` to implement a phase's milestones one by one (milestone 01 generates the initial app), or `/add-feature` to go feature by feature 6. Use `/update-design` whenever a feature changes the UI Source of truth: - The design source of truth is `docs/design/ui-blueprint.json`. - SVG files (`docs/design/screens/*.svg`) are only visual references. - Generated UI should follow `docs/design/design-tokens.json` — no hard-coded values. - No platform-specific implementation is generated before the App Shell milestone (milestone 01) is executed. See [`docs/design/README.md`](docs/design/README.md) for the full structure. --- ## E2E Testing (Playwright) Every verification step in this boilerplate includes end-to-end tests. The standard verification sequence — used by `/add-feature` and `/execute-milestones` — is: ```bash npm test # unit tests npm run lint npm run typecheck npm run test:e2e # Playwright E2E ``` How it works (defined in the `e2e-testing` skill): - **Setup is automatic**: on the first verification, if Playwright is missing, the agent installs `@playwright/test`, creates `playwright.config.ts` (dev-server integration, trace/screenshot on failure), and adds the `test:e2e` script. - **Tests are derived from acceptance criteria**: each feature gets `e2e/[feature].spec.ts` with one test per acceptance criterion, written before verification runs. - **The app shell has a smoke spec**: the App Shell milestone (milestone 01) creates `e2e/app-shell.spec.ts`, which checks that the shell renders and every route in `ui-blueprint.json` navigates. - **Blueprint-driven locators**: tests navigate by the blueprint's routes and use semantic locators (`getByRole`, `getByLabel`) — no CSS/XPath tied to implementation details, no fixed waits. - **No green-washing**: a failing E2E test is fixed, never skipped or deleted; milestone gates in `/execute-milestones` do not pass without a green E2E suite. ``` e2e/ ├── app-shell.spec.ts # smoke: shell renders, all blueprint routes navigate ├── [feature-name].spec.ts # one spec per feature (acceptance criteria) └── helpers/ # shared fixtures (only when duplicated 3+ times) ``` Playwright covers the `web` target; for `flutter` the equivalent is `integration_test`, and for `winui3` the platform's UI automation — with the same acceptance-criteria mapping. --- ## Commands Reference | Command | Description | Example | |---|---|---| | `/setup-project` | Create the six persistent documents automatically | `/setup-project` | | `/define-design` | Create the UI/UX design spec under `docs/design/` | `/define-design` | | `/update-design` | Update the design spec when a feature changes the UI | `/update-design add a profile screen` | | `/plan-milestones` | Plan phases and milestones; generates one `phase[N]-milestones.md` per phase (milestone 01 = App Shell Generation) | `/plan-milestones 2 phases, MVP first` | | `/execute-milestones` | Execute one phase file: its milestones one by one, with separate steering documents per milestone (file argument required) | `/execute-milestones phase1-milestones.md` | | `/add-feature` | Implement a feature end-to-end (autonomous) | `/add-feature User profile editing` | | `/review-docs` | Detailed document review via subagent | `/review-docs docs/architecture.md` | --- ## Skills Reference | Skill | When it loads | Output | |---|---|---| | `prd-writing` | Creating a Product Requirements Document | `docs/product-requirements.md` | | `functional-design` | Creating a functional design document | `docs/functional-design.md` | | `architecture-design` | Designing the system architecture | `docs/architecture.md` | | `repository-structure` | Defining the directory layout | `docs/repository-structure.md` | | `development-guidelines` | Creating coding conventions / implementing code | `docs/development-guidelines.md` | | `glossary-creation` | Creating a project glossary | `docs/glossary.md` | | `ui-design` | Creating the screen inventory, design brief, UI blueprint, and SVG wireframes | `docs/design/` files | | `design-tokens` | Creating and maintaining design tokens | `docs/design/design-tokens.json` | | `platform-ui-generation` | Converting design files into Web/Flutter/WinUI 3 code | generated app code | | `milestone-planning` | Planning phases/milestones and the feature breakdown per milestone | `docs/milestones/` phase files | | `milestone-execution` | Executing a phase file's milestones one by one with per-milestone steering docs | `.steering/[date]-milestone-NN-[name]/` files | | `e2e-testing` | Writing and running Playwright E2E tests as part of every verification step | `e2e/*.spec.ts` + `npm run test:e2e` | | `steering` | Planning, implementing, and retrospecting on a task | `.steering/[date]-[name]/` files | Each skill folder contains a `SKILL.md` (instructions) plus `template.md` and/or `guide.md` (reference material the skill points to). --- ## Agents Reference | Agent | Mode | Purpose | |---|---|---| | `doc-reviewer` | subagent | Reviews document quality across 5 dimensions; outputs a scored report with prioritized improvements | | `implementation-validator` | subagent | Validates code against the spec; checks quality, test coverage, security, performance; runs lint/test/typecheck | Agents are launched via the `task` tool (e.g., by the `/add-feature` and `/review-docs` commands). They run in an isolated context window. --- ## Customizing the Boilerplate ### Change the model Agents inherit the default model from `opencode.json`. To pin a specific model for a subagent, add `model` to its frontmatter: ```yaml --- description: ... mode: subagent model: anthropic/claude-sonnet-4-6 --- ``` Or set a global default in `opencode.json`: ```jsonc { "model": "anthropic/claude-sonnet-4-6" } ``` > Model IDs use the `provider/model-id` format. See for the full schema. ### Adjust permissions Edit the `permission` block in `opencode.json`. For example, to allow all bash commands: ```jsonc { "permission": { "bash": "allow" } } ``` ### Add a new skill 1. Create `.opencode/skills/my-skill/SKILL.md` 2. Add frontmatter with `name` and `description` (the description controls when opencode loads it) 3. Add any companion `template.md` or `guide.md` files 4. Restart opencode ### Add a new command 1. Create `.opencode/command/my-command.md` 2. Add `description` frontmatter + a prompt body (use `$ARGUMENTS` for user input) 3. Restart opencode ### Add a new agent 1. Create `.opencode/agent/my-agent.md` 2. Add `description` and `mode: subagent` frontmatter + a prompt body 3. Restart opencode --- ## Troubleshooting ### opencode won't start after editing config opencode validates `opencode.json` strictly and refuses to start on invalid fields. To recover: ```bash # Skip the project config and start from globals only OPENCODE_DISABLE_PROJECT_CONFIG=1 opencode ``` Then fix the broken file and restart normally. ### Skills not loading - Ensure each `SKILL.md` has a `description` in its frontmatter — skills without one are filtered out. - Ensure the folder name matches the `name` field. - Restart opencode after adding or changing skills. ### Commands not appearing - Command files must be directly inside `.opencode/command/` (not in subdirectories). - Restart opencode after adding commands. ### Dev Container: `opencode` command not found The install script adds opencode to `~/.opencode/bin/` and updates your shell profile. If the command isn't found in a new terminal: ```bash export PATH="$HOME/.opencode/bin:$PATH" opencode ``` Or create a permanent symlink: ```bash sudo ln -sf "$HOME/.opencode/bin/opencode" /usr/local/bin/opencode ``` --- ## License MIT — see [LICENSE](LICENSE).