Plan A from docs/superpowers/plans/2026-05-19-post-slm-unlock.md.
Small local SLMs (<=16k context) waste ~1500 tokens per turn on the
full tool catalogue. Two-stage routing replaces round-1 tools with a
single synthetic select_category schema; round-2+ sends only the
selected category's real tool schemas plus select_category for
re-selection.
- internal/tool/category.go: Category type, optional Categorized
interface, CategoryOf() with meta fallback. fs.read/fs.ls -> read,
fs.write/fs.edit -> write, fs.glob/fs.grep -> search, bash -> exec.
- internal/engine/twostage.go: synthetic select_category tool,
intercept helper, per-turn selectedCategory state under e.mu.
- Engine round 1 forces ToolChoiceRequired so SLMs don't fall back to
prose. State resets at the top and end of every runLoop.
- Activates automatically on a forced local arm with ContextWindow
<=16384, or via [router].force_two_stage TOML key.
- Integration test drives a 3-round trip and asserts: round 1 emits
exactly one schema (synthetic) with ToolChoiceRequired, round 2
contains only write-category schemas + select_category, real
fs.write executes. Invalid-category fallback round-trips back to
round-1 mode.
- /shell [cmd]: launch user's $SHELL via tea.ExecProcess (PTY handoff)
hands terminal to the shell and restores TUI on exit.
/shell <cmd> runs that command in the shell directly.
Detects $SHELL > $COMSPEC > /bin/sh|powershell.exe in order.
- bash tool: detect interactive commands before execution
Prefix-interactive: sudo, ssh, passwd, vim/vi/nano, less/more,
htop/top, mysql/psql, ftp/sftp, git push.
Exact-interactive (REPL): python3/python/node/irb/iex/ghci/julia.
Returns a tool result with interactive=true metadata and a hint to
use /shell instead of hanging or erroring.
- completions: add /shell to builtin command list
- help: document /shell [cmd]