git; PR status and actions come from the GitHub CLI (gh) running on the host the session runs on.
Live diff
The Diff pane reflects the working tree of the session’s repo — its worktree when the session runs in worktree mode, otherwise the repo root. It runs threegit invocations and merges the results so staged and unstaged changes stay distinct:
git diff --unified=3— unstaged changes.git diff --cached --unified=3— staged changes.git ls-files --others --exclude-standard— untracked files, rendered as synthetic “new file” diffs.
Continuum deliberately avoids
git diff HEAD, which flattens staged and unstaged deltas into one patch. Keeping them separate means a Revert on an unstaged hunk can’t accidentally hide a staged change that’s still commit-ready in the index.Auto-refresh
The Mac diff store watches the repo’s.git directory with a vnode source (write, extend, attrib, rename, link). Anything that touches the index, HEAD, or refs lands there, so when the agent stages or writes files the diff re-runs on its own. Three things keep that from thrashing:
- Refreshes coalesce on a 100 ms window, so a burst of edits doesn’t re-spawn
gitrepeatedly. - When a filesystem event produces no actual change, the store backs off — doubling up to a 15-second ceiling, and resetting the moment real content moves. An agent writing continuously to a busy worktree can’t pin a
gitsubprocess per event. - A 5-second poll runs alongside the watch as a backstop for changes the vnode source misses.
Per-hunk and per-file actions
Each file expands into its hunks. The available actions depend on the change state — no terminal required:- Stage / Unstage pipe a per-hunk or per-file patch into
git apply --cached(forward to stage,--reverseto unstage). Staging a whole untracked file usesgit addinstead. - Revert on an unstaged change reverse-applies the patch to the working tree, removing only that change without touching the index. On a staged change it reverse-applies to the index, which is an unstage, not a destructive revert.
- Trash on an untracked file moves it to the system Trash — recoverable, not a hard delete — and asks for confirmation first. It refuses any path that resolves outside the repo.
Inline PR review comments
When the branch has an open PR, the Mac diff pane pulls its GitHub review comments and renders each one on the line it was left on, threaded with its replies. You can post a new line comment or reply to an existing thread from the diff itself, and jump to the comment on GitHub. The comment poll runs every 30 seconds while a PR exists and drops to every 2 minutes when there isn’t one, so a branch with nothing to sync isn’t spawninggh continuously.
Commit sheet
When you’re ready to commit, the Commit… button opens a sheet. Submitting runsgit commit -m <message> against the session’s repo. Continuum commits exactly what’s staged — it does not auto-stage on your behalf.
The diff surfaces:
- Mac: the Code workbench review pane → Diff tab.
- iPhone: the Diff tab of the session workbench, served by
GET /sessions/:id/diff(truncated files lazy-fetch full hunks viaGET /sessions/:id/diff/<path>). Stage / Unstage / Discard are file-level here and route throughPOST /sessions/:id/diff-action/<path>. There is no commit sheet on iPhone — commit from the Mac.
PR status
Continuum resolves a session’s PR status two ways, with the host poll as the authority.Host poll (primary)
The Mac polls the host’sGET /sessions/:id/pr endpoint about once a minute, with jitter so many sessions don’t stampede together. The host resolves the session’s current git branch and runs:
gh pr view. This reports title, body, and number; state (open / draft / closed / merged); additions, deletions, and changed files; the review decision; and a status-check rollup.
Answers are cached on the host with a short TTL and shared across clients, so your Mac, phone, and the web app all read one gh result rather than three. The cache is deliberately stale-tolerant: when a probe fails, the last known answer keeps being served instead of collapsing to “no PR.” A host with a broken or unauthenticated gh can no longer wipe a good PR badge for every device at once.
Because the host checks the branch directly, it knows a PR is open even when the agent only mentioned it in prose — so the titlebar shows the open PR link instead of still offering “Create PR.”
Chat-scan mirror (fallback)
When no host client is available — or the host temporarily doesn’t recognize the session id during a launch or restart race — Continuum scans the chat transcript for ahttps://github.com/<owner>/<repo>/pull/<n> URL, using creation-context heuristics so it latches the PR this session created rather than an unrelated PR cited in passing. You can also paste a PR URL manually to pin the mirror to a specific PR.
PR actions
When Create PR is offered
One rule decides this, shared by the Mac titlebar, the iPhone header, the iPhone overflow menu, and the web and Android clients, so no two surfaces can disagree:- The session runs in a worktree.
- No provider turn is in flight. This is broader than “not streaming” — a prompt a client has already accepted but the host hasn’t started streaming yet still counts as a turn in flight. That gap is why the phone used to re-offer Create PR for the whole send round-trip while the Mac didn’t.
- The transcript has provider messages — there is something to open a PR about.
- The session already has no PR.
On Mac — the Code titlebar
- Create PR sends the agent a “Create PR” instruction with the PR-instructions skill attached, and auto-sends it. The agent opens the PR; the poll then detects it and flips the titlebar to a live #number link. A menu option creates a draft PR instead. The skill’s text comes from
.context/PR instructions.mdin your repo when present, and falls back to Continuum’s own canonical workflow otherwise. - Open PR opens the linked PR in your browser.
- Merge appears when the PR is open and its checks are green or haven’t reported. Before merging, Continuum creates a safety checkpoint; if the checkpoint fails, the merge is cancelled. Merge is additionally blocked while the session has open TODOs.
Host endpoints
The mobile, web, and Merge paths go through the host, which shells out togh:
- Create —
POST /sessions/:id/create-prrunsgh pr create --fill, honoring an optional title, body, and base branch. - Review / Approve —
POST /sessions/:id/pr/reviewrunsgh pr reviewwith--approve,--comment, or--request-changes. - Line comments —
GET/POST /sessions/:id/pr/commentsread and write GitHub review comments, including replies. - Merge —
POST /sessions/:id/mergerunsgh pr merge <n>with the chosen method (--squashdefault,--merge, or--rebase), plus optional--delete-branchand--auto. The host refuses to merge when checks are failing or pending unless you pass an admin override.
Idempotent writes
Every write carries an idempotency key, and the host’s command outbox makes retries safe:- A retried request with the same key replays the cached response instead of re-running the side effect — so a tap that times out and retries does not create a second PR or merge twice.
- A duplicate request for a key that’s still in flight returns
409. - Reusing a key with a different payload returns
422, catching a retry whose body was edited between taps.
Beyond the Mac
PRs are not Mac-only. The Go host agent that powers the Windows and Linux desktop apps, thecontinuum CLI, VPS hosts, and managed runners implements the same session routes — create PR, merge, approve, and read/write review comments — by shelling out to gh on that host. A session running on a Linux box opens its PRs from that Linux box.
On iPhone
The session workbench mirrors the same data through its PR tab. It offers:- Create PR and Merge — both queue through the command outbox, so a tap survives the host being briefly unreachable and retries with backoff instead of being silently dropped. The merge sheet lets you pick the method (squash / merge / rebase) and toggle delete-branch and auto-merge.
- Review (Approve / Comment / Request changes) — submitted directly to the host’s idempotent review endpoint.
Related
- Sessions — the session runtime and worktree setup.
- Code — the Diff tab and titlebar PR control in the Code workbench.
- Mobile — the command outbox and session workbench tabs.
- Remote devices — the non-Mac hosts that run these same endpoints.