feat: delete the curses TUI and the console layer that only it could open (#541) - #554
Merged
Conversation
…open (#541) The last issue in the Web UI milestone. `keel tui` is gone, and with it the eight console modules that were reachable from nowhere else. `keel/commands/` goes from 24,709 lines to 13,606; the whole change is +297 / -23,448. ── THE ISSUE SAID 9,432 LINES, AND THE REAL NUMBER IS THE FINDING ───────────── "`tui.py` imports from `keel.commands.{activity,admission,status}` -- it is a front-end OVER the shared report builders, not their owner." True about the web UI, and half the picture about the module: nine modules imported FROM `tui.py` (`ScreenLine`, `_blank`, `_message_style`, `CTRL_C_DISCLOSURE`, `_market_session_style`, `_human_dt`), and the whole console layer sat on them. Then the decisive fact: there is no `keel console` command. The console was reachable only from inside the dashboard. Deleting `tui.py` alone would have left 6,009 lines of source and 8,276 of tests that nothing could open -- still type-checked, still pinned, still maintained. Every runtime import of the console layer from outside itself was checked. There was exactly one: `keel/mcp/tools.py` reading the research corpora. Those four things are now `keel/corpus.py`, moved rather than reimplemented, so the MCP server reads exactly what the console read. Everything else that looked like a dependency was prose in a comment. ── GATE 2: ENUMERATED, NOT ASSUMED ──────────────────────────────────────────── `keel capabilities` listed eleven actions. Seven were `[cli]`. One was `[tui]` and four were `[console]`; each named the CLI command it mirrored, and every one of those commands is still here. **No capability became unreachable.** The registry is seven rows now, all `[cli]`, all behind the typed terminal gate, and that is a cleaner statement than the mix it replaced: every capability increase in this build is a CLI command run by a person at a terminal, and the browser can perform none of them -- a property of the server, which implements no verb that would reach one. One absence is worth stating because it looks like a regression and is not. `keel rules promote --force` skips the whole gauntlet and is NOT in the registry. It never was: this is an inventory of GATE CALL SITES, and that flag has none -- `rules.py` records why ("a flag the operator already typed at a terminal"). The console's retry flow DID gate it, which is why a force-promote row existed; the row described the console's ceremony, not the CLI's flag. ── DEAD CODE THAT HAD ALREADY BECOME WRONG ──────────────────────────────────── `update.py` still carried `build_relaunch_argv`/`relaunch_tui` -- an `execv` for one caller, the console's update view. With no argv to carry they rebuilt `[keel, "tui"]`, so a relaunch would have exec'd into `No such command 'tui'`, AFTER installing the new build. Deleted, and `keel update` now names `keel serve` as the thing to restart. ── WHAT MOVED RATHER THAN DIED ──────────────────────────────────────────────── The runbook's TUI-console section is now the browser's, and `tests/test_runbook_console.py` pins that one instead -- same job, new subject, including the two facts most expensive to get wrong: what the browser cannot do, and where a headless operator goes (`ssh -L 8765:127.0.0.1:8765`). `test_console_thinness.py` globbed `*console*.py`; it is `keel/web/*.py` alone now, and asserts the console stems are ABSENT so a module cannot reappear under a familiar filename outside the rules. `windows-curses` needed no removal: it was never declared. The desktop PRD said so, and no `import curses` remains anywhere. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01T6yA5khYnJ2qzheArRToQ2
4 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #541. Last issue in the Web UI milestone.
keel tuiis gone, and with it the eight console modules reachable from nowhere else.keel/commands/: 24,709 → 13,606 lines. Whole change:+297 / −23,448.The issue estimated 9,432 lines. The real number is the finding.
The issue reasoned: "
tui.pyimports fromkeel.commands.{activity,admission,status}— it is afront-end over the shared report builders, not their owner." True about the web UI, and half
the picture about the module: nine modules imported from
tui.py(ScreenLine,_blank,_message_style,CTRL_C_DISCLOSURE,_market_session_style,_human_dt), and the whole consolelayer sat on them.
Then the decisive fact: there is no
keel consolecommand. The console was reachable only frominside the dashboard. Deleting
tui.pyalone would have left 6,009 lines of source and 8,276 oftests that nothing could open — still type-checked, still pinned, still maintained.
I checked every runtime import of the console layer from outside itself. There was exactly one:
keel/mcp/tools.pyreading the research corpora. Those four things are nowkeel/corpus.py, movedrather than reimplemented, so the MCP server reads exactly what the console read. Everything else
that looked like a dependency —
rules.py,withdrawals.py,update.py,brokers.py,cli.py—was prose in a comment.
Gate 2: enumerated, not assumed
keel capabilitieslisted eleven actions. Seven[cli], one[tui], three[console]— and eachof the four non-CLI rows named the CLI command it mirrored. Every one of those commands is still
here (
keel autonomy on,keel resume/resume-entries,keel withdrawals attest --enabled,keel rules promote --force). No capability became unreachable.The registry is seven rows now, all
[cli], all behind the typed terminal gate — a cleanerstatement than the mix it replaced: every capability increase in this build is a CLI command run by
a person at a terminal, and the browser can perform none of them.
One absence looks like a regression and is not.
keel rules promote --forceskips the wholegauntlet and is not in the registry. It never was: this is an inventory of gate call sites, and
that flag has none —
rules.pyrecords why ("the CLI's--forceis a flag the operator alreadytyped at a terminal"). The console's retry flow did run a typed gate before calling with
force=True, which is why a force-promote row existed at all; the row described the console'sceremony, not the CLI's flag, and it went with the console. Flagging it because the registry now
lists no bypass, and that is a fact about the registry's scope rather than about the bypass.
Dead code that had already become wrong
update.pystill carriedbuild_relaunch_argv/relaunch_tui— anexecvwhose only caller wasthe console's Account-menu update view. With no argv to carry they rebuilt
[keel, "tui"], so arelaunch would have exec'd into
Error: No such command 'tui'— after installing the newbuild. Deleted, and
keel updatenow nameskeel serveas the thing to restart.Verification
ruff,mypyand the full suite are green (4262 passed, 3 skipped) — the suite is smaller because11,892 lines of tests for deleted code went with it, and nothing is skipped that used to run.
Smoked against a snapshot of the live 155 MB database:
keel tui→ "No such command";keel statusunchanged;keel capabilities→ seven;keel serveopens and all seven views renderwith no console errors; and
keel.corpusreads the research corpus the MCP server depends on(3 documents, 312 lines from the first).
What moved rather than died
tests/test_runbook_console.pypinsthat one — same job, new subject, including the two facts most expensive to get wrong: what the
browser cannot do, and where a headless operator goes (
ssh -L 8765:127.0.0.1:8765).test_console_thinness.pyglobbed*console*.py; it iskeel/web/*.pyalone now, and assertsthe console stems are absent so a module cannot reappear under a familiar filename outside
the rules.
test_brokers.pylost nine Venues-browser rendering tests; the service they rode on is untouchedand still covered, and
keel brokers listis the surface that remains.windows-cursesneeded no removal — it was never declared (the desktop PRD said so), and noimport cursesremains anywhere.🤖 Generated with Claude Code
https://claude.ai/code/session_01T6yA5khYnJ2qzheArRToQ2