docs(14.3-01): complete summer new generator plan

This commit is contained in:
Jakub Zych
2026-10-08 11:45:53 +02:00
parent 6695ab422a
commit d0888d7576
3 changed files with 240 additions and 20 deletions

View File

@@ -899,12 +899,12 @@ Plans:
5. `docs/setup/installation.md` leads with the one-liner, `go-modules-and-workspaces.md` and the console docs cover `summer new`, and `llms.txt`/`llms-full.txt` include the changes; docs checks pass.
6. Generator Go tests (golden output plus a real build of the scaffold in a temp dir) are the last plan.
**Plans:** 4 plans
**Plans:** 1/4 plans executed
Plans:
**Wave 1**
- [ ] 14.3-01-PLAN.md — `summer new` generator: starter plugin via make:plugin/plugin:add, relative go.work, config, .env + lagoon.GenerateAppKey, compose, CLAUDE.md/AGENTS.md, first commit, D-12 docker gate
- [x] 14.3-01-PLAN.md — `summer new` generator: starter plugin via make:plugin/plugin:add, relative go.work, config, .env + lagoon.GenerateAppKey, compose, CLAUDE.md/AGENTS.md, first commit, D-12 docker gate
**Wave 2** *(blocked on Wave 1 completion)*
- [ ] 14.3-02-PLAN.md — Bootstrap script in `modules/sunrise`, `GET /new` in the site plugin, node:24-bookworm acceptance, security review
@@ -1089,7 +1089,7 @@ Phases execute in numeric order: 1 → 2 → 3 → 4 → 5 → 6 → 7 → 8 →
| 14. Domain jobs and external integrations | 6/6 | In Progress| |
| 14.1. OAuth identities and fonoteka me routes (INSERTED) | 2/2 | Complete | 2026-10-05 |
| 14.2. Local Fonoteka frontend on local SummerCMS backend (INSERTED) | 0/TBD | Not started | - |
| 14.3. One-command app scaffolding (INSERTED) | 0/4 | Not started | - |
| 14.3. One-command app scaffolding (INSERTED) | 1/4 | In Progress| |
| 15. Journal plugin | 4/4 | Complete | 2026-10-06 |
| 16. grzybyfunkcjonalne.pl on reusable blog views | 0/TBD | Not started | - |
| 17. Blog companions | 0/TBD | Not started | - |

View File

@@ -1,19 +1,19 @@
---
gsd_state_version: "1.0"
milestone: v1.0
current_phase: "14.2"
current_phase_name: local-fonoteka-frontend-on-local-summercms-backend
current_phase: "14.3"
current_phase_name: "One-command app scaffolding: summer new and summercms.io/new bootstrap script"
status: executing
stopped_at: Phase 14.2 context gathered
last_updated: "2026-10-07T22:23:37.716Z"
last_activity: 2026-10-07
last_activity_desc: Completed quick task 261006-s0v (remove ML copy-from locale UI)
state_head: 498f4b4f3af1a7057e96f81ccf714a4b3c79f428
stopped_at: Completed 14.3-01-PLAN.md
last_updated: "2026-10-08T09:45:45.397Z"
last_activity: 2026-10-08
last_activity_desc: Phase 14.3 execution started
state_head: 6695ab422aa0155f49c7ca87bdcb5fbf405c9e35
progress:
total_phases: 31
completed_phases: 13
total_plans: 139
completed_plans: 135
total_plans: 143
completed_plans: 136
milestone_name: milestone
---
@@ -24,14 +24,14 @@ milestone_name: milestone
See: .planning/PROJECT.md (updated 2026-09-16)
**Core value:** An existing WinterCMS-shaped app can be ported plugin by plugin to a single Go binary without its frontend noticing: the PHP version's API contract is the acceptance test.
**Current focus:** Phase 15 — Journal plugin
**Current focus:** Phase 14.3 — One-command app scaffolding: summer new and summercms.io/new bootstrap script
## Current Position
Phase: 14.2 (local-fonoteka-frontend-on-local-summercms-backend) — READY TO EXECUTE
Plan: 4 of 4
Status: Ready for phase verification
Last activity: 2026-10-07 — Completed quick task 261007-qgx: record heading from translatable (mltext) fields
Phase: 14.3 (One-command app scaffolding: summer new and summercms.io/new bootstrap script) — EXECUTING
Plan: 2 of 4
Status: Ready to execute
Last activity: 2026-10-08 — Phase 14.3 execution started
Progress: [██████████] 100%
@@ -189,6 +189,7 @@ Progress: [██████████] 100%
| Phase 15 P15-01 | 11 | 3 tasks | 31 files |
| Phase 15 P15-02 | 75 min | 3 tasks | 39 files |
| Phase 15 P15-03 | 80 min | 3 tasks | 22 files |
| Phase 14.3 P01 | 13 min | 3 tasks | 17 files |
## Accumulated Context
@@ -604,6 +605,10 @@ Recent decisions affecting current work:
- [Phase 15]: NavigationItem has no IconSvg; journal-icon.svg is go:embed in AdminFS; user_id is WritableForeignKey and FormBeforeCreate stamps it when empty
- [Phase 15]: 15-04 security review was executor-self-performed (no gsd-security-auditor in this Cursor session); every cited TestName was re-run. Wave-3 HTTP tests stay at plugin root; controllers/api holds clampPerPage/media path units plus EndToEnd stubs.
- [Phase 15]: Host journal gitlink is a nested clone; bump via file:// fetch with protocol.file.allow=always. TestSearchGateOff must not skip.
- [Phase 14.3]: bonfire accepts new as a bare command name for summer new
- [Phase 14.3]: summer new compose.yaml publishes postgres:16 on 127.0.0.1:54320 only (user/password summer)
- [Phase 14.3]: summer new falls back to SummerCMS <summer@localhost> only for missing git identity keys
- [Phase 14.3]: plugin:add writes go.work use paths relative to the go.work directory
### Pending Todos
@@ -666,6 +671,6 @@ Items acknowledged and carried forward from previous milestone close:
## Session Continuity
Last session: 2026-10-07T17:58:21.728Z
Stopped at: Phase 14.2 context gathered
Resume file: .planning/phases/14.2-local-fonoteka-frontend-on-local-summercms-backend/14.2-CONTEXT.md
Last session: 2026-10-08T09:45:44.793Z
Stopped at: Completed 14.3-01-PLAN.md
Resume file: None

View File

@@ -0,0 +1,215 @@
---
phase: 14.3-one-command-app-scaffolding-summer-new-and-summercms-io-new
plan: 01
subsystem: cli
tags: [summer-new, scaffolding, internal-build, go-work, lagoon, compose, postgres16]
requires:
- phase: 01-framework-kernel-foundation
provides: make:plugin, plugin:add, summer build (internal/build), bonfire commands
- phase: 05-data-layer-full-fidelity
provides: lagoon app.key handling and key:generate
provides:
- "summer new <name> [--framework] [--no-plugin] [--no-git] writing a ready-to-run sm-<name>-app"
- "build.NewOptions, build.NewApp, build.ValidateAppName; unexported planNewApp/genFile for golden tests"
- "make:plugin opt-in starter route (StarterRoute) in the single routes.go template"
- "plugin:add writes relative go.work use paths"
- "lagoon.GenerateAppKey"
- "examples/hello/config/http.yaml (TestTypedItemRoute green)"
- "scripts/check-phase14.3.sh --generator (D-12 on real PostgreSQL 16)"
affects: [14.3-02 bootstrap script, 14.3-03 docs, 14.3-04 unit tests]
actuals:
tokens: 11696
tasks: 3
commits: 6
plan_head_before: 86fcd5d4fd2b8347629592a254029573cb67c7d3
plan_head_after: 6695ab422aa0155f49c7ca87bdcb5fbf405c9e35
tech-stack:
added: []
patterns:
- "Pure planNewApp (renders genFile list, reads only the framework go.mod) plus an executor that writes, then reuses makePlugin/AddPlugin/generate"
- "relModulePath helper shared by editAppModule, runGoWorkUse and the app replace"
- "frameworkFromBinary package variable so tests can replace binary-source detection"
key-files:
created:
- internal/build/new.go
- internal/build/new_test.go
- internal/build/stubs/new.tmpl
- examples/hello/config/http.yaml
- scripts/check-phase14.3.sh
modified:
- internal/build/scaffold.go
- internal/build/stubs/plugin.tmpl
- cmd/summer/main.go
- cmd/summer/main_test.go
- modules/bonfire/command.go
- modules/bonfire/command_test.go
- modules/bonfire/README.md
- modules/lagoon/keygen.go
- modules/lagoon/keygen_test.go
- modules/lagoon/README.md
- README.md
- docs/setup/installation.md
key-decisions:
- "bonfire accepts `new` as a bare command name (alongside build, dev, serve, migrate); required for `summer new`"
- "compose.yaml values (postgres:16, summer/summer, 127.0.0.1:54320) are literal in new.tmpl; Go constants build the matching .env DSN"
- "Fallback git identity is applied per missing key only (user.name and/or user.email), with a warning"
- "AGENTS.md is a relative symlink to CLAUDE.md"
- "Generated-app commit carries no trailers; .env is excluded by .gitignore written before git add -A"
patterns-established:
- "New app templates live in stubs/new.tmpl under define names prefixed new/"
- "Any error after os.Mkdir of the target removes the target (it did not exist before the run)"
requirements-completed: [D-01, D-02, D-03, D-04, D-05, D-06, D-07, D-08, D-09, D-10, D-11, D-12, D-22, D-23, D-24, D-25, D-27]
coverage:
- id: D1
description: "summer new writes sm-<name>-app with a relative framework replace, relative go.work, config/ and a starter plugin whose GET /{$} route is listed by route:list"
requirement: D-05
verification:
- kind: integration
ref: "internal/build/new_test.go#TestNewAppSmoke"
status: pass
- kind: integration
ref: "internal/build/build_test.go#TestMakeAndAddPluginOnHelloCopy"
status: pass
human_judgment: false
- id: D2
description: "Name rule, existing-target refusal, missing-framework error naming --framework, sibling detection and --no-plugin build"
requirement: D-02
verification:
- kind: other
ref: "Task 2 verify shell block (-trimpath summer; RULES-OK)"
status: pass
human_judgment: false
- id: D3
description: "Generated app builds, migrates on compose PostgreSQL 16 and serves the starter route with no edits; .env 0600 untracked, one fallback-identity commit, AGENTS.md symlink, no root go.sum"
requirement: D-12
verification:
- kind: e2e
ref: "bash scripts/check-phase14.3.sh --generator"
status: pass
human_judgment: false
- id: D4
description: "lagoon.GenerateAppKey exported; key:generate output unchanged"
requirement: D-08
verification:
- kind: unit
ref: "modules/lagoon/keygen_test.go#TestEncryptedKeyGeneratePrints32ByteBase64"
status: pass
- kind: unit
ref: "modules/lagoon/keygen_test.go#TestGenerateAppKeyIs32ByteBase64"
status: pass
human_judgment: false
- id: D5
description: "examples/hello serves without a manual config step"
requirement: D-07
verification:
- kind: integration
ref: "go -C examples/hello test ./..."
status: pass
human_judgment: false
- id: D6
description: "Generated CLAUDE.md wording is neutral and useful for agents"
requirement: D-10
verification: []
human_judgment: true
rationale: "Tone and usefulness of agent instructions need a human read; greps only prove the required links and names are present"
duration: 13min
completed: 2026-10-08
status: complete
---
# Phase 14.3 Plan 01: summer new generator Summary
**`summer new <name>` writes a ready-to-run sm-<name>-app (relative framework replace and go.work, config/, starter plugin with GET /, .env with a fresh key, postgres:16 compose on 127.0.0.1:54320, CLAUDE.md/AGENTS.md, first git commit) that builds, migrates and serves with no edits.**
## Performance
- **Duration:** 13 min
- **Started:** 2026-10-08T09:32:14Z
- **Completed:** 2026-10-08T09:44:54Z
- **Tasks:** 3
- **Files modified:** 17
## Accomplishments
- `build.NewApp` plus `summer new` with `--framework`, `--no-plugin`, `--no-git`; framework resolution `--framework` > sibling `summercms`/`summercms.go` > binary source tree, each checked by module path.
- Shared code-path fixes: `make:plugin` gains an opt-in starter route in the same template (plain output byte-identical, verified against the previous template); `plugin:add` writes relative `go.work` paths.
- Refusals: invalid names (regex, Go keywords, `main`, `internal`), any existing target, a target inside the framework checkout, a missing parent; a failed run removes its own target.
- `lagoon.GenerateAppKey` exported and documented; `examples/hello` ships `config/http.yaml`.
- `scripts/check-phase14.3.sh --generator` proves D-12 on real PostgreSQL 16: `GET /` returned `{"message":"Hello from SummerCMS","plugin":"golem15.demo"}`.
## Task Commits
1. **Task 1: summer new tracer** - `7bc955a` (feat)
2. **Task 2: framework detection, refusals, cleanup, --no-plugin** - `c33ebf3` (feat), hello fix `cc7386d` (fix)
3. **Task 3: key, compose, agent notes, git, next steps, gate** - `ca5b296` (feat, lagoon), `147ef24` (feat, generator), `6695ab4` (chore, gate)
## Files Created/Modified
- `internal/build/new.go` - NewOptions, NewApp, ValidateAppName, resolveFramework, binarySourceFramework, planNewApp, populateApp, initGit
- `internal/build/stubs/new.tmpl` - go.mod, config/*, .env, .env.example, compose.yaml, .gitignore, CLAUDE.md, next steps
- `internal/build/stubs/plugin.tmpl` - routes.go `{{if .StarterRoute}}` branch
- `internal/build/scaffold.go` - makePlugin(pluginOptions), relModulePath, relative runGoWorkUse
- `internal/build/new_test.go` - TestNewAppSmoke
- `cmd/summer/main.go`, `cmd/summer/main_test.go` - `new` command and its test entries
- `modules/bonfire/command.go`, `command_test.go`, `README.md` - `new` allowed as a bare name
- `modules/lagoon/keygen.go`, `keygen_test.go`, `README.md` - GenerateAppKey
- `examples/hello/config/http.yaml`, `README.md`, `docs/setup/installation.md` - body_limits gap closed
- `scripts/check-phase14.3.sh` - generator gate
## Decisions Made
- `new` is added to bonfire's bare-name allowlist (see deviation 1).
- Fallback git identity covers only the missing keys, so a user with `user.name` set but no email keeps their name.
- Compose values are literal in the template so the loopback-only binding is greppable; the DSN is assembled from matching Go constants.
## Deviations from Plan
### Auto-fixed Issues
**1. [Rule 3 - Blocking] bonfire rejected the bare command name `new`**
- **Found during:** Task 1
- **Issue:** `bonfire.NewRoot` only accepts `build`, `dev`, `serve`, `migrate` as bare names; `TestToolCommandNames` failed with `plugin command name must be namespace:verb: "new"`.
- **Fix:** Added `new` to `validCommandName`, to `TestValidBareRuntimeCommandNames`, and to the bonfire README sentence listing bare names (project documentation rule).
- **Files modified:** modules/bonfire/command.go, modules/bonfire/command_test.go, modules/bonfire/README.md
- **Verification:** `go test ./modules/bonfire/ ./cmd/summer/` pass
- **Committed in:** 7bc955a
**2. [Rule 1 - Bug] Gate script EXIT trap referenced function locals**
- **Found during:** Task 3
- **Issue:** The cleanup trap runs after `stage_generator` returns, when its `local` variables are gone, so Docker cleanup would have been skipped.
- **Fix:** Made `tmp`, `app`, `project`, `server_pid` globals.
- **Verification:** After the gate run no `phase143` containers or volumes remain and the temp dir is removed.
- **Committed in:** 6695ab4
---
**Total deviations:** 2 auto-fixed (1 blocking, 1 bug). **Impact:** Both necessary; the bonfire change only widens the accepted name set (non-breaking).
## Issues Encountered
- `internal/build/registry.go` is listed by `gofmt -l` before this plan; untouched (out of scope).
## User Setup Required
None - no external service configuration required.
## Next Phase Readiness
- Plan 02 can call `summer new <name> --framework <fw>` from the bootstrap script; next steps are printed by `summer new` itself (no `cd` line).
- Plan 03 should document `summer new` (console docs, installation one-liner, go-modules page, relative `plugin:add` go.work paths) and may drop the remaining hello `main.go` known-issue bullet.
- Plan 04 can golden-test `planNewApp` with `testAppKey` and replace `frameworkFromBinary`.
---
*Phase: 14.3-one-command-app-scaffolding-summer-new-and-summercms-io-new*
*Completed: 2026-10-08*
## Self-Check: PASSED