Skip to content

feat: CLI UX improvements — completion, colored output, progress bar#62

Merged
spencercjh merged 26 commits intomainfrom
feat/cli-ux
Mar 31, 2026
Merged

feat: CLI UX improvements — completion, colored output, progress bar#62
spencercjh merged 26 commits intomainfrom
feat/cli-ux

Conversation

@spencercjh
Copy link
Copy Markdown
Owner

Summary

  • Add spec-forge completion subcommand supporting bash/zsh/fish/powershell with dynamic completions for enum flags
  • Add colored terminal output via internal/cli package (Successf/Errorf/Skipf/Hintf/Statusf), respects NO_COLOR
  • Add progress bar to enricher batch processing (sequential + concurrent modes)

Closes #61

Test plan

  • make test — all tests pass (including new internal/cli tests at 100% coverage)
  • make lint — 0 issues
  • make build — succeeds
  • spec-forge completion bash|zsh|fish|powershell — valid scripts output
  • NO_COLOR=1 disables ANSI codes
  • spec-forge generate/enrich/publish — colored status output on stderr

🤖 Generated with Claude Code

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>
Copilot AI review requested due to automatic review settings March 31, 2026 02:24
@spencercjh spencercjh self-assigned this Mar 31, 2026
@spencercjh spencercjh added enhancement New feature or request go Pull requests that update go code labels Mar 31, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 completion subcommand (bash/zsh/fish/powershell) and flag enum completions.
  • Introduced internal/cli output helpers for consistent status/success/error/hint messaging (with NO_COLOR support).
  • 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.

Comment thread internal/cli/output.go Outdated
Comment thread internal/cli/output.go Outdated
Comment thread internal/enricher/processor/concurrent.go Outdated
Comment thread docs/plans/2026-03-30-cli-ux-improvements.md Outdated
Comment thread docs/plans/2026-03-30-cli-ux-improvements-design.md Outdated
Comment thread docs/plans/2026-03-30-cli-ux-improvements-design.md
…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>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread cmd/enrich.go
Comment thread cmd/enrich.go Outdated
Comment thread internal/cli/output_test.go Outdated
Comment thread cmd/root.go
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>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread internal/enricher/processor/concurrent.go
Comment thread internal/cli/output_test.go
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>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread cmd/generate.go
Comment thread internal/cli/output.go
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>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread internal/enricher/processor/concurrent.go
Comment thread docs/plans/2026-03-30-cli-ux-improvements-design.md Outdated
… 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>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread cmd/generate.go
Comment thread cmd/publish.go Outdated
Comment thread internal/enricher/processor/concurrent.go
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>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread cmd/generate.go
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>
@spencercjh spencercjh merged commit cd5d61a into main Mar 31, 2026
4 checks passed
@spencercjh spencercjh deleted the feat/cli-ux branch March 31, 2026 06:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request go Pull requests that update go code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(cli): CLI UX improvements — completion, colored output, progress bar

2 participants