Files
gitea-axi/.claude/gh-axi-interface.md

1790 lines
50 KiB
Markdown

# gh-axi Interface Reference
This document describes the complete user-facing interface of gh-axi as implemented in the source.
It is intended to be used as a conformance target for gitea-axi's implementation.
All output is TOON-encoded.
The TOON block type names (`pull_requests`, `issues`, `comment`, etc.) are exact — do not substitute synonyms.
---
## Table of Contents
1. [Invocation and Installation](#invocation-and-installation)
2. [Top-Level Flags](#top-level-flags)
3. [Repository and Host Targeting](#repository-and-host-targeting)
4. [Exit Codes](#exit-codes)
5. [Output Structure and TOON Encoding](#output-structure-and-toon-encoding)
6. [Count Line Format](#count-line-format)
7. [Truncation Behaviour](#truncation-behaviour)
8. [Suggestion / Help Lines](#suggestion--help-lines)
9. [Error Handling](#error-handling)
10. [Home / Dashboard](#home--dashboard)
11. [issue list](#issue-list)
12. [issue view](#issue-view)
13. [issue create](#issue-create)
14. [issue edit](#issue-edit)
15. [issue close](#issue-close)
16. [issue reopen](#issue-reopen)
17. [issue comment](#issue-comment)
18. [issue delete](#issue-delete)
19. [issue lock](#issue-lock)
20. [issue unlock](#issue-unlock)
21. [issue pin](#issue-pin)
22. [issue unpin](#issue-unpin)
23. [issue transfer](#issue-transfer)
24. [issue subissue add](#issue-subissue-add)
25. [issue subissue remove](#issue-subissue-remove)
26. [issue subissue list](#issue-subissue-list)
27. [pr list](#pr-list)
28. [pr view](#pr-view)
29. [pr create](#pr-create)
30. [pr edit](#pr-edit)
31. [pr close](#pr-close)
32. [pr merge](#pr-merge)
33. [pr review](#pr-review)
34. [pr checks](#pr-checks)
35. [pr diff](#pr-diff)
36. [pr checkout](#pr-checkout)
37. [pr ready](#pr-ready)
38. [pr reopen](#pr-reopen)
39. [pr comment](#pr-comment)
40. [pr update-branch](#pr-update-branch)
41. [pr revert](#pr-revert)
42. [label list](#label-list)
43. [label create](#label-create)
44. [label edit](#label-edit)
45. [label delete](#label-delete)
---
## Invocation and Installation
```
npx -y gh-axi <command> [subcommand] [args] [flags]
```
gh-axi requires the `gh` CLI installed and authenticated.
When `gh` is absent, the error code is `GH_NOT_INSTALLED` with the message:
`gh CLI is not installed — see https://cli.github.com`
---
## Top-Level Flags
These flags are processed by the SDK harness before any command runs.
They are accepted anywhere in the argument list after the binary name.
| Flag | Aliases | Description |
|------|---------|-------------|
| `--help` | `-h` | Show help for the current command |
| `--version` | `-v`, `-V` | Print the installed gh-axi version |
| `--repo <OWNER/NAME>` | `-R <OWNER/NAME>`, `--repo=<OWNER/NAME>`, `-R=<OWNER/NAME>` | Target a specific repository |
| `--hostname <host>` | `--hostname=<host>` | Target a custom GitHub Enterprise host |
The top-level help text is:
```
usage: gh-axi [command] [args] [flags]
commands[14]:
(none)=dashboard, issue, pr, run, workflow, release, repo, label, project, secret, variable, search, api, setup
flags[4]:
-R/--repo <OWNER/NAME> (after command), --hostname <host> (after command) or GH_HOST env, both flags accept space or equals form, --help, -v/-V/--version
examples:
gh-axi
gh-axi issue list --state open
gh-axi issue list -R owner/name
gh-axi issue list --repo=owner/name
gh-axi issue list --hostname git.example.com
gh-axi pr view 42
gh-axi secret list
gh-axi setup hooks
```
---
## Repository and Host Targeting
### -R / --repo flag
The `-R`/`--repo` flag must appear **after** the command (not before it):
```
gh-axi issue list -R owner/name # correct
gh-axi issue list --repo owner/name # correct
gh-axi issue list --repo=owner/name # correct
gh-axi issue list -R=owner/name # correct
gh-axi -R owner/name issue list # WRONG — not accepted
```
The `search` command is the sole exception: `--repo` is passed through to the underlying `gh` call in addition to being used for context resolution.
The `repo view` subcommand additionally accepts exactly one positional repository argument (`gh-axi repo view owner/name`) as a compatibility exception for `gh repo view [<repository>]`.
Do not combine the positional form with `--repo`.
### --hostname flag
`--hostname` must also appear after the command.
An explicit `--hostname` flag takes precedence over the `GH_HOST` environment variable.
When `--hostname` is present, `GH_HOST` is set to its value for the lifetime of the child `gh` process.
### Suggestion -R injection rule
When the current repo context was **not** inferred from the local git checkout (i.e. `ctx.source !== "git"`), suggestion lines include the repo flag.
The flag is placed **after** `gh-axi` and **before** the sub-command tokens using the `-R owner/name` form.
Template strings in the suggestions source use the pattern:
```
`gh-axi${repoFlag(c)} issue view <number>`
```
which expands to `` `gh-axi -R owner/name issue view <number>` `` when a non-git repo is active.
Suggestion lines are then post-processed by `normalizeRepoFlagLine`, which rewrites the anti-pattern `` `gh-axi -R <repo> <command>` `` to `` `gh-axi <command> -R <repo>` `` (flag after command).
When `--hostname` was supplied via flag (not env), all backtick-wrapped `gh-axi` commands in suggestions are also suffixed with ` --hostname <host>`.
---
## Exit Codes
gh-axi inherits exit code semantics from `axi-sdk-js`.
Verified against `axi-sdk-js@0.1.8` source: `exitCodeForError` returns 2 for `VALIDATION_ERROR` and 1 for every other error.
The mapping by error code is:
| AxiError code | Exit code |
|---|---|
| `REPO_NOT_FOUND` | 1 |
| `NOT_FOUND` | 1 |
| `AUTH_REQUIRED` | 1 |
| `FORBIDDEN` | 1 |
| `VALIDATION_ERROR` | 2 |
| `RATE_LIMITED` | 1 |
| `GH_NOT_INSTALLED` | 1 |
| `UNKNOWN` | 1 |
| Success | 0 |
---
## Output Structure and TOON Encoding
All output is TOON-encoded.
The SDK function `renderOutput(blocks: string[])` joins multiple TOON blocks into a single output string.
Common block types used across commands:
- `renderList(name, items, schema)` — a labelled list block; the name becomes the TOON block key (e.g. `issues:`, `pull_requests:`, `labels:`)
- `renderDetail(name, item, schema)` — a single-entity detail block
- `renderHelp(lines)` — a `help:` block containing suggestion lines
- `renderError(message, code, suggestions)` — an error block
- `encode(object)` — raw TOON encoding of a plain object
### Field definitions (schema primitives)
| Primitive | Description |
|---|---|
| `field(key)` | Outputs `key: value` verbatim |
| `field(key, alias)` | Outputs `alias: value` using `key` as the data lookup |
| `lower(key)` | Outputs value lowercased |
| `pluck(key, subkey, alias)` | Navigates `item[key][subkey]`, outputs as `alias` |
| `relativeTime(key, alias)` | Converts ISO timestamp to relative time string, outputs as `alias` |
| `joinArray(key, subkey, alias)` | Joins an array of objects by extracting `subkey` from each, comma-separated |
| `boolYesNo(key, alias)` | Outputs `yes` or `no` for a boolean |
| `mapEnum(key, map, default, alias)` | Maps enum strings; unknown values become `default` |
| `custom(alias, fn)` | Calls `fn(item)` and outputs result as `alias` |
---
## Count Line Format
The `formatCountLine` function produces one of four exact phrases depending on context:
| Condition | Output |
|---|---|
| `apiLimitHit === true` | `count: N+ (GitHub search API limit reached)` |
| `totalCount` is known from GraphQL | `count: N of T total` |
| `count > displayLimit` (display truncation) | `count: N (showing first D)` |
| `count === limit && count > 0` (hit request limit, no GraphQL total) | `count: N (showing first N)` |
| Otherwise | `count: N` |
Where:
- `N` = number of items returned
- `T` = true total from GraphQL
- `D` = display limit
For `issue list` and `pr list`: when `count === limit` and a `RepoContext` is available, gh-axi makes a GraphQL query for `totalCount`.
If the GraphQL call succeeds, the `count: N of T total` form is used.
If it fails, it falls back to `count: N (showing first N)`.
---
## Truncation Behaviour
### Body truncation (issues and PRs)
The `truncateBody(text, limit)` function truncates the body field.
- Issue `view` default schema: body truncated at **500 characters**.
- PR `view` default schema: body truncated at **500 characters**.
- Issue `comment` result schema: body truncated at **800 characters**.
When `--full` is passed to `issue view` or `pr view`, the body is output in full without truncation.
The exact hint text appended when truncation occurs is not directly visible in the schema — it is returned by `truncateBody` from `body.ts` (not provided in the fetched sources).
The `--full` flag is the documented way to bypass truncation.
### PR diff truncation
The `pr diff` subcommand truncates at **4000 characters** by default.
When truncated:
- The block contains `truncated: true` and `original_length: N`
- A suggestion is prepended: `` Run `gh-axi pr diff <num> --full` to see the complete diff ``
(with `-R owner/name` injected if non-git repo context)
When `--full` is passed, the full diff is output.
### Workflow log truncation
`run view --log` and `run view --log-failed` truncate at **20,000 characters** (tail kept).
When truncated, the complete log is best-effort saved to a temp file and exposed as a `full_log` field.
A `help:` hint tells agents to grep that file for earlier context.
---
## Suggestion / Help Lines
Every command ends with a `help:` block produced by `renderHelp(suggestions)`.
The suggestions are looked up from a static table by `(domain, action, isEmpty?, state?, id?)`.
Empty suggestions produce an empty `help:` block (not omitted).
### Issue suggestions
| Trigger | Suggestions |
|---|---|
| `issue list`, not empty | `` Run `gh-axi issue view <number>` to view details `` / `` Run `gh-axi issue create --title "..." --body-file <path>` to create `` |
| `issue list`, empty | `` Run `gh-axi issue create --title "..." --body-file <path>` to create an issue `` / `` Run `gh-axi issue list --state closed` to see closed issues `` |
| `issue view`, state=open | Comment / close / assign / search PRs suggestions |
| `issue view`, state=closed | Reopen / comment / search PRs suggestions |
| `issue create` | View / label suggestions with `id` filled |
| `issue edit` | `` Run `gh-axi issue view <id>` to see updated issue `` |
| `issue close` | `` Run `gh-axi issue reopen <id>` to reopen `` |
| `issue reopen` | Close / view suggestions |
| `issue comment` | `` Run `gh-axi issue view <id> --comments` to see all comments `` |
| `issue delete` | `` Run `gh-axi issue list` to see remaining issues `` |
| `issue lock`, `unlock`, `pin`, `unpin` | `` Run `gh-axi issue view <id>` to see issue details `` |
| `issue transfer` | (empty) |
### PR suggestions
| Trigger | Suggestions |
|---|---|
| `pr list`, not empty | View / create suggestions |
| `pr list`, empty | Create / closed-state suggestions |
| `pr view`, state=open | Checks / approve / merge suggestions |
| `pr view`, state=closed | `` Run `gh-axi pr reopen <id>` to reopen `` |
| `pr view`, state=merged | `` Run `gh-axi pr revert <id>` to revert `` |
| `pr create` | View / checks suggestions with `id` filled |
| `pr edit` | View suggestion |
| `pr close` | Reopen suggestion |
| `pr merge` | Revert suggestion |
| `pr review` | View suggestion |
| `pr checks` | View / merge suggestions |
| `pr diff` | Approve suggestion (plus truncation hint if truncated) |
| `pr checkout` | (empty) |
| `pr ready` | View suggestion |
| `pr reopen` | View suggestion |
| `pr comment` | `` Run `gh-axi pr view <id> --comments` to see all comments `` |
| `pr update-branch` | `` Run `gh-axi pr checks <id>` to monitor CI after update `` |
| `pr revert` | `` Run `gh-axi pr view <id>` to see the revert PR `` |
### Label suggestions
| Trigger | Suggestions |
|---|---|
| `label list` | `` Run `gh-axi label create --name "..." --color "..."` to create a label `` |
| `label create` | `` Run `gh-axi label list` to see all labels `` |
| `label edit` | `` Run `gh-axi label list` to see all labels `` |
| `label delete` | `` Run `gh-axi label list` to see remaining labels `` |
### Home suggestions
```
Run `gh-axi <command> <subcommand>` — commands: issue, pr, run, release, repo, label, secret, variable`
```
Additionally, if `issues.length >= 3`, a hint is prepended:
```
Run `gh-axi issue list` for full issue list
```
If `prs.length >= 3`, a hint is prepended:
```
Run `gh-axi pr list` for full PR list
```
---
## Error Handling
### AxiError codes
gh-axi defines these error codes (string literals):
```
REPO_NOT_FOUND | NOT_FOUND | AUTH_REQUIRED | FORBIDDEN |
VALIDATION_ERROR | RATE_LIMITED | GH_NOT_INSTALLED | UNKNOWN
```
### mapGhError — pattern-matched gh stderr
When a `gh` subprocess fails, `mapGhError(stderr, exitCode)` converts the raw stderr to a structured `AxiError`:
| Matched pattern | Code | Message |
|---|---|---|
| `Could not resolve to a Repository with the name '<name>'` | `REPO_NOT_FOUND` | `Repository "<name>" not found` |
| `Could not resolve to an? ... with the number of N` | `NOT_FOUND` | `Item #N does not exist in this repository` |
| `issue N not found` (case-insensitive) | `NOT_FOUND` | `Issue #N does not exist` |
| `pull request N not found` (case-insensitive) | `NOT_FOUND` | `Pull request #N does not exist` |
| `release with tag "T" not found` (case-insensitive) | `NOT_FOUND` | `Release "T" not found` |
| `run N not found` (case-insensitive) | `NOT_FOUND` | `Run N not found` |
| `gh auth login` (appears in stderr) | `AUTH_REQUIRED` | `GitHub auth required — run \`gh auth login\` first` |
| `authentication token is missing required scopes [S]` | `FORBIDDEN` | `GitHub token is missing required scope(s): S` |
| `secondary rate limit` | `RATE_LIMITED` | `GitHub secondary rate limit hit — wait ~60s and retry` |
| `API rate limit ... exceeded` | `RATE_LIMITED` | `GitHub API rate limit exceeded` |
| `sub-issue is already a sub-issue of issue with number N` | `VALIDATION_ERROR` | `Issue is already a sub-issue of #N` |
| `sub-?issue.*?(cycle\|circular)` | `VALIDATION_ERROR` | `Cannot add sub-issue: would create a cycle` |
| `issue cannot be a sub-?issue of itself` | `VALIDATION_ERROR` | `An issue cannot be a sub-issue of itself` |
| `HTTP 403` | `FORBIDDEN` | `Insufficient permissions for this action` |
| `HTTP 422` | `VALIDATION_ERROR` | Extracted `"message"` field from JSON body, or `Validation error` |
| `not found` (generic fallback, case-insensitive) | `NOT_FOUND` | First line of stderr |
| (no match) | `UNKNOWN` | First line of stderr, or `gh exited with code N` |
### Validation errors (argument-level)
These are thrown by command handlers before calling `gh`:
| Command | Condition | Message |
|---|---|---|
| `issue list` | `--search` flag present | `issue list does not support --search. Use \`gh-axi search issues "<query>"\` instead for full-text search with total counts.` |
| `pr list` | `--search` flag present | `pr list does not support --search. Use \`gh-axi search prs "<query>"\` instead for full-text search with total counts.` |
| `issue create` | `--title` absent | `--title is required` |
| `pr create` | `--title` absent | `--title is required` |
| `issue comment` | `--body` / `--body-file` absent | (from `takeBody` with `required: true`) |
| `pr comment` | `--body` / `--body-file` absent | (from `takeBody` with `required: true`) |
| `issue transfer` | `--to-repo` absent | `--to-repo is required for transfer` |
| `label create` | `--name` absent | `--name is required: gh-axi label create --name "..." --color "..."` |
| `label create` | `--color` absent | `--color is required: gh-axi label create --name "..." --color "..."` |
| `label edit` | positional name absent | `Label name is required: gh-axi label edit <name>` |
| `label delete` | positional name absent | `Label name is required: gh-axi label delete <name>` |
| `pr merge` | multiple method flags | `Choose only one merge method: --merge, --squash, or --rebase` |
| `pr merge` | `--method` and shorthand conflict | `Choose either --method or a matching merge method shorthand, not both` |
| `pr merge` | invalid `--method` value | `--method must be one of: merge, squash, rebase` |
| `issue subissue add` | no `--repo` context | `Could not determine repository — pass --repo <owner/name> or run inside a git checkout` |
| `issue subissue add` | no child numbers | `subissue add requires at least one child issue number` |
| `issue subissue remove` | no `--repo` context | `Could not determine repository — pass --repo <owner/name> or run inside a git checkout` |
| `issue subissue remove` | no child number | `subissue remove requires a child issue number` |
| `issue subissue list` | no `--repo` context | `Could not determine repository — pass --repo <owner/name> or run inside a git checkout` |
| `issue view`, `issue edit`, etc. | numeric arg missing | `Missing issue number` |
| `pr view`, `pr merge`, etc. | numeric arg missing | `Missing PR number` |
| issue type invalid | type name not found | `Unknown issue type "<name>". Available types: A, B, C` |
| issue type not configured | no types configured | `Issue types are not configured for this repository. Enable them in repo settings before using --type.` |
### Unknown subcommand errors
| Command | Message | Code | Suggestions |
|---|---|---|---|
| `issue <unknown>` | `Unknown issue subcommand: <sub>` | `VALIDATION_ERROR` | `Run \`gh-axi issue --help\` for usage` |
| `issue subissue <unknown>` | `Unknown subissue subcommand: <sub>` | `VALIDATION_ERROR` | `Run \`gh-axi issue subissue --help\` for usage` |
| `pr <unknown>` | `Unknown pr subcommand: <sub>` | `VALIDATION_ERROR` | `Run \`gh-axi pr --help\` to see available subcommands` |
| `label <unknown>` | `Unknown subcommand: <sub>` | `VALIDATION_ERROR` | `Available subcommands: list, create, edit, delete` |
---
## Home / Dashboard
**Invocation:** `gh-axi` (no command)
Runs `issue list` and `pr list` in parallel, each limited to 3 items.
### Output structure
```
repo: owner/name ← only when RepoContext is present
issues:
- number: 1
title: ...
state: open
author: alice
prs:
- number: 42
title: ...
author: bob
review: none
help:
- Run `gh-axi issue list` for full issue list ← only when issues.length >= 3
- Run `gh-axi pr list` for full PR list ← only when prs.length >= 3
- Run `gh-axi <command> <subcommand>` — commands: issue, pr, run, release, repo, label, secret, variable
```
When there are no open issues: `issues: 0 open` (raw string, not a list block).
When there are no open PRs: `prs: 0 open` (raw string, not a list block).
### Issue schema (home)
| Output field | Source |
|---|---|
| `number` | `number` |
| `title` | `title` |
| `state` | `state` lowercased |
| `author` | `author.login` |
### PR schema (home)
| Output field | Source |
|---|---|
| `number` | `number` |
| `title` | `title` |
| `author` | `author.login` |
| `review` | `reviewDecision` mapped: `APPROVED`→`approved`, `CHANGES_REQUESTED`→`changes_requested`, `REVIEW_REQUIRED`→`required`, otherwise→`none` |
---
## issue list
**Invocation:** `gh-axi issue list [flags]`
### Flags
| Flag | Type | Default | Required |
|---|---|---|---|
| `--state <open\|closed\|all>` | string | (not passed; gh default is `open`) | no |
| `--label <name>` | string | — | no |
| `--assignee <login>` | string | — | no |
| `--author <login>` | string | — | no |
| `--milestone <name>` | string | — | no |
| `--sort <created\|updated\|comments>` | string | — | no |
| `--limit <n>` | integer | `30` | no |
| `--fields <a,b,c>` | comma-separated | — | no |
| `--search` | boolean | — | forbidden (throws `VALIDATION_ERROR`) |
Note: `--sort` is implemented by appending `--search sort:<value>-desc` to the underlying `gh issue list` call.
### Default output fields
TOON block name: `issues`
| Output field | Source |
|---|---|
| `number` | `number` |
| `title` | `title` |
| `state` | `state` lowercased |
| `author` | `author.login` |
| `created` | `createdAt` as relative time |
### Extra fields via --fields
| Name | Output field | Source |
|---|---|---|
| `body` | `body` | `body` verbatim |
| `closedAt` | `closed_at` | `closedAt` as relative time |
| `labels` | `labels` | `labels[].name` joined |
| `milestone` | `milestone` | `milestone.title` |
| `updatedAt` | `updated_at` | `updatedAt` as relative time |
| `url` | `url` | `url` verbatim |
### Output structure
```
count: N [of T total | (showing first N)]
issues:
- number: 1
title: Fix login bug
state: open
author: alice
created: 2 days ago
help:
- Run `gh-axi issue view <number>` to view details
- Run `gh-axi issue create --title "..." --body-file <path>` to create
```
### Empty state
When no issues are found, `count: 0` is shown and the list block is empty.
The `help:` suggestions switch to the empty-list variant:
```
help:
- Run `gh-axi issue create --title "..." --body-file <path>` to create an issue
- Run `gh-axi issue list --state closed` to see closed issues
```
### Count line
- If `count < limit`: `count: N`
- If `count === limit` and GraphQL succeeds: `count: N of T total`
- If `count === limit` and GraphQL fails: `count: N (showing first N)`
---
## issue view
**Invocation:** `gh-axi issue view <number> [flags]`
### Flags
| Flag | Type | Default | Required |
|---|---|---|---|
| `--comments` | boolean | false | no |
| `--full` | boolean | false | no |
### Default output fields
TOON block name: `issue`
| Output field | Source | Notes |
|---|---|---|
| `number` | `number` | |
| `title` | `title` | |
| `state` | `state` lowercased | |
| `author` | `author.login` | |
| `created` | `createdAt` as relative time | |
| `type` | `issueType.name` | `"none"` if issueType absent/empty; field omitted entirely if the host does not support `issueType` in `gh issue view --json` |
| `body` | `body` truncated at 500 chars | Full text when `--full` is passed |
| `subissues` | GraphQL sub-issues | e.g. `["#20", "#101"]`; omitted if no sub-issues |
| `parent` | GraphQL parent | e.g. `"#16"`; omitted if no parent |
Sub-issue and parent fields require `RepoContext`.
If the GraphQL call for sub-issue relationships fails, those fields are silently omitted.
### Comments output
When `--comments` is passed, a separate `comments` list block is appended:
TOON block name: `comments`
| Output field | Source |
|---|---|
| `author` | `comments[].author.login` |
| `created` | `comments[].createdAt` as relative time |
| `body` | `comments[].body` truncated at 800 chars |
Note: the `number` (issue) field is **not** shown in the comment list when rendered as a sub-block.
---
## issue create
**Invocation:** `gh-axi issue create --title <text> [flags]`
### Flags
| Flag | Type | Default | Required |
|---|---|---|---|
| `--title <text>` | string | — | **yes** |
| `--body <text>` | string | — | no |
| `--body-file <path>` | path | — | no |
| `--assignee <login>` | string | — | no |
| `--label <name>` | string (repeatable) | — | no |
| `--milestone <name>` | string | — | no |
| `--project <name>` | string | — | no |
| `--type <name>` | string | — | no |
`--body` and `--body-file` are mutually exclusive alternatives (handled by `takeBody`).
### Default output fields
TOON block name: `issue`
| Output field | Source |
|---|---|
| `number` | `number` |
| `title` | `title` |
| `state` | `state` lowercased |
| `url` | `url` |
| `type` | `issueType.name` — only present when `--type` was supplied |
### Idempotency
`issue create` is **not** idempotent.
Each call creates a new issue regardless of title or content.
### Suggestions
After creation, `id` is set to the newly created issue number:
```
help:
- Run `gh-axi issue view <new-number>` to see the full issue
- Run `gh-axi issue edit <new-number> --add-label <label>` to label
```
---
## issue edit
**Invocation:** `gh-axi issue edit <number> [flags]`
### Flags
| Flag | Type | Default | Required |
|---|---|---|---|
| `--title <text>` | string | — | no |
| `--body <text>` | string | — | no |
| `--body-file <path>` | path | — | no |
| `--add-label <name>` | string | — | no |
| `--remove-label <name>` | string | — | no |
| `--add-assignee <login>` | string | — | no |
| `--remove-assignee <login>` | string | — | no |
| `--milestone <name>` | string | — | no |
| `--type <name>` | string | — | no |
| `--no-type` | boolean | false | no |
`--type` and `--no-type` are mutually exclusive.
`--no-type` removes the issue type (sets `issueTypeId: null` via GraphQL).
### Default output fields
TOON block name: `issue`
| Output field | Source |
|---|---|
| `number` | `number` |
| `title` | `title` |
| `state` | `state` lowercased |
| `labels` | `labels[].name` joined |
| `assignees` | `assignees[].login` joined |
| `type` | `issueType.name` — only present when `--type` or `--no-type` was supplied |
### Implementation note
If no non-type fields are provided (only `--type` or `--no-type`), the underlying `gh issue edit` call is **skipped** and only the GraphQL type mutation is performed.
---
## issue close
**Invocation:** `gh-axi issue close <number> [flags]`
### Flags
| Flag | Type | Default | Required |
|---|---|---|---|
| `--reason <completed\|not_planned>` | string | — | no |
| `--comment <text>` | string | — | no |
### Default output fields
TOON block name: `issue`
| Output field | Source |
|---|---|
| `number` | `number` |
| `state` | `state` lowercased |
### Idempotency
If the issue is already closed, the command returns without calling `gh issue close`.
Output adds a `message: Already closed` field:
```
issue:
number: 42
state: closed
message: Already closed
```
---
## issue reopen
**Invocation:** `gh-axi issue reopen <number>`
### Flags
None.
### Default output fields
TOON block name: `issue`
| Output field | Source |
|---|---|
| `number` | `number` |
| `state` | `state` lowercased |
### Idempotency
If the issue is already open, the command returns without calling `gh issue reopen`.
Output adds `message: Already open`:
```
issue:
number: 42
state: open
message: Already open
```
---
## issue comment
**Invocation:** `gh-axi issue comment <number> --body <text>`
### Flags
| Flag | Type | Default | Required |
|---|---|---|---|
| `--body <text>` | string | — | **yes** |
| `--body-file <path>` | path | — | **yes** (alternative to `--body`) |
Either `--body` or `--body-file` must be supplied.
### Default output fields
TOON block name: `comment`
| Output field | Source |
|---|---|
| `issue` | issue number (via `field("number", "issue")`) |
| `author` | `author.login` of the newly created comment |
| `created` | `createdAt` of the new comment as relative time |
| `body` | comment body truncated at 800 chars |
The comment data is retrieved by fetching all comments and taking the last one.
---
## issue delete
**Invocation:** `gh-axi issue delete <number>`
### Flags
None.
The underlying `gh issue delete --yes` is called (no confirmation prompt).
### Default output fields
TOON block name: `issue`
| Output field | Source |
|---|---|
| `number` | `number` (the deleted issue number) |
| `status` | literal string `"deleted"` |
---
## issue lock
**Invocation:** `gh-axi issue lock <number>`
### Flags
None.
### Default output fields
TOON block name: `issue`
| Output field | Source |
|---|---|
| `number` | `number` |
| `state` | `state` lowercased |
| `locked` | boolean |
### Idempotency
If the issue is already locked, no `gh` call is made.
Output adds `message: Already locked`.
---
## issue unlock
**Invocation:** `gh-axi issue unlock <number>`
### Flags
None.
### Default output fields
TOON block name: `issue`
| Output field | Source |
|---|---|
| `number` | `number` |
| `state` | `state` lowercased |
| `locked` | boolean |
### Idempotency
If the issue is already unlocked, no `gh` call is made.
Output adds `message: Already unlocked`.
---
## issue pin
**Invocation:** `gh-axi issue pin <number>`
### Flags
None.
### Default output fields
TOON block name: `issue`
| Output field | Source |
|---|---|
| `number` | `number` |
| `state` | `state` lowercased |
| `pinned` | `isPinned` boolean (output key is `pinned`, source field is `isPinned`) |
### Idempotency
If the issue is already pinned, no `gh` call is made.
Output adds `message: Already pinned`.
---
## issue unpin
**Invocation:** `gh-axi issue unpin <number>`
### Flags
None.
### Default output fields
TOON block name: `issue`
| Output field | Source |
|---|---|
| `number` | `number` |
| `state` | `state` lowercased |
| `pinned` | `isPinned` boolean (output key is `pinned`) |
### Idempotency
If the issue is already unpinned, no `gh` call is made.
Output adds `message: Already unpinned`.
---
## issue transfer
**Invocation:** `gh-axi issue transfer <number> --to-repo <owner/name>`
### Flags
| Flag | Type | Default | Required |
|---|---|---|---|
| `--to-repo <owner/name>` | string | — | **yes** |
When transferring across repos, use `-R source/repo` to set the source and `--to-repo dest/repo` for the destination:
```
gh-axi issue transfer 42 -R source/repo --to-repo dest/repo
```
### Default output fields
TOON block name: `issue`
| Output field | Source |
|---|---|
| `number` | new number in destination repo (or original if lookup fails) |
| `url` | URL of the transferred issue in the destination repo |
### Idempotency
Not idempotent.
Transfer is a one-way operation; errors come from `gh`.
### Suggestions
Transfer always produces empty suggestions (the table entry returns `[]`).
---
## issue subissue add
**Invocation:** `gh-axi issue subissue add <parent> <child> [<child> ...]`
Requires `RepoContext` (pass `-R owner/name` if not in a git checkout).
### Arguments
| Argument | Description |
|---|---|
| `<parent>` | Issue number of the parent |
| `<child> [<child> ...]` | One or more child issue numbers |
### Default output fields
TOON block name: `subissue_add`
| Output field | Source |
|---|---|
| `parent` | `"#<parentNumber>"` |
| `added` | array of `"#<number>"` strings for each successfully added child |
### Suggestion
```
Run `gh-axi issue view <parent-number>` to see the parent with its sub-issues
```
### Error behaviour
If adding a subsequent child fails after some children were already added, the error message includes:
```
<original error message>
Added before failure: #N1, #N2
```
---
## issue subissue remove
**Invocation:** `gh-axi issue subissue remove <parent> <child>`
Requires `RepoContext`.
### Arguments
| Argument | Description |
|---|---|
| `<parent>` | Issue number of the parent |
| `<child>` | Issue number of the child to remove |
### Default output fields
TOON block name: `subissue_remove`
| Output field | Source |
|---|---|
| `parent` | `"#<parentNumber>"` |
| `removed` | `"#<childNumber>"` |
### Idempotency
No idempotency check.
If the child is not a sub-issue, the GraphQL mutation returns an error which propagates as-is.
### Suggestion
```
Run `gh-axi issue subissue list <parent-number>` to see remaining sub-issues
```
---
## issue subissue list
**Invocation:** `gh-axi issue subissue list <parent>`
Requires `RepoContext`.
Fetches up to **100** sub-issues via GraphQL.
### Arguments
| Argument | Description |
|---|---|
| `<parent>` | Issue number of the parent |
### Default output fields
Count line appears first, then:
Header line (raw string): `parent: #<parentNumber>`
TOON block name: `subissues`
| Output field | Source |
|---|---|
| `number` | `number` |
| `title` | `title` |
| `state` | `state` lowercased |
### Count line
Uses `formatCountLine` with `limit: 100` and `totalCount` from GraphQL.
So if there are exactly 100 sub-issues, the count line will show `count: 100 of T total` if totalCount is available.
---
## pr list
**Invocation:** `gh-axi pr list [flags]`
### Flags
| Flag | Type | Default | Required |
|---|---|---|---|
| `--state <open\|closed\|all>` | string | `open` | no |
| `--label <name>` | string | — | no |
| `--assignee <login>` | string | — | no |
| `--author <login>` | string | — | no |
| `--base <branch>` | string | — | no |
| `--head <branch>` | string | — | no |
| `--draft` | boolean | false | no |
| `--limit <n>` | integer | `30` | no |
| `--fields <a,b,c>` | comma-separated | — | no |
| `--search` | — | — | forbidden (throws `VALIDATION_ERROR`) |
Note: `--state` defaults to `"open"` (always passed to `gh pr list`).
### Default output fields
TOON block name: `pull_requests`
| Output field | Source |
|---|---|
| `number` | `number` |
| `title` | `title` |
| `state` | `state` lowercased |
| `author` | `author.login` |
| `draft` | `isDraft` as `yes`/`no` |
| `review` | `reviewDecision` mapped: `APPROVED`→`approved`, `CHANGES_REQUESTED`→`changes_requested`, `REVIEW_REQUIRED`→`required`, otherwise→`none` |
### Extra fields via --fields
| Name | Output field | Source |
|---|---|---|
| `body` | `body` | `body` verbatim |
| `createdAt` | `created` | `createdAt` as relative time |
| `labels` | `labels` | `labels[].name` joined |
| `milestone` | `milestone` | `milestone.title` |
| `mergedAt` | `merged_at` | `mergedAt` as relative time |
| `url` | `url` | `url` verbatim |
### Count line
Same logic as `issue list`.
For `--state closed`, the GraphQL query filters `states:[CLOSED,MERGED]`.
For `--state all`, no `states` filter is applied.
### Empty state message
When `count: 0`, the help suggestions switch to:
```
help:
- Run `gh-axi pr create --title "..." --body-file <path>` to create a PR
- Run `gh-axi pr list --state closed` to see closed PRs
```
---
## pr view
**Invocation:** `gh-axi pr view <number> [flags]`
### Flags
| Flag | Type | Default | Required |
|---|---|---|---|
| `--comments` | boolean | false | no |
| `--reviews` | boolean | false | no |
| `--full` | boolean | false | no |
### Default output fields
TOON block name: `pull_request`
| Output field | Source | Notes |
|---|---|---|
| `number` | `number` | |
| `title` | `title` | |
| `state` | `state` lowercased | |
| `author` | `author.login` | |
| `draft` | `isDraft` as `yes`/`no` | |
| `merged` | computed | `"no"` if not merged; `mergedAt` value if state is `MERGED` |
| `checks` | computed from `statusCheckRollup` | `"N passed, N failed[, N skipped], N total"` or `"0 passed, 0 failed — this PR has no CI checks configured"` |
| `body` | `body` truncated at 500 chars | Full text when `--full` |
| `comment_count` | computed | `"N — use --comments to see full comments"` (when `--comments` not passed) |
| `comments` | full array | Present only when `--comments` is passed (replaces `comment_count`) |
| `review_count` | computed | `"N — use --reviews to see full reviews"` (when `--reviews` not passed) |
| `reviews` | full array | Present only when `--reviews` is passed (replaces `review_count`) |
### checks field format
When checks are configured:
```
checks: 3 passed, 1 failed, 1 skipped, 5 total
```
When no checks are configured:
```
checks: 0 passed, 0 failed — this PR has no CI checks configured
```
CI check classification:
- `pass`: conclusion is `SUCCESS` or `NEUTRAL`
- `fail`: conclusion is `FAILURE`, `TIMED_OUT`, or `ACTION_REQUIRED`
- `skip`: conclusion is `SKIPPED` or `CANCELLED`, or state/status is `EXPECTED` or `NEUTRAL`
- `pending`: everything else
### merged field format
- PR not merged: `merged: no`
- PR merged: `merged: <mergedAt-ISO-string>` (the raw `mergedAt` value, not relative time)
### comments block (when --comments)
The `comments` field contains an array of objects:
```
comments:
- author: alice
body: <comment text>
created: <createdAt ISO string>
```
### reviews block (when --reviews)
The `reviews` field is populated via REST API (`/pulls/{num}/reviews` and `/pulls/{num}/comments`).
Each review object:
```
reviews:
- author: alice
state: approved
submitted: <submitted_at ISO string>
body: <review body>
inline_comments:
- author: alice
path: src/foo.ts
line: 42
body: <comment text>
created: <created_at ISO string>
```
Review states are mapped from the REST API values:
`APPROVED`→`approved`, `CHANGES_REQUESTED`→`changes_requested`, `COMMENTED`→`commented`, `DISMISSED`→`dismissed`, `PENDING`→`pending`.
### Suggestions
View suggestions are state-dependent.
The `pr view` handler itself does not call `getSuggestions` (no `renderHelp` block in `prView`).
**There are no help suggestions on `pr view` output.**
---
## pr create
**Invocation:** `gh-axi pr create --title <text> [flags]`
### Flags
| Flag | Type | Default | Required |
|---|---|---|---|
| `--title <text>` | string | — | **yes** |
| `--body <text>` | string | — | no |
| `--body-file <path>` | path | — | no |
| `--base <branch>` | string | — | no |
| `--head <branch>` | string | — | no |
| `--draft` | boolean | false | no |
| `--assignee <login>` | string | — | no |
| `--reviewer <login>` | string | — | no |
| `--label <name>` | string (repeatable) | — | no |
| `--milestone <name>` | string | — | no |
| `--project <name>` | string | — | no |
### Default output fields
TOON block name: `created`
| Output field | Source |
|---|---|
| `number` | Parsed from URL output of `gh pr create` (or the URL string itself if parsing fails) |
| `url` | Last line of `gh pr create` stdout |
### Suggestions
```
help:
- Run `gh-axi pr view <new-number>` to see the full PR
- Run `gh-axi pr checks <new-number>` to monitor CI
```
---
## pr edit
**Invocation:** `gh-axi pr edit <number> [flags]`
### Flags
| Flag | Type | Default | Required |
|---|---|---|---|
| `--title <text>` | string | — | no |
| `--body <text>` | string | — | no |
| `--body-file <path>` | path | — | no |
| `--add-label <name>` | string | — | no |
| `--remove-label <name>` | string | — | no |
| `--add-assignee <login>` | string | — | no |
| `--remove-assignee <login>` | string | — | no |
| `--add-reviewer <login>` | string | — | no |
| `--remove-reviewer <login>` | string | — | no |
| `--milestone <name>` | string | — | no |
| `--base <branch>` | string | — | no |
### Default output fields
TOON block name: `edited`
| Output field | Source |
|---|---|
| `number` | `number` |
| `status` | literal `"ok"` |
---
## pr close
**Invocation:** `gh-axi pr close <number> [flags]`
### Flags
| Flag | Type | Default | Required |
|---|---|---|---|
| `--comment <text>` | string | — | no |
### Default output fields (success)
TOON block name: `closed`
| Output field | Source |
|---|---|
| `number` | `number` |
| `status` | literal `"ok"` |
### Idempotency
If the PR state is already `CLOSED` or `MERGED`, no `gh` call is made.
Output uses block name `pull_request` instead:
| Output field | Source |
|---|---|
| `number` | `number` |
| `state` | lowercased state |
| `already` | boolean `true` |
---
## pr merge
**Invocation:** `gh-axi pr merge <number> [flags]`
### Flags
| Flag | Type | Default | Required |
|---|---|---|---|
| `--method <merge\|squash\|rebase>` | string | — | no |
| `--merge` | boolean | false | no (shorthand for `--method merge`) |
| `--squash` | boolean | false | no (shorthand for `--method squash`) |
| `--rebase` | boolean | false | no (shorthand for `--method rebase`) |
| `--auto` | boolean | false | no |
| `--delete-branch` | boolean | false | no |
| `--body <text>` | string | — | no |
| `--body-file <path>` | path | — | no |
| `--subject <text>` | string | — | no |
Specifying multiple shorthand flags or conflicting `--method` + shorthand raises `VALIDATION_ERROR`.
### Default output fields (success)
TOON block name: `merged`
| Output field | Source |
|---|---|
| `number` | `number` |
| `status` | literal `"ok"` |
| `method` | the merge method used, or `"default"` if none was specified |
### Idempotency
If the PR is already merged, returns without calling `gh`.
Block name: `pull_request`
| Output field | Source |
|---|---|
| `number` | `number` |
| `state` | `"merged"` |
| `merged_by` | `mergedBy.login` or `null` |
| `merged_at` | `mergedAt` or `null` |
---
## pr review
**Invocation:** `gh-axi pr review <number> [flags]`
### Flags
| Flag | Type | Default | Required |
|---|---|---|---|
| `--approve` | boolean | false | no |
| `--request-changes` | boolean | false | no |
| `--comment` | boolean | false | no |
| `--body <text>` | string | — | no |
| `--body-file <path>` | path | — | no |
### Default output fields
TOON block name: `review`
| Output field | Source |
|---|---|
| `number` | `number` |
| `action` | `"approved"` / `"changes_requested"` / `"commented"` based on which flag was passed |
---
## pr checks
**Invocation:** `gh-axi pr checks <number>`
### Flags
None.
### Default output fields
When no checks are configured (zero checks):
```
checks: 0 passed, 0 failed — this PR has no CI checks configured
```
(Raw TOON-encoded object, no list block)
When checks exist:
First block (raw object):
```
summary: N passed, N failed[, N skipped][, N pending], N total
```
Then TOON list block name: `checks`
| Output field | Source |
|---|---|
| `name` | `check.name ?? check.context ?? "check"` |
| `conclusion` | one of `pass`, `fail`, `skip`, `pending` |
---
## pr diff
**Invocation:** `gh-axi pr diff <number> [flags]`
### Flags
| Flag | Type | Default | Required |
|---|---|---|---|
| `--full` | boolean | false | no |
### Output
Raw TOON-encoded object with key `pr_diff`:
| Field | Source |
|---|---|
| `number` | `number` |
| `diff` | diff text (truncated to 4000 chars unless `--full`) |
| `truncated` | boolean `true` — only present when truncated |
| `original_length` | integer — only present when truncated |
### Truncation hint
When truncated, prepended to suggestions (before any other suggestions):
```
Run `gh-axi pr diff <num> --full` to see the complete diff
```
(With `-R owner/name` injected if non-git repo context.)
---
## pr checkout
**Invocation:** `gh-axi pr checkout <number>`
### Flags
None.
### Default output fields
TOON block name: `checkout`
| Output field | Source |
|---|---|
| `number` | `number` |
| `branch` | Branch name parsed from `gh pr checkout` stdout (`Switched to branch '<name>'`), or raw stdout if not matched |
| `status` | literal `"ok"` |
### Suggestions
Empty (the table entry returns `[]`).
---
## pr ready
**Invocation:** `gh-axi pr ready <number>`
### Flags
None.
Marks a draft PR as ready for review.
### Default output fields (success)
TOON block name: `ready`
| Output field | Source |
|---|---|
| `number` | `number` |
| `status` | literal `"ok"` |
### Idempotency
If the PR is already not a draft, no `gh` call is made.
Block name: `pull_request`
| Output field | Source |
|---|---|
| `number` | `number` |
| `draft` | `"no"` |
| `already` | boolean `true` |
---
## pr reopen
**Invocation:** `gh-axi pr reopen <number>`
### Flags
None.
### Default output fields (success)
TOON block name: `reopened`
| Output field | Source |
|---|---|
| `number` | `number` |
| `status` | literal `"ok"` |
### Idempotency
If the PR is already open, no `gh` call is made.
Block name: `pull_request`
| Output field | Source |
|---|---|
| `number` | `number` |
| `state` | `"open"` |
| `already` | boolean `true` |
---
## pr comment
**Invocation:** `gh-axi pr comment <number> --body <text>`
### Flags
| Flag | Type | Default | Required |
|---|---|---|---|
| `--body <text>` | string | — | **yes** |
| `--body-file <path>` | path | — | **yes** (alternative) |
### Default output fields
TOON block name: `commented`
| Output field | Source |
|---|---|
| `number` | `number` |
| `status` | literal `"ok"` |
---
## pr update-branch
**Invocation:** `gh-axi pr update-branch <number>`
### Flags
None.
### Default output fields
TOON block name: `updated`
| Output field | Source |
|---|---|
| `number` | `number` |
| `status` | literal `"ok"` |
---
## pr revert
**Invocation:** `gh-axi pr revert <number>`
### Flags
None.
### Default output fields
TOON block name: `reverted`
The fields differ depending on which code path succeeded:
**If `gh pr revert` CLI command exists and succeeds:**
| Output field | Source |
|---|---|
| `number` | original PR number |
| `revert_pr` | new revert PR number parsed from URL, or `null` |
| `status` | literal `"ok"` |
**If falling back to REST API:**
| Output field | Source |
|---|---|
| `number` | original PR number |
| `revert_pr` | `number` from API response, or `null` |
| `url` | `html_url` from API response, or `null` |
| `status` | literal `"ok"` |
---
## label list
**Invocation:** `gh-axi label list [flags]`
### Flags
| Flag | Type | Default | Required |
|---|---|---|---|
| `--limit <n>` | integer | `500` | no |
### Default output fields
TOON block name: `labels`
| Output field | Source |
|---|---|
| `name` | `name` |
### Output structure
```
count: N [(showing first N)]
labels:
- name: bug
- name: enhancement
help:
- Run `gh-axi label create --name "..." --color "..."` to create a label
```
### Count line
Uses `formatCountLine` with `limit` as provided (default 500).
No GraphQL total-count lookup.
So if exactly 500 labels are returned: `count: 500 (showing first 500)`.
### Empty state
When `count: 0`, the list block has no items.
Suggestions remain the same (the table has no empty-specific entry for labels).
---
## label create
**Invocation:** `gh-axi label create --name <text> --color <hex> [flags]`
### Flags
| Flag | Type | Default | Required |
|---|---|---|---|
| `--name <text>` | string | — | **yes** |
| `--color <hex>` | string (hex without `#`) | — | **yes** |
| `--description <text>` | string | — | no |
### Default output fields
TOON block name (success): raw TOON object
```
created: ok
label: <name>
```
### Idempotency
Before creating, gh-axi checks if a label with the same name already exists (case-insensitive comparison).
If found, no `gh` call is made and the output is:
```
create: already_exists
label: <existing-label-name>
```
Note: the output field is `create` (not `created`) in the already-exists case.
---
## label edit
**Invocation:** `gh-axi label edit <name> [flags]`
`<name>` is the first positional argument after the `edit` subcommand.
### Flags
| Flag | Type | Default | Required |
|---|---|---|---|
| `--name <text>` | string | — | no |
| `--color <hex>` | string | — | no |
| `--description <text>` | string | — | no |
### Default output fields
TOON block name: raw TOON object
```
edit: ok
label: <new-name-or-original-name>
```
The `label` field shows the new name if `--name` was supplied, otherwise the original positional name.
---
## label delete
**Invocation:** `gh-axi label delete <name>`
`<name>` is the first positional argument after the `delete` subcommand.
The underlying `gh label delete --yes` is called (no confirmation prompt).
### Flags
None.
### Default output fields
TOON block name: raw TOON object
```
delete: ok
label: <name>
```
### Idempotency
No idempotency check.
If the label does not exist, `gh label delete` returns an error which propagates as a mapped `AxiError`.
---
## Appendix: Issue Help Text
```
usage: gh-axi issue <subcommand> [flags]
subcommands[14]:
list, view <number>, create, edit <number>, close <number>, reopen <number>, comment <number>, delete <number>, lock <number>, unlock <number>, pin <number>, unpin <number>, transfer <number>, subissue <add|remove|list>
flags{list}:
--state <open|closed|all>, --label <name>, --assignee <login>, --author <login>, --milestone <name>, --sort <created|updated|comments>, --limit <n> (default 30), --fields <a,b,c>
flags{view}:
--comments, --full (show complete body without truncation)
flags{create}:
--title <text> (required), --body <text> or --body-file <path>, --assignee <login>, --label <name> (repeatable), --milestone <name>, --type <name>
flags{edit}:
--title, --body <text> or --body-file <path>, --add-label, --remove-label, --add-assignee, --remove-assignee, --milestone, --type <name>, --no-type
flags{close}:
--reason <completed|not_planned>, --comment <text>
flags{comment}:
--body <text> or --body-file <path> (required)
flags{transfer}:
--to-repo <owner/name> (required)
subissue:
add <parent> <child> [<child> ...], remove <parent> <child>, list <parent>
examples:
gh-axi issue list --state closed --label bug
gh-axi issue view 42 --comments
gh-axi issue create --title "Fix login" --body "Steps to reproduce..."
gh-axi issue comment 42 --body-file comment.md
gh-axi issue close 42 --reason completed
gh-axi issue transfer 42 -R source/repo --to-repo dest/repo
gh-axi issue subissue add 16 20 101 125
gh-axi issue subissue list 16
```
## Appendix: PR Help Text
```
usage: gh-axi pr <subcommand> [flags]
subcommands[15]:
list, view <number>, create, edit <number>, close <number>, merge <number>, review <number>, checks <number>, diff <number>, checkout <number>, ready <number>, reopen <number>, comment <number>, update-branch <number>, revert <number>
flags{list}:
--state <open|closed|all>, --label, --assignee, --author, --base, --head, --draft, --limit <n> (default 30), --fields <a,b,c>
flags{view}:
--comments, --reviews (show review submissions and inline review comments), --full (show complete body without truncation)
flags{create}:
--title <text> (required), --body <text> or --body-file <path>, --base, --head, --draft, --assignee, --reviewer, --label <name> (repeatable), --milestone
flags{edit}:
--title <text>, --body <text> or --body-file <path>, --add-label, --remove-label, --add-assignee, --remove-assignee, --add-reviewer, --remove-reviewer, --milestone
flags{merge}:
--method <merge|squash|rebase>, --merge, --squash, --rebase, --auto, --delete-branch, --body <text> or --body-file <path>, --subject
flags{review}:
--approve, --request-changes, --comment, --body <text> or --body-file <path>
flags{comment}:
--body <text> or --body-file <path> (required)
flags{checks}:
(none)
flags{diff}:
--full (show complete diff without truncation)
examples:
gh-axi pr list --state open --label bug
gh-axi pr view 42 --comments
gh-axi pr view 42 --reviews
gh-axi pr comment 42 --body-file review.md
gh-axi pr merge 42 --squash --delete-branch
```
## Appendix: Label Help Text
```
usage: gh-axi label <subcommand> [flags]
subcommands[4]:
list, create, edit <name>, delete <name>
flags{list}:
--limit <n> (default 500)
flags{create}:
--name <text> (required), --color <hex> (required, without #), --description <text>
flags{edit}:
--name, --color, --description
examples:
gh-axi label list
gh-axi label create --name "priority:high" --color ff0000 --description "High priority"
gh-axi label delete "priority:low"
```
## Appendix: Subissue Help Text
```
usage: gh-axi issue subissue <add|remove|list> <parent> [child...]
subcommands[3]:
add <parent> <child> [<child> ...], remove <parent> <child>, list <parent>
examples:
gh-axi issue subissue add 16 20 101 125
gh-axi issue subissue remove 16 101
gh-axi issue subissue list 16
```