Strautomator
Strava 활동을 자동화해 주는 Strautomator는 IFTTT와 비슷하지만 Strava 전용이다
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기A strength-training app. Programs are authored in git; logged sets sync to SQLite.
저장소 README에서 가져옴
README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
A strength-training app. Programs are authored in git; logged sets sync to SQLite.
Named for how you climb terrain too steep to take head-on — obliquely, in structured legs, each one setting up the next. Which is what a training plan is.README 전문 보기 ↗A strength-training app. Programs are authored in git; logged sets sync to SQLite.
Named for how you climb terrain too steep to take head-on — obliquely, in structured legs, each one setting up the next. Which is what a training plan is.
The organizing principle: every kind of data lives in the substrate that matches how it changes. Training programs are documents — they get revised deliberately, and each revision has a reason worth keeping. Logged sets are events — they arrive constantly, in order, and are never edited in bulk. So programs live in git as plain text, and sets live in SQLite. Neither substrate pretends to be the other.
| Programs, blocks, exercise library | Logged sets | |
|---|---|---|
| Substrate | Markdown + YAML in this repo | Cloudflare D1 (SQLite) |
| Written by | Git commits — no in-app editor, for anyone | The logging client, buffered in IndexedDB |
| Read by | Everyone; parsed at build time | Everyone (public by default) |
| Authenticated | GitHub credentials | Passkey per device (WebAuthn) |
There is no in-app path to edit a program, including for the owner. A change to the plan is a commit, which means every revision carries its "why" in the history instead of becoming program_v3_FINAL.
Deviations inside a session — a substitution, a cut set, a note — are log data, not program edits. Plan and actual stay separate and separately queryable.
Guests get the full product with no account: sets they log stay in their own browser's IndexedDB, never sync, and the UI keeps a persistent "local only" badge up. That path doubles as the public demo.
A program renders as an elevation profile. Deload weeks dip, build phases climb, test day is the summit — the shape of the block is legible before you read a word of it.
582 moves — exercises.yaml (537) merged with skills.yaml (78 snowboard and hockey entries) and deduplicated by id. Filed by category of workout and then by body part, searchable instantly.
Programs and blocks reference moves by name. The resolver maps name → id → page at build time, so a prescription is always one tap from how to perform it — and any name that fails to resolve is reported rather than silently dropped.
exercises.yaml atoms — the exercise library, tagged by category (body part is derived)
skills.yaml sport-specific atoms, merged into the same catalog
blocks/ molecules — reusable chunks that programs compose (14)
programs/ compositions — one Markdown file per program (20: 5 current, 15 archived)
log/ logged history and the D1 schema
id slug. Names are the reference; ids are the identity.id, title, status). Exactly one program is status: active. Versioning is git history.ROTATOR CUFF WORK in a program table is a block reference.Everything is parsed at build time; there is no content database. Build health, including every unresolved name the pipeline collected, is exposed at /api/health.
Sets are written to IndexedDB first and flushed to D1 in the background, so logging works with no signal in a gym basement and reconciles later. The buffer is append-only and ULID-keyed, and there is exactly one writer per account — which is what lets the sync path skip conflict resolution entirely rather than inventing a merge policy it can't test.
The flush is safe to call concurrently: a caller arriving during an in-flight flush awaits that flush instead of no-op'ing, and the loop drains the buffer as read at entry. Devices are disposable; D1 is canonical, so any authenticated browser sees the same history.
Authentication is WebAuthn passkeys, one per device. Server routes are the only thing that can mutate D1; unauthenticated writes get a 401.
npm install
npm run dev # local dev server
npm run build # prerender all routes; fails on unresolved content
npm run preview # serve the production build
npm test # content pipeline, date resolution, set parsing — 43 tests
npm run check # svelte-check
Stack: SvelteKit 2 + Svelte 5 on Cloudflare Pages, D1 for logs, WebAuthn via @simplewebauthn. Deployment steps are in DEPLOY.md; the visual language is in DESIGN.md; the tag vocabulary is in TAXONOMY.md.
The interface has a dark mode and a paper mode — the toggle in the header. Paper is for reading a plan; dark is for using one in a gym.
Point an agent at the repo:
Draft a
<goal>block, constraints<schedule>, drawing only fromexercises.yamlandblocks/, following the conventions inprograms/.
Review the diff, commit. The guardrails are in the build: an unresolved move name fails the prerender, so a program that references something the library doesn't have never ships.
MIT.