Repository navigation
Put a site's server and build watch in the page header and the details - #595
Conversation
The first part of #557, following the prototype: the Server section and the process menus. The page's header gains a menu for each of the site's two processes, which says what the process is doing and holds the one thing to do about it, and the button that opens the review. The site's details gain a section for each process: the server's says where the site, its admin and its database are once it has an address, and what to log in with; the build watch's says what it is doing. Each section has a button of the same name as the header menu's item. What both places say is decided in site-processes.cjs, so they cannot disagree. The row of three large buttons at the top of the site's cards is gone, with the line of links under it. A server that is starting can no longer be pressed. The button says it is starting and is held, as is the menu's item. Before, it could be pressed and did nothing. Two things the taller details and the fuller header needed. The details stay in view only while they fit in what is in view; taller than that they scroll with the cards, or their own end would be out of reach until the page's end. And the header's actions give way by the page's width: short of room, the two processes are their dots and the review button is its first word, so that the site's name is not what is squeezed out. At a 1024px window it was squeezed to nothing. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…resting on them The journey for a header short of room now resizes the window twice: to the width of the smallest screen the suite runs on, where the processes' words give way, and to the smallest the window can be made, where the review button's do. At one width alone, the rule for the other could be removed and nothing noticed. The journey for the details checks the taller case part of the way down the page, from its top. At the page's end a column held in place is pushed out of view as well, so the check there passed either way. The journeys open "Open in" by resting on it, as a pointer does. A click could land after the pointer's arrival had already opened the menu, and close it: one run in a dozen failed on it. The site's name no longer has a minimum width of its own. With the actions giving way by the page's width it always has room, and no test could show the rule doing anything. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The first review of the server and build watch slice, applied. A build that fails before the watch can start was said as a watch that ended. The hook now says which of the two ended, and the details say it of the build. Every end nobody asked for is drawn as failed, with the code when there is one. What the server's section shows is decided in site-processes.cjs, with the links and the starting sentence, which is translatable now. The header's server menu has the site and its admin above its one action, since the details can be put away. In the journeys: the header's process menus are reached through one helper; the dev server's journey says that a second press is held by the button and no longer presses twice; where the window is, is asked of the main process after a round trip; and a fourth translation journey scans the two processes stopped, starting and running. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The second review of the server and build watch slice, applied. Stopping the watch while the build before it runs kills that build, and a killed process ends with no code, or on Windows with one of its own. Either was taken for a failure: a red dot, and the details saying the build had failed. The build's end is now left alone when a stop has already said the watch is idle, and Ctrl+C in the terminal, which that build holds, says so before it kills, as the button does. Which links the header's menu is given is decided in site-processes.cjs, with the rest of the server's section. In the journeys: a third build watch journey stops the build by the button and by Ctrl+C; the dev server's journey drops a count that could no longer fail; and the translation journey waits for the server and the watch to have been asked for before it speaks for them. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository: WordPress/contributor-toolkit/.coderabbit.yaml Review profile: CHILL Plan: Advanced Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
## Why #557 rebuilds what is inside the site's page, as the [prototype](https://github.com/jameskoster/wordpress-contributor-toolkit-prototype) draws it. This is item 3 of its nine, the ticket card: where a site links the Trac ticket or the GitHub issue it is working on, and reads what already exists on it. It was about 300 lines of inline markup in the middle of the site's view, in the old look. **This PR targets `redesign/wpds`, not `trunk`.** ## What changes - **The card is drawn with the design system**, as the prototype has it: a card with a title, "Trac ticket" or "GitHub issue"; with nothing linked, a field, its button and the way to find a first ticket; with one linked, the ticket's number and summary as the way to it, what Trac said of it, and under that its pull requests and, on Trac, its attachments, each as a list hanging from its heading. - **It is a component of its own**, `ticket-card.jsx`, and what it says is decided in `ticket-card.cjs`: its words for a ticket and for an issue, what Trac said as a badge and a line of facts, each row, and what each list says besides its rows: reading, empty, or failed and with what in its place. It has unit tests of its own. - **Its strings are translatable.** A ticket and an issue get whole sentences each; before, one sentence had the noun put into it. - **A button that is held still says why**, in the design system's button: `ReasonedUiButton`, beside the old one, which the rest of the page still uses. - **The two "Refresh" buttons are named for their lists**: each is its word and then its section's heading, as both are on screen. Each shows the one word. - **The notice that trunk has moved is still said to a screen reader.** The old block was a status region. The design system's notice says what is in it, and with a held button in it that reading fails and says nothing, so it is told its sentence. - **One sentence named a button that was not there.** After Trac's window was closed the card said to click "Show Trac attachments", which is gone once a read has answered. It says "Refresh". **Deliberately not in this PR:** - the pull request's banner, the note about uncommitted changes, and what a link or a switch says back: they are made by the site's view, placed in the card, and keep their old look until items 4 and 9; - the "Apply a patch or PR" card under it (item 4) and the list of a site's other tickets (item 5). ## How to test this Platforms: any. Use the Buildkite build for the current head of this branch. The journeys carry this. From the repository root, `npm run test:e2e` runs them all; `tests/e2e/journeys/ticket-card.spec.js` is new: - with nothing linked the card asks for a ticket and its button waits for one to be typed; the way to find a first ticket, the ticket's number, its component, a pull request's title and an attachment's name each open their page through the main process; - linking reads the pull requests and the ticket once each with nothing more pressed; the card then says the ticket's summary, status and facts, each pull request's number, state and date, and each attachment's uploader, age and size; - a list that could not be read says why and keeps the rows it last had, or says there is nothing to fall back on; an empty one says it is empty; Trac's window closed early is said as that, and not as "no attachments"; - a site opened with a ticket already linked does not go to Trac until asked, and offers to in both places; asked once, it fills in both; - while a build runs, Unlink, the field and Link are held, say why as their description, can still be reached, do nothing when pressed, and come back as the same buttons. `ticket-rebase.spec.js` now also holds that the notice about trunk having moved is said, by recording what the page's live regions say. `i18n.spec.js` gains the card in the pseudo-locale, with nothing linked, with a ticket and its lists, and with a failed and an empty list. `pr-checkout`, `ticket-branches`, `gutenberg-site` and `open-pull-request` now find the linked ticket by its number in the card. What they cannot reach is how it looks, and the real Trac: **Starting state:** a Core site that has finished setup, with no ticket linked. 1. In "Trac ticket", type `62281` and click "Link ticket". Trac's window opens for its human-check; pass it. The card shows `#62281` with the ticket's summary, a badge with its status and a line of facts, then "Linked pull requests" and "Trac attachments", each row with a tick to the rule down its side. 2. Click the ticket's number. The ticket opens in the browser; the app's window does not change. 3. Click "Refresh" beside "Linked pull requests" with the network off. A yellow notice says GitHub could not be reached and, under that, when the list on screen was read; the rows stay. **What must not have happened:** - Opening the app with a ticket already linked does not open Trac's window by itself. - "Unlink" during a build or an update does nothing, and says why on hover. ## Risks and limitations - **The explicit "Open in Trac" button is gone.** The ticket's number and summary are the way to it, with "Open in Trac" as the tooltip, as the prototype has it. A newcomer has to recognise a link. - **"Unlink" is no longer red.** It is a plain button in the card's header, as in the prototype. It parks the ticket's work and loses nothing, which red overstated. - **The linking prompt is shorter.** It no longer says the ticket is stored with the site, survives restarts and can be changed or removed. The prototype's sentence is "Link the ticket you're working on." - **Three things inside the card keep the old look**: the checked-out pull request's banner, the note about uncommitted changes, and what a link or a switch says back. They are the site's view's and are redrawn with items 4 and 9. - **"Apply…" and "Show Trac attachments" are held during a build, an install, an update or an apply with no stated reason**, as before; held buttons of the design system can now be reached by keyboard, so the missing reason is met more often. Several "Apply…" buttons share one name, as before. Both go with item 4, which redraws the apply. - **Announcements can overwrite one another.** Right after a link, "Linking ticket", "Checking GitHub" and "Reading the ticket on Trac" are put in the one live region in quick succession; and a refresh that fails twice with the same sentence is said once. The first is how the design system's loading buttons speak. - **The sentence the stale-ticket notice speaks is its two sentences joined with a space**, and those two, with every reason a button is held for, are not translatable yet: they come from modules this PR does not touch. The translation journey does not reach that state. - **For a moment after a build ends, "Unlink" can be pressed and is turned away** with "A command is already running": the card's buttons come back before the terminal does. It is older than this card, and longer on a slow disk; CI's Windows runner found it. Left for its own fix on `trunk`. - **Section headings are as large as the card's title**, as in the prototype. - **The guide pages still show the old card.** #561. - **About 1,475 lines added, 680 of them tests**, against about 360 removed. It is one pull request because the card is one block of the site's view: it could not be half moved. - **The manual steps above were not run by a person**: they need Trac's human-check. I looked at screenshots of the card with nothing linked, with a ticket and its lists, with a failed read of each list, and in a 1024px window. - **Checked on macOS only**, with the journeys this touches also run in a window resized to the Windows runner's 1024×728. Windows itself is CI's. - **Pre-PR review, two passes: everything marked to fix here was fixed, nine findings, two of medium weight; nine follow-ups are left**, all in this list or in the review outcome. The medium two were a notice that was no longer said to a screen reader, and a journey whose stand-ins could be late. ## Related Part of #557 (item 3 of its nine) and #542. Fourth slice on `redesign/wpds`, after #590, #594 and #595. --- <details> <summary>Design decisions and alternatives considered</summary> **The ways out are buttons drawn as links.** The prototype has anchors. They were buttons in the old card, and the main process opens the page; an anchor would also be something the window itself could follow. **The heading is the way to the ticket.** The old card had the number in a pill and an "Open in Trac" button beside it. The prototype makes the number and the summary the link; "Open in Trac", or "Open on GitHub", is its tooltip. **"Milestone:" is labelled.** The prototype's line reads "Defect (bug) · General · 7.2 · Opened 4 weeks ago". A real ticket's milestone is as often "Awaiting Review" or "Future Release", which beside a status badge reads as a second status. **"Apply…" keeps its dots.** The prototype says "Apply" and opens a dialog. Here the button reads the patch into the card below, which item 4 redraws; the dots say that it does not apply yet. **A closed pull request has no colour, a merged one is blue.** The old pill used GitHub's own three colours. The design system's badge has no purple, and its red means that something failed, which a closed pull request has not (#227). **"Read details from Trac" stays**, where the prototype has no such button: it always has the details. Reading them opens Trac's window and may ask for a human, so the app does it once after a ticket is linked and afterwards only when asked. **`pr-state.cjs` stays**, and the card's badge takes from it which of the three a state is. The apply's preview still draws its old pill from there, until item 4. </details> <details> <summary>Review outcome (required — see AGENTS.md)</summary> Run as the repository's review procedure, with the judgement pass in a fresh context that took no part in the change. First pass on `fde8836` against `5388e5d`; second pass on the fix-up `9b7a6ef`; `86bd6b5` applies what the second pass asked for, and the head, `4b0f828`, corrects a journey after CI. **First pass: five findings to fix here, eight follow-ups; two medium, none high.** It compared the removed block with the new card line by line and found every gate unchanged: when "Apply…" is hidden and held, when each "Refresh" and "Show Trac attachments" show, what holds Unlink, Link and the field, the Enter key, the next-action cue, and the spacing of what is handed into the card. Fixed: - **The notice that trunk has moved was never said** (medium). The design system's notice says its content by rendering it to a string, the held button in it cannot be rendered that way, and the failure is swallowed. The notice is told its sentence, and `ticket-rebase.spec.js` holds that it is said, red without the fix. - **The journey that reopens a site with a ticket linked installed its stand-ins after the window existed** (medium), so the first read of the pull requests could go to GitHub and a read of Trac made early would not be counted. A session can now run a journey's code before its window is waited for, and the journey checks that its stand-in answered that read. - **"A press on a held Unlink does nothing" could not fail**: the journey read the branch before a press that got through could have moved it. It now reads what the card would say at once if the press had got through. - **Two controls were named in two journey files** and are in the shared helpers; `TESTING.md` no longer counts them. - **Translation**: two sentences that quote a button now say so to translators; a failed read is two lines and not two sentences joined with a space, and so is the way to a first ticket; each Refresh is named from the two strings on screen, so its name cannot disagree with what it shows. Three follow-ups were done here too: the ticket field's helper matches a whole label; the registry's unused browse label is gone; a held button's reason is no longer also read as a sentence of its own. And the component is labelled "Component:", which following the prototype had dropped. **Second pass: four findings to fix here, three follow-ups; all low.** It read the design system's button, tooltip and notice and confirmed the names, the description and the spoken sentence reach the page as intended, and that the fourth journey's premise holds: a press that got through raises an alert in the card before anything is asked of the main process. Fixed: - **A count in that journey could not tell the two cases apart**, for the reason above: removed, with the wrap that fed it. - **The rebase journey's record of what was said kept only the last of two messages put in a region in one turn.** It keeps what each change put there. - **Two comments named one of the two places the registry's label is read.** - A comment line ran long. Two follow-ups were done here: a session checks its throwaway profile before a journey's code runs against the app, and the attachments' failure is told to a screen reader as written, since read out of its markup an "&" in an error would be said as "&". Left as follow-ups, all in Risks above except the last two: no stated reason on "Apply…" and "Show Trac attachments"; several "Apply…" with one name; announcements overwriting one another; the stale notice's spoken sentence joined in the component, to move to its module when that module is translated; heading sizes; the shorter prompt; the guide pages; a few small decisions still in the component (when a row's button is held, when "Refresh" shows); and two notices that still say what is in them the default way, which works for what they hold. **After CI: one journey corrected.** The journey that holds the card's buttons during a build was red on Windows, on both attempts, at the Unlink it presses once the build has ended. When a build ends the card's buttons come back at once and the terminal a moment later, after the site's status has been read again; a press in between is turned away with "A command is already running". On macOS that read is over before the journey presses, and on the Windows runner it is not. The journey now waits for the terminal's hint to be a link again. The failure was reproduced here by slowing the status read by a second and a half, and the corrected journey passes with it slowed. The gap itself is the app's and older than this card: see Risks. **Checks, on macOS, on `86bd6b5`; the head differs from it in that one journey, which was run again on the head, also in the small window:** | Check | Result | | --- | --- | | `npx eslint . --max-warnings=0` | clean | | `npm test` | 1811 pass, 2 skipped | | `npm run test:electron` | 1812 pass, 1 skipped | | `npm run test:e2e` (journeys) | 78 of 78 | | `npm run test:e2e:packaged` | 15 of 15, on an unsigned `npm run pack:dir` build of the head | | Eight journey files that reach the card or restart the app, in a 1024×728 window, the Windows runner's | 28 of 28 | **The tests' claims were audited by breaking each one** in the source and running the test that should notice. 36 breaks, and all 36 turn a journey red on a line that states the claim. 34 were run on the head; two, marked below, on the commit before it, whose lines the head does not touch. One claim is not shown red: that the reopened site's first read of the pull requests was answered by the stand-in. Making the stand-in late enough to show it would send that read to GitHub. | Break | Caught by | | --- | --- | | The way to find a first ticket goes nowhere | `ticket-card` | | An empty field can be linked | `ticket-card` | | The ticket's number goes nowhere | `ticket-card` | | The ticket does not say where it goes | `ticket-card`, `gutenberg-site` | | What Trac said of the ticket is not shown | `ticket-card` | | When the ticket was opened has no date behind it | `ticket-card` | | The component is not a way to its tickets | `ticket-card` | | "Read details" stays after the ticket has been read | `ticket-card` | | A pull request does not say its state | `ticket-card` | | A pull request does not say when it last moved | `ticket-card` | | A pull request's title goes nowhere | `ticket-card` | | An attachment does not say who uploaded it | `ticket-card` | | An attachment's name goes nowhere | `ticket-card` | | A patch cannot be read from its row | `ticket-card` | | A list that could not be read says nothing | `ticket-card` | | A list that could not be read loses its rows | `ticket-card` | | A failed read does not say there is nothing to fall back on | `ticket-card` | | A failed read says why and not what is shown instead (on `9b7a6ef`) | `ticket-card` | | An empty list says nothing | `ticket-card` | | A read Trac did not answer is said as "no attachments" | `ticket-card` | | A failed read of the attachments says nothing | `ticket-card` | | An unread ticket offers no way to read its attachments | `ticket-card` | | A Refresh button is named by its word alone (on `9b7a6ef`) | `ticket-card` | | A held button does not say why | `ticket-card` | | A held button cannot be reached | `ticket-card` | | A press on a held Unlink gets through | `ticket-card` | | The field is not held during a build | `ticket-card` | | The stale-ticket notice is not told what to say | `ticket-rebase` | | The checked-out pull request's banner is under the ticket's number | `pr-checkout` | | A checked-out pull request can still be applied from its row | `pr-checkout` | | A Gutenberg site's card is worded for Trac | `gutenberg-site` | | A Gutenberg site's card has Trac's attachments | `gutenberg-site` | | A section's heading is not translatable | `i18n` | | A fact's label is not translatable | `i18n` | | A state's word is not translatable | `i18n` | | A failure's sentence is not translatable | `i18n` | The audit also changed the code once: a prop on the held button turned out to do nothing the design system's button does not already do, and was removed. </details> 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
…dialog (#597) ## Why #557 rebuilds what is inside the site's page, as the [prototype](https://github.com/jameskoster/wordpress-contributor-toolkit-prototype) draws it. This is item 4 of its nine, apply patch and PR checkout: the card a pull request or a patch file is brought into the checkout from, the preview of what one would change, and the banner of a pull request that is checked out. It was about 250 lines of inline markup in the site's view, in the old look. **This PR targets `redesign/wpds`, not `trunk`.** ## What changes - **The apply card is drawn with the design system**, as the prototype has it: a card that can be folded, with a tab for each way in on a project that takes patch files, "Pull request" and "Diff", and the pull request's field alone on one that does not. - **What a patch would change is shown in a dialog** before it is applied, where it was a block in the card: its files, whose work it would land on, anything that changes what applying it means, and the button that applies it. - **The applied patch, a failure with its breakdown, and the checked-out pull request are the design system's notices.** The ones that were alerts or status regions still are. - **It is a component of its own**, `apply-card.jsx`, with what it decides in `apply-card.cjs` and unit tests beside it. Its own strings are translatable. The dialog is in front of the page, and that changed four things about the flow: - **A failed apply drops its preview.** It used to stay on the card beside the error. A dialog would come back in front of the error, so the error is read on the card and the patch is chosen again to retry. - **The preview steps aside while the app asks what should become of loose edits on trunk**, and is kept for the answer that goes on with the checkout. Saying "Cancel" to that question drops it. - **A preview is shown by its own site.** Every site's view is in the window at once, and one read while the contributor had gone to another site would have opened over that one. It waits for its site. - **The dialog's button is held, with the reason, while a command runs in the terminal.** An apply is refused then with a line in the terminal, which the dialog is in front of. Also: - **The card stays open while it has something to say** (the steps of an apply, a patch that is applied, a failure) whatever was chosen, and goes back to that choice afterwards. It remembers which tab it was left on. - **The screenshot harness waits for the ticket's number**, where it waited for a heading that #596 removed. That was missed there. **Deliberately not in this PR:** - translating what the card passes through from older modules: what a pull request's preview and banner say, what an applied patch says, why a patch did not fit, and the steps of an apply; - the list of a site's other tickets under the card (item 5), and the note about uncommitted changes (item 9). ## How to test this Platforms: any. Use the Buildkite build for the current head of this branch. The journeys carry this. From the repository root, `npm run test:e2e` runs them all; `tests/e2e/journeys/apply-card.spec.js` is new: - a patch that was chosen is shown in a dialog named for it, with what it changes, and nothing is written; leaving the dialog by its button or by Escape applies nothing and gives the card back on the tab it was left on; applied from the dialog, the patch is on disk, and focus goes to the card's header; - a patch that does not fit says before anything is written whose work it would land on; refused, its preview goes, the folded card opens to say what went wrong, the ticket's rows can be read again, and once the failure is dismissed the card is folded again; - a preview read for one site is not shown over another, and is there when its own site is opened again; - a patch cannot be applied while a command runs in the terminal, and the dialog's button says why; the command over, the same dialog can apply; - saying "Cancel" to the question about loose edits leaves the checkout and the edit as they were and does not bring the preview back. `i18n.spec.js` gains the card and a patch file's preview in the pseudo-locale. `patch-apply`, `pr-checkout`, `watch-during-changes`, `review-changes`, `store-persistence`, `gutenberg-site` and `terminal` walk the same flows as before, now through the tabs and the dialog. What they cannot reach is how it looks, a real pull request from GitHub, and an install that takes minutes: **Starting state:** a Core site that has finished setup, with a ticket linked. 1. In "Apply a patch or PR", type a pull request's number and click "Apply PR". A dialog opens, titled "Apply PR #…", with the files it changes. Click "Cancel": the dialog closes and nothing has changed. 2. Click the "Diff" tab, then "Choose a .diff or .patch file…", and choose a patch. The dialog is titled for the file. Click "Apply and rebuild": the dialog closes and the card shows the steps, then a green notice with "Revert this patch". 3. Click the card's header. It does not fold while the notice is there. Click "Revert this patch", and once it is gone click the header again: it folds. **What must not have happened:** - A patch that does not apply leaves no dialog in front of the error. - Nothing is written to the checkout before "Apply and rebuild" is pressed. ## Risks and limitations - **A failed apply cannot be tried again from the same preview.** The patch is chosen again; a pull request that was typed is typed again, since the field is cleared when it is read. - **Much of what the card says is not translatable yet**: the sentences it passes through from `pr-checkout.cjs`, `applied-layer.cjs`, `apply-conflict.cjs`, `watch-activity.cjs` and `update-plan.cjs`. Two notices join two of those sentences with a space. The translation journey covers the card with nothing applied and a patch file's preview. - **In a breakdown, why a change did not fit is on its own line**, lowercase and without a full stop: it was written to follow "near … ·". - **While the question about loose edits is up, the spoken "next step" still says to apply or cancel**, though neither button is on screen. And the next-action ring is not drawn round the dialog, which is in front of everything already. - **Linking a ticket while that question is up clears it, and the preview comes back.** Only "Cancel" drops it. - **A preview that arrives while another dialog is open on the same site**, the review or the create-site dialog, opens on top of it. - **After a pull request is checked out the card is gone, and focus with it.** The focus fix holds for a patch file, and for a pull request while its apply runs. - **During an update, an install or a build the dialog's button is held with no stated reason**, as the old one was. The reason is given when something holds the terminal. - **The card's heading is inside its header's button**, as the design system's collapsible card has it. The card is a region named by that heading; moving by headings may not find it. - **Whether the card is folded, and its tab, are not remembered across restarts.** That belongs with the settings (#559). - **The guide pages still show the old card.** #561. - **About 1,400 lines added, 560 of them tests**, against about 410 removed. One pull request, because the card, its preview and the pull request's banner are one block of the site's view and one flow. - **The manual steps above were not run by a person.** I looked at screenshots of the card with nothing applied, on each tab, of the dialog for a patch file and for a pull request, of the steps, of an applied patch, of a failure with its breakdown, and of a checked-out pull request. - **Checked on macOS only**, with the journeys this touches also run in a window resized to the Windows runner's 1024×728. Windows itself is CI's. - **Pre-PR review, two passes: everything marked to fix here was fixed, five findings, two of medium weight; the follow-ups left are in this list.** The medium two were a preview that could open over another site, and an apply button that could do nothing with its reason out of sight. ## Related Part of #557 (item 4 of its nine) and #542. Fifth slice on `redesign/wpds`, after #590, #594, #595 and #596. --- <details> <summary>Design decisions and alternatives considered</summary> **The patch file is chosen with a button, not the prototype's file input.** A page is not told where a file is, and the app reads the patch in the main process. The button opens the system's own dialog, as before, under the "Diff" tab. **"Apply PR" and "Apply and rebuild" keep their words on Gutenberg**, where the prototype says "Check out PR" and "Check out and rebuild". The app's sentences about a pull request ("PR #7 is applied", "Revert this PR") come from modules this PR passes through; changing two buttons alone would leave the two vocabularies side by side. **The description is the prototype's**, "Test changes in this checkout. Your own changes are preserved." The old sentence, that a pull request is checked out with its author's commits and a patch file is applied as a removable layer, is the line of help under each tab. **A failure drops the preview rather than showing the failure in the dialog.** A failure can carry a breakdown by file and place, and up to four ways on. That is the card's to hold, and it was already drawn there. **The steps stay on the card.** The prototype's dialog shows a spinner on its button until the apply is done. An apply here can install and build, for minutes, and the card's list says which step it is on while the page stays usable. **Notices are told to say nothing by themselves.** The design system's notice reads its own content out, and #596 found that reading can fail silently. The ones here that were alerts or status regions keep those roles, which announce them; the two that said nothing before, the applied patch and the checked-out pull request, still say nothing. **`pr-state.cjs` is gone.** Its last use was the old pill in the preview; the badge's rule lives with the work-item card's since #596. </details> <details> <summary>Review outcome (required — see AGENTS.md)</summary> Run as the repository's review procedure, with the judgement pass in a fresh context that took no part in the change. First pass on `ceba525` against `d5bbd47`; second pass on the fix-up `cab185f`; the head, `df655d2`, applies what the second pass asked for. **First pass: four findings to fix here, six follow-ups; two medium, none high.** It compared the removed block with the new components line by line and found every line of the applied patch's and the checked-out pull request's banners, the failure's buttons and their gates, and the alert and status roles carried over. It traced every reader of the preview after a failed apply and found none that needed it, and no path on which the dialog goes without an error or a question being shown. Fixed: - **A preview could open over another site** (medium). Every site's view renders its own dialog, and a dialog is drawn over the whole window: one read while the contributor had gone elsewhere opened there, with a button that applied to the site out of view. A preview is shown by its own site. - **"Apply and rebuild" could do nothing, with the reason behind the dialog** (medium). The refusal while something holds the terminal is older than the dialog, and was a line on the same page. The button is held and says why. - **Two decisions this change made were in the components**: when the dialog shows and when the card is open. They are in `apply-card.cjs`, with unit tests. - **Translation**: "Near" and the line it introduces are one sentence a translation can reorder; "Diff" says to translators that it is a noun; a string that was extracted and never shown is gone. Follow-ups done here too: focus goes to the card's header after an apply, where it fell to the top of the window; a place in a breakdown is keyed by where it comes; a weak assertion was moved and a helper widened; and "Cancel" on the question about loose edits drops the preview, where it would have brought the dialog back. **Second pass: one finding to fix here, five follow-ups; all low.** It read base-ui's handling of where focus goes and confirmed it always lands on the card's header and never on a field, that the reason and the terminal's lock are written together, and that the three new journeys read their absences after the page has rendered. Fixed: - **The reason named the terminal as where a command was running**, and not everything that holds the terminal prints there. It says something else is running on the site, and how to stop it. Follow-ups done here too: a dialog left without applying gives focus back to its opener whatever was pressed in it; the two-site journey waits for a positive sign before it reads that no dialog is shown; the helper that finds a way to a patch file no longer matches two unrelated buttons; an assertion that could not fail is gone. Left as follow-ups, all in Risks above: the breakdown's wording; the spoken next step and the ring during the question; linking a ticket during the question; a preview over another dialog of the same site; focus after a pull request's checkout; no stated reason during an update, install or build; and retrying from the same preview. **Checks, on macOS, on the head of this branch:** | Check | Result | | --- | --- | | `npx eslint . --max-warnings=0` | clean | | `npm test` | 1827 pass, 2 skipped | | `npm run test:electron` | 1828 pass, 1 skipped | | `npm run test:e2e` (journeys) | 84 of 84 | | `npm run test:e2e:packaged` | 15 of 15, on an unsigned `npm run pack:dir` build of the head | | Nine journey files that reach the card, in a 1024×728 window, the Windows runner's | 34 of 34 | **The tests' claims were audited by breaking each one** in the source and running the test that should notice. 27 breaks, each run on the head, and all 27 turn a journey red on a line that states the claim. | Break | Caught by | | --- | --- | | A pull request can be asked for with nothing typed | `apply-card` | | The preview is not named for its patch | `apply-card` | | The preview does not say how much the patch changes | `apply-card` | | The preview does not list the files | `apply-card` | | Leaving the preview does not drop it | `apply-card` | | The card forgets the tab it was left on | `apply-card` | | The card cannot be folded | `apply-card` | | A folded card stays folded over a failure | `apply-card` | | A failed patch keeps its preview | `apply-card` | | The preview does not say whose work the patch lands on | `apply-card`, `patch-apply` | | A failed patch does not say the checkout was left alone | `apply-card`, `patch-apply` | | A failure cannot be dismissed | `apply-card` | | A preview opens over whichever site is on screen | `apply-card` | | The dialog's button is not held while something holds the terminal | `apply-card` | | Saying no to the question leaves the preview | `apply-card` | | Focus is left on nothing when the dialog closes on an apply | `apply-card` | | The preview is in front of the question about loose edits | `pr-checkout` | | Reverting a pull request does nothing | `pr-checkout` | | The failure is not an alert | `patch-apply` | | Reverting a patch does nothing | `patch-apply` | | A Gutenberg site is offered a patch file | `gutenberg-site` | | The pull request field is not held during a build | `terminal` | | The card's title is not translatable | `i18n` | | A tab's help is not translatable | `i18n` | | The preview's button is not translatable | `i18n` | | The preview's way out is not translatable | `i18n` | | The preview's sentence is not translatable | `i18n` | The audit also changed the code once: the first version of the focus fix did nothing, which the journey written for it showed, and it was redone through the dialog's own option for it. </details> 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
## Why `AGENTS.md`, in its note about the Electron pin, says the Playground server crashes "about a second after "Start dev server"" and that the packaged smoke "never clicks "Start dev server"". Since the redesign (#595) the control in the page's header and in the details reads "Start development server". Someone following the note to check an Electron bump would look for a button that is not there. #617 corrected the same words in `TESTING.md` and left this file for a decision, since it is the project's instructions. ## What changes Two words, twice, in one line of `AGENTS.md`: "Start dev server" becomes "Start development server". Nothing else. The setup checklist's own button still reads "Start dev server and finish the wizard"; that is a different control, and the note is about starting a server on a site that is set up. ## How to test this Platforms: any. Nothing runs differently: it is prose. To see that the name is the control's: ``` git grep -n "Start development server" src/renderer/site-processes.cjs tests/e2e/helpers/ui.cjs ``` ## Risks and limitations - Review: not run by a separate reviewer. See below. - #571 changes one line of `AGENTS.md` too; if it is the same line, one of the two will need the other's words when trunk is merged across. ## Related Part of #542. Follows #617, before #591. --- <details> <summary>Review outcome (required — see AGENTS.md)</summary> - **Review:** not run — the change is two words repeated in one line of prose, at the maintainer's request. I checked that the line is still one line, that the name is the one `src/renderer/site-processes.cjs` gives the control, and that no other tracked doc still uses the old name (`git grep "Start dev server" AGENTS.md TESTING.md CONTRIBUTING.md .github`). - **Since review:** none. </details> 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
## Why #542 replaces the app's interface with the one in the [prototype](https://github.com/jameskoster/wordpress-contributor-toolkit-prototype), drawn with the WordPress Design System. It was built in slices on `redesign/wpds`, so that trunk, which releases are cut from, never held a half-redesigned window. The window is whole now: the shell, the page header and details, every card and dialog, and the tray. This pull request is how the branch reaches trunk. It lands before the last three sub-issues, on purpose. The settings dialog (#559) and dark mode (#560) add to a finished window and do not need a branch to hide in, and the guide (#561) is easier to rewrite against what is on trunk. They follow as pull requests against trunk. ## What changes Everything `redesign/wpds` holds; this pull request adds nothing of its own. Each slice was reviewed in its own pull request against that branch, and says there how to test it and what it leaves out. - **The shell** (#555): a sites list, the page area and a footer, in a larger window. #590 - **The page header and the details** (#556): the site's menu in the header, and what the checkout is in a sidebar that can be put away. #594 - **The site's page** (#557): the server and the build watch in the header and the details (#595); the ticket card, the apply card with a preview dialog, and the list of a site's tickets (#596, #597, #599); the create-site, rename and delete dialogs (#600, #601); confirmations as notices in the window's corner (#602); the page's notices, update card and setup checklist (#605); the terminal, logs, mail and the review dialogs painted with the design system's tokens (#606, #608); and lint rules that keep it so (#609, #610). - **The tray** (#558): along the bottom of the window, holding the terminal, the logs or the mail, with a count of unseen debug.log lines on the footer (#612, #613, #614, #615). - Along the way: #611 (the site menu's update item says why it is held), and three that tidy up before landing: #616 (a journey's race with the page's clock), #617 (comments the finished redesign made untrue) and #618 (the server's button by its present name in `AGENTS.md`). **What a contributor will notice first:** the terminal, the logs and the mail are no longer on the page but behind three buttons at the foot of the window; the terminal is dark text on light; the server and the build watch are started from the header; a patch is previewed in a dialog before it is applied; and what worked is said in the window's corner. **Not in this pull request:** - The settings dialog (#559). Until it, nothing about how the window is arranged is remembered across restarts: the details, the tray's height, the apply card's fold. - Dark mode (#560). The terminal reads its colours once, when it is made, and will need to follow the theme. - The user guide and its screenshots (#561), which describe the old interface. They are published from release tags, so they are not wrong until a release ships this; #561 is next, ahead of #559 and #560, for that reason. - How a mail is drawn, and how the window handles a link. Both are unchanged and tracked separately. ## How to test this Platforms: macOS and Windows, both. Buildkite builds signed artifacts for this pull request; use the build for its current head, and check that it is: a push to the branch makes earlier builds stale. The suite, from the repository root, after `npm ci`: ``` npm run lint npm test npm run test:e2e ``` 113 journeys walk every slice on macOS and Windows on each push. What they do not do is run a real site: a clone of `wordpress-develop`, an install, a build and a server are stood in for. The one test that does, `real-setup.yml`, is run by hand and was run on this branch at `548c020` (https://github.com/WordPress/contributor-toolkit/actions/runs/37298667056): a Core site on macOS and on Windows and a Gutenberg site on macOS were created, installed, built and served, and passed. **The Gutenberg site on Windows did not finish.** Its first attempt was cancelled after 74 minutes inside the journey, a minute short of the limit that would have failed it with evidence, so it says nothing about where it was; a second attempt was still running when this was written and its result is not in this description. The commits since `548c020` change a journey, comments and prose. **A pass by hand, on a real machine** (any platform; Apple Silicon for the server, which no test on a pull request starts for real). It follows the order a contributor meets things in: 1. Open the app with no sites. **Create new site**, a Core site, in a folder with a space in its path. The setup checklist runs its steps; the terminal's button at the foot of the window shows what each is doing. 2. Let the checklist's last step start the server, and finish WordPress's own setup in the browser. Back in the app the header says "Server running" and "Build watching". Stop the server and start it again: from **Server running** in the header, or with **Stop** and **Start** beside "Server" in the details. 3. Press the three buttons at the left of the footer in turn. Terminal: type `help`. Logs: the server's lines, the build watch's, and Debug.log. Email: where SMTP is listening. Drag the tray's top edge. 4. Link a ticket by its number. The card shows the ticket and its pull requests and patches. 5. Apply one of them. The preview dialog names the files; **Apply and rebuild** runs the steps on the card. 6. Edit a file under `src/`, then **Review & submit changes**. The diff is the edit and nothing else. 7. Create a second site, or open one from before, and move between the two from the sites list. Each has its own terminal, logs and mail. 8. **Update to latest trunk** from the site's menu. **What must not have happened:** work lost in a link, an apply, a switch or an update that did not say so; `node_modules` rebuilt where nothing changed; a failure said only in a tray that stayed closed; one site's output in another's tray; anything on the page under the tray. **What cannot be tested by hand, and what was not:** none of the slices' manual steps were run by a person. I looked at screenshots and drove the app through the journeys; everything local was on macOS, with Windows left to CI. This pass is the first one by hand. ## Risks and limitations - **It is one commit on trunk**, since the repository allows only squash merges. The slices' pull requests are its record. `redesign/wpds` should not be branched from after this: it will have diverged from trunk. - **Reviewed in slices, not as a whole.** Twenty-two pull requests, all but a two-word change to `AGENTS.md` reviewed by a separate reviewer context before they were opened, most in two passes; see below. The branch was then swept once for what falls between slices, which found comments and one unread field (#617) and the three points that follow. - **Three questions and two failures still use the system's own dialogs**: the discards ask through its confirm box, and a path that could not be copied and a server started before there is a build are said in its alert. #557 meant to replace them and did so for deletions only. - **Some dialogs are repainted, not rebuilt.** The review dialog and its destinations, the mail dialog and the question an update asks about loose edits have the design system's colours and type on the old component library's parts. - **A real Gutenberg setup on Windows is not shown to pass on this branch.** See "How to test this". It passed on trunk before the redesign, in 35 minutes; here it was past 46 on its second attempt. Whether that is the runner or the branch is not known. - **The guide describes the old interface** until #561. Do not cut a release before it. - **The bundle roughly doubled** (#590): the sites list brings `DataViews` and what it needs. Launch time was not measured. - **Less is always in view.** A build's output, a new line in debug.log and a caught mail are in a tray that may be closed. A failure opens the terminal, or the logs if nothing else is open; unseen debug.log lines are counted on the footer; a mail that arrives shows nowhere until its tray is opened, which was decided and is not an oversight. - **Translation is about half done.** The shell, the cards, the tray and most dialogs go through the translator. Roughly 200 strings in components and hooks do not yet (the review dialog and its destinations, the setup checklist, the logs, most of what the hooks say), nor about 150 in the modules they take sentences from. Strings that are new are in English in the shipped translations until they are translated. - **Focus is lost in a few places**: when the app swaps what the tray holds from under it, when a notice with a focused button goes, when a row's own action removes the row. - **Some failures are still worded by the main process** ("Error invoking remote method…"): a failed rename, a failed setup. - **Things carried over, not made by this:** a start that throws leaves the server's button dead until a restart; erasing typed input in the terminal breaks once the line wraps; a line written to debug.log while it is being attached to can be shown twice. - **#571 and #603 will conflict with trunk after this**, in the mail's journey and helpers and in the dev server's hook. - Each slice's own list has more, and says which of its limits were chosen. ## Related Closes #557. Closes #558. Part of #542, which stays open for #559, #560 and #561. #555 and #556 are closed already. --- <details> <summary>Design decisions and alternatives considered</summary> - **An integration branch, and one landing.** A window drawn half by the old view and half by the new one could not be released, and the slices were too many to hold back one by one behind a flag. Fixes and changes with no visible effect went to trunk first and were merged across, so this diff is the redesign and little else. - **Landing before #559 to #561.** The plan was to land when all seven sub-issues were in the branch. The remaining three do not change what is there: two add to it and one documents it. Holding a finished window on a branch for them only lengthens the time trunk and the branch can drift apart. - **What the prototype lacks is kept and redrawn**, and what it has somewhere else moves to where it puts it. Its labels are adopted. Where a slice departs from it, the slice says so. </details> <details> <summary>Review outcome (required — see AGENTS.md)</summary> **No review of the whole diff was run. The record is the slices': twenty-two pull requests into `redesign/wpds`, each but one reviewed before it was opened by a separate, read-only reviewer context following `.github/instructions/code-review.instructions.md`, most in two passes (the change, then its fix-up), with the counts and the findings in each pull request's own review outcome. The one is #618, two words in a line of prose.** - **Review:** completed, per slice — #590, #594 to #602, #605, #606, #608 to #617 (no review was run for #618); everything marked to fix in a slice was fixed in that slice, and what was left is in its Risks. - **Review:** completed, for leftovers only — a separate agent context, read-only; `redesign/wpds` at `548c020` against trunk; not a review of correctness, which the slices had: a search for dead CSS and code, comments that waited for a slice that has landed, what is left of the old component library and of the system's dialogs, strings not yet translatable, and repository docs that name the branch. Nothing found in the stylesheet, the dependencies or the docs; thirteen comments and one unread field, fixed in #617; the rest is in Risks above. - **CodeRabbit:** not run. Its check reads "Review skipped: automatic reviews are disabled" on this pull request and on the slices, so the slices' pre-PR reviews are the reviews of record, each for the head it names. - **Since review:** nothing was added to the branch outside a reviewed slice, apart from three merges of trunk (`da19ac6`, `3344172`, `23d46e7`). </details> <details> <summary>Implementation notes</summary> - `git diff origin/trunk...origin/redesign/wpds`: 148 files, about 14,800 lines added and 3,000 removed; about 6,300 of the added lines are tests. - The site's view, which was one component of five thousand lines, is spread over the four regions the layout has: the header, the cards, the details and the tray. Decisions are in `src/renderer/*.cjs` with unit tests; components draw them. - New for the suite: journeys per region under `tests/e2e/journeys/`, lint rules of the repository's own (`eslint-rules/`), and Stylelint over the window's stylesheet. - The main process changed in one place for the redesign's sake: the debug.log tail says which lines the file already held (#614). </details> <details> <summary>Screenshots or recording</summary> Not attached: I have no way to upload images from the command line. The prototype shows the design; the signed build shows the app. </details> 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
## Why The prototype draws each site's server dot at the left of its name in the sites list, so which sites are running can be seen without opening each. The app had the dot only in the open site's header: a contributor with three sites had to open each one to learn which server was up. The dot also sat 1.5px above the lowercase letters beside it, in the header as in the list. ## What changes Every entry in the sites list now wears the header's own dot before its name: grey while the server is stopped, green running, amber starting, red for a server that went by itself or could not start, with the reason as the dot's tooltip. The attention dot for a stale or half-updated site (#94) stays, drawn after it. A server lives in its site's view, open or not, so the view is the one thing that knows. Each `SiteRow` reports its server's state to the window as it changes and takes the report back when it unmounts; the window keeps the reports by path and hands them to `sitesListRows`. What a report says, what it does to the reports and what the dot shows are all decided in `src/renderer/sites-list.cjs`, where the suite can reach them. For a screen reader the dot's words follow the name, as the attention dot's do, and only when the dot is not the grey every site starts with: said after every name, "Server stopped" would be the thing heard most and needed least. So an entry is named `my-site` while stopped and `my-site (Server running)` while running. Both dots, and the header's, are now centred on the text's x-height with `vertical-align: middle`, which centres an inline box on the parent font's x-height by definition and so holds on Windows with a different font. A flex item, which the dots were, is centred on the line box instead, 1.5px higher. Deliberately not in it: a dot for the build watch in the list, and any control on the list's dot. The dot reports; the header and the details act. ## How to test this Platforms: any. The x-height alignment is worth a look on Windows too, where the font differs: the rule is font-agnostic, but only a look confirms it. The first journey in `tests/e2e/journeys/dev-server.spec.js` walks the reported path and reads the list's dot at each turn: starting, running, stopped and crashed, with the entry's name. It is red without the change. From the repository root: ```bash npx playwright test --project=journeys tests/e2e/journeys/dev-server.spec.js ``` What the journey cannot reach is a real server, since journeys stub the handler that starts one, and what the dots look like beside real text: **Starting state:** two sites, both set up, neither server running. The Buildkite artifact for the head commit, on macOS or Windows. 1. Look at the sites list. Expected: every entry has a grey dot at the left of its name, on the same line as the lowercase letters, and a stale site has its amber dot after it. 2. On the open site, open the server's menu in the page header and choose **Start development server**. Expected: the entry's dot turns amber while the server starts and green once the site opens in the browser. The header's dot sits on its words' x-height, as the list's does. 3. Click the other site in the list. Expected: its own dot is still grey, and the first site's dot is still green while you look at the second. 4. Go back to the first site and choose **Stop development server**. Expected: its dot is grey again. 5. Narrow the window until the header's menus show only their dots. Expected: one gap between a dot and its chevron, not two. **What must not have happened:** no site's entry has lost its name or project line; a long name still ends in an ellipsis; the attention dot of a stale site is still there, after the server dot; nothing else in the header moved. ## Risks and limitations - A running stale site shows two dots side by side, a green and an amber. The prototype has no attention dot to reconcile with, so this keeps both rather than folding two meanings into one dot. - A crashed server's words are the whole sentence from the details, so that entry's accessible name is long. It says what the red dot means, which "Server stopped" would not. - The guide's sidebar screenshots were not retaken. - Pre-PR review: 2 [fix here] · 0 [follow-up], both fixed in `6229fb6`. ## Related Follow-up to #590 (the sites list) and #595 (the server and the watch in the header). --- <details> <summary>Design decisions and alternatives considered</summary> - **The view reports up, rather than the main process broadcasting.** "Starting" is a renderer state: it covers the wait for the build watch before the server is even asked for. Only the view knows it, so a main-process list of running servers would have drawn the wrong colour for the longest phase. - **One effect, with a cleanup that takes the report back.** Two effects, one to report and one to clean up on unmount, would have lost the entry if the callback's identity ever changed; one effect's cleanup and re-run land in the same commit, so the list sees a single change and no grey dot in between. - **No words for a stopped server.** The prototype announces "Server stopped" before every name. Here the grey dot is the default and says nothing, as the attention dot says nothing when there is nothing to report. - **`vertical-align: middle` over a pixel offset.** The dot was measured 1.5px high against the ink of the letters, in a screenshot of the running app. A `margin-top` would have fixed that for this font and this size; `vertical-align: middle` is the CSS definition of "centred on the x-height", so it follows the font. </details> <details> <summary>Review outcome (required — see AGENTS.md)</summary> 2 [fix here] · 0 [follow-up] — both fixed. - 🟡 Architecture, `[fix here]`: the words a view reports of its server, and what a report does to the window's reports, were decided inline in `index.jsx`, where the suite cannot reach them. Fixed: `serverReport` and `withServerReport` in `src/renderer/sites-list.cjs`, with unit tests. - 🔵 Layout, `[fix here]`: the space between a process's dot and its words was the dot's margin, which stayed when the words gave way to the dot in a short header and doubled the gap before the chevron. Fixed: the margin is the words' own and goes with them. - **Review:** completed — a separate agent context running `.github/instructions/code-review.instructions.md`; reviewed head `aad1b72` / base `0cd70e4` (origin/trunk); `npm test` 2047 pass, `eslint src tests scripts` and Stylelint clean (a repo-wide `eslint .` fails only on stale checkouts under `.claude/worktrees`, which are not part of the branch); outcome above. - **Since review:** `aad1b72 → 6229fb6` checked; the one commit applies the two findings and nothing else. `npm test` 2049 pass, lint clean, and the dev-server, site-header, auto-start and logs journeys pass on the new head. - **CodeRabbit:** not yet requested. </details> <details> <summary>Implementation notes</summary> - `src/renderer/sites-list.cjs`: `serverDot` (what the row draws; unknown or missing reports are offline), `serverReport` (what a view reports from `serverProcess`), `withServerReport` (the reducer). `sitesListRows` takes `servers` by path. - `src/renderer/index.jsx`: `serverReports` state and the `onServerStatus` callback in `App`; the reporting effect in `SiteRow`. - `src/renderer/components/sites-sidebar.jsx`: draws `ProcessStatus` before the name and the hidden words after it. `ProcessStatus` in `site-header-actions.jsx` gained an optional `title`. - `src/renderer/shell.css`: the name span is one nowrap line with the ellipsis, the dots inline boxes; the header's dot and words are one inline span inside the button. - Journeys: `dev-server.spec.js` reads the list's dot at each state; `logs.spec.js` and `auto-start.spec.js` name a running site's entry with its dot's words, since the accessible name carries them. - Measured alignment, in the ink of a window screenshot at 1x: list dot centre 93.5 against the letters' 95.5 before, 95.5 against 95.5 after; header dot 32.5 against 34 before, 33.5 against 34 after. </details> <details> <summary>Screenshots or recording</summary> The list before the alignment fix (dots centred on the line box) and after (dots on the x-height), and the header's menu, are to be attached from the measuring run; `gh` cannot upload images, so they go in from the web UI. </details> 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Why
#557 rebuilds what is inside the site's page, as the prototype draws it. It lists nine things; this is the first two, the Server section and the process menus. Until now a site's server, its build watch and the way to its changes were three large buttons at the top of the cards, with a line of links under them, and they scrolled away with the cards.
This PR targets
redesign/wpds, nottrunk.What changes
site-processes.cjs.Two things the taller details and the fuller header needed:
Deliberately not in this PR: the other seven items of #557, each in its own PR; and the sites list's row actions and its "server running" dot.
How to test this
Platforms: any. Use the Buildkite build for the current head of this branch.
The journeys carry this. From the repository root,
npm run test:e2eruns them all:dev-server.spec.js: the server's button in the details starts one server, is held while the server starts, as is the header menu's item, and offers to stop it once it has an address; a third, new journey starts and stops the same server from the header's menu, finds nothing but the start in a stopped server's menu and the site and its admin in a running one's, reads the section's three addresses, follows one from each place and finds it opened by the main process with the window still on the app, and reads the credentials, the password only after asking.build-watch.spec.js: the header and the details say the same of the watch as it starts, is stopped from the header's menu, and ends by itself with an error; a build that fails before the watch is said as the build's failure; and a third, new journey stops that build by the watch's button and by Ctrl+C, and finds neither said as a failure.i18n.spec.js: a fourth journey reads the two processes in the pseudo-locale, stopped, starting and running, in the header, in their menus and in the details.site-header.spec.js: details that fit stay in view and details that do not scroll with the cards; a site still in its setup is offered no server, watch or review; and a header short of room, at two widths, keeps the site's name and every action under its own name.What they cannot reach is how it looks, and a real server:
Starting state: a Core site that has finished setup, with its dev server stopped.
What must not have happened:
Risks and limitations
src/edits on save and runs apart from the server. The section's sentence says the first half while the watch runs.Related
Part of #557 (items 1 and 2 of its nine) and #542. Third slice on
redesign/wpds, after #590 and #594.Design decisions and alternatives considered
"Build watch", not "Latest build". The prototype's section reports the last compile: whether it succeeded, how long ago, how long it took, which files. The app does not record any of that; it knows the watch's state and what the watcher printed. So the section is named for what it is and says the state in a sentence. Recording compiles is a feature of its own.
One module for both places. The header and the details show the same two processes. Two sets of conditions would drift, and the first sign would be a header saying "running" over a section saying "offline".
A starting server is held, not pressable. The prototype draws it so. The guard that made a second press do nothing (#488) stays in the hook, but no press reaches it any more, so the journey's claim is the held button and the held menu item, and one server counted.
The header's server menu has the site and its admin in it. The prototype's menu has only start and stop. The details can be put away, and under about 1088px of window they sit at the foot of the page; the two links most often wanted should not go with them. The database stays in the details.
The processes and the review are not offered during setup. The old row of buttons was not drawn then either: the checklist's last step is what starts the server the first time.
The details let go by measuring, not by a rule in the stylesheet. Whether they fit depends on the window's height and on what they are showing, which changes as a server starts. The prototype measures too.
The header gives way by the page's width, with container queries. The page's width is the window's less the sites list, which can be closed, so a rule on the window's width would be wrong half the time.
Review outcome (required — see AGENTS.md)
Run as the repository's review procedure, with the judgement pass in a fresh context that took no part in the change. First pass on
6c6cc59againstf066f94; second pass on the fix-upac56e03; the head,e8dee93, applies what the second pass asked for.First pass: seven findings to fix here, five follow-ups; none high. It confirmed that the disabled states, the next-action cue, the setup checklist's own start step and the way out of an update that is waiting for the watch all carried over from the three buttons.
Fixed:
index.jsx, out of the unit tests' reach. It is insite-processes.cjs.ui.cjs.One follow-up was done here instead: the site's links were only in the details, which can be put away. "View site" and "wp-admin" are in the header's server menu.
Second pass: four findings to fix here, one medium; three follow-ups. It traced every write of the watch's state and found that the record of which process ended cannot go stale, and that the server's address, "running" and "starting" are set and cleared together, so the section cannot be drawn from inputs that disagree.
Fixed:
index.jsx. It is insite-processes.cjs, with a unit test.One follow-up was done here: the translation journey now waits for the server and the watch to have been asked for before it speaks for them.
Left as follow-ups, all in Risks above: a paused watch offering "Start"; a start that throws leaving the button dead; a boot that cannot be cancelled; how the window handles a link; the Logs tab's label; and the time's unit.
Checks, on macOS, on the head of this branch:
npx eslint . --max-warnings=0npm testnpm run test:electronnpm run test:e2e(journeys)npm run test:e2e:packagednpm run pack:dirbuild of the headdev-server,build-watch,site-header,i18nin a 1024×728 window, the Windows runner'sThe tests' claims were audited by breaking each one in the source and running the test that should notice. 30 breaks, each run on the head, and all 30 turn a journey red on a line that states the claim.
dev-serverdev-serverdev-serverdev-serverdev-serverdev-serverbuild-watchbuild-watchbuild-watchbuild-watchbuild-watchbuild-watchdev-serverdev-serverdev-serverdev-serverdev-serveri18ni18ni18ni18ni18ni18nsite-headersite-headersite-headersite-headerreview-changestrunk-update-watchsite-header🤖 Generated with Claude Code