Pull Requests
The Pull Requests sidebar destination shows hosted pull requests for the
active repository. Strand supports GitHub, GitLab, Bitbucket Cloud and Azure DevOps, detected
from the repository's remotes; origin wins when more than one supported remote
exists. Open the same view from the command palette with "Show: Pull Requests".
Sign in#
GitHub and Azure DevOps Services delegate authentication to the provider's official CLI, and Strand never reads or stores those access tokens:
- GitHub requires GitHub CLI and
gh auth login. - GitLab requires glab and
glab auth login --hostname HOST(usegitlab.comfor the public service). - Bitbucket Cloud uses your system Git credential helper's HTTPS credential
for
api.bitbucket.org: Atlassian account email and a scoped API token. This API credential is separate from Git clone/push authentication. - Azure DevOps requires Azure CLI, the
azure-devopsextension, andaz login.
Settings → Hosting summarizes GitHub and Azure CLI connections. Its custom-host
section provides GitLab/Bitbucket setup and a provider selector for each remote.
Public hosts are automatic; select GitHub / Enterprise or GitLab for custom
hosts and refresh Pull Requests. GitHub Enterprise uses
gh auth login --hostname HOST; custom API routing follows gh configuration.
Hostnames are part of custom-host review identities, so drafts and follows do
not collide with the same repository name on another server.
Azure DevOps Server 2020+ uses the optional strand-azdo REST helper instead
of az. Enable it and add an HTTPS collection profile under Settings →
Hosting. PAT profiles work on every supported desktop and keep the token only
in the native credential vault; Windows profiles can use the current Windows
identity with Negotiate/NTLM. Private-CA PEM import is available for PAT
profiles. The collection URL automatically matches standard HTTPS and SSH clone URLs,
so Strand derives the project and repository from each Git remote. Leave the
collection field blank to derive and save it from the active repository. Additional
prefixes are needed only for server aliases; the longest match wins, with
origin preferred. Azure DevOps Services URLs are never routed through the
helper.
Packaged desktop builds import the interactive login-shell PATH, including
Homebrew, local-bin, and version-manager locations that GUI launchers normally
omit. Restart Strand after changing shell startup files or installing a CLI.
If the CLI is missing, signed out, or cannot access the repository, the view shows the provider error and the setup command. Provider calls time out after 30 seconds instead of blocking the app indefinitely.
Create a PR#
Choose Create PR in the Pull Requests toolbar, or run “Pull Requests: create for current branch…” from the command palette. The dialog creates a pull request or GitLab merge request from the checked-out branch with a title, Markdown description, target branch, and optional draft state. After creation, Strand opens the new PR and follows it automatically.
If the checked-out branch does not exist on the detected repository remote,
Strand pushes it before asking the provider to create the PR. A branch without
an upstream starts tracking that remote branch; an existing upstream on another
remote is preserved. A failed push leaves the dialog open and the PR is not
created. Authentication continues to use the signed-in gh or az CLI for
cloud providers, or the matched helper profile for Azure DevOps Server.
“Draft pull request with AI…” in the command palette opens the same dialog, resolves its default target, and then starts generation. AI generation itself does not push or create anything automatically.
Choose Fill with Codex or Fill with Claude Code to draft both editable
fields using the AI provider selected in Settings → AI. Strand compares the
selected target branch's merge base with local HEAD and sends that bounded,
committed diff to the configured vendor CLI. Staged and unstaged changes are not
included. If the fields already contain text, the button changes to Replace
so overwriting the current draft is explicit. AI generation does not push the
branch, contact GitHub/Azure DevOps, or create the PR; review and edit the result
before choosing Create pull request.
The dialog shows which AI provider produced the text and how much bounded diff context was included. Generation has a visible Cancel action, conservative sensitive-file include/exclude confirmation, Undo AI replacement, and an explicit retry with the other provider after non-authentication failures. The alternate retry does not change the provider selected in Settings.
Browse PRs#
The GitHub inbox initially loads 100 open, closed, and merged pull requests. Use Load more pull requests in the inbox footer to continue through older pages. The loaded count and total stay visible; search and filters apply to loaded rows. Azure DevOps retains its existing latest-100 inbox. Use the local search field to match a PR number, title, author, source branch, or target branch without starting another provider request. The filter tabs are:
- All — every returned status.
- Authored — every status authored by the account signed into
ghoraz. - Completed — merged and closed-without-merge PRs, with distinct badges.
If Strand cannot identify the signed-in provider account, All and Completed remain available and Authored shows a sign-in/refresh explanation. Search and filter state survive detail navigation and reset when the active repository changes. Run “Pull Requests: search…” from the command palette to return to the inbox and focus its search field.
If the checked-out branch has an active PR, Strand opens that PR automatically.
It also follows that PR in the background even if you never open Pull Requests.
Closed and merged PRs never auto-open. Otherwise, click a row to inspect it, or
use Up/Down or j/k and press Enter. Pull Requests in the detail
toolbar returns to the list and restores its keyboard focus. Open on host
hands the active PR to the provider website.
GitHub detail also loads reviews, threads, replies, comments, commits and checks in bounded pages. Load more checks/reviews/comments/commits appears beside its section; Code offers Load more review threads, and each thread offers Load more replies when needed. Counts describe loaded items, and incomplete checks cannot report readiness. Each active page request offers Cancel. Loaded items and drafts survive a failed or cancelled page. A source push requires Refresh before continuing to prevent mixing review coordinates. Both actions are available through “Pull Requests: load next data page” and “Pull Requests: cancel loading page” in Quick Launch.
Follow PR activity#
Choose Follow in a PR header, or run “Pull Requests: follow open pull request” from the command palette. Followed rows carry a bell badge. Strand persists followed PRs, their last successful activity snapshot, and the most recent worktree path for that hosted repository across relaunches. Switching branches may add another automatically followed PR; it does not remove earlier ones.
While Strand is running or minimized, it checks followed PRs after startup, every 60 seconds, and when the window regains focus. A single desktop notification per PR can summarize new non-system comments or thread replies, approvals or requested changes, newly failing checks or Azure policies, a new head commit, and merged or closed state. The first successful snapshot is only a baseline and never notifies. Merged or closed PRs notify once and are then removed from Following.
Strand checks desktop-notification permission when monitoring starts; a first manual follow requests it when the platform requires a prompt. On Windows, Strand reads Tauri's native desktop permission directly instead of WebView2's unrelated browser permission. Denying permission does not stop following: Strand keeps a persistent warning and a later manual Follow attempt can ask again. Explicitly choosing Following to unfollow mutes automatic following for that PR until you manually follow it again. Automatic removal after merge or close does not create that mute.
Provider or network failures keep the last successful snapshot and retry later, so a temporary outage cannot create false activity or turn an unknown check state green. Monitoring uses small provider activity queries and never fetches or parses patches.
For a draft PR, the detail header replaces Merge with Ready for review when the signed-in provider account can change that PR's stage. GitHub uses its viewer update capability; Azure DevOps presents the action conservatively for the signed-in PR author, and the provider remains authoritative if permissions changed. A successful transition refreshes the current detail in place and the normal Merge control appears. The command-palette action “Pull Requests: merge or mark ready…” follows the same rule.
For an active, non-draft PR, choose Merge in the detail header or run that command-palette action. The split merge control works like GitHub: its primary button immediately runs the selected strategy, while the adjacent chevron opens a keyboard-operable menu for merge-commit, squash, and rebase. Required checks, reviews, branch policies, and merge queues remain enforced by GitHub or Azure DevOps. Strand includes the exact source commit currently displayed in the merge request; if the branch changes before the action reaches the provider, the stale merge is refused and Strand asks you to refresh. The source branch is not deleted automatically.
In Merge options, GitHub repositories that require a queue expose Join merge queue, queue position when reported, and Leave merge queue. Other GitHub repositories expose Enable auto-merge and Cancel auto-merge when the provider permits them. Choose an allowed merge strategy before enabling. Immediate Merge uses GitHub's guarded merge endpoint; it does not silently queue the request.
Azure exposes Enable auto-complete and Cancel auto-complete, with a waiting for policies state instead of a queue position. Strand exposes Azure enablement conservatively to the signed-in PR author, and cancellation to that author or the existing auto-complete owner; Azure enforces current permissions. Azure Server requires helper protocol 7 with the new completion operation. Release distribution of that helper must accompany this app change.
Deferred completion remains controlled by provider policies and can include
later source pushes. GitHub enable/enqueue requests carry an atomic expected
head; Azure enablement rechecks the head and includes lastMergeSourceCommit.
Cancellation never merges code. Controls refresh after each request and when
activity reports a changed head. A failed request or refresh stays visible next
to the controls. Run “Pull Requests: merge queue or auto-complete…” in Quick
Launch to focus this surface.
The adjacent Pull request actions menu closes an active PR behind a second confirmation. A closed GitHub or abandoned Azure DevOps PR shows Reopen pull request there instead. Merged/completed PRs have no lifecycle or merge action. Summary and Timeline replace their composers with an explicit read-only state, and Code keeps inline threads visible without reply, resolve, or comment controls. These rules are shared by GitHub, Azure DevOps Services, and the optional Azure DevOps Server helper.
Directly below the PR title, the readiness strip combines the open/draft state, review decision, provider checks, merge conflicts or policy state, and the last reported update time. Select its status details disclosure to see the exact blockers or pending signals. Strand only shows Ready to merge when every reported signal is clear. Missing or unrecognized provider data is shown as Status incomplete; Azure policy/check detail that the current CLI path does not expose is never treated as success. The provider remains authoritative when you choose Merge.
The list loads only compact row data; Strand loads rich metadata only after a
PR is opened. This keeps large repositories below provider query limits and
means moving through the list does not start provider calls. Refreshing keeps
the current list or detail mounted, including focus, scroll, active tab, file
selection, and unsent drafts. The toolbar shows Updating…, the last update
age, or a non-blocking failure with Retry instead of blanking the workspace.
Lightweight activity reloads rich detail only when something changed. The
opened PR uses the full content width, starts directly beneath the compact PR
toolbar, and keeps its three tabs centered there. Use Left/Right, Home,
and End while the tab bar is focused.
Review tools#
In the Code toolbar, Mark reviewed saves the currently displayed source commit on this device, independently of file viewed marks and review drafts. Changes since last review… opens a comparison dialog. Choose a saved revision or Find previous reviews, then Show changes for a keyboard-navigable file list and one diff at a time. Arrow keys, Home and End move through files.
Comparisons use the exact two commit trees, including after a rebase or force push. Strand labels rewritten history and fetches missing objects without checking out a branch. If the provider no longer retains the old commit, the error leaves the boundary and previous comparison intact. A changed source head labels the previous result until you compare again.
Choose Pull request actions → Export unresolved feedback…, then Load all unresolved feedback. This explicit read traverses GitHub thread and reply pages; errors prevent a partial export from being presented as complete. Cancel read or closing the dialog stops further paging. Preview and Copy feedback include provider links, source commit, thread/comment IDs, authors, full replies, file and line-side context, and outdated/iteration markers. File-level feedback is included; GitHub top-level comments have no resolution state and are outside this export. The clipboard text is ready to paste into an external agent.
On a standard suggestion block in Code, choose Preview suggestion…. The selected suggestion is checked automatically and shown as Before and After. Use Open branch in worktree… first: the local HEAD must be the exact provider source commit, and the file must have no staged or unstaged changes. Apply to working file rechecks the head, comment body, range and previewed file content before writing. It preserves line endings and leaves the change unstaged for review. It does not submit a provider comment or commit.
Outdated, old-side, mixed-side, column or offset-form suggestions cannot be applied automatically. Azure suggestions also require the current iteration; unknown or old iteration coordinates are refused. Errors preserve the preview and review drafts. Source changes require reloading feedback and a new preview.
Quick Launch offers compare reviewed head…, mark head reviewed…, export unresolved feedback…, and preview suggestions… under Pull Requests. All open the same keyboard-operable dialog.
Summary#
Summary shows the source → target branch, reviewers, comment and commit counts, and aggregate file/addition/deletion totals as compact fact rows. Description and checks are collapsible. Descriptions render as Markdown without executing raw HTML or silently loading remote images. Checks are green when successful, yellow while running or queued, red when failed, and neutral when the provider does not report a recognized state. The compact comment composer is shared with Timeline, so an unsent draft survives tab switches and refreshes.
Timeline#
Timeline orders commits, GitHub issue/review-thread comments, Azure DevOps thread comments, and opened/merged/closed lifecycle markers newest-first on one chronology rail. Commit events show the author, subject, short hash, timestamp, and a provider link when available. Comments render as safe Markdown with author markers, timestamps, and inline file paths. Commit metadata is fetched only for the opened PR; newly detected pushes refresh this chronology without making the inbox query heavy or loading Code. GitHub and Azure profile images appear when the provider supplies a usable identity; initials remain visible if an avatar is absent or cannot load. Select a comment timestamp to open that comment directly on the provider host. File-backed comments also show View in Code. It switches to Code, selects the referenced file, and focuses the inline provider thread when line coordinates are available.
Use Write to compose a top-level comment and Preview to inspect the
rendered result before sending. The formatting toolbar supports bold, italic,
inline or fenced code, quotes, bulleted/numbered/task lists, links, and images.
Select existing text before choosing a format to wrap or prefix it. Choose
Comment or press Mod+Enter to send through the selected provider
connection. Cloud credentials remain in gh/az; Azure Server PATs remain in
the native credential vault.
The image action inserts standard Markdown for a screenshot or image that
already has an http(s) URL. This also works with image Markdown copied from
the provider website. Direct local-file upload is not currently available
because the supported GitHub and Azure provider paths do not share a stable
binary attachment API. Images in descriptions, previews, and comments stay unloaded
until you explicitly choose Show image, preventing a PR from silently
making a remote tracking request when opened.
Code#
Code loads only when its tab opens. Its aggregate strip shows source → target,
commit count, changed-file count, and total additions/deletions. A narrow left
rail groups changed files in the same Pierre folder tree used by Local Changes;
addition/deletion totals stay in the selected-file header instead of every
tree row. Use the folder chevrons
to expand or collapse paths; use Up/Down, j/k, Home, or End to
select a file. The rest of the full-width workspace renders the selected patch
edge to edge beneath the same compact, collapsible file header used by Local
Changes. Use the two layout buttons in that header to switch between stacked
and split diffs; the choice is saved per repository. Only one file diff is
mounted at a time to keep large PRs responsive. Provider patches larger than
16 MB are not rendered. For completed Azure DevOps PRs, Code reconstructs the
patch from the provider's recorded target and merge commits, so deleting the
source branch does not remove the historical diff.
Code also tracks review progress locally for the exact pull-request head and
each file's rendered patch. Choose Mark viewed or press v; if that file or
the PR head later changes, its check becomes changed instead of silently
remaining reviewed. The header shows viewed-file and unresolved-thread totals.
Use All, Unviewed, or Threads to focus the file tree, [ / ] or
j / k to move between files, and n / Shift+n to jump between unresolved
threads. These filters preserve the one-mounted-diff performance boundary.
On an open GitHub or Azure DevOps pull request, hover a line number and choose the + in its
gutter. Drag the + across adjacent lines to comment on a range, or drag across
line numbers and then use the + at the end of the selection. Strand
highlights the range and opens a compact composer directly beneath that code,
inside the diff. Add comment publishes a provider review thread
on that exact old- or new-file range; Mod+Enter sends from the composer.
Before publishing, Strand verifies that
the pull request head is still the commit used by the displayed patch; if it
changed, the draft stays in place and Code asks you to refresh and reselect.
Closed and merged pull requests stay read-only.
Choose Add to review in that inline composer to queue the selected range instead of publishing it immediately. Review in the Code header opens the exact-head review draft, where pending comments can be removed and a Markdown summary can be written or previewed. Submit the whole draft as Comment, Approve, or Request changes; requesting changes requires a summary. The same composer is reachable from the command palette with “Pull Requests: submit review…”. Drafts survive leaving the tab and provider failures, but a new source commit makes the old draft visibly stale and blocks submission until it is discarded or rewritten against the refreshed patch. GitHub sends the summary and pending inline comments as one review pinned to that commit. Azure DevOps Services and Server resolve the latest provider iteration and each file's change-tracking ID, recheck the exact head, then publish the decision, inline comments, and optional summary in that order. Azure review submission is several provider writes, so a partial failure names what was already posted and preserves the draft for manual reconciliation.
When a new head commit is detected, Strand keeps the existing patch visible while the replacement loads and labels it stale. Inline-comment submission is disabled until the new patch succeeds, so comments cannot be anchored to old coordinates. Background monitoring never reloads a patch when the head SHA is unchanged.
Fetched GitHub and Azure DevOps review threads remain visible directly beneath their anchored line or range. Replies stay grouped in the same card, and resolved or outdated threads are labeled. The same review comments also appear in Timeline, so comments added on either provider are visible after refreshing the pull request.
On an open pull request, writable GitHub and Azure thread cards expose
Reply and Resolve or Reopen. Replies publish immediately; use
Mod+Enter to send or Esc to close the reply editor without losing its draft.
Successful writes update both the inline card and Timeline without
reloading the patch or moving your current file and scroll position. These
actions target the existing provider thread rather than creating another
line-coordinate discussion. Azure Services uses the signed-in az CLI, while
Azure Server uses its configured helper profile.
Submitted reviews appear in the Summary tab. When GitHub reports that your account may update a review, Edit summary changes its Markdown body. When the pull request and review are eligible for dismissal, Dismiss review… requires a reason before the provider write is enabled. Azure DevOps votes do not have an editable review body; Strand instead offers Reset my vote only on the signed-in reviewer's current nonzero vote. Every successful action refreshes rich detail so revoked capabilities and provider state take effect immediately. These controls are absent on terminal pull requests.
Azure policy evaluations participate in readiness when their dedicated query
succeeds. A failed or incomplete policy query remains unknown instead of being
treated as green. Azure inline comments never infer coordinates from the patch:
Strand resolves the displayed head to the latest iteration, pages that
iteration's cumulative change list, maps the file to its provider
changeTrackingId, and rechecks the head immediately before publishing.
Open pull requests can be closed after confirmation, and closed/abandoned pull
requests can be reopened when the provider grants permission. The PR overflow
menu also exposes Open branch in worktree… for GitHub and Azure. Strand
verifies the provider's current source commit, fetches that exact object without
creating a PR ref or writing FETCH_HEAD, and opens the normal New worktree
dialog with a derived pr-<number>-<source> task branch. An existing local
branch is reused only when it already points to that exact commit; otherwise
Strand proposes a suffixed branch instead of opening stale code.
Open GitHub pull requests additionally expose Update branch from target. The provider request includes the source commit displayed by Strand, so a head change fails closed instead of updating code that was not reviewed. Azure DevOps does not expose the same safe source-branch update operation; use the exact-head local worktree action there. The worktree command is available while any PR is active, and the update command appears only for an open GitHub PR; both contextual commands disappear on the inbox.
Suggestions and richer Azure policy details are planned but are not presented as available yet.
GitLab and Bitbucket Cloud#
Both adapters page their lists, commits and discussions to completion; a failed page is an error rather than a complete-looking partial result. Rich detail loads on selection and patches load only on Code. Activity refreshes do not download patches or commit history. Pipeline/commit status alone is not treated as a complete view of provider merge policies.
GitLab supports comments, approvals, inline replies and resolution, close/reopen, mark-ready and merging with the project's merge method or squash. Inline comments preserve diff-version base/start/head commits and renamed-file paths. Approval and merge include the reviewed SHA. Request changes remains available on GitLab's website.
Bitbucket Cloud supports comments, inline replies, approval, request-changes and closing a request. Merge, discussion resolution, reopening and draft transitions remain provider-site actions. Cloud's merge API cannot atomically guard the reviewed head, so Strand does not offer that write. Inline comments and review decisions recheck the head before and after writing; the API cannot pin them atomically. If the head changes during a write, inspect the posted result before retrying. Fork checkout also requires opening the source fork locally. Bitbucket Server is outside this adapter's scope.
GitLab and Bitbucket review batches consist of separate API writes. A failure retains the draft and reports confirmed progress: refresh and reconcile posted items before retrying to avoid duplicates. Provider permissions remain authoritative even when a control was enabled by the last refresh.