Repository navigation
feat(cli): leveled logger + fang wrap (re-merge of #8 + #9) - #10
Merged
Merged
Conversation
Adds charmbracelet/log as the package-level structured logger and wires
two new persistent flags on rootCmd:
-v, --verbose count (1 = info, 2+ = debug; default = warn)
--quiet (overrides -v, clamps to error only)
Output discipline: logs always go to stderr; stdout stays reserved for
command output users may pipe (lists, JSON, success lines). With
--json and no -v, logs are silenced entirely so the JSON stream stays
pristine for jq/scripting; --json with -v flips the formatter to JSON
on stderr.
Two instrumentation sites in this PR:
- client.do() now emits debug logs on http request entry, exit, and
failure (method, url, status / err). Every command that goes through
the shared do() path picks this up automatically.
- config.loadConfig()'s prior "warning: could not parse config file"
stderr write is now a structured logger.Warn — visible at default
level since warnings still emit.
Other fmt.Print* sites untouched: they're user-facing data, not logs.
Tests: TestConfigureLogger_LevelMatrix exercises the precedence matrix
across {default, -v, -vv, -vvv, --quiet, --quiet+-vv, --json,
--json+-v}. Existing pair tests untouched.
Note for users: cobra previously bound -v to --version. -v now means
--verbose; --version still works in long form.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Drops fang.Execute(ctx, rootCmd, fang.WithVersion(version)) in for plain rootCmd.Execute(). Net effect: - --help and subcommand --help render with structured sections (USAGE / COMMANDS / FLAGS), aligned columns, subdued styling. - Errors get a styled prefix on stderr. - man and completion subcommands ship for free. - --version still reports the build-time-injected `version` var via fang.WithVersion (fang otherwise reports "unknown" since it doesn't read cobra's Version field by default). Transitive dep bump: charmbracelet/log (PR #8) brought in an older x/cellbuf that's incompatible with x/ansi v0.11.x — fang requires the newer ansi. go get github.com/charmbracelet/x/cellbuf@latest pulls both onto a coherent set (cellbuf v0.0.15, ansi v0.11.5). No source change needed. Tests still green; no behavior change to any RunE. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Bare gofmt nit caught by golangci-lint v2.11.4 in CI. Field widths in the table-driven test struct were over-padded; gofmt prefers single-space alignment when the field name+type fits. Pure whitespace-only change.
4 tasks
ironystock
added a commit
that referenced
this pull request
Apr 28, 2026
Two issues caught by CI on the Blacksmith migration PR: 1) Mod tidy drift. PR #10 (logger + fang) shipped go.mod with charmbracelet/fang as `// indirect` even though main.go imports it directly, plus go.sum carried orphan entries from the cellbuf@latest upgrade (old ansi/cellbuf/term/displaywidth/uax29 versions, two old colorprofile versions). `go mod tidy` cleans both up. The new mod-tidy CI check did exactly what it was added to do — caught the leftover hygiene before it could mask a real dep issue down the line. 2) Check-name drift from the Blacksmith migration. The wizard rewrote `windows-latest` -> `blacksmith-4vcpu-windows-2025` in matrix.os, which propagates into the job name `Test (...)` and therefore the GitHub check-run name. Main's branch protection ruleset requires the literal name `Test (windows-latest)` — so if this PR merged as-was, every future PR would be silently blocked by a required check that no workflow run ever produces. Fix: split matrix.os (stable label that drives the job name and ruleset matching) from matrix.runner (the actual runs-on value that can change). Same trick lets matrix Linux finally benefit from Blacksmith too — the wizard left it on GitHub-hosted ubuntu while moving the standalone jobs (mod-tidy, lint, goreleaser) to Blacksmith. After this commit: - Job names stay `Test (ubuntu-latest)` / `Test (macos-latest)` / `Test (windows-latest)` regardless of runner provider. - Linux matrix runs on Blacksmith. - macOS stays on GitHub-hosted (Blacksmith doesn't offer macOS). - Windows runs on Blacksmith. - Ruleset needs no change. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Brings the contents of merged PRs #8 (leveled logger + `-v`/`--quiet` flags) and #9 (charmbracelet/fang wrap) into `main`. Both PRs were merged earlier today, but into their stacked-branch bases, not into `main` — so the code lives on `feat/cli-fang-wrap` but was never reflected on `main`.
Why this happened
#8's base was `refactor/cmd-rememberize-split` (the #7 branch); #9's base was `feat/cli-leveled-logger` (the #8 branch). When you clicked Merge on #8 and #9, GitHub merged them into those base branches as configured, not into `main`. GitHub auto-retargets stacked PRs only when the base branch is deleted — leaving the base branches alive (which is the default behavior on merge) breaks the auto-retarget.
Lesson for next time
When using stacked PRs, either:
Captured to my agent memory as a feedback note so I don't repeat the workflow on the next sprint.
Diff scope
7 files, +278/-2:
Nothing new — verbatim recovery of #8 + #9. Both already had locally-green builds and tests; CI will re-validate now that base = main.
Verification
Test plan
🤖 Generated with Claude Code
Need help on this PR? Tag
@codesmithwith what you need.