Skip to content

Repository files navigation

Disclaimer: I am not an android developer, the code is entirely generated by Claude code. Please make sure to do your own due-diligence, and if anything of concern is found, please report it.

Pace : track less, quit for good

Pace is a private Android companion for cutting down and stopping smoking. It pairs honest tracking with an AI coach powered by Ollama Cloud that talks you through the hard minutes, proposes something concrete to do, and reaches out before your next scheduled window instead of after.

Your history never leaves the device. The coach is opt-in, uses your own Ollama API key, and sends only the message or voice turn you submit, photos you explicitly attach, and the handful of optional grounding numbers already on your screen.

Today Eight-week trends Editable ledger
Today Eight-week trends Editable ledger

What it does

Tracking that doesn't shame you

A ceiling, not a quota. One tap logs a cigarette, with a 12-second undo from the app or the home-screen widget. Minimum spacing, a morning hold, and quiet hours shape the day; a hard day never rewrites history, and a lower ceiling always takes effect tomorrow rather than retroactively.

A coach that never says the word

Naming the substance is itself a trigger cue reactivity is well established so the coach is built to never say cigarette, smoking, nicotine, craving or quitting. Not once, not even if you say it first. The grounded figures it receives are phrased the same way: moments, waits, clean stretches. If you raise it, it answers the feeling underneath and moves the conversation somewhere else.

It runs on Ollama Cloud with the model you pick, and talks like a friend rather than a helpdesk. Four personalities ship in the box Friendly, Bubbly, Deadpan, Steady and the prompt stays fully editable:

ugh the 3pm craving is hitting hard

Whoa, the 3pm cravings are like a pop-up ad always right when you're scrolling! How about a 2-minute "wiggle-dance" to a random song? 🎶 It burns calories, not cigarettes, and you can brag about your moves later. Got a favourite jam to spin?

Every message replays the recent conversation, so it follows the thread instead of answering each line cold. Before each reply Pace grounds it in your own local figures count against ceiling, minutes to the next window, the current clean stretch, moments resisted, money kept, the situations you find hardest, your stated reason, and the local time and day so replies fit the hour you are actually in. Mark your hardest stretch of the day on the Plan screen and it leans in harder then.

Craving conversation Distraction on demand Coach settings
Coach chat Riddle Coach settings

Replies stream token by token and can be stopped mid-sentence. Riddle me pulls a two-minute lateral-thinking puzzle to occupy your head until the moment passes.

The phone button opens a voice-only call: Android turns speech into a text turn for the coach, then reads the reply aloud with the device TTS voice. Neither side is shown as text, and the call history is discarded when the call screen closes. The normal composer can also pick a photo or open the camera; attached images use the same vision-capable Ollama model as the reply. Image bytes are sent once and discarded; a short visual description is kept privately with the chat so later replies still understand the conversation.

The tune icon on the Coach screen opens its settings: pick a personality or edit the system prompt outright, toggle whether your stats are shared with the model, and set how often it checks in.

Ask for a hand and get an actual plan

A blank five-minute countdown asks you to invent a distraction at the moment you are least able to. Instead the Toolkit asks the coach for one specific thing to do, and offers to time that:

In the next 5 minutes, raid the kitchen for the weirdest utensil you can find maybe that banana slicer or a novelty ice-cream fork and give it a dramatic backstory you'll record in a quick voice memo. 🌱

It reaches out first

Two kinds of notification, both written fresh by the model and both opening straight into the chat:

  • Nudges land when your next planned window is within 20 minutes one line under 20 words, tailored to your numbers. If the model is unreachable, built-in copy is used so the cue still arrives.
  • Check-ins arrive on your chosen interval (hourly to every six hours) whether or not a craving is due, with something funny or curious to snag your attention while Pace is closed.

Both obey quiet hours, a daily cap and a cooldown, and neither ever tells you it is time to smoke.

The coach runs its own day

Beyond reacting, the coach keeps an agenda built from where you are in your day rather than from a timer:

  • A morning plan shortly after your wake time the shape of the day, the stretch it already knows is hardest for you, and one specific thing to do before it arrives.
  • Invitations to move during the hours you set as your day, capped per day with a hard gap between them. Each one names an actual session and opens straight into it.
  • One line in the evening, an hour or two before bed, about how today went and nothing to do about it now.

Everything it writes is also appended to the chat, so opening a notification lands in a conversation that has already started instead of an empty composer. Turn the whole agenda off in Plan → Let the coach start.

Everything it knows about you, without being asked

When stats are shared, each request is grounded in far more than a count. On top of the figures above the model receives your values, the stretch your own timestamps cluster in, where your body is in the current clean stretch, how much you have walked today against your usual, how long since you last moved on purpose, this week against last week, and how long until you normally sleep all phrased so none of it can be echoed back as a trigger. The learned window is labelled as the app's observation rather than something you said, so it is treated as a hunch to act on instead of a fact to recite.

It finds your hardest stretch instead of asking for it

You can still mark a difficult window by hand, but Pace reads it off your own log timestamps: a month of history, bucketed by half hour, scanned for the densest two-to-three-hour band and trimmed back to where the moments actually start and stop. It only speaks up once there is enough history to mean something and the day is genuinely lumpy a flat day gets no invented pattern. Plan offers the window it found as one tap, and the coach leans in during it whether or not you accepted.

Movement, because it is the only tool here with a dose behind it

Eight guided sessions with a step-by-step timer: a five-minute walk, a proper fifteen-minute one, easy running intervals, a push-up ladder, a bodyweight circuit, morning and wind-down mobility flows, and a three-minute desk reset that needs no floor space. Every step carries its own cue, so a pose you have never heard of still tells you what to do, and a short buzz on each change means a walk can be followed with the phone in a pocket.

The walking and running sessions are checked against the pedometer when step counting is on, so they show real distance covered rather than time elapsed and you can rate the moment before and after, which makes these the only tools in the app that can show you your own number falling.

What the next few days actually cost

Alongside the recovery ladder which says what is being won, and reaches out ten years sits its counterpart: one hill, drawn from published CDC and NHS timings, with a marker showing where you are on it. Symptoms begin around four hours, summit across the second and third day, and fade over three to four weeks. Knowing the top is day three before standing on it is the protective part; someone who believes it climbs forever has no reason to keep waiting. It retires itself after a month rather than sitting there announcing that nothing is happening.

Values, not just a paragraph

The free-text reason is the wrong shape for the moment it matters nobody reads a paragraph at minute two of a bad afternoon. Alongside it you can keep up to five short lines in your own words. They sit on Today where a craving finds them, and the coach reaches for them instead of generic encouragement.

The gap widens as you earn it

Set a starting minimum gap and Pace grows it for you: every N steady days days finished at or below your ceiling the gap increases by one step, up to a maximum you choose. A hard day simply earns nothing; it never pushes the target further away. The Plan screen shows the current gap and how many steady days remain before the next increase.

Hundreds of badges, starting from your first hour

Ten families of tiered milestones hours held, clear-day streaks, moments resisted, money kept, time reclaimed and more over 200 badges in total. The low tiers are the point: three hours in, you have already earned something rather than staring at a distant milestone. Progress groups them by family with the next threshold in sight.

One ledger for every logged choice

Settings → Habit ledger opens one dated timeline for cigarettes, coffee, alcohol, your custom drink and check-ins. Step through any past day, add a cigarette or drink at the exact time it happened, filter the timeline, or delete a duplicate. Check-ins remain read-only evidence, and the daily summary keeps steps in view. Correcting an older cigarette entry also backfills its plan snapshot, so the day counts properly toward your averages, steady days and adaptive gap.

A quarter of history, and whether this week is better than last

Progress opens on the two questions a single day cannot answer.

This week against last week, compared over the same number of days — on a Tuesday it weighs two days against the first two of last week, never against last week's full seven. Comparing a part against a whole flatters the part, and a screen that congratulates you every Monday morning is worth nothing by Friday. It shows what changed: fewer or more logged, clear days gained or lost, whether the longest wait grew.

Thirteen weeks as a calendar, rows of weeks under each other with the actual cigarette count printed in every dated square and a colour for its relationship to the plan — clear, under the ceiling, at it, over it. Weeks stacked this way make a bad Friday visible as a column instead of as four separate bars a month apart. Days before you started are drawn as blanks rather than as perfect days: a grid that shows the month before you installed the app as a wall of green is a grid that lies.

Eight-week habit trends make the wider ledger explorable. Switch among cigarettes, coffee, alcohol, your custom drink, check-ins and steps to see the total, weekly average, current-week value and a week-by-week bar chart without leaving Progress. The same card opens the ledger when a bar deserves a closer look.

The rest of the screen is grouped rather than stacked — this week, your history, your body, what your history shows, milestones — so the part you came for is one heading away instead of ten cards down.

Watch your body repair itself

Twelve recovery milestones on the published CDC/NHS timeline, from heart rate settles at 20 minutes to lung cancer risk halved at 10 years. Today shows the next one you are working toward; Progress shows the whole ladder. Alongside it: cigarettes avoided against your baseline, money saved, life regained at 11 minutes per cigarette, and your best zero-cigarette run.

Count what you did instead

Optional step counting, off until you turn it on in Progress → Walking. Steps today, distance, 7- and 30-day averages, a per-day chart and your best day so far. Distance is estimated from your stride, which is derived from the height you can set in Plan — it is an estimate, and the app says so rather than presenting it as measured.

It reads the phone's own pedometer, which the sensor hub maintains whether or not anything is listening. Pace samples it when you open the app and every few hours in the background, so there is no foreground service, no persistent notification, and no wakelock. Averages count only the days actually recorded, so leaving your phone at home does not show up as a decline in walking.

An offline toolkit

5-4-3-2-1 grounding, a scene-change reset, sequence and memory games, a share-sheet message to a trusted person, and vetted puzzle links plus the plain timer as a fallback. All of it works with no network and no AI key.

Onboarding Progress Toolkit
Onboarding Progress Toolkit

A widget worth keeping

The redesigned card keeps the small Pace label, today's count and status together, then gives the live countdown its own raised glass panel. Below them sit the proportional ceiling meter, clean-stretch and money pills, today's steps when step counting is on, your badge count, a line that refreshes hourly, and Talk and Log actions. The pills are fitted to the width the widget actually has, so a narrow one drops the last of them rather than clipping it mid-word. It re-renders exactly when a window ends, so the countdown never outlives the wait. At sleep time, the widget switches to a neutral rest face with no countdown, count, clean-stretch statistic, quote, or action; the normal view returns at wake time.

Under the meter runs an indeterminate progress bar the one thing on a home-screen widget that genuinely moves, animated by the system with no app process running, so a widget mid-wait never looks frozen. The remaining time itself is stated in whole minutes and recalculated on a cadence you choose: every minute, every ten, or never. Refreshing stops the moment your window opens and never runs through an overnight rest window.

Badges Home-screen widget
Badges Widget

Make it yours

Five accent families Sage, Ocean, Ember, Violet, Slate carried through the app and the widget, plus Material You if you would rather follow your wallpaper, and a true-black dark mode for OLED screens.

Motion is a first-class setting rather than an afterthought. Full adds drifting gradients, breathing rings and rolling counters; Subtle keeps the transitions and drops the decoration; None cuts straight to each state. Turning animations off system-wide always wins, so nobody has to find this screen twice.

The widget gets its own panel: surface style, corner rounding, opacity, every row it draws, whether logging takes one tap or two, and the refresh cadence. Each change lands on the home screen as you make it, and a working miniature sits above the controls a widget is the one surface you cannot see while configuring it.

Widget and motion settings


Install

Pace is not on Google Play. Grab the APK from the latest release and install it directly.

For automatic updates, install Obtainium and add this repository's URL — it watches GitHub Releases and prompts you when a new version lands.

Minimum supported version is Android 8 / API 26. Every release is built and signed by GitHub Actions from the tagged commit; see docs/RELEASING.md.

To confirm an APK really came from this project, check the signing certificate:

apksigner verify --print-certs pace-<version>.apk
# SHA-256: 80:29:7E:4E:3A:05:AD:6C:1B:B6:B7:A3:A5:00:31:74:FB:D7:02:2A:AF:FA:19:B6:B2:FA:16:95:0E:24:63:AB

Setting up the AI coach

  1. Create a key at ollama.com/settings/keys.
  2. In Pace, open Settings → AI coach and turn it on.
  3. Paste the key and tap Test key. Pace calls /api/tags and replaces the suggested models with the ones your account can actually reach.
  4. Tap Check key & models, choose a verified vision-capable model, and tap Save. The same model handles chat, voice, and photos.

AI settings

The key is encrypted with a hardware-backed Android Keystore AES-GCM key before it is written to the preferences store, so it is never at rest in readable form. Remove key clears it and disables the coach.

How the key and your data are handled

  • The key lives only on your device. It is never logged, included in JSON exports, or committed to this repository.
  • Requests go to https://ollama.com over HTTPS. Nothing is sent until you enable the coach and save a key.
  • Only the current text/voice turn, explicitly attached image, and grounded figures listed above are transmitted — never your raw log history, notes, or locations.
  • Reasoning traces returned by thinking models are discarded. Chat replies are kept in chat history; voice-call turns are memory-only.
  • Turn the coach off and Pace is fully offline again.

Build

Prerequisites: Android Studio with SDK Platform 36 and Build Tools 36, plus JDK 17 or newer (Android Studio's bundled JetBrains Runtime works). Gradle itself does not need installing the checked-in wrapper fetches Gradle 9.4.1.

./gradlew :app:assembleDebug

Run the checks:

./gradlew :app:testDebugUnitTest :app:lintDebug

Install on a connected device or emulator:

./gradlew :app:installDebug

The debug APK lands in app/build/outputs/apk/debug/app-debug.apk. If SDK discovery fails, create a git-ignored local.properties with sdk.dir= pointing at your Android SDK.

Private builds: bring your key and your history

For a personal build you can bake in your own key and carry over history from another tracker, so a fresh install needs no setup. Add any of these to local.properties the file is git-ignored, so none of it can reach the repository:

pace.ollamaApiKey=sk-your-own-key
pace.ollamaModel=qwen3.5:397b-cloud
pace.seedYesterday=7
pace.seedToday=5
pace.seedLastTime=14:42
pace.seedCeiling=10
pace.seedSpacing=120

On first launch Pace spreads those cigarettes across plausible waking hours, ending exactly on seedLastTime, writes daily snapshots so the history counts toward streaks and averages, applies the plan, and enables the coach. Seeding is recorded in preferences, so reinstalling over existing data never duplicates anything. Omit the keys and a clean checkout builds a normal empty app.

The release build enables R8 minification and resource shrinking. Signing material is deliberately absent from this repository; supply your own keystore.properties (git-ignored) to produce a signed release.


Architecture

Single-module Kotlin app, Compose-only UI, no dependency-injection framework a hand-rolled AppContainer holds the singletons.

Layer Location Contents
UI feature/ Today, Coach, Toolkit, Progress, Plan, Settings, onboarding, shared components
Presentation PaceViewModel.kt PaceUiState from combined flows, plus transient CoachUiState for streaming
Domain domain/ Pacing, progress, quit metrics, badge rules, coach prompt construction
Data data/ Room database, Proto DataStore preferences, JSON backup import/export
Platform core/ Ollama client, Keystore vault, notifications, link allowlist

Notable pieces:

  • core/network/OllamaClient.kt streaming NDJSON chat, one-shot completions, and model listing.
  • core/security/SecretVault.kt AES-GCM wrapping of the API key.
  • core/coach/CoachService.kt the only path from local data to the network; a no-op until you opt in.
  • domain/CoachPrompt.kt the default persona and the exact facts each request may include.
  • domain/QuitProgress.kt smoke-free duration, streaks, avoided cigarettes, recovery milestones.
  • domain/AdaptiveSpacing.kt how the minimum gap grows with steady days.
  • data/seed/ProvisioningSeeder.kt one-time import of a private build's key and history.
  • worker/PaceWorkers.kt nudge and check-in workers plus rollover, widget refresh, badge review.

Outbound HTTPS is restricted to an allowlist in core/network/SafeLinks.kt; cleartext traffic is disabled.


Verification

The unit suite covers plan timing, cross-midnight quiet hours, weekday/weekend wake times, daylight-saving transitions, recovery and zero-ceiling behaviour, progress and savings math, quit metrics and recovery milestones, badge and reduction eligibility, notification suppression, URL allowlisting, coordinate rounding, widget debounce, and backup validation. Room reversal and idempotency are covered by instrumentation tests.

The build has been exercised on a Google APIs Android 16 / API 36 emulator, including a live Ollama Cloud round trip through the coach. Minimum supported version is Android 8 / API 26.


Privacy

No account, backend, analytics, advertising, or telemetry. Android cloud backup and device transfer are off. Cigarette records, notes and chat history live in app-private Room and DataStore storage. Pace requests no location permission at all. Export happens only to a folder you choose. See PRIVACY.md for the full statement and THIRD_PARTY_NOTICES.md for dependency licenses.

Pace is a self-management aid, not medical care, and does not replace a clinician or cessation adviser. AI replies can be wrong and are never medical advice.


Credits

Approach informed by the open-source quit-smoking community, including SmokingYou, awesome-smoking, quit-smoking-instantly, and Quit-Smoke-App. Recovery timings follow published CDC and NHS cessation guidance. Puzzles by Gabriele Cirulli and Simon Tatham.


License

Pace is free software licensed under the GNU General Public License v3.0 — see LICENSE. Dependency licenses are listed in THIRD_PARTY_NOTICES.md.

About

Pace is a private Android companion for cutting down and stopping smoking. It pairs tracking with an AI coach powered by Ollama Cloud that talks you through the hard minutes, proposes something concrete to do, and reaches out before your next scheduled window instead of after.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages