Skip to content

cprof config: an interactive panel for the whole configuration, with a live preview #43

Description

@dcotelo

Problem

~/.cprof.json is edited by hand or through a dozen subcommands, and one part
of it is genuinely awkward to write: the statusline block. lines is a
nested array of segment names, bar, thresholds, colors and
weekly_threshold each have their own rules, and the only feedback is cprof doctor telling you afterwards that a value was rejected and what it fell back
to. There is no way to see what a setting does before committing to it.

Proposed behavior

cprof config opens a panel over the whole configuration — profiles, rules,
repository pins, the default, fallback and the statusline — with a preview pane
showing what the highlighted setting does. For a statusline row that preview is
the real rendered line, with your glyphs, colours, width and segments:

┌─ cprof config ─────────┐┌─ preview ──────────────────┐
│ profiles               ││ ⚑ work │ [Opus 5] │ cprof   │
│ rules                  ││ Context ▓▓▓▓░░░░░░ 39%      │
│> statusline.bar.width  ││ Usage ▓▓░░░░░░░░ 18%        │
│ statusline.colors      ││                             │
│ fallback               ││ width: 10   ←→ to change    │
└────────────────────────┘└─────────────────────────────┘

cprof config undo restores the previous configuration.

Alternatives considered

  • Statusline only. Narrower and with the same preview payoff, since the
    statusline is the only config with something to show. Rejected: the panel
    should cover the whole config.
  • A wizard, or config set/config get/config edit. Less machinery and
    more in character with the rest of the tool, but neither shows what a setting
    does before you commit to it, which is the point.
  • A TUI written in pure bash 3.2. Keeps jq as the only dependency, at the
    cost of several hundred lines of raw-mode handling, key decoding, a redraw
    loop and a restore that must survive every exit path — a missed restore
    leaves the user's shell with echo off, a worse failure than any cprof has
    today. Rejected in favour of letting fzf own the loop.
  • gum or dialog instead of fzf. gum is sequential prompts, not a panel;
    dialog is the closest to a boxed panel but the least likely to be installed
    on a Mac and has a clumsy shell interface. fzf brings the preview pane, which
    is the feature that justifies a dependency at all.

Additional context

Decisions already taken (in the brainstorm, recorded in the design doc):
whole config rather than statusline only; a panel rather than a wizard; fzf
as an optional dependency, with the panel absent rather than degraded when
it is missing; destructive operations in scope behind typed confirmation;
immediate writes with a one-step backup and cprof config undo.

This reverses a prior decision. The clauth evaluation listed a TUI among the
things cprof should not adopt, with in-place credential swap, auto-switch, an
MCP delegate and a daemon. It is revisited because the config surface has grown
since — the statusline block did not exist then — and because this is an
optional layer over the existing commands, not a new way to run the tool. cprof
stays fully usable and scriptable with no fzf installed.

Architecture, in one line: everything editable becomes a row generated
from the config by jq — id, value, kind, constraint, action — and screens are
filtered row lists. fzf owns the loop and calls back into three normal CLI
entry points: --rows, --preview and --apply. Adding a setting to the
panel is then a row definition rather than new drawing code, which is what
keeps it in step as the config grows.

Why that matters for testing: the untestable surface is exactly one
function, the fzf invocation. Row generation, preview rendering, validation,
apply and undo are all CLI entry points the suite drives with no TTY, the way
it already drives statusline --stdin. The rule to hold while building it: if
a behaviour can only be reached by pressing a key, it is in the wrong place.

The risk worth naming. Destructive rows — remove --purge, login,
share — touch credential directories, symlinks and the keychain, inside a
screen whose purpose is fast movement. Mitigations are specified: never the
default selection, typed confirmation naming the profile, a second confirmation
for --purge, and login handed to the real subcommand because it opens a
browser.

Open questions for the plan: whether row ids are a documented stable
surface or explicitly internal; whether --rows emits tab-separated fields or
JSON; how rule reordering works, since it is a different interaction from
editing a value; and whether the panel may show usage figures at all, given
that would make it the first surface that could fetch from the network
(recommendation: cache-only, never fetch).

Rollout: not a release on its own. The first version can cover the
statusline block and the default profile, with the remaining screens added as
rows and no further architecture — which front-loads the live preview, the part
that has to feel right for the rest to be worth building.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestsize:xlNew subsystem, or an open design question that needs a spec first

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions