feat(cli): 3 UX fixes — compact --help, silent plugin update sub-output, --json minified (v3.2.15)#57
Merged
Merged
Conversation
…ut, --json minified (v3.2.15) All from live testing of v3.2.14 / earlier turns: A. --help compact-with-wrap (revert v3.2.12 next_line_help) - root Cli: drop `next_line_help = true` so commands + options render compactly again - For args carrying `[default]` + `[possible values]` (-o/--output, --mode, --harness on harness run / skill run), set `hide_default_value` + `hide_possible_values` and embed a manual `\n[default: …, possible values: …]` tail in the `help` string — desc inline, bracketed block wraps to indented next line - HarnessMode variant docs stripped back to a comment block (was forcing long-format Possible values block in clap's renderer) - v31_integration test `root_help_renders_long_format` renamed to `root_help_renders_compact_with_wrapped_defaults` with the new positive assertions B. plugin update: silence orchestrator's per-step `▸` lines - New `vault_sync::run_silent` forces `progress_writer = Some(io::sink())`, killing both intro/outro frame AND per-step `▸ <label>` lines on TTY - `plugin_update::run` switches to `run_silent` so the framed `⚡ Plugin Update` header appears as the FIRST thing after the brand banner. The animated spinner is now the only progress signal during work — matches doctor/update - v3.2.13's `run_embedded` removed (no remaining caller; the in-between 'silenced banner but kept step lines' mode wasn't useful) C. --json minified by default - resolve_output_mode: `--json` and `--output json` no longer auto-prettify on TTY - To get indented JSON: pass `--json --pretty` (or `--output json --pretty`) - Easier copy/paste of the structured response into scripts/curl; humans can still opt back into pretty - Tests in mode.rs split into mono+pretty pairs Tests: 1284 passed; clippy clean; fmt clean. NOT MERGED — user reviewing locally first.
…-command emoji (v3.2.15 round 2)
Three more UX fixes from this turn's live testing (rolled into the v3.2.15
PR per user request 'ทำรวมใน PR เดียวกัน'):
D. Per-command emoji — pre-3.2.15 both doctor and update used 🧠 (same as
the OneBrain wordmark banner). v3.2.15: doctor → 🔬, update → 🚀,
plugin update → 🔄.
E. skill/harness --help flag-per-line — the run subcommand's description
in those help screens was a dense dot-separated single-line summary.
Now uses #[command(about = ...\n...)] so each --flag lands on its
own indented line.
F. plugin update version tracking — captures
.claude-plugin/plugin.json::version BEFORE + AFTER vault-sync.
Surfaces the delta in:
- vault-sync step row: vX → vY / vX · up-to-date / installed vY /
current vY · skipped (dry-run)
- verdict footer: updated vX → vY / update complete · vY /
already up-to-date · vY / dry-run · current vY
- JSON envelope: version_before / version_after (additive)
Implementation: shared helpers plugin_update_vault_detail +
plugin_update_verdict_text in dispatch.rs so the static and animated
renderers stay in sync.
1284 passed; clippy clean; fmt clean. NOT MERGED — user testing locally.
…lag duplicate (v3.2.15 round 3) Two more UX fixes from this turn's live testing — bundled per user's 'ทำรวมใน PR เดียวกัน' request: G. **skill run / harness run --help: no flag duplicate at top.** Pre-3.2.15 round-3 the verb-level help repeated the parent-level Commands:-listing flag breakdown above its own Options: section (where every flag is already listed with [default] + [possible values]). Now uses #[command(about = ..., long_about = ...)] so the parent listing keeps the flag breakdown but the verb-level help shows just the short prose. H. **--output table / --output tsv removed entirely.** Both variants fell through to serialize_json(value, false) for every command — the format flag silently lied (\`--output table doctor\` emitted the same minified JSON as \`--output json doctor\`). User picked 'lบออก — เหลือ text/json/yaml (แนะนำ)'. Removed the OutputMode::Table / Tsv variants, the dispatcher arms, the resolver branches, the value_parser entries, the help text listings, and all 6 dependent tests. Remaining set: text / json / yaml. 1281 passed (lost 3 tests with the variants); clippy clean; fmt clean. Still NOT MERGED — user testing locally first.
… (v3.2.15 round 4)
Two more UX fixes from this turn's live testing:
I. **`skill run --help` / `harness run --help` now render Options compact**
like top-level `onebrain --help`. Reverted round-3's parent-listing
flag-per-line breakdown on `SkillVerb::Run` / `HarnessVerb::Run` —
discovered the multi-line `#[command(about = ...)]` was triggering
clap's auto-switch to long format (option name on own line + indented
desc) at the verb level. Now both variants use a single-line doc-comment
about so verb-level Options stays compact AND `[default]` + `[possible
values]` still wraps to an indented next line for the args that carry
both. Parent-level `skill --help` / `harness --help` Commands: rows now
show a one-line summary (trade-off: lost the per-flag breakdown in the
parent listing, but user explicitly chose compact verb-level).
J. **Positional `<NAME>` description for skill info / show / bootstrap +
hidden bundle verbs.** Previously rendered as a bare `<NAME>` with no
help text because the variant's doc-comment described the verb itself
but didn't propagate to the inline-struct positional arg. Now every
such variant uses the block form `Variant { /// <doc> name: String, }`.
1281 passed; clippy clean; fmt clean. Still NOT MERGED — user testing.
…v doc-drift cleaned Round-1 review caught: - CHANGELOG had 9 bullets under v3.2.15 (over the 8-bullet cap) — dropped the stale entry about parent-listing flag-per-line (round 4 reverted that, so the bullet documented behaviour that never shipped). - Stale doc-comment refs to dropped `table` / `tsv` variants in legacy_output.rs, main.rs, banner.rs (top-level module doc + the suppress-precedence comment), output/mode.rs, output/progress.rs. 1281 passed; clippy clean; fmt clean. Still NOT MERGED.
Round-2 cleanup pass on PR #57 before the v3.2.x final cut. Applied high-ROI items from the three review streams (clean code / consistency / binary footprint): **Binary footprint (-39% release size)** - Cargo.toml release profile: `opt-level = "z"` (was implicit 3) + `lto = "fat"` (was "thin"). Trimmed 5.4 MB → 3.3 MB. The CLI's hot paths are I/O-bound, so size-optimised codegen carries no measurable runtime hit for sub-second runs. **Deduplication** - `read_plugin_version`: hoisted from private `fn` in `onebrain-fs::vault_sync::orchestrate` to `pub fn` re-exported at the crate root. `onebrain-cli::v31::plugin_update` drops its duplicate helper and calls through. (Code-Simplifier finding 1.1.) - `vault_sync::run_with(embedded, silent)` → `run_with(silent)`. The orchestrator only consults `embedded` on the `progress_writer = None` branch, and the silent path always sets the writer to a sink — the flag was structurally dead. (Code-Simplifier finding 1.4.) **Dead code drop** - `plugin_update_vault_detail`: dropped the unused `partial_failed: bool` parameter. Both callsites + the rustdoc decision-table updated. (Code-Simplifier finding 2.2.) - `ProgressRenderer::set_step_delay`: demoted from `pub` to `pub(crate)`. Production paths only ever pass `None`; the seam exists for the cross-module animated-path tests. (Code-Simplifier finding 2.1.) **Consistency** - `OutputMode` enum: added rustdoc summary line naming the three remaining variants (Text/Json/Yaml). (Consistency finding M3.) - `commands/vault_sync.rs`: added `use std::io;` so body uses `io::sink()` matching the rustdoc references. (Consistency finding M4.) **Deferred to v3.3** (per binary-size reviewer): - reqwest → ureq swap (kills the entire tokio/hyper/h2 async stack; ~700–900 KB saved but needs its own PR for review) - serde_yaml (deprecated) → serde_yaml_ng (active fork; ~30–60 KB, drop-in) - clap feature audit (`env` usage) **Skipped** (per Consistency reviewer): - M1 rename `run_silent`/`run_quiet` → `run_embedded` (cosmetic only; the cleanup above already shipped the semantic simplification) - M2 naming-convention comment block (informational; defer) - Renderer unification `render_plugin_update_inner` (~80 LOC reduction but cross-cuts the static/animated split — too risky for the final v3.2.x cut) 1281 passed; clippy clean; fmt clean. Release binary: 3.3 MB (was 5.4 MB).
kengio
added a commit
that referenced
this pull request
May 29, 2026
…nify (v3.2.18) (#60) Five dependency/cleanup changes for the v3.3 cycle, shipped as one patch release (no new CLI command — completions deferred to v3.3): - reqwest → ureq (blocking sync HTTP) across the 4 GitHub/tarball fetch sites (update + vault-sync). ureq carries no async runtime, so this removes the entire async stack (tokio/hyper/h2/tower/tower-http/hyper-rustls/ tokio-rustls/hyper-util) from the release binary -- all pulled in only by reqwest. TLS stays rustls; JSON parsed via existing serde_json. Net: -342 KB (3.34->3.01 MB), -54 crates (178->124), ~12% faster clean build (41.0->36.2s). Runtime of everyday commands unchanged (they make no HTTP calls; the fetch paths are network-bound). - Removed the dead tokio_helper runtime shim (#[allow(dead_code)], zero callers, the only direct tokio user). The daemon (v3.3) re-introduces tokio deliberately for its async RPC server. - serde_yaml (archived/unmaintained) -> serde_yaml_ng via package-rename alias; zero code changes. - Dropped the unused clap `env` feature (no #[arg(env)] in the tree). - Unified the two plugin-update text renderers into render_plugin_update_inner, removing the PluginUpdateTextData trait that existed only to make the static renderer generic over a test double (-~80 LOC; Code-Simplifier finding, PR #57). - Renamed vault_sync::run_silent + register_schedule::run_quiet -> both run_embedded (Consistency reviewer finding, PR #57). 3-round review (correctness/ureq parity · deps+tokio-removal · holistic): cargo fmt + clippy -D warnings clean, 1296 tests pass, live `update --check` verified against real GitHub over rustls. docs/reference updated.
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
3 UX fixes from live testing of v3.2.14 / this turn — bundled into one PR per user request.
A. `--help` compact-with-wrap (revert v3.2.12 long-format)
v3.2.12's blanket `next_line_help = true` made every arg render in long format. User testing flagged "ดูยาก" (hard to read). v3.2.15 reverts to compact AND wraps `[default]/[possible values]` to indented next line:
```
Options:
--vault Override vault root (highest priority · beats ONEBRAIN_VAULT and walk-up)...
-o, --output Output format. Default `text` is TTY-friendly; pipe-detected calls drop color/pretty automatically
[default: text, possible values: text, json, yaml, table, tsv]
--json Shorthand for `--output json`
```
Same wrap applied to `harness run --help` and `skill run --help` for `--mode` / `--harness`. `HarnessMode` variant docs stripped (the multi-line Possible values block was forcing long format).
B. `plugin update` no header leak
User testing of v3.2.14 flagged that 5 `▸ ` lines from `vault_sync`'s TtyProgress leaked ABOVE the framed `⚡ Plugin Update` header. v3.2.15 routes through new `vault_sync::run_silent` which forces `progress_writer = Some(io::sink())` — kills the per-step TTY lines AND the intro/outro frame. The framed header now appears as the FIRST thing in the report (right after the brand banner), with the animated spinner as the only progress signal — matches `doctor`/`update`.
`run_embedded` removed (no remaining caller; the in-between mode wasn't useful).
C. `--json` minified by default
Pre-3.2.15 auto-prettified JSON on TTY, which was convenient for humans glancing at a structured response but made the "copy/paste into curl / a script" path noisier than necessary. v3.2.15: `--json` (and `--output json`) emit single-line minified JSON by default; `--json --pretty` opts into indented.
```bash
$ onebrain --json plugin update --dry-run
{"version":"1","command":"plugin.update","ok":true,"data":{...},"warnings":[]}
$ onebrain --json --pretty plugin update --dry-run
{
"version": "1",
...
}
```
Test impact
Files
```
CHANGELOG.md | 8 +++-
Cargo.lock | 8 ++--
Cargo.toml | 2 +-
crates/onebrain-cli/src/cli.rs | 53 ++++++++++++++++----------
crates/onebrain-cli/src/commands/vault_sync.rs | 32 ++++++++++++----
crates/onebrain-cli/src/output/mode.rs | 41 ++++++++++++++++----
crates/onebrain-cli/src/v31/plugin_update.rs | 13 ++++---
crates/onebrain-cli/tests/v31_integration.rs | 51 +++++++++++++++++--------
8 files changed, 145 insertions(+), 63 deletions(-)
```
User testing locally before merge per their request. Ready to review when they're back.