| 1 | --- |
| 2 | title: The phone app |
| 3 | description: g1t on Android and iOS, built with Expo. Highly experimental and barely working yet. Android first, downloaded from g1t.sh while it waits for Google Play. |
| 4 | --- |
| 5 | |
| 6 | The phone app is meant to be g1t on Android and iOS, with its own |
| 7 | screens for what you do away from a desk: triaging and discussing |
| 8 | [work items](/guides/work-items/) in Work, talking with your team in |
| 9 | Chat, with notifications on your phone, and reviewing pull requests in |
| 10 | Code. Everything else opens on the site, in your phone's browser. |
| 11 | |
| 12 | :::caution[Highly experimental] |
| 13 | The phone app is early and barely works yet: expect missing screens, |
| 14 | rough edges and things that break. For real work, use |
| 15 | [the desktop app](/guides/desktop/) or g1t in your phone's browser. |
| 16 | ::: |
| 17 | |
| 18 | ## Install it |
| 19 | |
| 20 | Android comes first. Get it from [g1t.sh/download](https://g1t.sh/download): |
| 21 | the page opens on **Android** when you visit it on an Android phone, and |
| 22 | [g1t.sh/download?platform=android](https://g1t.sh/download?platform=android) |
| 23 | opens it from anywhere. |
| 24 | |
| 25 | 1. On your Android phone, choose **Download for Android**. On a computer, |
| 26 | scan the code beside it with the phone's camera instead. |
| 27 | 2. Open the downloaded file. Android asks once to allow your browser to |
| 28 | install apps: allow it. If Play Protect warns about an unknown app, |
| 29 | choose **More details**, then **Install anyway**. |
| 30 | 3. Open **g1t** and choose **Sign in with g1t**. |
| 31 | |
| 32 | Point at the file's name on the page to see its SHA-256, to check the file |
| 33 | you have is the one g1t published. Like every g1t build during the alpha, |
| 34 | the app isn't code-signed yet, which is why Android warns |
| 35 | ([unsigned during the alpha](/guides/desktop/#unsigned-during-the-alpha)). |
| 36 | |
| 37 | **Why a download, and not Google Play?** Google Play and the App Store |
| 38 | publish a company's apps only once it is verified with a D-U-N-S number, |
| 39 | and Flagon's is on its way. Until then the Android app is published on |
| 40 | g1t.sh, as [the desktop app](/guides/desktop/) is. It moves |
| 41 | into Google Play as soon as it can. iOS has no way in but the App Store, |
| 42 | so it follows then. |
| 43 | |
| 44 | **Updates** reach the app by themselves: most arrive the next time you |
| 45 | open it, with nothing to install. A change that needs a new install is a |
| 46 | new release on the download page; installing it over the one you have |
| 47 | keeps you signed in. |
| 48 | |
| 49 | The bar along the bottom is the site's phone bar: |
| 50 | |
| 51 | | Tab | What is on it | |
| 52 | | --- | --- | |
| 53 | | **Home** | Coming. Opens Home on the site meanwhile. | |
| 54 | | **Work** | The workspace's work items and their Board, for every member, Code access or not. **Sessions** opens from the icon in its header. See [Work](#work). | |
| 55 | | **Chat** | Your starred conversations, channels and direct messages, with what is unread, moving live. See [Chat](#chat). | |
| 56 | | **Notifications** | Coming. Opens your notifications on the site meanwhile; messages to you already arrive [on the phone](#notifications). | |
| 57 | | **More** | **Sessions** first (see [Sessions](#sessions)), then **Code**, for members with Code access; whether this phone gets notifications, your workspaces, how you signed in, and **Sign out**. | |
| 58 | |
| 59 | **Code**, under **More**, is the workspace's repositories, each with its |
| 60 | pull requests and its **Work**: the work items linked to it. A pull |
| 61 | request shows its description, checks, conversation and changed files, |
| 62 | and you can approve it or ask for changes. |
| 63 | |
| 64 | ## Work |
| 65 | |
| 66 | Work on the phone is the site's [Work](/guides/work-items/), laid out for |
| 67 | one hand. A switch at its top, **Items | Board**, chooses between the |
| 68 | list and the Board. |
| 69 | |
| 70 | - **The list** shows the workspace's open work items, newest first: each |
| 71 | with its number, title, state, labels and the repositories it is linked |
| 72 | to, which fold into "+2" past the first few. Pull down to read it |
| 73 | again; it loads more as you near its end. |
| 74 | - **Filters** are in a sheet: tap the filter button in the header, a |
| 75 | filter's chip above the list, or **Work** in the bar again. Choose the |
| 76 | state, **Assigned to me**, a label, a milestone, a repository and its role. |
| 77 | - **A work item** shows its description and comments (in Markdown, with |
| 78 | `#123` references opening what they name), its labels, milestone and |
| 79 | assignees, and under them its repositories: each with its role, its pull |
| 80 | requests for the item and whether the work **landed** there, and which |
| 81 | targets are still missing. **Suggested** repositories can be added as |
| 82 | targets with a tap. |
| 83 | - **The bar at its foot** comments. Its **⋯** closes the work item (as |
| 84 | done, or as not planned), reopens it, links a repository as a target, |
| 85 | copies its link, or opens it on the site. Tap a repository to open it or |
| 86 | unlink it. |
| 87 | - **New work item** (the **+** on Work) takes a title, a description, |
| 88 | labels and the repositories it should land in; none is fine. Opened from |
| 89 | a repository's Work, that repository is its origin. |
| 90 | - **The Board** is the site's [Board](/guides/work-items/#the-board): |
| 91 | **Backlog**, **In progress**, **In review**, **Landing** and **Done**, |
| 92 | each card a work item with who or which session is on it. Tap a card to |
| 93 | open the work item. |
| 94 | |
| 95 | ## Sessions |
| 96 | |
| 97 | **Sessions** is the site's [Sessions](/guides/sessions/#the-sessions-page): |
| 98 | the sessions at work across the workspace. Open it from the icon in |
| 99 | Work's header, or first in **More**. |
| 100 | |
| 101 | - **Everything**, **Live** and **Recent** at the top choose what it |
| 102 | lists. Pull down to read it again. |
| 103 | - **Filters** are in a sheet: **Started by me**, and a repository. |
| 104 | - **A session** shows its facts (who, harness, repository, branch, state, |
| 105 | when it was last heard from), what it is working on (its work item and |
| 106 | pull request), its subagents as a tree, the files it touched, and its |
| 107 | timeline. |
| 108 | |
| 109 | ## Chat |
| 110 | |
| 111 | Chat on the phone is the site's Chat: the same conversations, as they |
| 112 | happen. |
| 113 | |
| 114 | - **Conversations** show messages as the site draws them: bold, italic, |
| 115 | code, lists, quotes, tables and links, with `@mentions`, `#channels` |
| 116 | and `#123` references standing out. Messages by one person a few minutes |
| 117 | apart run together, and each day is marked. |
| 118 | - **Live.** New messages, edits, deletions and reactions appear as they |
| 119 | happen, and the line above the box says who is typing. Unread counts in |
| 120 | the list and on the **Chat** tab move as messages arrive anywhere. |
| 121 | - **Sending** shows your message at once. If it doesn't reach g1t, it |
| 122 | stays, marked **Not sent**: tap it to try again. |
| 123 | - **Long-press a message** to react, reply in a thread, copy it, or edit |
| 124 | or delete your own. Tap a reaction to add yours or take it back. |
| 125 | - **Threads** open from a message's replies, with the message they are |
| 126 | under at the top. |
| 127 | - **⋯** on a conversation stars, mutes or leaves it. |
| 128 | - **New message** (the pen at the top of Chat) messages a person, or a few |
| 129 | people together, or makes a channel. **Browse** at the |
| 130 | foot of the list joins public channels. |
| 131 | |
| 132 | A notification for a conversation you have open is not shown; one for |
| 133 | another shows as a banner at the top of the screen. |
| 134 | |
| 135 | ## Notifications |
| 136 | |
| 137 | The phone gets the same notifications as [browser push](/guides/notifications/#on-your-phone): |
| 138 | messages to you, mentions and replies in threads you are in, under the |
| 139 | same rules. Nothing comes while you are using |
| 140 | g1t in a browser or in the app itself, and nothing in |
| 141 | [Do not disturb](/guides/chat/#sounds-and-do-not-disturb). Tapping one |
| 142 | opens the conversation or thread it is about. |
| 143 | |
| 144 | The app asks to notify you the first time you sign in. To change it |
| 145 | later, use **More → Notifications on this phone**, or the phone's own |
| 146 | settings for g1t, where Android lists the **Messages** channel. Signing |
| 147 | out stops them on that phone. |
| 148 | |
| 149 | ## Signing in |
| 150 | |
| 151 | **Sign in with g1t** opens g1t.sh in your phone's browser, where you sign |
| 152 | in as usual (with your password, GitHub, two-factor) and approve the app. |
| 153 | The browser sends you back to the app, signed in. The app never sees your |
| 154 | password. This is [OAuth](/guides/authentication/#signing-in-with-oauth): |
| 155 | the app is listed as **g1t for Android** or **g1t for iOS** in |
| 156 | [Settings → Connected applications](https://g1t.sh/settings/applications), |
| 157 | where **Change access** narrows what it can do and **Sign out** ends it at |
| 158 | once. |
| 159 | |
| 160 | The approval page lists what the app asks for: reading your account, |
| 161 | workspaces, repositories, checks and workflows, reading and writing |
| 162 | work items, pull requests and notifications, and reading artifacts. Untick what you would rather it |
| 163 | could not do. |
| 164 | |
| 165 | **Use an access token** signs in with a |
| 166 | [personal access token](/guides/authentication/#access-tokens) you paste |
| 167 | in instead. The token stays on your phone, in its keystore. |
| 168 | |
| 169 | The app asks for `chat:read` and `chat:write` too. They let it use |
| 170 | Chat's routes and live connections on the site, and register for |
| 171 | notifications, and nothing else there: the app's sign-in cannot open the |
| 172 | site's pages as you. |
| 173 | |
| 174 | ## Links |
| 175 | |
| 176 | A `g1t://` link opens the app, as it opens [the desktop app](/guides/desktop/#links): |
| 177 | `g1t://acme/-/chat/dm/chn_1` is that conversation. The app shows the |
| 178 | pages it has screens for: |
| 179 | |
| 180 | | Link | Opens | |
| 181 | | --- | --- | |
| 182 | | `g1t://<workspace>/-/work`, with the list's filters (`?repo=web&label=bug`) | Work, filtered as the link says | |
| 183 | | `g1t://<workspace>/-/work/<number>` | The work item | |
| 184 | | `g1t://<workspace>/-/work/new` | A new work item | |
| 185 | | `g1t://<workspace>/-/work/board` | Work, on the Board | |
| 186 | | `g1t://<workspace>/-/sessions` | Sessions | |
| 187 | | `g1t://<workspace>/-/sessions/<id>` | The session | |
| 188 | | `g1t://<workspace>/-/chat`, `…/-/chat/<channel>`, `…/-/chat/dm/<id>` | Chat, or the conversation, in that workspace | |
| 189 | | `g1t://<owner>/<repo>` | The repository | |
| 190 | | `g1t://<owner>/<repo>/pull/<number>` | The pull request | |
| 191 | | `g1t://<owner>/<repo>/issues/<number>` | What that old issue number names in the repository: the work item the issue became, or a pull request. The app asks g1t, as the site does. `…/issues` and `…/issues/new` open Work filtered to the repository, and a new work item from it. | |
| 192 | |
| 193 | The same paths as `https://g1t.sh/…` links, such as |
| 194 | `https://g1t.sh/<workspace>/-/work/<number>` or |
| 195 | `https://g1t.sh/<workspace>/-/sessions/<id>`, open these screens once |
| 196 | g1t.sh publishes the files Android and iOS check first (see |
| 197 | [below](#whats-not-there-yet)). The workspace's labels and milestones open |
| 198 | on the site. |
| 199 | |
| 200 | Any other page opens on the site, in the browser. |
| 201 | |
| 202 | ## Your own g1t |
| 203 | |
| 204 | The app works with a g1t you [run yourself](/guides/self-hosting/) as well |
| 205 | as with g1t.sh. It talks to one g1t at a time, and opens on g1t.sh unless |
| 206 | you point it elsewhere. Two ways to point it at yours: |
| 207 | |
| 208 | - **Scan its code.** Your g1t's download page, `<your g1t>/download`, has |
| 209 | a QR code under its platforms, **Use the phone app with** your g1t. Scan it with the phone's camera, or |
| 210 | open the page on the phone and choose **Open in the g1t app**. The app |
| 211 | asks **Use g1t.example.com?**, then signs you in there. |
| 212 | - **Type its address.** On the sign-in screen, choose **Using your own |
| 213 | g1t? Sign in there** and enter the address you open it at in a browser, |
| 214 | such as `g1t.example.com`. |
| 215 | |
| 216 | Either way the app reads `<your g1t>/.well-known/g1t.json`, where your g1t |
| 217 | says where its API is, so you never type that. A g1t from before the phone |
| 218 | app has no such file: the app then takes the API to be `api.` in front of |
| 219 | the site, and offers **Its API is at another address** if it is not. |
| 220 | |
| 221 | The sign-in screen then says **Signing in to g1t.example.com**, with |
| 222 | **Change** and **Use g1t.sh**. Switching signs you out of the g1t you were |
| 223 | on. |
| 224 | |
| 225 | | Your g1t | What to know | |
| 226 | | --- | --- | |
| 227 | | Reached by the phone | `PUBLIC_URL` and `API_URL` must be addresses the phone can open. `localhost` on a phone is the phone itself: use your computer's address on the network, or a domain. | |
| 228 | | `https` | Store builds of the app open `https` addresses only, as Android requires. A development build also opens `http`, for a g1t on your own network. | |
| 229 | | Notifications | Work with no setup: your g1t sends them through Expo's push service, as g1t.sh does. To keep notifications' words off Expo's, Google's and Apple's services, set `PHONE_PUSH=off` ([self-hosting](/guides/self-hosting/#the-phone-app)); the app then says your g1t sends no notifications, and Chat still updates while it is open. | |
| 230 | | Older versions | A g1t from before the phone app does not let the app's sign-in into Chat. Upgrade it, or sign in with an access token that has **Use the website as you**. | |
| 231 | |
| 232 | ## What's not there yet |
| 233 | |
| 234 | - **Google Play and the App Store**, once Flagon's D-U-N-S number |
| 235 | arrives ([above](#install-it)). Until then, Android from the download |
| 236 | page; iOS waits for the App Store. |
| 237 | - **Home, Notifications and Artifacts** as tabs of their own. |
| 238 | Their pages open on the site meanwhile. |
| 239 | - **More of Work.** Changing an existing work item's labels, assignees |
| 240 | or milestone, reacting, and the workspace's **Labels** and |
| 241 | **Milestones** pages are on the site for now. |
| 242 | - **Attachments and custom emoji.** Files in messages, and a |
| 243 | workspace's own `:emoji:`, show as their names. |
| 244 | - **Replying from a notification**, without opening the app. |
| 245 | - **https links.** `g1t.sh` addresses open the site in the browser, not |
| 246 | the app, until g1t.sh publishes the files Android and iOS check first. |
| 247 | |
| 248 | ## For operators: building and releasing |
| 249 | |
| 250 | The app lives in `apps/mobile`: [Expo](https://expo.dev) with Expo |
| 251 | Router, in TypeScript, sharing types with the site through |
| 252 | `@g1t/contracts`. It builds with EAS Build. `apps/mobile/README.md` has |
| 253 | the commands for running it on a phone and the first-time setup. |
| 254 | |
| 255 | | Build | Command | What it makes | |
| 256 | | --- | --- | --- | |
| 257 | | Development | `eas build --profile development --platform android` | An APK of `g1t (dev)` (`sh.g1t.app.dev`) that loads its code from your computer. | |
| 258 | | Preview | `npm run build:android:apk -w @g1t/mobile` | An APK of `g1t` (`sh.g1t.app.preview`) to install on testers' phones. | |
| 259 | | Production | `npm run build:android -w @g1t/mobile` | An Android App Bundle of `g1t` (`sh.g1t.app`) for Google Play. | |
| 260 | |
| 261 | The three install side by side. `eas submit --platform android` sends |
| 262 | the latest production build to Google Play's internal testing track as a |
| 263 | draft, once there is a Play account to send it to. |
| 264 | |
| 265 | ### Releasing on g1t.sh/download |
| 266 | |
| 267 | Until the app is in Google Play, the `preview` build is the one people |
| 268 | install, from g1t.sh/download. A release is a tag `mobile-v<version>`, |
| 269 | where the version is `version` in `apps/mobile/app.config.ts`: push it, |
| 270 | and the `Mobile release` workflow (`.g1t/workflows/mobile-release.yml`) |
| 271 | has EAS build the APK, then publishes it to the `g1t-downloads` bucket |
| 272 | at `g1t.sh/downloads/mobile/<version>/` and points `mobile/latest.json` |
| 273 | at it, which the download page reads. `scripts/mobile-release.mjs` does |
| 274 | the same by hand (`build`, `fetch`, `manifest`, `publish`). |
| 275 | |
| 276 | | Secret or variable | What it is | |
| 277 | | --- | --- | |
| 278 | | `EXPO_TOKEN` | An Expo access token with access to the g1t project, from expo.dev | |
| 279 | | `CLOUDFLARE_API_TOKEN`, `CLOUDFLARE_ACCOUNT_ID` | As the deploy has them | |
| 280 | |
| 281 | Most changes need no release: `eas update --channel preview` in |
| 282 | `apps/mobile` sends the app's new code to every installed copy of that |
| 283 | version, which takes it the next time it opens. A release is for a change |
| 284 | to the app's native side (a new native module, `app.config.ts`) or its |
| 285 | `version`, which is also what decides which updates a copy takes. |