Review GitHub pull requests on your phone. Pully groups a pull request's files by what they do, writes a short summary and a guided tour through the change, and lets you ask questions about it or have Claude Code or Codex review it, all from an Android app built for one-handed reading.
Note
Pully is a personal project under active development. The Android app is the product and the iPhone app runs the same shared screens on real data; the web app trails behind both.
| Inbox | Open a pull request | Diff |
|---|---|---|
![]() |
![]() |
![]() |
| Tour | Ask | Review with AI |
![]() |
![]() |
![]() |
The pull requests in these clips are made up. They were filmed from the Android app against a stand-in server.
- Inbox. Pull requests waiting on you, the ones you wrote, and stacks of pull requests shown as one row. Group them by kind and see the riskiest first. The Inbox updates by itself while it is open, and every pull request on it is read ahead, so tapping one opens it at once.
- Overview, Diff and Tour. A summary of what changed and why, the description and conversation as GitHub shows them (Mermaid diagrams drawn on the phone), a diff that reads like code, and a Tour that walks through the change in a sensible order.
- Ask. Ask anything about a pull request or your whole Inbox, with the chat history kept.
- Review with AI. Claude Code, Codex or Pi (any model behind your own API) reviews the pull request with a chosen set of review skills, and you pick which findings to post back to GitHub. Each person signs in to their own Claude Code and Codex subscription in Settings; no API keys.
- Explore. Browse public GitHub projects and open their pull requests without signing in.
- Diff links for agents. Coding agents post a diff with an agent key and hand you a link that
opens like a pull request (
skills/post-diff-to-pully). - Made for the phone. Gestures that follow your finger, sheets, haptics and sounds, light and dark colour themes, two panes on an unfolded foldable, alerts for the checks and AI work you follow, and in-app updates with a What's new sheet.
Every release is described, with pictures, in android/CHANGELOG.md.
Two panes when the phone unfolds. An unfolded foldable has room for the list and the pull request at once, so the Inbox stays on the left and the pull request you open sits beside it, with its row marked. Every screen is the same screen in each shape; only where it sits changes. With the list right there, the Back arrow on the right pane had nothing to go back to, so it's gone (0.66.0). Inside a pull request, like a layer of its stack, Back still returns to the first one.
Motion goes the way you went. Swiping between a pull request's tabs used to spring the rows back toward the tab you were leaving before the new one slid in, so every change looked like it went backwards. Now the direction is decided once, in the UI kit, never by a screen: the next tab or file comes in from the right, Back always goes backward, and a quick flick counts however short. A design check keeps it that way (#28).
A stack is one row. A stack of pull requests is one change split up so it can be reviewed in pieces, so the Inbox shows it as a single row with its count, checks and changes together. Tap it for every layer, from the top one down to the branch they merge into, each with its number, author and place, like 2/3.
Any OpenCode theme. Settings and Commands offer OpenCode's colour themes as well as Pully's own. A script converts OpenCode's theme files into the app's palette, mapping each one onto the same roles: background, panel, text and accent. Pully's own palette has a dark pair for every colour, and a check fails if one is missing.
Android app ─┐
iPhone app ─┼── Pully server (Rust) ── GitHub, Claude Code, Codex
Web app ─┘ native, or on Cloudflare Workers
- Phone apps. Kotlin with Compose. Android and iOS share their domain, client and UI code
through Kotlin Multiplatform (
mobile/);android/andios/are the two hosts. - Server.
backend/is one Rust crate that builds both the native server and the Cloudflare Worker inpackages/worker, which keeps the server's data in a Durable Object and runs each login's AI in its own container. The server keeps every pull request it has read and tells phones what changed, so the apps read from their own copy first and catch up quietly (plan 14). - Sign-in. A Pully account with Google; GitHub is connected the way
gh auth logindoes it. - Web.
packages/appis the Vue web app, styled from the same design tokens as the phone.
| Path | What it is |
|---|---|
android/ |
The Android app, its design rules (DESIGN.md) and changelog. |
ios/ |
The iPhone host for the shared app. |
mobile/ |
Kotlin Multiplatform code shared by Android and iOS. |
backend/ |
The Rust server: GitHub, review state, AI runs, accounts, sync. |
ai-kit/ |
Claude Code, Codex and embeddings shared with ThyMind; a private submodule. |
packages/worker |
The same server built for Cloudflare Workers. |
packages/app |
The Vue web app. |
packages/core |
Diff parsing, providers and analysis used by the web app and the Action. |
packages/cli |
A small launcher that serves the web app from a local Rust server. |
packages/actions |
The CLI behind the GitHub Action in action.yml. |
skills/ |
Agent skills for posting diffs to Pully and reading in-app feedback. |
plans/, docs/ |
Design plans and notes on the server, releases and migrations. |
You need Node.js 24 with pnpm, Rust, and for the app JDK 21 and the Android SDK. The server and
the apps build on ai-kit/, a submodule from a private repository, so fetch it once per clone.
git submodule update --init
pnpm install
# Android app: unit tests and a debug APK
cd android && ./gradlew :app:testDebugUnitTest :app:assembleDebug
# Server
cargo test --manifest-path backend/Cargo.toml
cargo run --manifest-path backend/Cargo.toml # see backend/README.md for settings
# Cloudflare Worker, locally
pnpm -F @pulls.review/worker dev
# Checks that run in CI
pnpm run lint && pnpm run typecheck
pnpm run contracts:check && pnpm run android:designCode rules live in CONTRACTS files beside the code they govern, and the Android look is set
by android/DESIGN.md; CLAUDE.md explains both.
main is the integration branch: each merge deploys the Cloudflare server as staging and
publishes Pully Staging, a separate app that installs beside Pully. Stable releases go out from
the release branch through a promotion pull request that runs the full Android, iOS and server
checks. docs/RELEASE_TRACK.md has the details.
Designed and built by Octavian Tocan, working with Claude Code and Codex.
Pully started as a fork of pulls.review by Anthony Fu, which was itself inspired by Linear's PR review guides.







