# Development Guide This guide is the starting point for day-to-day work on `a1s`. It covers the project shape, common commands, source layout, dependencies, and conventions. ## Project Overview `a1s` is a k9s-style terminal UI for browsing AWS resources through the CloudControl API. The user creates credentials and scopes from the command prompt, then browses AWS resources through those scopes: 1. Credentials, including SDK profiles, SSO registrations, SSO roles, and assumed roles. 2. Single-region scopes. 3. Group scopes for multi-scope browsing. 4. An active resource or group target plus resource type. The browser shows a paginated resource table and resource detail rendered as YAML. Row actions carry the row's origin region scope. Module: `github.com/chucklehead-dev/a1s`. ## Commands ```bash go build ./... go vet ./... gofmt -l ./cmd/a1s ./internal go test ./... go test ./cmd/a1s -update go test -tags integration -race ./cmd/a1s go run ./cmd/a1s ``` `gofmt -l ./cmd/a1s ./internal` must print nothing before a change is done. Release builds set `main.version`, `main.commit`, and `main.date` through linker flags. Local builds report `a1s version dev (commit none, built unknown)` through `a1s --version`. Use `A1S_DEBUG=1 go run ./cmd/a1s` to tee `tea.Msg` traffic to `a1s-debug.log`. Debug logging happens in `Update`, so it does not perturb golden renders. The built `a1s` binary and root-level scratch `*.json` files are local artifacts and should not be committed. ## Source Layout The TUI shell lives in `cmd/a1s/`. Reusable layers live under `internal/`. `internal` packages must not depend on Bubble Tea model types. AWS SDK usage is isolated in `internal/awsclient`. Important packages: - `internal/props`: pure JSON/YAML and schema helpers for create/edit/update. - `internal/config`: `Config`/`Creds` split, `CredStore` seam, fetch tuning. - `internal/awsclient`: AWS-backed loaders, mutators, and waiters. - `internal/fetch`: bounded rate-limited detail worker pool behind `DetailGetter`. - `internal/typecache`: global CloudFormation type description cache. - `internal/scopecache`: non-sensitive discovery cache for global resource type names, SSO account/role rows, and credential-enabled regions. - `internal/prefetchstate`: persisted set of resource types that need detail prefetch. - `internal/runtime`: process-level dependency construction. - `internal/tui`: reusable local Bubble Tea components with no root-model, AWS, config-store, or app-command dependencies. See `docs/components/`. All `internal` caches are nil-safe and live under `os.UserCacheDir` (`~/.cache/a1s`) by default. ## cmd/a1s File Map - `main.go`: cobra root, config/creds load, theme/keybinding validation, runtime construction, `tea.NewProgram`. - `reset_config.go`: `--reset-config` early-exit reset path, default file rewrite, and destructive path guards. - `model.go`: root `model`, screen and overlay enums, session structs, constructors, `Init`. - `model_update.go`: top-level `Update`, handler ordering, global keys, overlay/screen routing. - `model_scope.go`: scope transitions, overlays, columns, sizing, persistence, back navigation. - `model_mutation.go`: create/delete/update submit and mutation result handlers. - `model_editor.go`: shared `$EDITOR` workflow plus create/edit policy. - `registry.go`: screen and overlay controller registries. - `messages.go`: typed `tea.Msg` definitions. - `keys.go`: key map, defaults, overrides, rebindable action vocabulary. - `aws.go`: `ssoClient` and `awsSession`. - `loaders_iface.go`: loader interfaces and provider seams. - `commands.go`: `tea.Cmd` factories. - `detail.go`: CloudControl detail getter adapter. - `errors.go`: AWS error formatting and hints. - `shell_view.go`: root `View()`, shell frame composition, prompt/body routing, modal compositing, and active controller dispatch. - `shell_status.go`: breadcrumbs, loading activity text, toast/footer help, and shell text-fitting helpers. - `styles.go`: palette defaults, theme application, list chrome styles, and package style shims. - `editor.go`: editor command, temp files, and error annotation helpers. - `screen_*.go`: one struct per screen or overlay. Large screens may have adjacent ownership files such as resource-list row/loading helpers, credential/scope-table workflow helpers, or command-prompt grammar helpers. See `docs/screens/`. - `*_test.go` and `testdata/*.golden`: pure-state, golden, and integration tests. ## Dependencies Use Charm v2 packages: - `charm.land/bubbletea/v2` - `charm.land/bubbles/v2` - `charm.land/lipgloss/v2` Other important dependencies: - `spf13/cobra` - `aws-sdk-go-v2` services for CloudControl, CloudFormation, SSO, SSO OIDC, and Account. - `gopkg.in/yaml.v3` for config. Do not replace it with viper; viper lowercases map keys. - `santhosh-tekuri/jsonschema/v6` for create/update validation. - `wI2L/jsondiff` for RFC 6902 patches. - `golang.org/x/time` for rate limiting. ## Conventions - Keep edits narrow and compile-clean. - Preserve keybindings, config shape, cache paths, stale-guard semantics, CloudControl behavior, and golden output unless the task intentionally changes them. - Keep destructive config/cache maintenance flags in `cmd/a1s` before normal startup. Resolve paths through the existing config/cache helpers, write config and credentials through `internal/config`, guard broad delete roots, and exit without starting Bubble Tea. - Put reusable TUI primitives in `internal/tui` only when they stay app-effect free. Screens in `cmd/a1s` should translate component state into root-model mutations and `tea.Cmd`s. - Comments should explain why, not what. Multi-sentence mechanism rationale belongs near the implementation it protects. - Lists and tables should use `compactListStyles()` to drop blank chrome lines. - Default tests treat views as a pure function of model state. Tests that need commands to run belong in the opt-in integration tier. ## Related Docs - `docs/ARCHITECTURE.md`: model, runtime, update flow, stale guards, write paths, and invariants. - `docs/components/`: reusable `internal/tui` component contracts. - `docs/screens/`: screen and overlay controller ownership. - `docs/CONFIGURATION.md`: CLI flags, config files, theme, keybindings, and sensitive-data boundaries. - `docs/TESTING.md`: default tests, golden workflow, integration tier, and live smoke testing. - `docs/DOCUMENTATION.md`: documentation authoring rules. ## Release Workflow CI runs formatting, `go vet`, `go test ./...`, Bombadil TypeScript checks, and a GoReleaser snapshot build. Public releases are published through `.github/workflows/release.yml`: 1. Push a SemVer tag such as `v0.1.0`, or run the manual `Release` workflow from `main`. 2. Leave manual `dry_run` enabled to build snapshot archives, attach them to the workflow run as an Actions artifact, and avoid creating a tag or GitHub release. 3. Disable manual `dry_run` to create or reuse the tag at current `main`, then publish GoReleaser archives and checksums. GoReleaser builds Linux amd64/arm64, macOS arm64, and Windows amd64/arm64 archives. It injects the release version, commit, and build date into `a1s --version`.