feat(web): show draft pull requests as drafts in the sidebar - #219
Merged
Conversation
A draft pull request rendered in the sidebar exactly like one that is ready for review: emerald `#123`, and a tooltip reading "PR #123 - Open". The pull request panel already muted drafts, so the same pull request looked like two different things in two places. `isDraft` now travels with the change request: optional on the `ChangeRequest` and VCS-status contracts, decoded by all four source control adapters in their own spelling, and carried through `GitManager` into thread status. GitHub is the only provider that needed new request fields, and they ride along on calls it already makes. The sidebar takes its state and tone from `resolvePullRequestState`, the resolver the pull request panel uses, which replaces a parallel colour switch. Drafts read muted zinc with a "Draft" tooltip; merged and closed still outrank the flag. Mobile is unchanged: gray already means "closed" there, so it needs a different answer than tone. Written by an agent (Claude Code, claude-opus-5).
incognitojam
marked this pull request as ready for review
August 20, 2026 09:56
incognitojam
added a commit
that referenced
this pull request
Aug 20, 2026
> [!NOTE] > TL;DR: Add ledger coverage for the seven substantive fork capabilities merged after the latest nightly promotion, so the next upstream rebase reports their semantic overlap before release. The fork feature ledger did not yet cover draft pull request status, missing-workspace startup guards, attention-state sidebar prominence, provider subscription limits, active-terminal close confirmation, fork analytics identity, or arbitrary file attachments. This records the behavioral invariants, implementation and upstream watch paths, focused test evidence, and retirement criteria for PRs #219, #222, #224, #225, #226, #227, and #228. Draft status and terminal close confirmation cite their partial upstream counterparts in [upstream pingdotgg#7148](pingdotgg#7148) and [upstream pingdotgg#7592](pingdotgg#7592). The smaller #220, #221, and #223 fixes intentionally remain patch-stack-only under the ledger's incremental coverage policy. The ledger mutation tests now select fixtures by the property they need instead of assuming the alphabetically first capability has multiple PRs and an unassessed upstream status. Verification: - `vp run --filter @t3tools/scripts ledger:check` - `vp test run scripts/fork-feature-ledger.test.ts scripts/generate-fork-features-summary.test.ts` — 34 tests passed - `vp check .github/fork-features.yml scripts/fork-feature-ledger.test.ts` --- Written by an agent (T3 Code, gpt-5.6-sol).
yngatech-nightly Bot
pushed a commit
that referenced
this pull request
Aug 20, 2026
> [!NOTE] > A draft pull request looked identical to one ready for review in the sidebar — emerald `#123`, tooltip reading "Open". It now reads muted with a "Draft" tooltip, using the same resolver the pull request panel already used. Web only; mobile needs a different answer. ## The problem `prStatusIndicator` branched on `pr.state` alone, so a draft rendered exactly like a pull request that was ready for review. The tooltip said `PR #123 - Open`, and that string is also the link's `aria-label`. The pull request panel already got this right — `resolvePullRequestState` mutes drafts and its comment says the tones are shared "so one pull request cannot look like two different things in two places". The sidebar was the exception. ## The fix `isDraft` now travels with the change request. It is optional on both `ChangeRequest` and the VCS-status contract, so an old server or a provider that does not report it reads as "not known to be a draft" rather than silently claiming ready-for-review. All four source control adapters decode their own spelling: GitHub `isDraft`, GitLab `draft` with the pre-14.0 `work_in_progress` fallback, Bitbucket `draft`, Azure `isDraft`. Only GitHub needed new request fields, and they ride along on `--json` calls it already makes — no extra round trip. GitLab, Bitbucket and Azure were already returning the field in payloads that were being discarded. On the client, the sidebar now takes its state word and tone from `resolvePullRequestState`, which removes the parallel colour switch and leaves one place to change a tone. Merged and closed still outrank the flag: a draft that lands reads Merged. Two supporting changes that are easy to miss: - `threadChangeRequestSnapshotsEqual` compares `isDraft`. Without it, "Ready for review" would not repaint the row. - `settledPrHoverColorClass` takes the pull request rather than just its state, so hovering a settled draft no longer restores emerald and announces it as ready. ## Scope Mobile is deliberately untouched. `text-zinc-500` already means **closed** in `thread-pr-presentation.ts`, so painting drafts gray there would make the two indistinguishable on the surface with the smallest tap target. It needs a glyph rather than a tone, which is its own change. `isDraft` reaches mobile on the wire and is ignored. ## Before / after The same real draft pull request (this one), on the same seeded sidebar. Before, it is emerald and its tooltip reads `PR #219 - Open`; after, it is muted and reads `PR #219 - Draft`. | Before | After | | --- | --- | | <img src="https://raw.githubusercontent.com/yngatech/t3code/assets/pr-219-draft-pr-number/before.png" width="420" alt="Sidebar thread row showing #219 in emerald"> | <img src="https://raw.githubusercontent.com/yngatech/t3code/assets/pr-219-draft-pr-number/after.png" width="420" alt="Sidebar thread row showing #219 in muted gray"> | ## Verification `ThreadStatusIndicators` and the full `sourceControl` suite pass (204 tests), `GitManager` passes (89). Typecheck is clean on web, server, contracts, client-runtime, desktop and mobile. New tests cover a draft round trip per provider adapter, a `GitManager` status test asserting a draft arrives as `isDraft: true`, and on the web side the muted tone, the `Draft` tooltip, merged-outranks-draft, the hover tone, and both snapshot-equality cases. --- Written by an agent (Claude Code, claude-opus-5).
yngatech-nightly Bot
pushed a commit
that referenced
this pull request
Aug 20, 2026
> [!NOTE] > TL;DR: Add ledger coverage for the seven substantive fork capabilities merged after the latest nightly promotion, so the next upstream rebase reports their semantic overlap before release. The fork feature ledger did not yet cover draft pull request status, missing-workspace startup guards, attention-state sidebar prominence, provider subscription limits, active-terminal close confirmation, fork analytics identity, or arbitrary file attachments. This records the behavioral invariants, implementation and upstream watch paths, focused test evidence, and retirement criteria for PRs #219, #222, #224, #225, #226, #227, and #228. Draft status and terminal close confirmation cite their partial upstream counterparts in [upstream pingdotgg#7148](pingdotgg#7148) and [upstream pingdotgg#7592](pingdotgg#7592). The smaller #220, #221, and #223 fixes intentionally remain patch-stack-only under the ledger's incremental coverage policy. The ledger mutation tests now select fixtures by the property they need instead of assuming the alphabetically first capability has multiple PRs and an unassessed upstream status. Verification: - `vp run --filter @t3tools/scripts ledger:check` - `vp test run scripts/fork-feature-ledger.test.ts scripts/generate-fork-features-summary.test.ts` — 34 tests passed - `vp check .github/fork-features.yml scripts/fork-feature-ledger.test.ts` --- Written by an agent (T3 Code, gpt-5.6-sol).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Note
A draft pull request looked identical to one ready for review in the sidebar — emerald
#123, tooltip reading "Open". It now reads muted with a "Draft" tooltip, using the same resolver the pull request panel already used. Web only; mobile needs a different answer.The problem
prStatusIndicatorbranched onpr.statealone, so a draft rendered exactly like a pull request that was ready for review. The tooltip saidPR #123 - Open, and that string is also the link'saria-label.The pull request panel already got this right —
resolvePullRequestStatemutes drafts and its comment says the tones are shared "so one pull request cannot look like two different things in two places". The sidebar was the exception.The fix
isDraftnow travels with the change request. It is optional on bothChangeRequestand the VCS-status contract, so an old server or a provider that does not report it reads as "not known to be a draft" rather than silently claiming ready-for-review.All four source control adapters decode their own spelling: GitHub
isDraft, GitLabdraftwith the pre-14.0work_in_progressfallback, Bitbucketdraft, AzureisDraft. Only GitHub needed new request fields, and they ride along on--jsoncalls it already makes — no extra round trip. GitLab, Bitbucket and Azure were already returning the field in payloads that were being discarded.On the client, the sidebar now takes its state word and tone from
resolvePullRequestState, which removes the parallel colour switch and leaves one place to change a tone. Merged and closed still outrank the flag: a draft that lands reads Merged.Two supporting changes that are easy to miss:
threadChangeRequestSnapshotsEqualcomparesisDraft. Without it, "Ready for review" would not repaint the row.settledPrHoverColorClasstakes the pull request rather than just its state, so hovering a settled draft no longer restores emerald and announces it as ready.Scope
Mobile is deliberately untouched.
text-zinc-500already means closed inthread-pr-presentation.ts, so painting drafts gray there would make the two indistinguishable on the surface with the smallest tap target. It needs a glyph rather than a tone, which is its own change.isDraftreaches mobile on the wire and is ignored.Before / after
The same real draft pull request (this one), on the same seeded sidebar. Before, it is emerald and its tooltip reads
PR #219 - Open; after, it is muted and readsPR #219 - Draft.Verification
ThreadStatusIndicatorsand the fullsourceControlsuite pass (204 tests),GitManagerpasses (89). Typecheck is clean on web, server, contracts, client-runtime, desktop and mobile.New tests cover a draft round trip per provider adapter, a
GitManagerstatus test asserting a draft arrives asisDraft: true, and on the web side the muted tone, theDrafttooltip, merged-outranks-draft, the hover tone, and both snapshot-equality cases.Written by an agent (Claude Code, claude-opus-5).