---
description: Reference blueprint for building Go CLI tools. Human-guided step-by-step recipe covering Cobra scaffold, pkg/api+auth+output, agent-forward design, testing, embedded docs, and Homebrew release.
category: general
---
flowchart TD
_HEADER_["
Creating Go CLI Tools
Reference blueprint for building Go CLI tools. Human-guided step-by-step recipe covering Cobra scaffold, pkg/api+auth+output, agent-forward design, testing, embedded docs, and Homebrew release.
"]:::headerStyle
classDef headerStyle fill:none,stroke:none
subgraph _MAIN_[" "]
%% Phase 1: Project Initialization
subgraph Init["Phase 1: Project Initialization"]
GO_MOD[go mod init] --> STRUCTURE[Create Directory
Structure]
STRUCTURE --> MAIN[main.go
Entry Point]
MAIN --> MAKEFILE[Makefile
Standard Targets]
MAKEFILE --> GITIGNORE[.gitignore +
LICENSE + README]
end
%% Phase 2: Core Packages
subgraph Core["Phase 2: Core Packages (pkg/)"]
GITIGNORE --> AUTH[pkg/auth
Auth Chain]
GITIGNORE --> API[pkg/api
HTTP Client]
GITIGNORE --> OUTPUT[pkg/output
Rendering]
AUTH --> AUTH_TEST[auth_test.go]
API --> API_TEST[client_test.go]
OUTPUT --> OUTPUT_TEST[output_test.go]
end
%% Phase 3: Commands
subgraph Commands["Phase 3: Commands (cmd/)"]
AUTH_TEST & API_TEST & OUTPUT_TEST --> ROOT_CMD[cmd/root.go
Global Flags]
ROOT_CMD --> RESOURCE_CMDS[cmd/resource.go
One File Per Resource]
ROOT_CMD --> DOCS_CMD[cmd/docs.go
Embedded README]
ROOT_CMD --> SKILL_CMD[cmd/skill.go
print + add]
ROOT_CMD --> COMPLETION[cmd/completion.go
bash/zsh/fish]
end
%% Phase 4: Agent-Forward Patterns
subgraph AgentFwd["Phase 4: Agent-Forward Design"]
RESOURCE_CMDS --> JSON_OUT[JSON-First Output
--json on all cmds]
JSON_OUT --> FIELDS[--fields + --jq
Token Reduction]
JSON_OUT --> STRUCTURED_ERR[Structured Errors
on stderr]
JSON_OUT --> DETERMINISTIC[Deterministic Output
Sorted, ISO 8601]
FIELDS & STRUCTURED_ERR & DETERMINISTIC --> NON_INTERACTIVE[Non-Interactive Mode
No Prompts]
NON_INTERACTIVE --> IDEMPOTENT[Idempotent Ops
Safe Retries]
end
%% Phase 5: Testing
subgraph Testing["Phase 5: Testing (3 Tiers)"]
IDEMPOTENT --> SMOKE[Smoke Tests
make test]
IDEMPOTENT --> UNIT[Unit Tests
make test-unit]
IDEMPOTENT --> INTEGRATION[Integration Tests
make test-integration]
SMOKE --> SMOKE_CHECK{Builds +
--help?}
UNIT --> COVERAGE_CHECK{90%+ on
pkg/?}
INTEGRATION --> CRUDL[CRUDL Lifecycle
Create-Get-Update-
Get-List-Delete]
CRUDL --> CROSS_PRODUCT[Cross-Product
Matrix Coverage]
CROSS_PRODUCT --> AST_VERIFY[ast-grep
Coverage Verify]
end
%% Phase 6: Embedded Docs
subgraph EmbedDocs["Phase 6: Embedded Documentation"]
DOCS_CMD & SKILL_CMD --> EMBED_README[go:embed
README.md]
EMBED_README --> EMBED_SKILL[go:embed
skill/SKILL.md]
EMBED_SKILL --> EMBED_REF[go:embed
skill/reference/]
EMBED_REF --> LLMS_TXT[llms.txt
Agent Discovery]
LLMS_TXT --> GENDOCS[cmd/gendocs
Man Pages]
end
%% Phase 7: Release Automation
subgraph Release["Phase 7: Release Automation"]
AST_VERIFY & SMOKE_CHECK & COVERAGE_CHECK & GENDOCS --> GORELEASER[.goreleaser.yml
Build Config]
GORELEASER --> GH_WORKFLOW[GitHub Actions
release.yml]
GH_WORKFLOW --> HOMEBREW[Homebrew Formula
Auto-Updated]
GORELEASER --> GITEA_WORKFLOW[Gitea Workflow
bump-tap.yml]
GITEA_WORKFLOW --> HOMEBREW_PRIVATE[Private Tap
Auto-Updated]
end
%% Phase 8: Post-Creation Checklist
subgraph PostCreate["Phase 8: Post-Creation Checklist"]
HOMEBREW & HOMEBREW_PRIVATE --> ADD_SECRET[Add TAP_TOKEN
Secret to Repo]
ADD_SECRET --> VERIFY_JSON[Verify --json
All Commands]
VERIFY_JSON --> UPDATE_CLAUDE[Update CLAUDE.md
Skill Reference]
UPDATE_CLAUDE --> ALLOW_CMD[Add to
settings.json]
ALLOW_CMD --> MAKE_CHECK[make check
fmt+lint+test]
MAKE_CHECK --> TAG_RELEASE[git tag v0.1.0
Push to Remote]
TAG_RELEASE --> DONE([Done])
end
click GO_MOD "#" "**go mod init**\nInitialize the Go module:\n`go mod init github.com/roboalchemist/
`\n\nThis sets the import path for all packages in the project."
click STRUCTURE "#" "**Create Directory Structure**\nStandard layout for all roboalchemist Go CLIs:\n- `cmd/` -- Cobra commands (one file per resource)\n- `pkg/api/` -- HTTP client and types\n- `pkg/auth/` -- Auth chain (env var then config file)\n- `pkg/output/` -- Table, JSON, plaintext rendering\n- `skill/` -- Claude Code skill files\n- `cmd/gendocs/` -- Man page generator"
click MAIN "#" "**main.go Entry Point**\nMinimal main.go with `//go:embed` directives:\n- Embeds README.md, skill/SKILL.md, skill/reference/\n- Injects version via ldflags\n- Calls `cmd.SetVersion()`, `cmd.SetReadmeContents()`,\n `cmd.SetSkillData()`, then `cmd.Execute()`"
click MAKEFILE "#" "**Makefile Standard Targets**\nALL targets are required:\n- `build` -- binary with version ldflags\n- `test` -- smoke tests (no API key)\n- `test-unit` -- 90%+ coverage on pkg/\n- `test-integration` -- subprocess tests vs live API\n- `install` -- sudo install to /usr/local/bin/\n- `deps` -- go mod download + tidy\n- `fmt` / `lint` / `man` / `check` / `help`"
click GITIGNORE "#" "**.gitignore + LICENSE + README**\nProject scaffolding files:\n- `.gitignore` for Go binaries, coverage, dist/\n- `LICENSE` (MIT)\n- `README.md` with install, auth, usage sections"
click AUTH "#" "**pkg/auth -- Auth Chain**\nAuth priority:\n1. `_API_KEY` env var\n2. Legacy env var aliases\n3. Config file: `~/.-auth.json` (mode 0600)\n\nFunctions: `GetAPIKey()`, `SaveAuth()`, `ClearAuth()`"
click API "#" "**pkg/api -- HTTP Client**\nCore HTTP client with:\n- `_API_URL` override for testing\n- Request building with auth headers\n- Error handling and response unwrapping\n- Pagination support\n- Rate limit handling\n\nAll methods return typed structs from `types.go`."
click OUTPUT "#" "**pkg/output -- Rendering**\nThree output modes:\n- Table (default, colored, `tablewriter`)\n- JSON (`--json`, with `--fields` and `--jq`)\n- Plaintext (`--plaintext`, tab-separated)\n\nAlso: `errors.go`, `fields.go`, `jq.go`, `prune.go`\nRespects `NO_COLOR` and TTY detection."
click AUTH_TEST "#" "**auth_test.go**\nUnit tests for the auth package:\n- Save/load/clear auth cycle\n- Env var overrides config file\n- Config file permissions (0600)\n- Missing config returns empty\n\nUse temp dirs for isolation."
click API_TEST "#" "**client_test.go**\nUnit tests using `httptest.NewServer`:\n- Request building and auth headers\n- Error response handling\n- Pagination parsing\n- Rate limit detection\n- Base URL override via env var\n\nTarget 90%+ coverage."
click OUTPUT_TEST "#" "**output_test.go**\nUnit tests for rendering:\n- JSON output is valid JSON\n- Table output has borders\n- Plaintext is tab-separated\n- Field filtering works\n- JQ expressions apply correctly\n- Color detection logic"
click ROOT_CMD "#" "**cmd/root.go -- Global Flags**\nRoot command with persistent flags:\n- `--json` / `-j` -- JSON output\n- `--plaintext` / `-p` -- tab-separated\n- `--no-color` -- disable ANSI\n- `--debug` -- verbose stderr\n- `--fields` -- JSON field selection\n- `--jq` -- built-in JQ filtering\n\n`GetOutputOptions()` maps flags to output.Options."
click RESOURCE_CMDS "#" "**cmd/resource.go -- One Per Resource**\nEach API resource gets its own file:\n- Define `var xxxCmd = cobra.Command{}`\n- Register flags in `init()`\n- `rootCmd.AddCommand(xxxCmd)` in init\n- `runXxx()` calls API client then output.Render\n\nKeep commands thin -- logic in pkg/."
click DOCS_CMD "#" "**cmd/docs.go -- Embedded README**\nPrints the full README.md to stdout:\n`tool docs` -- full docs\n`tool docs | less` -- human viewing\n`tool docs > /tmp/ref.md` -- agent saves"
click SKILL_CMD "#" "**cmd/skill.go -- print + add**\nClaude Code skill integration:\n- `tool skill print` -- print SKILL.md to stdout\n- `tool skill add` -- install to ~/.claude/skills/\n\nCopies SKILL.md and reference/ files."
click COMPLETION "#" "**cmd/completion.go**\nShell completion for bash, zsh, fish, powershell.\nCobra generates these automatically.\n`tool completion bash > ~/.bash_completion.d/tool`"
click JSON_OUT "#" "**JSON-First Output**\nThe most important agent-forward pattern.\nEvery data-returning command MUST support `--json`.\n\nstdout = data only (JSON, table, plaintext)\nstderr = logs, progress, debug, errors\n\nAgents parse stdout and discard stderr:\n`result=$(tool fetch --json 2>/dev/null)`"
click FIELDS "#" "**--fields + --jq**\nReduce token usage for agents:\n- `--fields id,name,status` -- only requested fields\n- `--jq '.[] | select(.active)'` -- filter expressions\n\nImplemented in `pkg/output/fields.go` and `pkg/output/jq.go`."
click STRUCTURED_ERR "#" "**Structured Errors on stderr**\nJSON mode errors are structured:\n`{'code':'NOT_FOUND','message':'...','recoverable':false}`\n\nExit codes:\n- 0 = success\n- 1 = user/correctable error\n- 2 = usage error\n- 3+ = system/runtime errors"
click DETERMINISTIC "#" "**Deterministic Output**\nAgents compare outputs across runs:\n- Always sort collections by stable key (ID)\n- ISO 8601 timestamps (never relative)\n- Stable JSON key ordering\n- Pretty-print with indentation"
click NON_INTERACTIVE "#" "**Non-Interactive Mode**\nAgents cannot interact with prompts.\n- All input via `--flags` or env vars\n- Detect piped usage with `os.Stdin.Stat()`\n- `--dry-run` for validation without execution\n- `--force` for skip-confirmation destructive ops"
click IDEMPOTENT "#" "**Idempotent Operations**\nAgents retry failed operations. Design for safe re-execution:\n- Create-or-update (upsert) pattern\n- `--force` to overwrite existing\n- Batch operations with `--ids`\n- Selector-based bulk ops"
click SMOKE "#" "**Smoke Tests -- make test**\nNo API key needed. Validates:\n- Binary builds successfully\n- `--help` exits 0\n- `--version` exits 0\n- `docs` prints output\n- `skill print` works\n- `completion bash/zsh` works"
click UNIT "#" "**Unit Tests -- make test-unit**\nRun with:\n`go test -v -race -coverprofile=coverage.out ./...`\n\nTarget 90%+ coverage on:\n- `pkg/api/` -- httptest mocks\n- `pkg/auth/` -- temp dirs, env overrides\n- `pkg/output/` -- capture stdout"
click INTEGRATION "#" "**Integration Tests -- make test-integration**\nRun against live API as subprocess:\n- Build binary once in TestMain\n- Invoke as subprocess per test\n- Skip when API credentials missing\n- `READONLY=1` skips write tests\n- `_API_URL` override for base URL"
click SMOKE_CHECK "#" "**Builds + --help?**\nSmoke test gate:\n- Does the binary compile?\n- Does --help exit 0?\n- Does --version show the version?\n\nIf any fail, stop and fix before proceeding."
click COVERAGE_CHECK "#" "**90%+ on pkg/?**\nUnit test coverage gate:\n- `pkg/api/` >= 90%\n- `pkg/auth/` >= 90%\n- `pkg/output/` >= 90%\n\nCheck with:\n`go tool cover -func=coverage.out`"
click CRUDL "#" "**CRUDL Lifecycle**\nIdempotent test pattern for every CRUD resource:\n1. Create -- make the resource\n2. Get -- verify it exists\n3. Update -- modify a field\n4. Get -- verify the update\n5. List -- verify it appears\n6. Delete -- remove it\n7. List -- verify it is gone\n8. Get -- verify not-found error\n\nLeaves system in original state."
click CROSS_PRODUCT "#" "**Cross-Product Matrix**\nEvery data-returning command x every output flag:\n- `--json` -- valid JSON, expected keys\n- `--plaintext` -- tabs, no ANSI\n- `--no-color` -- no escape sequences\n- `--fields` -- only specified fields\n- `--jq` -- expression applies correctly\n- `--debug` -- stderr contains debug output\n\nEvery cell in the matrix needs a test."
click AST_VERIFY "#" "**ast-grep Coverage Verify**\nExtract all Cobra commands and flags with ast-grep,\nthen cross-reference against integration_test.go.\n\nAny command or flag not covered = test gap.\nThis is the final verification that nothing was missed."
click EMBED_README "#" "**go:embed README.md**\nEmbed the full README into the binary:\n`//go:embed README.md`\n`var readmeContents string`\n\nPassed to cmd package via `SetReadmeContents()`.\nPrinted by `tool docs` command."
click EMBED_SKILL "#" "**go:embed skill/SKILL.md**\nEmbed the Claude Code skill:\n`//go:embed skill/SKILL.md`\n`var skillMD string`\n\nPrinted by `tool skill print`.\nCopied by `tool skill add`."
click EMBED_REF "#" "**go:embed skill/reference/**\nEmbed the entire skill directory:\n`//go:embed skill`\n`var skillFS embed.FS`\n\nIncludes reference/commands.md and other files.\nAll copied to ~/.claude/skills/ on `skill add`."
click LLMS_TXT "#" "**llms.txt -- Agent Discovery**\nAgent-readable doc index at project root:\n- Brief description\n- Quick start (install, auth, usage)\n- Command list with doc links\n- Output format summary\n- Auth instructions\n\nOptionally embedded and served via hidden command."
click GENDOCS "#" "**cmd/gendocs -- Man Pages**\nGenerate man pages and markdown docs:\n- Uses `cobra/doc` library\n- `make man` generates man/man1/*.1\n- `make docs-gen` generates markdown CLI reference\n- Every command needs a `.Example` field\n- Root `Long` includes ENVIRONMENT, FILES, EXIT STATUS"
click GORELEASER "#" "**.goreleaser.yml**\nBuild configuration for GoReleaser:\n- Multi-platform builds (darwin/linux, amd64/arm64)\n- Version ldflags injection\n- Homebrew tap auto-update\n- Changelog generation\n\nDefault for all new Go CLI tools."
click GH_WORKFLOW "#" "**GitHub Actions release.yml**\nTriggered on tag push (`v*`):\n1. Checkout code\n2. Setup Go\n3. Run GoReleaser\n4. Builds binaries + creates GitHub Release\n5. Auto-updates homebrew-tap formula\n\nRequires `HOMEBREW_TAP_TOKEN` secret."
click HOMEBREW "#" "**Homebrew Formula (Public)**\nPublic tap: `roboalchemist/tap` on GitHub.\n`brew install roboalchemist/tap/`\n\nGoReleaser auto-updates the formula on each release.\nFormula includes: desc, url, sha256, depends_on go, test block."
click GITEA_WORKFLOW "#" "**Gitea Workflow bump-tap.yml**\nFor private tools hosted on Gitea:\n- Triggered on release\n- Computes SHA of tarball\n- Pushes updated formula to homebrew-private\n\nRequires `TAP_TOKEN` secret."
click HOMEBREW_PRIVATE "#" "**Private Tap (Gitea)**\nPrivate tap: `roboalchemist/private` on Gitea.\n`brew tap roboalchemist/private ssh://git@gitea.roboalch.com:2222/...`\n`brew install roboalchemist/private/`"
click ADD_SECRET "#" "**Add TAP_TOKEN Secret**\nAdd the appropriate secret to the repo:\n- GitHub: `HOMEBREW_TAP_TOKEN` (PAT with repo scope)\n- Gitea: `TAP_TOKEN` (API token)\n\nRequired for automated formula updates."
click VERIFY_JSON "#" "**Verify --json All Commands**\nManual verification that every resource command\nproduces valid JSON with `--json`.\n\nCheck stdout/stderr separation,\nfield selection, and error formatting."
click UPDATE_CLAUDE "#" "**Update CLAUDE.md Skill Reference**\nAdd the new tool to the skill reference tables\nin CLAUDE.md and any relevant rules files.\n\nEnsures the tool is discoverable by future sessions."
click ALLOW_CMD "#" "**Add to settings.json**\nAdd the tool binary name to\n`~/.claude/settings.json` allowed commands\nso Claude Code can invoke it directly."
click MAKE_CHECK "#" "**make check**\nFinal validation: runs `fmt` + `lint` + `test` + `test-unit`.\nAll must pass before tagging a release.\n\nThis is the definition of done gate."
click TAG_RELEASE "#" "**git tag v0.1.0**\nTag and push the first release:\n`git tag v0.1.0`\n`git push origin v0.1.0`\n\nTriggers GoReleaser or bump-tap workflow.\nAutomatically builds, releases, and updates homebrew."
click DONE "#" "**Done**\nThe CLI tool is complete when:\n- All 3 test tiers pass\n- Homebrew formula is published\n- Skill is installed in Claude Code\n- `--json` works on every command\n- Man pages are generated\n- llms.txt exists at project root"
classDef init fill:#d1ecf1,stroke:#7ec8d8
classDef core fill:#e8daef,stroke:#b07cc6
classDef commands fill:#dfe6ff,stroke:#5b7bce
classDef agent fill:#ffeaa7,stroke:#e0c040
classDef testing fill:#fff3cd,stroke:#f0c040
classDef docs fill:#d1ecf1,stroke:#7ec8d8
classDef release fill:#d4edda,stroke:#5cb85c
classDef postcheck fill:#f0e6d3,stroke:#d4a76a
classDef approved fill:#d4edda,stroke:#5cb85c
class GO_MOD,STRUCTURE,MAIN,MAKEFILE,GITIGNORE init
class AUTH,API,OUTPUT,AUTH_TEST,API_TEST,OUTPUT_TEST core
class ROOT_CMD,RESOURCE_CMDS,DOCS_CMD,SKILL_CMD,COMPLETION commands
class JSON_OUT,FIELDS,STRUCTURED_ERR,DETERMINISTIC,NON_INTERACTIVE,IDEMPOTENT agent
class SMOKE,UNIT,INTEGRATION,SMOKE_CHECK,COVERAGE_CHECK,CRUDL,CROSS_PRODUCT,AST_VERIFY testing
class EMBED_README,EMBED_SKILL,EMBED_REF,LLMS_TXT,GENDOCS docs
class GORELEASER,GH_WORKFLOW,HOMEBREW,GITEA_WORKFLOW,HOMEBREW_PRIVATE release
class ADD_SECRET,VERIFY_JSON,UPDATE_CLAUDE,ALLOW_CMD,MAKE_CHECK,TAG_RELEASE postcheck
class DONE approved
end
style _MAIN_ fill:none,stroke:none,padding:0
_HEADER_ ~~~ _MAIN_