{"id":31679199,"url":"https://github.com/stho01/promty","last_synced_at":"2025-10-08T06:46:00.615Z","repository":{"id":318387076,"uuid":"1071072056","full_name":"stho01/Promty","owner":"stho01","description":"A powerful and flexible command-line parser and command executor framework for .NET applications. Build beautiful CLI tools with minimal boilerplate code.","archived":false,"fork":false,"pushed_at":"2025-10-07T14:27:35.000Z","size":7432,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-10-07T15:22:38.392Z","etag":null,"topics":["arguments","cli","cli-framework","command-line","command-line-parser","console","csharp","developer-tools","dotnet","dotnet-core","flags","framework","nuget","parser","type-safe"],"latest_commit_sha":null,"homepage":"https://stho01.github.io/Promty/","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/stho01.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-10-06T20:33:47.000Z","updated_at":"2025-10-07T14:31:17.000Z","dependencies_parsed_at":"2025-10-07T15:23:25.132Z","dependency_job_id":null,"html_url":"https://github.com/stho01/Promty","commit_stats":null,"previous_names":["stho01/prompty","stho01/promty"],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/stho01/Promty","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stho01%2FPromty","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stho01%2FPromty/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stho01%2FPromty/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stho01%2FPromty/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/stho01","download_url":"https://codeload.github.com/stho01/Promty/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stho01%2FPromty/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278891741,"owners_count":26063861,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-08T02:00:06.501Z","response_time":56,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["arguments","cli","cli-framework","command-line","command-line-parser","console","csharp","developer-tools","dotnet","dotnet-core","flags","framework","nuget","parser","type-safe"],"created_at":"2025-10-08T06:46:00.023Z","updated_at":"2025-10-08T06:46:00.610Z","avatar_url":"https://github.com/stho01.png","language":"C#","readme":"\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"gpx/logo6.png\" alt=\"Promty Logo\" width=\"200\"/\u003e\n\n  # Promty\n\n  [![NuGet Version](https://img.shields.io/nuget/v/Promty?style=flat-square\u0026logo=nuget)](https://www.nuget.org/packages/Promty)\n  [![NuGet Downloads](https://img.shields.io/nuget/dt/Promty?style=flat-square\u0026logo=nuget)](https://www.nuget.org/packages/Promty)\n  [![Build](https://img.shields.io/github/actions/workflow/status/stho01/promty/dotnet.yml?branch=main\u0026style=flat-square\u0026logo=github)](https://github.com/stho01/promty/actions)\n  [![License](https://img.shields.io/badge/license-MIT-blue?style=flat-square)](LICENSE)\n\n  A powerful and flexible command-line parser and command executor framework for .NET applications. Build beautiful CLI tools with minimal boilerplate code.\n\n  **[📚 Documentation](https://stho01.github.io/Promty/)** · **[🚀 Getting Started](https://stho01.github.io/Promty/guide/getting-started)** · **[💡 Examples](https://stho01.github.io/Promty/examples/basic)**\n\u003c/div\u003e\n\n## Features\n\n- 🎯 **Type-safe argument binding** - Automatically bind command-line arguments to strongly-typed classes\n- 🚩 **Long and short flags** - Support for both `--verbose` and `-v` style flags\n- 📝 **Automatic help generation** - Beautiful, table-formatted help text generated from attributes\n- ⚡ **Process command execution** - Easily wrap external CLI tools\n- 🎨 **Attribute-based configuration** - Use simple attributes to configure commands and arguments\n- ✅ **Validation** - Automatic validation for required arguments\n- 🔄 **Flexible architecture** - Extend `Command\u003cTArgs\u003e` or `ProcessCommand` base classes\n\n## Installation\n\n```bash\ndotnet add package Promty\n```\n\n## Quick Start\n\n### 1. Create a Command\n\n```csharp\nusing Promty;\n\n[Description(\"greet\", \"Greets a person by name\")]\npublic class GreetCommand : Command\u003cGreetCommand.Args\u003e\n{\n    public class Args\n    {\n        [Description(\"name\", \"The name of the person to greet\")]\n        public string Name { get; set; } = string.Empty;\n\n        [FlagAlias(\"uppercase\", 'u')]\n        [Description(\"Print the greeting in uppercase\")]\n        public bool Uppercase { get; set; }\n\n        [FlagAlias(\"repeat\", 'r')]\n        [Description(\"Number of times to repeat the greeting\")]\n        public int? Repeat { get; set; }\n    }\n\n    public override Task\u003cint\u003e ExecuteAsync(Args args)\n    {\n        var greeting = $\"Hello, {args.Name}!\";\n\n        if (args.Uppercase)\n        {\n            greeting = greeting.ToUpper();\n        }\n\n        var repeat = args.Repeat ?? 1;\n        for (int i = 0; i \u003c repeat; i++)\n        {\n            Console.WriteLine(greeting);\n        }\n\n        return Task.FromResult(0);\n    }\n}\n```\n\n### 2. Set Up the Executor\n\n```csharp\nusing System.Reflection;\nusing Promty;\n\nvar executor = new CommandExecutor();\nexecutor.RegisterCommandsFromAssembly(Assembly.GetExecutingAssembly());\n\nreturn await executor.ExecuteAsync(args);\n```\n\n### 3. Run Your CLI\n\n```bash\n# Show available commands\ndotnet run\n\n# Run with arguments\ndotnet run -- greet Alice --uppercase -r 3\n\n# Output:\n# HELLO, ALICE!\n# HELLO, ALICE!\n# HELLO, ALICE!\n```\n\n## Command Types\n\n### Standard Commands\n\nStandard commands use typed argument binding with automatic parsing and validation.\n\n```csharp\n[Description(\"copy\", \"Copies a file from source to destination\")]\npublic class CopyCommand : Command\u003cCopyCommand.Args\u003e\n{\n    public class Args\n    {\n        [Description(\"source\", \"The source file path\")]\n        public string Source { get; set; } = string.Empty;\n\n        [Description(\"destination\", \"The destination file path\")]\n        public string Destination { get; set; } = string.Empty;\n\n        [FlagAlias(\"verbose\", 'v')]\n        [Description(\"Show detailed output\")]\n        public bool Verbose { get; set; }\n\n        [FlagAlias(\"overwrite\", 'o')]\n        [Description(\"Overwrite existing files\")]\n        public bool Overwrite { get; set; }\n    }\n\n    public override Task\u003cint\u003e ExecuteAsync(Args args)\n    {\n        // Implementation here\n        File.Copy(args.Source, args.Destination, args.Overwrite);\n        return Task.FromResult(0);\n    }\n}\n```\n\n### Process Commands\n\nProcess commands forward all arguments to an external executable. Perfect for wrapping existing CLI tools.\n\n```csharp\n[Description(\"git\", \"Execute git commands\")]\npublic class GitCommand : ProcessCommand\n{\n    protected override string ExecutablePath =\u003e \"git\";\n}\n```\n\nUsage:\n```bash\ndotnet run -- git status\ndotnet run -- git commit -m \"Initial commit\"\ndotnet run -- git --version\n```\n\n## Attributes\n\n### DescriptionAttribute\n\nUse `[Description]` for both commands and arguments:\n\n**For Commands:**\n```csharp\n[Description(\"command-name\", \"Command description\")]\npublic class MyCommand : Command\u003cMyCommand.Args\u003e\n```\n\n**For Positional Arguments:**\n```csharp\n[Description(\"arg-name\", \"Argument description\")]\npublic string MyArgument { get; set; }\n```\n\n**For Flag Arguments:**\n```csharp\n[FlagAlias(\"verbose\", 'v')]\n[Description(\"Show detailed output\")]\npublic bool Verbose { get; set; }\n```\n\n### FlagAliasAttribute\n\n- **`[FlagAlias(long, short)]`** - Defines flag aliases\n  - `[FlagAlias(\"verbose\", 'v')]` - Both long and short\n  - `[FlagAlias(\"verbose\")]` - Long only\n  - `[FlagAlias('v')]` - Short only\n\n## Argument Types\n\nPromty supports automatic type conversion for:\n\n- `string`\n- `int`, `long`, `double`\n- `bool`\n- Nullable versions: `int?`, `bool?`, etc.\n- `[Flags]` enums (see below)\n\n### Argument Rules\n\n1. **Positional arguments** (without `[FlagAlias]` and not `[Flags]` enums) are **required** and must come **before** flags\n2. **Flag arguments** (with `[FlagAlias]`) are **optional**\n3. **`[Flags]` enum properties** are automatically treated as optional flags\n4. Boolean flags don't require values: `--verbose` is equivalent to `--verbose true`\n\n### Flags Enums\n\nInstead of defining multiple boolean properties, you can use a `[Flags]` enum to group related flags together. Each enum value becomes an individual command-line flag that can be combined.\n\n```csharp\n[Description(\"build\", \"Build a project with options\")]\npublic class BuildCommand : Command\u003cBuildCommand.Args\u003e\n{\n    [Flags]\n    public enum BuildOptions\n    {\n        None = 0,\n        [FlagAlias(\"verbose\", 'v')]\n        [Description(\"Enable verbose output\")]\n        Verbose = 1,\n        [FlagAlias(\"debug\", 'd')]\n        [Description(\"Build in debug mode\")]\n        Debug = 2,\n        [Description(\"Disable build cache\")]\n        NoCache = 4,\n        [Description(\"Skip running tests\")]\n        SkipTests = 8\n    }\n\n    public class Args\n    {\n        [Description(\"project\", \"Project name\")]\n        public string Project { get; set; } = string.Empty;\n\n        // No [FlagAlias] needed on the property!\n        public BuildOptions Options { get; set; }\n    }\n\n    public override Task\u003cint\u003e ExecuteAsync(Args args)\n    {\n        Console.WriteLine($\"Building {args.Project}\");\n\n        if (args.Options.HasFlag(BuildOptions.Verbose))\n            Console.WriteLine(\"Verbose mode enabled\");\n\n        if (args.Options.HasFlag(BuildOptions.Debug))\n            Console.WriteLine(\"Debug mode enabled\");\n\n        return Task.FromResult(0);\n    }\n}\n```\n\nUsage:\n```bash\n# Combine multiple flags\ndotnet run -- build MyProject --verbose --debug --skip-tests\n\n# Use short aliases\ndotnet run -- build MyProject -v -d\n\n# Mix aliases with kebab-case names\ndotnet run -- build MyProject -v --no-cache\n```\n\n**Flags Enum Features:**\n- Each enum field becomes an individual flag in the help text\n- Use `[FlagAlias]` on enum fields for custom long/short aliases\n- Enum fields without `[FlagAlias]` auto-convert to kebab-case (e.g., `NoCache` → `--no-cache`)\n- Use `[Description]` on enum fields to provide help text\n- The `None = 0` value is automatically excluded from help output\n- Multiple flags can be combined and are stored as a bitwise combination\n\n## Help Text\n\nPromty automatically generates beautiful help text:\n\n```\nUsage: greet \u003cname\u003e [options]\n\nGreets a person by name\n\nArguments:\n  \u003cname\u003e  The name of the person to greet\n\nOptions:\n  -u, --uppercase          Print the greeting in uppercase\n  -r, --repeat \u003crepeat\u003e    Number of times to repeat the greeting\n```\n\nFor commands with `[Flags]` enums, each flag is displayed individually:\n\n```\nUsage: build \u003cproject\u003e [options]\n\nBuild a project with options\n\nArguments:\n  \u003cproject\u003e  Project name\n\nOptions:\n  -v, --verbose     Enable verbose output\n  -d, --debug       Build in debug mode\n  --no-cache        Disable build cache\n  --skip-tests      Skip running tests\n```\n\nCommand list is formatted as a table:\n\n```\nAvailable commands:\n\n  build    Build a project with options\n  copy     Copies a file from source to destination\n  git      Execute git commands\n  greet    Greets a person by name\n```\n\n## Error Handling\n\nReturn appropriate exit codes from your commands:\n\n```csharp\npublic override Task\u003cint\u003e ExecuteAsync(Args args)\n{\n    if (!File.Exists(args.Source))\n    {\n        Console.WriteLine($\"Error: Source file '{args.Source}' not found\");\n        return Task.FromResult(1); // Error exit code\n    }\n\n    // Success\n    return Task.FromResult(0);\n}\n```\n\n## Advanced Usage\n\n### Multiple Assemblies\n\nRegister commands from multiple assemblies:\n\n```csharp\nusing Promty;\n\nvar executor = new CommandExecutor();\nexecutor.RegisterCommandsFromAssembly(Assembly.GetExecutingAssembly());\nexecutor.RegisterCommandsFromAssembly(typeof(PluginCommand).Assembly);\n\nreturn await executor.ExecuteAsync(args);\n```\n\n### Custom Validation\n\nImplement validation in your command:\n\n```csharp\npublic override Task\u003cint\u003e ExecuteAsync(Args args)\n{\n    if (args.Port \u003c 1 || args.Port \u003e 65535)\n    {\n        Console.WriteLine(\"Error: Port must be between 1 and 65535\");\n        return Task.FromResult(1);\n    }\n\n    // Continue with valid arguments\n}\n```\n\n## Examples\n\nCheck out the example commands in the repository:\n\n- **GreetCommand** - Demonstrates typed arguments and flags\n- **CopyCommand** - Shows file operations with validation\n- **GitCommand** - Example of wrapping an external CLI tool\n- **DotNetCommand** - Another process command example\n\n## License\n\nMIT License - see LICENSE file for details\n\n## Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstho01%2Fpromty","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstho01%2Fpromty","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstho01%2Fpromty/lists"}