Skip to content

Edit voro.toml settings by selection on the Config screen, dispatch cap first - #182

Merged
MJohnson459 merged 1 commit into
mainfrom
config-settings-list
Aug 20, 2026
Merged

Edit voro.toml settings by selection on the Config screen, dispatch cap first#182
MJohnson459 merged 1 commit into
mainfrom
config-settings-list

Conversation

@MJohnson459

Copy link
Copy Markdown
Contributor

The Config screen bound a letter per value — V for the default viewer, A for
the default agent — and max_running, the one queue option with no TUI surface
at all, was about to take a third. This turns the screen into a list of settings
you select, with one key that edits whatever is under the selection, and makes
the dispatch cap its first new setting.

What changed. A Settings list now sits between the agents pane and the
viewers: default agent, default viewer, dispatch cap, each showing the value in
force and where it came from — (voro.toml) where the file names the key, and
the rule Voro fell back to where it does not (first agent found on PATH, the only viewer configured, voro's default). The provenance is what the resolved
value alone cannot say, since an operator's cap of 5 and Voro's own default of 5
read identically. A flat App::config_rows (ConfigRow::Setting/Viewer) holds
the settings and the viewers as one selectable space, exactly as cockpit_rows
does for the cockpit, so config_sel runs continuously over both lists, exactly
one highlight is ever drawn, and Hit::ViewerRow becomes Hit::ConfigRow
indexing the same space so a click in either list lands the selection.

e/⏎ route through one activate_config_row(): the two defaults open the
pickers V/A used to open, the cap opens a new Mode::EditMaxRunning numeric
entry pre-filled with the cap in force, a user viewer opens the viewer form, and
a built-in viewer keeps today's refusal naming a. a and d stay keys —
adding acts with nothing selected and deleting is destructive, neither being an
edit of a variable — and d on a setting is refused pointing at ⏎. V and A
are unbound; the key line, the ? map and DESIGN.md §9's case-convention
exception list all drop them, shrinking CASE_EXCEPTIONS from seven to five.

The cap is written by a new voro-core::config_edit::set_max_running, through
the same load_doc/write_doc pair as every other edit, so comments and
surrounding content survive; it refuses a negative count in the loader's own
sentence, now factored into agent::negative_max_running so the two surfaces
cannot drift. 0 stays legal and keeps its meaning. The save calls refresh()
like delete_selected_viewer does, so raising the cap while the queue reads
⏸ dispatch at capacity (n/n running) restores the dispatch rows on the same
keypress. AgentsConfig now keeps max_running as the raw Option<i64> and
exposes max_running_from_file, default_agent_from_file and
default_viewer_from_file for the provenance column, rather than the TUI
re-reading the file.

DESIGN.md is updated in prose in the same change: §5 gains the settings list, its
provenance rule and the cap's semantics; §7 notes the cap is now set on the
screen as well as in the file; §9's Config paragraph explains selection-not-keys
and why, and both case-convention sentences lose their Config-screen clauses.
CHANGELOG has an entry under Unreleased/Changed.

How it was verified. cargo test --workspace (882 tests), cargo clippy --workspace --all-targets -- -D warnings and cargo fmt --all are clean. New
tests: the writer in voro-core (creates the file, preserves comments, accepts
0, refuses a negative in the loader's words); in app.rs the row list and its
selection arithmetic, ⏎ routing per row kind, d refused on a setting, the
provenance of every row with and without a file, and the cap save path writing,
refusing and re-gating the queue; in ui.rs the settings pane at 80x24 with both
provenances and exactly one highlight either side of the boundary. Existing
Config tests were updated where the index space moved.

Also driven live in tmux against a scratch store and config (verify skill):
j/k crossing from settings into viewers and back with one highlight; ⏎ opening
both pickers, the viewer form and the cap entry pre-filled; -3 and a typed
letter refused with the entry still open; esc leaving the file byte-identical;
saving 4 keeping the file's hand-written comment and turning ⏸ dispatch at capacity (1/1 running) back into two dispatch rows without a restart; V/A
inert; the built-in refusals and add/delete unchanged; and the parse-error branch
still drawing neither list.

@MJohnson459
MJohnson459 force-pushed the config-settings-list branch from 4491765 to e01b785 Compare August 19, 2026 10:33
The Config screen bound a letter per value — `V` for the default viewer,
`A` for the default agent — and `max_running`, the one queue option with
no TUI surface at all, was next in line for a third. That does not scale,
and it is the wrong model: a config screen is a list of settings you
select, with one key that edits whatever is under the selection.

The screen now carries a Settings list above the viewers — the default
agent, the default viewer, and the dispatch cap — each showing the value
in force and whether it came from `voro.toml` or is Voro's own default,
which the resolved value alone cannot say when the operator's number
happens to equal the default. A flat `config_rows` list holds the
settings and the viewers together, the way `cockpit_rows` does, so one
selection runs over both and ⏎ (or `e`) opens each row's own editor: the
pickers `V`/`A` used to open, the viewer form, and a new numeric entry
for the cap. `a` and `d` stay keys — `a` acts with nothing selected and
`d` is destructive, neither being an edit of the selected value — and `d`
on a setting is refused pointing at ⏎. `V` and `A` are unbound, which
shrinks the case-convention exception list from seven entries to five.

The cap is written by a new `config_edit::set_max_running` through the
same comment-preserving `toml_edit` pair as the rest, refusing a negative
count in the loader's own sentence (now factored into one place), and the
save refreshes, so raising the cap while the queue reads `⏸ dispatch at
capacity` restores the dispatch rows on that keypress. `AgentsConfig`
keeps `max_running` as the raw `Option<i64>` and exposes the three
from-file accessors the provenance column reads.

Verified with `cargo test --workspace`, clippy and fmt clean, and driven
live in tmux against a scratch store and config: selection crossing the
two lists with one highlight, both pickers and the cap entry opening on
⏎, a negative and a non-numeric entry refused with the form still open,
esc leaving the file untouched, a saved cap keeping the file's comments
and re-gating the queue in place, `V`/`A` inert, and the parse-error
branch unchanged.
@MJohnson459
MJohnson459 force-pushed the config-settings-list branch from e01b785 to 43ac8d9 Compare August 20, 2026 12:30
@MJohnson459
MJohnson459 merged commit 7f8e2b7 into main Aug 20, 2026
7 checks passed
@MJohnson459
MJohnson459 deleted the config-settings-list branch August 20, 2026 13:05
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