a template starter repo for sveltekit projects
0

Configure Feed

Select the types of activity you want to include in your feed.

Systems map#

This file exists so a reader can decide which small part of suede is relevant to a task without opening anything else. Areas are divided by reason for change — parts that change for the same reason share an entry, even when they sit in different directories. Suede is a template, so the runtime areas are deliberately thin starting points; the process layer is the part that's fully built.

Layout#

suede/
├── AGENTS.md                  # cross-agent rulebook; read at task start
├── README.md                  # human-facing orientation doc
├── SYSTEMS_MAP.md             # this file
├── package.json               # scripts + deps; version field is the chronver release
├── svelte.config.js           # SvelteKit config, Cloudflare adapter
├── vite.config.ts             # Vite + the three Vitest test projects
├── eslint.config.js           # lint policy (ignore list derives from .gitignore)
├── wrangler.jsonc             # Cloudflare Worker config; bindings start here
├── worker-configuration.d.ts  # generated by `pnpm gen` — never hand-edit
├── drizzle.config.ts          # D1/Drizzle config; names the not-yet-created schema
├── scripts/
│   └── db-check.js            # env-var gate for the db:* scripts
├── src/
│   ├── app.html               # document shell
│   ├── app.css                # global styles; the single stylebase import
│   ├── app.d.ts               # App.Platform types — Cloudflare bindings enter here
│   ├── lib/
│   │   ├── assets/            # favicon and friends
│   │   ├── components/ui/     # human-owned UI primitives (SuedeButton)
│   │   └── styles/            # project-local styles layered over stylebase
│   ├── routes/                # SvelteKit pages — the placeholder a fork replaces
│   └── stories/               # Storybook stories + demo scaffolding
├── static/                    # files served as-is
├── .storybook/                # Storybook config
├── .pi/
│   ├── skills/                # the process layer; task/ is the spine
│   └── prompts/               # user-invoked prompt templates
├── .deciduous/                # decision graph — per-machine; only sync/ commits
├── agent-notes/               # scratch space (gitignored)
├── docs/                      # regenerated decision-graph viewer (gitignored)
└── tmp/                       # per-task slice-briefs (gitignored)

Areas#

App shell and routes#

For: The rendered product surface — pages, layout, and the document shell; in suede itself a placeholder landing page a fork replaces with its real app. Lives at: src/routes/+layout.svelte, src/routes/+page.svelte, src/app.html, src/app.css, src/app.d.ts Seams: src/app.d.ts types App.Platform — the point where Cloudflare bindings become visible to route code; new bindings surface here. src/app.css is the single global-style entry point (the stylebase import plus app-wide rules). Fragile: none found — the shell is a few files of placeholder.

UI foundation#

For: The design-system starting kit — human-owned primitives, their stories, and the global token base the primitives assume. Lives at: src/lib/components/ui/SuedeButton.svelte, src/lib/styles/, src/stories/, .storybook/ Why this shape: Primitives and stories share an area because a primitive change is incomplete without its story update (AGENTS.md, "Storybook discipline") — they change for the same reason by rule. Seams: @taurean/stylebase is imported exactly once, in src/app.css — swap or extend the token base there. .storybook/main.ts globs stories from all of src/, so stories can sit beside their component or in src/stories/. SuedeButton wraps Bits UI's Button.Root; new primitives follow the same wrap-a-headless-primitive pattern. Fragile: SuedeButton's styles lean entirely on stylebase custom properties (--hue-*, --space-*, --ff-ui) and its u:fs-1 utility class — ripping stylebase leaves the button unstyled with no build error. Most of src/stories/ is Storybook onboarding scaffolding a fork deletes; only SuedeButton.stories.svelte reflects real project code.

Data layer (stubbed)#

For: Persistence via Cloudflare D1 through Drizzle — configured but intentionally empty until a fork needs a database. Lives at: drizzle.config.ts, scripts/db-check.js, the db:* scripts in package.json Seams: The schema location is fixed by drizzle.config.ts (src/lib/server/db/schema.ts); creating that file is how the layer comes alive. scripts/db-check.js gates every db:* script on the three CLOUDFLARE_* env vars. Fragile: The configured schema file does not exist yet, so every db:* command fails until a fork creates it — by design, but nothing else says so. svelte.config.js includes drizzle.config.ts in the TypeScript project, so type errors there break pnpm check.

Platform and deploy#

For: How the app becomes a Cloudflare Worker — the adapter, wrangler configuration, and generated platform types. Lives at: wrangler.jsonc, svelte.config.js, worker-configuration.d.ts (generated) Seams: Bindings added in wrangler.jsonc flow into Env via wrangler types (pnpm gen) and surface in route code through App.Platform. The adapter line in svelte.config.js is the swap point for leaving Cloudflare. Fragile: worker-configuration.d.ts is generated — pnpm build and pnpm check run wrangler types --check and fail when it drifts from wrangler.jsonc; regenerate, never hand-edit. wrangler.jsonc's main points at build output, so pnpm preview needs a build first.

Verification harness#

For: What "passing" means for this repo — the test projects, lint, and formatting policy. Lives at: vite.config.ts (the test.projects block), eslint.config.js, the scripts in package.json Why this shape: One Vitest config carries three projects — browser client, node server, and storybook story tests — so a single pnpm test covers every seam the testing doctrine names (.pi/skills/task/testing.md). Seams: A new kind of test is a fourth entry in test.projects. File naming routes tests: *.svelte.{test,spec}.ts runs in the browser project, plain *.{test,spec}.ts in node. Fragile: eslint.config.js builds its ignore list from .gitignore (includeIgnoreFile), so editing .gitignore silently changes what gets linted. Prettier checks everything, including .pi/ markdown — process-layer edits can fail pnpm lint (this bit the 2026.7.2 release cut). requireAssertions: true means a test with no assertion fails.

Process layer#

For: How work happens in this repo and its forks — the rulebook, the task-process skills and prompts, the decision graph, and release conventions; independent of what the app does. Lives at: AGENTS.md, .pi/skills/ (task is the spine; slice-brief, systems-map, project-plan, review, decision-graph, suede-kickoff support it), .pi/prompts/, .deciduous/ Seams: Forks tailor the layer through suede-kickoff Step 3 Thread B — issue tracker, version scheme, commit types, which skills apply. Global skills and prompts ride in from the user's environment without repo changes. Fragile: suede-kickoff is consumed once — it deletes itself at the end of a fork's bootstrap. .deciduous/ is per-machine (only sync/ is committable), so the graph does not travel with a clone. docs/ is the regenerated graph viewer — gitignored; never edit it by hand.