Files
summercms/.planning/phases/01-framework-kernel-foundation/01-03-SUMMARY.md
Jakub Zych 9b2b035b68 docs(01-03): complete plugin scaffold CLI and watch-loop plan
- Record make:plugin, bonfire output and summer dev results
2026-09-16 14:01:34 +02:00

7.4 KiB

phase, plan, subsystem, tags, requires, provides, affects, tech-stack, key-files, key-decisions, patterns-established, requirements-completed, duration, completed
phase plan subsystem tags requires provides affects tech-stack key-files key-decisions patterns-established requirements-completed duration completed
01-framework-kernel-foundation 03 kernel
go
cobra
fsnotify
cli
scaffolding
watch
phase provides
01-framework-kernel-foundation Manifest-driven summer build, shared bonfire.NewRoot, hello app workspace
make:plugin and plugin:add scaffolding against summer.yaml
Deterministic bonfire Output widgets and prompts with non-TTY fallback
Built-in summer dev watch/rebuild/restart loop
01-04
04
added patterns
golang.org/x/term v0.46.0
github.com/fsnotify/fsnotify v1.10.1
summer.yaml is the sole ordered plugin list; scaffold then plugin:add then build
One injected bonfire.Output decides TTY/color once per process
summer dev calls the same build.App used by summer build
created modified
internal/build/manifest.go
internal/build/scaffold.go
bonfire/output.go
bonfire/widgets.go
bonfire/prompts.go
internal/dev/watch.go
internal/build/build.go
cmd/summer/main.go
bonfire/root.go
bonfire/command.go
examples/hello/plugins/greeter/plugin.go
go.mod
go.sum
plugin:add is idempotent on the same id+module and rejects conflicting ids
Child go commands override inherited GOWORK so summer build in a nested app does not use a parent workspace
Confirm is silent on non-TTY and uses its default so tests never hang
Watch ignores app-root main.go and plugins.gen.go to prevent generate loops
Pattern: make:plugin writes plugins/<name>/{go.mod,plugin.go,config/}; plugin:add wires manifest, go.work and go.mod replace
Pattern: plugin command names are namespace:verb; kernel names build and dev are the only colon-less exceptions
Pattern: summer dev prints rebuild: <duration> after each successful build.App and reaps the child on cancel
KERN-04
KERN-09
CLI-01
26min 2026-09-16

Phase 1 Plan 3: Plugin Scaffold, CLI Output and Watch Loop Summary

make:plugin / plugin:add wire a compiling module into summer.yaml, bonfire degrades spinner/progress/table/prompts without a TTY, and summer dev rebuilds through build.App with measured restart latency

Performance

  • Duration: 26 min
  • Started: 2026-09-16T11:33:58Z
  • Completed: 2026-09-16T12:00:25Z
  • Tasks: 3
  • Files modified: 21

Accomplishments

  • summer make:plugin scaffolds plugins/<name> with go.mod (toolchain go1.27.0), plugin.go and empty config/; plugin:add appends one ordered manifest entry, go work use, and a portable app go.mod require/replace
  • Shared cobra adapter injects one bonfire.Output built from stdin/stdout/stderr; non-TTY spinner is [...] message, progress is [N/M] pct% at 10% steps, tables are TSV, and NO_COLOR / TERM=dumb disable ANSI
  • summer dev watches sources, debounces, calls build.App, prints rebuild: <duration>, keeps the last child on build failure, and reaps it on cancel without looping on generated main.go / plugins.gen.go

Task Commits

Each task was committed atomically:

  1. Task 1: Add and rebuild a compiling plugin from the tool - 9b1a25d (feat)
  2. Task 2: Give tool and plugin commands deterministic rich output - a6004e4 (feat)
  3. Task 3: Rebuild and restart the hello binary during source edits - 270b7f1 (feat)

Plan metadata: pending (docs: complete plan)

Files Created/Modified

  • internal/build/manifest.go - Load/Save summer.yaml, lowercase vendor.plugin IDs
  • internal/build/scaffold.go - MakePlugin / AddPlugin with path containment checks
  • internal/build/build.go - generate-and-compile plus GOWORK isolation for child go commands
  • cmd/summer/main.go - make:plugin, plugin:add, build, dev tool commands
  • bonfire/output.go / widgets.go / prompts.go - injected Output, spinner, progress, table, prompts
  • bonfire/root.go / command.go - cobra adapter, named ErrCommandName for plugin names without :
  • internal/dev/watch.go - fsnotify watch loop with debounce, serialize, restart, reap
  • examples/hello/plugins/greeter/plugin.go - table plus confirm on greeter:hello without hanging on closed stdin

Decisions Made

  • Keep generated plugin paths under plugins/<name> derived from the ID's plugin segment
  • Treat build and dev as the only kernel command names allowed without a colon
  • Detect widgets from stdout TTY and prompts from stdin+stdout TTY so piped tests use defaults
  • secret uses term.ReadPassword on a TTY file and a plain stdin line otherwise; answers are never written back
  • Watch production path always calls build.App; tests inject Build/Start so debounce and ignore behavior stay fast

Deviations from Plan

Auto-fixed Issues

1. [Rule 3 - Blocking] Child go commands inherited test GOFLAGS/GOWORK

  • Found during: Task 1 (plugin compile on a temp hello copy)
  • Issue: go test sets -mod=readonly and a parent workspace; go build of a temp app then targeted the wrong module
  • Fix: Strip inherited GOWORK/GOFLAGS and set GOWORK to the nearest app go.work (or off)
  • Files modified: internal/build/scaffold.go, internal/build/build.go
  • Verification: go test ./internal/build
  • Committed in: 9b1a25d (Task 1)

2. [Rule 3 - Blocking] NewRoot now returns a named command-name error

  • Found during: Task 2
  • Issue: Plugin names without namespace:verb must fail registration; callers and generated main.go still treated NewRoot as a single return
  • Fix: NewRoot/NewRootIO return (*cobra.Command, error); generateMain and hello callers updated
  • Files modified: bonfire/root.go, internal/build/build.go, examples/hello/main.go, examples/hello/hello_test.go, cmd/summer/main.go
  • Verification: go test ./bonfire ./cmd/summer and hello tests
  • Committed in: a6004e4 (Task 2)

3. [Rule 3 - Blocking] Greeter test Output stub no longer satisfied the interface

  • Found during: Task 2
  • Issue: Expanding Output broke examples/hello/plugins/greeter/plugin_test.go's three-method stub
  • Fix: Run the command against bonfire.NewOutput with injected streams
  • Files modified: examples/hello/plugins/greeter/plugin_test.go
  • Verification: go test in the greeter module
  • Committed in: a6004e4 (Task 2)

Total deviations: 3 auto-fixed (3 blocking) Impact on plan: Required for temp-app builds, named registration errors, and a compiling greeter test. No scope creep. Choice prompts use a numbered list rather than TTY arrow keys; non-TTY behavior matches the plan.

Issues Encountered

  • go mod tidy in a workspace still drops toolchain go1.27.0 unless it is rewritten; Task 1 restores it after plugin tidy (same D-05 pattern as Plans 01 and 02).

Authentication Gates

None.

User Setup Required

None - no external service configuration required.

Next Phase Readiness

Ready for 01-04-PLAN.md (phase unit-test coverage). Scaffolding, rich CLI output and summer dev exist on the hello path. Do not add HTTP/DB/auth here.

Self-Check: PASSED

  • Created scaffold, output, watch, and SUMMARY files exist on disk
  • Commits 9b1a25d, a6004e4 and 270b7f1 exist
  • Root and hello go vet ./... and go test ./... passed
  • STATE.md and ROADMAP.md were not updated in this worktree

Phase: 01-framework-kernel-foundation Completed: 2026-09-16