Skip to content

Polished UI, fixes, extra features for multiservice management#1

Closed
andkirby wants to merge 21 commits intoTawe:mainfrom
andkirby:codex-tui-polish
Closed

Polished UI, fixes, extra features for multiservice management#1
andkirby wants to merge 21 commits intoTawe:mainfrom
andkirby:codex-tui-polish

Conversation

@andkirby
Copy link
Copy Markdown

Hi there,

It's quite an upgrade... :D

It has been migrated to Bubbles 2.1, with numerous updates to the UI, multiservice management, and mouse support (click, scroll). The UI is now quite solid, as it was previously jumpy.
Testing was performed only in iTerm2/macOS Terminal.

Please feel free to test it from my repository. I hope I haven't broken anything from before.

Here is full list for 0.2.0.

  • Added multi-service start, stop, and restart commands with quoted glob pattern support so multiple managed services can be controlled in one invocation
  • Added name:port targeting for managed services so ambiguous service names can be disambiguated from the CLI
  • Extracted the Bubble Tea UI into pkg/cli/tui so the TUI logic is isolated from the main CLI package
  • Added mouse row selection, mouse wheel scrolling, and viewport-focused navigation so table and log interaction works without keyboard-only control
  • Added centered modal overlays for help and confirmation dialogs so help and destructive actions no longer replace the main table view
  • Replaced the ad hoc search field with Bubbles text input so filter editing behaves like a real input control and updates inline in the footer
  • Simplified the table chrome by moving counts into headers, bolding the active sort column, and removing redundant status text from the top of the screen
  • Fixed Enter handling so the top section opens logs and the bottom section starts the selected managed service without being swallowed by confirm bindings
  • Fixed log rendering so the header is separated from the first log line and the viewport uses the actual remaining terminal height
  • Fixed stale table layout offsets so footer spacing, viewport sizing, and mouse hit-testing stay aligned after the filter moved into the footer
  • Added shared keymap-driven help text with Bubble components so visible shortcuts and actual bindings stay in sync
  • Added clearer TUI and quickstart documentation so the current footer filter, modal help, mouse controls, batch commands, and logs header behavior are documented
  • Bumped the application version to 0.2.0 and rendered the version in the TUI header in muted gray
image image

andkirby added 21 commits March 12, 2026 17:18
Add comprehensive state transition tests for TUI model including:
- Navigation (Tab focus switching, Escape to return)
- Mode switching (search, help)
- Key sequences (multi-step user flows)
- View rendering (table and help output)

Increases pkg/cli test coverage from 2.4% to 32.9%.

Tests verify model state transitions without requiring terminal UI.
…and name:port disambiguation

- Add batch start/stop/restart commands accepting multiple service names
- Support glob pattern matching ('service*', '*-api', '*web*')
- Add name:port format for disambiguation (web-api:3000)
- Add parser module with fallback lookup for name:port identifiers
- Update documentation with proper quoting examples

Files:
- pkg/cli/parser.go: New name:port parser with fallback logic
- pkg/cli/parser_test.go: Comprehensive parser unit tests
- pkg/cli/commands.go: Updated all commands to use parser
- cmd/devpt/main.go: Updated help text
- README.md, QUICKSTART.md: Added name:port examples

Related: DEVPT-001
Implement enhanced viewport interactions for logs viewer:
- Mouse click navigation (gutter jump, text centering)
- Keyboard shortcuts for highlight cycling (n/N keys)
- Match counter display in footer (e.g., "Match 3/15")
- Terminal resize persistence for highlight state

Changes:
- Add calculateGutterWidth() helper for viewport layout
- Add highlightMatches[] and highlightIndex state fields
- Add mouse click handling for gutter and text areas
- Add keyboard event handling for n/N highlight navigation
- Extend footer rendering with match counter
- Add comprehensive test suite (17 tests, all passing)

Test coverage:
- Mouse click navigation (gutter, text, edge cases)
- Highlight cycling (forward/backward, wrap behavior)
- Match counter display (formatting, bounds)
- Resize persistence (highlight state preservation)
- Viewport integration (updates, sizing, content flow)
…view

When switching from logs/debug mode back to table view, the viewport was
not being properly redrawn because the tableContentHash optimization was
preventing SetContent from being called. The viewport would continue to
display stale logs content instead of the table content.

The fix invalidates tableContentHash in all mode transition paths from
logs/debug mode to table mode, forcing the viewport content to be
refreshed on the next render cycle.
Cloudflared tunnels are commonly used for development to expose local
servers publicly. Without this pattern, cloudflared processes would be
filtered out during process scanning, causing managed services that use
cloudflared to rely solely on the IsRunning fallback check.

This could cause flickering (appearing/disappearing) if the process
detection was inconsistent. Now cloudflared processes are properly
detected and matched to their managed service definitions.
Previously, processes were filtered by dev patterns BEFORE matching to
managed services. This caused non-dev commands (like cloudflared, custom
scripts, etc.) to be filtered out, making their managed services rely
solely on the IsRunning fallback check - which could cause flickering.

Now the filter receives managed service PIDs upfront and always keeps
those processes regardless of whether they match dev patterns. This
ensures stable visibility for any managed service, no matter what
command it runs.

UX improvement: Users can add any process as a managed service and it
will always be visible in the TUI without flickering.
Cherry-picked 52c426a with conflict resolution.

The original fix ensures command mode (:) and search mode (/) handle
all key input at the top of the Update function, preventing keys like
'b', 'q', 's', 'n' from being intercepted by other handlers.

Conflicts resolved:
- tui.go: Combined command/search mode handlers (from origin) with
  logs/logsDebug mode handlers (from our branch) at top of Update
- tui_key_input_test.go: Updated to use pointer receiver (*topModel)
  to match our codebase convention
- tui_ui_test.go: Updated hint text from 'Esc or b' to 'Esc to back'
- Selected line in running section shows gray when managed section has focus
- Selected line in managed section shows gray when running section has focus
- Single-click changes selection without switching focus (so gray is visible)
- Double-click or Tab still switches focus and performs actions
@Tawe
Copy link
Copy Markdown
Owner

Tawe commented Mar 29, 2026

This is awesome. There’s a lot of amazing improvements here, especially around the TUI and multi-service workflows, really appreciate the effort that went into this.

While going through it, it helped surface an underlying issue in DevPT around how services are matched to running processes. We were already leaning a bit too much on LastPID, and this PR makes that path more central, which exposed the problem more clearly.

I’ve fixed that on main by tightening the matching so PID is treated as a hint rather than identity, and only trusted when it lines up with stronger signals like project root / CWD.

There’s also a small follow-on in the name:port flow, once something resolves to a service, registry updates should go through the canonical service name rather than the raw name:port string. That should align naturally once this is rebased.

Before I can merge this, I’ll need the PR rebased on top of the updated matching behaviour. Once that’s done, I’d love to get this merged.

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