Last verified: 2026-02-10
Essential guidance for AI coding agents working in the Render CLI.
What: Terminal interface for Render platform (Go + Bubble Tea TUI) Why: Manage deployments, services, logs, and infrastructure from the command line
- Search existing code for similar implementations
- Follow established patterns in
pkg/tui/ - Check if types exist in
pkg/client/before defining new ones
Never do (without explicit approval):
- Edit files in
pkg/client/(generated code) - Modify
*_gen.gofiles - Remove existing tests
- Change navigation stack architecture in
pkg/tui/stack.go
Always ask first:
- Major TUI architectural changes
- Adding new dependencies
- Changes to command flag APIs (breaking changes)
Safe to do:
- Add new views in
pkg/tui/views/ - Add new commands in
cmd/ - Write tests anywhere
- Refactor within a single package
- Requirements unclear: Ask before implementing
- Architecture questions: Propose minimal approach, get feedback
- TUI interactions: Describe intended flow, get confirmation
Prefer small, incremental changes over large speculative implementations.
# Building
go build -o render . # Build binary
# Testing
go test ./... # All tests
go test -run TestName ./pkg/... # Single test
# Linting & Formatting
golangci-lint run # Lint
prek run --all-files # All hooks (see prek.toml)
# Type Generation (from public-api-schema)
export RENDER_API_PATH=/path/to/api
cd ../public-api-schema && ./generate-cli.shcmd/- Cobra command definitionspkg/client/- Generated API client (READ-ONLY)pkg/tui/- Bubble Tea TUI framework (see AGENTS.md)pkg/config/- User config file (~/.render/cli.yaml)pkg/cfg/- Environment defaults (different from config!)pkg/command/- Output formats, context utilitiespkg/dependencies/- Dependency injection containerpkg/style/- Lipgloss styling system
TUI: Elm Architecture (Message → Update → View). See pkg/tui/AGENTS.md.
Data Access: Service → Repo → Client (three-layer architecture):
- Client (
pkg/client/): Generated HTTP client - never edit - Repo (
pkg/*/repo.go): Wraps client, handles pagination & error parsing - Service (
pkg/*/service.go): Business logic, orchestrates multiple repos, enriches data
// Service combines data from multiple repos
svc, _ := s.repo.ListServices(ctx, params) // calls client internally
proj, _ := s.projectRepo.ListProjects(ctx) // different repo
return s.enrich(svc, proj) // business logicOutput formats: Use command.IsInteractive(ctx) for branching:
if command.IsInteractive(ctx) {
return runTUI(deps)
}
return runNonInteractive(ctx, deps) // JSON, YAML, TEXTNaming:
| Element | Pattern | Example |
|---|---|---|
| Commands | New{Action}Cmd() |
NewServiceListCmd() |
| Models | {Entity}Model |
ServiceListModel |
| Messages | {Action}Msg |
LoadServicesMsg |
# Start API
tilt up api
curl -k https://api.localhost.render.com:8443/health
# Configure CLI
export RENDER_HOST="https://api.localhost.render.com:8443/v1/"
export RENDER_API_KEY="your-api-key"
./render services list| Variable | Description |
|---|---|
RENDER_HOST |
API base URL |
RENDER_API_KEY |
API key (skips OAuth) |
RENDER_WORKSPACE |
Workspace ID override |
RENDER_CLI_CONFIG_PATH |
Config file path override |
- Table-driven tests with
stretchr/testify - Manual fakes in
pkg/tui/testhelper/ - Hooks (
prek.toml): golangci-lint, shellcheck, shfmt, yaml checks, large file detection
- Don't block in
Update()- usetea.Cmdfor async work - Handle
tea.KeyCtrlCandtea.KeyCtrlDfor proper exit - Run
resetif terminal breaks after a crash Push()returns atea.Cmdthat must be returned fromUpdate()- Generated types are read-only - regenerate via
generate-cli.sh
pkg/tui/: See AGENTS.md for Bubble Tea patterns and examples
All naming conventions, field formatting rules, and flag standards are defined in STYLE.md. See the Agent quick reference for the condensed spec used when creating or reviewing commands.