Repository navigation
cockpit v3: verb previews with Undo, sheets, since last look (W6, W8, W10) - #214
Merged
Merged
Conversation
… W10)
Steering at the node. Every structural verb (Add child, Start now, Team,
Autonomy & merge, Pause / Resume, Move, Name it / file under, and any
other verb as a plain preview) opens a preview under the header before
anything changes: the parent's First / Then / Later columns with the
change as a dashed ghost and its old place struck through (MiniColumns,
boxes in a grid, no lines), the roll-up change, the effects and who
approves. Apply sends the preview id and the page's facts version; the
toast offers Undo and the node keeps "Undo (n min left)" for the rest of
its 10 minutes (the steer/UndoLatest pattern). Add child pulls a held
child whose title matches forward instead of copying it; Move and Name it
offer only parents one level up. Verb keys (a s t u p m n) open the
previews, Esc cancels, and `u` stays the toast's Undo while one is
offered. The chat's plain words, `/` menu, quick verbs and offers open the
same previews on the page (never an apply), and keep focus in the box.
Team is the team editor in a panel: every member with a vendor and a
model, nothing preselected (words like "swap luz to codex" stage that one
change), the $/h before and after, from the definition's own preview; a
definition version on Apply and Undo by re-pinning the version before. It
works on a live factory today.
Sheets open from the address: Needs you (?peek=needs: ranked by what each
ask holds, merges on one base as one item, asks that block nothing grouped
with "Apply all", the closed alarms with their causes, the other tree's
count), the base env (?peek=env), Try it (?peek=try&at=<ref>: the passing
steps by name, the flag and the sign-in note; from the roll-up's env chip,
a tile's badge and "Try what passes") and the keys (?peek=keys). The v3 top
bar gains the "n need you" pill and the base env chip. Find extends the
⌘K palette: nodes by ref or title with their breadcrumbs, and the search's
projects, PRs and tasks open their node pages.
Since last look: three seconds on a page (in view) marks this person's
last look; the since line and children's changes it showed stay until the
next visit; rows show what changed with the Since overlay; the server's
ISO "since" reads as a time.
The steering routes sit behind the NodeSource seam: steerRoutes implements
api.md (POST …/n/{ref}/preview|apply, POST …/undo/{token}, GET
…/needs-you, GET …/find, PUT …/n/{ref}/seen) and SERVED_STEER attaches
each to the live source once its endpoint lands (TODOs name them). The
sample factory previews, applies and undoes every verb, ranks Needs you,
finds and keeps marks, so stories and tests run the real components.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ds you count, since lines for the visit - Team Undo on a live factory re-pins the version before only while the version it made is still in force (read again first, the window from that version's time); after a newer version it says "undo from Versions". It is forgotten once it ran, from the toast or beside the verbs. - A refused apply (409 stale, 422, 403) reads the node pages and the preview again, so Apply works on what is there now; the live Team editor's refusal reads them too. - The shell's ranked "n need you" and the base env chip read again when the snapshot's open asks change or the summary's poll answers. - The "since" line and each child's changes stay for the whole visit, though an apply or answer reads the page again after the mark moved. - Apply all only when every quiet ask's first answer is the same one; one summary toast. Nothing needs you, Try it and a missing node say what is so; no dangling separator. - A blocked form asks no preview (Add child without a title, Team with nothing picked); Move and Name take the parent from the last crumb (also a folded implicit one); Cancel and Esc wait while applying; closing a sheet goes back over the entry it pushed (or replaces it), so Back never reopens it. - docs/FACTORY.md lists the preview fields the web reads beyond api.md (CLIENT_PREVIEW_FIELDS, checked by a test) and the arguments it sends; Name sends its name as `title`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
❌ UI Snapshot doesn't match the committed baseline. If this UI change is intentional, update the baseline — each path renders in the same pinned image, so the result matches this gate:
Diff PNGs ( |
This was referenced Nov 4, 2026
Merged
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.
Related issue
Closes # (cockpit v3 plan items W6, W8, W10;
notes/factory-v3/final/plan.md, milestone 2 "Steer at the node")Summary
Cockpit v3 can now steer where you are. Every structural verb on a node opens a preview under the header before anything changes: the parent's First / Then / Later columns with the change as a dashed ghost, the roll-up change, the effects and who approves. Apply has Undo for 10 minutes. Needs you, Find, the keys, the base env and Try it are sheets that open by address. Three seconds on a page marks your last look. Still behind
?cockpit=v3; v1 and v2 are unchanged (the shared top bar, palette, key list and toast only gain optional, v3-only parts).ELI5: before, clicking "Start now" said "a preview here soon". Now it shows where the panel would move in its feature's columns, what its wait becomes, who approves, and a Start now button. If you change your mind, Undo stays on the node for 10 minutes.
The server's verb routes (S12) are not on staging yet. Each client call sits behind the
NodeSourceseam, andSERVED_STEERadds it to the live source once its endpoint lands. Until then a live verb says it cannot be previewed and changes nothing. Team is the exception: it already runs on a live factory through the team editor's own routes. The sample factory implements every route, so stories and tests run the real components.Plan bullets → what this PR does
W6. Verb previews and Undo (
v3/verbs/,v3/nodeSteer.ts)PreviewPanel+MiniColumns:columns_after). The changed node is a dashed ghost; its old place (moved_from) is struck through. They are boxes in a grid; nothing joins them.rollup_delta, theneffects, then "Who approves" (approver_noteor the approver).apply_label), Cancelesc, "Undo for 10 min after applying."nodeWire.normalizePreviewalso reads api.md's open forms:rollup_deltaas an object ({progress: {before, after}}),effectsas sentences.AddChildPreview:pulls_forward). The banner says "… is already here, held for …. Adding it now pulls it forward into Then instead of making a second copy". The ghost moves out of Later and Apply reads "Pull forward and plan".StartNowPreview: the node moves to First in its parent's columns (the ghost), and the lines show what its wait becomes, the team, the burn, what it unlocks and the risk.TeamPanel: the team editor in a panel.useTeamPreview(definition preview), a definition version on Apply (useDefinitionEdit), and Undo by re-pinning the version before (usePinDefinition), as the team editor does. A link opens the full editor.team()with the generic preview.AutonomyPreview: an auto-merge switch for the subtree. The lines say what it covers now and later, the first effect, what is not affected (a human-merged base stays human-merged) and who approves.PausePreview(Pause / Resume).MovePreview: only the parents one level up that the server lists (parents) are offered. A pick shows both roll-ups changing. Apply stays off until another parent is picked. A move two levels up is the server's 422wrong_level, shown as "Not applied: …".NamePreview: a name and/or a parent one level up.useApplyVerbshows the toast with Undo, which callsundo(token).upresses it while the toast shows.useNodeUndo,undoLabel).a s t u p m n, now bound.uyields to the toast's Undo while one is offered./menu, quick verbs and offer card. They now open the preview on the page instead of a "soon" toast, and keep focus in the chat box.?verb=…&title|member|to=(handling moved fromNodeRouteinto the page). A folded implicit parent's redirect keeps the query.W8. Sheets (
v3/sheets/V3Sheets.tsx, opened by?peek=; mounted by the v3 shell, the story kit andrenderNode)?peek=needs[&tree=factory]):?peek=needskeeps today's list.blocks_nothingas items with breadcrumbs,closed_alarmsoptional).GET …/find,{q, items}read too). Projects, PRs and tasks that the search finds open their node pages.?under v3 opens?peek=keys. The list gains each verb's key, "Enter on an answer: never answers", and ⌘K as Find.?peek=env, also from the v3 top bar's env chip): Deployed sha · branch · age, Health (smoke and checks), Follows, Sign-in, Holds (merged changes), Open the app / API / Factory › Environments.?peek=try&at=<ref>): the passing steps by name with their acceptance step and "API only …", then Env, Flag (try_flag, shown only when sent) and Sign-in, then Open the app / Open the API. Opens from the roll-up's env chip ("in base env @sha · Try it ↗"), a tile's Try it badge and the acceptance block's "Try what passes".W10. Since last look
useMarkSeen: after 3 s with the page in view (the timer pauses while the tab is hidden),seen(ref)sendsPUT …/n/{ref}/seen.useVisitSincekeeps the since line and the changes it showed for this visit, even when the page is read again. The next visit starts from the new mark.since.atreads as "12:30" (today) or "Nov 2".Deviations
steerRoutesimplements api.md's routes with tests, andSERVED_STEERis empty, with TODOs naming each endpoint. One line adds each route to the live source once its endpoint lands. Until then a live verb says "this server cannot preview it yet, so nothing changed", and Needs you keeps today's peek. The S9/S10 work onfactory/v3-m2-views(not merged) was read, and the client accepts its shapes.{auto_merge: boolean}as its args. The base the subtree merges into comes from the server's lines, not the client.VerbPreviewadds (client) fields:title,moved_from,approver_note,pulls_forward,parents,apply_label.rollup_deltaandeffectsare read as lines ({label, html}). The S12 server can send them or the object form.Review fixes
undoLeft, assteer/UndoLatest). If someone landed v14 after it, the button goes away and the toast's Undo says "v13 is no longer in force; undo from Versions." Once it runs, from the toast or beside the verbs, it is forgotten.useVisitSincekeeps the first read'srollup.sinceand each child'schanged(merged with later reads). An apply, an answer or an Undo after the 3 s mark no longer removes them. A visit to another node starts over.Promise.allSettled, and one toast says which went through and which did not.useVerbPreview(…, {enabled})debounces the arguments and the flag together. Add child without a title and the sample Team with nothing picked ask nothing.toonly to get itsparents. If a server answers that read with an error, the panel offers no parent and says so, instead of showing an error.docs/FACTORY.md(the S12 contract), together with the arguments the web sends.CLIENT_PREVIEW_FIELDSis checked against that list by a test. Name now sends its name astitle, as the S12 branch reads it.Test Plan
npx tsc -b: clean.oxlint --deny-warningsonsrc/components/factory src/pages/factory: clean. Prettier: clean.pre-commit run --files <changed>: passed.vitest run src/components/factory src/pages/factory src/lib: 233 files, 4139 tests, all passed. Fullvitest run: 548 files, 10497 tests passed.TeamPanel.live.test.tsx: Undo is offered for v13 (8 min left), runs once and is gone. With v14 on top, no Undo is offered and the toast says to undo from Versions.VerbPreviews.test.tsx: after the stale refusal, Apply applies; Move under a folded implicit parent; Add child without a title asks no preview; Cancel and Esc wait while applying.CockpitV3.test.tsx: a new open decision in the snapshot raises the pill from 5 to 6, with no v3 write.nodeSteer.test.tsx: the since line survives an apply after the mark; every client-only preview field comes through and is named in docs/FACTORY.md.V3Sheets.test.tsx: Apply all gives one summary toast; no Apply all when the first answers differ; Nothing needs you; Try it without base env and with an unknown ref; Back after closing never reopens.tests/e2e_ui/chat/test_composer_acceptance.py::test_status_counts_and_pr_share_workspace_bar, as on the server-only cockpit v3: level views and lenses, Needs you and Find, last-look marks (S8, S9, S10) #213. Pre-commit, server-rest, E2E, stores-crdb and stores-mysql fail as on every branch off this staging (cockpit v3: the real node API end to end (Home, the feature, the project and the task on a live server) #211, cockpit v3: check v3's own chat parts in the e2e; name the proposal kinds that hold work #212).v3/verbs/VerbPreviews.test.tsx(12):undo u-1.rollup_delta(object form) and approver shown, and Undo latest calls the token ("tok-1").?verb=add&title=fills the title without stealing focus.s, Esc,u, anduas the toast's Undo.v3/verbs/TeamPanel.live.test.tsx: live Team through the definition preview, thenPUT /definitionwithbase_version, then UndoPOST /definition/pin {version: 12}.v3/sheets/V3Sheets.test.tsx(7):v3/nodeSteer.test.tsx(8):CockpitPalette.test.tsx(+2): v3 finds T-16 with its breadcrumb and opens/n/T-16; without a Find route a project hit opens its node page.CockpitV3.test.tsx(+1): in the shell, "Open C-16" opens the v3 Needs you; the "5 need you" pill, the base env chip and its sheet;?opens?peek=keys.levelsRule.test.tsx(+1): every verb's preview and every sheet has no line between nodes and no empty cell.NodeChattests now expect the page's preview (data-label) instead of the page'sonVerbaction.pytest tests/examples/test_factory_sample_tokens.py: 3 passed (FORBIDDEN_SAMPLE_TOKENS green).How to try it:
just dev, open a factory with?cockpit=v3. On a project, Team shows the editor (live today). Other verbs say they cannot be previewed until S12 lands. In Storybook, openFactory/Cockpit v3/Verb previews(StartNow, AddPullForward, TeamSwap, AutonomyAndMerge, Move, NameIt, each with an…Appliedstory that clicks Apply) andFactory/Cockpit v3/Sheets(NeedsYou, FindByRef, Keys, BaseEnv, TryIt). AlsoFactory/Cockpit v3/Node page› SinceLastLook / SeenNothingSince.Demo
Prototype shots beside this PR's captures, each with what matches and what differs: https://claude.ai/artifact/7ULiGSSCbUek8SaFeHD3AR (private; ask Luka for access). Screenshots are not committed (repo rule), and the CLI cannot upload attachments. The captures are in
wt/v3-tmp/v3-m2-web-steer/shots/.Type of change
Test coverage
Coverage notes
Manual: every new story was captured in a real browser from the built Storybook (Playwright over the static build) at 1440 and 390, light and dark, and checked against the prototype's shots
02,04,08,09,14and15. No page scrolled sideways. The e2e checks (W11) come with milestone 3.Changelog
Cockpit v3 previews every structural verb before it applies, with Undo for 10 minutes, and adds Needs you, Find, base env and Try it sheets and "since your last look"
🤖 Generated with Claude Code