Merge requests
GitHub pull requests and GitLab merge requests are the same object in Strado.
One shape, one chip, one review pane — the provider only decides which API is
called and whether the chip reads # or !.
What you see
A branch with an open request gets a chip on its board row carrying the number, the state, and a glyph for the CI result. Clicking it opens the review in the app; middle-clicking or copying the link still takes you to the provider.
Beyond number and state, Strado reads the title, the source and target branches, the author, the timestamps, and the pipeline or check result. GitLab projects with approval rules also report approvals given against approvals required, while the request is still open — a merged or closed one carries no approval count. GitHub does not report approvals at all.
Opening one
From the diff overlay. You pick a target branch from the remote branches the repo actually has, give it a title and an optional description, and Strado opens the request from the worktree's current branch.
Opening from a detached HEAD is refused: there is no source branch to name.
Merging is also available from the app once the request is open.
Connecting a provider
Both live under Settings, then Connections, and both work the same way: enter the host, paste a token, and Strado validates it against the provider before saving anything.
| GitHub | GitLab | |
|---|---|---|
| Host | github.com or your Enterprise domain | your GitLab domain |
| Token scope | classic: repo. Fine-grained: Contents and Pull requests, read and write | api |
| Validated against | GET /user | GET /api/v4/user |
| Stored at | ~/.strado/github.json | ~/.strado/gitlab.json |
Heads up
A read-only fine-grained GitHub token connects successfully and then fails later. Validation only asks who you are, which a read-only token can answer, so the connection succeeds and chips populate normally — and then opening or merging a pull request fails, because both are writes. If the two sections above did not work but everything else did, this is why.
Strado creates both files with mode 0600 — though the mode applies at
creation only, so one that already existed keeps the permissions it had; see
files and locations. The server never
gives a token back:
reading the configuration returns the list of connected hosts and nothing else,
so the token is write-only from the UI's point of view.
Removing a host deletes its entry from the file.
Two accounts on one host
Note
Per-owner tokens are a GitHub-only feature. GitLab tokens are stored per host, one token per host, with no owner dimension.
On GitHub, the connection form has an optional owner field — an org or a username. Fill it in and the token is stored against that owner specifically; leave it blank and it is stored against the bare host.
Lookup then goes owner first, host second:
| Entry | Matches |
|---|---|
github.com/acme | repos under the acme owner |
github.com | everything else on that host |
The owner Strado matches is the first path segment of the repo's origin URL.
So a work token saved under github.com/acme serves your employer's repos, and
a personal token saved against the bare github.com catches the rest.
SSH aliases
Multi-account git setups usually give each account its own ~/.ssh/config
alias, and the repo's remote then names the alias rather than a real host —
git@github-acme:acme/thing.git. That name means nothing to a host check.
When Strado does not recognise a remote's host, it asks OpenSSH what the name resolves to, using the same config evaluation git itself performs, and classifies the real hostname instead. The lookup is local: no network, no authentication, only your ssh config.
Three things worth knowing about when it fires:
- Only for SSH remotes. An HTTPS remote cannot carry an alias, so it is never probed.
- Only after the direct host check fails. A remote that already names a recognised host resolves without any ssh call.
- It fails closed. No
sshbinary, a bad host, or a resolution slower than three seconds all mean "not an alias", and the repo is treated as having no provider rather than being guessed at.
Results are cached for as long as the app runs, since aliases essentially never change.
When no token matches
The request pane reports that the provider needs authentication rather than failing quietly. The same happens mid-session if a token is revoked or expires — the next poll comes back asking you to reconnect.
A repo whose origin is neither a known GitLab nor a known GitHub host has no
request feature at all. Nothing is shown and nothing errors.