Skip to content

refactor: fold REPL slash commands into one dispatcher#107

Merged
tgockel merged 1 commit into
trunkfrom
0084-repl-command-dispatcher
Jul 13, 2026
Merged

refactor: fold REPL slash commands into one dispatcher#107
tgockel merged 1 commit into
trunkfrom
0084-repl-command-dispatcher

Conversation

@tgockel

@tgockel tgockel commented Jul 13, 2026

Copy link
Copy Markdown
Owner

Repl::run/run_with carried one typed callback pair per slash command (on_tools, on_reset, on_sidecar), so adding /sidecar grew the generic signature by two type params and touched every test call site. The per-command callbacks collapse into a single on_command dispatcher: FnMut(String, Vec) -> Future<Option>, where None means "unknown command". Only /help and /quit stay built in; each caller command's name, help line, and semantics now live together in run.rs (the REPL_COMMANDS table beside the dispatcher match).

/help is composed from structured HelpEntry values: the Repl sandwiches caller entries between its built-in /help and /quit lines and pads one column across all of them. Production output is byte-identical to the deleted HELP_TEXT, locked by a unit test against the old literal. The unknown-command notice echoes the raw post-/ text as typed, and the dispatcher keeps /tools foo (and friends) unknown by guarding on empty args, so observable behavior is unchanged. Two edge quirks of the old exact-match arms are deliberately dropped: trailing-whitespace commands (/quit ) now execute and tab-separated /sidecar args now parse.

Two altitude notes from the 0081 review land in the same pass:

  • llm::RebuildingAgent owns the built RigAgent plus its rebuild recipe (resolved agent, cache root, registry), exposing extend_tools / tools / run_turn with the dirty-flag rebuild inside run_turn. This replaces the Rc<RefCell<Rc>> + Rc<Cell> + shared tool-vec plumbing that run.rs threaded through its closures.

  • session_setup::SessionRuntime groups the four teardown-bound handles (watcher, mcp_arcs, network, containers; field order mirrors teardown order). teardown now consumes it, and the run/mcp commands assemble it via SessionRuntime::new instead of threading four parallel &mut handles into the REPL state.

Found while designing (filed, not fixed): SIGINT during a turn drops the mem::take'n history before writeback, silently emptying the conversation -- plan/next/repl-interrupt-history-loss.md.

Summary

What does this change, and why?

Checklist

  • cargo fmt --all -- --check passes
  • cargo clippy --workspace --all-targets -- -D warnings is clean
  • cargo test --workspace passes
  • Docs in doc/ updated if behavior changed (mdbook build still clean)
  • CHANGELOG updated for user-visible changes

Notes for reviewers

Anything worth calling out -- tricky bits, follow-ups, or intentionally out-of-scope items.

Repl::run/run_with carried one typed callback pair per slash command
(on_tools, on_reset, on_sidecar), so adding /sidecar grew the generic
signature by two type params and touched every test call site. The
per-command callbacks collapse into a single on_command dispatcher:
FnMut(String, Vec<String>) -> Future<Option<String>>, where None means
"unknown command". Only /help and /quit stay built in; each caller
command's name, help line, and semantics now live together in run.rs
(the REPL_COMMANDS table beside the dispatcher match).

/help is composed from structured HelpEntry values: the Repl sandwiches
caller entries between its built-in /help and /quit lines and pads one
column across all of them. Production output is byte-identical to the
deleted HELP_TEXT, locked by a unit test against the old literal. The
unknown-command notice echoes the raw post-/ text as typed, and the
dispatcher keeps /tools foo (and friends) unknown by guarding on empty
args, so observable behavior is unchanged. Two edge quirks of the old
exact-match arms are deliberately dropped: trailing-whitespace
commands (/quit ) now execute and tab-separated /sidecar args now
parse.

Two altitude notes from the 0081 review land in the same pass:

- llm::RebuildingAgent owns the built RigAgent plus its rebuild recipe
  (resolved agent, cache root, registry), exposing extend_tools /
  tools / run_turn with the dirty-flag rebuild inside run_turn. This
  replaces the Rc<RefCell<Rc<RigAgent>>> + Rc<Cell<bool>> + shared
  tool-vec plumbing that run.rs threaded through its closures.

- session_setup::SessionRuntime groups the four teardown-bound handles
  (watcher, mcp_arcs, network, containers; field order mirrors
  teardown order). teardown now consumes it, and the run/mcp commands
  assemble it via SessionRuntime::new instead of threading four
  parallel &mut handles into the REPL state.

Found while designing (filed, not fixed): SIGINT during a turn drops
the mem::take'n history before writeback, silently emptying the
conversation -- plan/next/repl-interrupt-history-loss.md.
@tgockel tgockel merged commit 69dd13a into trunk Jul 13, 2026
6 checks passed
@tgockel tgockel deleted the 0084-repl-command-dispatcher branch July 13, 2026 01:35
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