Skip to content

feat: migrate interactive mode to Terminal.Gui TUI framework#242

Merged
joshsmithxrm merged 3 commits intomainfrom
feature/tui-enhancements
Jan 7, 2026
Merged

feat: migrate interactive mode to Terminal.Gui TUI framework#242
joshsmithxrm merged 3 commits intomainfrom
feature/tui-enhancements

Conversation

@joshsmithxrm
Copy link
Owner

Summary

  • Switch TUI framework from Spectre.Console + raw Console to Terminal.Gui 1.19
  • Document multi-UI platform architecture with 3 new ADRs (0024-0026)
  • Create TUI application structure with SqlQueryScreen integrated with ISqlQueryService
  • Add 23 unit tests for QueryResultConverter value formatting logic

Architecture Changes

This PR establishes PPDS as a multi-interface platform where:

  • CLI commands use Spectre.Console for output
  • TUI (ppds -i) uses Terminal.Gui for full application experience
  • VS Code extension will communicate via ppds serve RPC

New ADRs

ADR Title Purpose
0024 Shared Local State All UIs access ~/.ppds/ via Application Services
0025 UI-Agnostic Progress IProgressReporter pattern for long operations
0026 Structured Error Model PpdsException hierarchy with ErrorCode/UserMessage

New Files

src/PPDS.Cli/Tui/
├── PpdsApplication.cs          # Entry point with InteractiveSession lifecycle
├── MainWindow.cs               # Main menu with File/Tools/Help navigation
├── Screens/
│   └── SqlQueryScreen.cs       # SQL query with service integration
└── Views/
    ├── QueryResultConverter.cs # Testable value formatting logic
    └── QueryResultsTableView.cs # TableView wrapper with pagination

Test plan

  • All 1146 CLI unit tests pass
  • 23 new tests for QueryResultConverter
  • Build succeeds on all target frameworks (net8.0, net9.0, net10.0)
  • Manual test: ppds -i launches Terminal.Gui TUI
  • Manual test: SQL Query screen executes queries against Dataverse

Related Issues

Addresses issues #204, #205, #206, #207, #208, #234 (TUI enhancements epic)

🤖 Generated with Claude Code

@gemini-code-assist
Copy link

Summary of Changes

Hello @joshsmithxrm, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request undertakes a significant refactoring of the interactive mode within the PPDS CLI by transitioning its underlying UI framework to Terminal.Gui. This foundational change not only enhances the interactive user experience but also establishes a clear architectural separation between UI components and core application services. It introduces a functional interactive SQL query interface and formalizes a multi-UI platform strategy through new Architecture Decision Records, promoting consistency and reusability across diverse frontends like the CLI, TUI, and a planned VS Code extension.

Highlights

  • TUI Framework Migration: The interactive mode's UI framework has been migrated from Spectre.Console to Terminal.Gui 1.19, providing a more robust foundation for future interactive features.
  • Multi-UI Architecture Formalization: New Architecture Decision Records (ADR-0024, ADR-0025, ADR-0026) have been introduced to formalize principles for shared local state, UI-agnostic progress reporting, and a structured error model across CLI, TUI, and future VS Code extension interfaces.
  • Interactive SQL Query Screen: A new interactive SQL query screen has been implemented within the Terminal.Gui TUI, allowing users to execute queries against Dataverse and view results in a paginated table.
  • Query Result Handling & Display: Utilities for converting query results to a DataTable and formatting various data types for display have been added, alongside a custom QueryResultsTableView component that supports pagination, cell copying, and direct opening of Dataverse records.
  • New Unit Tests: 23 new unit tests were added to validate the QueryResultConverter's value formatting logic and URL generation, ensuring data presentation accuracy.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request is a major feature contribution, migrating the interactive mode to the Terminal.Gui framework. The changes are extensive, including the new TUI application structure, supporting views and screens, new architectural decision records (ADRs), and unit tests. The architecture with a multi-interface platform in mind is well-thought-out and documented in the ADRs.

My review focuses on the new TUI implementation. I've identified several high-severity issues related to asynchronous programming and UI threading best practices that should be addressed:

  • Cancellation: The CancellationToken from the command host is ignored, making async operations during startup and execution un-cancellable, aligning with the rule on integrating cancellation tokens.
  • Threading: UI elements are updated from background threads without marshalling to the main UI loop, which can cause instability. Also, a fire-and-forget async call in a constructor can lead to race conditions.
  • Concurrency: The 'load more' functionality is susceptible to race conditions from concurrent executions.
  • Disposal: There are sync-over-async calls during disposal which can lead to deadlocks.

I've also included a medium-severity comment about ensuring culture-invariant formatting for numeric values. Addressing these points will significantly improve the robustness and stability of the new TUI.

@codecov
Copy link

codecov bot commented Jan 7, 2026

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR migrates the interactive mode from Spectre.Console to Terminal.Gui 1.19, establishing PPDS as a multi-interface platform with comprehensive TUI capabilities. The change introduces three new ADRs (0024-0026) that define the architecture for supporting multiple UIs (CLI, TUI, VS Code extension) with shared services and local state management.

Key changes:

  • TUI framework migration: Replaces Spectre.Console interactive mode with Terminal.Gui full-screen application
  • Architecture documentation: Three ADRs establish patterns for shared state (ADR-0024), progress reporting (ADR-0025), and error handling (ADR-0026)
  • Test coverage: 23 new unit tests for QueryResultConverter value formatting logic

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
src/PPDS.Cli/Tui/PpdsApplication.cs Entry point for Terminal.Gui TUI with InteractiveSession lifecycle management
src/PPDS.Cli/Tui/MainWindow.cs Main menu window with navigation to SQL Query and other planned features
src/PPDS.Cli/Tui/Screens/SqlQueryScreen.cs SQL query screen with ISqlQueryService integration, pagination, and keyboard shortcuts
src/PPDS.Cli/Tui/Views/QueryResultsTableView.cs TableView wrapper with pagination, clipboard copy, and browser integration
src/PPDS.Cli/Tui/Views/QueryResultConverter.cs Utility for converting QueryResult to DataTable with value formatting
tests/PPDS.Cli.Tests/Tui/Views/QueryResultConverterTests.cs Comprehensive unit tests for QueryResultConverter (23 tests)
src/PPDS.Cli/Commands/InteractiveCommand.cs Updated to launch PpdsApplication instead of previous interactive CLI
src/PPDS.Cli/PPDS.Cli.csproj Adds Terminal.Gui 1.19 package reference
docs/adr/0024_SHARED_LOCAL_STATE.md ADR defining ~/.ppds/ as single source of truth for all UIs
docs/adr/0025_UI_AGNOSTIC_PROGRESS.md ADR for IProgressReporter pattern for long operations
docs/adr/0026_STRUCTURED_ERROR_MODEL.md ADR for PpdsException hierarchy with ErrorCode/UserMessage
CLAUDE.md Updated with multi-UI architecture guidance, ADR references, and new rules
.claude/design.md New design document for TUI enhancements roadmap

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@joshsmithxrm
Copy link
Owner Author

Bot Review Response

Addressed the following findings in commit 82e4cdb:

Gemini Findings (Fixed)

Finding Resolution
cancellationToken ignored in InteractiveCommand Now passed to PpdsApplication.Run() and registered for shutdown
Sync-over-async in Dispose Added documentation explaining Terminal.Gui constraint; session disposal is fast
Fire-and-forget async in constructor Added .ContinueWith() error handler that updates UI on main thread
UI update from non-UI thread All async callbacks now use Application.MainLoop.Invoke()
Concurrent LoadMoreAsync calls Added _isLoadingMore guard flag
Culture-sensitive N2 format Dismissed - intentional for user-facing display

Code Scanning Findings (Fixed)

Finding Resolution
Generic catch clauses (5x) Replaced with specific InvalidOperationException and HttpRequestException
Missed Where (2x) Dismissed - foreach is clearer for DataRow creation pattern
Missed ternary (2x) Dismissed - if/else is more readable in these cases

joshsmithxrm and others added 3 commits January 6, 2026 23:25
Issues: #204, #205, #206, #207, #208, #234
Branch: feature/tui-enhancements
- Add Terminal.Gui 1.19 NuGet package for TUI rendering
- Create TUI application structure (PpdsApplication, MainWindow, SqlQueryScreen)
- Create QueryResultsTableView with pagination, copy, and URL features
- Extract QueryResultConverter for testable value formatting logic
- Update InteractiveCommand to launch Terminal.Gui app

Architecture documentation (ADRs):
- ADR-0024: Shared Local State Architecture (~/.ppds/ for all UIs)
- ADR-0025: UI-Agnostic Progress Reporting (IProgressReporter pattern)
- ADR-0026: Structured Error Model (PpdsException hierarchy)

Updates CLAUDE.md with Platform Architecture section explaining
the multi-interface platform (CLI, TUI, VS Code extension).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Pass cancellationToken from InteractiveCommand to PpdsApplication
- Register cancellation token to stop Terminal.Gui application
- Add proper error handling for fire-and-forget async in constructor
- Use Application.MainLoop.Invoke() for UI updates from async methods
- Add guard flag to prevent concurrent LoadMoreAsync calls
- Replace generic catch clauses with specific exceptions
  (InvalidOperationException, HttpRequestException)
- Add documentation comment explaining sync-over-async in Dispose

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@joshsmithxrm joshsmithxrm force-pushed the feature/tui-enhancements branch from 5a9d719 to dbf1972 Compare January 7, 2026 05:25
@joshsmithxrm joshsmithxrm merged commit e317e58 into main Jan 7, 2026
13 checks passed
@github-project-automation github-project-automation bot moved this from Todo to Done in PPDS Roadmap Jan 7, 2026
@joshsmithxrm joshsmithxrm deleted the feature/tui-enhancements branch January 7, 2026 05:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants