Skip to content

Add a TUI Config screen for voro.toml: view agents, manage viewers and defaults#93

Merged
MJohnson459 merged 1 commit into
mainfrom
feat/config-screen
Jul 26, 2026
Merged

Add a TUI Config screen for voro.toml: view agents, manage viewers and defaults#93
MJohnson459 merged 1 commit into
mainfrom
feat/config-screen

Conversation

@MJohnson459

Copy link
Copy Markdown
Contributor

Adds the TUI Config screen for voro.toml plus voro viewer add/remove, closing the gap where Voro could read voro.toml but never show or edit it.

What changed

  • voro-core::config_edit — one comment-preserving write helper (new toml_edit dependency) that all edits route through: add/edit/delete a viewer, set default_viewer/default_agent. It preserves existing content, formatting, and comments (only the touched key changes), creates a missing file, and validates non-empty name/command, duplicate names, and the whitespace/: name guard, with a {path}-missing warning. projects_referencing_viewer backs the referenced-by refusal.
  • TUI Config screen — fourth screen in the cycle (Cockpit → Tasks → Projects → Config; Tab or 4). Agents are read-only with provenance and the default marked (editing a built-in = a wholesale override table, deliberately deferred). Named viewers are editable: a add (name+command form), e/⏎ edit command, d delete, V/A pick default viewer/agent. Deleting a viewer a project's review_action names is refused with the projects named; deleting the default clears default_viewer. The anonymous [viewer] table shows read-only. A parse failure surfaces on-screen. The config view reloads after every write.
  • Quick path — the projects screen review-action picker grows a "new viewer…" entry opening the same add form, then pins the project to the created viewer.
  • CLIvoro viewer add <name> <cmd> and voro viewer remove <name>, sharing the helper and the referenced-by refusal, so viewer list gains its inverse. HELP updated.
  • DESIGN.md — §5 notes the file is now machine-edited comment-preservingly by the TUI/CLI; §9 documents the Config screen and the quick path.

Verification

  • cargo test --workspace (416 tests) and cargo clippy --workspace --all-targets -- -D warnings clean; cargo fmt applied.
  • New tests: config_edit unit tests (missing file, comment/format preservation, duplicate/empty/bad-name rejections, edit, default-clearing on delete, default setters); CLI viewer add/remove round-trip through viewer list incl. referenced-by refusal; TUI key-driven add/edit/default/delete, referenced-viewer refusal, and the review-action "new viewer…" quick path; a Config-screen render smoke test.
  • Manual CLI smoke run against a scratch config exercised add, the {path} warning, duplicate refusal, referenced-by refusal naming the project, and repoint-then-remove — confirming comments/formatting survived on disk.

Branch feat/config-screen (committed locally in the bg worktree; not pushed — run voro pr 183 to open the PR).

Voro could read voro.toml but never show or change it: viewers,
default_viewer, and default_agent were hand-edit-only, and first-time
viewer setup dropped the operator out of the TUI. This adds the editing
surface.

A new voro-core::config_edit module rewrites voro.toml through toml_edit
so a machine write preserves existing content, formatting, and comments,
touching only the changed key. It is the single helper the TUI and CLI
share: add/edit/delete a viewer, set default_viewer/default_agent, with
non-empty-name/-command and duplicate-name validation, a {path} warning,
and creation of a missing file. toml_edit is a new voro-core dependency,
justified by the comment-preserving requirement.

The TUI gains a fourth screen (Cockpit -> Tasks -> Projects -> Config,
key 4). It renders the effective agents read-only with provenance and
the default marked (editing a built-in means a wholesale override table,
deferred), and the named viewers editably: add form, edit command,
delete, and pick-from-list defaults. Deleting a viewer a project's
review_action names is refused with the projects named; deleting the
default clears default_viewer. The projects screen's review-action
picker grows a "new viewer..." entry opening the same form and pinning
the project to the viewer it creates.

CLI counterpart: voro viewer add/remove, sharing the write helper and
the referenced-by refusal, so viewer list gains its inverse.

Verified: cargo test --workspace (416 tests) and clippy clean; new unit
tests cover the write helper (missing file, comment preservation,
duplicate/empty/referenced rejections, default clearing) and CLI/TUI
round-trips; a manual CLI smoke run exercised add/list/duplicate/
referenced-refusal/repoint-remove with comments preserved on disk.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
Claude-Session: https://claude.ai/code/session_017jn5FdvFmkaSac4nKQKwWp
@MJohnson459
MJohnson459 merged commit 4cb69ed into main Jul 26, 2026
6 checks passed
@MJohnson459
MJohnson459 deleted the feat/config-screen branch July 26, 2026 08:58
MJohnson459 added a commit that referenced this pull request Jul 26, 2026
main does not compile its test targets. #95 removed DispatchCtx's
session_task_id field; #93 was branched before that landed and added two
test-only DispatchCtx literals that still assign it. Each PR was green on
its own base, and because both sites are inside #[cfg(test)] modules
`cargo build --workspace` still passes — only `cargo test` and
`cargo clippy --all-targets` fail, so the breakage reached main unnoticed.

Delete the two assignments, matching the neighbouring literal in the same
test module that already omits the field. No behaviour change.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
Claude-Session: https://claude.ai/code/session_0146m6RCmCo8i64XpfXSqEJ4
MJohnson459 added a commit that referenced this pull request Jul 26, 2026
* Drop the stale session_task_id from two test DispatchCtx literals

main does not compile its test targets. #95 removed DispatchCtx's
session_task_id field; #93 was branched before that landed and added two
test-only DispatchCtx literals that still assign it. Each PR was green on
its own base, and because both sites are inside #[cfg(test)] modules
`cargo build --workspace` still passes — only `cargo test` and
`cargo clippy --all-targets` fail, so the breakage reached main unnoticed.

Delete the two assignments, matching the neighbouring literal in the same
test module that already omits the field. No behaviour change.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
Claude-Session: https://claude.ai/code/session_0146m6RCmCo8i64XpfXSqEJ4

* Render a markdown subset in TUI task bodies

Task bodies are written in markdown but the popup and detail pane rendered
them as plain text. Add a hand-rolled renderer (matching the editor.rs
no-dependency precedent) that styles a small subset: **bold**, `inline
code`, fenced code blocks, #-### headings, and -/* bullets.

The logic lives in one pure function, markdown::body_lines, isolated behind
a module boundary so a real parser could be swapped in later. Both render
sites in ui.rs call it in place of the previous lines().map(...). Anything
the renderer does not understand — including malformed markup like an
unclosed fence or an unmatched ** — degrades to literal text so content is
never dropped or mangled.

Presentation only: no voro-core, schema, or storage changes. Scroll
measurement in draw_detail keeps working since it operates on the styled
lines. Verified with cargo test/clippy and by eyeballing both surfaces
against a scratch DB (ANSI capture confirms bold/cyan/dim/bullet styling).

Co-Authored-By: Claude Opus 4.8 <[email protected]>
Claude-Session: https://claude.ai/code/session_0146m6RCmCo8i64XpfXSqEJ4

---------

Co-authored-by: Claude Opus 4.8 <[email protected]>
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