byob-go-cli

byob-go-cli

Bring Your Own Beads — Go CLI edition. A forkable template repository for Go CLI tools. Holds my preferred architectural decisions and idiomatic tips as beads records, ready to be cloned into a new project (or injected into an existing one) as the starting point for coding agents.

Status: experimental. The decision set, memory tier, and distribution mechanics are all likely to evolve. Expect breaking changes to category names, bead IDs, and the make import / make export workflow between releases. Pin to a specific tag if you need stability.

What this is

This is not a library and not a Go package — it's a template. You fork it by copying it, re-init its beads database with a project- specific prefix, and then add your own task beads on top of the inherited decision beads. Coding agents working in the fork consult the decision beads as "how to structure things" and implement the tasks following those decisions.

Two layers of guidance live in the beads DB:

  1. Library beads — architectural decisions grouped into categories, shipped under a custom byob issue type so they're distinguishable from your project's own work. Full Problem / Idea / Tradeoffs / Sketch template. Consulted on demand via bd list --type=byob and bd show.
  2. Memories — one-line idiomatic tips (e.g. "wrap errors with %w", "use sync.OnceValue", "call t.Helper() in test helpers"). These auto-inject into every agent session via bd prime, so they are always-on context without ceremony.

Library beads are grouped under category roots (parentless beads) covering the breadth of a Go CLI — architectural choices, CLI ergonomics, testing patterns, observability, and the packaging and release surface. Once imported, bd list --type=byob --no-parent enumerates the categories, and bd list --type=byob -l errors (or any category label) drills in.

Agents: if you've been asked to apply byob to an existing repo, see CLAUDE.md first. The workflow is "seed the target's beads DB from the release, then file task beads" — not "review and fix."

Decisions

21 category epics, each grouping a handful of decisions in the Problem / Idea / Tradeoffs / Sketch shape.

  • Agent onboarding

    You are working inside a forked copy of byob-go-cli, a personal template repository for Go CLI tools. The beads database you're looking at contains the template's architectural decisions alongside the tasks for this specific project.

    0 decisions
  • Command shape

    Options struct + NewCmdXxx constructor + pure runFunc three-part separation.

    6 decisions
  • Config

    Layered, lazily loaded configuration with discovery and provenance.

    3 decisions
  • Errors

    Semantic error types mapped to exit codes by the top-level runner.

    4 decisions
  • Factory + DI

    Central factory struct with lazy-loaded dependencies passed into every command.

    1 decision
  • HTTP client

    A single *http.Client on the Factory, built from a composable http.RoundTripper middleware chain; deterministic httptest seams in tests.

    5 decisions
  • Input validation

    Defense against untrusted input beyond the flag-value checks already in byob-errors.1: path traversal, config-shape validation, shell injection, SQL injection, and enum/range checks at the Options boundary.

    5 decisions
  • Interfaces

    Interface-driven seams for swappable implementations and test doubles.

    3 decisions
  • IOStreams

    Single abstraction for stdin/stdout/stderr with TTY detection and color support.

    3 decisions
  • Layout

    Conventional directory split and cobra command grouping.

    1 decision
  • Lifecycle

    Process-lifecycle and cancellation: signal handling, context propagation through runFuncs.

    3 decisions
  • Logging

    Structured, contextual, leveled logging threaded through every command without ceremony.

    4 decisions
  • Output

    TTY-adaptive human output plus first-class structured export.

    3 decisions
  • Progress

    Adaptive progress that looks right on a TTY and degrades off-TTY. Spinners for unknown-total, bars for known-total.

    4 decisions
  • Prompter

    Narrow Prompter interface on the Factory with TTY detection, scripted test double, and a library pick that won't rot.

    5 decisions
  • Release

    Pure-Go discipline (CGO_ENABLED=0, go:embed) as the foundation; Makefile+ldflags for day-to-day builds; goreleaser for tag-triggered cross-compile, archives, checksums, optional homebrew/nfpm channels. Both paths inject the same ldflags vars so version output is path-independent.

    10 decisions
  • Runtime directories

    Per-OS directories for cache, state, and data (config is covered in byob-config), plus the atomic-write discipline that keeps them consistent under concurrent invocations.

    4 decisions
  • Security

    Supply-chain and secret-handling posture: pin by hash not tag, scan for known CVEs on every push, ship SBOMs and signatures from the release pipeline, and refuse to accept secrets as flag values.

    5 decisions
  • Storage

    Multi-engine persistent storage for CLI state: sqlite + postgres behind a consumer-scoped Store interface. CockroachDB rides the postgres wire protocol.

    6 decisions
  • Testing

    Test-first command structure: runF injection, in-memory IO, test doubles.

    4 decisions
  • User docs

    Narrative user docs distinct from generated reference (byob-output.3). README carries orient-and-quickstart only; --help Long/Example fields carry the detailed reference; narrative docs cover concepts and troubleshooting. Release notes come from git history, not a hand-maintained CHANGELOG.

    5 decisions

Memories

24 one-paragraph idiomatic tips. Read all.