From 9b2b035b68ec71012801369fc4a79d1ec8331a10 Mon Sep 17 00:00:00 2001 From: Jakub Zych Date: Wed, 16 Sep 2026 14:01:34 +0200 Subject: [PATCH] docs(01-03): complete plugin scaffold CLI and watch-loop plan - Record make:plugin, bonfire output and summer dev results --- .../01-03-SUMMARY.md | 164 ++++++++++++++++++ 1 file changed, 164 insertions(+) create mode 100644 .planning/phases/01-framework-kernel-foundation/01-03-SUMMARY.md diff --git a/.planning/phases/01-framework-kernel-foundation/01-03-SUMMARY.md b/.planning/phases/01-framework-kernel-foundation/01-03-SUMMARY.md new file mode 100644 index 0000000..98658b8 --- /dev/null +++ b/.planning/phases/01-framework-kernel-foundation/01-03-SUMMARY.md @@ -0,0 +1,164 @@ +--- +phase: 01-framework-kernel-foundation +plan: 03 +subsystem: kernel +tags: [go, cobra, fsnotify, cli, scaffolding, watch] + +requires: + - phase: 01-framework-kernel-foundation + provides: Manifest-driven summer build, shared bonfire.NewRoot, hello app workspace +provides: + - 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 +affects: [01-04, 04] + +tech-stack: + added: + - golang.org/x/term v0.46.0 + - github.com/fsnotify/fsnotify v1.10.1 + patterns: + - 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 + +key-files: + created: + - internal/build/manifest.go + - internal/build/scaffold.go + - bonfire/output.go + - bonfire/widgets.go + - bonfire/prompts.go + - internal/dev/watch.go + modified: + - internal/build/build.go + - cmd/summer/main.go + - bonfire/root.go + - bonfire/command.go + - examples/hello/plugins/greeter/plugin.go + - go.mod + - go.sum + +key-decisions: + - "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" + +patterns-established: + - "Pattern: make:plugin writes plugins//{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: after each successful build.App and reaps the child on cancel" + +requirements-completed: [KERN-04, KERN-09, CLI-01] + +duration: 26min +completed: 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/` 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: `, 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/` 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*