Skip to main content

gor/
cli.rs

1//! CLI argument definitions using clap's derive API.
2//!
3//! Defines the top-level [`Args`] struct and the [`Command`] enum
4//! for all subcommands.
5
6use clap::{Parser, Subcommand};
7
8/// A fast, self-contained GitHub CLI written in Rust.
9#[derive(Parser, Debug)]
10#[command(
11    name = "gor",
12    version,
13    about = "GitHub on Rust — a fast, self-contained GitHub CLI",
14    long_about = "A fast, self-contained GitHub CLI written in Rust. Equivalent to `gh` but with no external dependencies on `git` or OpenSSL."
15)]
16pub struct Args {
17    /// GitHub hostname for GitHub Enterprise Server (default: github.com).
18    #[arg(long, env = "GH_HOST", global = true)]
19    pub hostname: Option<String>,
20
21    /// Subcommand to execute.
22    #[command(subcommand)]
23    pub command: Command,
24}
25
26/// Top-level subcommands for `gor`.
27#[derive(Subcommand, Debug)]
28pub enum Command {
29    /// Authenticate with a GitHub account.
30    #[command(subcommand)]
31    Auth(AuthCommand),
32    /// Work with GitHub repositories.
33    #[command(subcommand)]
34    Repo(RepoCommand),
35    /// Work with GitHub pull requests.
36    #[command(subcommand)]
37    Pr(PrCommand),
38    /// Work with GitHub issues.
39    #[command(subcommand)]
40    Issue(IssueCommand),
41    /// Make an authenticated GitHub API request.
42    #[command(subcommand)]
43    Api(ApiCommand),
44    /// Manage configuration values.
45    #[command(subcommand)]
46    Config(ConfigCommand),
47    /// Work with repository labels.
48    #[command(subcommand)]
49    Label(LabelCommand),
50    /// Work with releases.
51    #[command(subcommand)]
52    Release(ReleaseCommand),
53    /// Open a repository in the browser.
54    Browse(BrowseCommand),
55    /// Work with gists.
56    #[command(subcommand)]
57    Gist(GistCommand),
58    /// Search GitHub.
59    #[command(subcommand)]
60    Search(SearchCommand),
61    /// Work with GitHub Actions workflows.
62    #[command(subcommand)]
63    Workflow(WorkflowCommand),
64    /// Manage command aliases.
65    #[command(subcommand)]
66    Alias(AliasCommand),
67    /// Work with GitHub organizations.
68    #[command(subcommand)]
69    Org(OrgCommand),
70    /// Manage SSH keys.
71    #[command(subcommand)]
72    SshKey(SshKeyCommand),
73    /// Manage GPG keys.
74    #[command(subcommand)]
75    GpgKey(GpgKeyCommand),
76    /// List and manage secrets.
77    #[command(subcommand)]
78    Secret(SecretCommand),
79    /// List and manage Actions variables.
80    #[command(subcommand)]
81    Variable(VariableCommand),
82    /// Work with GitHub Actions workflow runs.
83    #[command(subcommand)]
84    Run(RunCommand),
85    /// List and manage repository caches.
86    #[command(subcommand)]
87    Cache(CacheCommand),
88    /// Work with repository rulesets.
89    #[command(subcommand)]
90    Ruleset(RulesetCommand),
91    /// Manage GitHub CLI extensions.
92    #[command(subcommand)]
93    Extension(ExtensionCommand),
94    /// Work with GitHub Codespaces.
95    #[command(subcommand)]
96    Codespace(CodespaceCommand),
97    /// List and manage GitHub Projects.
98    #[command(subcommand)]
99    Project(ProjectCommand),
100    /// Verify artifact attestations.
101    #[command(subcommand)]
102    Attestation(AttestationCommand),
103    /// Work with GitHub Classroom.
104    #[command(subcommand)]
105    Classroom(ClassroomCommand),
106    /// Manage GitHub Copilot.
107    #[command(subcommand)]
108    Copilot(CopilotCommand),
109    /// Generate shell completion scripts.
110    Completion {
111        /// Shell type: bash, zsh, fish, or powershell.
112        shell: String,
113    },
114}
115
116/// Arguments for `gor api`.
117#[derive(clap::Subcommand, Debug)]
118pub enum ApiCommand {
119    /// Make a REST API request to a GitHub endpoint.
120    Rest {
121        /// The API endpoint path (e.g. /repos/owner/repo).
122        endpoint: String,
123
124        /// HTTP method (default: GET).
125        #[arg(short = 'X', long, default_value = "GET")]
126        method: String,
127
128        /// Add a typed field parameter (key=value) for the request body.
129        #[arg(short = 'F', long = "field")]
130        fields: Vec<String>,
131
132        /// Add a raw field parameter (key=value) for the request body.
133        #[arg(short = 'f', long = "raw-field")]
134        raw_fields: Vec<String>,
135
136        /// Add a custom HTTP header (key: value).
137        #[arg(short = 'H', long = "header")]
138        headers: Vec<String>,
139
140        /// Read the request body from a file (use @- for stdin).
141        #[arg(long)]
142        input: Option<String>,
143
144        /// Follow Link headers to fetch all pages.
145        #[arg(long)]
146        paginate: bool,
147
148        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
149        #[arg(long, env = "GH_HOST")]
150        hostname: Option<String>,
151
152        /// Filter JSON output with a jq expression.
153        #[arg(long)]
154        jq: Option<String>,
155
156        /// Format output via a Go/Handlebars template.
157        #[arg(long)]
158        template: Option<String>,
159
160        /// Suppress status output.
161        #[arg(long)]
162        silent: bool,
163
164        /// Include response headers in the output.
165        #[arg(short = 'i', long)]
166        include: bool,
167    },
168    /// Make a GraphQL API request.
169    Graphql {
170        /// The GraphQL query string. Reads from stdin if omitted.
171        #[arg(short = 'q', long = "query")]
172        query: Option<String>,
173
174        /// GraphQL variables as key=value pairs (repeatable).
175        #[arg(short = 'F', long = "field")]
176        fields: Vec<String>,
177
178        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
179        #[arg(long, env = "GH_HOST")]
180        hostname: Option<String>,
181
182        /// Filter JSON output with a jq expression.
183        #[arg(long)]
184        jq: Option<String>,
185
186        /// Format output via a Go/Handlebars template.
187        #[arg(long)]
188        template: Option<String>,
189    },
190}
191
192/// Subcommands for `gor repo`.
193#[derive(Subcommand, Debug)]
194pub enum RepoCommand {
195    /// View a repository's description, stats, and metadata.
196    View {
197        /// Repository to view (OWNER/REPO format). Auto-detected from git remote if omitted.
198        owner_repo: Option<String>,
199        /// Open the repository in the default browser.
200        #[arg(short = 'w', long)]
201        web: bool,
202        /// Output as JSON. Optionally specify comma-separated field names.
203        #[arg(long, num_args = 0.., value_delimiter = ',')]
204        json: Option<Vec<String>>,
205        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
206        #[arg(long, env = "GH_HOST")]
207        hostname: Option<String>,
208    },
209    /// List repositories for a user or organization.
210    List {
211        /// Owner to list repos for (username or org). Defaults to authenticated user.
212        #[arg(long)]
213        owner: Option<String>,
214        /// Filter by visibility: public, private, or all (default: all).
215        #[arg(long, default_value = "all")]
216        visibility: String,
217        /// Filter by fork status: include, exclude, or only (default: include).
218        #[arg(long, default_value = "include")]
219        fork: String,
220        /// Filter by primary language.
221        #[arg(short = 'l', long)]
222        language: Option<String>,
223        /// Maximum number of repos to show (default: 30).
224        #[arg(short = 'L', long, default_value = "30")]
225        limit: u32,
226        /// Output as JSON. Optionally specify comma-separated field names.
227        #[arg(long, num_args = 0.., value_delimiter = ',')]
228        json: Option<Vec<String>>,
229        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
230        #[arg(long, env = "GH_HOST")]
231        hostname: Option<String>,
232    },
233    /// Clone a repository locally.
234    Clone {
235        /// Repository to clone (OWNER/REPO format or full URL).
236        owner_repo: String,
237        /// Target directory name.
238        #[arg(short = 'd', long)]
239        directory: Option<String>,
240        /// Name of the upstream remote (default: upstream).
241        #[arg(long, default_value = "upstream")]
242        upstream_remote_name: String,
243        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
244        #[arg(long, env = "GH_HOST")]
245        hostname: Option<String>,
246    },
247    /// Create a repository.
248    Create {
249        /// Repository name.
250        name: String,
251        /// Repository description.
252        #[arg(long)]
253        description: Option<String>,
254        /// Create a private repository.
255        #[arg(long)]
256        private: bool,
257        /// Create an internal repository (GHES only).
258        #[arg(long)]
259        internal: bool,
260        /// Organization to create the repository under.
261        #[arg(long)]
262        org: Option<String>,
263        /// Template repository (OWNER/REPO).
264        #[arg(long)]
265        template: Option<String>,
266        /// Clone the new repository locally after creation.
267        #[arg(long)]
268        clone: bool,
269        /// Remote name when cloning (default: origin).
270        #[arg(long, default_value = "origin")]
271        remote: String,
272        /// Push local content to the new repository.
273        #[arg(long)]
274        push: bool,
275        /// Disable the wiki.
276        #[arg(long)]
277        disable_wiki: bool,
278        /// Disable the issue tracker.
279        #[arg(long)]
280        disable_issues: bool,
281        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
282        #[arg(long, env = "GH_HOST")]
283        hostname: Option<String>,
284    },
285    /// Fork a repository.
286    Fork {
287        /// Repository to fork (OWNER/REPO format).
288        owner_repo: String,
289        /// Organization to fork into.
290        #[arg(long)]
291        org: Option<String>,
292        /// Clone the fork locally after creation.
293        #[arg(long)]
294        clone: bool,
295        /// Remote name when cloning (default: origin).
296        #[arg(long, default_value = "origin")]
297        remote: String,
298        /// Custom name for the fork.
299        #[arg(long)]
300        fork_name: Option<String>,
301        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
302        #[arg(long, env = "GH_HOST")]
303        hostname: Option<String>,
304    },
305    /// Delete a repository.
306    Delete {
307        /// Repository to delete (OWNER/REPO format).
308        owner_repo: String,
309        /// Skip confirmation prompt.
310        #[arg(long)]
311        yes: bool,
312        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
313        #[arg(long, env = "GH_HOST")]
314        hostname: Option<String>,
315    },
316    /// Edit a repository's settings.
317    Edit {
318        /// Repository to edit (OWNER/REPO format). Auto-detected from git remote if omitted.
319        #[arg(short = 'R', long)]
320        repo: Option<String>,
321        /// Repository description.
322        #[arg(long)]
323        description: Option<String>,
324        /// Repository visibility: public, private, or internal.
325        #[arg(long, value_parser = ["public", "private", "internal"])]
326        visibility: Option<String>,
327        /// Add a topic (repeatable).
328        #[arg(long = "add-topic")]
329        add_topic: Vec<String>,
330        /// Remove a topic (repeatable).
331        #[arg(long = "remove-topic")]
332        remove_topic: Vec<String>,
333        /// Default branch name.
334        #[arg(long)]
335        default_branch: Option<String>,
336        /// Enable wiki (true/false).
337        #[arg(long, value_parser = ["true", "false"])]
338        enable_wiki: Option<String>,
339        /// Enable issues (true/false).
340        #[arg(long, value_parser = ["true", "false"])]
341        enable_issues: Option<String>,
342        /// Enable projects (true/false).
343        #[arg(long, value_parser = ["true", "false"])]
344        enable_projects: Option<String>,
345        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
346        #[arg(long, env = "GH_HOST")]
347        hostname: Option<String>,
348    },
349    /// Transfer a repository to another user or organization.
350    Transfer {
351        /// Target user or organization.
352        target: String,
353        /// Repository to transfer (OWNER/REPO format). Auto-detected from git remote if omitted.
354        #[arg(short = 'R', long)]
355        repo: Option<String>,
356        /// New name for the repository after transfer.
357        #[arg(long)]
358        new_name: Option<String>,
359        /// Team slug to grant access in the new organization (repeatable).
360        #[arg(long)]
361        team: Vec<String>,
362        /// Skip confirmation prompt.
363        #[arg(long)]
364        yes: bool,
365        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
366        #[arg(long, env = "GH_HOST")]
367        hostname: Option<String>,
368    },
369    /// Sync a fork with its upstream repository.
370    Sync {
371        /// Repository to sync (OWNER/REPO format). Auto-detected from git remote if omitted.
372        #[arg(short = 'R', long)]
373        repo: Option<String>,
374        /// Branch to sync into (default: the fork's default branch).
375        #[arg(short = 'b', long)]
376        branch: Option<String>,
377        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
378        #[arg(long, env = "GH_HOST")]
379        hostname: Option<String>,
380    },
381}
382
383/// Subcommands for `gor auth`.
384#[derive(Subcommand, Debug)]
385pub enum AuthCommand {
386    /// Log in to a GitHub account using the OAuth device flow.
387    Login {
388        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
389        #[arg(long, env = "GH_HOST")]
390        hostname: Option<String>,
391        /// Request specific OAuth scopes (comma-separated).
392        /// Default: repo,read:org,workflow,gist
393        #[arg(long)]
394        scopes: Option<String>,
395        /// Read token from stdin instead of starting the device flow.
396        #[arg(long, conflicts_with = "scopes")]
397        with_token: bool,
398    },
399    /// Log out of a GitHub account.
400    Logout {
401        /// GitHub hostname (default: github.com).
402        #[arg(long, env = "GH_HOST")]
403        hostname: Option<String>,
404    },
405    /// Show the current authentication status.
406    Status {
407        /// GitHub hostname (default: github.com).
408        #[arg(long, env = "GH_HOST")]
409        hostname: Option<String>,
410    },
411    /// Configure git to use gor as a credential helper.
412    SetupGit {
413        /// GitHub hostname (default: github.com).
414        #[arg(long, env = "GH_HOST")]
415        hostname: Option<String>,
416    },
417    /// Print or refresh the authentication token.
418    Token {
419        /// GitHub hostname (default: github.com).
420        #[arg(long, env = "GH_HOST")]
421        hostname: Option<String>,
422        /// Refresh the stored token via the OAuth device flow.
423        #[arg(long)]
424        refresh: bool,
425        /// Request additional OAuth scopes during refresh (repeatable).
426        #[arg(short = 's', long)]
427        scopes: Vec<String>,
428        /// Mask the token output (show only first and last few characters).
429        #[arg(long)]
430        secure: bool,
431    },
432}
433
434/// Subcommands for `gor pr`.
435#[derive(Subcommand, Debug)]
436pub enum PrCommand {
437    /// List pull requests in a repository.
438    List {
439        /// Repository to list PRs for (OWNER/REPO format). Auto-detected from git remote if omitted.
440        owner_repo: Option<String>,
441        /// Filter by state: open, closed, merged, or all (default: open).
442        #[arg(long, default_value = "open")]
443        state: String,
444        /// Filter by base branch.
445        #[arg(long)]
446        base: Option<String>,
447        /// Filter by head branch.
448        #[arg(long)]
449        head: Option<String>,
450        /// Filter by PR author login.
451        #[arg(long)]
452        author: Option<String>,
453        /// Filter by label (repeatable).
454        #[arg(long = "label")]
455        labels: Vec<String>,
456        /// Filter by assignee login.
457        #[arg(long)]
458        assignee: Option<String>,
459        /// Maximum number of PRs to show (default: 30).
460        #[arg(short = 'L', long, default_value = "30")]
461        limit: u32,
462        /// Open the PR list in the default browser.
463        #[arg(short = 'w', long)]
464        web: bool,
465        /// Output as JSON. Optionally specify comma-separated field names.
466        #[arg(long, num_args = 0.., value_delimiter = ',')]
467        json: Option<Vec<String>>,
468        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
469        #[arg(long, env = "GH_HOST")]
470        hostname: Option<String>,
471    },
472    /// View details of a pull request.
473    View {
474        /// Pull request number.
475        number: u64,
476        /// Repository to view PR from (OWNER/REPO format). Auto-detected from git remote if omitted.
477        #[arg(short = 'R', long)]
478        repo: Option<String>,
479        /// Open the PR in the default browser.
480        #[arg(short = 'w', long)]
481        web: bool,
482        /// Include the PR's comment thread.
483        #[arg(long)]
484        comments: bool,
485        /// Output as JSON. Optionally specify comma-separated field names.
486        #[arg(long, num_args = 0.., value_delimiter = ',')]
487        json: Option<Vec<String>>,
488        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
489        #[arg(long, env = "GH_HOST")]
490        hostname: Option<String>,
491    },
492    /// Create a pull request.
493    Create {
494        /// Repository (OWNER/REPO format). Auto-detected from git remote if omitted.
495        #[arg(short = 'R', long)]
496        repo: Option<String>,
497        /// PR title.
498        #[arg(long)]
499        title: Option<String>,
500        /// PR body (markdown).
501        #[arg(long)]
502        body: Option<String>,
503        /// Base branch to merge into. Auto-detected from the repo's default branch.
504        #[arg(long)]
505        base: Option<String>,
506        /// Head branch. Auto-detected from the current branch.
507        #[arg(long)]
508        head: Option<String>,
509        /// Create as a draft PR.
510        #[arg(long)]
511        draft: bool,
512        /// Add labels (repeatable).
513        #[arg(long = "label")]
514        labels: Vec<String>,
515        /// Assign people by login (repeatable).
516        #[arg(long)]
517        assignee: Vec<String>,
518        /// Milestone ID or title.
519        #[arg(long)]
520        milestone: Option<String>,
521        /// Add to project board by number.
522        #[arg(long)]
523        project: Option<u32>,
524        /// Open the PR in the default browser after creation.
525        #[arg(short = 'w', long)]
526        web: bool,
527        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
528        #[arg(long, env = "GH_HOST")]
529        hostname: Option<String>,
530    },
531    /// Close a pull request.
532    Close {
533        /// Pull request number.
534        number: u64,
535        /// Repository (OWNER/REPO format). Auto-detected from git remote if omitted.
536        #[arg(short = 'R', long)]
537        repo: Option<String>,
538        /// Add a closing comment.
539        #[arg(long)]
540        comment: Option<String>,
541        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
542        #[arg(long, env = "GH_HOST")]
543        hostname: Option<String>,
544    },
545    /// Reopen a closed pull request.
546    Reopen {
547        /// Pull request number.
548        number: u64,
549        /// Repository (OWNER/REPO format). Auto-detected from git remote if omitted.
550        #[arg(short = 'R', long)]
551        repo: Option<String>,
552        /// Add a comment when reopening.
553        #[arg(long)]
554        comment: Option<String>,
555        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
556        #[arg(long, env = "GH_HOST")]
557        hostname: Option<String>,
558    },
559    /// Add a comment to a pull request.
560    Comment {
561        /// Pull request number.
562        number: u64,
563        /// Repository (OWNER/REPO format). Auto-detected from git remote if omitted.
564        #[arg(short = 'R', long)]
565        repo: Option<String>,
566        /// Comment body (markdown supported).
567        #[arg(long, conflicts_with = "body_file")]
568        body: Option<String>,
569        /// Read comment body from file (use @- for stdin).
570        #[arg(long, conflicts_with = "body")]
571        body_file: Option<String>,
572        /// Open the PR in the default browser after commenting.
573        #[arg(short = 'w', long)]
574        web: bool,
575        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
576        #[arg(long, env = "GH_HOST")]
577        hostname: Option<String>,
578    },
579    /// Merge a pull request.
580    Merge {
581        /// Pull request number.
582        number: u64,
583        /// Repository (OWNER/REPO format). Auto-detected from git remote if omitted.
584        #[arg(short = 'R', long)]
585        repo: Option<String>,
586        /// Merge with a merge commit (default).
587        #[arg(long, conflicts_with_all = &["squash", "rebase"])]
588        merge: bool,
589        /// Squash commits into one.
590        #[arg(long, conflicts_with_all = &["merge", "rebase"])]
591        squash: bool,
592        /// Rebase commits onto the base branch.
593        #[arg(long, conflicts_with_all = &["merge", "squash"])]
594        rebase: bool,
595        /// Merge commit message body.
596        #[arg(long)]
597        body: Option<String>,
598        /// Merge commit subject.
599        #[arg(long)]
600        subject: Option<String>,
601        /// Delete the head branch after merging.
602        #[arg(long)]
603        delete_branch: bool,
604        /// Use admin privileges to bypass branch protection.
605        #[arg(long)]
606        admin: bool,
607        /// Enable auto-merge (merge when all checks pass).
608        #[arg(long)]
609        auto: bool,
610        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
611        #[arg(long, env = "GH_HOST")]
612        hostname: Option<String>,
613    },
614    /// Check out a pull request's head branch locally.
615    Checkout {
616        /// Pull request number.
617        number: u64,
618        /// Repository (OWNER/REPO format). Auto-detected from git remote if omitted.
619        #[arg(short = 'R', long)]
620        repo: Option<String>,
621        /// Custom local branch name.
622        #[arg(short = 'b', long)]
623        branch: Option<String>,
624        /// Initialize and update submodules.
625        #[arg(long)]
626        recurse_submodules: bool,
627        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
628        #[arg(long, env = "GH_HOST")]
629        hostname: Option<String>,
630    },
631    /// View the diff of a pull request.
632    Diff {
633        /// Pull request number.
634        number: u64,
635        /// Repository (OWNER/REPO format). Auto-detected from git remote if omitted.
636        #[arg(short = 'R', long)]
637        repo: Option<String>,
638        /// Control colorized output: always, never, auto.
639        #[arg(long, default_value = "auto")]
640        color: String,
641        /// Show only the names of changed files.
642        #[arg(long)]
643        name_only: bool,
644        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
645        #[arg(long, env = "GH_HOST")]
646        hostname: Option<String>,
647    },
648    /// Edit a pull request.
649    Edit {
650        /// Pull request number.
651        number: u64,
652        /// Repository (OWNER/REPO format). Auto-detected from git remote if omitted.
653        #[arg(short = 'R', long)]
654        repo: Option<String>,
655        /// New PR title.
656        #[arg(long)]
657        title: Option<String>,
658        /// New PR body (markdown).
659        #[arg(long)]
660        body: Option<String>,
661        /// Change the base branch.
662        #[arg(long)]
663        base: Option<String>,
664        /// Add labels (repeatable).
665        #[arg(long = "add-label")]
666        add_label: Vec<String>,
667        /// Remove labels (repeatable).
668        #[arg(long = "remove-label")]
669        remove_label: Vec<String>,
670        /// Add assignees by login (repeatable).
671        #[arg(long = "add-assignee")]
672        add_assignee: Vec<String>,
673        /// Remove assignees by login (repeatable).
674        #[arg(long = "remove-assignee")]
675        remove_assignee: Vec<String>,
676        /// Milestone ID or title.
677        #[arg(long)]
678        milestone: Option<String>,
679        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
680        #[arg(long, env = "GH_HOST")]
681        hostname: Option<String>,
682    },
683    /// Review a pull request.
684    Review {
685        /// Pull request number.
686        number: u64,
687        /// Repository (OWNER/REPO format). Auto-detected from git remote if omitted.
688        #[arg(short = 'R', long)]
689        repo: Option<String>,
690        /// Submit an approving review.
691        #[arg(long)]
692        approve: bool,
693        /// Request changes.
694        #[arg(long)]
695        request_changes: bool,
696        /// Leave a general comment (default).
697        #[arg(long)]
698        comment: bool,
699        /// Review body text.
700        #[arg(long)]
701        body: Option<String>,
702        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
703        #[arg(long, env = "GH_HOST")]
704        hostname: Option<String>,
705    },
706    /// View CI checks for a pull request.
707    Checks {
708        /// Pull request number.
709        number: u64,
710        /// Repository (OWNER/REPO format). Auto-detected from git remote if omitted.
711        #[arg(short = 'R', long)]
712        repo: Option<String>,
713        /// Poll until all checks complete.
714        #[arg(long)]
715        watch: bool,
716        /// Output as JSON. Optionally specify comma-separated field names.
717        #[arg(long, num_args = 0.., value_delimiter = ',')]
718        json: Option<Vec<String>>,
719        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
720        #[arg(long, env = "GH_HOST")]
721        hostname: Option<String>,
722    },
723    /// Mark a draft pull request as ready for review.
724    Ready {
725        /// Pull request number.
726        number: u64,
727        /// Repository (OWNER/REPO format). Auto-detected from git remote if omitted.
728        #[arg(short = 'R', long)]
729        repo: Option<String>,
730        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
731        #[arg(long, env = "GH_HOST")]
732        hostname: Option<String>,
733    },
734}
735
736/// Subcommands for `gor issue`.
737#[derive(Subcommand, Debug)]
738pub enum IssueCommand {
739    /// List issues in a repository.
740    List {
741        /// Repository to list issues for (OWNER/REPO format). Auto-detected from git remote if omitted.
742        owner_repo: Option<String>,
743        /// Filter by state: open, closed, or all (default: open).
744        #[arg(long, default_value = "open")]
745        state: String,
746        /// Filter by label (repeatable).
747        #[arg(long = "label")]
748        labels: Vec<String>,
749        /// Filter by assignee login.
750        #[arg(long)]
751        assignee: Option<String>,
752        /// Filter by issue author login.
753        #[arg(long)]
754        author: Option<String>,
755        /// Filter by @mention.
756        #[arg(long)]
757        mention: Option<String>,
758        /// Filter by milestone title or number.
759        #[arg(long)]
760        milestone: Option<String>,
761        /// Maximum number of issues to show (default: 30).
762        #[arg(short = 'L', long, default_value = "30")]
763        limit: u32,
764        /// Open the issue list in the default browser.
765        #[arg(short = 'w', long)]
766        web: bool,
767        /// Output as JSON. Optionally specify comma-separated field names.
768        #[arg(long, num_args = 0.., value_delimiter = ',')]
769        json: Option<Vec<String>>,
770        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
771        #[arg(long, env = "GH_HOST")]
772        hostname: Option<String>,
773    },
774    /// View details of an issue.
775    View {
776        /// Issue number.
777        number: u64,
778        /// Repository to view issue from (OWNER/REPO format). Auto-detected from git remote if omitted.
779        #[arg(short = 'R', long)]
780        repo: Option<String>,
781        /// Open the issue in the default browser.
782        #[arg(short = 'w', long)]
783        web: bool,
784        /// Include the issue's comment thread.
785        #[arg(long)]
786        comments: bool,
787        /// Output as JSON. Optionally specify comma-separated field names.
788        #[arg(long, num_args = 0.., value_delimiter = ',')]
789        json: Option<Vec<String>>,
790        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
791        #[arg(long, env = "GH_HOST")]
792        hostname: Option<String>,
793    },
794    /// Close an issue.
795    Close {
796        /// Issue number.
797        number: u64,
798        /// Repository (OWNER/REPO format). Auto-detected from git remote if omitted.
799        #[arg(short = 'R', long)]
800        repo: Option<String>,
801        /// Add a closing comment.
802        #[arg(long)]
803        comment: Option<String>,
804        /// Reason for closing: completed or not_planned.
805        #[arg(long, value_parser = ["completed", "not_planned"])]
806        reason: Option<String>,
807        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
808        #[arg(long, env = "GH_HOST")]
809        hostname: Option<String>,
810    },
811    /// Reopen a closed issue.
812    Reopen {
813        /// Issue number.
814        number: u64,
815        /// Repository (OWNER/REPO format). Auto-detected from git remote if omitted.
816        #[arg(short = 'R', long)]
817        repo: Option<String>,
818        /// Add a comment when reopening.
819        #[arg(long)]
820        comment: Option<String>,
821        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
822        #[arg(long, env = "GH_HOST")]
823        hostname: Option<String>,
824    },
825    /// Add a comment to an issue.
826    Comment {
827        /// Issue number.
828        number: u64,
829        /// Repository (OWNER/REPO format). Auto-detected from git remote if omitted.
830        #[arg(short = 'R', long)]
831        repo: Option<String>,
832        /// Comment body (markdown supported).
833        #[arg(long, conflicts_with = "body_file")]
834        body: Option<String>,
835        /// Read comment body from file (use @- for stdin).
836        #[arg(long, conflicts_with = "body")]
837        body_file: Option<String>,
838        /// Open the issue in the default browser after commenting.
839        #[arg(short = 'w', long)]
840        web: bool,
841        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
842        #[arg(long, env = "GH_HOST")]
843        hostname: Option<String>,
844    },
845    /// Create an issue.
846    Create {
847        /// Repository (OWNER/REPO format). Auto-detected from git remote if omitted.
848        #[arg(short = 'R', long)]
849        repo: Option<String>,
850        /// Issue title (required).
851        #[arg(long)]
852        title: Option<String>,
853        /// Issue body (markdown).
854        #[arg(long)]
855        body: Option<String>,
856        /// Add labels (repeatable).
857        #[arg(long = "label")]
858        labels: Vec<String>,
859        /// Assign users by login (repeatable).
860        #[arg(long)]
861        assignee: Vec<String>,
862        /// Milestone ID or title.
863        #[arg(long)]
864        milestone: Option<String>,
865        /// Add to project board by number.
866        #[arg(long)]
867        project: Option<u32>,
868        /// Open the issue in the default browser after creation.
869        #[arg(short = 'w', long)]
870        web: bool,
871        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
872        #[arg(long, env = "GH_HOST")]
873        hostname: Option<String>,
874    },
875    /// Edit an issue.
876    Edit {
877        /// Issue number.
878        number: u64,
879        /// Repository (OWNER/REPO format). Auto-detected from git remote if omitted.
880        #[arg(short = 'R', long)]
881        repo: Option<String>,
882        /// New issue title.
883        #[arg(long)]
884        title: Option<String>,
885        /// New issue body (markdown).
886        #[arg(long)]
887        body: Option<String>,
888        /// Add labels (repeatable).
889        #[arg(long = "add-label")]
890        add_label: Vec<String>,
891        /// Remove labels (repeatable).
892        #[arg(long = "remove-label")]
893        remove_label: Vec<String>,
894        /// Add assignees by login (repeatable).
895        #[arg(long = "add-assignee")]
896        add_assignee: Vec<String>,
897        /// Remove assignees by login (repeatable).
898        #[arg(long = "remove-assignee")]
899        remove_assignee: Vec<String>,
900        /// Milestone ID or title.
901        #[arg(long)]
902        milestone: Option<String>,
903        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
904        #[arg(long, env = "GH_HOST")]
905        hostname: Option<String>,
906    },
907    /// Transfer an issue to another repository.
908    Transfer {
909        /// Issue number.
910        number: u64,
911        /// Destination repository (OWNER/REPO format).
912        destination: String,
913        /// Source repository (OWNER/REPO format). Auto-detected from git remote if omitted.
914        #[arg(short = 'R', long)]
915        repo: Option<String>,
916        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
917        #[arg(long, env = "GH_HOST")]
918        hostname: Option<String>,
919    },
920}
921
922/// Subcommands for `gor config`.
923#[derive(Subcommand, Debug)]
924pub enum ConfigCommand {
925    /// Get a config value.
926    Get {
927        /// Config key to read.
928        key: String,
929    },
930    /// Set a config value.
931    Set {
932        /// Config key to set.
933        key: String,
934        /// Value to set.
935        value: String,
936    },
937    /// List all config values.
938    List,
939}
940
941/// Subcommands for `gor label`.
942#[derive(Subcommand, Debug)]
943pub enum LabelCommand {
944    /// List labels in a repository.
945    List {
946        /// Repository (OWNER/REPO format). Auto-detected from git remote if omitted.
947        #[arg(short = 'R', long)]
948        repo: Option<String>,
949        /// Filter labels by name substring.
950        #[arg(long)]
951        search: Option<String>,
952        /// Maximum number of labels to show (default: 30).
953        #[arg(short = 'L', long, default_value = "30")]
954        limit: u32,
955        /// Output as JSON. Optionally specify comma-separated field names.
956        #[arg(long, num_args = 0.., value_delimiter = ',')]
957        json: Option<Vec<String>>,
958        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
959        #[arg(long, env = "GH_HOST")]
960        hostname: Option<String>,
961    },
962    /// Create a label.
963    Create {
964        /// Label name.
965        name: String,
966        /// Label color (hex, without #). Auto-generated if omitted.
967        #[arg(long)]
968        color: Option<String>,
969        /// Label description.
970        #[arg(long)]
971        description: Option<String>,
972        /// Repository (OWNER/REPO format). Auto-detected from git remote if omitted.
973        #[arg(short = 'R', long)]
974        repo: Option<String>,
975        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
976        #[arg(long, env = "GH_HOST")]
977        hostname: Option<String>,
978    },
979    /// Edit a label.
980    Edit {
981        /// Current label name.
982        name: String,
983        /// New label name.
984        #[arg(long)]
985        rename: Option<String>,
986        /// New label color (hex, without #).
987        #[arg(long)]
988        color: Option<String>,
989        /// New label description.
990        #[arg(long)]
991        description: Option<String>,
992        /// Repository (OWNER/REPO format). Auto-detected from git remote if omitted.
993        #[arg(short = 'R', long)]
994        repo: Option<String>,
995        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
996        #[arg(long, env = "GH_HOST")]
997        hostname: Option<String>,
998    },
999    /// Delete a label.
1000    Delete {
1001        /// Label name.
1002        name: String,
1003        /// Repository (OWNER/REPO format). Auto-detected from git remote if omitted.
1004        #[arg(short = 'R', long)]
1005        repo: Option<String>,
1006        /// Skip the confirmation prompt.
1007        #[arg(short = 'y', long)]
1008        yes: bool,
1009        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
1010        #[arg(long, env = "GH_HOST")]
1011        hostname: Option<String>,
1012    },
1013    /// Clone labels from another repository.
1014    Clone {
1015        /// Source repository to clone labels from (OWNER/REPO format).
1016        source: String,
1017        /// Target repository (OWNER/REPO format). Auto-detected from git remote if omitted.
1018        #[arg(short = 'R', long)]
1019        repo: Option<String>,
1020        /// Overwrite existing labels in the target repo.
1021        #[arg(long)]
1022        force: bool,
1023        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
1024        #[arg(long, env = "GH_HOST")]
1025        hostname: Option<String>,
1026    },
1027}
1028
1029/// Subcommands for `gor release`.
1030#[derive(Subcommand, Debug)]
1031pub enum ReleaseCommand {
1032    /// List releases in a repository.
1033    List {
1034        /// Repository (OWNER/REPO format). Auto-detected from git remote if omitted.
1035        #[arg(short = 'R', long)]
1036        repo: Option<String>,
1037        /// Maximum number of releases to show (default: 30).
1038        #[arg(short = 'L', long, default_value = "30")]
1039        limit: u32,
1040        /// Exclude draft releases.
1041        #[arg(long)]
1042        exclude_drafts: bool,
1043        /// Exclude prereleases.
1044        #[arg(long)]
1045        exclude_prereleases: bool,
1046        /// Output as JSON. Optionally specify comma-separated field names.
1047        #[arg(long, num_args = 0.., value_delimiter = ',')]
1048        json: Option<Vec<String>>,
1049        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
1050        #[arg(long, env = "GH_HOST")]
1051        hostname: Option<String>,
1052    },
1053    /// View details of a release.
1054    View {
1055        /// Tag name or release ID.
1056        release: String,
1057        /// Repository (OWNER/REPO format). Auto-detected from git remote if omitted.
1058        #[arg(short = 'R', long)]
1059        repo: Option<String>,
1060        /// Open the release in the default browser.
1061        #[arg(short = 'w', long)]
1062        web: bool,
1063        /// Output as JSON. Optionally specify comma-separated field names.
1064        #[arg(long, num_args = 0.., value_delimiter = ',')]
1065        json: Option<Vec<String>>,
1066        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
1067        #[arg(long, env = "GH_HOST")]
1068        hostname: Option<String>,
1069    },
1070    /// Delete a release.
1071    Delete {
1072        /// Tag name or release ID.
1073        release: String,
1074        /// Repository (OWNER/REPO format). Auto-detected from git remote if omitted.
1075        #[arg(short = 'R', long)]
1076        repo: Option<String>,
1077        /// Skip the confirmation prompt.
1078        #[arg(short = 'y', long)]
1079        yes: bool,
1080        /// Keep the associated git tag (do not delete it).
1081        #[arg(long)]
1082        skip_tag: bool,
1083        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
1084        #[arg(long, env = "GH_HOST")]
1085        hostname: Option<String>,
1086    },
1087    /// Edit a release.
1088    Edit {
1089        /// Tag name or release ID.
1090        release: String,
1091        /// Repository (OWNER/REPO format). Auto-detected from git remote if omitted.
1092        #[arg(short = 'R', long)]
1093        repo: Option<String>,
1094        /// New release title.
1095        #[arg(long)]
1096        title: Option<String>,
1097        /// New release body (markdown).
1098        #[arg(long)]
1099        notes: Option<String>,
1100        /// Read release body from a file (use "-" for stdin).
1101        #[arg(long)]
1102        notes_file: Option<String>,
1103        /// Set draft status (true or false).
1104        #[arg(long)]
1105        draft: Option<bool>,
1106        /// Set prerelease status (true or false).
1107        #[arg(long)]
1108        prerelease: Option<bool>,
1109        /// Change the tag the release points to.
1110        #[arg(long)]
1111        tag: Option<String>,
1112        /// Change the target commitish (branch or commit SHA).
1113        #[arg(long)]
1114        target: Option<String>,
1115        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
1116        #[arg(long, env = "GH_HOST")]
1117        hostname: Option<String>,
1118    },
1119    /// Upload assets to a release.
1120    Upload {
1121        /// Tag name or release ID.
1122        release: String,
1123        /// Asset files to upload.
1124        files: Vec<String>,
1125        /// Repository (OWNER/REPO format). Auto-detected from git remote if omitted.
1126        #[arg(short = 'R', long)]
1127        repo: Option<String>,
1128        /// Override the asset name (only meaningful for a single asset upload).
1129        #[arg(long)]
1130        name: Option<String>,
1131        /// Override the auto-detected MIME type.
1132        #[arg(long = "mime-type")]
1133        mime_type: Option<String>,
1134        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
1135        #[arg(long, env = "GH_HOST")]
1136        hostname: Option<String>,
1137    },
1138    /// Create a new release.
1139    Create {
1140        /// Tag name for the release (must already exist).
1141        tag: String,
1142        /// Repository (OWNER/REPO format). Auto-detected from git remote if omitted.
1143        #[arg(short = 'R', long)]
1144        repo: Option<String>,
1145        /// Release title (defaults to tag name).
1146        #[arg(long)]
1147        title: Option<String>,
1148        /// Release body (markdown).
1149        #[arg(long)]
1150        notes: Option<String>,
1151        /// Read release notes from a file (use "-" for stdin).
1152        #[arg(long)]
1153        notes_file: Option<String>,
1154        /// Create as a draft release.
1155        #[arg(long)]
1156        draft: bool,
1157        /// Mark as a prerelease.
1158        #[arg(long)]
1159        prerelease: bool,
1160        /// Target commitish (branch or commit SHA).
1161        #[arg(long)]
1162        target: Option<String>,
1163        /// Discussion category for the release.
1164        #[arg(long)]
1165        discussion_category: Option<String>,
1166        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
1167        #[arg(long, env = "GH_HOST")]
1168        hostname: Option<String>,
1169    },
1170    /// Download release assets.
1171    Download {
1172        /// Tag name or release ID.
1173        release: String,
1174        /// Repository (OWNER/REPO format). Auto-detected from git remote if omitted.
1175        #[arg(short = 'R', long)]
1176        repo: Option<String>,
1177        /// Filter assets by glob pattern (repeatable).
1178        #[arg(long = "pattern")]
1179        patterns: Vec<String>,
1180        /// Output directory (default: current directory).
1181        #[arg(short = 'D', long, default_value = ".")]
1182        dir: String,
1183        /// Skip assets whose file already exists.
1184        #[arg(long)]
1185        skip_existing: bool,
1186        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
1187        #[arg(long, env = "GH_HOST")]
1188        hostname: Option<String>,
1189    },
1190    /// Delete a release asset.
1191    DeleteAsset {
1192        /// Asset ID to delete.
1193        asset_id: u64,
1194        /// Repository (OWNER/REPO format). Auto-detected from git remote if omitted.
1195        #[arg(short = 'R', long)]
1196        repo: Option<String>,
1197        /// Skip confirmation prompt.
1198        #[arg(short = 'y', long)]
1199        yes: bool,
1200        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
1201        #[arg(long, env = "GH_HOST")]
1202        hostname: Option<String>,
1203    },
1204}
1205
1206/// Arguments for `gor browse`.
1207#[derive(clap::Args, Debug)]
1208pub struct BrowseCommand {
1209    /// Repository (OWNER/REPO format). Auto-detected from git remote if omitted.
1210    #[arg(short = 'R', long)]
1211    pub repo: Option<String>,
1212    /// Open a specific branch or tree.
1213    #[arg(short = 'b', long)]
1214    pub branch: Option<String>,
1215    /// Open a specific commit.
1216    #[arg(short = 'c', long)]
1217    pub commit: Option<String>,
1218    /// Open the projects tab.
1219    #[arg(long)]
1220    pub projects: bool,
1221    /// Open the wiki.
1222    #[arg(long)]
1223    pub wiki: bool,
1224    /// Open the settings page.
1225    #[arg(long)]
1226    pub settings: bool,
1227    /// Open a specific issue by number.
1228    #[arg(short = 'i', long)]
1229    pub issue: Option<u64>,
1230    /// Open a specific pull request by number.
1231    #[arg(short = 'p', long)]
1232    pub pr: Option<u64>,
1233    /// GitHub hostname for GitHub Enterprise Server (default: github.com).
1234    #[arg(long, env = "GH_HOST")]
1235    pub hostname: Option<String>,
1236}
1237
1238/// Subcommands for `gor gist`.
1239#[derive(Subcommand, Debug)]
1240pub enum GistCommand {
1241    /// List gists.
1242    List {
1243        /// List public gists.
1244        #[arg(long)]
1245        public: bool,
1246        /// List secret gists.
1247        #[arg(long)]
1248        secret: bool,
1249        /// List gists for a specific user (public only).
1250        #[arg(long)]
1251        user: Option<String>,
1252        /// Maximum number of gists to show (default: 30).
1253        #[arg(short = 'L', long, default_value = "30")]
1254        limit: u32,
1255        /// Output as JSON. Optionally specify comma-separated field names.
1256        #[arg(long, num_args = 0.., value_delimiter = ',')]
1257        json: Option<Vec<String>>,
1258        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
1259        #[arg(long, env = "GH_HOST")]
1260        hostname: Option<String>,
1261    },
1262    /// Create a gist.
1263    Create {
1264        /// Files to include in the gist.
1265        files: Vec<String>,
1266        /// Gist description.
1267        #[arg(long)]
1268        desc: Option<String>,
1269        /// Create a public gist (default: secret).
1270        #[arg(long)]
1271        public: bool,
1272        /// Override the filename in the gist.
1273        #[arg(long)]
1274        filename: Option<String>,
1275        /// Open the new gist in the browser.
1276        #[arg(short = 'w', long)]
1277        web: bool,
1278        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
1279        #[arg(long, env = "GH_HOST")]
1280        hostname: Option<String>,
1281    },
1282    /// View a gist's content and metadata.
1283    View {
1284        /// Gist ID to view.
1285        gist_id: String,
1286        /// Output the raw content of the gist.
1287        #[arg(long)]
1288        raw: bool,
1289        /// Select a specific file to view.
1290        #[arg(long)]
1291        filename: Option<String>,
1292        /// Open the gist in the browser.
1293        #[arg(short = 'w', long)]
1294        web: bool,
1295        /// Output as JSON. Optionally specify comma-separated field names.
1296        #[arg(long, num_args = 0.., value_delimiter = ',')]
1297        json: Option<Vec<String>>,
1298        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
1299        #[arg(long, env = "GH_HOST")]
1300        hostname: Option<String>,
1301    },
1302    /// Edit a gist.
1303    Edit {
1304        /// Gist ID to edit.
1305        gist_id: String,
1306        /// New description for the gist.
1307        #[arg(long)]
1308        desc: Option<String>,
1309        /// Add a file to the gist (path=content or file path).
1310        #[arg(long)]
1311        add: Vec<String>,
1312        /// Rename a file (old:new).
1313        #[arg(long)]
1314        filename: Option<String>,
1315        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
1316        #[arg(long, env = "GH_HOST")]
1317        hostname: Option<String>,
1318    },
1319    /// Delete a gist.
1320    Delete {
1321        /// Gist ID to delete.
1322        gist_id: String,
1323        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
1324        #[arg(long, env = "GH_HOST")]
1325        hostname: Option<String>,
1326    },
1327}
1328
1329/// Subcommands for `gor search`.
1330#[derive(Subcommand, Debug)]
1331pub enum SearchCommand {
1332    /// Search repositories.
1333    Repos {
1334        /// Search query.
1335        query: Vec<String>,
1336        /// Filter by primary language.
1337        #[arg(long)]
1338        language: Option<String>,
1339        /// Filter by repository topic.
1340        #[arg(long)]
1341        topic: Option<String>,
1342        /// Filter by star count range (e.g., ">100", "10..50").
1343        #[arg(long)]
1344        stars: Option<String>,
1345        /// Sort by: stars, forks, updated, best-match.
1346        #[arg(long, default_value = "best-match")]
1347        sort: String,
1348        /// Sort order: asc or desc.
1349        #[arg(long, default_value = "desc")]
1350        order: String,
1351        /// Maximum number of results (default: 30).
1352        #[arg(short = 'L', long, default_value = "30")]
1353        limit: u32,
1354        /// Output as JSON. Optionally specify comma-separated field names.
1355        #[arg(long, num_args = 0.., value_delimiter = ',')]
1356        json: Option<Vec<String>>,
1357        /// Open the search results in the browser.
1358        #[arg(short = 'w', long)]
1359        web: bool,
1360        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
1361        #[arg(long, env = "GH_HOST")]
1362        hostname: Option<String>,
1363    },
1364    /// Search code.
1365    Code {
1366        /// Search query.
1367        query: Vec<String>,
1368        /// Filter by language.
1369        #[arg(long)]
1370        language: Option<String>,
1371        /// Search within a specific repository (OWNER/REPO).
1372        #[arg(long)]
1373        repo: Option<String>,
1374        /// Maximum number of results (default: 30).
1375        #[arg(short = 'L', long, default_value = "30")]
1376        limit: u32,
1377        /// Output as JSON. Optionally specify comma-separated field names.
1378        #[arg(long, num_args = 0.., value_delimiter = ',')]
1379        json: Option<Vec<String>>,
1380        /// Open the search results in the browser.
1381        #[arg(short = 'w', long)]
1382        web: bool,
1383        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
1384        #[arg(long, env = "GH_HOST")]
1385        hostname: Option<String>,
1386    },
1387    /// Search issues and pull requests.
1388    Issues {
1389        /// Search query.
1390        query: Vec<String>,
1391        /// Filter by type: issue, pr.
1392        #[arg(long)]
1393        r#type: Option<String>,
1394        /// Filter by state: open, closed.
1395        #[arg(long)]
1396        state: Option<String>,
1397        /// Filter by labels (comma-separated).
1398        #[arg(long)]
1399        labels: Option<String>,
1400        /// Maximum number of results (default: 30).
1401        #[arg(short = 'L', long, default_value = "30")]
1402        limit: u32,
1403        /// Output as JSON. Optionally specify comma-separated field names.
1404        #[arg(long, num_args = 0.., value_delimiter = ',')]
1405        json: Option<Vec<String>>,
1406        /// Open the search results in the browser.
1407        #[arg(short = 'w', long)]
1408        web: bool,
1409        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
1410        #[arg(long, env = "GH_HOST")]
1411        hostname: Option<String>,
1412    },
1413    /// Search commits.
1414    Commits {
1415        /// Search query.
1416        query: Vec<String>,
1417        /// Filter by author.
1418        #[arg(long)]
1419        author: Option<String>,
1420        /// Search within a specific repository (OWNER/REPO).
1421        #[arg(long)]
1422        repo: Option<String>,
1423        /// Maximum number of results (default: 30).
1424        #[arg(short = 'L', long, default_value = "30")]
1425        limit: u32,
1426        /// Output as JSON. Optionally specify comma-separated field names.
1427        #[arg(long, num_args = 0.., value_delimiter = ',')]
1428        json: Option<Vec<String>>,
1429        /// Open the search results in the browser.
1430        #[arg(short = 'w', long)]
1431        web: bool,
1432        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
1433        #[arg(long, env = "GH_HOST")]
1434        hostname: Option<String>,
1435    },
1436}
1437
1438/// Subcommands for `gor workflow`.
1439#[derive(Subcommand, Debug)]
1440pub enum WorkflowCommand {
1441    /// List workflows in a repository.
1442    List {
1443        /// Repository (OWNER/REPO format). Auto-detected from git remote if omitted.
1444        #[arg(short = 'R', long)]
1445        repo: Option<String>,
1446        /// Maximum number of workflows to show (default: 30).
1447        #[arg(short = 'L', long, default_value = "30")]
1448        limit: u32,
1449        /// Output as JSON. Optionally specify comma-separated field names.
1450        #[arg(long, num_args = 0.., value_delimiter = ',')]
1451        json: Option<Vec<String>>,
1452        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
1453        #[arg(long, env = "GH_HOST")]
1454        hostname: Option<String>,
1455    },
1456    /// View a workflow's details.
1457    View {
1458        /// Workflow ID, filename (e.g. deploy.yml), or name.
1459        workflow: String,
1460        /// Repository (OWNER/REPO format). Auto-detected from git remote if omitted.
1461        #[arg(short = 'R', long)]
1462        repo: Option<String>,
1463        /// Output as JSON. Optionally specify comma-separated field names.
1464        #[arg(long, num_args = 0.., value_delimiter = ',')]
1465        json: Option<Vec<String>>,
1466        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
1467        #[arg(long, env = "GH_HOST")]
1468        hostname: Option<String>,
1469    },
1470    /// Enable a workflow.
1471    Enable {
1472        /// Workflow ID, filename (e.g. deploy.yml), or name.
1473        workflow: String,
1474        /// Repository (OWNER/REPO format). Auto-detected from git remote if omitted.
1475        #[arg(short = 'R', long)]
1476        repo: Option<String>,
1477        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
1478        #[arg(long, env = "GH_HOST")]
1479        hostname: Option<String>,
1480    },
1481    /// Disable a workflow.
1482    Disable {
1483        /// Workflow ID, filename (e.g. deploy.yml), or name.
1484        workflow: String,
1485        /// Repository (OWNER/REPO format). Auto-detected from git remote if omitted.
1486        #[arg(short = 'R', long)]
1487        repo: Option<String>,
1488        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
1489        #[arg(long, env = "GH_HOST")]
1490        hostname: Option<String>,
1491    },
1492    /// Run a workflow.
1493    Run {
1494        /// Workflow ID, filename (e.g. deploy.yml), or name.
1495        workflow: String,
1496        /// Repository (OWNER/REPO format). Auto-detected from git remote if omitted.
1497        #[arg(short = 'R', long)]
1498        repo: Option<String>,
1499        /// Branch to run the workflow on.
1500        #[arg(short = 'b', long)]
1501        branch: Option<String>,
1502        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
1503        #[arg(long, env = "GH_HOST")]
1504        hostname: Option<String>,
1505    },
1506}
1507
1508/// Subcommands for `gor org`.
1509#[derive(Subcommand, Debug)]
1510pub enum OrgCommand {
1511    /// List organizations for the authenticated user.
1512    List {
1513        /// Maximum number of organizations to show (default: 30).
1514        #[arg(short = 'L', long, default_value = "30")]
1515        limit: u32,
1516        /// Output as JSON. Optionally specify comma-separated field names.
1517        #[arg(long, num_args = 0.., value_delimiter = ',')]
1518        json: Option<Vec<String>>,
1519        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
1520        #[arg(long, env = "GH_HOST")]
1521        hostname: Option<String>,
1522    },
1523    /// View an organization's profile.
1524    View {
1525        /// Organization name.
1526        org: String,
1527        /// Open the organization in the browser.
1528        #[arg(short = 'w', long)]
1529        web: bool,
1530        /// Output as JSON. Optionally specify comma-separated field names.
1531        #[arg(long, num_args = 0.., value_delimiter = ',')]
1532        json: Option<Vec<String>>,
1533        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
1534        #[arg(long, env = "GH_HOST")]
1535        hostname: Option<String>,
1536    },
1537}
1538
1539/// Subcommands for `gor ssh-key`.
1540#[derive(Subcommand, Debug)]
1541pub enum SshKeyCommand {
1542    /// List SSH keys.
1543    List {
1544        /// Output as JSON. Optionally specify comma-separated field names.
1545        #[arg(long, num_args = 0.., value_delimiter = ',')]
1546        json: Option<Vec<String>>,
1547        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
1548        #[arg(long, env = "GH_HOST")]
1549        hostname: Option<String>,
1550    },
1551    /// Add an SSH key.
1552    Add {
1553        /// Title for the key.
1554        #[arg(short = 't', long)]
1555        title: String,
1556        /// Read the public key from a file.
1557        #[arg(short = 'f', long)]
1558        file: Option<String>,
1559        /// Provide the public key inline.
1560        #[arg(short = 'b', long)]
1561        body: Option<String>,
1562        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
1563        #[arg(long, env = "GH_HOST")]
1564        hostname: Option<String>,
1565    },
1566    /// Delete an SSH key.
1567    Delete {
1568        /// SSH key database ID to delete.
1569        key_id: String,
1570        /// Skip confirmation prompt.
1571        #[arg(short = 'y', long)]
1572        yes: bool,
1573        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
1574        #[arg(long, env = "GH_HOST")]
1575        hostname: Option<String>,
1576    },
1577}
1578
1579/// Subcommands for `gor gpg-key`.
1580#[derive(Subcommand, Debug)]
1581pub enum GpgKeyCommand {
1582    /// List GPG keys.
1583    List {
1584        /// Output as JSON. Optionally specify comma-separated field names.
1585        #[arg(long, num_args = 0.., value_delimiter = ',')]
1586        json: Option<Vec<String>>,
1587        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
1588        #[arg(long, env = "GH_HOST")]
1589        hostname: Option<String>,
1590    },
1591    /// Add a GPG key.
1592    Add {
1593        /// Read the armored public key from a file.
1594        #[arg(short = 'f', long)]
1595        file: Option<String>,
1596        /// Provide the armored key inline.
1597        #[arg(short = 'b', long)]
1598        body: Option<String>,
1599        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
1600        #[arg(long, env = "GH_HOST")]
1601        hostname: Option<String>,
1602    },
1603    /// Delete a GPG key.
1604    Delete {
1605        /// GPG key ID to delete.
1606        key_id: String,
1607        /// Skip confirmation prompt.
1608        #[arg(short = 'y', long)]
1609        yes: bool,
1610        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
1611        #[arg(long, env = "GH_HOST")]
1612        hostname: Option<String>,
1613    },
1614}
1615
1616/// Subcommands for `gor secret`.
1617#[derive(Subcommand, Debug)]
1618pub enum SecretCommand {
1619    /// List secrets.
1620    List {
1621        /// Organization to list secrets for.
1622        #[arg(long)]
1623        org: Option<String>,
1624        /// Environment name for environment-scoped secrets.
1625        #[arg(short = 'e', long)]
1626        env: Option<String>,
1627        /// Output as JSON. Optionally specify comma-separated field names.
1628        #[arg(long, num_args = 0.., value_delimiter = ',')]
1629        json: Option<Vec<String>>,
1630        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
1631        #[arg(long, env = "GH_HOST")]
1632        hostname: Option<String>,
1633    },
1634    /// Set a secret.
1635    Set {
1636        /// Secret name.
1637        name: String,
1638        /// Secret value body.
1639        #[arg(short = 'b', long)]
1640        body: Option<String>,
1641        /// Read secret value from a file.
1642        #[arg(short = 'f', long)]
1643        file: Option<String>,
1644        /// Organization to set the secret for.
1645        #[arg(long)]
1646        org: Option<String>,
1647        /// Environment name for environment-scoped secrets.
1648        #[arg(short = 'e', long)]
1649        env: Option<String>,
1650        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
1651        #[arg(long, env = "GH_HOST")]
1652        hostname: Option<String>,
1653    },
1654    /// Delete a secret.
1655    Delete {
1656        /// Secret name to delete.
1657        name: String,
1658        /// Delete at the organization level.
1659        #[arg(long)]
1660        org: Option<String>,
1661        /// Environment name for environment-scoped secrets.
1662        #[arg(short = 'e', long)]
1663        env: Option<String>,
1664        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
1665        #[arg(long, env = "GH_HOST")]
1666        hostname: Option<String>,
1667    },
1668}
1669
1670/// Subcommands for `gor variable`.
1671#[derive(Subcommand, Debug)]
1672pub enum VariableCommand {
1673    /// List variables.
1674    List {
1675        /// Organization to list variables for.
1676        #[arg(long)]
1677        org: Option<String>,
1678        /// Environment name for environment-scoped variables.
1679        #[arg(short = 'e', long)]
1680        env: Option<String>,
1681        /// Output as JSON. Optionally specify comma-separated field names.
1682        #[arg(long, num_args = 0.., value_delimiter = ',')]
1683        json: Option<Vec<String>>,
1684        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
1685        #[arg(long, env = "GH_HOST")]
1686        hostname: Option<String>,
1687    },
1688    /// Set a variable.
1689    Set {
1690        /// Variable name.
1691        name: String,
1692        /// Variable value.
1693        #[arg(short = 'b', long)]
1694        body: Option<String>,
1695        /// Read variable value from a file.
1696        #[arg(short = 'f', long)]
1697        file: Option<String>,
1698        /// Organization to set the variable for.
1699        #[arg(long)]
1700        org: Option<String>,
1701        /// Environment name for environment-scoped variables.
1702        #[arg(short = 'e', long)]
1703        env: Option<String>,
1704        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
1705        #[arg(long, env = "GH_HOST")]
1706        hostname: Option<String>,
1707    },
1708    /// Delete a variable.
1709    Delete {
1710        /// Variable name to delete.
1711        name: String,
1712        /// Delete at the organization level.
1713        #[arg(long)]
1714        org: Option<String>,
1715        /// Environment name for environment-scoped variables.
1716        #[arg(short = 'e', long)]
1717        env: Option<String>,
1718        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
1719        #[arg(long, env = "GH_HOST")]
1720        hostname: Option<String>,
1721    },
1722}
1723
1724/// Subcommands for `gor run`.
1725#[derive(Subcommand, Debug)]
1726pub enum RunCommand {
1727    /// List workflow runs.
1728    List {
1729        /// Workflow filename or ID to filter by.
1730        #[arg(short = 'w', long)]
1731        workflow: Option<String>,
1732        /// Branch to filter by.
1733        #[arg(short = 'b', long)]
1734        branch: Option<String>,
1735        /// Repository (OWNER/REPO format). Auto-detected from git remote if omitted.
1736        #[arg(short = 'R', long)]
1737        repo: Option<String>,
1738        /// Maximum number of runs to show (default: 30).
1739        #[arg(short = 'L', long, default_value = "30")]
1740        limit: u32,
1741        /// Output as JSON. Optionally specify comma-separated field names.
1742        #[arg(long, num_args = 0.., value_delimiter = ',')]
1743        json: Option<Vec<String>>,
1744        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
1745        #[arg(long, env = "GH_HOST")]
1746        hostname: Option<String>,
1747    },
1748    /// View a workflow run's details and jobs.
1749    View {
1750        /// Run ID.
1751        id: u64,
1752        /// Repository (OWNER/REPO format). Auto-detected from git remote if omitted.
1753        #[arg(short = 'R', long)]
1754        repo: Option<String>,
1755        /// Open the run in the browser.
1756        #[arg(short = 'w', long)]
1757        web: bool,
1758        /// Show logs for a specific job.
1759        #[arg(long)]
1760        log: Option<u64>,
1761        /// Show logs only for failed jobs.
1762        #[arg(long)]
1763        log_failed: bool,
1764        /// Output as JSON. Optionally specify comma-separated field names.
1765        #[arg(long, num_args = 0.., value_delimiter = ',')]
1766        json: Option<Vec<String>>,
1767        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
1768        #[arg(long, env = "GH_HOST")]
1769        hostname: Option<String>,
1770    },
1771    /// Cancel a workflow run.
1772    Cancel {
1773        /// Run ID.
1774        id: u64,
1775        /// Repository (OWNER/REPO format). Auto-detected from git remote if omitted.
1776        #[arg(short = 'R', long)]
1777        repo: Option<String>,
1778        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
1779        #[arg(long, env = "GH_HOST")]
1780        hostname: Option<String>,
1781    },
1782    /// Download artifacts from a workflow run.
1783    Download {
1784        /// Run ID.
1785        id: u64,
1786        /// Repository (OWNER/REPO format). Auto-detected from git remote if omitted.
1787        #[arg(short = 'R', long)]
1788        repo: Option<String>,
1789        /// Output directory (default: current directory).
1790        #[arg(short = 'D', long, default_value = ".")]
1791        dir: String,
1792        /// Filter artifacts by name (repeatable).
1793        #[arg(long = "name")]
1794        names: Vec<String>,
1795        /// Download job logs instead of artifacts.
1796        #[arg(long)]
1797        log: bool,
1798        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
1799        #[arg(long, env = "GH_HOST")]
1800        hostname: Option<String>,
1801    },
1802    /// Rerun a workflow run.
1803    Rerun {
1804        /// Run ID.
1805        id: u64,
1806        /// Repository (OWNER/REPO format). Auto-detected from git remote if omitted.
1807        #[arg(short = 'R', long)]
1808        repo: Option<String>,
1809        /// Rerun only failed jobs.
1810        #[arg(long)]
1811        failed_jobs: bool,
1812        /// Enable debug logging for the rerun.
1813        #[arg(long)]
1814        debug: bool,
1815        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
1816        #[arg(long, env = "GH_HOST")]
1817        hostname: Option<String>,
1818    },
1819    /// Watch a workflow run until completion.
1820    Watch {
1821        /// Run ID.
1822        id: u64,
1823        /// Repository (OWNER/REPO format). Auto-detected from git remote if omitted.
1824        #[arg(short = 'R', long)]
1825        repo: Option<String>,
1826        /// Poll interval in seconds (default: 3).
1827        #[arg(long, default_value = "3")]
1828        interval: u64,
1829        /// Exit with the run's conclusion code.
1830        #[arg(long)]
1831        exit_status: bool,
1832        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
1833        #[arg(long, env = "GH_HOST")]
1834        hostname: Option<String>,
1835    },
1836    /// Delete a workflow run.
1837    Delete {
1838        /// Run ID to delete.
1839        id: u64,
1840        /// Repository (OWNER/REPO format). Auto-detected from git remote if omitted.
1841        #[arg(short = 'R', long)]
1842        repo: Option<String>,
1843        /// Skip confirmation prompt.
1844        #[arg(short = 'y', long)]
1845        yes: bool,
1846        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
1847        #[arg(long, env = "GH_HOST")]
1848        hostname: Option<String>,
1849    },
1850}
1851
1852/// Subcommands for `gor cache`.
1853#[derive(Subcommand, Debug)]
1854pub enum CacheCommand {
1855    /// List caches.
1856    List {
1857        /// Repository (OWNER/REPO format). Auto-detected from git remote if omitted.
1858        #[arg(short = 'R', long)]
1859        repo: Option<String>,
1860        /// Output as JSON. Optionally specify comma-separated field names.
1861        #[arg(long, num_args = 0.., value_delimiter = ',')]
1862        json: Option<Vec<String>>,
1863        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
1864        #[arg(long, env = "GH_HOST")]
1865        hostname: Option<String>,
1866    },
1867    /// Delete caches.
1868    Delete {
1869        /// Cache key to delete (exact match).
1870        key: Option<String>,
1871        /// Repository (OWNER/REPO format). Auto-detected from git remote if omitted.
1872        #[arg(short = 'R', long)]
1873        repo: Option<String>,
1874        /// Delete all caches in the repository.
1875        #[arg(long, conflicts_with = "key", conflicts_with = "key_prefix")]
1876        all: bool,
1877        /// Delete caches whose keys start with this prefix.
1878        #[arg(long, conflicts_with = "key", conflicts_with = "all")]
1879        key_prefix: Option<String>,
1880        /// Scope deletion to a specific branch/tag ref.
1881        #[arg(long, name = "ref")]
1882        ref_: Option<String>,
1883        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
1884        #[arg(long, env = "GH_HOST")]
1885        hostname: Option<String>,
1886    },
1887}
1888
1889/// Subcommands for `gor ruleset`.
1890#[derive(Subcommand, Debug)]
1891pub enum RulesetCommand {
1892    /// List rulesets.
1893    List {
1894        /// Repository (OWNER/REPO format). Auto-detected from git remote if omitted.
1895        #[arg(short = 'R', long)]
1896        repo: Option<String>,
1897        /// Output as JSON. Optionally specify comma-separated field names.
1898        #[arg(long, num_args = 0.., value_delimiter = ',')]
1899        json: Option<Vec<String>>,
1900        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
1901        #[arg(long, env = "GH_HOST")]
1902        hostname: Option<String>,
1903    },
1904    /// View a ruleset's details.
1905    View {
1906        /// Ruleset ID.
1907        id: u32,
1908        /// Repository (OWNER/REPO format). Auto-detected from git remote if omitted.
1909        #[arg(short = 'R', long)]
1910        repo: Option<String>,
1911        /// Open the ruleset in the browser.
1912        #[arg(short = 'w', long)]
1913        web: bool,
1914        /// Output as JSON. Optionally specify comma-separated field names.
1915        #[arg(long, num_args = 0.., value_delimiter = ',')]
1916        json: Option<Vec<String>>,
1917        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
1918        #[arg(long, env = "GH_HOST")]
1919        hostname: Option<String>,
1920    },
1921}
1922
1923/// Subcommands for `gor extension`.
1924#[derive(Subcommand, Debug)]
1925pub enum ExtensionCommand {
1926    /// List installed extensions.
1927    List {
1928        /// Output as JSON. Optionally specify comma-separated field names.
1929        #[arg(long, num_args = 0.., value_delimiter = ',')]
1930        json: Option<Vec<String>>,
1931        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
1932        #[arg(long, env = "GH_HOST")]
1933        hostname: Option<String>,
1934    },
1935    /// Install an extension.
1936    Install {
1937        /// Extension name or URL.
1938        name: String,
1939        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
1940        #[arg(long, env = "GH_HOST")]
1941        hostname: Option<String>,
1942    },
1943    /// Remove an extension.
1944    Remove {
1945        /// Extension name to remove.
1946        name: String,
1947        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
1948        #[arg(long, env = "GH_HOST")]
1949        hostname: Option<String>,
1950    },
1951    /// Upgrade extensions.
1952    Upgrade {
1953        /// Extension name to upgrade. If omitted with --all, upgrades all.
1954        name: Option<String>,
1955        /// Upgrade all installed extensions.
1956        #[arg(long, conflicts_with = "name")]
1957        all: bool,
1958        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
1959        #[arg(long, env = "GH_HOST")]
1960        hostname: Option<String>,
1961    },
1962}
1963
1964/// Subcommands for `gor codespace`.
1965#[derive(Subcommand, Debug)]
1966pub enum CodespaceCommand {
1967    /// List codespaces.
1968    List {
1969        /// Repository (OWNER/REPO format).
1970        #[arg(short = 'R', long)]
1971        repo: Option<String>,
1972        /// Output as JSON. Optionally specify comma-separated field names.
1973        #[arg(long, num_args = 0.., value_delimiter = ',')]
1974        json: Option<Vec<String>>,
1975        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
1976        #[arg(long, env = "GH_HOST")]
1977        hostname: Option<String>,
1978    },
1979    /// Create a codespace.
1980    Create {
1981        /// Repository (OWNER/REPO format).
1982        repo: String,
1983        /// Branch to create the codespace from.
1984        #[arg(short = 'b', long)]
1985        branch: Option<String>,
1986        /// Machine type.
1987        #[arg(long)]
1988        machine: Option<String>,
1989        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
1990        #[arg(long, env = "GH_HOST")]
1991        hostname: Option<String>,
1992    },
1993    /// Delete a codespace.
1994    Delete {
1995        /// Codespace name to delete.
1996        name: String,
1997        /// Repository to scope selection (OWNER/REPO format).
1998        #[arg(short = 'R', long)]
1999        repo: Option<String>,
2000        /// Skip confirmation prompt.
2001        #[arg(long)]
2002        yes: bool,
2003        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
2004        #[arg(long, env = "GH_HOST")]
2005        hostname: Option<String>,
2006    },
2007    /// View codespace logs.
2008    Logs {
2009        /// Codespace name.
2010        name: String,
2011        /// Repository to scope selection (OWNER/REPO format).
2012        #[arg(short = 'R', long)]
2013        repo: Option<String>,
2014        /// Output as JSON. Optionally specify comma-separated field names.
2015        #[arg(long, num_args = 0.., value_delimiter = ',')]
2016        json: Option<Vec<String>>,
2017        /// Follow log output until the codespace is ready.
2018        #[arg(short = 'f', long)]
2019        follow: bool,
2020        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
2021        #[arg(long, env = "GH_HOST")]
2022        hostname: Option<String>,
2023    },
2024    /// SSH into a codespace.
2025    Ssh {
2026        /// Codespace name.
2027        name: String,
2028        /// Repository to scope selection (OWNER/REPO format).
2029        #[arg(short = 'R', long)]
2030        repo: Option<String>,
2031        /// SSH config profile.
2032        #[arg(long)]
2033        profile: Option<String>,
2034        /// Print SSH connection config instead of connecting.
2035        #[arg(long)]
2036        config: bool,
2037        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
2038        #[arg(long, env = "GH_HOST")]
2039        hostname: Option<String>,
2040    },
2041    /// Stop a codespace.
2042    Stop {
2043        /// Codespace name to stop.
2044        name: Option<String>,
2045        /// Repository to scope selection (OWNER/REPO format).
2046        #[arg(short = 'R', long)]
2047        repo: Option<String>,
2048        /// Stop all codespaces owned by the user.
2049        #[arg(long, conflicts_with = "name")]
2050        all: bool,
2051        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
2052        #[arg(long, env = "GH_HOST")]
2053        hostname: Option<String>,
2054    },
2055    /// Copy files between local and remote codespace.
2056    Cp {
2057        /// Codespace name.
2058        name: String,
2059        /// Source and destination paths (use `remote:` prefix for codespace paths).
2060        /// The last path is the destination, all others are sources.
2061        #[arg(required = true)]
2062        paths: Vec<String>,
2063        /// Recursively copy directories.
2064        #[arg(short = 'r', long)]
2065        recursive: bool,
2066        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
2067        #[arg(long, env = "GH_HOST")]
2068        hostname: Option<String>,
2069    },
2070    /// List forwarded ports for a codespace.
2071    Ports {
2072        /// Codespace name.
2073        name: String,
2074        /// Output as JSON. Optionally specify comma-separated field names.
2075        #[arg(long, num_args = 0.., value_delimiter = ',')]
2076        json: Option<Vec<String>>,
2077        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
2078        #[arg(long, env = "GH_HOST")]
2079        hostname: Option<String>,
2080    },
2081    /// Rebuild a codespace from its devcontainer configuration.
2082    Rebuild {
2083        /// Codespace name.
2084        name: String,
2085        /// Skip confirmation prompt.
2086        #[arg(short = 'y', long)]
2087        yes: bool,
2088        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
2089        #[arg(long, env = "GH_HOST")]
2090        hostname: Option<String>,
2091    },
2092}
2093
2094/// Subcommands for `gor alias`.
2095#[derive(Subcommand, Debug)]
2096pub enum AliasCommand {
2097    /// List aliases.
2098    List {
2099        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
2100        #[arg(long, env = "GH_HOST")]
2101        hostname: Option<String>,
2102    },
2103    /// Set an alias.
2104    Set {
2105        /// Alias name.
2106        name: String,
2107        /// Command to alias (with arguments).
2108        command: Vec<String>,
2109        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
2110        #[arg(long, env = "GH_HOST")]
2111        hostname: Option<String>,
2112    },
2113    /// Delete an alias.
2114    Delete {
2115        /// Alias name to delete.
2116        name: String,
2117        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
2118        #[arg(long, env = "GH_HOST")]
2119        hostname: Option<String>,
2120    },
2121}
2122
2123/// Subcommands for `gor project`.
2124#[derive(Subcommand, Debug)]
2125pub enum ProjectCommand {
2126    /// List projects.
2127    List {
2128        /// Organization to list projects for.
2129        #[arg(long, conflicts_with_all = ["owner", "repo"])]
2130        org: Option<String>,
2131        /// User to list projects for.
2132        #[arg(long, conflicts_with_all = ["org", "repo"])]
2133        owner: Option<String>,
2134        /// Repository (OWNER/REPO format). Auto-detected from git remote if omitted.
2135        #[arg(short = 'R', long, conflicts_with_all = ["org", "owner"])]
2136        repo: Option<String>,
2137        /// Use Projects V2 (GraphQL) instead of classic Projects (REST).
2138        #[arg(long)]
2139        v2: bool,
2140        /// Maximum number of projects to show (default: 30).
2141        #[arg(short = 'L', long, default_value = "30")]
2142        limit: u32,
2143        /// Output as JSON. Optionally specify comma-separated field names.
2144        #[arg(long, num_args = 0.., value_delimiter = ',')]
2145        json: Option<Vec<String>>,
2146        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
2147        #[arg(long, env = "GH_HOST")]
2148        hostname: Option<String>,
2149    },
2150    /// View a project's details.
2151    View {
2152        /// Project number.
2153        number: u64,
2154        /// Organization that owns the project.
2155        #[arg(long, conflicts_with = "owner")]
2156        org: Option<String>,
2157        /// User that owns the project.
2158        #[arg(long, conflicts_with = "org")]
2159        owner: Option<String>,
2160        /// Open the project in the browser.
2161        #[arg(short = 'w', long)]
2162        web: bool,
2163        /// Output as JSON. Optionally specify comma-separated field names.
2164        #[arg(long, num_args = 0.., value_delimiter = ',')]
2165        json: Option<Vec<String>>,
2166        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
2167        #[arg(long, env = "GH_HOST")]
2168        hostname: Option<String>,
2169    },
2170    /// Add an item to a project.
2171    ItemAdd {
2172        /// Project number.
2173        #[arg(long)]
2174        project: u64,
2175        /// Issue number to add.
2176        #[arg(long, conflicts_with = "pull_request")]
2177        issue: Option<u64>,
2178        /// Pull request number to add.
2179        #[arg(long = "pr", conflicts_with = "issue")]
2180        pull_request: Option<u64>,
2181        /// Organization that owns the project.
2182        #[arg(long, conflicts_with = "owner")]
2183        org: Option<String>,
2184        /// User that owns the project.
2185        #[arg(long, conflicts_with = "org")]
2186        owner: Option<String>,
2187        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
2188        #[arg(long, env = "GH_HOST")]
2189        hostname: Option<String>,
2190    },
2191}
2192
2193/// Subcommands for `gor attestation`.
2194#[derive(Subcommand, Debug)]
2195pub enum AttestationCommand {
2196    /// Verify an artifact attestation.
2197    Verify {
2198        /// File to verify.
2199        file: String,
2200        /// Expected artifact owner/organization.
2201        #[arg(long)]
2202        owner: Option<String>,
2203        /// Repository to scope verification to.
2204        #[arg(long)]
2205        repo: Option<String>,
2206        /// Local Sigstore bundle file instead of fetching from API.
2207        #[arg(long)]
2208        bundle: Option<String>,
2209        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
2210        #[arg(long, env = "GH_HOST")]
2211        hostname: Option<String>,
2212    },
2213}
2214
2215/// Subcommands for `gor classroom`.
2216#[derive(Subcommand, Debug)]
2217pub enum ClassroomCommand {
2218    /// List classrooms.
2219    List {
2220        /// Output as JSON. Optionally specify comma-separated field names.
2221        #[arg(long, num_args = 0.., value_delimiter = ',')]
2222        json: Option<Vec<String>>,
2223        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
2224        #[arg(long, env = "GH_HOST")]
2225        hostname: Option<String>,
2226    },
2227    /// List assignments for a classroom.
2228    Assignments {
2229        /// Classroom ID.
2230        id: u64,
2231        /// Output as JSON. Optionally specify comma-separated field names.
2232        #[arg(long, num_args = 0.., value_delimiter = ',')]
2233        json: Option<Vec<String>>,
2234        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
2235        #[arg(long, env = "GH_HOST")]
2236        hostname: Option<String>,
2237    },
2238}
2239
2240/// Subcommands for `gor copilot`.
2241#[derive(Subcommand, Debug)]
2242pub enum CopilotCommand {
2243    /// Show Copilot subscription status.
2244    Status {
2245        /// Output as JSON. Optionally specify comma-separated field names.
2246        #[arg(long, num_args = 0.., value_delimiter = ',')]
2247        json: Option<Vec<String>>,
2248        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
2249        #[arg(long, env = "GH_HOST")]
2250        hostname: Option<String>,
2251    },
2252    /// Show Copilot usage statistics for an organization.
2253    Usage {
2254        /// Organization to query usage for.
2255        #[arg(long)]
2256        org: Option<String>,
2257        /// Output as JSON. Optionally specify comma-separated field names.
2258        #[arg(long, num_args = 0.., value_delimiter = ',')]
2259        json: Option<Vec<String>>,
2260        /// GitHub hostname for GitHub Enterprise Server (default: github.com).
2261        #[arg(long, env = "GH_HOST")]
2262        hostname: Option<String>,
2263    },
2264}