|
| 1 | +# PROJECT KNOWLEDGE BASE |
| 2 | + |
| 3 | +**Generated:** 2026-02-11 |
| 4 | +**Commit:** 5fd1715 |
| 5 | +**Branch:** main |
| 6 | + |
| 7 | +## OVERVIEW |
| 8 | + |
| 9 | +Mac dev environment setup CLI. Go 1.24 + Cobra + Charmbracelet (bubbletea/lipgloss/huh) TUI. |
| 10 | +Installs Homebrew packages, casks, npm globals, shell config, macOS preferences, dotfiles. |
| 11 | + |
| 12 | +## STRUCTURE |
| 13 | + |
| 14 | +``` |
| 15 | +openboot/ |
| 16 | +├── cmd/openboot/ # main.go → cli.Execute() |
| 17 | +├── internal/ |
| 18 | +│ ├── auth/ # OAuth-like login, token in ~/.openboot/auth.json (0600) |
| 19 | +│ ├── brew/ # Homebrew ops, parallel install (4 workers), retry logic |
| 20 | +│ ├── cli/ # Cobra commands: root, snapshot, doctor, update, version |
| 21 | +│ ├── config/ # Embedded YAML (packages + presets), remote config fetch |
| 22 | +│ │ └── data/ # packages.yaml (9 categories), presets.yaml (3 presets) |
| 23 | +│ ├── dotfiles/ # Clone + stow/symlink with .openboot.bak backup |
| 24 | +│ ├── installer/ # Main orchestrator: 7-step wizard (693 lines) |
| 25 | +│ ├── macos/ # `defaults write` preferences, app restart |
| 26 | +│ ├── npm/ # Batch install with sequential fallback |
| 27 | +│ ├── search/ # Online search via openboot.dev API (8s timeout) |
| 28 | +│ ├── shell/ # Oh-My-Zsh install, .zshrc config |
| 29 | +│ ├── snapshot/ # Capture/match/restore environment state (see subdir AGENTS.md) |
| 30 | +│ ├── system/ # RunCommand/RunCommandSilent, arch detection, git config |
| 31 | +│ ├── ui/ # TUI components (see subdir AGENTS.md) |
| 32 | +│ └── updater/ # Auto-update: check GitHub → download → replace binary |
| 33 | +├── test/ |
| 34 | +│ ├── integration/ # Build tag: //go:build integration |
| 35 | +│ └── e2e/ # Build tag: //go:build e2e |
| 36 | +├── testutil/ # Shared test helpers |
| 37 | +├── scripts/install.sh # curl|bash installer (detects arch, verifies checksums) |
| 38 | +└── Makefile # Build targets |
| 39 | +``` |
| 40 | + |
| 41 | +## WHERE TO LOOK |
| 42 | + |
| 43 | +| Task | Location | Notes | |
| 44 | +|------|----------|-------| |
| 45 | +| Add CLI command | `internal/cli/` | Register in root.go init(), follow cobra pattern | |
| 46 | +| Add package category | `internal/config/data/packages.yaml` | Rebuild after changing embedded YAML | |
| 47 | +| Change install flow | `internal/installer/installer.go` | 7 steps: homebrew → git → preset → packages → shell → macos → dotfiles | |
| 48 | +| Add TUI component | `internal/ui/` | Use bubbletea Model pattern, lipgloss styling | |
| 49 | +| Change brew behavior | `internal/brew/brew.go` | Parallel workers, StickyProgress for output | |
| 50 | +| Add snapshot data | `internal/snapshot/capture.go` | Add to CaptureWithProgress steps | |
| 51 | +| Update self-update | `internal/updater/updater.go` | AutoUpgrade() called from root.go RunE | |
| 52 | +| Modify presets | `internal/config/data/presets.yaml` | 3 presets: minimal, developer, full | |
| 53 | + |
| 54 | +## DEPENDENCY GRAPH |
| 55 | + |
| 56 | +``` |
| 57 | +cli (root) |
| 58 | +├── installer (orchestrator) |
| 59 | +│ ├── brew → ui |
| 60 | +│ ├── npm → ui |
| 61 | +│ ├── config (no deps) |
| 62 | +│ ├── dotfiles (no deps) |
| 63 | +│ ├── macos (no deps) |
| 64 | +│ ├── shell (no deps) |
| 65 | +│ ├── system (no deps) |
| 66 | +│ └── ui → config, search, snapshot, system |
| 67 | +├── updater → ui |
| 68 | +├── auth → ui |
| 69 | +└── snapshot → config, macos |
| 70 | +``` |
| 71 | + |
| 72 | +## CONVENTIONS |
| 73 | + |
| 74 | +- **Error wrapping**: `fmt.Errorf("context: %w", err)` — always wrap with context |
| 75 | +- **UI output**: Use `ui.Header/Success/Error/Info/Warn/Muted` — never raw fmt for user-facing text |
| 76 | +- **Command exec**: `system.RunCommand()` (interactive) or `system.RunCommandSilent()` (capture output) |
| 77 | +- **Embedded data**: `//go:embed data/*.yaml` with `embed.FS`, loaded in `init()` |
| 78 | +- **Testing**: Table-driven with testify/assert. Build tags for integration/e2e |
| 79 | +- **Concurrency**: `sync.WaitGroup` with bounded workers (max 4 for brew) |
| 80 | +- **Dry-run**: All destructive operations check `cfg.DryRun` first |
| 81 | +- **Version string**: Hardcoded in `internal/cli/root.go` — bump manually before release |
| 82 | +- **Config storage**: `~/.openboot/` directory for auth, state, snapshots |
| 83 | + |
| 84 | +## ANTI-PATTERNS |
| 85 | + |
| 86 | +- No `as any` equivalent — no type assertion abuse |
| 87 | +- No ignored errors (`_ = err`) in production code |
| 88 | +- No `panic()` except `log.Fatalf` in `init()` for fatal config errors |
| 89 | +- No hardcoded `~` paths — always `os.UserHomeDir()` |
| 90 | +- No unbounded goroutines — always WaitGroup + max workers |
| 91 | +- No direct stdout for styled text — always through `ui` package |
| 92 | + |
| 93 | +## COMMANDS |
| 94 | + |
| 95 | +```bash |
| 96 | +make build # go build -o openboot ./cmd/openboot |
| 97 | +make build-release # Optimized: -ldflags="-s -w" -trimpath + UPX |
| 98 | +make test-unit # go test -v ./... |
| 99 | +make test-integration # go test -v -tags=integration ./... |
| 100 | +make test-e2e # go test -v -tags=e2e -short ./... |
| 101 | +make test-all # All above + coverage |
| 102 | +make clean # Remove binaries + coverage |
| 103 | +go vet ./... # Lint check |
| 104 | +``` |
| 105 | + |
| 106 | +## RELEASE PROCESS |
| 107 | + |
| 108 | +1. Bump version in `internal/cli/root.go` |
| 109 | +2. `git commit && git push` |
| 110 | +3. Build: `GOOS=darwin GOARCH=arm64 go build -ldflags="-s -w" -o openboot-darwin-arm64 ./cmd/openboot` |
| 111 | +4. `gh release create vX.Y.Z openboot-darwin-arm64 openboot-darwin-amd64 checksums.txt` |
| 112 | + |
| 113 | +CI auto-releases on `v*` tags via `.github/workflows/release.yml`. |
| 114 | + |
| 115 | +## NOTES |
| 116 | + |
| 117 | +- **macOS only**: No Linux/Windows support. darwin binaries only. |
| 118 | +- **Auto-update**: Enabled by default. Config: `~/.openboot/config.json` `{"autoupdate": "true"|"notify"|"false"}`. Env: `OPENBOOT_DISABLE_AUTOUPDATE=1`. |
| 119 | +- **Color palette**: Primary #22c55e (green), Secondary #60a5fa (blue), Warning #eab308, Danger #ef4444, Subtle #666666. |
| 120 | +- **Snapshot upload**: Requires auth token from openboot.dev OAuth flow. |
| 121 | +- **install.sh**: Supports `OPENBOOT_DRY_RUN=true` and `OPENBOOT_INSTALL_DIR=path`. |
0 commit comments