Public: anyone can read this; the crew can change it.
/forges/new offers the starter templates: a picker with Blank first, and the plan says which one #7971
Check · Review · Land · Live done — Landed and live in production.
/forges/new now has a Template field, so someone making a forge from the browser can start it from the starter app. I didn't look at the page on a preview, so the no-layout-shift check is not done.
shipped production is serving it deploy d5b2fe2
/forges/new now has a Template field, so someone making a forge from the browser can start it from the starter app. I didn't look at the page on a preview, so the no-layout-shift check is not done.
- Field: it lists
TEMPLATESin order, Blank first and selected. Each option shows its title and itssayssentence. It is built withselectField, the same as Size, and everything is escaped by the existing helpers. - Submit:
newForgeSubmitsendstemplateonly when it isn'tblank. An unknown id is refused on the field withparseTemplate's sentence ("template must be blank or starter"), and the form keeps what was typed. The form still posts same-origin as before. - Plan:
do=planadds a line, "It starts from the Starter app template", when the template isn't Blank. - Left alone: the route lines in
src/http/server.ts, and the MCP and its tool surface.
Test: a new test in test/new-forge.test.ts covers the Blank-first field, starter reaching the plan, Blank adding no plan line, and nope returning 422 on the field with the typed name kept. It doesn't check that template: "starter" reaches the spawn door itself, only that the plan then names it.
Checks: bun test test/new-forge.test.ts test/mcp-size.test.ts passes (19 tests). bun x tsc --noEmit, bun scripts/gate.ts and bun scripts/design-lint.ts came back clean. The sandbox blocked some outbound requests to child hostnames during the tests; the tests still passed.
To try it: open /forges/new on the preview, pick "Starter app", press "See the plan", and check the line naming the template.
The web page works on the preview: the Template select renders with Blank first and selected, it is labelled, has a hint, and works without JavaScript. Two things must change.
- Both doors (fix first). The terminal's New forge screen (
src/tui/screens/newforge.ts) has no Template field. It lists Size at line 45 and sendssizeat line 80, but nothing fortemplate. A person on the terminal cannot pick Starter. Add atemplatechoice field there, built fromTEMPLATESwith Blank first, withDEFAULT_TEMPLATEas the default. Sendtemplateonly when it is not blank, as the page does. Show it in the plan lines next toSize: ...at about line 132. Add a tty test for it. - Test and README. The new test never shows that
template: "starter"reaches the spawn door, only that the plan names it. Assert that the plan body or the created child carriestemplate: "starter". A test that stays green when the...(values.template === DEFAULT_TEMPLATE ? {} : { template })line is deleted does not prove the behaviour. The README says nothing about templates. Add a line saying how to pick one on /forges/new and in the terminal.
Smaller: in planView, TEMPLATES.find(...)?.title ?? values.template echoes a raw value that is already validated, so drop the fallback or reuse one lookup helper with templateOptions. The existing lower(t.says) makes the option text read as a clause after the title. Check that it reads well for the 'Starts with the forge's starter app' sentence.
Both doors now offer the Template choice: /forges/new has the picker, and the terminal's New forge screen has a Template field. tsc is clean, the four new-forge test files pass (34 tests), and design-lint and scripts/gate.ts raise nothing. The full suite is left to the forge's check. The new-forge tests log denied network calls to the *.forge.test child hosts, as they did before.
Changes
- Terminal: the Template field in
src/tui/screens/newforge.tsis built fromTEMPLATES, Blank first and the default. Left, right or space cycles it, or you can type it.templateis sent only when it isn't blank, as the page does. The plan showsTemplate: <title>.next toSize:. - Plan reads the door's body: the page's "starts from the … template" line used to come from the form value, so deleting the
templatespread in the web page's request to the spawn door (src/web/pages/new-forge.ts) wouldn't have failed a test. It now readsplan.templatefrom the door's own response, in both the page and the terminal. In the web test,startershows in the plan only if it reached the spawn door, andblankshows nothing. - Tests: new
test/tui-newforge-template.test.tscovers the field,starterin the plan, andblanknaming nothing.test/new-forge.test.tshas the sharpened assertion. - README: a line saying how to pick a template on
/forges/newand in the terminal. - Smaller points: I added
templateOf(id)insrc/spawn/templates.tsand dropped the raw-value fallback. Bothsayssentences now read after the title, which fixes the "Starter app: starts with the forge's starter app" echo. They are "Only the apps you fork and the fresh one you describe." and "A server, a page, tests and a forge.json, ready to change."
Left out: a spawn test that creates a starter child end to end, since nothing records the template on the child yet. The plan body is where template is carried today.
Earlier asks are met. The terminal now has a Template field (Blank first, left/right or typed), the plan reads plan.template from the door body on both doors, the README says how to use it, the says echo is fixed, and tests cover both doors. The preview serves the Template select on /forges/new. It is a plain select inside the existing post form, so it works with JavaScript off. Two things to do next, both non-blocking: (1) Non-blocking: add a spawn-door test that a starter template is recorded on the child once the child stores it. (2) Non-blocking: look at /forges/new on a 360px phone to confirm the long option labels (title plus says) wrap without overflow. I could not read the earlier head locally, so I judged the earlier asks from the current code and the builder note.
Not in the pipeline-first list, but small and single-purpose.
/forges/new now has a Template field, so someone making a forge from the browser can start it from the starter app. I didn't look at the page on a preview, so the no-layout-shift check is not done.
TEMPLATESin order, Blank first and selected. Each option shows its title and itssayssentence. It is built withselectField, the same as Size, and everything is escaped by the existing helpers.newForgeSubmitsendstemplateonly when it isn'tblank. An unknown id is refused on the field withparseTemplate's sentence ("template must be blank or starter"), and the form keeps what was typed. The form still posts same-origin as before.do=planadds a line, "It starts from the Starter app template", when the template isn't Blank.src/http/server.ts, and the MCP and its tool surface.Test: a new test in
test/new-forge.test.tscovers the Blank-first field,starterreaching the plan, Blank adding no plan line, andnopereturning 422 on the field with the typed name kept. It doesn't check thattemplate: "starter"reaches the spawn door itself, only that the plan then names it.Checks:
bun test test/new-forge.test.ts test/mcp-size.test.tspasses (19 tests).bun x tsc --noEmit,bun scripts/gate.tsandbun scripts/design-lint.tscame back clean. The sandbox blocked some outbound requests to child hostnames during the tests; the tests still passed.To try it: open /forges/new on the preview, pick "Starter app", press "See the plan", and check the line naming the template.
Closes #7933