Ken Yasue 2a803a80b9 Add E2E Testing (Playwright) section to README
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 12:29:07 +02:00

opencode Spec-Driven Development Boilerplate

A spec-driven development boilerplate for opencode, converted from the Claude Code 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 → /generate-app → /plan-milestones → /execute-milestones (phase by phase)

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

Creates the design specification under docs/design/: design brief, design tokens, ui-blueprint.json (the source of truth for UI generation), 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 <change> — 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 — Generate the initial app: /generate-app web | flutter | winui3

Scaffolds the app shell from the approved design: theme (from tokens), routes, screens, and reusable components. No feature logic yet.

Step 6 — 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. Phase 1 delivers the MVP; later phases build on it by priority and dependency.

Step 7 — Implement the milestones

Two ways to work through the plan:

Option A — execute a phase file: /execute-milestones <phase-file> 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 <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 8 — Repeat and maintain

  • Remaining phases → /execute-milestones <next phase file>, or feature by feature with /add-feature <feature>
  • UI changes → /update-design <change> first, then /add-feature
  • Re-planning → re-run /plan-milestones or edit docs/milestones/ in conversation
  • Document quality checks → /review-docs <path>

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


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:
    curl -fsSL https://opencode.ai/install | bash
    
    See https://opencode.ai/docs for alternatives (npm, Homebrew, etc.)
  • Docker (only if using the Dev Container)

Quick Start

  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:
    opencode
    

Option B — Manual setup

# 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)
│   │   ├── 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
    │   ├── generate-app.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:

{
  "$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

Creates the design specification under docs/design/ (design brief, design tokens, UI blueprint, 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 <change> 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. Generate the app

> /generate-app web
> /generate-app flutter
> /generate-app winui3

Scaffolds the initial application for the selected target from the design spec — app shell, theme (from tokens), routes, screens, and reusable components. No feature logic is implemented here.

4. 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. Phase 1 delivers the MVP. You'll be asked once about phase count, MVP scope, priorities, and constraints; sensible defaults are proposed from the PRD.

5. 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

6. 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.

7. 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.

8. 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 <change> for targeted refinements
  4. Run /generate-app web, /generate-app flutter, or /generate-app winui3
  5. Run /plan-milestones to break the product into phases and milestones (one phaseN-milestones.md per phase)
  6. Use /execute-milestones phase1-milestones.md to implement a phase's milestones one by one, or /add-feature to go feature by feature
  7. 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 /generate-app is executed.

See 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, /execute-milestones, and /generate-app — is:

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: /generate-app 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
/generate-app Scaffold the initial app for a target platform /generate-app web
/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 /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 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:

---
description: ...
mode: subagent
model: anthropic/claude-sonnet-4-6
---

Or set a global default in opencode.json:

{
  "model": "anthropic/claude-sonnet-4-6"
}

Model IDs use the provider/model-id format. See https://opencode.ai/config.json for the full schema.

Adjust permissions

Edit the permission block in opencode.json. For example, to allow all bash commands:

{
  "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:

# 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:

export PATH="$HOME/.opencode/bin:$PATH"
opencode

Or create a permanent symlink:

sudo ln -sf "$HOME/.opencode/bin/opencode" /usr/local/bin/opencode

License

MIT — see LICENSE.

Description
No description provided
Readme MIT 363 KiB
Languages
TypeScript 82.3%
JavaScript 17.7%