Cada repetição. Registrada.
Um diário de treino rápido e privado para musculação, na App Store para iPhone, iPad e Apple Watch.
Lançado em 12 de julho de 2026. Criei o Reps porque queria usá-lo no meu próprio treino: um diário silencioso o bastante para treinar ao lado dele, dias que se bloqueiam quando o trabalho termina e um conector que permite que o Claude leia meu histórico e planeje a próxima sessão sem tocar no banco de dados. Trinta e seis mil linhas de Swift e 185 testes depois, ele chega em dezessete idiomas. Foi assim que ele tomou forma.
Toque em um círculo, bloqueie o dia.
Um diário de treino tem uma única função: registrar a série antes que você a esqueça. O Reps é o diário que eu queria para mim. Ele abre no dia de hoje, mostra a divisão que planejei e registra uma série com um único toque em um círculo. Não há feed nem números de outras pessoas, porque eu nunca usaria nenhum dos dois entre as séries.
Uma série é um peso e um número de repetições. RPE, cronômetros de descanso e notas existem para quem os quer e ficam fora do caminho para todos os outros. Os recordes pessoais se calculam sozinhos a partir das séries concluídas: o maior peso, mais a repetição máxima estimada pela fórmula de Brzycki.
Se eu tivesse que cortar todo o resto, ficaria com os dias bloqueados. Termine um dia, bloqueie-o, e o app recusa novas edições até que você mesmo o desbloqueie. Desbloquear é um ato explícito no app, e uma automação agindo em seu nome não consegue editar um dia bloqueado de forma alguma. Quando você revisa um mês de treino, um dia bloqueado aparece exatamente como você o registrou.
O modelo de negócio segue a mesma regra. O diário é gratuito, para sempre, e seu registro nunca fica atrás de um paywall. A assinatura Reps Pro vende exatamente uma coisa: planejamento com IA gerenciado, para quem quer o planejador sem precisar trazer uma chave de API.
Letra de mão em um quadro-negro.
Os diários de treino em papel acertaram em uma coisa: uma data, um exercício e números rabiscados logo abaixo. O Reps mantém o objeto inteiro. Datas e pesos são renderizados em Bradley Hand e Noteworthy, a paleta se mantém em tinta sobre quase-preto com um único verde, e os divisores não são uma textura pronta. Eles oscilam porque um Shape de dezesseis linhas desloca cada segmento para fora da linha central:
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 } }
Experimente a linha abaixo. Ela reconstrói a interação central do app para esta página: toque em um círculo para concluir uma série, depois bloqueie o dia e veja como ele recusa você.
Sexta-feira, 12 de junho
Remada invertida
Toque nos círculos. Bloqueie o dia. Tente de novo.
Onde a letra de mão para.
Dez dos dezessete idiomas de lançamento usam as fontes manuscritas. Japonês, coreano, chinês, árabe, hindi e tailandês recorrem à SF Rounded, porque a Bradley Hand não tem glifos para essas escritas e uma fonte CJK de caligrafia falsa parece fantasia. A cor segue a mesma disciplina: o verde da marca é claro, então o texto de destaque em superfícies claras se escurece sozinho para manter um contraste de 5.4:1, e os estados de foco do tvOS têm sua própria tinta. Cada alvo de toque respeita o mínimo de 44-point da Apple, porque você acerta esses controles entre as séries, com as mãos cansadas, não em uma mesa.
As partes que você nunca vê vêm do Kit941, o design system em SwiftUI que os apps 941 compartilham: tokens de espaçamento, movimento e háptica, componentes testados com snapshots e o Liquid Glass da Apple encapsulado atrás de um único estilo. O Reps nunca chama .glassEffect() diretamente. O visual de caderno pertence ao Reps; o esqueleto é compartilhado.
iPhone, iPad e Apple Watch, em dezessete idiomas.
O Reps roda no iPhone, iPad e Apple Watch a partir de uma única base de código em SwiftUI. O app do Watch é deliberadamente pequeno: mostra as séries do dia e as marca como concluídas direto do pulso, e o WatchConnectivity leva cada mudança ao telefone em segundos. Em uma academia, uma checklist vence um teclado.
A Siri e os Atalhos se conectam por meio de App Intents. Diga “registrar uma série” e a série é salva sem abrir o app, porque a intent passa pelo mesmo caminho de escrita validado que a interface usa.
- English
- Deutsch
- Español
- Français
- Italiano
- Nederlands
- Português
- Svenska
- Bahasa Indonesia
- Tiếng Việt
- 日本語
- 한국어
- 简体中文
- 繁體中文
- العربية
- हिन्दी
- ไทย
Dezessete idiomas lançados no primeiro dia, com metadados da App Store em 22 localidades. Um script de verificação condiciona cada build a zero chaves ausentes nas 735 strings.
As versões para Mac e Apple TV existem e funcionam. Elas serão lançadas quando estiverem prontas.
Uma única porta de entrada.
O Reps vem com um conector: uma CLI e um servidor MCP que dão a um agente acesso real ao seu diário. O Claude lê seu histórico, percebe o que estagnou e planeja a sexta-feira. Do terminal:
$ 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?
Leituras e escritas seguem caminhos diferentes. As leituras abrem uma réplica local sincronizada dos seus dados, somente leitura, então uma consulta não pode corromper nada e funciona offline. As escritas nunca tocam esse armazenamento. Cada mutação vai para o app como um comando; o app a valida com as mesmas regras que a interface impõe, aplica, sincroniza e devolve um recibo. Um dia bloqueado recusa a edição de um agente exatamente como recusa a ponta de um dedo.
Cada comando que o conector aceita passa pela mesma validação de um toque, e um dia bloqueado lança um erro antes que qualquer coisa toque o armazenamento:
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
Lê a réplica sincronizada diretamente, somente leitura. Envia cada escrita como um comando, nunca toca o banco de dados.
O app
Valida cada comando com as mesmas regras da interface. Dias bloqueados recusam edições. Cada escrita devolve um recibo.
O planejador com IA recebe o mesmo tratamento. O modelo, gerenciado ou com a sua própria chave, apenas interpreta a intenção: que tipo de dia, o que enfatizar, o que evitar. Um motor determinístico no telefone faz a programação de verdade: escolhe entre os 42 exercícios do corpus, aplica esquemas de repetições compatíveis com seu objetivo, progride as cargas a partir do seu histórico registrado e verifica o resultado antes que ele chegue ao diário. A IA nunca escreve um treino diretamente.
Duas arquiteturas funcionais morreram no caminho até aqui: uma extensão do Claude Desktop baseada em arquivos e, depois, um servidor pareado na rede local com TLS pinning e seu próprio barramento RPC. Cada uma adicionava uma segunda porta para os dados, então cada uma foi removida. O app lançado tem uma só.
O conector expõe 23 ferramentas MCP, de get_exercise_history a set_custom_program. Passei o ano escrevendo sobre software cujo primeiro leitor é um assistente; o Reps é esse argumento transformado em produto. O Get Bananas colocou um servidor MCP em uma lista de compras. O Reps entrega ao agente um planejador e mantém as barreiras de proteção.
Onde os dados moram.
Promessas de privacidade custam pouco, então aqui está a própria configuração do armazenamento. Os dados de treino se espelham no seu banco de dados privado do iCloud; as métricas de saúde moram em um segundo armazenamento que nunca sincroniza e nunca entra em um backup:
// 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 )
Seus dados de treino
Moram no seu banco de dados privado do iCloud e sincronizam de aparelho para aparelho pela Apple. O Reps não tem sistema de contas nem servidor que armazene treinos. Eu não consigo ler os números do seu agachamento.
Métricas de saúde
Frequência cardíaca e calorias lidas do app Saúde ficam em um segundo armazenamento: no aparelho, excluído dos backups, nunca sincronizado. Vincule um treino do Saúde a um dia bloqueado e apenas o vínculo sincroniza. As medições ficam no telefone.
Planejamento com IA
Opcional. Se você usar, o pedido de plano (seu perfil e histórico recente) vai para o provedor que você escolheu: o serviço gerenciado ou a sua própria chave de API. O motor que expande e valida cada plano roda no telefone. Dispense a IA e nada vai para nenhum provedor de IA.
Tudo registrado.
O Reps é gratuito na App Store. Eu o criei para o meu próprio treino e é o diário que abro todos os dias; se você quer a mesma coisa, ele está lá. Se você constrói para agentes, o caminho de escrita é a parte que vale a pena roubar. (As contagens são números do dia do lançamento.)