Skip to content

feat: CLI friendliness — warm output, --color, spinners, friendly empty-states - #73

Merged
vxfemboy merged 6 commits into
mainfrom
feat/friendliness
Jul 26, 2026
Merged

feat: CLI friendliness — warm output, --color, spinners, friendly empty-states#73
vxfemboy merged 6 commits into
mainfrom
feat/friendliness

Conversation

@vxfemboy

Copy link
Copy Markdown
Member

Sub-project B of "make kibble adoptable": make the first-run feel delightful. Distribution (A) got people in the door; this makes them stay.

What's in it (6 commits)

  • ui module (src/ui.rs, bin-only) — owns kibble's color/visual language with per-stream gating (stdout and stderr decide independently, so cmd 2>log never leaks ANSI into the log). owo-colors, full-gated → the lean retrieval lib is untouched.
  • --color=auto/always/never global flag (+ NO_COLOR respected).
  • Warm status lines + next-step hints on index/search/crawl/extract/ingest/build — with honest destination paths (index reports the resolved [index].dir, extract the real --out).
  • Friendly empty-states — bare kibble greets and points to kibble init; search no-match nudges.
  • Progress spinners (indicatif, full-gated) on the 5 long ops — stderr, TTY-gated, cleared before the result line.

The non-negotiable: machine safety

Piped / --json / non-TTY output is byte-identical to before — no color, no emoji. Enforced by per-stream gating and now guarded by an integration test (tests/machine_safety.rs) that shells the binary piped and asserts zero ANSI/emoji.

Verification

  • cargo test: 386 + 3 (ui) + integration incl. the new machine-safety test — all pass. cargo clippy --all-targets -- -D warnings clean. Lean build compiles; owo-colors + indicatif absent from the lean graph.
  • Per-stream gating verified with a real pty (both redirect directions). --color=always forces color even piped; --color=never/NO_COLOR force plain.
  • Per-task reviews + Opus whole-branch review (READY TO MERGE). Fixes applied from review: per-stream color decision, honest override paths, gated greeting emoji, the machine-safety test.

Known follow-up (non-blocking)

caps/ask not-found messages emit lib-side (not bin-side), so they can't route through the bin-only ui module without hoisting emission. Left warm-uniform as a follow-up; they're already plain/correct today.

🤖 Generated with Claude Code

vxfemboy added 6 commits July 26, 2026 12:17
owo-colors/indicatif are full-feature (bin-only) deps; the lean retrieval
lib is untouched. ui owns kibble's color/visual language via pure, tested
formatters gated on TTY + NO_COLOR + --color. No command output changed yet.
…ted)

Review caught: init_color derived one global from stdout's TTY, but warn/err/
hint print to stderr — so 'cmd 2>log' (stdout still TTY) would leak ANSI into
log, and '>out' would wrongly suppress interactive error color. Split into
COLOR_STDOUT/COLOR_STDERR, each gating on its own stream. + cover fmt_warn.
Route high-traffic command output through ui (index/search/crawl/extract/
ingest/build); add try:-hints; bare 'kibble' greets and points to init;
'no results' nudges. Piped/--json output stays byte-identical (gated).
Review caught two issues in the warmed output:
- index/extract messages hardcoded 'data/index'/'data/extracted' even when
  overridden ([index].dir / --out), so they lied about where files went. Now
  index reports the resolved cfg.index.dir and extract reports the real --out.
- bare 'kibble | cat' leaked one 🦴; move the greeting into ui::greet() which
  shows the accent only when stdout is colored (piped = emoji-free).
…ract)

indicatif spinner on stderr, gated by the same TTY/color decision so it never
shows when piped or --json. Purely visual; clears before the final ok line.
Final-review gap: the 'non-negotiable' invariant (piped/--json → no ANSI/
emoji) was only manually verified. Add an integration test that shells the
binary with piped stdio and asserts zero ANSI/bone-emoji across init/index/
search/search --json/bare — so a future ui::ok slipping onto a data path fails CI.
@vxfemboy
vxfemboy merged commit 7541af6 into main Jul 26, 2026
@vxfemboy
vxfemboy deleted the feat/friendliness branch July 26, 2026 16:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant