- delegateCommands() builds every delegate from one table of name,
description and common-flags hint; toolCommands appends it
- route:list, key:generate, admin:create and admin:reset-password are new
delegates; the child keeps summer's stdin, so the password prompts work
- migrate:rollback, queue:work and schedule:run lose their hand-written
flag copies: --plugin, --queue and --once now pass through verbatim
- the command list marks delegates with "(flags pass to the app binary)"
and the help command prints a Long text with the common flags
- console introduction, setup-and-maintenance and the root README
describe the passthrough behaviour and the new delegates
- delegateCommand builds a Passthrough bonfire command, so
`summer serve --addr :8123`, `summer serve --help` and `-h` reach the
app binary instead of failing with "unknown flag: --addr"
- one leading "--" is dropped so `summer serve -- --addr :8123` still
works
- appRunner is a package-level seam that tests replace to capture argv
- Command.Passthrough turns off cobra flag parsing and uses arbitrary
args, so every argument after the command name, including --help, -h
and --, reaches Run through Input.Args unchanged
- Command.Long sets cobra's Long text for the help command; without it
the description is shown as before
- both fields are additive: commands without Passthrough parse flags and
reject unknown ones exactly as before
- README and docs/console/writing-commands.md describe both fields
- new.sh reads the basename of SHELL (via ${SHELL:-} under set -u) and
prints fish_add_path "<dir>" for fish, which keeps it for new sessions,
export PATH="<dir>:$PATH" naming ~/.zshrc or ~/.bashrc for zsh and
bash, and today's generic export line with "your shell profile" for
any other, empty or unset shell
- dq_escape escapes the install directory for the target shell's double
quotes: backslash, double quote and dollar always, plus backtick and a
single-quoted ! for POSIX shells; a per-character loop, so bash 3.2
and 5.2 behave the same
- the behaviour harness defaults SHELL to empty so cases do not depend on
the developer's login shell, adds an unset-SHELL mode and covers fish,
zsh, bash, empty, unset, unknown and two metacharacter directories
- TestBootstrapEndToEnd pins SHELL=/bin/bash
- sunrise README and docs/setup/installation.md describe the per-shell
hint; the manual PATH section gains fish_add_path (go env GOPATH)/bin
- security review: T-14.3-20..26 added, every row pinned by a named test or gate stage
- validation: per-plan map with exact tests and commands, validated and nyquist_compliant
- --unit: vet, full suite with named --- PASS lines for every required test,
goldens unchanged, examples/hello, docs check, site plugin/app, landing page
- --forbidden: no SUMMER_ name in new.sh, no new go.mod require since v0.1.12,
no plugin/yaegi dependency, relative golden paths, goldens not ignored
- --bootstrap and --terminal run the gated end-to-end checks
- --security parses the threat register; --all runs every stage in its own process
- TestScriptBehavior: 25 cases on a stub PATH (real git, stub go/docker/summer)
against a bare fake framework remote: usage and name errors, existing app,
Go missing/old/devel, git required, Docker warning, newest release tag,
SUMMERCMS_REF, fast-forward re-runs, refusals with HEAD unchanged,
summer called from the parent with stdin closed, cd line and PATH hint
- TestScriptShellcheck: shellcheck -s bash new.sh, skipped only without shellcheck
- 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.