diff --git a/.cursor/rules/ai-rules-generated-00-project-context.mdc b/.cursor/rules/ai-rules-generated-00-project-context.mdc new file mode 100644 index 0000000..aa3b4c1 --- /dev/null +++ b/.cursor/rules/ai-rules-generated-00-project-context.mdc @@ -0,0 +1,58 @@ +--- +description: Project overview and context for react-router-starter +globs: **/* +alwaysApply: true +--- + +# Project Context + +## What This Repo Is + +**react-router-starter** is a monorepo starter for React Router 7 apps with best practices: Storybook, @lambdacurry/forms, Bun test + React Testing Library, and shared AI rules. + +## Structure + +- **apps/todo-app** – Reference app (React Router 7, Vite, Tailwind v4, forms, Storybook, tests). +- **packages/** – Shared packages (e.g. `@todo-starter/ui`, `@todo-starter/utils`) used by apps. +- **ai-rules/** – Source-of-truth AI rules (project context, React Router, Storybook, forms, testing, monorepo, UI). +- **.cursor/rules/** – Generated Cursor rules (do not edit directly). +- **AGENTS.md / CLAUDE.md / GEMINI.md** – Generated agent rules (do not edit directly). + +## Issue Tracking (Beads) + +Beads is required **only** when running Ralph loops or when a task explicitly comes from Beads. For ad-hoc work, you can skip Beads. + +When Beads is in use, follow `.devagent/plugins/ralph/AGENTS.md` and use the CLI: + +```bash +bd ready # Find available work +bd show # View issue details +bd update --status in_progress # Claim work +bd update --status closed # Complete work +bd sync # Sync with git +``` + +## Quality Gates (todo-app) + +From `apps/todo-app/package.json`: + +- **Test:** `bun run test:run` or `bun run test:ci` (Bun test) +- **Lint:** `npm run lint` (Biome) +- **Typecheck:** `npm run typecheck` (tsc) +- **Build:** `npm run build` (react-router build) +- **Storybook:** `npm run storybook` (dev), `npm run build-storybook` (build) + +Run these from `apps/todo-app` or via workspace root scripts if defined. + +## Conventions + +- **Routing:** File-based routes in `app/routes/`; use loaders/actions and route types. +- **Forms:** @lambdacurry/forms + remix-hook-form + Zod; see `ai-rules/lambda-curry-forms.md`. +- **Tests:** Bun test + React Testing Library; use `renderWithRouter` for router-dependent components; see `apps/todo-app/TESTING.md` and `ai-rules/testing-best-practices.md`. +- **Styling:** Tailwind CSS v4; mobile-first; prefer existing UI components. + +## AI Rules Workflow + +- **Edit source rules** in `ai-rules/` +- **Generated outputs** in `.generated-ai-rules/` and `.cursor/rules/` are maintained by repository automation +- **Do not edit generated files directly**; change source rules in `ai-rules/` diff --git a/.cursorrules/lambda-curry-forms.mdc b/.cursor/rules/ai-rules-generated-lambda-curry-forms.mdc similarity index 97% rename from .cursorrules/lambda-curry-forms.mdc rename to .cursor/rules/ai-rules-generated-lambda-curry-forms.mdc index 327326c..95da5cc 100644 --- a/.cursorrules/lambda-curry-forms.mdc +++ b/.cursor/rules/ai-rules-generated-lambda-curry-forms.mdc @@ -105,17 +105,6 @@ export const action = async ({ request }: ActionFunctionArgs) => { }; ``` -## Advanced Patterns - -### Conditional Fields -```typescript -const watchAccountType = methods.watch('accountType'); - -{watchAccountType === 'business' && ( - -)} -``` - ## Available Form Components ### TextField Component diff --git a/.cursor/rules/ai-rules-generated-monorepo.mdc b/.cursor/rules/ai-rules-generated-monorepo.mdc new file mode 100644 index 0000000..bce838a --- /dev/null +++ b/.cursor/rules/ai-rules-generated-monorepo.mdc @@ -0,0 +1,49 @@ +--- +description: Monorepo structure, package boundaries, and workspace conventions +globs: **/* +alwaysApply: true +--- + +# Monorepo Rules + +## Package Structure +- `apps/` - Applications (todo-app) +- `packages/` - Shared packages (ui, utils) +- Each package has its own package.json with proper exports + +## Workspace Dependencies +- Use `workspace:*` for internal package dependencies +- Keep external dependencies in sync across packages +- Use peerDependencies for shared libraries like React + +## Import Patterns +```tsx +// Import from workspace packages +import { Button } from '@todo-starter/ui'; +import { cn, type Todo } from '@todo-starter/utils'; + +// Import from local files +import { TodoItem } from '~/components/todo-item'; +import type { Route } from './+types/home'; +``` + +## Package Naming +- Use scoped packages: `@todo-starter/package-name` +- Keep names descriptive and consistent +- Use kebab-case for package names + +## Scripts and Tasks +- Define scripts at both root and package level +- Use Turbo for orchestrating build tasks +- Prefer package-specific scripts for development + +## TypeScript Configuration +- Use Tailwind CSS v4's CSS-first configuration with `@theme` directive +- Use path mapping for workspace packages +- Keep tsconfig.json files minimal and focused + +## Best Practices +- Keep packages focused and single-purpose +- Avoid circular dependencies between packages +- Use proper exports in package.json +- Document package APIs and usage patterns diff --git a/.cursorrules/react-router.mdc b/.cursor/rules/ai-rules-generated-react-router.mdc similarity index 100% rename from .cursorrules/react-router.mdc rename to .cursor/rules/ai-rules-generated-react-router.mdc diff --git a/.cursorrules/storybook.mdc b/.cursor/rules/ai-rules-generated-storybook.mdc similarity index 97% rename from .cursorrules/storybook.mdc rename to .cursor/rules/ai-rules-generated-storybook.mdc index f444e83..0320753 100644 --- a/.cursorrules/storybook.mdc +++ b/.cursor/rules/ai-rules-generated-storybook.mdc @@ -18,6 +18,7 @@ alwaysApply: false Components that use `Link`, `useNavigate`, `useFetcher`, or `useHref` need router context. Use a global decorator in `preview.tsx`: ```tsx +import type { Preview } from '@storybook/react'; import type { ComponentType } from 'react'; import { createMemoryRouter, RouterProvider } from 'react-router-dom'; diff --git a/.cursor/rules/ai-rules-generated-testing-best-practices.mdc b/.cursor/rules/ai-rules-generated-testing-best-practices.mdc new file mode 100644 index 0000000..cdc1b50 --- /dev/null +++ b/.cursor/rules/ai-rules-generated-testing-best-practices.mdc @@ -0,0 +1,78 @@ +--- +description: Bun test and React Testing Library patterns for React Router apps +globs: apps/**/*.test.{ts, tsx}, apps/**/*.spec.{ts, tsx}, apps/**/test/**/* +alwaysApply: false +--- + +# Testing Best Practices + +## Stack + +- **Runner:** Bun test (`bun:test`) with JSDOM bootstrap in `test/setup.ts` (loaded via `bunfig.toml`) +- **Component/DOM:** React Testing Library +- **Router:** `createMemoryRouter` + `RouterProvider` via shared `renderWithRouter` helper + +## Test Layout (todo-app) + +| Pattern | Location | Purpose | +|---------------|-----------------------------------|--------| +| Unit | `app/lib/__tests__/*.test.ts` | Pure utilities, helpers | +| Component | `app/components/__tests__/*.test.tsx` | UI with router/context mocking | +| Integration | `app/routes/__tests__/*.integration.test.tsx` | Full route + provider flows | + +Shared setup: `test/setup.ts` (jest-dom, RTL cleanup). Shared helpers: `test/test-utils.tsx`. + +## Router-Dependent Components + +Use `renderWithRouter` for any component that uses `Link`, `useNavigate`, `useFetcher`, or `useHref`: + +```tsx +import { renderWithRouter } from '../../../test/test-utils'; + +it('renders and submits', () => { + renderWithRouter(); +}); + +it('renders at /contact', () => { + renderWithRouter(, { initialEntries: ['/contact'] }); +}); +``` + +For full route trees (loaders, nested layouts), use `createTestRouter` or pass `routes` into `renderWithRouter`. + +## Integration Tests + +Wrap route components with the same providers as the app (e.g. TodoProvider), then assert user flows: + +```tsx +import { renderWithRouter } from '../../test/test-utils'; +import { TodoProvider } from '../../lib/todo-context'; +import Home from '../home'; + +renderWithRouter( + + + +); +// fire events, assert DOM/state +``` + +## Bun Config (reference) + +- **preload:** `test/setup.ts` via `bunfig.toml` +- **jsdom:** initialized in `test/setup.ts` (globals + `@testing-library/jest-dom`) +- **testTimeout:** Bun default is `5000`; adjust with `bun test --timeout ` when needed + +## Commands + +- `bun run test` – run tests +- `bun run test:watch` – watch mode +- `bun run test:run` / `bun run test:ci` – single run (CI) + +## Best Practices + +- Prefer `getByRole`, `getByLabelText`, `getByPlaceholderText` over brittle selectors +- Use `jest.fn()` from `bun:test` for callbacks; assert calls and args +- Hoist repeated regex/selectors to describe scope to satisfy lint rules +- Keep tests focused; use multiple `it` blocks instead of one large test +- For forms: test validation, submit behavior, and error display (see lambda-curry-forms rules for FormError) diff --git a/.cursor/rules/ai-rules-generated-ui-components.mdc b/.cursor/rules/ai-rules-generated-ui-components.mdc new file mode 100644 index 0000000..b32f7f8 --- /dev/null +++ b/.cursor/rules/ai-rules-generated-ui-components.mdc @@ -0,0 +1,85 @@ +--- +description: UI component conventions and shadcn/ui patterns +globs: packages/ui/**/*.tsx, packages/ui/**/*.ts, apps/**/app/**/*.tsx +alwaysApply: true +--- + +# UI Component Rules + +## Component Structure +- Use forwardRef for components that need ref forwarding +- Implement proper TypeScript interfaces +- Use class-variance-authority for variant-based styling + +## shadcn/ui Patterns +```tsx +// Component example +import * as React from 'react'; +import { cva, type VariantProps } from 'class-variance-authority'; +import { cn } from '@todo-starter/utils'; +import { Slot } from '@radix-ui/react-slot'; + +const buttonVariants = cva( + 'base-classes', + { + variants: { + variant: { + default: 'default-classes', + destructive: 'destructive-classes' + }, + size: { + default: 'default-size', + sm: 'small-size' + } + }, + defaultVariants: { + variant: 'default', + size: 'default' + } + } +); + +export interface ButtonProps + extends React.ButtonHTMLAttributes, + VariantProps { + asChild?: boolean; +} + +const Button = React.forwardRef( + ({ className, variant, size, asChild = false, ...props }, ref) => { + const Comp = asChild ? Slot : 'button'; + return ( + + ); + } +); +Button.displayName = 'Button'; +``` + +## Styling Guidelines +- Use Tailwind CSS classes for styling +- Leverage CSS variables for theming +- Use cn() utility for conditional classes +- Follow shadcn/ui color and spacing conventions + +## Accessibility +- Include proper ARIA attributes +- Ensure keyboard navigation works +- Use semantic HTML elements +- Test with screen readers + +## Component Organization +- Keep components in `packages/ui/src/components/ui/` +- Export all components from main index file +- Group related components together +- Use consistent naming conventions + +## Best Practices +- Prefer composition over complex props +- Keep components focused and reusable +- Document component APIs with TypeScript +- Test components in isolation diff --git a/.cursorrules/00-project-context.mdc b/.cursorrules/00-project-context.mdc deleted file mode 100644 index 0c13c6a..0000000 --- a/.cursorrules/00-project-context.mdc +++ /dev/null @@ -1,51 +0,0 @@ ---- -description: Project overview and context for react-router-starter -alwaysApply: true ---- - -# Project Context - -## What This Repo Is - -**react-router-starter** is a monorepo starter for React Router 7 apps with best practices from reportory: Storybook, @lambdacurry/forms, Vitest + React Testing Library, and shared Cursor rules. - -## Structure - -- **apps/todo-app** – Reference app (React Router 7, Vite, Tailwind v4, forms, Storybook, tests). -- **packages/** – Shared packages (e.g. `@todo-starter/ui`, `@todo-starter/utils`) used by apps. -- **.cursorrules/** – Cursor AI rules (project context, React Router, Storybook, forms, testing, monorepo, UI). - -## Issue Tracking - -This project uses **Beads (bd)** for issues. See `AGENTS.md` for workflow. - -```bash -bd ready # Find available work -bd show # View issue details -bd update --status in_progress # Claim work -bd close # Complete work -bd sync # Sync with git -``` - -## Quality Gates (todo-app) - -From `apps/todo-app/package.json`: - -- **Test:** `npm run test:run` or `npm run test:ci` (Vitest) -- **Lint:** `npm run lint` (Biome) -- **Typecheck:** `npm run typecheck` (tsc) -- **Build:** `npm run build` (react-router build) -- **Storybook:** `npm run storybook` (dev), `npm run build-storybook` (build) - -Run these from `apps/todo-app` or via workspace root scripts if defined. - -## Conventions - -- **Routing:** File-based routes in `app/routes/`; use loaders/actions and route types. -- **Forms:** @lambdacurry/forms + remix-hook-form + Zod; see `.cursorrules/lambda-curry-forms.mdc`. -- **Tests:** Vitest + React Testing Library; use `renderWithRouter` for router-dependent components; see `apps/todo-app/TESTING.md` and `.cursorrules/testing-best-practices.mdc`. -- **Styling:** Tailwind CSS v4; mobile-first; prefer existing UI components. - -## Rule Order - -Cursor rules in `.cursorrules/` are applied as configured. `00-project-context.mdc` is intended to load first (naming prefix) to establish project context; other rule files add domain-specific guidance (React Router, Storybook, forms, testing, monorepo, UI). diff --git a/.cursorrules/monorepo.mdc b/.cursorrules/monorepo.mdc deleted file mode 100644 index dec7a87..0000000 --- a/.cursorrules/monorepo.mdc +++ /dev/null @@ -1,90 +0,0 @@ ---- -alwaysApply: true ---- - -# Monorepo Cursor Rules - -## Package Structure -- `apps/` - Applications (todo-app) -- `packages/` - Shared packages (ui, utils) -- Each package has its own package.json with proper exports - -## Workspace Dependencies -- Use `workspace:*` for internal package dependencies -- Keep external dependencies in sync across packages -- Use peerDependencies for shared libraries like React - -## Import Patterns -```tsx -// Import from workspace packages -import { Button } from '@todo-starter/ui'; -import { cn, type Todo } from '@todo-starter/utils'; - -// Import from local files -import { TodoItem } from '~/components/todo-item'; -import type { Route } from './+types/home'; -``` - -## Package Naming -- Use scoped packages: `@todo-starter/package-name` -- Keep names descriptive and consistent -- Use kebab-case for package names - -## Scripts and Tasks -- Define scripts at both root and package level -- Use Turbo for orchestrating build tasks -- Prefer package-specific scripts for development - -## TypeScript Configuration -- Use Tailwind CSS v4's CSS-first configuration with `@theme` directive -- Use path mapping for workspace packages -- Keep tsconfig.json files minimal and focused - -## Best Practices -- Keep packages focused and single-purpose -- Avoid circular dependencies between packages -- Use proper exports in package.json -- Document package APIs and usage patterns -# Monorepo Cursor Rules - -## Package Structure -- `apps/` - Applications (todo-app) -- `packages/` - Shared packages (ui, utils) -- Each package has its own package.json with proper exports - -## Workspace Dependencies -- Use `workspace:*` for internal package dependencies -- Keep external dependencies in sync across packages -- Use peerDependencies for shared libraries like React - -## Import Patterns -```tsx -// Import from workspace packages -import { Button } from '@todo-starter/ui'; -import { cn, type Todo } from '@todo-starter/utils'; - -// Import from local files -import { TodoItem } from '~/components/todo-item'; -import type { Route } from './+types/home'; -``` - -## Package Naming -- Use scoped packages: `@todo-starter/package-name` -- Keep names descriptive and consistent -- Use kebab-case for package names - -## Scripts and Tasks -- Define scripts at both root and package level -- Use Turbo for orchestrating build tasks -- Prefer package-specific scripts for development - -## TypeScript Configuration -- Use Tailwind CSS v4's CSS-first configuration with `@theme` directive -- Use path mapping for workspace packages -- Keep tsconfig.json files minimal and focused - -## Best Practices -- Keep packages focused and single-purpose -- Avoid circular dependencies between packages -- Use proper exports in package.json -- Document package APIs and usage patterns diff --git a/.cursorrules/ui-components.mdc b/.cursorrules/ui-components.mdc deleted file mode 100644 index b993ab8..0000000 --- a/.cursorrules/ui-components.mdc +++ /dev/null @@ -1,162 +0,0 @@ ---- -alwaysApply: true ---- - -# UI Components Cursor Rules - -## Component Structure -- Use forwardRef for components that need ref forwarding -- Implement proper TypeScript interfaces -- Use class-variance-authority for variant-based styling - -## shadcn/ui Patterns -```tsx -// Component example -import * as React from 'react'; -import { cva, type VariantProps } from 'class-variance-authority'; -import { cn } from '@todo-starter/utils'; - -const buttonVariants = cva( - 'base-classes', - { - variants: { - variant: { - default: 'default-classes', - destructive: 'destructive-classes' - }, - size: { - default: 'default-size', - sm: 'small-size' - } - }, - defaultVariants: { - variant: 'default', - size: 'default' - } - } -); - -export interface ButtonProps - extends React.ButtonHTMLAttributes, - VariantProps { - asChild?: boolean; -} - -const Button = React.forwardRef( - ({ className, variant, size, asChild = false, ...props }, ref) => { - const Comp = asChild ? Slot : 'button'; - return ( - - ); - } -); -Button.displayName = 'Button'; -``` - -## Styling Guidelines -- Use Tailwind CSS classes for styling -- Leverage CSS variables for theming -- Use cn() utility for conditional classes -- Follow shadcn/ui color and spacing conventions - -## Accessibility -- Include proper ARIA attributes -- Ensure keyboard navigation works -- Use semantic HTML elements -- Test with screen readers - -## Component Organization -- Keep components in `packages/ui/src/components/ui/` -- Export all components from main index file -- Group related components together -- Use consistent naming conventions - -## Best Practices -- Prefer composition over complex props -- Keep components focused and reusable -- Document component APIs with TypeScript -- Test components in isolation - -# UI Components Cursor Rules - -## Component Structure -- Use forwardRef for components that need ref forwarding -- Implement proper TypeScript interfaces -- Use class-variance-authority for variant-based styling - -## shadcn/ui Patterns -```tsx -// Component example -import * as React from 'react'; -import { cva, type VariantProps } from 'class-variance-authority'; -import { cn } from '@todo-starter/utils'; - -const buttonVariants = cva( - 'base-classes', - { - variants: { - variant: { - default: 'default-classes', - destructive: 'destructive-classes' - }, - size: { - default: 'default-size', - sm: 'small-size' - } - }, - defaultVariants: { - variant: 'default', - size: 'default' - } - } -); - -export interface ButtonProps - extends React.ButtonHTMLAttributes, - VariantProps { - asChild?: boolean; -} - -const Button = React.forwardRef( - ({ className, variant, size, asChild = false, ...props }, ref) => { - const Comp = asChild ? Slot : 'button'; - return ( - - ); - } -); -Button.displayName = 'Button'; -``` - -## Styling Guidelines -- Use Tailwind CSS classes for styling -- Leverage CSS variables for theming -- Use cn() utility for conditional classes -- Follow shadcn/ui color and spacing conventions - -## Accessibility -- Include proper ARIA attributes -- Ensure keyboard navigation works -- Use semantic HTML elements -- Test with screen readers - -## Component Organization -- Keep components in `packages/ui/src/components/ui/` -- Export all components from main index file -- Group related components together -- Use consistent naming conventions - -## Best Practices -- Prefer composition over complex props -- Keep components focused and reusable -- Document component APIs with TypeScript -- Test components in isolation - diff --git a/.devagent/loops/starter-improvements.yaml b/.devagent/loops/starter-improvements.yaml deleted file mode 100644 index 669254f..0000000 --- a/.devagent/loops/starter-improvements.yaml +++ /dev/null @@ -1,121 +0,0 @@ -name: starter-improvements -description: > - Update react-router-starter to be a comprehensive prototype starting point - with best practices from reportory, Storybook, forms library, and testing examples. - -context: - goal: | - Create a best-practices starter template that can be quickly duplicated - for prototype apps. Should demonstrate patterns for react-router, forms, - testing, and Storybook that we use across Lambda Curry projects. - - references: - - ~/projects/reportory/.cursorrules/react-router.md - - ~/projects/reportory/.cursorrules/storybook.md - - ~/projects/reportory/.cursorrules/lambda-curry-forms.md - - ~/projects/reportory/.cursorrules/testing-best-practices.md - -beads: - - id: update-deps - name: Update Dependencies - description: | - Update all dependencies to latest stable versions. - - Run bun update - - Check for any breaking changes - - Ensure everything builds and types check - priority: 1 - agent: 1 - - - id: setup-storybook - name: Setup Storybook with React Router - description: | - Add Storybook with proper React Router mocking. - Reference: ~/projects/reportory/.cursorrules/storybook.md - - Tasks: - - Install Storybook for Vite/React - - Configure mock react-router decorators - - Create example stories for existing components - - Add Storybook scripts to package.json - priority: 2 - agent: 2 - depends_on: [update-deps] - - - id: forms-examples - name: Lambda Curry Forms Integration - description: | - Add form examples using @lambdacurry/forms best practices. - Reference: ~/projects/reportory/.cursorrules/lambda-curry-forms.md - - Tasks: - - Create example form components - - Show validation patterns with zod - - Demonstrate action handlers - - Add Storybook stories for forms - priority: 2 - agent: 3 - depends_on: [update-deps] - - - id: testing-examples - name: Testing Examples - description: | - Add comprehensive testing examples. - Reference: ~/projects/reportory/.cursorrules/testing-best-practices.md - - Tasks: - - Unit test examples for utilities - - Component test examples with react-router mocking - - Integration test patterns - - Ensure vitest config is optimal - priority: 2 - agent: 4 - depends_on: [update-deps] - - - id: ai-rules - name: Setup AI Rules - description: | - Copy and adapt relevant ai-rules from reportory. - - Tasks: - - Copy react-router.md - - Copy storybook.md (if added) - - Copy lambda-curry-forms.md - - Copy testing-best-practices.md - - Create project-specific 00-project-context.md - - Update .cursorrules structure - priority: 3 - agent: 5 - depends_on: [setup-storybook, forms-examples, testing-examples] - - - id: biome-check - name: Biome Config Review - description: | - Review and update Biome configuration. - - Tasks: - - Check biome version (currently 2.2.0) - - Review rules for best practices - - Ensure lint/format scripts work - - Run full lint pass and fix issues - priority: 3 - agent: 1 - depends_on: [ai-rules] - - - id: docs-update - name: Update Documentation - description: | - Update README and documentation. - - Tasks: - - Update README with new features - - Add usage examples - - Document Storybook commands - - Document testing patterns - priority: 4 - agent: 2 - depends_on: [biome-check] - -settings: - maxAgents: 5 - model: claude-sonnet-4-20250514 - autoMerge: false diff --git a/.devagent/workspace/memory/tech-stack.md b/.devagent/workspace/memory/tech-stack.md new file mode 100644 index 0000000..b437c6b --- /dev/null +++ b/.devagent/workspace/memory/tech-stack.md @@ -0,0 +1,101 @@ +# React Router Starter Tech Stack + +## Context + +This repo is a React Router 7 monorepo starter that demonstrates production‑ready patterns for routing, forms, UI components, Storybook, and testing. + +## Core Stack + +### Application Framework & Runtime +- App framework: React Router v7 (framework mode) +- Language: TypeScript 5.9.3 (root), 5.8.3 (apps/packages) +- Runtime: Node.js >= 20.11.0 (engines), Bun 1.2.19 (package manager) +- Package manager: Bun (workspaces enabled) + +### Build & Development Tools +- Monorepo tooling: Turborepo 2.8.1 +- Build tool: Vite 6.4.1 (root), 6.3.3 (todo-app + Storybook) +- Module system: ESM only +- Type generation: React Router auto-generated types in `.react-router/types/` + +### Frontend +- UI framework: React 19.2.4 (root resolution; apps target ^19.1.0) +- Routing: React Router v7 Framework Mode (SSR/SPA hybrid) +- CSS framework: Tailwind CSS v4 toolchain (`tailwindcss`, `@tailwindcss/vite`) +- UI component library: shadcn/ui patterns + Radix UI primitives +- Icons: lucide-react +- Utilities: class-variance-authority, tailwind-merge, clsx + +### Backend (SSR) +- Server framework: React Router v7 server runtime +- API style: Loader/action functions (no separate API layer in starter) +- Authentication: N/A (not included in starter) + +### Data & State Management +- Forms & validation: `@lambdacurry/forms` + `remix-hook-form` + Zod +- State management: React Context + useReducer +- Data fetching: React Router loaders/actions +- Database: None (starter uses in-memory state) + +### Testing & Quality +- Testing framework: Bun test (bun:test) + jsdom 26.1.0 +- Component testing: @testing-library/react 16.1.0 +- Linting: Biome 2.3.11 +- Formatting: Biome 2.3.11 +- Type checking: TypeScript + React Router generated types + +### Documentation & UI Dev +- Storybook: v8 (`@storybook/react-vite`, `@storybook/addon-essentials`) + +### Hosting & Infrastructure +- Application hosting: TBD (not included in starter) +- Database hosting: N/A +- CDN: TBD +- Asset storage: Local/static + +### CI/CD & DevOps +- CI/CD platform: TBD +- Deployment trigger: TBD +- Environments: development, production + +### AI & External Services +- AI/LLM: N/A for this starter +- Analytics: N/A +- Monitoring: N/A +- Email: N/A + +## Product Capabilities + +Key features this stack enables: +- React Router 7 SSR/SPA hybrid app foundation +- End‑to‑end form patterns with validation and accessibility +- Shared UI component library with shadcn/ui conventions +- Component documentation via Storybook +- Testing patterns for routes and components + +## Constraints & Requirements + +Technical or business constraints that shaped these choices: +- Must support React Router v7 framework mode +- Must demonstrate accessible, progressive enhancement form patterns +- Keep dependencies compatible with Bun workspaces +- Provide Storybook and testing examples out of the box + +## Future Integrations (Roadmap) + +Planned additions or changes: +- CI pipeline (lint/typecheck/test) +- Auth + database example (optional starter add‑on) +- Deployment template (Vercel or similar) + +## Decision Rationale (Optional) + +Why key technologies were chosen: +- **React Router v7**: First‑class SSR + data loading patterns +- **Tailwind v4**: CSS‑first theming with modern build pipeline +- **@lambdacurry/forms**: Type‑safe forms with progressive enhancement +- **Storybook**: Shared UI patterns and visual regression readiness + +--- + +**Last Updated**: 2026-02-03 diff --git a/.devagent/workspace/product/mission.md b/.devagent/workspace/product/mission.md new file mode 100644 index 0000000..750b80f --- /dev/null +++ b/.devagent/workspace/product/mission.md @@ -0,0 +1,45 @@ +# React Router Starter Mission + +## Mission +Provide a reliable, opinionated React Router 7 starter that accelerates new app development with proven defaults for routing, forms, UI components, Storybook, and testing. + +## Problem +Teams repeatedly rebuild the same foundation for React Router apps: routing, form patterns, UI primitives, and testing scaffolding. This duplication slows delivery and produces inconsistent quality across projects. + +## Approach +- Ship a reference todo app that demonstrates real patterns, not toy examples. +- Standardize form handling with `@lambdacurry/forms` + Zod for accessibility and progressive enhancement. +- Provide shared UI components aligned with shadcn/ui conventions. +- Include Storybook for visual documentation and component review. +- Make testing patterns explicit with Bun test + Testing Library. +- Make the starter **AI-first** with DevAgent so agents can clone, bootstrap, and run coding loops to build features in one pass. + +## Value Propositions +- Faster project bootstrap with fewer architectural decisions upfront. +- Consistent patterns across teams and apps. +- Reduced regressions through shared testing and Storybook practices. +- Clear guidance for AI agents via centralized AI rules. +- DevAgent workflows enable repeatable, agent-driven delivery with minimal setup. + +## Target Users +- Lambda Curry engineers building React Router apps. +- Teams adopting React Router v7 who want a vetted starter. + +## Scope (V1) +- In scope: React Router v7 setup, Tailwind v4, forms integration, shared UI package, Storybook, testing examples. +- Out of scope: Auth, database, billing, production ops. + +## Principles +- Prefer real, composable examples over exhaustive abstraction. +- Accessibility and progressive enhancement by default. +- Keep the starter lean: add only what a majority of teams need. + +## Success Metrics +- Time‑to‑first‑feature under 1 day for a new app. +- Engineers can scaffold a new route + form + UI component without searching for patterns. +- Storybook and tests run cleanly out of the box. +- Agents can clone the repo and complete a feature loop end‑to‑end without manual setup fixes. + +--- + +**Last Updated**: 2026-02-03 diff --git a/AGENTS.md b/AGENTS.md index 4a1dfa4..6ee9dfc 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,23 +1,7 @@ -# Agent Workflow (React Router Starter) +@ai-rules/.generated-ai-rules/ai-rules-generated-00-project-context.md +@ai-rules/.generated-ai-rules/ai-rules-generated-lambda-curry-forms.md +@ai-rules/.generated-ai-rules/ai-rules-generated-monorepo.md +@ai-rules/.generated-ai-rules/ai-rules-generated-react-router.md +@ai-rules/.generated-ai-rules/ai-rules-generated-ui-components.md -This repo uses **Beads (bd)** for all work tracking and **Ralph** for autonomous execution. Follow these rules whenever you act as an agent. - -## Beads (Required) - -- All work must be tracked in Beads. Do not use markdown TODO lists as a substitute. -- Read task context first: `bd show --json` and `bd comments --json`. -- Update status when you start/finish: `bd update --status in_progress|closed|blocked`. - -## Ralph / Devagent - -- Full Ralph playbook: `.devagent/plugins/ralph/AGENTS.md`. -- Workflows and setup guides: `.devagent/plugins/ralph/workflows/`. -- Use Ralph tasks and labels to route work (see the playbook). - -## AI Rules - -- Cursor rules live in `.cursorrules/`. Start with `00-project-context.mdc` and apply the domain rules (React Router, Storybook, forms, testing, monorepo, UI). - -## Quality Gates - -- Always derive lint/test/typecheck/build commands from `package.json` before running gates. +@ai-rules/.generated-ai-rules/ai-rules-generated-optional.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..6ee9dfc --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,7 @@ +@ai-rules/.generated-ai-rules/ai-rules-generated-00-project-context.md +@ai-rules/.generated-ai-rules/ai-rules-generated-lambda-curry-forms.md +@ai-rules/.generated-ai-rules/ai-rules-generated-monorepo.md +@ai-rules/.generated-ai-rules/ai-rules-generated-react-router.md +@ai-rules/.generated-ai-rules/ai-rules-generated-ui-components.md + +@ai-rules/.generated-ai-rules/ai-rules-generated-optional.md diff --git a/FORMS_INTEGRATION.md b/FORMS_INTEGRATION.md index 4f14d08..9e4f879 100644 --- a/FORMS_INTEGRATION.md +++ b/FORMS_INTEGRATION.md @@ -11,9 +11,9 @@ This document outlines the integration of the `@lambdacurry/forms` library into - `remix-hook-form` - React Router integration - `zod` - Schema validation -### Cursor Rules -- Added `.cursorrules/lambda-curry-forms.mdc` with comprehensive guidelines for using the forms library -- Includes patterns, best practices, and component usage examples +### AI Rules +- Added `ai-rules/lambda-curry-forms.md` with comprehensive guidelines for using the forms library +- Generated outputs in `ai-rules/.generated-ai-rules/` and `.cursor/rules/` are managed by repository automation; update source rules instead of editing generated files directly. ### Components Updated @@ -200,7 +200,7 @@ The forms library integrates seamlessly with: 1. **Install Dependencies:** Run `bun install` to install new packages 2. **Run Development:** Use `bun run dev` to start the development server 3. **Explore Examples:** Navigate through the updated components and new route -4. **Read Cursor Rules:** Review `.cursorrules/lambda-curry-forms.mdc` for detailed guidelines +4. **Read AI Rules:** Review `ai-rules/lambda-curry-forms.md` for detailed guidelines ## 🔗 Resources diff --git a/GEMINI.md b/GEMINI.md new file mode 100644 index 0000000..6ee9dfc --- /dev/null +++ b/GEMINI.md @@ -0,0 +1,7 @@ +@ai-rules/.generated-ai-rules/ai-rules-generated-00-project-context.md +@ai-rules/.generated-ai-rules/ai-rules-generated-lambda-curry-forms.md +@ai-rules/.generated-ai-rules/ai-rules-generated-monorepo.md +@ai-rules/.generated-ai-rules/ai-rules-generated-react-router.md +@ai-rules/.generated-ai-rules/ai-rules-generated-ui-components.md + +@ai-rules/.generated-ai-rules/ai-rules-generated-optional.md diff --git a/ai-rules/.generated-ai-rules/ai-rules-generated-00-project-context.md b/ai-rules/.generated-ai-rules/ai-rules-generated-00-project-context.md new file mode 100644 index 0000000..25d5b5e --- /dev/null +++ b/ai-rules/.generated-ai-rules/ai-rules-generated-00-project-context.md @@ -0,0 +1,52 @@ +# Project Context + +## What This Repo Is + +**react-router-starter** is a monorepo starter for React Router 7 apps with best practices: Storybook, @lambdacurry/forms, Bun test + React Testing Library, and shared AI rules. + +## Structure + +- **apps/todo-app** – Reference app (React Router 7, Vite, Tailwind v4, forms, Storybook, tests). +- **packages/** – Shared packages (e.g. `@todo-starter/ui`, `@todo-starter/utils`) used by apps. +- **ai-rules/** – Source-of-truth AI rules (project context, React Router, Storybook, forms, testing, monorepo, UI). +- **.cursor/rules/** – Generated Cursor rules (do not edit directly). +- **AGENTS.md / CLAUDE.md / GEMINI.md** – Generated agent rules (do not edit directly). + +## Issue Tracking (Beads) + +Beads is required **only** when running Ralph loops or when a task explicitly comes from Beads. For ad-hoc work, you can skip Beads. + +When Beads is in use, follow `.devagent/plugins/ralph/AGENTS.md` and use the CLI: + +```bash +bd ready # Find available work +bd show # View issue details +bd update --status in_progress # Claim work +bd update --status closed # Complete work +bd sync # Sync with git +``` + +## Quality Gates (todo-app) + +From `apps/todo-app/package.json`: + +- **Test:** `bun run test:run` or `bun run test:ci` (Bun test) +- **Lint:** `npm run lint` (Biome) +- **Typecheck:** `npm run typecheck` (tsc) +- **Build:** `npm run build` (react-router build) +- **Storybook:** `npm run storybook` (dev), `npm run build-storybook` (build) + +Run these from `apps/todo-app` or via workspace root scripts if defined. + +## Conventions + +- **Routing:** File-based routes in `app/routes/`; use loaders/actions and route types. +- **Forms:** @lambdacurry/forms + remix-hook-form + Zod; see `ai-rules/lambda-curry-forms.md`. +- **Tests:** Bun test + React Testing Library; use `renderWithRouter` for router-dependent components; see `apps/todo-app/TESTING.md` and `ai-rules/testing-best-practices.md`. +- **Styling:** Tailwind CSS v4; mobile-first; prefer existing UI components. + +## AI Rules Workflow + +- **Edit source rules** in `ai-rules/` +- **Generated outputs** in `.generated-ai-rules/` and `.cursor/rules/` are maintained by repository automation +- **Do not edit generated files directly**; change source rules in `ai-rules/` diff --git a/ai-rules/.generated-ai-rules/ai-rules-generated-lambda-curry-forms.md b/ai-rules/.generated-ai-rules/ai-rules-generated-lambda-curry-forms.md new file mode 100644 index 0000000..b212fbc --- /dev/null +++ b/ai-rules/.generated-ai-rules/ai-rules-generated-lambda-curry-forms.md @@ -0,0 +1,256 @@ +**Summary:** +This document provides essential guidelines for using `@lambdacurry/forms` with `remix-hook-form` and Zod v4. Key benefits include progressive enhancement, type safety, consistent UI, and WCAG 2.1 AA accessibility compliance. Always prefer `remix-hook-form` over other form libraries in Remix applications. + +**Reference Documentation:** https://raw.githubusercontent.com/lambda-curry/forms/refs/heads/main/llms.txt + +## Core Architecture & Setup + +**@lambdacurry/forms** provides form-aware wrapper components that automatically integrate with React Router and Remix Hook Form context, eliminating boilerplate while maintaining full customization. + +### Essential Imports & Setup +```typescript +import { zodResolver } from '@hookform/resolvers/zod'; +import { RemixFormProvider, useRemixForm, getValidatedFormData } from 'remix-hook-form'; +import { z } from 'zod'; +import { useFetcher, type ActionFunctionArgs } from 'react-router'; +import { TextField, Checkbox, RadioGroup, DatePicker, FormError } from '@lambdacurry/forms'; +import { Button } from '@lambdacurry/forms/ui'; +``` + +### Zod Schema Patterns +```typescript +const formSchema = z.object({ + email: z.string().email('Invalid email address'), + password: z.string().min(8, 'Password must be at least 8 characters'), + terms: z.boolean().refine(val => val === true, 'You must accept terms'), +}); + +type FormData = z.infer; +``` + +## Standard Form Implementation Pattern + +### Complete Login Form Example with FormError +```typescript +const LoginForm = () => { + const fetcher = useFetcher<{ + message?: string; + errors?: Record + }>(); + + const methods = useRemixForm({ + resolver: zodResolver(formSchema), + defaultValues: { email: '', password: '' }, + fetcher, + submitConfig: { action: '/login', method: 'post' }, + }); + + const isSubmitting = fetcher.state === 'submitting'; + + return ( + + + + + + + {/* Place FormError before the submit button for critical errors */} + + + + + + ); +}; +``` + +### Server Action Handler with FormError Support +```typescript +export const action = async ({ request }: ActionFunctionArgs) => { + const { data, errors } = await getValidatedFormData( + request, + zodResolver(formSchema) + ); + + if (errors) return { errors }; + + try { + const user = await authenticateUser(data.email, data.password); + return { message: 'Login successful!' }; + } catch (error) { + // Multiple error types - field-level and form-level + return { + errors: { + email: { message: 'Account may be suspended' }, + _form: { message: 'Invalid credentials. Please try again.' } + } + }; + } +}; +``` + +## Available Form Components + +### TextField Component +```typescript + +``` + +### Checkbox Component +```typescript + +``` + +### RadioGroup Component +```typescript +// Pattern 1: Using options prop + + +// Pattern 2: Using RadioGroupItem children + + + + +``` + +### Other Components +```typescript +