Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 17 additions & 12 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Operating manual for coding agents working in this repository. Read this fully b
Two products in one monorepo:

- **`flutterwindcss`** — Tailwind CSS's *design system and styling vocabulary* for Flutter. A real pub dependency. It provides design tokens (spacing, radius, semantic colors) and a utility authoring API over Flutter's **primitive** widgets. This is the "Tailwind" layer.
- **`flutterbits`** — shadcn/ui for Flutter. **Copy-paste** components (the developer owns the source, fetched via a CLI from a registry), styled entirely through `flutterwindcss` and semantic tokens. This is the "shadcn/ui" layer.
- **`flutterbits`** — shadcn/ui for Flutter, **plus an opinionated app-structure layer**. **Copy-paste** components (the developer owns the source, fetched via a CLI from a registry), styled entirely through `flutterwindcss` and semantic tokens. Two things in one: (1) shadcn's familiar primitives (parity), and (2) an **intention-revealing "structure" layer** — `Layout`, `Screen`, and typed routing that model how a Next.js/Expo dev thinks, replacing `MaterialApp`/`Scaffold`/`Navigator` ceremony while staying Material-free. This second part is the differentiator. **flutterbits is mobile-first** (portable to web/desktop, matured by demand). Full design: `docs/superpowers/specs/2026-06-10-flutterbits-charter.md` and its two companions (structure+routing, registry+CLI).

The headline feature is **theme portability**: a developer pastes any [tweakcn](https://tweakcn.com)/shadcn theme into a web generator and gets a working Flutter `theme.dart`. No other Flutter UI library does this — protect it.

Expand All @@ -32,11 +32,12 @@ packages/
registry/ # SOURCE OF TRUTH for components: .dart files + JSON manifests
apps/
docs/ # Fumadocs (Next.js) site: docs + the tweakcn -> theme.dart generator + registry endpoint
example/ # Flutter showcase app; ALSO the golden-test + compile target for the registry
example/ # flutterwindcss ENGINE showcase (pure-path WidgetsApp + FwAnimatedTheme) + engine golden/smoke target
gallery/ # flutterbits COMPONENT showcase; the golden-test + compile target for the registry (planned)
tooling/ # registry builder, melos config, CI scripts
```

> **This is the *target* layout.** Today `packages/flutterwindcss/`, `tooling/bake_palette.dart`, `apps/example/`, and `apps/docs/` exist — `apps/example` is a runnable, pure-path **engine** showcase (`WidgetsApp` + `FwAnimatedTheme`), not yet the **component** golden target (no `flutterbits` components yet); `apps/docs` is a **Fumadocs (Next.js/TS)** site whose tweakcn→`theme.dart` generator is **complete (G0–G5 all shipped)** — the color core (`src/lib/generator/color/`, G1), the CSS parser (`src/lib/generator/parse/`, G2 — `:root`/`.dark` → `RawTheme`), the emitter (`src/lib/generator/emit/`, G3 — `RawTheme` → `ResolvedTheme` → `theme.json` → `theme.dart`, end-to-end golden vs `themes.dart`), the web UI (`src/app/(home)/theme-generator/`, G4 — paste → preview → copy, logic in the tested `src/lib/generator/preview.ts`), and the docs page (`content/docs/theme-generator.mdx`, G5). `flutterbits_cli/`, `registry/`, and the melos config are still planned. CI covers `packages/flutterwindcss` (analyze + format + tests + floor-compat + arch-guard), `apps/example` (analyze + format + widget smoke tests), **and** `apps/docs` (the `docs-generator` job: eslint + scoped `tsc` on `src/lib/generator` *and* the `theme-generator` route + Vitest). Don't go looking for dirs that aren't there yet.
> **This is the *target* layout.** Today `packages/flutterwindcss/`, `tooling/bake_palette.dart`, `apps/example/`, and `apps/docs/` exist — `apps/example` is a runnable, pure-path **engine** showcase (`WidgetsApp` + `FwAnimatedTheme`) and stays **engine-only**; the **component** golden + compile target is a **separate `apps/gallery`** app (planned — does not exist yet, created with the first component slice), NOT `apps/example` (decision 2026-06-10: the engine showcase and the component showcase are distinct apps); `apps/docs` is a **Fumadocs (Next.js/TS)** site whose tweakcn→`theme.dart` generator is **complete (G0–G5 all shipped)** — the color core (`src/lib/generator/color/`, G1), the CSS parser (`src/lib/generator/parse/`, G2 — `:root`/`.dark` → `RawTheme`), the emitter (`src/lib/generator/emit/`, G3 — `RawTheme` → `ResolvedTheme` → `theme.json` → `theme.dart`, end-to-end golden vs `themes.dart`), the web UI (`src/app/(home)/theme-generator/`, G4 — paste → preview → copy, logic in the tested `src/lib/generator/preview.ts`), and the docs page (`content/docs/theme-generator.mdx`, G5). `flutterbits_cli/`, `registry/`, and the melos config are still planned. CI covers `packages/flutterwindcss` (analyze + format + tests + floor-compat + arch-guard), `apps/example` (analyze + format + widget smoke tests), **and** `apps/docs` (the `docs-generator` job: eslint + scoped `tsc` on `src/lib/generator` *and* the `theme-generator` route + Vitest). Don't go looking for dirs that aren't there yet.

- **Toolchain floor (hard): Flutter ≥ 3.29 / Dart ≥ 3.7.** The wide-gamut `Color` API (`Color.withValues` per §3.8, and the `Color.a/.r/.g/.b` accessors), the `Row`/`Column`/`Flex` `spacing` parameter, and pub workspaces require 3.27/3.6 — below that, the code will not compile. We floor one minor higher at **Dart 3.7** so `dart format` uses the modern "tall" style (Dart 3.7+) rather than the legacy short style; mixing the two fails the format check. This floor is set in every `pubspec.yaml` `environment:` and **verified by a CI job pinned to it** (separate from the golden job, which pins a newer version for determinism). Keep the floor identical in the pubspecs and the README.
- Dependency resolution: **pub workspaces** (`resolution: workspace` in each `pubspec.yaml`). Task running / versioning / publishing: **Melos** — the intended cross-package runner, adopted once the workspace holds multiple packages. While `flutterwindcss` is the only package, use plain `flutter`/`dart` per-package (see §10).
Expand Down Expand Up @@ -70,7 +71,7 @@ These encode hard-won decisions. Violating any of them is a review failure.

## 4. Coding conventions (Dart)

- Public types are prefixed `Fw` (`FwStyle`, `FwButton`, `FwColors`, `FwButtonVariant`).
- **`flutterwindcss` (engine) public types are prefixed `Fw`** (`FwStyle`, `FwColors`, `FwTokens`, `FwBreakpoint`), and so are the routing/structure **library** base types that ship as engine-style code (`FwRoute`, `FwRoutePattern`, `FwPresentation`, `FwStatusBar`). **flutterbits *components* are UNprefixed** — `Button`, `Card`, `Screen`, `Layout` — because they are copy-paste source the developer owns (shadcn-style) and need no namespace. (Material name clashes, only possible in the rare Material-interop case, are resolved by namespacing the barrel `import '.../ui/ui.dart' as ui;`, not by prefixing — see the charter §5.) When you see `Fw` inside a component, that is the engine showing through.
- Prefer `const` constructors wherever the analyzer allows; leaf widgets that never change should be `const`.
- Variants are **typed enums + exhaustive `switch`** (the cva equivalent). No stringly-typed variant maps. The `switch` must be exhaustive so the compiler catches a missing case — do not add a `default:` that papers over new enum values.
- Every file passes `dart format` (100-col) and `flutter analyze` with **zero** warnings before you call a task done.
Expand Down Expand Up @@ -109,7 +110,7 @@ Until the first component lands, follow the component checklist below and the en
- [ ] Directional layout throughout (§3.3).
- [ ] A registry manifest entry (§8) listing pub deps and `registryDeps`.
- [ ] Golden tests for **every variant × size × brightness** (§9).
- [ ] Imported and rendered in `apps/example` so CI compiles it.
- [ ] Imported and rendered in `apps/gallery` (the flutterbits component target — **not** `apps/example`, which is the engine showcase) so CI compiles it.

If a desired behavior genuinely cannot be done in Flutter, do not fake it — add it to the **Won't-do list** (§11) and note it in the component's docs.

Expand Down Expand Up @@ -137,22 +138,24 @@ If a desired behavior genuinely cannot be done in Flutter, do not fake it — ad

## 8. Registry & CLI

- Registry manifest per component (JSON): `{ name, description, pubDeps: [...], registryDeps: [...], files: [{ path, content }] }`. `registryDeps` resolves inter-component needs (e.g. `dialog` pulls in `button`).
- `flutterbits add <name>` writes files into the host project (default `lib/components/ui/`), installs `pubDeps`, recursively adds `registryDeps`, then runs `dart format`.
- `flutterbits diff <name>` shows upstream changes vs the developer's copy (the copy-paste survival mechanism — analogous to shadcn's diff).
- The registry build step (`tooling/`) generates manifests FROM the `registry/*.dart` source. Never hand-edit a manifest's `content`.
- Registry manifest per item (JSON): `{ name, type, description, exported, pubDeps: [...], registryDeps: [...], files: [{ path, type, target, content }] }`. **Install-types** (shadcn's `registry:ui`/`lib`/`hook` analog): `component` → `lib/components/ui/<name>.dart`; `util` → `lib/components/ui/_utils/<name>.dart` (shared lib utilities — the `anchor`/overlay substrate, `showConfirm`/`showSheet`/`showToast`; Flutter has no native "hooks", so these are plain utilities). `registryDeps` resolves inter-item needs recursively (e.g. `dialog` pulls in `button`; `popover` pulls in `anchor`).
- `flutterbits init` scaffolds a project: adds `flutterwindcss`, creates `lib/components/ui/` + `_utils/`, writes a starter `theme.dart`, an initial barrel, an optional starter `Layout`, and `flutterbits.json` (the config — `components.json` analog: registry URL + target paths + theme path).
- `flutterbits add <name>` writes files into the host project (default `lib/components/ui/`), installs `pubDeps`, recursively adds `registryDeps`, **regenerates the barrel**, then runs `dart format`.
- **The barrel `lib/components/ui/ui.dart`** is CLI-**generated, never hand-edited** — it re-exports every `exported` item so devs import the whole set from one place (and `import … as ui;` namespaces it for the rare Material-interop clash). Internal utils (e.g. `anchor`) are imported directly and stay out of the barrel.
- `flutterbits diff <name>` shows upstream changes vs the developer's copy (the copy-paste survival mechanism — analogous to shadcn's diff); it **shows, never auto-merges** (the dev owns their edits).
- The registry build step (`tooling/build_registry.dart`) generates manifests FROM the `registry/*.dart` source. Never hand-edit a manifest's `content`. Full design: `docs/superpowers/specs/2026-06-10-flutterbits-registry-cli-design.md`.

---

## 9. Testing — mandatory, not optional

This is the safety net that makes a solo, wave-by-wave rollout survivable.

- **Golden tests** use `matchesGoldenFile`. **`flutterwindcss` engine goldens live in-package** (`packages/flutterwindcss/test/golden/`) — a library tests its own widgets. **Component goldens** (every variant × size × brightness) live in `apps/example`, which is also the registry compile target.
- **Golden tests** use `matchesGoldenFile`. **`flutterwindcss` engine goldens live in-package** (`packages/flutterwindcss/test/golden/`) — a library tests its own widgets. **Component goldens** (every variant × size × brightness) live in **`apps/gallery`**, which is also the registry compile target. (`apps/example` is the *engine* showcase and hosts only engine smoke tests — the two apps are deliberately separate, decision 2026-06-10.)
- CI pins a **fixed font** and platform so goldens are deterministic across machines, and **CI (Linux) is the authoritative golden platform** — goldens are generated/verified there, and a local `--update-goldens` on a dev box is *not* authoritative. A golden diff on CI is a failing build, not a nuisance.
- Update goldens only intentionally: `flutter test --update-goldens`, and review the image diff before committing.
- `flutterwindcss` gets unit tests for `FwStyle` resolution — especially **last-wins conflict behavior** and that chaining produces a single resolved widget.
- Before marking any task done: `flutter analyze` (zero warnings) AND `flutter test` (green) AND the registry compiles in `apps/example`.
- Before marking any task done: `flutter analyze` (zero warnings) AND `flutter test` (green) AND the registry compiles in `apps/gallery`.

---

Expand All @@ -178,6 +181,8 @@ Adjust paths if the layout drifts; keep this section current.
| Task | Command |
|---|---|
| Build registry manifests | `dart run tooling/build_registry.dart` |
| Run the flutterbits component gallery | `cd apps/gallery && flutter run` (any device; e.g. `-d chrome`) |
| Test/golden the gallery | `cd apps/gallery && flutter test` (`--update-goldens` locally is non-authoritative; CI Linux is the source of truth) |
| Run docs site / generator | `cd apps/docs && pnpm dev` |

Once the workspace holds multiple packages, **Melos** wraps the per-package commands (`melos bootstrap`, `melos run analyze`, `melos run test`); adopt it then, not before.
Expand Down Expand Up @@ -217,7 +222,7 @@ Everything **not** in 11a or 11b is fair game and must not be refused on cost gr
- **Verdict before "won't" (MUST).** Before declaring anything a Non-Goal or limitation, write a one-paragraph feasibility verdict: the mechanism that *would* implement it, its rough cost, and the honest call. Attach it to the spec. Default to building; only the §11 bar excuses not building.
- **Read before you edit.** Open the canonical sources (`lib/src/style/`, `lib/src/theme/`, `lib/src/tokens/`, and once it exists `registry/button.dart`) and match their patterns before writing new code.
- **Small, focused changes.** One component or one utility group per change. Don't refactor unrelated code in passing.
- **No new dependencies without justification.** Prefer the framework's widgets layer. Known sanctioned deps: `lucide_icons_flutter` (icons), `flutter_animate` (animation). Anything else needs a reason in the PR description.
- **No new dependencies without justification.** Prefer the framework's widgets layer. Known sanctioned deps: `lucide_icons_flutter` (icons), `flutter_animate` (animation), and **`go_router`** (the routing engine the flutterbits structure layer *wraps* — not forks — declared as a `pubDep` of the structure components only; never a `flutterwindcss` dep). `flutter_svg` is sanctioned **by-demand** for blocks that render real SVG illustrations. Anything else needs a reason in the PR description. Deps are declared **per-component in the manifest `pubDeps`**, never globally: a copied `Button` drags in nothing; `add toast` pulls `flutter_animate`; `add layout` pulls `go_router`.
- **Don't invent APIs.** If unsure whether a Flutter symbol exists in the widgets layer, verify before using it. Do not assume Material symbols are available.
- **Surface assumptions.** If a task is ambiguous (which variant set? which platforms?), state the assumption you made inline rather than guessing silently.
- **Never weaken the rules in §3 to make a task pass.** If a rule blocks you, stop and flag it — don't import Material, don't hardcode a color, don't nest wrappers to ship faster.
Expand Down
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
Two products in one monorepo, built so that **any [tweakcn](https://tweakcn.com)/shadcn theme you paste into a web generator becomes a working Flutter `theme.dart`** — theme portability no other Flutter UI library offers.

- **`flutterwindcss`** — Tailwind CSS v4's *design system and styling vocabulary* for Flutter. Design tokens (spacing, radius, semantic colors, typography, shadows) and a typed, compile‑time utility API (`.tw`) over Flutter's primitive widgets. This is the **Tailwind** layer.
- **`flutterbits`** — shadcn/ui for Flutter. **Copy‑paste** components you own, fetched via a CLI from a registry, styled entirely through `flutterwindcss` and semantic tokens. This is the **shadcn/ui** layer.
- **`flutterbits`** — shadcn/ui for Flutter. **Copy‑paste** components you own, fetched via a CLI from a registry, styled entirely through `flutterwindcss` and semantic tokens — **plus** an opinionated, intention‑revealing **structure layer** (`Layout`, `Screen`, typed routing) that models app‑building the Next.js/Expo way. Mobile‑first, portable. This is the **shadcn/ui** layer (and a bit more).

## Install & docs

Expand Down Expand Up @@ -88,7 +88,7 @@ Flutter has no structure/style split and no CSS cascade — the widget tree *is*

**🚧 Next on the roadmap:**

1. **`flutterbits` components** and the **registry + CLI** (`flutterbits add` / `diff`). *(The engine is ready — ~96% of daily-driver Tailwind is covered and a full-catalog audit found no engine blocker.)*
1. **`flutterbits` components** and the **registry + CLI** (`flutterbits init` / `add` / `diff`) — primitives (shadcn parity), the **structure layer** (`Layout`/`Screen`/routing over `go_router`), blocks, and templates. Design specs: [`flutterbits-charter`](docs/superpowers/specs/2026-06-10-flutterbits-charter.md), [structure + routing](docs/superpowers/specs/2026-06-10-flutterbits-structure-and-routing-design.md), [registry + CLI](docs/superpowers/specs/2026-06-10-flutterbits-registry-cli-design.md). *(The engine is ready — ~96% of daily-driver Tailwind is covered and a full-catalog audit found no engine blocker.)*
2. **Remaining engine long-tail (by demand only)** — niche/feasible items (`inset-shadow`, `mask-*`, backdrop color filters, `columns`, negative margins, `scroll-margin/padding`, decoration styling) built when a real component needs one; the rest is the [coverage & roadmap](docs/superpowers/specs/2026-06-07-flutterwindcss-coverage-and-roadmap.md)'s delegated (animation → [`flutter_animate`](https://pub.dev/packages/flutter_animate); forms/prose/tables/SVG → flutterbits) / impossible sets.

See [`docs/superpowers/specs`](docs/superpowers/specs) for the full engine design and [`docs/superpowers/plans`](docs/superpowers/plans) for the implementation plans.
Expand All @@ -99,7 +99,8 @@ See [`docs/superpowers/specs`](docs/superpowers/specs) for the full engine desig
packages/
flutterwindcss/ # pub package: tokens, FwTheme, FwStyle accumulator, .tw utilities
apps/
example/ # flutterwindcss engine showcase (pure path, runnable); component golden target (planned)
example/ # flutterwindcss ENGINE showcase (pure path, runnable) + engine golden/smoke target
gallery/ # flutterbits COMPONENT showcase + golden/compile target (planned)
docs/ # Fumadocs site + the tweakcn→theme.dart generator (shipped: parse→color→emit pipeline, web UI at /theme-generator, docs)
registry/ # (planned) source-of-truth copy-paste components
tooling/ # registry builder + the Tailwind palette baker
Expand Down
Loading
Loading