feat: CLI UX improvements — completion, colored output, progress bar#62
feat: CLI UX improvements — completion, colored output, progress bar#62spencercjh merged 26 commits intomainfrom
Conversation
Signed-off-by: spencercjh <spencercjh@gmail.com>
Add internal/cli package providing terminal output helpers: - Successf, Errorf, Skipf, Hintf, Statusf for formatted colored output - NO_COLOR environment variable support for disabling ANSI codes - ColorEnabled() for querying current color state Signed-off-by: spencercjh <spencercjh@gmail.com>
Signed-off-by: spencercjh <spencercjh@gmail.com>
Add progressbar v3 to both sequential and concurrent batch processing methods. The bar writes to stderr, shows batch count, and updates description on failures. Signed-off-by: spencercjh <spencercjh@gmail.com>
…ormat, target) Signed-off-by: spencercjh <spencercjh@gmail.com>
Replace slog.InfoContext and fmt.Fprintf calls with colored cli package helpers in cmd/root.go (printHintAndExit) and cmd/spring.go (printProjectInfo, runSpringPatch). Error messages use red, hints use cyan/yellow, success uses green, and skip states use dim formatting. Signed-off-by: spencercjh <spencercjh@gmail.com>
…d progress bar Signed-off-by: spencercjh <spencercjh@gmail.com>
- Extract registerCompletion() helper that logs warnings on failure - Handle progressbar Add/Finish errors with debug logging - Remove all nolint:errcheck comments Signed-off-by: spencercjh <spencercjh@gmail.com>
Signed-off-by: spencercjh <spencercjh@gmail.com>
Signed-off-by: spencercjh <spencercjh@gmail.com>
Signed-off-by: spencercjh <spencercjh@gmail.com>
- Remove redundant colorEnabled state, delegate to color.NoColor - Add prefix assertions for Errorf and Hintf tests - Add NO_COLOR mode test for Hintf Signed-off-by: spencercjh <spencercjh@gmail.com>
There was a problem hiding this comment.
Pull request overview
This PR improves the spec-forge CLI user experience by adding shell completion support, standardizing user-facing output with a colored/structured output helper, and showing batch enrichment progress.
Changes:
- Added
spec-forge completionsubcommand (bash/zsh/fish/powershell) and flag enum completions. - Introduced
internal/clioutput helpers for consistent status/success/error/hint messaging (withNO_COLORsupport). - Added a progress bar to enricher batch processing for both sequential (streaming) and concurrent modes.
Reviewed changes
Copilot reviewed 12 out of 13 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
cmd/completion.go |
Adds the completion subcommand and a helper for registering flag completions. |
cmd/root.go |
Routes classified errors/hints through the new CLI output helpers; registers completion in test root cmd. |
cmd/generate.go |
Replaces user-facing slog.Info* status messages with internal/cli output; registers enum completions. |
cmd/enrich.go |
Replaces user-facing status messages with internal/cli output; registers enum completions. |
cmd/publish.go |
Replaces user-facing status messages with internal/cli output; registers enum completions. |
cmd/spring.go |
Replaces user-facing slog.InfoContext output with internal/cli output. |
internal/cli/output.go |
New colored output helper package built on fatih/color. |
internal/cli/output_test.go |
Tests for output helpers and NO_COLOR behavior. |
internal/enricher/processor/concurrent.go |
Adds schollz/progressbar progress bar to sequential and concurrent batch processing loops. |
go.mod |
Adds fatih/color and schollz/progressbar/v3 dependencies (and indirect deps). |
go.sum |
Updates checksums for new/updated dependencies. |
docs/plans/2026-03-30-cli-ux-improvements.md |
Implementation plan documentation for the UX changes. |
docs/plans/2026-03-30-cli-ux-improvements-design.md |
Design documentation for completion/color/progress-bar features. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…detection Use os.LookupEnv to detect NO_COLOR presence (per no-color.org convention), so NO_COLOR="" also disables color. Only set color.NoColor=true when NO_COLOR is present; otherwise delegate to fatih/color's built-in TTY detection for proper pipe/redirect behavior. Signed-off-by: spencercjh <spencercjh@gmail.com>
bar.Describe and bar.Add are now both inside the mutex section, ensuring the description update and count increment are atomic. Signed-off-by: spencercjh <spencercjh@gmail.com>
Update progress bar file location to concurrent.go, fix dependency versions to match go.mod, and correct Non-TTY behavior description. Signed-off-by: spencercjh <spencercjh@gmail.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 12 out of 13 changed files in this pull request and generated 4 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
enrich --output is a file path, not a format enum. The yaml/json completion was misleading and prevented file path autocompletion. Signed-off-by: spencercjh <spencercjh@gmail.com>
Instead of asserting environment-dependent values, verify the actual invariant: NO_COLOR present forces color.NoColor=true, absent preserves existing value. Add restore of global color.NoColor to prevent leakage. Signed-off-by: spencercjh <spencercjh@gmail.com>
printHintAndExit already prints the error via cli.Errorf + cli.Hintf, so the slog.Error call was causing every error to appear twice on stderr. Signed-off-by: spencercjh <spencercjh@gmail.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 12 out of 13 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Initial description now includes "| 0 failed" matching the sequential mode and the design spec. Signed-off-by: spencercjh <spencercjh@gmail.com>
…tions Use LookupEnv to capture whether NO_COLOR was originally set, and restore with Setenv or Unsetenv accordingly to avoid leaking an empty string value when the variable was originally unset. Signed-off-by: spencercjh <spencercjh@gmail.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 12 out of 13 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
The generate command's slog.InfoContext calls for start/restore/complete messages duplicate the colored cli.Statusf output. Demote them to slog.DebugContext so they only appear with -v, keeping stderr output consistent through the cli package. Signed-off-by: spencercjh <spencercjh@gmail.com>
…output Use color.CyanString/YellowString to build the full hint line in memory before writing, instead of two separate Fprintf calls that could be split by concurrent writes to the same writer. Signed-off-by: spencercjh <spencercjh@gmail.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 12 out of 13 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
… implementation The design doc claimed explicit os.Stdout.IsTerminal() / os.Stderr.IsTerminal() checks, but the implementation only checks NO_COLOR and delegates TTY detection to fatih/color defaults. Updated the doc to reflect the actual approach. Signed-off-by: spencercjh <spencercjh@gmail.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 12 out of 13 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Replacing slog.InfoContext with slog.DebugContext removed the start-of- generation feedback for non-verbose users. Use cli.Statusf instead, consistent with this PR's goal of routing user-facing output through the cli package. Signed-off-by: spencercjh <spencercjh@gmail.com>
Show which spec file is being published alongside the target, making it easier to troubleshoot when running from different directories. Signed-off-by: spencercjh <spencercjh@gmail.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 12 out of 13 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Restore operations are user-visible pipeline steps (default --keep-patched is false), so they should use cli.Statusf/Successf rather than slog.DebugContext which is invisible without -v. Signed-off-by: spencercjh <spencercjh@gmail.com>
Summary
spec-forge completionsubcommand supporting bash/zsh/fish/powershell with dynamic completions for enum flagsinternal/clipackage (Successf/Errorf/Skipf/Hintf/Statusf), respectsNO_COLORCloses #61
Test plan
make test— all tests pass (including newinternal/clitests at 100% coverage)make lint— 0 issuesmake build— succeedsspec-forge completion bash|zsh|fish|powershell— valid scripts outputNO_COLOR=1disables ANSI codesspec-forge generate/enrich/publish— colored status output on stderr🤖 Generated with Claude Code