- installation: one-liner first, what the script does and its overrides,
running the generated app, summer new without the script, then the
examples/hello walkthrough; the obsolete known-issues callout is gone (D-18)
- go modules and workspaces: what summer new writes (relative replace,
framework detection order, committed relative go.work, no root go.sum);
plugin:add adds a relative go.work path
- console scaffolding: Creating an application with --framework, --no-plugin,
--no-git, the files written, first commit and naming convention (D-01)
- console introduction, llms note in site.yaml, root README quick start
- ASVS L1 table (V5, V6, V10, V12, V14) and T-14.3-01..19 plus T-14.3-SC
with controls, evidence and the plan 04 test that will pin each row
- 17 mitigated, 3 accepted (low), 0 open; refusal probe results
- --acceptance: in a bare node:24-bookworm container install jq, the Docker
CLI and compose plugin (Docker apt repo) and Go 1.27.0 (sha256 from go.dev),
pipe the committed new.sh into bash with SUMMERCMS_REPO=/fw and
SUMMERCMS_REF=HEAD, then run the D-20 chain and require the starter route
- refuses when modules/sunrise/new.sh differs from HEAD; unique compose
project with host-side cleanup of containers, volumes and networks
- --acceptance-production: same chain against https://summercms.io/new
- modules/sunrise/new.sh: curl | bash installer wrapped in main(), checks
Go 1.27+/git/Docker, clones or fast-forwards the framework at the newest
release tag (SUMMERCMS_REPO/DIR/REF overrides), installs summer and runs
summer new next to the checkout, prints the cd line and a PATH hint
- sunrise.Script() returns a fresh copy of the embedded script
- smoke, shape, truncation and gated end-to-end tests; README and modules row
- scripts/check-phase14.3.sh --generator runs summer new next to a
symlinked checkout with no git identity, checks the layout and first
commit, then docker compose up, summer build, migrate and serve, and
requires the starter route to answer
Claude-Session: https://claude.ai/code/session_01M8Qu9LgCKYy7iYEho52tW8
- .env (0600) with a fresh lagoon.GenerateAppKey key and the compose DSN;
.env.example without a key
- compose.yaml runs postgres:16 on 127.0.0.1:54320 with a healthcheck
- .gitignore, CLAUDE.md with AGENTS.md as a relative symlink
- git init on main and one commit, with a fallback identity only when git
has none; git failures are warnings; --no-git skips it
- print the next steps after creating the app
Claude-Session: https://claude.ai/code/session_01M8Qu9LgCKYy7iYEho52tW8
- key:generate now calls GenerateAppKey; its output is unchanged
- tools can write a fresh app.key without the check-mark decoration
- document lagoon.GenerateAppKey in the lagoon README
Claude-Session: https://claude.ai/code/session_01M8Qu9LgCKYy7iYEho52tW8
- add examples/hello/config/http.yaml so serve, route:list and
TestTypedItemRoute work without a manual config step
- drop the matching setup step and known-issue notes from README.md and
docs/setup/installation.md
- resolve the framework from --framework, then a sibling summercms or
summercms.go checkout, then the binary's own source tree, each accepted
only when its go.mod declares the framework module
- refuse a missing parent and a target inside the framework checkout
- remove the half-written app when any step fails
- add --no-plugin for an app with no starter plugin
- build.NewApp writes sm-<name>-app: go.mod with a relative framework
replace, go.work, summer.yaml, config/ and a starter plugin
- make:plugin gains an opt-in starter route (GET /{$}) in the same
routes.go template; plain make:plugin output is unchanged
- plugin:add writes go.work use paths relative to the go.work directory
- bonfire accepts new as a bare tool command name
Four plans: Go glue (dev seed, plugin-command DB, marker, framework
/storage mount, access log), dev-stack.sh and guard, Nuxt specs and
manual UAT, unit tests and check-phase14.2.sh. Adds D-23 (Centrifugo
collection/wishlist namespaces) and resolves research open questions.
The record heading, breadcrumb crumb and document title took the first
plain text field only, so records named by an mltext field fell back to
the generic update message. A shared recordDisplayName helper now takes
the first text or ML field and reads its default locale, then the first
non-empty one.
A settings entry with a controller opens that controller's route from
its card (settingsPath); singleton cards still open /settings/<code>.
On a linked controller with no navigation entry of its own the rail
marks Settings current, the breadcrumbs read Settings > entry label
(plus the record title on record and create routes) and the page title
uses the entry label. The settings docs describe the admin behaviour;
the embedded admin shell is rebuilt.
pact.SettingsItem gains an additive Controller field, the equivalent of a
WinterCMS registerSettings 'url' => Backend::url(...) entry. A link entry
declares no Model, Form or NewModel and needs no AdminFS; start-up fails
when it combines Controller with a singleton form or a model, or names an
unregistered controller. Settings codes stay one namespace.
GET /settings lists a link entry with its controller only when the
principal passes the item's permissions and may open the controller.
Registry.Setting never returns a link entry, so the singleton settings
endpoints answer 404 for its code. SettingsEntry carries controller,
empty for singletons; the OpenAPI document, generated SPA types and
settings fixture follow, and the pact and cabana READMEs and the
settings docs describe the link.
The admin sets the html font size to 14px, so the rem utilities w-11 and
size-5 shrank the track to 38.5px and the knob to 17.5px against the
fixed 26px height and 18px travel. Use w-[44px] and size-[20px] so the
knob sits in a symmetric 3px inset at both ends. Rebuild the embedded
admin shell.