···11# Suede
2233-SvelteKit starter template. Entry point for stack, conventions, and process: `AGENTS.md`.
33+A SvelteKit starter template with an agentic development process baked in.
44+55+Suede is two layers in one repo:
66+77+1. **A runtime stack** — SvelteKit on Cloudflare Pages + Workers, D1 + Drizzle for data, Vitest + Playwright for tests, Storybook for component states, stylebase + Bits UI for the design layer.
88+2. **A process layer** — a constant concept-to-merge pipeline, a decision graph (`deciduous`), per-task notes, in-repo skills and commands, and clear boundaries between what humans author and what agents author.
99+1010+You don't build _in_ suede so much as you fork it: copy the repo, run the kickoff skill, and the new project inherits both layers with the details tailored to it.
1111+1212+[`AGENTS.md`](AGENTS.md) is the canonical rulebook — it's always in the agent's context (wired up via [`opencode.json`](opencode.json)) and is the source of truth wherever this README summarizes. When the two disagree, AGENTS.md wins.
1313+1414+## Stack
1515+1616+| Concern | Choice |
1717+| --------------- | -------------------------------------------------------------------------------- |
1818+| Framework | SvelteKit (Svelte 5) |
1919+| Hosting | Cloudflare Pages + Workers (`wrangler`) |
2020+| Database | Cloudflare D1 via Drizzle ORM |
2121+| Tests | Vitest (+ Playwright browser tests) |
2222+| Component dev | Storybook |
2323+| UI primitives | Bits UI + [@taurean/stylebase](https://www.npmjs.com/package/@taurean/stylebase) |
2424+| Package manager | pnpm |
2525+2626+Every piece is a default, not a mandate — keep/rip decisions are made per fork during kickoff (see below).
2727+2828+## Getting started
2929+3030+```bash
3131+pnpm install
3232+cp .env.example .env # fill in Cloudflare D1 credentials if using the DB
3333+pnpm dev # start the dev server
3434+```
3535+3636+Day-to-day scripts:
3737+3838+| Command | What it does |
3939+| ----------------------------------------------------------- | ----------------------------------------------------------------------------------- |
4040+| `pnpm dev` | Vite dev server |
4141+| `pnpm build` | Production build (checks wrangler types first) |
4242+| `pnpm preview` | Run the built Worker locally via wrangler |
4343+| `pnpm check` | Type-check (svelte-check + wrangler types) |
4444+| `pnpm lint` | Prettier check + ESLint |
4545+| `pnpm format` | Prettier write |
4646+| `pnpm test` | Vitest, single run |
4747+| `pnpm storybook` | Storybook dev server on port 6006 |
4848+| `pnpm db:push` / `db:generate` / `db:migrate` / `db:studio` | Drizzle workflows against D1 (each verifies `.env` first via `scripts/db-check.js`) |
4949+5050+The quality gate before any task is called done: `pnpm check`, `pnpm lint`, and `pnpm test` if tests changed — with command + result captured as evidence in the task note.
5151+5252+## Starting a new project from suede
5353+5454+Suede is a template you duplicate, not a dependency you install. The flow:
5555+5656+1. **Copy the repo.** Clone suede (or copy the working tree) to a new directory. The working tree _is_ the new project — don't work on a side copy.
5757+2. **Install and verify.** `pnpm install`, confirm `git status` is clean.
5858+3. **Run the kickoff skill.** Tell the agent something like _"start a new project from this template"_ or _"fork suede"_. That triggers [`suede-kickoff`](.opencode/skills/suede-kickoff/SKILL.md), which walks through:
5959+ - **Capture lineage** — record the suede chronver tag and commit hash _before_ anything destructive. The tag lands in the new `package.json` as `"suede": { "from": "<tag>" }`.
6060+ - **Reset history** — delete `.git`, init a fresh repo on `main`.
6161+ - **Grilling session** — a one-question-at-a-time interview in two threads. **Thread A** captures the project itself (name, purpose, primary user, project shape, first version). **Thread B** captures process-layer tailoring: which stack pieces to keep or rip (Cloudflare, D1, Storybook, SvelteKit itself, …), issue tracker (GitHub Issues is the default), version scheme (chronver vs semver), commit-type vocabulary, pipeline compression, and which global skills apply.
6262+ - **Bootstrap commit** — update `package.json` (name, version, `suede.from`), reset the `.deciduous/` graph, commit.
6363+ - **Branch the follow-up task** — `chore/suede-kickoff`, where the Thread B answers are turned into actual edits to `AGENTS.md`, `.opencode/`, configs, and this README. The kickoff skill deletes itself at the end of that task — it's consumed once.
6464+6565+The grill produces a plan; the follow-up branch produces the diff. No code is written during the interview.
6666+6767+Downstream forks can always trace their lineage: `package.json#suede.from` holds the suede tag they branched from.
6868+6969+## Working with the coding agent
7070+7171+Suede is built to be driven through a coding agent (OpenCode, Claude Code, or similar). The contract:
7272+7373+- **AGENTS.md is always loaded.** It defines the stack, the git workflow, the pipeline, and the guardrails. Agent-facing integration files live in `.opencode/` (skills, commands, plugins).
7474+- **Authoring boundaries.** Humans own the presentation layer: Svelte component markup, `<style>` blocks, `src/lib/styles/`, design tokens. Agents own the TypeScript: `<script lang="ts">` blocks, `*.ts` in `src/lib/` and `src/routes/`, Drizzle schemas, server routes, Workers. An agent never edits markup or scoped CSS.
7575+- **Storybook discipline.** A change to a UI primitive in `src/lib/components/` is incomplete without a story update in the same commit — stories are the agent-owned record of the human-owned visual contract.
7676+- **The human merges.** Agents may branch, commit (with a co-author trailer crediting assistance), push branches, and apply tags — but never merge to `main` or push to it directly. Every task lands through a PR the human reviews.
7777+- **Everything is recorded.** Decisions go in the decision graph in real time; each task ends with a note in `agent-notes/`.
7878+7979+## From concept to merge
8080+8181+Every task moves through the same pipeline. The _process_ is constant across all suede forks; the _details_ (tracker, branch convention, version scheme) are tailored at kickoff. Stages compress for small tasks — a prototype might skip the PRD file and tracker labels — but the shape stays.
8282+8383+| Stage | Skill | What happens |
8484+| ----------- | ------------------------------------- | -------------------------------------------------------------------------------------------- |
8585+| 1. Concept | — | A problem exists: in conversation, an issue, or a QA bug report |
8686+| 2. Grill | `grill-me` / `grill-with-docs` | Stress-test the idea, one question at a time, until understanding is shared |
8787+| 3. PRD | `to-prd` | Synthesize the conversation into a PRD: problem, stories, decisions, scope |
8888+| 4. Issues | `to-issues` | Break the PRD into tracer-bullet vertical slices, each independently demoable |
8989+| 5. Triage | `triage` | Label and queue: `needs-triage` → `ready-for-agent` / `ready-for-human` / `wontfix` |
9090+| 6. Build | `tdd` (+ in-repo `tdd-supplementary`) | RED → GREEN per slice; one test, one implementation, repeat; public-interface behaviour only |
9191+| 7. Diagnose | `diagnose` | For hard bugs: build a feedback loop first, then bisect |
9292+| 8. Review | `review` | Two-axis PR review (Standards + Spec) in parallel sub-agents, before merge |
9393+| 9. QA | `qa` | Conversational bug filing against the running app, producing tracker issues |
9494+| 10. Release | (AGENTS.md "Releases") | chronver bump as the final commit on the branch; human merges and tags |
9595+| 11. Handoff | `handoff` | When context runs out, compact the session for the next agent |
9696+9797+Stage skills live in the global `~/.agents/skills/` plugin; suede ships only its repo-specific supplements in `.opencode/skills/`.
9898+9999+### The shape of a single task
100100+101101+1. **Start** — pull `main`, branch `<type>/<slug>` (always from `main`, never from an in-flight branch), log a goal node with the verbatim prompt. If requirements are fuzzy, grill before touching code.
102102+2. **During** — log action nodes before major edits, honour authoring boundaries, commit as `<type>(<scope>): <subject>` in present-tense imperative, link each commit to the graph.
103103+3. **End** — run the quality gate, write the task note, bump the version (`chore(release): cut <version>` as the final commit), hand back. The human reviews the PR, merges, and the merge commit gets tagged on `main`.
104104+105105+Branch types and commit types share one vocabulary — the conventional-commits 1.0.0 list (`feat`, `fix`, `chore`, `docs`, `refactor`, `test`, `build`, `ci`, `perf`, `style`), enumerated in AGENTS.md.
106106+107107+## Tools
108108+109109+### Decision graph (`deciduous`)
110110+111111+Suede tracks project decisions as a graph: `goal → options → decision → actions → outcomes`, with observations attached anywhere. Logging is real-time, not retroactive — log what you're about to do, then log how it went, and link every commit to a node. The graph records the _project's_ decisions (what the user is building and choosing), never the agent's internal process.
112112+113113+- Rules and the node-flow model: AGENTS.md "Decision Graph Workflow"
114114+- Full CLI reference and workflows: [`.opencode/commands/decision.md`](.opencode/commands/decision.md)
115115+- Session-start context recovery: [`.opencode/commands/recover.md`](.opencode/commands/recover.md)
116116+- Web viewer: [`.opencode/commands/serve-ui.md`](.opencode/commands/serve-ui.md) · multi-user sync: [`.opencode/commands/sync.md`](.opencode/commands/sync.md)
117117+- Two OpenCode plugins enforce the habit: `require-action-node` (no file edits without a recent action/goal node) and `post-commit-reminder` (link commits after the fact).
118118+119119+### Task notes (`agent-notes/`)
120120+121121+One markdown note per task, written at task end, never deleted. Filename `YYYY-MM-DD-NN-<slug>.md`; six fixed sections (Task, Decisions, Actions, Files touched, Verification, Follow-ups) from the [template](agent-notes/0000-00-00-00-task-template.md). Size scales with the task — trivial tasks get short notes, not skipped sections. `agent-notes/plans/` is a gitignored scratch space.
122122+123123+### In-repo skills (`.opencode/skills/`)
124124+125125+| Skill | Purpose |
126126+| ------------------- | -------------------------------------------------------------------------- |
127127+| `suede-kickoff` | One-shot bootstrap of a new project from a fresh suede clone (see above) |
128128+| `tdd-supplementary` | Suede-specific TDD additions: the test prune pass and Storybook discipline |
129129+| `pulse` | Map the system's _current_ state as decision nodes — no history, just now |
130130+| `narratives` | Reconstruct how the system evolved, as prose narratives |
131131+| `archaeology` | Turn those narratives into a backdated, queryable decision graph |
132132+133133+Cross-cutting process skills (grill-me, to-prd, tdd, review, qa, …) live in the global `~/.agents/skills/` plugin, not in the repo.
134134+135135+### Commands (`.opencode/commands/`)
136136+137137+`/build-test` (typecheck + test gate), `/decision` (graph management), `/decision-graph` (build a graph from commit history), `/recover` (session-start context recovery), `/serve-ui`, `/sync`.
138138+139139+## Git workflow and releases
140140+141141+- Branch from `main`, always. Every task is reviewed in a PR; the human is the only one who merges.
142142+- The human is commit author; agent-made commits carry a co-author trailer.
143143+- **chronver** by default (`YYYY.M.D[.N]`, no leading zeros): every release branch ships its own version bump as its final commit, the merge commit on `main` is tagged with the bare version string and pushed with `--follow-tags`, and `git log <prev>..<new>` is the changelog — no `CHANGELOG.md`. Libraries with dependents switch to semver at kickoff.
144144+- Default tracker is GitHub Issues; forks can override at kickoff.
145145+146146+Full details: AGENTS.md "Git workflow", "Task flow", and "Releases".