
Golang Spf13 Cobra
Ship idiomatic Cobra CLIs in Go with correct RunE error propagation, Args validators, and patterns that pass structured eval traps instead of ad-hoc `os.Exit` hacks.
Overview
golang-spf13-cobra is an agent skill for the Build phase that teaches correct spf13/cobra patterns—especially RunE error propagation and Args validators—for Go CLI subcommands.
Install
npx skills add https://github.com/samber/cc-skills-golang --skill golang-spf13-cobraWhat is this skill?
- RunE vs Run: propagate errors through Cobra instead of panicking or os.Exit inside Run
- Use built-in Args validators (e.g. ExactArgs) instead of manual len(args) checks in RunE
- Aligns with eval assertions that trap common model mistakes on Cobra scaffolding
- Covers external API calls from subcommands with non-zero exit on failure
- Discourages os.Exit inside RunE handlers
- Eval fixtures include multi-assertion traps for RunE and Args-validator patterns
Adoption & trust: 1.9k installs on skills.sh; 2k GitHub stars; 3/3 security scanners passed (skills.sh audits).
What problem does it solve?
Your agent keeps generating Cobra commands with Run, manual arg length checks, or os.Exit, so API failures do not surface through standard CLI error handling.
Who is it for?
Indie builders creating Go CLIs that call APIs or manage infrastructure and want agent output to match senior Go/Cobra conventions.
Skip if: Python Click projects, pure HTTP services with no CLI surface, or teams already enforcing Cobra solely via a private linter without agent codegen.
When should I use this skill?
Writing or reviewing Go code that uses spf13/cobra for subcommands, flags, or API-backed CLI handlers.
What do I get? / Deliverables
Generated or reviewed Go commands use RunE, cobra Args validators, and returned errors so failures exit non-zero without brittle exit calls inside handlers.
- Cobra subcommand stubs with RunE and Args validators
- Review notes correcting Run/os.Exit anti-patterns
Recommended Skills
Journey fit
Cobra command design is core backend/CLI construction during the Build phase when you are implementing executables, not when you are still ideating markets. Subcommands, flags, and error contracts live in Go backend CLI code — the canonical shelf is build/backend even if you later ship the binary in Ship.
How it compares
Prefer this skill over generic “build a CLI in Go” prompts when you need Cobra-specific error and Args semantics, not a blank-slate main package.
Common Questions / FAQ
Who is golang-spf13-cobra for?
Solo Go developers and agent users scaffolding or reviewing spf13/cobra command trees for tools they ship themselves.
When should I use golang-spf13-cobra?
During Build/backend work when adding subcommands, wiring external API calls, or fixing exit-code behavior in existing Cobra CLIs.
Is golang-spf13-cobra safe to install?
It is documentation and eval-oriented guidance; confirm repo trust via the Security Audits panel on this page before adding it to your agent bundle.
SKILL.md
READMESKILL.md - Golang Spf13 Cobra
[ { "id": 1, "name": "rune-vs-run-error-propagation", "description": "Tests use of RunE instead of Run for error propagation", "prompt": "I'm writing a cobra subcommand in Go that calls an external API. If the API returns an error, the command should exit non-zero. Should I use Run or RunE?", "trap": "Without the skill, the model may say both work, suggest using Run with os.Exit(1), or not explain why Run is problematic. The correct answer is always RunE — it propagates the error through cobra's error handling chain.", "assertions": [ { "id": "1.1", "text": "Recommends RunE, not Run" }, { "id": "1.2", "text": "Explains that Run cannot return an error — you'd need os.Exit or panic" }, { "id": "1.3", "text": "Shows RunE returning the error from the handler" }, { "id": "1.4", "text": "Does NOT suggest using os.Exit inside RunE" }, { "id": "1.5", "text": "Mentions that returning error from RunE causes cobra to exit non-zero" } ] }, { "id": 2, "name": "args-validator-not-manual-check", "description": "Tests use of cobra Args validators instead of manual len(args) checks in RunE", "prompt": "I'm writing a Go CLI with cobra. My 'delete' command requires exactly one positional argument (the resource name). How should I validate this?", "trap": "Without the skill, the model writes len(args) != 1 check inside RunE. The correct approach is Args: cobra.ExactArgs(1) on the command definition, which validates before RunE runs and gives a standard error message.", "assertions": [ { "id": "2.1", "text": "Sets Args: cobra.ExactArgs(1) on the command struct" }, { "id": "2.2", "text": "Does NOT write len(args) check inside RunE" }, { "id": "2.3", "text": "Mentions that cobra prints a standard error message when validation fails" }, { "id": "2.4", "text": "RunE body accesses args[0] directly without re-validating length" } ] }, { "id": 3, "name": "outOrStdout-not-os-stdout", "description": "Tests use of cmd.OutOrStdout() instead of os.Stdout for testable output", "prompt": "I'm writing a cobra command in Go that prints a table of results to the terminal. How should I write to stdout from inside RunE?", "trap": "Without the skill, the model uses fmt.Println or os.Stdout directly. The correct approach is fmt.Fprintln(cmd.OutOrStdout(), ...) which can be redirected to a buffer in tests.", "assertions": [ { "id": "3.1", "text": "Uses cmd.OutOrStdout() as the io.Writer target" }, { "id": "3.2", "text": "Does NOT use os.Stdout directly" }, { "id": "3.3", "text": "Does NOT use fmt.Println (which hardcodes os.Stdout)" }, { "id": "3.4", "text": "Mentions testability as the reason — SetOut can redirect the writer in tests" } ] }, { "id": 4, "name": "persistent-prerunE-hook-chain", "description": "Tests PersistentPreRunE on root for global config init and the child override trap", "prompt": "In my Go CLI with cobra, I want to initialize viper config before any subcommand runs. I also have one subcommand that needs its own PersistentPreRunE for extra setup. How do I make sure both run?", "trap": "Without the skill, the model defines PersistentPreRunE on both root and child without noting that the child's hook replaces the parent's — so root's config init never runs for that subcommand.", "assertions": [ { "id": "4.1", "text": "Explains that a child's PersistentPreRunE replaces (not chains) the parent's" }, { "id": "4.2", "text": "Shows explicitly calling the parent's PersistentPreRunE from inside the child's hook" }, { "id": "4.3", "text": "Does NOT claim both hooks run automatically" }, { "id": "4.4", "tex