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
Binary file modified bin/dot
Binary file not shown.
1 change: 1 addition & 0 deletions docs/contributor/authoring-flows.md
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,7 @@ The flow immediately appears in `dot flows` and `dot scaffold`.
| `fullstack` | `flows/fullstack.go` | `project_name`, `api_language`, `frontend_framework` |
| `microservices` | `flows/microservices.go` | `project_name`, `services` (loop: `service_name`, `service_port`) |
| `plugin-template` | `flows/plugin_template.go` | `project_name`, `module_path`, `plugin_description`, `plugin_author`, `plugin_year`, `plugin_include_injection`, `plugin_include_generator` |
| `frontend` | `flows/frontend.go` | `project_name`, `framework`, `frontend-router`, `ui-library`, `frontend-styling`, `frontend-state`, `frontend-formatter`, `frontend-linter`, `include-vitest`, `include-playwright`, `include-storybook`, `include-auth`, `include-theme`, `include-feature-flags`, `include-sentry`, `include-analytics`, `include-seo` |

---

Expand Down
173 changes: 173 additions & 0 deletions docs/contributor/flows/frontend.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
# Flow: `frontend`

Scaffolds a TypeScript frontend project — React+Vite or Next.js — with a full range of optional add-ons: router, UI library, styling, state management, testing, auth, feature flags, Sentry, analytics, and SEO.

---

## Identity

| Field | Value |
|-------|-------|
| ID | `frontend` |
| Title | Frontend Wizard |
| File | `flows/frontend.go` |
| Root question | `project_name` |

---

## Questions

| ID | Type | Label | Options / Default |
|----|------|-------|-------------------|
| `project_name` | Text | "Project name" | Default: `"my-app"` |
| `framework` | Option | "Framework" | `react-vite`, `next` |
| `frontend-router` | Option | "Router" | `react-router`, `tanstack-router`, `none` — React+Vite only |
| `ui-library` | Option | "UI library" | `shadcn`, `arkui`, `version14`, `none` |
| `frontend-styling` | Option | "Styling" | `tailwind`, `css-modules`, `panda-css` — skipped when shadcn |
| `frontend-state` | Option | "State management" | `zustand`, `jotai`, `none` |
| `frontend-formatter` | Option | "Formatter" | `biome`, `prettier` |
| `frontend-linter` | Option | "Linter" | `biome`, `prettier` |
| `check-vitest-available` | If | _(silent: fw == react-vite?)_ | Routes to `include-vitest` or `include-playwright` |
| `include-vitest` | Confirm | "Include Vitest + React Testing Library?" | Default: `false` — React+Vite only |
| `include-playwright` | Confirm | "Include Playwright (E2E tests)?" | Default: `false` |
| `include-storybook` | Confirm | "Include Storybook?" | Default: `false` |
| `include-auth` | Confirm | "Include authentication?" | Default: `false` |
| `auth-provider` | Option | "Auth provider" | `clerk`, `better-auth`, `vanilla` — when `include-auth` = true |
| `include-theme` | Confirm | "Include custom theme provider?" | Default: `false` |
| `include-feature-flags` | Confirm | "Include feature flags?" | Default: `false` |
| `feature-flags-provider` | Option | "Feature flags provider" | `posthog`, `vercel`, `local` — when `include-feature-flags` = true |
| `include-sentry` | Confirm | "Include Sentry error tracking?" | Default: `false` |
| `include-analytics` | Confirm | "Include analytics?" | Default: `false` |
| `analytics-provider` | Option | "Analytics provider" | `ga4`, `plausible`, `posthog` — when `include-analytics` = true |
| `include-seo` | Confirm | "Include SEO setup?" | Default: `false` |
| `confirm-generate` | Confirm | "Generate the project now?" | Default: `true` |

---

## Question graph

```
project_name
└── framework
├── [react-vite] → frontend-router
│ └── ui-library
│ ├── [shadcn] → frontend-state (skips styling)
│ └── [other] → frontend-styling
│ └── frontend-state
└── [next] ──────────────── ui-library (same tree as above)

frontend-state
└── frontend-formatter
└── frontend-linter
└── check-vitest-available (IfQuestion)
├── [react-vite] → include-vitest
│ └── include-playwright
└── [next] → include-playwright

include-playwright
└── include-storybook
└── include-auth
├── [true] → auth-provider
│ └── include-theme
└── [false] → include-theme

include-theme
└── include-feature-flags
├── [true] → feature-flags-provider
│ └── include-sentry
└── [false] → include-sentry

include-sentry
└── include-analytics
├── [true] → analytics-provider
│ └── include-seo
└── [false] → include-seo

include-seo
└── confirm-generate
└── (end)
```

---

## Generator resolution

| Condition | Generators added |
|-----------|-----------------|
| Always | `base_project`, `typescript_base` |
| `framework` = `react-vite` | `react_app` |
| `framework` = `next` | `nextjs_base` |
| `framework` = `react-vite` AND `frontend-router` = `react-router` | `react_router_v7` |
| `framework` = `react-vite` AND `frontend-router` = `tanstack-router` | `tanstack_router` |
| `ui-library` = `shadcn` | `shadcn_ui` |
| `ui-library` = `arkui` | `ark_ui` |
| `ui-library` = `version14` | `version14_ui` |
| `ui-library` ≠ `shadcn` AND `frontend-styling` = `tailwind` | `tailwind_v4` |
| `ui-library` ≠ `shadcn` AND `frontend-styling` = `css-modules` | `css_modules` |
| `ui-library` ≠ `shadcn` AND `frontend-styling` = `panda-css` | `panda_css` |
| `frontend-state` = `zustand` | `zustand_setup` |
| `frontend-state` = `jotai` | `jotai_setup` |
| `include-vitest` = true AND `framework` = `react-vite` | `vitest_testing_library` |
| `include-playwright` = true | `playwright_setup` |
| `include-storybook` = true | `storybook_setup` |
| `include-auth` = true AND `auth-provider` = `clerk` | `auth_clerk_frontend` |
| `include-auth` = true AND `auth-provider` = `better-auth` | `auth_better_auth_frontend` |
| `include-auth` = true AND `auth-provider` = `vanilla` | `auth_vanilla_frontend` |
| `include-theme` = true | `theme_provider` |
| `include-feature-flags` = true AND `feature-flags-provider` = `posthog` | `feature_flags_posthog` |
| `include-feature-flags` = true AND `feature-flags-provider` = `vercel` | `feature_flags_vercel` |
| `include-feature-flags` = true AND `feature-flags-provider` = `local` | `feature_flags_local` |
| `include-sentry` = true | `sentry_frontend` |
| `include-analytics` = true AND `analytics-provider` = `ga4` | `analytics_ga4` |
| `include-analytics` = true AND `analytics-provider` = `plausible` | `analytics_plausible` |
| `include-analytics` = true AND `analytics-provider` = `posthog` AND NOT already `feature_flags_posthog` | `feature_flags_posthog` (dedup) |
| `frontend-formatter` = `prettier` (last) | `prettier_config`, `prettier_typescript_deps`, `prettier_frontend_rules` |
| `frontend-formatter` = `biome` (last) | `biome_config` |

---

## Fixture examples

**Minimal React+Vite** (`tools/test-flow/testdata/202605280001_frontend_react_vite_minimal.json`):

```json
{
"name": "frontend_react_vite_minimal",
"flow_id": "frontend",
"answers": {
"project_name": "my-app",
"framework": "react-vite",
"frontend-router": "none",
"ui-library": "none",
"frontend-styling": "tailwind",
"frontend-state": "none",
"frontend-formatter": "biome",
"frontend-linter": "biome",
"include-vitest": false,
"include-playwright": false,
"include-storybook": false,
"include-auth": false,
"include-theme": false,
"include-feature-flags": false,
"include-sentry": false,
"include-analytics": false,
"include-seo": false,
"confirm-generate": true
}
}
```

**All modules** (`tools/test-flow/testdata/202605280008_frontend_react_vite_all_modules.json`):
shadcn forces Tailwind — the `frontend-styling` question is skipped; PostHog dedup — selecting PostHog for both feature flags and analytics emits `feature_flags_posthog` once.

---

## Source

`flows/frontend.go`

## See also

- [docs/generators/nextjs_base.md](../generators/nextjs_base.md)
- [docs/generators/react_router_v7.md](../generators/react_router_v7.md)
- [docs/generators/shadcn_ui.md](../generators/shadcn_ui.md)
78 changes: 78 additions & 0 deletions docs/contributor/generators/analytics_ga4.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# Generator: `analytics_ga4`

Adds Google Analytics 4 via `react-ga4` — writes an initializer and a `.env.example` with the measurement ID.

---

## Identity

| Field | Value |
|-------|-------|
| Name | `analytics_ga4` |
| Version | `0.2.0` |
| Package | `generators/analytics_ga4` |

---

## Dependencies

| Generator | Why |
|-----------|-----|
| `typescript_base` | Requires package.json to merge dependencies into |

---

## Answers consumed

None.

---

## Files written

| Path | Description |
|------|-------------|
| `src/lib/ga4.ts` | GA4 init and `trackEvent` helper |
| `.env.example` | Required env var (`VITE_GA_MEASUREMENT_ID`) |

Also merges into:

| Path | Keys added / updated |
|------|---------------------|
| `package.json` | `dependencies`: `react-ga4^2` |

---

## Validators

| Check | Type | Passes when |
|-------|------|-------------|
| `src/lib/ga4.ts` | `file_exists` | File is present after generation |

---

## Post-generation commands

| Command | WorkDir | Notes |
|---------|---------|-------|
| `pnpm install --dangerously-allow-all-builds` | project root | Installs react-ga4 |

## Test commands

| Command | Background | Ready delay | Notes |
|---------|-----------|-------------|-------|
| `pnpm exec tsc --noEmit` | No | — | Verifies TypeScript compiles |

---

## Conflicts

| Generator | Reason |
|-----------|--------|
| `analytics_plausible` | Both provide analytics — only one analytics library should be installed |

---

## See also

- [docs/flows/frontend.md](../flows/frontend.md)
78 changes: 78 additions & 0 deletions docs/contributor/generators/analytics_plausible.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# Generator: `analytics_plausible`

Adds Plausible Analytics via `plausible-tracker` — writes a tracker initializer and a `.env.example` with the domain.

---

## Identity

| Field | Value |
|-------|-------|
| Name | `analytics_plausible` |
| Version | `0.2.0` |
| Package | `generators/analytics_plausible` |

---

## Dependencies

| Generator | Why |
|-----------|-----|
| `typescript_base` | Requires package.json to merge dependencies into |

---

## Answers consumed

None.

---

## Files written

| Path | Description |
|------|-------------|
| `src/lib/plausible.ts` | Plausible tracker init and `trackEvent` helper |
| `.env.example` | Required env var (`VITE_PLAUSIBLE_DOMAIN`) |

Also merges into:

| Path | Keys added / updated |
|------|---------------------|
| `package.json` | `dependencies`: `plausible-tracker^0.3` |

---

## Validators

| Check | Type | Passes when |
|-------|------|-------------|
| `src/lib/plausible.ts` | `file_exists` | File is present after generation |

---

## Post-generation commands

| Command | WorkDir | Notes |
|---------|---------|-------|
| `pnpm install --dangerously-allow-all-builds` | project root | Installs plausible-tracker |

## Test commands

| Command | Background | Ready delay | Notes |
|---------|-----------|-------------|-------|
| `pnpm exec tsc --noEmit` | No | — | Verifies TypeScript compiles |

---

## Conflicts

| Generator | Reason |
|-----------|--------|
| `analytics_ga4` | Both provide analytics — only one analytics library should be installed |

---

## See also

- [docs/flows/frontend.md](../flows/frontend.md)
Loading
Loading