|
| 1 | +# CLI Architecture — Vertical Slice |
| 2 | + |
| 3 | +## Guiding principle |
| 4 | + |
| 5 | +Each user-facing feature is a **vertical slice**: a self-contained package that |
| 6 | +owns its own command wiring, business logic, API calls, and output formatting. |
| 7 | +Slices are allowed to share infrastructure (the kernel) but are **forbidden from |
| 8 | +depending on each other**. |
| 9 | + |
| 10 | +This keeps features independently changeable. Adding `blast-radius` cannot break |
| 11 | +`dead-code`. Refactoring `auth` cannot affect `analyze`. |
| 12 | + |
| 13 | +## Package map |
| 14 | + |
| 15 | +``` |
| 16 | +main.go entry — calls cmd.Execute(), nothing else |
| 17 | +
|
| 18 | +cmd/ wiring layer — cobra commands that delegate to slice handlers |
| 19 | + root.go root command, global flags |
| 20 | + version.go version subcommand (trivial, no handler) |
| 21 | + analyze.go ─────────────────────────────────────────────┐ |
| 22 | + deadcode.go ──────────────────────────────────────────┐ │ |
| 23 | + blastradius.go ────────────────────────────────────┐ │ │ |
| 24 | + graph.go ──────────────────────────────────┐ │ │ │ |
| 25 | + auth.go ──────────────────────────────┐ │ │ │ │ |
| 26 | + │ │ │ │ │ |
| 27 | +internal/ │ │ │ │ │ |
| 28 | + ┌──────────────── SHARED KERNEL ───────┐ │ │ │ │ │ |
| 29 | + │ api/ HTTP client primitives │ │ │ │ │ │ |
| 30 | + │ config/ ~/.supermodel/config.yaml │◄──┘ │ │ │ │ |
| 31 | + │ cache/ local graph cache │◄──────┘ │ │ │ |
| 32 | + │ ui/ output, tables, spinners │◄──────────┘ │ │ |
| 33 | + │ build/ version/commit/date vars │◄──────────────┘ │ |
| 34 | + └──────────────────────────────────────┘ │ |
| 35 | + │ |
| 36 | + ┌──────────────── VERTICAL SLICES ─────────────────────┐ │ |
| 37 | + │ analyze/ upload & full analysis pipeline │◄─┘ |
| 38 | + │ deadcode/ dead code detection │ |
| 39 | + │ blastradius/ downstream impact analysis │ |
| 40 | + │ graph/ graph display and export │ |
| 41 | + │ auth/ login / logout / token storage │ |
| 42 | + └──────────────────────────────────────────────────────┘ |
| 43 | +``` |
| 44 | + |
| 45 | +## Rules |
| 46 | + |
| 47 | +| From → To | Allowed? | |
| 48 | +|-------------------|----------| |
| 49 | +| `main.go` → `cmd/` | ✅ | |
| 50 | +| `cmd/` → any `internal/` | ✅ (wiring) | |
| 51 | +| `internal/<slice>` → `internal/kernel` | ✅ | |
| 52 | +| `internal/<slice>` → `internal/<slice>`| ❌ **FORBIDDEN** | |
| 53 | +| `internal/kernel` → `internal/<slice>` | ❌ **FORBIDDEN** | |
| 54 | + |
| 55 | +**Shared kernel packages** (`internal/api`, `internal/build`, `internal/cache`, |
| 56 | +`internal/config`, `internal/ui`) must contain zero business logic. They are |
| 57 | +pure infrastructure — HTTP primitives, config loading, formatting utilities. |
| 58 | + |
| 59 | +Any package under `internal/` that is NOT in the kernel list is treated as a |
| 60 | +slice and subject to the cross-slice import ban. |
| 61 | + |
| 62 | +## Adding a new feature |
| 63 | + |
| 64 | +1. Create `internal/<feature>/` with `command.go`, `handler.go`, `types.go`. |
| 65 | +2. Register the cobra command in `cmd/<feature>.go` by calling into the slice. |
| 66 | +3. Do not import any other slice from the new package. |
| 67 | +4. The architecture check in CI will reject the PR if the rule is violated. |
| 68 | + |
| 69 | +## Adding a new kernel package |
| 70 | + |
| 71 | +1. Add the package under `internal/<name>/`. |
| 72 | +2. Add `"internal/<name>": true` to `sharedKernel` in |
| 73 | + `scripts/check-architecture/main.go`. |
| 74 | +3. Keep it free of business logic. |
| 75 | + |
| 76 | +## Enforcement |
| 77 | + |
| 78 | +The `.github/workflows/architecture.yml` workflow runs on every PR that touches |
| 79 | +`internal/`, `cmd/`, or `main.go`. It zips the repository, sends it to the |
| 80 | +[Supermodel API](https://api.supermodeltools.com), parses the dependency graph, |
| 81 | +and fails the build if any cross-slice `IMPORTS` relationship is found. |
| 82 | + |
| 83 | +Run locally: |
| 84 | + |
| 85 | +```sh |
| 86 | +SUPERMODEL_API_KEY=<key> go run ./scripts/check-architecture |
| 87 | +``` |
0 commit comments