Commit Graph

38 Commits

Author SHA1 Message Date
Lukas May
c66d7ecfb2 fix(21-05): move PlanTasksFetcher onTasks callback to useEffect
Replace the setState-during-render pattern in PlanTasksFetcher with a
useEffect hook. The onTasks callback was being called directly in the
render body when tasksQuery.isSuccess was true, which could cause
infinite re-render loops when the parent state update triggered a
re-render. Now data flows through useEffect with proper dependencies.
2026-02-05 09:05:07 +01:00
Lukas May
1530d7ab15 feat(21-05): enable route-based code splitting via TanStack Router autoCodeSplitting
Enable autoCodeSplitting in TanStackRouterVite plugin to split the monolithic
582 KB bundle into route-level chunks. Main vendor chunk drops to 454 KB with
initiative detail (~13 KB), inbox (~13 KB), and dashboard (~65 KB) as separate
lazy-loaded chunks. Eliminates the Vite 500 KB chunk size warning.
2026-02-05 09:04:25 +01:00
Lukas May
4ae85da3f6 feat(21-04): add subscription error handling with toast feedback on all pages
- Replace silent onError: () => {} with sticky toast notification
- Toast uses fixed ID 'sub-error' to prevent duplicate notifications
- duration: Infinity keeps toast visible until dismissed
- Applied to initiatives/index.tsx, initiatives/$id.tsx, inbox.tsx
2026-02-05 09:04:17 +01:00
Lukas May
5efb4d4e8b feat(21-01): wire toast notifications into all mutation flows
- SpawnArchitectDropdown: toast.success on spawn, toast.error on failure
- ActionMenu: toast.success on archive, toast.error on failure
- CreateInitiativeDialog: toast.success on creation
- Inbox: toast.success/error for resumeAgent and respondToMessage mutations
- Replace all console.error-only mutation error handling with user-visible toasts
2026-02-05 09:01:45 +01:00
Lukas May
a6c2864b74 feat(21-02): add skeleton loading states to initiative detail page
Replace plain "Loading initiative..." and "Loading phases..." text with
structured skeleton placeholders matching the page layout: header with
back arrow/title/badge, two-column grid with phase accordions and
sidebar panels.
2026-02-05 09:01:22 +01:00
Lukas May
1e1aadaece feat(21-03): fix mobile responsive layout for inbox detail panel
- Hide inbox list on mobile when agent selected (drill-down pattern)
- Add "Back to list" button visible only on mobile (lg:hidden)
- Clicking back clears selection and returns to list view
2026-02-05 08:59:39 +01:00
Lukas May
d323e1ea8e feat(21-01): add ErrorBoundary, Sonner toast provider, and 404 navigation
- Create ErrorBoundary class component with recovery UI (reload button)
- Create Sonner Toaster wrapper (bottom-right, richColors)
- Wire ErrorBoundary around Outlet in root route to catch render errors
- Add Toaster as sibling to AppLayout in root route
- Update notFoundComponent with Back to Dashboard link button
2026-02-05 08:57:30 +01:00
Lukas May
c52c6f170f feat(21-03): add cross-screen navigation links
- Remove disabled nav stubs (Agents, Tasks, Settings) from AppLayout
- Make TaskRow agent names clickable links to inbox page
- Add task ID link and "View in context" link in inbox detail panel
2026-02-05 08:57:07 +01:00
Lukas May
11fa5f4be9 feat(21-02): add Skeleton component and skeleton loading states for dashboard + inbox
Create reusable Skeleton component with animate-pulse styling. Replace
plain "Loading..." text with structured skeleton placeholders matching
card layouts in InitiativeList and inbox page.
2026-02-05 08:56:35 +01:00
Lukas May
170ac55afd feat(20-02): wire SSE subscription hooks into dashboard, detail, and inbox pages
Add useSubscription hooks to all three UI pages that invalidate React
Query caches on domain events:
- Dashboard: onTaskUpdate invalidates listInitiatives + listPhases
- Detail: onTaskUpdate invalidates phases/tasks/plans, onAgentUpdate
  invalidates listAgents
- Inbox: onAgentUpdate invalidates listWaitingAgents + listMessages

Subscription failures are silent (onError: () => {}) so pages degrade
gracefully to manual refresh when the backend is not running.
2026-02-04 22:21:44 +01:00
Lukas May
eaf3f10722 feat(20-02): add splitLink to route subscriptions to SSE httpSubscriptionLink
Replace single httpBatchLink with splitLink that routes subscription
operations to httpSubscriptionLink (SSE) while keeping queries/mutations
on httpBatchLink. No new packages needed — both exports are part of
@trpc/client v11.
2026-02-04 22:20:16 +01:00
Lukas May
3cac453364 feat(19-04): wire inbox page with data fetching, detail panel, and answer submission
Replaces stub inbox page with full implementation connecting InboxList
and QuestionForm components to tRPC backend. Two-column layout with
agent list on left and detail panel on right. Handles answer submission
via resumeAgent mutation, notification dismissal via respondToMessage,
and loading/error states following patterns from initiative detail page.
2026-02-04 21:55:42 +01:00
Lukas May
648f9db230 feat(19-03): create QuestionForm component
- Renders mixed question types from questions array
- Submit disabled until all questions answered
- onSubmit called with Record<string, string> mapping questionId to answer
2026-02-04 21:52:08 +01:00
Lukas May
bf3521e3dd feat(19-02): create InboxList component with filter/sort controls
InboxList joins agents with their latest messages, provides filter
(all/waiting/completed) and sort (newest/oldest) controls, renders
MessageCard instances, and shows empty state when no messages match.
2026-02-04 21:52:01 +01:00
Lukas May
f73b85062d feat(19-03): create OptionGroup and FreeTextInput components
- OptionGroup renders radio or checkbox based on multiSelect prop
- "Other" field auto-selects when user types into it
- FreeTextInput renders Input or Textarea based on multiline prop
2026-02-04 21:51:40 +01:00
Lukas May
6450e4072a feat(19-02): create MessageCard component for agent inbox
MessageCard displays agent name with status, message preview (truncated
to 80 chars), relative timestamp, and response indicator (filled/empty
circle). Uses shadcn Card base with selected state highlighting.
2026-02-04 21:51:24 +01:00
Lukas May
1e26bfadbd feat(18-04): wire Initiative Detail page with data fetching and all components
Replace placeholder with full initiative detail page: tRPC data fetching
(getInitiative, listPhases, listPlans, listTasks), PhaseWithTasks helper
component pattern for stable hooks, two-column layout with phases on left
and progress/decisions on right, TaskDetailModal with selectedTask state,
queue actions for phases and tasks, loading/error states.
2026-02-04 21:37:41 +01:00
Lukas May
92d4d36421 feat(18-02): create PhaseAccordion component
Expandable/collapsible phase container with chevron toggle, phase
number + name header, task count (completed/total), StatusBadge,
phase-level DependencyIndicator, and TaskRow list when expanded.
2026-02-04 21:33:20 +01:00
Lukas May
5b17b7a93b feat(18-03): create TaskDetailModal component for initiative detail
Controlled dialog showing full task metadata, dependencies, dependents,
and action buttons (Queue Task / Stop Task) with proper enable/disable
logic based on task status and dependency completion.
2026-02-04 21:33:18 +01:00
Lukas May
4becfe8452 feat(18-02): create TaskRow component
Renders a single task row with Unicode tree connectors (├── / └──),
StatusBadge, inline agent name, and DependencyIndicator for blocked
tasks. Entire row is clickable with hover feedback.
2026-02-04 21:32:56 +01:00
Lukas May
3baba49edd feat(18-03): create DecisionList component for initiative detail
Collapsible list of key decisions with expand/collapse per item and
show more/less toggle when exceeding maxVisible threshold. Renders
in a Card with empty-state placeholder.
2026-02-04 21:32:50 +01:00
Lukas May
8cfc197378 feat(18-01): create ProgressPanel component
- Card with Progress heading using CardHeader/CardContent pattern
- Reuses existing ProgressBar for task completion percentage
- Displays phase and task completion counts
- Handles 0/0 gracefully via ProgressBar's built-in guard
2026-02-04 21:32:46 +01:00
Lukas May
a00b7b56b3 feat(18-02): create DependencyIndicator component
Pure presentational component that renders blocked-by annotations
with ^ prefix in amber text. Returns null when blockedBy is empty.
2026-02-04 21:32:35 +01:00
Lukas May
62409a6302 feat(18-01): create InitiativeHeader component
- Back button with ChevronLeft icon for dashboard navigation
- Card displaying initiative name, status badge, and dates
- Disabled Actions placeholder button for future Plan 04 work
- Pure presentational component receiving props
2026-02-04 21:32:28 +01:00
Lukas May
cc533c81f7 refactor(17-04): remove placeholder New Initiative button from AppLayout header
The dashboard page now owns the create action via its own header button
and empty state CTA. This keeps AppLayout generic — other pages like
Inbox shouldn't show initiative-specific actions.
2026-02-04 21:08:47 +01:00
Lukas May
24bfcfa421 feat(17-04): wire initiative dashboard with filter, list, and create dialog
Replace placeholder DashboardPage with fully functional initiative dashboard:
- Page header with title, status filter dropdown, and New Initiative button
- InitiativeList with statusFilter prop for backend-driven filtering
- CreateInitiativeDialog controlled by local state
- Navigation to /initiatives/$id via TanStack Router useNavigate
- All card callbacks wired (view, spawn architect, delete placeholder)
2026-02-04 21:08:20 +01:00
Lukas May
895c96435c feat(17-02): create InitiativeList component
- Fetches initiatives via trpc.listInitiatives with optional status filter
- Handles loading, error, empty, and populated states
- Empty state shows "No initiatives yet" with CTA button
- Error state shows message with retry button
- Renders vertical stack of InitiativeCards with space-y-3 gap
- Fix: SerializedInitiative type for tRPC Date→string serialization
2026-02-04 21:04:43 +01:00
Lukas May
f6caa5df1a feat(17-03): add SpawnArchitectDropdown and ActionMenu components
- SpawnArchitectDropdown: discuss/breakdown modes via tRPC mutations
- Brief success state on button text after spawn
- ActionMenu: archive with browser confirm, disabled edit/duplicate/delete
- No deleteInitiative tRPC procedure exists, so delete is placeholder
- Both components invalidate listInitiatives on success
2026-02-04 21:04:42 +01:00
Lukas May
e5acb9f214 feat(17-03): create CreateInitiativeDialog with shadcn primitives
- Install shadcn Dialog, Input, Label, Textarea components
- Move from @/ literal dir to src/components/ui/ (known shadcn CLI issue)
- CreateInitiativeDialog: controlled dialog with name/description fields
- tRPC createInitiative mutation with loading/error states
- Form resets on open, validates name non-empty
2026-02-04 21:04:05 +01:00
Lukas May
ec93835ae5 feat(17-02): create InitiativeCard component
- Renders initiative name, StatusBadge, ProgressBar, and phase count
- Fetches phase stats per-card via trpc.listPhases (self-contained)
- Spawn Architect dropdown with discuss/breakdown modes
- More actions menu with edit/duplicate/archive/delete
- Responsive: stacks vertically on mobile, hides phase count text
- Card clickable with stopPropagation on action buttons
2026-02-04 21:03:44 +01:00
Lukas May
ff60ce08bc feat(17-01): create ProgressBar component
- Percentage-based horizontal bar with completed/total props
- Gray track (bg-muted), blue fill for partial, green fill for 100%
- Text label showing percentage
- Handles 0/0 total gracefully (empty bar)
2026-02-04 21:00:40 +01:00
Lukas May
22873a0ad9 feat(17-01): create StatusBadge component
- Colored badges for initiative statuses (active, completed, archived)
- Colored badges for phase statuses (pending, in_progress, completed, blocked)
- Unknown statuses default to gray
- Display text uppercase with underscores replaced by spaces
2026-02-04 21:00:23 +01:00
Lukas May
6d2920d60f feat(16-04): add TanStack Router file-based routes and app shell layout
Create route structure with __root, index (redirect to /initiatives),
initiatives/index (dashboard stub), initiatives/$id (detail stub with
type-safe params), and inbox (stub). Add AppLayout with persistent nav
header matching wireframe: title, New Initiative button, navigation tabs
with active highlighting. Disabled tabs for Agents/Tasks/Settings (out
of scope). Replace temporary health-check App with RouterProvider.
Route tree auto-generated by TanStack Router Vite plugin.
2026-02-04 20:38:30 +01:00
Lukas May
64d751d203 feat(16-04): install TanStack Router and add shadcn/ui base components
Add @tanstack/react-router, @tanstack/router-plugin (Vite plugin for
file-based route generation), and Radix UI primitives. Configure
TanStackRouterVite plugin before React plugin in vite config. Add four
foundational shadcn/ui components: button, badge, card, dropdown-menu.
2026-02-04 20:37:28 +01:00
Lukas May
0d5645f9c8 feat(16-03): wire tRPC React Query client with providers
Create tRPC client with httpBatchLink targeting /trpc (Vite proxy).
Wrap app in trpc.Provider and QueryClientProvider with sensible
defaults. Add health check query to App.tsx for connection
verification. Add vite-env.d.ts for CSS module types. Remove
unused Plan import from backend router.
2026-02-04 18:07:15 +01:00
Lukas May
603d90850b feat(16-03): install tRPC React Query dependencies
Add @trpc/client, @trpc/react-query, @tanstack/react-query to web
package. Link @codewalk-district/shared as workspace dependency.
Add project reference to shared in tsconfig.app.json.
2026-02-04 18:03:44 +01:00
Lukas May
bb468e00f0 feat(16-01): configure Tailwind CSS and shadcn/ui
- Tailwind CSS v3 with postcss and autoprefixer
- shadcn/ui components.json and cn() utility
- Path alias @/ -> ./src/ in vite.config.ts and tsconfig.app.json
- CSS custom properties for shadcn theming (light/dark)
- tailwindcss-animate and @tailwindcss/typography plugins
- App.tsx uses cn() with Tailwind classes to verify integration
2026-02-04 18:00:51 +01:00
Lukas May
99348e0650 feat(16-01): create Vite + React + TypeScript project
- packages/web/ with Vite dev server, React 19, TypeScript
- Server proxy /trpc -> http://127.0.0.1:3847 for CORS-free dev
- Root npm workspaces configured (packages/*)
- dev:web script for workspace dev server
2026-02-04 17:10:15 +01:00