Baton Manual

Chapter 15

The iPhone and Android apps

Baton for iPhone and iPad comes from the App Store, and for Android from Google Play. Both run the same Flutter code as every other build, and everything in the chapters before this one works the same in them. A few things are different, and they are the reason this chapter exists.

15.1How these screenshots were made

The pictures in this guide come from the browser build at baton.dudko.dev/app, version 0.2.11, in a window the size of a phone’s screen — 390 by 844 points, touched rather than clicked. Baton’s layout follows the width of the screen, not the platform, so this is the layout the store apps draw. Where the browser build shows something the store apps do not, it is listed here:

In the screenshotsIn the store apps
The license row in the drawer, the License key group in Settings, and the key dialogNone of them: the store handles the purchase, so there is no key to enter and nothing is locked.
A warning sign on the response panel’s last tab: the browser cannot use cookiesThe cookie jar works. A cookie a response sets is sent with later requests for the rest of the session, and is never written to the workspace.
Settings saying the workspace is kept in the browserSettings saying it is kept inside the app, on this device.
Web Worker as the engine on the Scripts tabQuickJS on Android, JavaScriptCore on iPhone — the same baton.* API and the same sandbox.

15.2A workspace lives inside the app

iOS and Android give an app no folder it can keep coming back to, so the app keeps its workspaces in its own storage on the device. That storage is private to the app, and it goes when the app is uninstalled. Connecting a repository (Section 13) is what makes a workspace outlive the phone, and what puts it on your other devices.

15.3Sync goes through the host

There is no git on a phone to run, so the app syncs through the API of the host the repository lives on: GitHub, GitLab or Bitbucket. Every sync writes one commit with all its files. GitHub is authorized by device flow — the app shows a code and you enter it on github.com — and GitLab and Bitbucket take a token you paste. A commit made this way is created by the host, so it is not signed and there is no history on the phone; commit from a computer when either matters.

15.4Secrets are in the phone’s own store

Secret values go to the Keychain on iPhone and the Keystore on Android — never to the workspace, as on every other platform (Section 7). A colleague who clones the repository gets the names and sets their own values; so do you, on a second device.

15.5Requests go straight to the API

The apps send requests directly, as the desktop builds do. A browser may only call an API that allows it with CORS headers, and the browser build relays the rest through a worker; a phone has no such rule, so a worker is needed for schedules and nothing else. WebSocket handshakes carry their headers here too, which the browser build cannot do.

OAuth 2.0 authorizes in the platform’s own sign-in sheet, which returns to the app when you are done (Section 8).

A workspace link comes in two spellings. baton://open?repo=… opens the app on iPhone and Android and shows the repository it names; nothing is fetched until you choose Continue. https://baton.dudko.dev/open?repo=… opens a page on the site that shows the same coordinates and offers the app, so it works for someone who does not have it yet.

15.7AI agents work on a computer

The MCP server that lets an AI agent read, edit and run requests is a program on a computer, beside a checkout of the repository; a phone cannot run one. What an agent changes reaches the phone the way any other change does — committed, pushed, and pulled by the next sync. The desktop guide describes connecting one.

15.8Updates come from the store

The store updates the app. There is no update check of Baton’s own in the store builds, and nothing to turn off.