Implement Terminal.Gui.Cli library (Stage A) and migrate clet#176
Closed
tig wants to merge 13 commits into
Closed
Conversation
Comprehensive design document for extracting clet's hosting infrastructure into a reusable Terminal.Gui.Cli library. Key design decisions: - Library owns the TG lifecycle (commands never call Application.Create) - No reflection; NativeAOT from day one - Registry is instances, not types (dynamic, DI-friendly) - Extensible CommandRunOptions with repeatable option accumulation - OpenCLI-conformant structured introspection (--opencli flag) - help/agent-guide as registered IViewerCommand implementations - IViewerCommand.RenderCatAsync for --cat dispatch without TUI - 3-part AI agent discovery model (llms.txt, agent-guide, --opencli) - Engineering Constitution with 8 architectural rules (C1-C8) - 4-stage implementation strategy (prove in clet, rewrite in gui-cs/cli) Honestly acknowledges extraction costs: ArgParser must be rewritten from scratch (data-driven vs clet's hard-coded flag enumeration). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6851e39740
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Implement the core Terminal.Gui.Cli class library as specified in specs/terminal-gui-cli.md §13 Stage A. The library extracts and generalizes clet's hosting infrastructure into a reusable package. Key components: - Core abstractions: ICliCommand, ICliCommand<T>, IViewerCommand, CommandRunOptions, CommandResult, ICommandRegistry - CommandRegistry: case-insensitive, duplicate-rejecting alias lookup - ArgParser: data-driven parser (rewritten from scratch, not extracted) with --option=value and -- separator support - CliHost: main entry point owning parse/dispatch/lifecycle/output - JsonEnvelope: AOT-safe source-generated JSON wire format - ExitCodes: POSIX-conventional exit code mapping - InputCommandRunner: shared boilerplate for TUI input commands - OpenCliWriter: hand-built OpenCLI JSON from registry metadata - TerminalEscapeSanitizer: terminal escape sequence filtering - TypeNames, ResultWriter, IHelpProvider, MetadataHelpProvider Test coverage: 95 tests covering registry, parser, exit codes, JSON envelope, sanitizer, run options, and CliHost end-to-end. Full solution builds with 0 warnings, 0 errors. All 445 existing clet unit tests continue to pass (library is additive, no refactoring of clet yet). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Delete Abstractions/, Json/, and hosting files now provided by the library (IClet, ICletRegistry, CletRunOptions, CletRunResult, CletRunStatus, CletKind, CletOptionDescriptor, BoxedCletResult, CletRegistry, ExitCodes, TerminalEscapeSanitizer, CletTypeNames, OutputFormatter, CommandLineRoot, AliasDispatcher, SchemaV1, CletJsonContext) - Replace Program.cs to use CliHost from Terminal.Gui.Cli - Update BuiltInClets to use ICommandRegistry - Update MarkdownHelpRenderer to use ICliCommand, ICommandRegistry, CommandOptionDescriptor, CommandKind, TypeNames - Update MarkdownContentResolver to use CommandRunOptions with GetExtensionList/HasExtension for global options - Update all clet implementations to use library interfaces: ICliCommand<T>, IViewerCommand, CommandResult<T>, CommandResult, CommandStatus, CommandKind, CommandOptionDescriptor, CommandRunOptions - Add ProjectReference to Terminal.Gui.Cli (already present in csproj) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…types - Add ProjectReference to Terminal.Gui.Cli in all three test projects - Delete test files now covered by Terminal.Gui.Cli.Tests: CommandLineRootTests, CletRegistryTests, OutputFormatterTests, SchemaV1Tests, TerminalEscapeSanitizerTests, CletTypeNamesTests, CletRunResultTests, ExitCodesTests - Replace old types with library equivalents across remaining tests: ICletRegistry -> ICommandRegistry, IClet -> ICliCommand, CletKind -> CommandKind, CletRunOptions -> CommandRunOptions, CletRunResult -> CommandResult, CletRunStatus -> CommandStatus, IViewerClet -> IViewerCommand, CletRegistry -> CommandRegistry - Update CletOptions -> CommandOptions - Replace AllowedFiles property with Extensions allow-file - Fix CommandResult<T> record struct construction (positional ctor) - Include IntegrationTests migration to library types Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…tests - Program.cs: version includes Terminal.Gui version for --version output - MarkdownClet: add RenderCatAsync for --cat mode (replaces AliasDispatcher logic) - MarkdownClet: remove --cat and --no-browse from per-command options (now framework flag and global option respectively) - Smoke tests: update to use --opencli instead of deleted 'list --json' - Smoke tests: version regex updated for 'clet X.Y.Z (...)' format - Unit test: fix Options_ContainsTheme assertion count Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1. OpenCliWriter: escape option names through AppendJsonString to prevent JSON injection via CommandOptionDescriptor with special characters. 2. CommandRegistry: validate PrimaryAlias is included in Aliases collection at registration time. Throws InvalidOperationException if missing, preventing commands that appear in help but can't be invoked. 3. TerminalEscapeSanitizer.SanitizeRenderedOutput: restrict CSI pass-through to SGR sequences only (m-terminated). Non-SGR CSI sequences (device queries, erase, mode changes) are now stripped for defense-in-depth. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
# Conflicts: # src/Clet/Clets/Input/ConfirmClet.cs # src/Clet/Hosting/CommandLineRoot.cs # tests/Clet.UnitTests/CommandLineRootTests.cs
Replace the ~20-line headless driver workaround in MarkdownHelpRenderer with a single call to Markdown.RenderToAnsi() (TG #5388). - Bump Terminal.Gui to 2.4.1-develop.11 (includes RenderToAnsi) - Bump Terminal.Gui.Editor to 2.4.1 (compatible with TG 2.4.x) - Fix xUnit1051 warnings in CliHostTests (pass CancellationToken) - Regenerate help.ans golden (minor rendering difference) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
7 tasks
1 task
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.
Summary
Implements Stage A of the Terminal.Gui.Cli library spec: extract clet's hosting infrastructure into a reusable
Terminal.Gui.Cliclass library, migrate clet to consume it via ProjectReference, and delete all duplicated code.What this PR delivers
New library:
src/Terminal.Gui.Cli/(26 source files)A complete, AOT-friendly CLI hosting library with:
ICliCommand,ICliCommand<T>,IViewerCommand,ICommandRegistry,CommandRunOptions,CommandResult,CommandKind,CommandStatus,CommandOptionDescriptorCommandRegistry(case-insensitive, duplicate-rejecting, PrimaryAlias validation)ArgParser(data-driven: framework flags + consumer globals + per-command options)CliHost(parse → root flags → dispatch → TUI lifecycle → output → exit codes)JsonEnvelope(SchemaV1),ResultWriter,OpenCliWriter(OpenCLI-conformant introspection)MetadataHelpProvider,IHelpProviderinterfaceTerminalEscapeSanitizer(input sanitization + SGR-only output pass-through)Library tests:
tests/Terminal.Gui.Cli.Tests/(98 tests)Covers registry, parser, host dispatch, JSON envelope, exit codes, type names, escape sanitizer, and consumer global options flow.
clet migration
ICliCommand,CommandRunOptions, etc.)Program.csrewritten to useCliHostMarkdownHelpRenderersimplified to useMarkdown.RenderToAnsi()(TG #5388)Dependency updates
2.4.1-develop.11(includesMarkdown.RenderToAnsi()API)2.4.1(compatible with TG 2.4.x)Key design decisions
IApplication; they never callApplication.Create()--openclireplaceslistcommand--catis a framework flagIViewerCommand.RenderCatAsyncExtensionsdictionary--allow-file,--allow-binary,--no-browseregistered viaCliHostOptions.GlobalOptionsInputCletRunnerstays in cletCletStyling.BaseSchemeNamewhich library deliberately omits (spec §9.1)FileAccessPolicy/MarkdownContentResolverstay in cletSecurity fixes (from code review)
AppendJsonString(prevents JSON injection)PrimaryAliasmust be inAliases(throwsArgumentExceptionat registration)Test results
Zero warnings in both Debug and Release builds.
Spec/doc impact
specs/terminal-gui-cli.md— authoritative spec (unchanged; this PR implements it)specs/stage-a-progress.md— new tracking doc with decisions, learnings, and spec feedback--catin §6.1, nolistcommand mentions)Upstream dependency
Markdown.RenderToAnsi()API2.4.1-develop.11package