AgentConnect.jsx rewritten:
- Option 1: Built-in AI Coach — lists all 8 providers with free tier
badges and 'Get key' links, step-by-step setup instructions
- Option 2: External AI Agent (MCP) — Claude Desktop (with Windows
path), Claude Code CLI, Cursor, Windsurf/other
- Page renamed from 'Connect Your AI Agent' to 'Connect AI'
Settings.jsx:
- Added Help & Support section: Report a Bug (GitHub Issues),
Ask a Question (GitHub Discussions), Star on GitHub
React hooks must be called unconditionally on every render. The
checklist useState was at line 89, after 'if (loading) return' at
line 70 — hooks violation crashed the entire React app (blank screen).
Moved to line 38 with the other state declarations.
Timezone:
- Add diligence/utils/dates.py with today_for_user(), now_for_user(), day_start_utc()
- Replace all 20 date.today() calls across 10 files with timezone-aware helpers
- Remove hardcoded Asia/Bangkok offset hack in nutrition router
- Change defaults from Asia/Bangkok to UTC in user model, nutrition model, config
- Add timezone field to RegisterRequest schema
- Set user.timezone from browser detection during registration
- Frontend sends Intl.DateTimeFormat().resolvedOptions().timeZone on register
Branding:
- Login page: Fitness Rewards -> Diligence, updated tagline and emoji
- index.html title: Fitness Rewards -> Diligence
Frontend rebuild:
- Fresh Vite build with all changes (index-CsKoBN0D.js)
- Nav bar, timezone detection, and branding all verified in built bundle
- New AgentConnect.jsx page with MCP URL, token, setup instructions
- Claude Desktop config snippet with copy button
- Claude Code CLI command with copy button
- Agent capabilities overview
- Added to bottom nav bar (6th item, plug icon)
- Backend /api/agent/config endpoint returns deployment-aware MCP details
- Nav padding adjusted for 6 items
- Frontend rebuilt with new page
Previous commit wiped App.jsx due to emoji encoding error in the
patch script. Restored from Stream A commit (c075eb9), then applied
ChatCoach changes using a file-based Python script to handle unicode.
- import ChatCoach from './pages/ChatCoach' (line 21)
- NavLink /chat with brain emoji + 'Coach' label (line 95)
- Route /chat -> ProtectedRoute -> ChatCoach (line 125)
Frontend:
- ChatCoach.jsx: streaming chat UI with SSE, provider indicator, suggestion
chips, 'no AI configured' state with setup link
- App.jsx: import + /chat route + nav bar (More → Coach with brain emoji)
- api.js: getAIStatus() method
Documentation:
- README.md: 'Built-in AI Coach' section with 8-provider table, external
agent config snippets for Claude Desktop, Claude Code, Cursor, Windsurf,
and COROS multi-MCP pattern
- AGENT_GUIDE.md: multi-device integration, Strava AI/ML warning,
provider-agnostic statement
Nav bar: Home | Log | Keto | Programs | Coach
Settings still reachable at /settings (linked from Coach setup prompt)
SEC-16: Add frontend ports mapping (80:80) to docker-compose.yml
UI-01: Add routes for Welcome, SettingsIntegrations, MealPlan in App.jsx
SEC-01: Remove traceback leak from auth error responses
SEC-02: Fix require_admin to use is_admin column (was undefined ADMIN_USERNAME)
SEC-03: Add API_TOKEN auth for MCP connector -> backend communication
SEC-04: OAuth state now uses signed JWT tokens (was raw user UUID)
OS-01: First registered user gets admin immediately during registration
10 files changed, 97 insertions(+), 25 deletions(-)
Two bugs fixed:
1. Backend: list_programs endpoint did not include catalog_id in its
response, so the frontend filter (p.catalog_id) always matched zero
programs. The previous LogActivity card never rendered because
loadActiveProgram() found no active program with a catalog link.
Now also exposes current_week.
2. UX restructure: instead of showing the program workout card at the
top of /log unconditionally, the card now appears AFTER the user
selects the 'Workout' category — matching the natural flow:
Log -> Workout -> see today's program workout option.
The Workout category now reveals:
- Active program banner (clickable, shows program name + week,
navigates to ProgramDetail on tap)
- Today's workout card with exercise preview and one-tap 75 pts
- Other uncompleted workouts in the current week (up to 3)
- 'Or log freeform' divider before the existing form
When all workouts in the current week are done, a green completion
banner appears instead.
Refactored the workout card into a ProgramWorkoutCard component since
it's now used for both today's featured workout and weekly upcoming.
Dashboard:
- The program bar at the top of the home page is now clickable and
navigates to the program detail page. Backend get_today_status now
returns program_id alongside name/day/total_days.
LogActivity:
- On mount, fetches the user's active catalog program and its today's
workout. If there's an uncompleted non-rest workout for today, a
featured 'Today's Program Workout' card appears at the top with an
exercise preview and a one-tap '✓ Complete — 75 pts' button.
- Tapping Complete fires the same /workout/{id}/complete endpoint as
ProgramDetail, surfaces weekly/completion bonuses in the success
message, and returns to the Dashboard.
- The standard category grid below is now relabeled 'Or log something
else' when a program workout is available.
CatalogDetail, ProgramDetail, ProgramSearch and SupportAdmin all use
inline-styled root divs instead of the .page CSS class, so they were
missing the padding-bottom: 96px that clears the fixed bottom nav bar.
Last button/section was hidden behind the nav.
Adds paddingBottom: 96px to each page's root div. Support.jsx has its
own full-height chat layout and is intentionally left as-is.
The 'View Details' button on ProgramSearch navigated to /catalog/:id
but no route or page existed. Now creates a proper detail view that
fetches via getCatalogProgram, shows program metadata, weeks/workouts,
progression rules, and an Adopt button that redirects to the user's
new program tracking page on success.