Skip to content

Add Tab-toggled fullscreen help overlay, trim startup tips - #852

Merged
mpfaffenberger merged 4 commits into
mainfrom
awtilso/PUP-352
Aug 23, 2026
Merged

Add Tab-toggled fullscreen help overlay, trim startup tips#852
mpfaffenberger merged 4 commits into
mainfrom
awtilso/PUP-352

Conversation

@AndrewTilson

@AndrewTilson AndrewTilson commented Aug 22, 2026

Copy link
Copy Markdown
Collaborator

What

Replaces the verbose startup tip spam with a single bold "Press Tab for help" hint. Pressing Tab on an empty input buffer now opens a fullscreen vi/vim-style help overlay; Tab on a non-empty buffer keeps its existing completion behavior unchanged.

Overlay contents

  • Dynamically assembled from the existing command registry and plugin-callback sources (no new command-registration framework) — Core, Configuration, Session, Tool, and Plugin/Private command sections stay in sync with /help automatically.
  • Curated static sections for things with no dynamic registry of their own: Keybindings, Modes & Passthrough, MCP & Plugins.
  • Fixed, deliberate section display order (Session → Keybindings → Core → Modes → Configuration → MCP/Plugins → Plugin/Private → Tools).
  • Vi-style navigation (j/k, gg/G), scrollable paging, Tab/Esc/q/Ctrl+C to close.
  • Defensive: a broken plugin's help callback can never crash the Tab key.

Verified

  • Confirmed via a programmatic diff that every command/alias/shell-passthrough row in /help is already present in the new overlay (both read from the same live registry + plugin-callback sources, so they can't structurally diverge.
  • Full test suite: 7668 passed, 28 skipped, 1 xpassed.
  • Reconciled cleanly with the double-Ctrl+C-to-quit feature that landed upstream in the same files during rebase — non-overlapping insertion point, no functional conflict, both features' own tests pass together.
  • Ruff clean.

Follow-up (separate PR)

Intent is for /help to eventually point at this same overlay/catalog instead of maintaining a second, separately-formatted flat-text renderer (command_handler.py's get_commands_help()). Content-wise this is already a non-issue — confirmed every command in /help today already appears in the new overlay, since both read from the same live command-registry + plugin-callback sources.

Known considerations for that follow-up (not addressed here, out of scope for this PR):

  • Headless/-p mode: execute_single_prompt() dispatches slash commands with no live REPL terminal running. /help will need a tty/interactive-mode check with a flat-text fallback so code-puppy -p "/help" in scripts/CI doesn't hang or crash trying to launch a fullscreen Application with no terminal to host it.
  • Scrollback/history: today's /help output goes through emit_info() and is captured in the conversation transcript/autosave. The fullscreen overlay is ephemeral chrome with no persistent trace — a deliberate product trade-off to make explicitly, not an incidental side effect.
  • Dead code: once /help fully switches over, get_commands_help() in command_handler.py (and its ~20 associated tests) becomes dead and should be removed rather than left dangling.
image image

@AndrewTilson
AndrewTilson marked this pull request as draft August 22, 2026 23:55
Andrew Tilson - awtilso added 3 commits August 22, 2026 19:14
Replaces the verbose startup tip spam with a single bold 'Press Tab
for help' hint. Pressing Tab on an empty input buffer now opens a
fullscreen vi/vim-style help overlay covering commands, keybindings,
modes, and MCP/plugins; Tab on a non-empty buffer keeps its existing
completion behavior.

- help_catalog.py: assembles overlay content from the existing command
  registry and plugin callback sources (no new registration framework)
  plus curated static sections for keybindings/modes.
- help_overlay.py: fullscreen renderer/launcher with vi-style
  navigation (j/k, gg/G), paging, and defensive error handling so a
  broken plugin callback can never crash the Tab key.
- Reconciled with the double-Ctrl+C-to-quit feature that landed
  upstream in the same files during rebase (non-overlapping insertion
  point, no functional conflict).

Ref: https://jira.walmart.com/browse/PUP-352
The SYSTEM message renderer escapes Rich markup in plain strings
before printing, so inline bold markup in the i18n string would show
up as literal brackets. Wrap it in a rich.text.Text with style=bold
instead, matching the private fork's implementation.
@AndrewTilson
AndrewTilson marked this pull request as ready for review August 23, 2026 00:20
Comments were written defensively and had drifted into narrating history
rather than explaining code: references to internal planning docs and
review sessions a reader has no access to, plus rationale repeated in
three places. Kept the non-obvious ones (the launch-race lock, the
AsyncMock requirement, why Ctrl+K is conditional) and cut the rest.

Tests: 10 of them mocked get_available_agents, which this module never
calls. Collapsed 8 single-shape parser tests and 2 column-width tests
into parametrized cases, and dropped an exception test wholly subsumed
by the lock-release test. Fixed a shadowed duplicate test name that was
silently preventing one lock test from running at all.
@mpfaffenberger
mpfaffenberger merged commit 1614e06 into main Aug 23, 2026
3 checks passed
@AndrewTilson
AndrewTilson deleted the awtilso/PUP-352 branch August 23, 2026 01:32
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.

2 participants