BikeControl (SwiftControl)
使用 Zwift Click、Zwift Play、Shimano Di2 或任何藍牙控制器,搭配 MyWhoosh、Rouvy、Zwift 等。iOS、Android、Windows、macOS 均可免費試用。
AI 翻译
尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证正在加载完整 README。 以下为已保存的摘录。
A mobile-first training log (PWA) that your PT programmes through Claude.
Claude reads your history and pushes today's plan into the app; you train
from the Today screen, log sets live, and hit Send to PT when you finish.
Built with Next.js 15 (App Router), TypeScript, Tailwind, Postgres (Neon) +
Drizzle, NextAuth (Google), and a remote MCP server at /api/mcp.
Run these in order in the Neon SQL editor (or psql). They're idempotent.查看完整 README ↗A mobile-first training log (PWA) that your PT programmes through Claude. Claude reads your history and pushes today's plan into the app; you train from the Today screen, log sets live, and hit Send to PT when you finish.
Built with Next.js 15 (App Router), TypeScript, Tailwind, Postgres (Neon) +
Drizzle, NextAuth (Google), and a remote MCP server at /api/mcp.
Claude (PT project) LiftLog MCP (/api/mcp) App
"Heading to the gym" ──► get_athlete_context, get_sessions, get_recovery
Claude drafts Session B, you approve
──► push_plan ──► validate (V1–V10) ──► Today: "Session B · From your PT 16:40" + push
... you train, log sets live ...
Finish ▸ Send to PT
"Review today" ──► get_sessions (planned vs actual, RPE, flags)
──► update_working_weight / add_coach_flag
pnpm install
Run these in order in the Neon SQL editor (or psql). They're idempotent.
supabase/schema.sql — base tablessupabase/migration-001-security.sql, supabase/migration-002-per-set-details.sqlsupabase/seed.sql — exercise librarysupabase/migration-003-liftlog-v2.sql — plans, check-ins, coach flags,
constraints, MCP OAuth + audit, push, integrationssupabase/seed-002-liftlog-v2.sql — injury constraints, load modes,
carriage values, and the machines the programme uses (with slugs Claude
uses as exerciseId)supabase/migration-004-cardio-and-fixes.sql, supabase/migration-005-form-cues.sqlsupabase/seed-003-history.sql — the imported Lift Log historysupabase/migration-006-per-user.sql — athlete profiles (timezone,
targets, rotation) and per-user exercise blocks; hands the seeded
injuries and blocks to the owner. The owner's email is at the top of the
file (and in the seeds): change it if you deploy for someone else.A Neon URL uses Neon's HTTP driver. Any other URL uses node-postgres, so local Postgres works for development.
Create an OAuth client (Web) in Google Cloud Console with redirect URI
<APP_URL>/api/auth/callback/google.
cp .env.local.example .env.local
Every variable is documented in .env.local.example. You need at least
DATABASE_URL, AUTH_SECRET, AUTH_GOOGLE_ID, AUTH_GOOGLE_SECRET and
APP_URL. Set ALLOWED_EMAILS to your Google address: it locks sign-in
and the MCP connector to you.
Every athlete's data is their own: sessions, plans, check-ins, coach flags,
injuries, blocked exercises, timezone, nutrition targets and rotation. To let
someone in, add their Google address to ALLOWED_EMAILS and set
OWNER_EMAILS to yours, so only you can recalibrate the shared machines in
the exercise library. On first visit their timezone comes from their browser;
they set targets, rotation and injuries in Settings › Your training and
Settings › Injuries & limits, and connect their own Claude with the same
connector URL.
pnpm dev # app
pnpm test # domain rule tests (vitest)
pnpm typecheck
The MCP server is a remote Streamable HTTP server at <APP_URL>/api/mcp
(stateless JSON responses, so it runs on Vercel serverless). Auth is OAuth 2.1
per the MCP authorization spec: the app is its own authorization server
(dynamic client registration, PKCE S256, rotating refresh tokens), and you
sign in with the same Google account you use in the app.
<APP_URL>/api/mcp, then sign in and approve.claude mcp add --transport http liftlog <APP_URL>/api/mcpMCP_API_KEY +
MCP_API_KEY_USER, then
claude mcp add --transport http liftlog <APP_URL>/api/mcp --header "Authorization: Bearer $MCP_API_KEY"Settings › Connections in the app shows connected clients, the last tool call, and an audit log of every write Claude made. You can disconnect from there too.
| Tools | |
|---|---|
| Read | get_athlete_context, get_sessions, get_recovery, get_exercise_history, search_exercises |
| Write | push_plan, update_plan, log_session, update_working_weight, add_coach_flag, resolve_coach_flag, upsert_check_in |
| Resources | liftlog://log/latest.md, liftlog://session/{date}.md |
| Prompt | programme_next_session |
There are no delete tools. Deletes happen in the app only.
src/domain/validation.ts)push_plan runs these server-side. Errors block the write; warnings
are returned to Claude and shown on Today.
| # | Rule | Level |
|---|---|---|
| V1 | Exercise is NO or matches an injury constraint's blocked pattern | Error unless overrideReason |
| V2 | Chest press and triceps isolation in the same pairGroup | Error |
| V3 | Working openKg > 15% under last session's top set | Warning |
| V4 | Load increase while sleep is under the recoveryGate | Warning |
| V5 | Increment off-rule (upper +2.5, lower +5, accessories reps first) | Warning |
| V6 | Compound rest under 150 s | Warning |
| V7 | Per-side machine with no carriage weight | Warning |
| V8 | Counterweight machine with a higher number sold as progress | Error |
| V9 | No log history (calibration weight) | Warning |
| V10 | A plan for that date + type is already in progress | Error |
update_working_weight rejects jumps of more than 2 increments without
force + reason (the 50 → 90 kg squat).
The Today check-in (sleep, protein, water) can be typed in the app, told to
Claude (upsert_check_in), or synced. A value you enter yourself is never
overwritten by a sync.
offline read:sleep read:recovery and redirect URI
<APP_URL>/api/integrations/whoop/callback.WHOOP_CLIENT_ID and WHOOP_CLIENT_SECRET.Sleep is time asleep (in bed − awake − no data), dated by the morning you
woke up. It refreshes in the background every 30 minutes while you use the
app, and whenever Claude calls get_recovery.
MyFitnessPal has no public API, and Apple Health has no web API (HealthKit only runs on the iPhone). The bridge runs from your phone:
POST <APP_URL>/api/ingest/health, header Authorization: Bearer <token>,
JSON body { "proteinG": …, "waterMl": … }.The endpoint also accepts waterL, sleepMin/sleepH, an explicit date,
or { "days": [...] } to backfill.
Generate keys with npx web-push generate-vapid-keys, set the three VAPID
variables, then turn on notifications in Settings. On iPhone, add the app to
the Home Screen first.
src/
domain/ # Pure business rules. The app UI and MCP both call these.
load.ts # true-load maths (plates + carriage), increments, jump guard
validation.ts # V1–V10
progression.ts # double progression ("1 of 2"), live underload nudge
recovery.ts, rotation.ts, flags.ts, export.ts (Lift Log markdown)
__tests__/ # cases from the real log
server/ # DB-backed services (server-only)
plans.ts, sessions.ts, history.ts, checkins.ts, flags.ts, athlete.ts
mcp/server.ts # MCP tools, resources, prompt
oauth.ts # OAuth 2.1 authorization server
integrations/ # whoop.ts, apple-health.ts
push.ts, audit.ts
app/
(app)/today # Today: check-in, next session ("From your PT"), coach flags
(app)/session/[id] # Live session: rest timer, sets, RPE, load sheet, swap
(app)/session/[id]/finish # Finish + Send to PT / Obsidian / copy
(app)/progress[/id] # Exercise progress + next bump
(app)/form/[cue] # Animated form cues
(app)/history, exercises, log, settings
api/mcp # MCP endpoint
api/oauth/*, oauth/authorize # OAuth server + consent screen
api/integrations/whoop/*, api/ingest/health
worker/index.js # Service-worker push handler (bundled by next-pwa)
supabase/ # SQL schema, migrations, seeds