---
phase: 16-frontend-scaffold
plan: 04
type: execute
wave: 3
depends_on: ["16-03"]
files_modified: [packages/web/package.json, packages/web/src/App.tsx, packages/web/src/routeTree.gen.ts, packages/web/src/router.tsx, packages/web/src/routes/__root.tsx, packages/web/src/routes/index.tsx, packages/web/src/routes/initiatives/index.tsx, packages/web/src/routes/initiatives/$id.tsx, packages/web/src/routes/inbox.tsx, packages/web/src/layouts/AppLayout.tsx, packages/web/src/components/ui/button.tsx, packages/web/src/components/ui/badge.tsx, packages/web/src/components/ui/card.tsx, packages/web/src/components/ui/dropdown-menu.tsx]
autonomous: true
---

<objective>
Set up TanStack Router with page stubs and the app shell layout (navigation bar) matching the wireframe header.

Purpose: Establish the navigation structure and persistent layout that all subsequent screens plug into. Phase 17-19 will implement the actual page content; this plan creates the skeleton they slot into. TanStack Router provides fully type-safe routing with validated params and search params.
Output: Working router with 3 page stubs (Dashboard, Initiative Detail, Inbox) and persistent nav header.
</objective>

<execution_context>
@~/.claude/get-shit-done/workflows/execute-plan.md
@~/.claude/get-shit-done/templates/summary.md
</execution_context>

<context>
@.planning/PROJECT.md
@.planning/ROADMAP.md
@.planning/STATE.md

# Wireframe navigation structure
@docs/wireframes/initiative-dashboard.md

# tRPC client from Plan 03
@packages/web/src/lib/trpc.ts
@packages/web/src/main.tsx
</context>

<tasks>

<task type="auto">
  <name>Task 1: Install TanStack Router and add shadcn/ui base components</name>
  <files>packages/web/package.json, packages/web/src/components/ui/button.tsx, packages/web/src/components/ui/badge.tsx, packages/web/src/components/ui/card.tsx, packages/web/src/components/ui/dropdown-menu.tsx</files>
  <action>
1. Install in packages/web:
   - Dependencies: `@tanstack/react-router`
   - Dev dependencies: `@tanstack/router-plugin` (Vite plugin for route generation), `@radix-ui/react-dropdown-menu`, `@radix-ui/react-slot` (shadcn/ui primitives)

2. Update `packages/web/vite.config.ts` to add the TanStack Router Vite plugin:
   ```typescript
   import { TanStackRouterVite } from '@tanstack/router-plugin/vite'

   export default defineConfig({
     plugins: [
       TanStackRouterVite(),
       react(),
     ],
     // ... existing proxy config
   })
   ```
   The TanStack Router plugin must come BEFORE the react plugin. It auto-generates the route tree from the file-based routes in `src/routes/`.

3. Add the 4 most-needed shadcn/ui components. Use `npx shadcn@latest add button badge card dropdown-menu` from packages/web directory. If the CLI doesn't work with this directory structure, manually create the component files following the shadcn/ui source (available at ui.shadcn.com).

   The components go in `packages/web/src/components/ui/`:
   - `button.tsx` — needed by every page (View, Spawn, Queue, etc.)
   - `badge.tsx` — needed for StatusBadge component
   - `card.tsx` — needed for InitiativeCard
   - `dropdown-menu.tsx` — needed for ActionMenu and SpawnArchitectDropdown

   These are the foundation components. Additional shadcn components will be added in later phases as needed.

4. Run `npm install` from root.
  </action>
  <verify>
cd packages/web && npx vite build succeeds.
Component files exist in packages/web/src/components/ui/.
  </verify>
  <done>TanStack Router and shadcn/ui base components installed.</done>
</task>

<task type="auto">
  <name>Task 2: Create file-based routes, app shell layout, and page stubs</name>
  <files>packages/web/src/App.tsx, packages/web/src/router.tsx, packages/web/src/routes/__root.tsx, packages/web/src/routes/index.tsx, packages/web/src/routes/initiatives/index.tsx, packages/web/src/routes/initiatives/$id.tsx, packages/web/src/routes/inbox.tsx, packages/web/src/layouts/AppLayout.tsx</files>
  <action>
1. Create file-based route structure in `packages/web/src/routes/`:

   TanStack Router uses file-based routing. The Vite plugin generates `routeTree.gen.ts` automatically from the file structure:

   - `__root.tsx` — Root layout route (wraps all pages with AppLayout)
   - `index.tsx` — `/` route, redirects to `/initiatives`
   - `initiatives/index.tsx` — `/initiatives` DashboardPage
   - `initiatives/$id.tsx` — `/initiatives/$id` InitiativeDetailPage (type-safe param)
   - `inbox.tsx` — `/inbox` InboxPage

2. Create `packages/web/src/routes/__root.tsx`:
   The root route wraps all pages with the AppLayout shell:
   ```typescript
   import { createRootRoute, Outlet } from '@tanstack/react-router'
   import { AppLayout } from '../layouts/AppLayout'

   export const Route = createRootRoute({
     component: () => (
       <AppLayout>
         <Outlet />
       </AppLayout>
     ),
     notFoundComponent: () => (
       <div className="p-8 text-center">
         <h1 className="text-2xl font-bold">Page not found</h1>
         <p className="text-muted-foreground mt-2">The page you're looking for doesn't exist.</p>
       </div>
     ),
   })
   ```

3. Create `packages/web/src/routes/index.tsx`:
   Redirect root `/` to `/initiatives`:
   ```typescript
   import { createFileRoute, redirect } from '@tanstack/react-router'

   export const Route = createFileRoute('/')({
     beforeLoad: () => {
       throw redirect({ to: '/initiatives' })
     },
   })
   ```

4. Create `packages/web/src/routes/initiatives/index.tsx`:
   Dashboard stub:
   ```typescript
   import { createFileRoute } from '@tanstack/react-router'
   import { trpc } from '../../lib/trpc'

   export const Route = createFileRoute('/initiatives/')({
     component: DashboardPage,
   })

   function DashboardPage() {
     const health = trpc.health.useQuery()
     return (
       <div>
         <h1 className="text-2xl font-bold">Initiative Dashboard</h1>
         <p className="text-muted-foreground mt-2">
           Server: {health.data?.status ?? 'connecting...'}
         </p>
         <p className="text-muted-foreground mt-1">Content coming in Phase 17</p>
       </div>
     )
   }
   ```

5. Create `packages/web/src/routes/initiatives/$id.tsx`:
   Detail stub with type-safe params:
   ```typescript
   import { createFileRoute } from '@tanstack/react-router'

   export const Route = createFileRoute('/initiatives/$id')({
     component: InitiativeDetailPage,
   })

   function InitiativeDetailPage() {
     const { id } = Route.useParams()
     return (
       <div>
         <h1 className="text-2xl font-bold">Initiative Detail</h1>
         <p className="text-muted-foreground mt-2">Initiative ID: {id}</p>
         <p className="text-muted-foreground mt-1">Content coming in Phase 18</p>
       </div>
     )
   }
   ```

6. Create `packages/web/src/routes/inbox.tsx`:
   Inbox stub:
   ```typescript
   import { createFileRoute } from '@tanstack/react-router'

   export const Route = createFileRoute('/inbox')({
     component: InboxPage,
   })

   function InboxPage() {
     return (
       <div>
         <h1 className="text-2xl font-bold">Agent Inbox</h1>
         <p className="text-muted-foreground mt-1">Content coming in Phase 19</p>
       </div>
     )
   }
   ```

7. Create `packages/web/src/layouts/AppLayout.tsx`:
   The persistent navigation shell from the wireframe header:
   ```
   CODEWALK DISTRICT                                    [+ New Initiative]
   Initiatives    Agents    Tasks    Settings
   ```
   Implementation:
   - Header with app title "Codewalkers" on the left
   - "New Initiative" button on the right (placeholder handler for now)
   - Navigation tabs: Initiatives (links to /initiatives), Inbox (links to /inbox)
   - Skip "Agents", "Tasks", "Settings" tabs for now — not in Phase 16-19 scope. Include them as disabled/greyed out.
   - Use `Link` from `@tanstack/react-router` for navigation links
   - Active nav item highlighted using `activeProps` or `activeOptions` on Link
   - Children rendered via props.children (passed from root route Outlet)
   - Minimal Tailwind styling: fixed header, content below with padding

8. Create `packages/web/src/router.tsx`:
   ```typescript
   import { createRouter } from '@tanstack/react-router'
   import { routeTree } from './routeTree.gen'

   export const router = createRouter({ routeTree })

   declare module '@tanstack/react-router' {
     interface Register {
       router: typeof router
     }
   }
   ```

9. Update `packages/web/src/App.tsx`:
   Replace the temporary health-check component with the router:
   ```typescript
   import { RouterProvider } from '@tanstack/react-router'
   import { router } from './router'

   function App() {
     return <RouterProvider router={router} />
   }

   export default App
   ```

10. Run `cd packages/web && npx vite build` — the TanStack Router plugin will generate `routeTree.gen.ts` during the build. The generated file should be committed to git (it's a type-safe route manifest).

Keep it simple. These are stubs — the real UI comes in Phases 17-19. The goal is a working navigation skeleton with the right route structure.
  </action>
  <verify>
cd packages/web && npx vite build succeeds.
routeTree.gen.ts generated with routes: /, /initiatives, /initiatives/$id, /inbox.
AppLayout renders header and child content.
  </verify>
  <done>TanStack Router configured with file-based routes. App shell layout renders nav header. Page stubs in place for Phases 17-19 to fill in.</done>
</task>

</tasks>

<verification>
Before declaring plan complete:
- [ ] `cd packages/web && npx vite build` succeeds
- [ ] Route `/initiatives` renders DashboardPage stub
- [ ] Route `/initiatives/some-id` renders InitiativeDetailPage stub with type-safe param
- [ ] Route `/inbox` renders InboxPage stub
- [ ] AppLayout nav header present on all pages
- [ ] Active nav item highlighted
- [ ] routeTree.gen.ts generated
</verification>

<success_criteria>

- TanStack Router configured with file-based routes
- Type-safe params on /initiatives/$id route
- AppLayout shell matches wireframe header structure
- Page stubs ready for Phase 17-19 implementation
- Navigation between pages works
- Build passes cleanly
  </success_criteria>

<output>
After completion, create `.planning/phases/16-frontend-scaffold/16-04-SUMMARY.md`
</output>
