{"id":36553569,"url":"https://github.com/yigit433/kommando","last_synced_at":"2026-02-16T09:18:57.165Z","repository":{"id":50710681,"uuid":"519909913","full_name":"yigit433/kommando","owner":"yigit433","description":"🍃 Simple and usable cli tool for golang.","archived":false,"fork":false,"pushed_at":"2026-02-07T02:07:02.000Z","size":30,"stargazers_count":5,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-02-07T13:22:20.369Z","etag":null,"topics":["cli-toolkit","golang-library"],"latest_commit_sha":null,"homepage":"https://pkg.go.dev/github.com/yigit433/kommando","language":"Go","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/yigit433.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":"2022-07-31T23:35:21.000Z","updated_at":"2026-02-07T02:03:03.000Z","dependencies_parsed_at":"2022-09-12T03:22:14.066Z","dependency_job_id":null,"html_url":"https://github.com/yigit433/kommando","commit_stats":null,"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"purl":"pkg:github/yigit433/kommando","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yigit433%2Fkommando","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yigit433%2Fkommando/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yigit433%2Fkommando/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yigit433%2Fkommando/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yigit433","download_url":"https://codeload.github.com/yigit433/kommando/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yigit433%2Fkommando/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29504689,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-16T09:05:14.864Z","status":"ssl_error","status_checked_at":"2026-02-16T08:55:59.364Z","response_time":115,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["cli-toolkit","golang-library"],"created_at":"2026-01-12T06:38:01.154Z","updated_at":"2026-02-16T09:18:57.159Z","avatar_url":"https://github.com/yigit433.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"## Kommando [![Go Report Card](https://goreportcard.com/badge/github.com/yigit433/kommando)](https://goreportcard.com/report/github.com/yigit433/kommando)\n\nA minimalist CLI framework for Go.\n\n### Features\n\n- Typed flags with short aliases (`-p`, `--port`)\n- Nested subcommands (`app server start`)\n- Global flags and environment variable binding\n- Automatic `--help` / `-h` on every command\n- Shell completion (Bash, Zsh, Fish, PowerShell)\n- Error returns instead of panics\n\n### Installation\n\n```\ngo get github.com/yigit433/kommando/v3\n```\n\n### Quick Start\n\n```go\npackage main\n\nimport (\n    \"fmt\"\n    \"os\"\n\n    \"github.com/yigit433/kommando/v3\"\n)\n\nfunc main() {\n    app := kommando.New(\"myapp\",\n        kommando.WithDescription(\"My CLI tool\"),\n        kommando.WithOutput(os.Stdout),\n        kommando.WithGlobalFlags(\n            kommando.Flag{Name: \"verbose\", Short: 'v', Type: kommando.FlagBool, Description: \"verbose output\"},\n        ),\n    )\n\n    app.AddCommand(\u0026kommando.Command{\n        Name:        \"greet\",\n        Description: \"Greet someone\",\n        Aliases:     []string{\"g\"},\n        Flags: []kommando.Flag{\n            {Name: \"name\", Short: 'n', Description: \"who to greet\", Type: kommando.FlagString, Default: \"World\"},\n            {Name: \"times\", Short: 't', Description: \"repeat N times\", Type: kommando.FlagInt, Default: \"1\"},\n        },\n        Execute: func(ctx *kommando.Context) error {\n            name, _ := ctx.String(\"name\")\n            times, _ := ctx.Int(\"times\")\n            for i := 0; i \u003c int(times); i++ {\n                fmt.Fprintf(ctx.Output(), \"Hello, %s!\\n\", name)\n            }\n            return nil\n        },\n    })\n\n    if err := app.Run(os.Args[1:]); err != nil {\n        fmt.Fprintf(os.Stderr, \"error: %v\\n\", err)\n        os.Exit(1)\n    }\n}\n```\n\n```\n$ myapp greet -n Alice -t 3\nHello, Alice!\nHello, Alice!\nHello, Alice!\n\n$ myapp greet --help\ngreet - Greet someone\nAliases: g\nFlags:\n  -n, --name \u003cstring\u003e   who to greet\n  -t, --times \u003cint\u003e     repeat N times\nGlobal Flags:\n  -v, --verbose \u003cbool\u003e  verbose output\n```\n\n### Subcommands\n\n```go\napp.AddCommand(\u0026kommando.Command{\n    Name:        \"server\",\n    Description: \"Server management\",\n    SubCommands: []*kommando.Command{\n        {\n            Name:        \"start\",\n            Description: \"Start the server\",\n            Flags: []kommando.Flag{\n                {Name: \"port\", Short: 'p', Type: kommando.FlagInt, Default: \"8080\", Env: \"APP_PORT\"},\n            },\n            Execute: func(ctx *kommando.Context) error {\n                port, _ := ctx.Int(\"port\")\n                fmt.Fprintf(ctx.Output(), \"Listening on :%d\\n\", port)\n                return nil\n            },\n        },\n        {\n            Name:        \"stop\",\n            Description: \"Stop the server\",\n            Execute: func(ctx *kommando.Context) error {\n                fmt.Fprintln(ctx.Output(), \"Server stopped.\")\n                return nil\n            },\n        },\n    },\n})\n```\n\n```\n$ myapp server start --port 3000\nListening on :3000\n\n$ APP_PORT=9090 myapp server start\nListening on :9090\n\n$ myapp server --help\nserver - Server management\nCommands:\n  start            Start the server\n  stop             Stop the server\n```\n\n### Environment Variable Binding\n\nFlags can read values from environment variables. Priority order: **CLI flag \u003e env var \u003e default value**.\n\n```go\nkommando.Flag{\n    Name:     \"token\",\n    Type:     kommando.FlagString,\n    Required: true,\n    Env:      \"API_TOKEN\",\n}\n```\n\n```\n$ API_TOKEN=secret myapp deploy    # works without --token flag\n```\n\n### Shell Completion\n\nBuilt-in `completion` command generates scripts for your shell:\n\n```\n$ myapp completion bash \u003e\u003e ~/.bashrc\n$ myapp completion zsh \u003e\u003e ~/.zshrc\n$ myapp completion fish \u003e ~/.config/fish/completions/myapp.fish\n$ myapp completion powershell \u003e\u003e $PROFILE\n```\n\nOr programmatically:\n\n```go\napp.GenerateCompletion(os.Stdout, kommando.Bash)\n```\n\n### Error Handling\n\nKommando returns errors instead of panicking. Use `errors.Is` to check for specific conditions:\n\n```go\nerr := app.Run(os.Args[1:])\nif errors.Is(err, kommando.ErrCommandNotFound) {\n    // unknown command\n}\nif errors.Is(err, kommando.ErrRequiredFlag) {\n    // missing required flag\n}\n```\n\n### Unknown Flag Handling\n\nBy default, unknown flags return an error. Use `WithAllowUnknownFlags` to accept them:\n\n```go\n// Default: unknown flags cause ErrUnknownFlag\napp := kommando.New(\"myapp\")\n\n// Allow unknown flags (values accessible via ctx.String)\napp := kommando.New(\"myapp\", kommando.WithAllowUnknownFlags())\n```\n\n### Bare `--` Separator\n\nEverything after a bare `--` is treated as positional arguments, even if it looks like a flag:\n\n```\n$ myapp greet --name Alice -- --not-a-flag\n# Args: [\"--not-a-flag\"], Flags: {name: \"Alice\"}\n```\n\n### Available Errors\n\n| Error | Description |\n|-------|-------------|\n| `ErrDuplicateCommand` | A command with that name already exists |\n| `ErrRequiredFlag` | A required flag was not provided |\n| `ErrInvalidFlagValue` | Flag value could not be parsed as the expected type |\n| `ErrCommandNotFound` | The specified command does not exist |\n| `ErrUnknownFlag` | A flag not defined for the command was provided |\n| `ErrUnsupportedShell` | Completion requested for an unsupported shell |\n| `ErrInvalidName` | A command or flag has an empty name |\n\n### Flag Types\n\n| Type | Go accessor | Zero value |\n|------|-------------|------------|\n| `FlagString` (default) | `ctx.String(\"name\")` | `\"\"` |\n| `FlagBool` | `ctx.Bool(\"verbose\")` | `false` |\n| `FlagInt` | `ctx.Int(\"port\")` | `0` |\n| `FlagFloat` | `ctx.Float(\"rate\")` | `0.0` |\n| `FlagStringSlice` | `ctx.StringSlice(\"tag\")` | `nil` |\n| `FlagCount` | `ctx.Count(\"verbose\")` | `0` |\n\n### Slice Flags\n\n`FlagStringSlice` collects multiple string values via repetition or commas:\n\n```go\nkommando.Flag{Name: \"tag\", Short: 't', Type: kommando.FlagStringSlice}\n```\n\n```\n$ myapp test --tag a --tag b        # [\"a\", \"b\"]\n$ myapp test --tag a,b,c            # [\"a\", \"b\", \"c\"]\n$ myapp test --tag a,b --tag c      # [\"a\", \"b\", \"c\"]\n$ myapp test --tag=x,y              # [\"x\", \"y\"]\n```\n\nEnvironment variables and defaults use comma-separated values: `TAG=a,b,c` or `Default: \"x,y\"`.\n\n### Count Flags\n\n`FlagCount` increments a counter each time the flag appears:\n\n```go\nkommando.Flag{Name: \"verbose\", Short: 'v', Type: kommando.FlagCount}\n```\n\n```\n$ myapp test --verbose              # 1\n$ myapp test --verbose --verbose    # 2\n$ myapp test -vvv                   # 3\n$ myapp test -vv --verbose          # 3\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyigit433%2Fkommando","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyigit433%2Fkommando","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyigit433%2Fkommando/lists"}