Development
Branching
Section titled “Branching”- All work happens on
main. No long-lived feature branches. - Releases are tagged (e.g.
v0.3.0). CI updatesstableto match automatically after the tag is pushed. README.mdonstableis the source of truth for released functionality.README.mdonmainmay describe unreleased work.
Getting started
Section titled “Getting started”git clone https://github.com/fgrehm/crib.gitcd cribmake setup-hooks # configure pre-commit hooks (gofmt + golangci-lint)make build # produces bin/cribmake test # run unit testsBuilding and testing
Section titled “Building and testing”Requires Go 1.26+.
make build # produces bin/cribmake install # build + install to ~/.local/binmake test # unit tests (go test ./internal/... -short)make lint # golangci-lint v2 (errcheck, govet, staticcheck, unused, ineffassign)make test-integration # integration tests (requires Docker or Podman)make test-e2e # end-to-end tests against the crib binarymake audit # cyclomatic complexity + dead code analysis (informational)make docs # serve docs site at http://localhost:4321/cribRun a single test:
go test ./internal/config/ -short -run TestParseFullCode style
Section titled “Code style”- Go module:
github.com/fgrehm/crib - All packages under
internal/(this is a binary, not a library) - CLI: spf13/cobra. Logging:
log/slog. - Linting: golangci-lint v2 with errcheck, govet, staticcheck, unused, ineffassign
- Pre-commit hooks run
gofmtandgolangci-linton staged.gofiles
Commit format
Section titled “Commit format”Conventional commits, present tense, under 72 characters.
feat(auth): add OAuth login supportfix: resolve memory leak in background tasksdocs: add troubleshooting entry for pasta networkingUse scopes when they clarify the component. Skip them for broad changes.
Pull requests
Section titled “Pull requests”- All work happens on
main. No long-lived feature branches. - Open PRs against
main. - Keep PRs focused. One feature or fix per PR.
- Run
make test && make lintbefore pushing. - Update
CHANGELOG.mdunder[Unreleased]for user-facing changes. Internal refactors that preserve behavior need no entry.
Architecture
Section titled “Architecture”cmd/ -> CLI (cobra). Thin layer, delegates to engine/.internal/ config/ -> devcontainer.json parsing, variable substitution, merging feature/ -> DevContainer Features (OCI resolution, ordering, Dockerfile generation) engine/ -> Core orchestration (up/down/remove flows, lifecycle hooks) driver/ -> Container runtime abstraction (Docker/Podman via single OCI driver) compose/ -> Docker Compose / Podman Compose helper plugin/ -> Plugin system (codingagents, packagecache, shellhistory, ssh) workspace/ -> Workspace state management (~/.crib/workspaces/) dockerfile/ -> Dockerfile parsing and rewritingDependency flow: cmd/ -> engine/ -> {config/, feature/, driver/, compose/, dockerfile/, workspace/}. No cycles.
See Implementation Notes for deeper details on quirks, workarounds, and spec compliance.