Każde powtórzenie. Czarno na białym.
Szybki, prywatny dziennik do treningu siłowego, dostępny w App Store na iPhone, iPad i Apple Watch.
Premiera 12 lipca 2026. Zbudowałem Reps, bo sam go potrzebowałem: dziennika na tyle cichego, żeby nie przeszkadzał przy sztandze, dni, które blokują się po skończonej robocie, i konektora, dzięki któremu Claude czyta moją historię i planuje kolejną sesję, nie dotykając bazy danych. Trzydzieści sześć tysięcy linii Swifta i 185 testów później aplikacja ukazuje się w siedemnastu językach. Oto jak powstała.
Stuknij w kółko, zablokuj dzień.
Dziennik treningowy ma jedno zadanie: zapisać serię, zanim wyleci z głowy. Reps to dziennik, jakiego chciałem dla siebie. Otwiera się na dzisiejszym dniu, pokazuje zaplanowany split i zapisuje serię jednym stuknięciem w kółko. Nie ma tu feedu ani cudzych wyników, bo między seriami i tak nigdy bym z nich nie korzystał.
Seria to ciężar i liczba powtórzeń. RPE, timery przerw i notatki istnieją dla tych, którzy ich chcą, a pozostałym nie wchodzą w drogę. Rekordy życiowe liczą się same z ukończonych serii: najwyższy ciężar oraz szacowany maks na jedno powtórzenie (wzór Brzycki).
Funkcja, którą zostawiłbym, gdybym musiał wyciąć całą resztę, to blokowane dni. Kończysz dzień, blokujesz go i aplikacja odmawia dalszych zmian, dopóki nie odblokujesz go samodzielnie. Odblokowanie to świadome działanie w aplikacji, a automatyzacja występująca w Twoim imieniu nie może edytować zablokowanego dnia w ogóle. Gdy przeglądasz miesiąc treningów, zablokowany dzień wygląda dokładnie tak, jak został zapisany.
Model biznesowy trzyma się tej samej zasady. Dziennik jest darmowy, na zawsze, a Twoje zapisy nigdy nie trafiają za paywall. Subskrypcja Reps Pro sprzedaje dokładnie jedną rzecz: zarządzane planowanie AI, dla tych, którzy chcą planera, ale nie chcą przynosić własnego klucza API.
Odręczne pismo na tablicy.
Papierowe dzienniki treningowe jedną rzecz robiły dobrze: data, ćwiczenie i nabazgrane pod spodem liczby. Reps zachowuje cały ten przedmiot. Daty i ciężary renderowane są w Bradley Hand i Noteworthy, paleta trzyma się atramentu na niemal czerni z jedną zielenią, a separatory nie są teksturą z zasobów. Falują, bo Shape złożony z szesnastu odcinków spycha każdy segment poza linię środkową:
struct RepsHandDrawnLine: Shape { func path(in rect: CGRect) -> Path { var path = Path() let segments = max(Int(rect.width / 12), 8) let segmentWidth = rect.width / CGFloat(segments) path.move(to: CGPoint(x: 0, y: rect.midY)) for index in 1...segments { let x = CGFloat(index) * segmentWidth let y = rect.midY + (index.isMultiple(of: 2) ? -0.8 : 0.9) path.addLine(to: CGPoint(x: x, y: y)) } return path } }
Wypróbuj wiersz poniżej. Odtwarza on na tej stronie kluczową interakcję aplikacji: stuknij w kółko, żeby zaliczyć serię, potem zablokuj dzień i patrz, jak aplikacja odmawia.
Piątek, 12 czerwca
Podciąganie australijskie
Stuknij w kółka. Zablokuj dzień. Spróbuj ponownie.
Gdzie kończy się odręczne pismo.
Dziesięć z siedemnastu premierowych języków używa odręcznych krojów. Japoński, koreański, chiński, arabski, hindi i tajski przechodzą na SF Rounded, bo Bradley Hand nie ma glifów dla tych pism, a udający odręczność font CJK wygląda jak kostium. Kolor podlega tej samej dyscyplinie: zieleń marki jest jasna, więc tekst akcentowy na jasnych powierzchniach sam się przyciemnia, żeby utrzymać kontrast 5.4:1, a stany fokusu na tvOS mają własny atrament. Każdy cel dotyku trzyma wymagane przez Apple minimum 44-point, bo w te kontrolki trafiasz między seriami, ze zmęczeniem w dłoniach, a nie przy biurku.
Części, których nigdy nie widać, pochodzą z Kit941 — systemu projektowego SwiftUI, który dzielą aplikacje 941: tokeny odstępów, ruchu i haptyki, komponenty testowane snapshotami oraz Liquid Glass od Apple opakowany w jeden styl. Reps nigdy nie wywołuje .glassEffect() bezpośrednio. Notesowy wygląd należy do Reps; szkielet jest wspólny.
iPhone, iPad i Apple Watch, w siedemnastu językach.
Reps działa na iPhone, iPad i Apple Watch z jednej bazy kodu SwiftUI. Aplikacja na zegarku celowo pozostaje mała: pokazuje serie dnia i pozwala odhaczać je z nadgarstka, a WatchConnectivity przenosi każdą zmianę na telefon w kilka sekund. Na siłowni checklista wygrywa z klawiaturą.
Siri i Skróty podpinają się przez App Intents. Powiedz „zapisz serię”, a seria trafia do dziennika bez otwierania aplikacji, bo intencja przechodzi przez tę samą zwalidowaną ścieżkę zapisu, z której korzysta interfejs.
- English
- Deutsch
- Español
- Français
- Italiano
- Nederlands
- Português
- Svenska
- Bahasa Indonesia
- Tiếng Việt
- 日本語
- 한국어
- 简体中文
- 繁體中文
- العربية
- हिन्दी
- ไทย
Siedemnaście języków od pierwszego dnia, z metadanymi App Store w 22 lokalizacjach. Skrypt weryfikacyjny dopuszcza build tylko wtedy, gdy w 735 ciągach nie brakuje ani jednego klucza.
Wersje na komputery Mac i Apple TV istnieją i działają. Wyjdą, kiedy będą gotowe.
Jedne drzwi wejściowe.
Reps dostarczany jest z konektorem: CLI i serwerem MCP, które dają agentowi realny dostęp do Twojego dziennika. Claude czyta Twoją historię, widzi, co utknęło, i planuje piątek. Z poziomu terminala:
$ reps last Friday, June 26 — Chest / Back [locked] Barbell Bench Press 255 lb × 6, 6, 6, 5 Weighted Pull-Up 25 lb × 5, 5, 4 Weighted Dip 60 lb × 10, 10, 10 $ claude "I started BJJ twice a week. What should change?" Reading your last 8 weeks via the reps connector… pulling volume is high for a grappling schedule. Suggesting: drop one row day, add hip hinge + neck work. Plan Friday around this?
Odczyty i zapisy idą różnymi drogami. Odczyty otwierają zsynchronizowaną lokalną replikę Twoich danych, tylko do odczytu, więc zapytanie niczego nie uszkodzi i działa offline. Zapisy nigdy nie dotykają tego magazynu. Każda mutacja trafia do aplikacji jako polecenie; aplikacja waliduje je tymi samymi regułami, które egzekwuje interfejs, stosuje, synchronizuje i zwraca pokwitowanie. Zablokowany dzień odmawia edycji agentowi dokładnie tak samo, jak odmawia palcowi.
Każde polecenie przyjmowane przez konektor przechodzi tę samą walidację co stuknięcie, a zablokowany dzień rzuca błąd, zanim cokolwiek dotknie magazynu:
guard let session = try sessionForDay(date, modelContext: modelContext) else { throw CommandError.validationFailed("no workout exists on \(dayLabel)") } guard !session.isLocked else { throw CommandError.dayIsLocked(dayLabel) } guard let target = (session.sets ?? []).first(where: { $0.exerciseName.caseInsensitiveCompare(exerciseName) == .orderedSame && $0.setNumber == setNumber }) else { throw CommandError.validationFailed("no set \(setNumber) of \(exerciseName)") }
Claude / CLI / Siri
Czyta zsynchronizowaną replikę bezpośrednio, tylko do odczytu. Każdy zapis wysyła jako polecenie, nigdy nie dotyka bazy danych.
Aplikacja
Waliduje każde polecenie tymi samymi regułami co interfejs. Zablokowane dni odmawiają edycji. Każdy zapis zwraca pokwitowanie.
Planer AI traktowany jest tak samo. Model — zarządzany albo na Twoim własnym kluczu — jedynie odczytuje intencję: jaki rodzaj dnia, co zaakcentować, czego unikać. Właściwe programowanie wykonuje deterministyczny silnik na telefonie: wybiera ćwiczenia z 42-elementowego korpusu, dobiera schematy powtórzeń do Twojego celu, progresuje obciążenia na podstawie zapisanej historii i lintuje wynik, zanim w ogóle trafi on do dziennika. AI nigdy nie zapisuje treningu bezpośrednio.
Po drodze umarły dwie działające architektury: oparte na plikach rozszerzenie Claude Desktop, a potem parowany serwer w sieci lokalnej z pinningiem TLS i własną szyną RPC. Każda dodawała drugie drzwi do danych, więc każda wyleciała. Wydana aplikacja ma jedne.
Konektor udostępnia 23 narzędzia MCP, od get_exercise_history po set_custom_program. Cały rok pisałem o oprogramowaniu, którego pierwszym czytelnikiem jest asystent; Reps to ten argument w wydanej postaci. Get Bananas umieściło serwer MCP w liście zakupów. Reps wręcza agentowi planer i nie zdejmuje barierek.
Gdzie mieszkają dane.
Deklaracje o prywatności są tanie, więc oto sama konfiguracja magazynu danych. Dane treningowe mają lustrzaną kopię w Twojej prywatnej bazie iCloud; metryki zdrowotne mieszkają w drugim magazynie, który nigdy się nie synchronizuje i nigdy nie trafia do backupu:
// No explicit name: the synced configuration keeps the historical // default.store path, which the Mac connector reads directly. let modelConfiguration = ModelConfiguration( schema: syncedSchema, isStoredInMemoryOnly: false, cloudKitDatabase: .private("iCloud.com.941apps.Reps") ) let healthCacheConfiguration = ModelConfiguration( "Reps-healthcache", schema: localSchema, isStoredInMemoryOnly: false, cloudKitDatabase: .none )
Twoje dane treningowe
Mieszkają w Twojej prywatnej bazie danych iCloud i synchronizują się między urządzeniami przez Apple. Reps nie ma systemu kont ani serwera przechowującego treningi. Nie jestem w stanie odczytać Twoich wyników w przysiadzie.
Metryki zdrowotne
Tętno i kalorie odczytane ze Zdrowia zostają w drugim magazynie: na urządzeniu, poza backupami, nigdy nie synchronizowane. Powiąż trening ze Zdrowia z zablokowanym dniem, a zsynchronizuje się tylko samo powiązanie. Pomiary zostają na telefonie.
Planowanie AI
Opcjonalne. Jeśli z niego korzystasz, zapytanie o plan (Twój profil i ostatnia historia) trafia do wybranego przez Ciebie dostawcy: usługi zarządzanej albo Twojego własnego klucza API. Silnik, który rozwija i waliduje każdy plan, działa na telefonie. Pomiń AI, a nic nie trafi do żadnego dostawcy AI.
Czarno na białym.
Reps jest darmowy w App Store. Zbudowałem go do własnych treningów i to dziennik, który otwieram codziennie; jeśli chcesz tego samego, czeka na Ciebie. Jeśli budujesz dla agentów, ścieżka zapisu to część, którą warto ukraść. (Liczby pochodzą z dnia premiery.)