Skip to content

feat: add modular setup CLI for optional feature removal#58

Open
matheuskafuri wants to merge 21 commits into
occult:mainfrom
matheuskafuri:feat/modular-setup-cli
Open

feat: add modular setup CLI for optional feature removal#58
matheuskafuri wants to merge 21 commits into
occult:mainfrom
matheuskafuri:feat/modular-setup-cli

Conversation

@matheuskafuri

@matheuskafuri matheuskafuri commented Mar 27, 2026

Copy link
Copy Markdown

Summary

  • Add [feature:X] comment markers to 10 shared files across the codebase, wrapping all code blocks belonging to the 5 optional features (Payment, Chat, Mail, Tasks, File Upload)
  • Implement interactive TUI setup tool (cmd/setup/) using charmbracelet/huh that lets developers uncheck features they don't need — the tool deletes files, patches shared files via markers, regenerates Ent ORM, and verifies both Go and frontend builds
  • Add design document and test plan covering 10 test scenarios (individual removal, multi-feature, all-features, edge cases)

How it works

After cloning, developers commit and run make setup. A TUI checklist presents all 5 optional features pre-checked. Unchecking a feature triggers surgical removal: standalone files deleted, marker-delimited blocks stripped from shared files, Ent ORM regenerated, dependencies cleaned, and builds verified. The tool removes itself on success.

Test plan

  • Test 1: Keep all features → prints "No changes needed", no files modified
  • Test 2: Remove Chat only → chat files/schemas deleted, Ent regenerated, build passes
  • Test 3: Remove Payment only → Stripe files deleted, middleware patched, build passes
  • Test 4: Remove Mail only → auth handler degrades gracefully, build passes
  • Test 5: Remove Tasks only → admin handler patched, build passes
  • Test 6: Remove Files only → container + sidebar patched, build passes
  • Test 7: Remove Chat + Payment → multiple Ent schema removal, build passes
  • Test 8: Remove ALL features → core skeleton remains, build passes, tool self-removes
  • Test 9: Dirty git tree → tool refuses to run
  • Test 10: Idempotent run → second run with same selection succeeds

See docs/plans/2026-03-27-modular-setup-cli-test-plan.md for full verification commands.

Q&A

https://drive.google.com/file/d/10A74uX7UwIqCtiWhSCRvNttdO7F8hZAT/view?usp=sharing

Wrap feature-specific code blocks in container.go, router.go, auth.go,
admin.go, middleware/auth.go, user.go, AppSidebar.tsx, config.yaml,
routenames/names.go, and Makefile with start/end markers for the 5
optional features: payment, chat, mail, tasks, and files.

These markers are inert comments that enable the setup CLI to
surgically remove deselected features.
Interactive TUI tool (cmd/setup/) that lets developers opt-out of
features they don't need when bootstrapping a Pagode project.

Supports removing: Payment (Stripe), Chat (WebSocket), Mail (Resend),
Background Tasks (Backlite), and File Upload. The tool deletes feature
files, patches shared files via comment markers, regenerates Ent ORM,
runs go mod tidy, and verifies both Go and frontend builds before
cleaning itself up.

Usage: make setup (or go run cmd/setup/main.go)
- Add FeatureName field to Module struct, replacing hardcoded name map
  in featureNamesFromModules so new features need no changes to main.go
- Remove 6 unused Module fields (UserEdges, NavItems, RouteNames, etc.)
- Always warn visibly when frontend build verification is skipped
- Use filepath.Join/Dir instead of manual string slicing in projectRoot
- Tighten isGitClean to only exempt untracked files in cmd/setup/
Copilot AI review requested due to automatic review settings March 27, 2026 23:26

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a one-shot “setup” CLI to remove optional features from the template (via [feature:<name>] markers), along with Ent regeneration/cleanup improvements and dedicated documentation/test coverage for the removal flow.

Changes:

  • Added cmd/setup TUI tool + removal pipeline (delete feature-owned files/dirs, patch marked blocks, regenerate Ent, tidy deps, verify builds, self-delete).
  • Added/expanded [feature:*] markers across Go/TSX/YAML/Makefile so optional feature removal can safely excise shared references.
  • Added documentation (SETUP guide + design/test plan) and tests for marker patching and Ent cleanup behavior.

Reviewed changes

Copilot reviewed 29 out of 30 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
resources/js/components/ui/shape-landing-hero.tsx Refactors motion easing values into shared constants.
resources/js/components/AppSidebar.tsx Adds feature markers around optional nav items and icon imports.
resources/js/Pages/Plans.tsx Adds icon import used by plan UI.
pkg/ui/layouts/primary.go Adds feature markers around optional menu links.
pkg/services/container.go Adds feature markers around optional services, imports, init/shutdown wiring.
pkg/routenames/names.go Adds feature markers around optional route-name constants.
pkg/middleware/auth.go Adds feature markers around payment-only imports and middleware.
pkg/handlers/router.go Adds feature markers around optional WebSocket routing hooks.
pkg/handlers/auth.go Adds feature markers around mail-only wiring and email behaviors.
pkg/handlers/admin.go Adds feature markers around tasks/admin UI wiring (Backlite).
go.sum Updates module checksums for new setup CLI dependencies.
go.mod Adds indirect dependencies needed for the setup CLI.
ent/schema/user.go Adds feature markers around optional edges (payment/chat).
ent/admin/types.go Normalizes acronym casing for generated admin structs (e.g., IPHash).
ent/admin/handler.go Updates generated admin UI column labels + casing.
ent/admin/extension_test.go Adds tests for field-name/label acronym normalization.
ent/admin/extension.go Adds acronym normalization helpers for admin generation.
docs/plans/2026-03-27-modular-setup-cli-test-plan.md Adds a detailed manual regression test plan for feature removal.
docs/plans/2026-03-27-modular-setup-cli-design.md Documents the setup CLI architecture and marker strategy.
config/config.yaml Adds feature markers around optional config sections.
cmd/web/main.go Adds feature markers around tasks startup wiring.
cmd/setup/remover_test.go Adds regression test ensuring marker scan skips cmd/setup but patches cmd/web.
cmd/setup/remover.go Implements marker scanning + block removal + small cleanup passes.
cmd/setup/modules.go Declares optional feature manifests (files/dirs/schemas per feature).
cmd/setup/main.go Adds TUI orchestration and end-to-end removal pipeline.
cmd/setup/cleanup_test.go Adds tests for Ent stale artifact cleanup and pre-regeneration admin cleanup.
cmd/setup/cleanup.go Implements Ent regen, stale Ent cleanup, build verification, and self-cleanup.
SETUP.md Adds a dedicated setup guide (usage, internals, maintainer checklist).
README.md Links to SETUP guide and documents optional feature setup entrypoint.
Makefile Adds setup target + feature markers around chat-specific make target.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread cmd/setup/cleanup.go
Comment on lines +161 to +167
// Remove the huh dependency and run go mod tidy again.
if err := c.runCmd("go", "get", "-u", "github.com/charmbracelet/huh@none"); err != nil {
// Ignore error — go mod tidy will clean it up anyway.
if c.verbose {
fmt.Printf(" note: could not remove huh dependency directly: %v\n", err)
}
}

Copilot AI Mar 27, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using go get -u github.com/charmbracelet/huh@none during self-cleanup risks upgrading unrelated dependencies due to -u. Prefer a dependency removal approach that doesn’t trigger upgrades (e.g., go mod edit -droprequire or go get github.com/charmbracelet/huh@none without -u), then run go mod tidy.

Copilot uses AI. Check for mistakes.
Comment thread cmd/setup/remover.go
Comment on lines +70 to +90
func (r *Remover) PatchFeatureMarkers(featureNames []string) (int, error) {
filesPatched := 0

for _, name := range featureNames {
files, err := r.findFilesWithMarker(name)
if err != nil {
return filesPatched, err
}

for _, f := range files {
patched, err := r.removeMarkerBlocks(f, name)
if err != nil {
return filesPatched, fmt.Errorf("failed to patch %s for feature %s: %w", f, name, err)
}
if patched {
filesPatched++
if r.verbose {
fmt.Printf(" patched: %s (removed [feature:%s] blocks)\n", relPath(r.root, f), name)
}
}
}

Copilot AI Mar 27, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PatchFeatureMarkers increments filesPatched per (feature, file) patch. If a single file contains markers for multiple removed features, it will be counted multiple times, so the reported “files patched” total can be misleading. Track unique file paths patched across all features (e.g., a set) and return the unique count.

Copilot uses AI. Check for mistakes.
Comment thread cmd/setup/cleanup_test.go
"testing"
)

func TestCleanStaleEntFilesRemovesGeneratedAdminFiles(t *testing.T) {

Copilot AI Mar 27, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test name suggests it removes generated admin files, but the assertions verify ent/admin/handler.go and ent/admin/types.go still exist; it’s actually validating removal of orphaned entity artifacts (e.g., paymentcustomer) while preserving shared/admin files. Rename the test to reflect what it’s asserting to avoid confusion when maintaining the ent cleanup logic.

Suggested change
func TestCleanStaleEntFilesRemovesGeneratedAdminFiles(t *testing.T) {
func TestCleanStaleEntFilesRemovesOrphanedEntArtifactsPreservesAdminFiles(t *testing.T) {

Copilot uses AI. Check for mistakes.
Comment on lines +75 to +93
### Module Manifest Structure

Each optional feature is described declaratively as a `Module` struct:

```go
type Module struct {
Name string // Display name in TUI (e.g., "Payment (Stripe)")
Description string // One-liner description
Files []string // Standalone files to delete
Dirs []string // Directories to delete recursively
EntSchemas []string // Ent schema files to remove (triggers ent-gen)
UserEdges []string // Edge names to remove from ent/schema/user.go
NavItems []string // Sidebar nav item titles to remove from AppSidebar.tsx
RouteNames []string // Constants to remove from routenames/names.go
ConfigKeys []string // Top-level keys to remove from config.yaml
GoDeps []string // Go module paths to expect removal via go mod tidy
MakeTargets []string // Makefile targets to remove
}
```

Copilot AI Mar 27, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The design doc’s Module struct (with UserEdges, NavItems, RouteNames, etc.) doesn’t match the current implementation in cmd/setup/modules.go (which only has Name, FeatureName, Description, Files, Dirs, EntSchemas). The flow diagram also references go generate ./ent, but the implementation runs go run -mod=mod entc.go from ent/. Please update this doc section to reflect the actual code so maintainers don’t follow a stale contract.

Copilot uses AI. Check for mistakes.
Comment thread go.mod
Comment on lines +36 to +41
github.com/charmbracelet/bubbles v0.21.1-0.20250623103423-23b8fd6302d7 // indirect
github.com/charmbracelet/bubbletea v1.3.6 // indirect
github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc // indirect
github.com/charmbracelet/huh v1.0.0 // indirect
github.com/charmbracelet/lipgloss v1.1.0 // indirect
github.com/charmbracelet/x/ansi v0.9.3 // indirect

Copilot AI Mar 27, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

github.com/charmbracelet/huh is imported directly by cmd/setup/main.go, but it’s currently listed as // indirect in go.mod. This makes dependency intent unclear and can get flipped unexpectedly by go mod tidy. Update go.mod so huh is a direct requirement (i.e., remove the // indirect classification by re-tidying with cmd/setup present).

Copilot uses AI. Check for mistakes.
@matheuskafuri matheuskafuri changed the title Fix modular setup CLI removal flow and docs feat: add modular setup CLI for optional feature removal Mar 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants