Public: anyone can read this; the crew can change it.

Every app in the explorer says "make it yours" and one tap forks it, counted by a test #10728

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

Every app row in the explorer now forks in one tap for a signed-in reader, with a plain-words receipt and an Undo. The same receipt and undo are on the MCP `make_it_yours` tool.

shipped production is serving it deploy da127e7

opened this

Every app row in the explorer now forks in one tap for a signed-in reader, with a plain-words receipt and an Undo. The same receipt and undo are on the MCP make_it_yours tool.

What changed

  • Explorer row (src/web/studio/explore.ts): "Make it yours" is now a POST form, so one tap forks the app into the reader's forge. It is private by default and follows the original, as before.
  • Receipt and undo (src/web/studio/make_it_yours.ts, routes in src/http/server.ts): the tap lands on GET /:owner/:name/make-it-yours/receipt, which says what was made and offers Open mine, Undo and Back to explore. Undo posts to /make-it-yours/undo and returns to /explore with the confirmation.
  • Undo rule (src/actions/make_it_yours.ts): undoMakeItYours removes the copy and its app only while the copy has no commits of its own and no pull was sent from it. Otherwise it keeps the copy and says why.
  • MCP: no tool was added. make_it_yours gained undo: true, and a made copy now answers with the same receipt sentence (receiptWords) as the page. test/mcp-size.test.ts passes without raising any ceiling.
  • Tests: test/explorer-make-it-yours.test.ts counts one action per app row, signed in and signed out. It walks one fork end to end: tap, receipt, undo, original untouched. It also checks that a cross-origin tap gets 403 and that the MCP make and undo use the same words.
  • Edited test: test/explore.test.ts asserted href= for the signed-in button. That button is now a form, so I changed those assertions to action=.

What I chose not to do

  • Sign-in: the signed-out row still links to the existing plan page, which sends the reader through sign-in and back to the plan. I did not make a signed-out tap fork automatically after sign-in, because that would need a state-changing GET. This is only partly the "sign-in first, then back to the fork" you asked for: after sign-in the reader still confirms once on the plan page.
  • Undo scope: undo does not delete a copy that has work of its own.

How to try it

  • Open /explore signed in and tap "Make it yours" on an app. Read the receipt, then tap Undo.
  • Over MCP: make_it_yours { repo, dryRun: false }, then make_it_yours { repo, undo: true }.

Checks

  • Passing: bun x tsc --noEmit, scripts/gate.ts, scripts/design-lint.ts, and the explore, make-it-yours and MCP tests.
  • Skipped: scripts/fast.ts named 1,673 of 2,527 test files, which was too broad to run here. I ran the related files by hand and left the full suite to the forge's check.

🤖 Generated with Claude Code

Closes #10713

commented

Every app row in the explorer now forks in one tap for a signed-in reader, with a plain-words receipt and an Undo. The same receipt and undo are on the MCP make_it_yours tool.

What changed

  • Explorer row (src/web/studio/explore.ts): "Make it yours" is now a POST form, so one tap forks the app into the reader's forge. It is private by default and follows the original, as before.
  • Receipt and undo (src/web/studio/make_it_yours.ts, routes in src/http/server.ts): the tap lands on GET /:owner/:name/make-it-yours/receipt, which says what was made and offers Open mine, Undo and Back to explore. Undo posts to /make-it-yours/undo and returns to /explore with the confirmation.
  • Undo rule (src/actions/make_it_yours.ts): undoMakeItYours removes the copy and its app only while the copy has no commits of its own and no pull was sent from it. Otherwise it keeps the copy and says why.
  • MCP: no tool was added. make_it_yours gained undo: true, and a made copy now answers with the same receipt sentence (receiptWords) as the page. test/mcp-size.test.ts passes without raising any ceiling.
  • Tests: test/explorer-make-it-yours.test.ts counts one action per app row, signed in and signed out. It walks one fork end to end: tap, receipt, undo, original untouched. It also checks that a cross-origin tap gets 403 and that the MCP make and undo use the same words.
  • Edited test: test/explore.test.ts asserted href= for the signed-in button. That button is now a form, so I changed those assertions to action=.

What I chose not to do

  • Sign-in: the signed-out row still links to the existing plan page, which sends the reader through sign-in and back to the plan. I did not make a signed-out tap fork automatically after sign-in, because that would need a state-changing GET. This is only partly the "sign-in first, then back to the fork" you asked for: after sign-in the reader still confirms once on the plan page.
  • Undo scope: undo does not delete a copy that has work of its own.

How to try it

  • Open /explore signed in and tap "Make it yours" on an app. Read the receipt, then tap Undo.
  • Over MCP: make_it_yours { repo, dryRun: false }, then make_it_yours { repo, undo: true }.

Checks

  • Passing: bun x tsc --noEmit, scripts/gate.ts, scripts/design-lint.ts, and the explore, make-it-yours and MCP tests.
  • Skipped: scripts/fast.ts named 1,673 of 2,527 test files, which was too broad to run here. I ran the related files by hand and left the full suite to the forge's check.

🤖 Generated with Claude Code

commented

Explorer rows now fork in one tap and show a receipt with an undo. The same flow is available through make_it_yours in the MCP. The check failed on two tests; I fixed one, and the other I couldn't reproduce here, so it is not fixed.

  • Server-Timing sweep (fixed): the new GET /:owner/:name/make-it-yours/receipt redirects when there is no receipt to show. The sweep test keeps a list of GET pages that redirect, and this one wasn't on it. I added /alice/forge/make-it-yours/receipt to that list in test/server-timing-sweep.test.ts. It passes now.
  • Pull list dot test (not reproduced): "the pull list wears a dot per row, and the head badges only Private" in test/pull-quiet.test.ts passes here. It passed on three repeated runs together with the explorer and make-it-yours tests. This change doesn't touch pull rendering, so it looks like a flake in that shard. I couldn't see its failure output beyond the summary. If it fails again on this push, send me the log for it.

tsc --noEmit is clean, and I pushed the fix as dc1d62dd0.

Changes requested — before the latest push

Mostly sound: the tap is a same-origin-checked POST, the receipt and undo are real, and the MCP reuses the words. Changes needed, in one round:

  1. FIRST: the terminal door is missing. Nothing in src/tui/ offers Make it yours or its undo, and there is no docs/features/<name>.md for the how-to. Add a TUI screen (entry where AGENTS.md says) calling makeItYours and undoMakeItYours, and the feature doc.
  2. Undo disables the app before deleteRepo can refuse (has_pulls), leaving a kept copy with its app switched off. Check for pulls first, or do both together.
  3. Undo on the receipt of an 'already yours' copy would delete a fork the reader made earlier. Offer Undo only for a copy this tap just made, or say so in the words.
  4. MCP undo maps unauthorized and failed to 'not_found'. Map each kind to its own answer.
  5. Design (principles 6 and 7): the receipt wraps three buttons in a card. Drop the card; put the actions as plain buttons under the one-sentence header. Also the title and sub say the same thing twice (principle 1).
  6. Tests: add undo refused when the copy has its own commits or a pull, undo by a signed-out visitor, and the already-yours receipt.
  7. Box 1: the signed-out row only links to the plan page; 'sign-in first, then back to the fork' is not met. Make sign-in return land on the receipt flow, or confirm in one tap.
commented

All seven points are addressed and pushed. gate.ts, tsc --noEmit, design-lint and the nine make-it-yours, explore and TUI test files (76 tests) pass. I did not run the rest of the suite; the forge runs the full check on push.

  1. Terminal door and doc. The palette on a repository now offers Undo make it yours once you have a copy (src/tui/screens/yours.ts). It asks to confirm, then calls undoMakeItYours and says why when the copy is kept. The make flow's toast now uses receiptWords and points to that command. The how-to is in docs/features/make-it-yours.md, covering the web, terminal and MCP doors.
  2. Undo order. undoMakeItYours now checks for a pull sent from the copy before it disables the app. A refused undo leaves the app on, and a test checks that.
  3. Undo only for a copy just made. A new copy redirects to …/receipt?made=1, and only that receipt shows Undo. An already-yours copy gets "was already yours" with no Undo. Anyone who adds ?made=1 to the URL by hand still gets the Undo button, but undo's own refusals (own commits, sent pull) still apply.
  4. MCP undo. unauthorized, failed, changed and not_found each get their own answer.
  5. Design. The card is gone, and the receipt is one sentence as the header with plain buttons under it. The sub that repeated the title is dropped.
  6. Tests. I added tests for undo refused with the copy's own commits, undo refused with a pull sent from it, undo by a signed-out visitor, and the already-yours receipt with no Undo. Two existing tests changed to match: the explore link assertion now includes ?receipt=1, and the receipt redirect expects ?made=1.
  7. Signed-out row. The link is now /make-it-yours?receipt=1. Sign-in already returns to that URL with its query, and the plan page carries the flag into its form, so one confirming tap lands on the receipt.

For the pull test I merge the pull into the original first. That leaves the copy with nothing ahead, so only the sent pull keeps it.

Changes requested — before the latest push

Earlier asks: terminal undo and the doc, undo order, receipt only for a fresh copy, MCP error kinds, design (card gone, one sentence), web tests and the signed-out ?receipt=1 link are all met. One ask remains, on lines new since my last review: the terminal door's undo has no test. Add a TUI test (see the existing tests for src/tui/screens) that (1) the palette offers "Undo make it yours" only after a copy exists and not before, and (2) confirming it removes the copy and a copy with commits of its own is kept with the toast saying why. Non-blocking: an MCP test for undo answering changed and not_found; the long import and redirect lines in the web and MCP modules want wrapping.

commented

Every app row in the explorer now has one Make it yours action. Signed in, one tap forks the app and shows a short receipt in plain words with an Undo button. MCP make_it_yours uses the same words and takes undo: true. The terminal has the same undo in a repository's : palette, as "Undo make it yours".

This push adds tests for the undo paths that had none:

  • Terminal tests (test/tui-working-yours.test.ts), run against a real app, alice/garden:

- The palette doesn't list "Undo make it yours" before bob has a copy, and does once he has one. - Confirming it removes bob/garden, leaves alice/garden alone, and shows "bob/garden is removed. The original was not touched." - A copy with a commit of its own is kept, and the message explains why: "bob/garden has changes of your own, so it is kept." - To check that these tests catch a break, I temporarily disabled the confirm handler: both confirm tests failed. - The palette helper now takes the repository it opens on. Bob is made a member here, as test/explorer-make-it-yours.test.ts already does.

  • MCP undo tests (test/explorer-make-it-yours.test.ts):

- A second undo after a successful one answers not_found: nothing of yours was made from that app. - Undo on a copy with its own commit answers changed: … and keeps the copy. - The MCP call helper is now shared by these tests. It returns the raw text, because a refusal comes back as kind: message, not JSON.

  • Long lines wrapped: the import lines in src/http/mcp/tools/make_it_yours.ts and src/tui/screens/yours.ts, plus the redirect, flash, Undo form and hidden-input lines in src/web/studio/make_it_yours.ts and src/web/studio/explore.ts. The code does the same thing; it is only wrapped.

Checks run: bun scripts/gate.ts, bun x tsc --noEmit and bun scripts/design-lint.ts are clean. scripts/fast.ts picked 1,673 test files, far too many to run here, so I ran the 9 files that cover this feature by hand: all 137 tests pass.

To try it: sign in, open /explore, tap Make it yours on an app, then tap Undo on the receipt. In the terminal, open the original repository, press :, and choose "Undo make it yours".

🤖 Generated with Claude Code

Approved

All earlier asks are met: the terminal door has Undo make it yours (confirm, gated like the page), the how-to is in docs/features/make-it-yours.md (README untouched), undo refuses before switching the app off, the MCP undo has distinct answers, the receipt card is gone, the signed-out link carries the receipt flag, and the new tests cover each undo path. Non-blocking: ?made=1 typed by hand shows an Undo button, but undo still refuses copies with own commits or sent pulls, and it is origin-checked.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs