diff --git a/.prettierignore b/.prettierignore index 5fc75845..8cfbf2f9 100644 --- a/.prettierignore +++ b/.prettierignore @@ -6,6 +6,7 @@ # what made swarmctl's fail. docs/tools/hivectl-cli.md docs/tools/swarmctl-cli.md +docs/tools/forge-cli.md # Files with multi-line list-item continuations that prettier strips to col 0. # prettier's `proseWrap: "preserve"` prevents prose reflow but not list-item diff --git a/Cargo.lock b/Cargo.lock index 066ec58f..0d1fafcc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1739,6 +1739,7 @@ version = "0.1.0" dependencies = [ "anyhow", "clap", + "clap-markdown", "forgejo-api", "libc", "reqwest", diff --git a/docs/tools/README.md b/docs/tools/README.md index c127e718..9f521648 100644 --- a/docs/tools/README.md +++ b/docs/tools/README.md @@ -31,6 +31,9 @@ debug agent behavior. - **[forge](forge.md)** — the `hive-forge` Forgejo CLI every agent has for issues, PRs, and comments. Not an MCP tool — a binary agents shell out to instead of ad-hoc curl. +- **[forge-cli](forge-cli.md)** — the exhaustive, auto-generated + flag-by-flag reference for `hive-forge`, kept in lockstep with the + binary by CI the same way `hivectl-cli.md` is. - **[lifecycle](lifecycle.md)** — kill/start/restart/update for an agent's own direct children, plus the approval-gated config-change tools. diff --git a/docs/tools/forge-cli.md b/docs/tools/forge-cli.md new file mode 100644 index 00000000..84dd3862 --- /dev/null +++ b/docs/tools/forge-cli.md @@ -0,0 +1,1406 @@ +# Command-Line Help for `hive-forge` + +This document contains the help content for the `hive-forge` command-line program. + +**Command Overview:** + +* [`hive-forge`↴](#hive-forge) +* [`hive-forge issue`↴](#hive-forge-issue) +* [`hive-forge issue show`↴](#hive-forge-issue-show) +* [`hive-forge issue create`↴](#hive-forge-issue-create) +* [`hive-forge issue edit`↴](#hive-forge-issue-edit) +* [`hive-forge issue view`↴](#hive-forge-issue-view) +* [`hive-forge issue comment`↴](#hive-forge-issue-comment) +* [`hive-forge issue comments`↴](#hive-forge-issue-comments) +* [`hive-forge issue close`↴](#hive-forge-issue-close) +* [`hive-forge issue reopen`↴](#hive-forge-issue-reopen) +* [`hive-forge issue labels`↴](#hive-forge-issue-labels) +* [`hive-forge issue labels list`↴](#hive-forge-issue-labels-list) +* [`hive-forge issue labels add`↴](#hive-forge-issue-labels-add) +* [`hive-forge issue labels remove`↴](#hive-forge-issue-labels-remove) +* [`hive-forge issue assign`↴](#hive-forge-issue-assign) +* [`hive-forge issue dependency`↴](#hive-forge-issue-dependency) +* [`hive-forge issue dependency list`↴](#hive-forge-issue-dependency-list) +* [`hive-forge issue dependency add`↴](#hive-forge-issue-dependency-add) +* [`hive-forge issue dependency remove`↴](#hive-forge-issue-dependency-remove) +* [`hive-forge issue reaction`↴](#hive-forge-issue-reaction) +* [`hive-forge issue reaction list`↴](#hive-forge-issue-reaction-list) +* [`hive-forge issue reaction add`↴](#hive-forge-issue-reaction-add) +* [`hive-forge issue reaction remove`↴](#hive-forge-issue-reaction-remove) +* [`hive-forge issue timeline`↴](#hive-forge-issue-timeline) +* [`hive-forge pr`↴](#hive-forge-pr) +* [`hive-forge pr show`↴](#hive-forge-pr-show) +* [`hive-forge pr commits`↴](#hive-forge-pr-commits) +* [`hive-forge pr create`↴](#hive-forge-pr-create) +* [`hive-forge pr status`↴](#hive-forge-pr-status) +* [`hive-forge pr merge`↴](#hive-forge-pr-merge) +* [`hive-forge pr reviews`↴](#hive-forge-pr-reviews) +* [`hive-forge pr assign-reviewer`↴](#hive-forge-pr-assign-reviewer) +* [`hive-forge pr diff`↴](#hive-forge-pr-diff) +* [`hive-forge pr view`↴](#hive-forge-pr-view) +* [`hive-forge pr edit`↴](#hive-forge-pr-edit) +* [`hive-forge pr comment`↴](#hive-forge-pr-comment) +* [`hive-forge pr comments`↴](#hive-forge-pr-comments) +* [`hive-forge pr close`↴](#hive-forge-pr-close) +* [`hive-forge pr reopen`↴](#hive-forge-pr-reopen) +* [`hive-forge pr labels`↴](#hive-forge-pr-labels) +* [`hive-forge pr labels list`↴](#hive-forge-pr-labels-list) +* [`hive-forge pr labels add`↴](#hive-forge-pr-labels-add) +* [`hive-forge pr labels remove`↴](#hive-forge-pr-labels-remove) +* [`hive-forge pr assign-committer`↴](#hive-forge-pr-assign-committer) +* [`hive-forge pr dependency`↴](#hive-forge-pr-dependency) +* [`hive-forge pr dependency list`↴](#hive-forge-pr-dependency-list) +* [`hive-forge pr dependency add`↴](#hive-forge-pr-dependency-add) +* [`hive-forge pr dependency remove`↴](#hive-forge-pr-dependency-remove) +* [`hive-forge pr reaction`↴](#hive-forge-pr-reaction) +* [`hive-forge pr reaction list`↴](#hive-forge-pr-reaction-list) +* [`hive-forge pr reaction add`↴](#hive-forge-pr-reaction-add) +* [`hive-forge pr reaction remove`↴](#hive-forge-pr-reaction-remove) +* [`hive-forge pr timeline`↴](#hive-forge-pr-timeline) +* [`hive-forge comment-show`↴](#hive-forge-comment-show) +* [`hive-forge comment-edit`↴](#hive-forge-comment-edit) +* [`hive-forge clone`↴](#hive-forge-clone) +* [`hive-forge repo-create`↴](#hive-forge-repo-create) +* [`hive-forge repo-add-collaborator`↴](#hive-forge-repo-add-collaborator) +* [`hive-forge repo-labels`↴](#hive-forge-repo-labels) +* [`hive-forge repo-search`↴](#hive-forge-repo-search) +* [`hive-forge lint`↴](#hive-forge-lint) +* [`hive-forge lint unassigned`↴](#hive-forge-lint-unassigned) +* [`hive-forge lint no-reviewer`↴](#hive-forge-lint-no-reviewer) +* [`hive-forge lint stale-branches`↴](#hive-forge-lint-stale-branches) +* [`hive-forge lint assignments`↴](#hive-forge-lint-assignments) +* [`hive-forge lint unlabeled`↴](#hive-forge-lint-unlabeled) +* [`hive-forge list`↴](#hive-forge-list) +* [`hive-forge milestone`↴](#hive-forge-milestone) +* [`hive-forge milestone list`↴](#hive-forge-milestone-list) +* [`hive-forge milestone create`↴](#hive-forge-milestone-create) +* [`hive-forge milestone close`↴](#hive-forge-milestone-close) +* [`hive-forge branches`↴](#hive-forge-branches) +* [`hive-forge tree-sha`↴](#hive-forge-tree-sha) +* [`hive-forge subscription`↴](#hive-forge-subscription) +* [`hive-forge attach-issue`↴](#hive-forge-attach-issue) +* [`hive-forge attach-comment`↴](#hive-forge-attach-comment) +* [`hive-forge attachment-get`↴](#hive-forge-attachment-get) +* [`hive-forge artifact-get`↴](#hive-forge-artifact-get) +* [`hive-forge ci-log`↴](#hive-forge-ci-log) +* [`hive-forge ci-rerun`↴](#hive-forge-ci-rerun) +* [`hive-forge ci-runs`↴](#hive-forge-ci-runs) + +## `hive-forge` + +Forgejo CLI wrapper for hyperhive + +**Usage:** `hive-forge [OPTIONS] ` + +###### **Subcommands:** + +* `issue` — Issue-scoped commands: `issue …` +* `pr` — PR-scoped commands: `pr …` +* `comment-show` — Print the body (or full JSON) of a single comment by id +* `comment-edit` — Edit an existing comment by id +* `clone` — Clone a forge repo (default `-r`/`HIVE_FORGE_REPO`) with credentials auto-injected. Pairs with `pr-create --agit` +* `repo-create` — Create a forge repo under the current user (or `--org`). Prints the repo URL +* `repo-add-collaborator` — Add a collaborator to the active repo (`-r`/`HIVE_FORGE_REPO`) with a permission level. Companion to `repo-create` +* `repo-labels` — List every label defined on the repo (name + description), optionally filtered by a name substring +* `repo-search` — Search the forge for repositories by keyword, topic, or description +* `lint` — Triage lint queries (unassigned / no-reviewer / stale-branches / assignments / unlabeled) +* `list` — List issues / PRs with filters (`--kind`, `--state`, `--assignee`, `--author`, `--label`, `--limit`). Pretty rows by default; pass `--json` for raw JSON +* `milestone` — Manage milestones (list / create / close) +* `branches` — List branches, optionally filtered +* `tree-sha` — Print the tree SHA at a branch or commit +* `subscription` — Get/set this user's watch subscription on a repo, or --list all watched repos +* `attach-issue` — Upload a file as an attachment to an issue +* `attach-comment` — Upload a file as an attachment to a comment +* `attachment-get` — Download an attachment by UUID or URL. Saves to a temp file and prints the path (pass `-o -` to stream raw bytes to stdout) +* `artifact-get` — Download a CI Actions artifact from a run (` --run `). Saves a zip, or pass `-o -` to stream to stdout +* `ci-log` — Print a CI Actions run's job step logs (`--run [--job i] [--step i]`) +* `ci-rerun` — Re-run CI without an empty commit. Pass one of `--pr `, `--run `, or `--branch `; `--workflow` defaults to `ci.yml` +* `ci-runs` — List CI Actions runs, newest first (`--workflow`, `--branch`, `--limit`, `--page`) — the run numbers `ci-log`/`ci-rerun --run`/ `artifact-get --run` take + +###### **Options:** + +* `-r`, `--repo ` — Repo to act on, as `owner/name` (default: inferred from the cwd's git `origin` remote, then `HIVE_FORGE_REPO`). Works with any verb +* `-f`, `--forge ` — Act as a dashboard-provisioned external forge account (by its FORGES-tab label) instead of the internal forge. Independent of `-r/--repo` +* `--json` — Emit JSON instead of the default human-readable output (for verbs that support both) + + + +## `hive-forge issue` + +Issue-scoped commands: `issue …` + +**Usage:** `hive-forge issue ` + +###### **Subcommands:** + +* `show` — Show issue metadata as JSON +* `create` — Create an issue +* `edit` — Edit an issue's title / body / state / milestone +* `view` — Show title + body + comments +* `comment` — Post a comment on the issue +* `comments` — List comments on the issue +* `close` — Close the issue +* `reopen` — Reopen a closed issue +* `labels` — List / add / remove labels +* `assign` — Assign or unassign a user +* `dependency` — List / add / remove dependencies (issues this one is blocked by) +* `reaction` — List / add / remove emoji reactions on the issue, or on one of its comments with `--comment ` +* `timeline` — List timeline events + + + +## `hive-forge issue show` + +Show issue metadata as JSON + +**Usage:** `hive-forge issue show ` + +###### **Arguments:** + +* `` — Issue number + + + +## `hive-forge issue create` + +Create an issue + +**Usage:** `hive-forge issue create [OPTIONS] --title ` + +###### **Options:** + +* `--title <TITLE>` — Issue title (required) +* `--body <BODY>` — Inline body text +* `--body-file <BODY_FILE>` — Read body from a file. `-` means stdin +* `--assignee <ASSIGNEE>` — Initial assignee login +* `--label <LABELS>` — Label name to attach, repeatable (e.g. `--label area/ops --label type/bug`). Same spelling `labels add` accepts. An unresolved name errors out (before the issue is created) rather than silently attaching fewer labels than asked for + + + +## `hive-forge issue edit` + +Edit an issue's title / body / state / milestone + +**Usage:** `hive-forge issue edit [OPTIONS] <NUMBER>` + +###### **Arguments:** + +* `<NUMBER>` — Issue (or PR — shares the same `/issues/<n>` endpoint) number + +###### **Options:** + +* `--title <TITLE>` — New title (omit to leave unchanged) +* `--body <BODY>` — Inline body text (omit to leave unchanged) +* `--body-file <BODY_FILE>` — Read body from a file. `-` means stdin +* `--state <STATE>` — New state + + Possible values: `open`, `closed` + +* `--milestone <MILESTONE>` — Milestone id (0 to unset) + + + +## `hive-forge issue view` + +Show title + body + comments + +**Usage:** `hive-forge issue view <NUMBER>` + +###### **Arguments:** + +* `<NUMBER>` — Issue or PR number + + + +## `hive-forge issue comment` + +Post a comment on the issue + +**Usage:** `hive-forge issue comment [OPTIONS] <NUMBER>` + +###### **Arguments:** + +* `<NUMBER>` — Issue or PR number + +###### **Options:** + +* `--body <BODY>` — Inline body text +* `--body-file <BODY_FILE>` — Read body from a file. `-` means stdin +* `--force` — Post even when the thread has unread activity (skips the read-before-comment guard) + + + +## `hive-forge issue comments` + +List comments on the issue + +**Usage:** `hive-forge issue comments [OPTIONS] <NUMBER>` + +###### **Arguments:** + +* `<NUMBER>` — Issue or PR number + +###### **Options:** + +* `--limit <LIMIT>` — Number of comments from the start of the thread, or (with `--since`) the most this call returns — capped at [`crate::verbs::MAX_LIMIT`] in the latter case. Mutually exclusive with `--tail` + + Default value: `10` +* `--tail <TAIL>` — Return the last `N` comments (chronological). Mutually exclusive with `--limit`/`--since` +* `--since <SINCE>` — Only show comments at or after this RFC3339 timestamp (same format this verb's own output prints). Mutually exclusive with `--tail` +* `--show-reactions` — Fetch + display each shown comment's reaction summary. Costs one extra request per comment shown — opt-in, not the default + + + +## `hive-forge issue close` + +Close the issue + +**Usage:** `hive-forge issue close <NUMBER>` + +###### **Arguments:** + +* `<NUMBER>` — Issue or PR number + + + +## `hive-forge issue reopen` + +Reopen a closed issue + +**Usage:** `hive-forge issue reopen <NUMBER>` + +###### **Arguments:** + +* `<NUMBER>` — Issue or PR number + + + +## `hive-forge issue labels` + +List / add / remove labels + +**Usage:** `hive-forge issue labels <NUMBER> [COMMAND]` + +###### **Subcommands:** + +* `list` — List labels (default when no action is given) +* `add` — Add labels by name +* `remove` — Remove labels by name + +###### **Arguments:** + +* `<NUMBER>` — Issue or PR number + + + +## `hive-forge issue labels list` + +List labels (default when no action is given) + +**Usage:** `hive-forge issue labels list` + + + +## `hive-forge issue labels add` + +Add labels by name + +**Usage:** `hive-forge issue labels add [LABELS]...` + +###### **Arguments:** + +* `<LABELS>` — Label names to add + + + +## `hive-forge issue labels remove` + +Remove labels by name + +**Usage:** `hive-forge issue labels remove [LABELS]...` + +###### **Arguments:** + +* `<LABELS>` — Label names to remove + + + +## `hive-forge issue assign` + +Assign or unassign a user + +**Usage:** `hive-forge issue assign [OPTIONS] <NUMBER> <USER>` + +###### **Arguments:** + +* `<NUMBER>` — Issue or PR number +* `<USER>` — User login to assign (or unassign with `--remove`) + +###### **Options:** + +* `--remove` — Remove the user instead of adding + + + +## `hive-forge issue dependency` + +List / add / remove dependencies (issues this one is blocked by) + +**Usage:** `hive-forge issue dependency <NUMBER> [COMMAND]` + +###### **Subcommands:** + +* `list` — List dependencies (default when no action is given) — the issues/PRs this one is blocked by +* `add` — Add one or more issues/PRs this one is blocked by +* `remove` — Remove one or more dependency links + +###### **Arguments:** + +* `<NUMBER>` — Issue or PR number + + + +## `hive-forge issue dependency list` + +List dependencies (default when no action is given) — the issues/PRs this one is blocked by + +**Usage:** `hive-forge issue dependency list` + + + +## `hive-forge issue dependency add` + +Add one or more issues/PRs this one is blocked by + +**Usage:** `hive-forge issue dependency add [DEPS]...` + +###### **Arguments:** + +* `<DEPS>` — Issue/PR numbers to add as dependencies + + + +## `hive-forge issue dependency remove` + +Remove one or more dependency links + +**Usage:** `hive-forge issue dependency remove [DEPS]...` + +###### **Arguments:** + +* `<DEPS>` — Issue/PR numbers to remove as dependencies + + + +## `hive-forge issue reaction` + +List / add / remove emoji reactions on the issue, or on one of its comments with `--comment <id>` + +**Usage:** `hive-forge issue reaction [OPTIONS] <NUMBER> [COMMAND]` + +###### **Subcommands:** + +* `list` — List reactions (default when no action is given) +* `add` — Add a reaction — a Forgejo shortcode, e.g. `+1`, `heart`, `rocket` +* `remove` — Remove your own reaction with this content + +###### **Arguments:** + +* `<NUMBER>` — Issue or PR number. Ignored (but still required) when `--list-allowed` is set + +###### **Options:** + +* `--comment <COMMENT>` — Target a specific comment's reactions instead of the issue/PR itself — the comment's own id (from `comments`/`comment-show`), not its position in the thread +* `--list-allowed` — Print the instance's actual configured reaction shortcodes (`GET /settings/ui`) instead of listing/adding/removing — instance-global, ignores `number`/`--comment` + + + +## `hive-forge issue reaction list` + +List reactions (default when no action is given) + +**Usage:** `hive-forge issue reaction list` + + + +## `hive-forge issue reaction add` + +Add a reaction — a Forgejo shortcode, e.g. `+1`, `heart`, `rocket` + +**Usage:** `hive-forge issue reaction add <CONTENT>` + +###### **Arguments:** + +* `<CONTENT>` + + + +## `hive-forge issue reaction remove` + +Remove your own reaction with this content + +**Usage:** `hive-forge issue reaction remove <CONTENT>` + +###### **Arguments:** + +* `<CONTENT>` + + + +## `hive-forge issue timeline` + +List timeline events + +**Usage:** `hive-forge issue timeline [OPTIONS] <NUMBER>` + +###### **Arguments:** + +* `<NUMBER>` — Issue or PR number + +###### **Options:** + +* `--limit <LIMIT>` — Return the first `N` events, capped at 49 (see the module doc comment for why). Default kept small on purpose + + Default value: `10` +* `--since <SINCE>` — Only show events at or after this RFC3339 timestamp (same format this verb's own output prints) — pass back the last-seen row's `created_at` to fetch only what's new + + + +## `hive-forge pr` + +PR-scoped commands: `pr <show|status|create|merge|reviews|assign-reviewer|commits|diff|view|edit|comment|comments|close|reopen|labels|assign-committer|dependency|reaction|timeline> …` + +**Usage:** `hive-forge pr <COMMAND>` + +###### **Subcommands:** + +* `show` — Show PR metadata as JSON +* `commits` — List the PR's commits as JSON +* `create` — Create a pull request +* `status` — PR health view: mergeable / CI / reviews +* `merge` — Merge the PR +* `reviews` — List a PR's reviews, or submit one +* `assign-reviewer` — Request (or withdraw with `--remove`) a review from a user +* `diff` — Print the PR's unified diff +* `view` — Show title + body + comments +* `edit` — Edit the PR's title / body / state / milestone. Fields not passed are left unchanged +* `comment` — Post a comment on the PR +* `comments` — List comments on the PR +* `close` — Close the PR +* `reopen` — Reopen a closed PR +* `labels` — List / add / remove labels +* `assign-committer` — Assign or unassign a user (the PR's assignee list) +* `dependency` — List / add / remove dependencies (issues/PRs this one is blocked by) +* `reaction` — List / add / remove emoji reactions on the PR, or on one of its comments with `--comment <id>` +* `timeline` — List timeline events + + + +## `hive-forge pr show` + +Show PR metadata as JSON + +**Usage:** `hive-forge pr show <NUMBER>` + +###### **Arguments:** + +* `<NUMBER>` — PR number + + + +## `hive-forge pr commits` + +List the PR's commits as JSON + +**Usage:** `hive-forge pr commits <NUMBER>` + +###### **Arguments:** + +* `<NUMBER>` — PR number + + + +## `hive-forge pr create` + +Create a pull request + +**Usage:** `hive-forge pr create [OPTIONS] --title <TITLE>` + +###### **Options:** + +* `--title <TITLE>` — PR title +* `--head <HEAD>` — Head branch. Not required (and ignored) in `--agit` mode, which pushes the current `HEAD` +* `--base <BASE>` — Base branch (default: main) + + Default value: `main` +* `--body <BODY>` — Inline body text +* `--body-file <BODY_FILE>` — Read body from a file. `-` means stdin +* `--draft` — Open as draft. Ignored in `--agit` mode +* `--push` — Push the local `--head` branch to `--remote` before creating the PR +* `--remote <REMOTE>` — Remote to push to (default: `forge`, or `origin` in `--agit` mode) +* `--agit` — Open the PR via Forgejo's `AGit` flow instead of pushing a branch — works for read-only collaborators. Run from inside a cloned repo +* `--topic <TOPIC>` — `AGit` topic — groups repeated pushes into one PR (re-run with the same topic to update it). Defaults to the branch name. Only meaningful with `--agit` +* `--label <LABELS>` — Label name to attach, repeatable (e.g. `--label area/ops --label type/bug`). Same spelling `labels add` accepts — an unresolved name errors out rather than silently attaching fewer labels than asked for. In `--agit` mode this is applied as a follow-up call once the PR number is known (the `AGit` push itself has no label field), so it's silently skipped (not a label-resolution error) if the PR URL couldn't be parsed back out of the push output — same fallback as the deferred multi-line body + + + +## `hive-forge pr status` + +PR health view: mergeable / CI / reviews + +**Usage:** `hive-forge pr status [OPTIONS]` + +###### **Options:** + +* `--pr <PR>` — PR number — full health view (mergeable, CI, reviews, last comment). Mutually exclusive with `--sha` +* `--sha <SHA>` — Explicit commit sha (or ref) — CI-only fast path. Mutually exclusive with `--pr` + + + +## `hive-forge pr merge` + +Merge the PR + +**Usage:** `hive-forge pr merge [OPTIONS] <NUMBER>` + +###### **Arguments:** + +* `<NUMBER>` — PR number to merge + +###### **Options:** + +* `--method <METHOD>` — Merge strategy (default: a merge commit). Squash is not offered + + Default value: `merge` + + Possible values: + - `merge`: + Create a merge commit + - `rebase`: + Rebase the head branch onto the base, then fast-forward + +* `--keep-branch` — Keep the head branch after merging (deleted by default) +* `--force` — Merge even if the PR is not mergeable, CI is not green, or a review requests changes + + + +## `hive-forge pr reviews` + +List a PR's reviews, or submit one + +**Usage:** `hive-forge pr reviews [OPTIONS] <NUMBER>` + +###### **Arguments:** + +* `<NUMBER>` — PR number + +###### **Options:** + +* `--approve` — Approve the PR (submit an APPROVED review) +* `--request-changes` — Request changes on the PR (submit a `REQUEST_CHANGES` review) +* `--comment` — Leave a comment review (submit a COMMENT review) +* `-m`, `--body <BODY>` — Optional body / message for the review (used with --approve, --request-changes, or --comment) + + + +## `hive-forge pr assign-reviewer` + +Request (or withdraw with `--remove`) a review from a user + +**Usage:** `hive-forge pr assign-reviewer [OPTIONS] <NUMBER> <USER>` + +###### **Arguments:** + +* `<NUMBER>` — PR number +* `<USER>` — User login to request a review from (or withdraw with `--remove`) + +###### **Options:** + +* `--remove` — Withdraw the review request instead of adding it + + + +## `hive-forge pr diff` + +Print the PR's unified diff + +**Usage:** `hive-forge pr diff [OPTIONS] <NUMBER>` + +###### **Arguments:** + +* `<NUMBER>` — PR number + +###### **Options:** + +* `--full` — Print the unfiltered diff. By default, autogenerated-file hunks (`flake.lock`, `Cargo.lock`, …) are collapsed to a placeholder so human-authored changes stay readable + + + +## `hive-forge pr view` + +Show title + body + comments + +**Usage:** `hive-forge pr view <NUMBER>` + +###### **Arguments:** + +* `<NUMBER>` — Issue or PR number + + + +## `hive-forge pr edit` + +Edit the PR's title / body / state / milestone. Fields not passed are left unchanged + +**Usage:** `hive-forge pr edit [OPTIONS] <NUMBER>` + +###### **Arguments:** + +* `<NUMBER>` — Issue (or PR — shares the same `/issues/<n>` endpoint) number + +###### **Options:** + +* `--title <TITLE>` — New title (omit to leave unchanged) +* `--body <BODY>` — Inline body text (omit to leave unchanged) +* `--body-file <BODY_FILE>` — Read body from a file. `-` means stdin +* `--state <STATE>` — New state + + Possible values: `open`, `closed` + +* `--milestone <MILESTONE>` — Milestone id (0 to unset) + + + +## `hive-forge pr comment` + +Post a comment on the PR + +**Usage:** `hive-forge pr comment [OPTIONS] <NUMBER>` + +###### **Arguments:** + +* `<NUMBER>` — Issue or PR number + +###### **Options:** + +* `--body <BODY>` — Inline body text +* `--body-file <BODY_FILE>` — Read body from a file. `-` means stdin +* `--force` — Post even when the thread has unread activity (skips the read-before-comment guard) + + + +## `hive-forge pr comments` + +List comments on the PR + +**Usage:** `hive-forge pr comments [OPTIONS] <NUMBER>` + +###### **Arguments:** + +* `<NUMBER>` — Issue or PR number + +###### **Options:** + +* `--limit <LIMIT>` — Number of comments from the start of the thread, or (with `--since`) the most this call returns — capped at [`crate::verbs::MAX_LIMIT`] in the latter case. Mutually exclusive with `--tail` + + Default value: `10` +* `--tail <TAIL>` — Return the last `N` comments (chronological). Mutually exclusive with `--limit`/`--since` +* `--since <SINCE>` — Only show comments at or after this RFC3339 timestamp (same format this verb's own output prints). Mutually exclusive with `--tail` +* `--show-reactions` — Fetch + display each shown comment's reaction summary. Costs one extra request per comment shown — opt-in, not the default + + + +## `hive-forge pr close` + +Close the PR + +**Usage:** `hive-forge pr close <NUMBER>` + +###### **Arguments:** + +* `<NUMBER>` — Issue or PR number + + + +## `hive-forge pr reopen` + +Reopen a closed PR + +**Usage:** `hive-forge pr reopen <NUMBER>` + +###### **Arguments:** + +* `<NUMBER>` — Issue or PR number + + + +## `hive-forge pr labels` + +List / add / remove labels + +**Usage:** `hive-forge pr labels <NUMBER> [COMMAND]` + +###### **Subcommands:** + +* `list` — List labels (default when no action is given) +* `add` — Add labels by name +* `remove` — Remove labels by name + +###### **Arguments:** + +* `<NUMBER>` — Issue or PR number + + + +## `hive-forge pr labels list` + +List labels (default when no action is given) + +**Usage:** `hive-forge pr labels list` + + + +## `hive-forge pr labels add` + +Add labels by name + +**Usage:** `hive-forge pr labels add [LABELS]...` + +###### **Arguments:** + +* `<LABELS>` — Label names to add + + + +## `hive-forge pr labels remove` + +Remove labels by name + +**Usage:** `hive-forge pr labels remove [LABELS]...` + +###### **Arguments:** + +* `<LABELS>` — Label names to remove + + + +## `hive-forge pr assign-committer` + +Assign or unassign a user (the PR's assignee list) + +**Usage:** `hive-forge pr assign-committer [OPTIONS] <NUMBER> <USER>` + +###### **Arguments:** + +* `<NUMBER>` — Issue or PR number +* `<USER>` — User login to assign (or unassign with `--remove`) + +###### **Options:** + +* `--remove` — Remove the user instead of adding + + + +## `hive-forge pr dependency` + +List / add / remove dependencies (issues/PRs this one is blocked by) + +**Usage:** `hive-forge pr dependency <NUMBER> [COMMAND]` + +###### **Subcommands:** + +* `list` — List dependencies (default when no action is given) — the issues/PRs this one is blocked by +* `add` — Add one or more issues/PRs this one is blocked by +* `remove` — Remove one or more dependency links + +###### **Arguments:** + +* `<NUMBER>` — Issue or PR number + + + +## `hive-forge pr dependency list` + +List dependencies (default when no action is given) — the issues/PRs this one is blocked by + +**Usage:** `hive-forge pr dependency list` + + + +## `hive-forge pr dependency add` + +Add one or more issues/PRs this one is blocked by + +**Usage:** `hive-forge pr dependency add [DEPS]...` + +###### **Arguments:** + +* `<DEPS>` — Issue/PR numbers to add as dependencies + + + +## `hive-forge pr dependency remove` + +Remove one or more dependency links + +**Usage:** `hive-forge pr dependency remove [DEPS]...` + +###### **Arguments:** + +* `<DEPS>` — Issue/PR numbers to remove as dependencies + + + +## `hive-forge pr reaction` + +List / add / remove emoji reactions on the PR, or on one of its comments with `--comment <id>` + +**Usage:** `hive-forge pr reaction [OPTIONS] <NUMBER> [COMMAND]` + +###### **Subcommands:** + +* `list` — List reactions (default when no action is given) +* `add` — Add a reaction — a Forgejo shortcode, e.g. `+1`, `heart`, `rocket` +* `remove` — Remove your own reaction with this content + +###### **Arguments:** + +* `<NUMBER>` — Issue or PR number. Ignored (but still required) when `--list-allowed` is set + +###### **Options:** + +* `--comment <COMMENT>` — Target a specific comment's reactions instead of the issue/PR itself — the comment's own id (from `comments`/`comment-show`), not its position in the thread +* `--list-allowed` — Print the instance's actual configured reaction shortcodes (`GET /settings/ui`) instead of listing/adding/removing — instance-global, ignores `number`/`--comment` + + + +## `hive-forge pr reaction list` + +List reactions (default when no action is given) + +**Usage:** `hive-forge pr reaction list` + + + +## `hive-forge pr reaction add` + +Add a reaction — a Forgejo shortcode, e.g. `+1`, `heart`, `rocket` + +**Usage:** `hive-forge pr reaction add <CONTENT>` + +###### **Arguments:** + +* `<CONTENT>` + + + +## `hive-forge pr reaction remove` + +Remove your own reaction with this content + +**Usage:** `hive-forge pr reaction remove <CONTENT>` + +###### **Arguments:** + +* `<CONTENT>` + + + +## `hive-forge pr timeline` + +List timeline events + +**Usage:** `hive-forge pr timeline [OPTIONS] <NUMBER>` + +###### **Arguments:** + +* `<NUMBER>` — Issue or PR number + +###### **Options:** + +* `--limit <LIMIT>` — Return the first `N` events, capped at 49 (see the module doc comment for why). Default kept small on purpose + + Default value: `10` +* `--since <SINCE>` — Only show events at or after this RFC3339 timestamp (same format this verb's own output prints) — pass back the last-seen row's `created_at` to fetch only what's new + + + +## `hive-forge comment-show` + +Print the body (or full JSON) of a single comment by id + +**Usage:** `hive-forge comment-show <ID>` + +###### **Arguments:** + +* `<ID>` — Comment id + + + +## `hive-forge comment-edit` + +Edit an existing comment by id + +**Usage:** `hive-forge comment-edit [OPTIONS] <ID>` + +###### **Arguments:** + +* `<ID>` — Comment id + +###### **Options:** + +* `--body <BODY>` — Inline body text +* `--body-file <BODY_FILE>` — Read body from a file. `-` means stdin + + + +## `hive-forge clone` + +Clone a forge repo (default `-r`/`HIVE_FORGE_REPO`) with credentials auto-injected. Pairs with `pr-create --agit` + +**Usage:** `hive-forge clone [OPTIONS] [DEST]` + +###### **Arguments:** + +* `<DEST>` — Destination directory. Defaults to the repo's basename (e.g. `internal/knowledge` → `knowledge`) + +###### **Options:** + +* `--branch <BRANCH>` — Branch to check out after cloning +* `--depth <DEPTH>` — Shallow-clone depth (omit for a full clone) + + + +## `hive-forge repo-create` + +Create a forge repo under the current user (or `--org`). Prints the repo URL + +**Usage:** `hive-forge repo-create [OPTIONS] <NAME>` + +###### **Arguments:** + +* `<NAME>` — Repository name (required). Created under the authenticated user unless `--org` is given + +###### **Options:** + +* `--description <DESCRIPTION>` — Repository description +* `--private` — Create the repo as private (default: public) +* `--default-branch <DEFAULT_BRANCH>` — Default branch name (e.g. `main`). Only takes effect with `--auto-init` +* `--org <ORG>` — Create under this organisation instead of your own namespace +* `--auto-init` — Seed an initial commit (README) so the repo is non-empty and can be cloned immediately. Omit to create a bare repo you push into + + + +## `hive-forge repo-add-collaborator` + +Add a collaborator to the active repo (`-r`/`HIVE_FORGE_REPO`) with a permission level. Companion to `repo-create` + +**Usage:** `hive-forge repo-add-collaborator [OPTIONS] <USER>` + +###### **Arguments:** + +* `<USER>` — Collaborator's forge login to add + +###### **Options:** + +* `--permission <PERMISSION>` — Permission level to grant (default: write — a freshly added collaborator usually needs to push) + + Default value: `write` + + Possible values: + - `read`: + Pull (read-only) access + - `write`: + Push (read/write) access + - `admin`: + Full administrative access to the repo + + + + +## `hive-forge repo-labels` + +List every label defined on the repo (name + description), optionally filtered by a name substring + +**Usage:** `hive-forge repo-labels [PATTERN]` + +###### **Arguments:** + +* `<PATTERN>` — Substring pattern to filter label names (case-sensitive) + + + +## `hive-forge repo-search` + +Search the forge for repositories by keyword, topic, or description + +**Usage:** `hive-forge repo-search [OPTIONS]` + +###### **Options:** + +* `-q`, `--query <QUERY>` — Keyword to search for (matches repo name by default; combine with `--include-desc` to also match description text) +* `--topic` — Restrict matches to repositories that have the keyword as a **topic** tag rather than in the name +* `--include-desc` — Extend the keyword search to repository descriptions (in addition to names, or topics when `--topic` is set) +* `--limit <LIMIT>` — Maximum number of results to return (default: 30) + + Default value: `30` + + + +## `hive-forge lint` + +Triage lint queries (unassigned / no-reviewer / stale-branches / assignments / unlabeled) + +**Usage:** `hive-forge lint <COMMAND>` + +###### **Subcommands:** + +* `unassigned` — List issues or PRs without an assignee +* `no-reviewer` — List PRs with no formally requested reviewer +* `stale-branches` — List remote branches with no commits in N days, each with its merge outcome (skips branches that are heads of open PRs) +* `assignments` — Group open issues + PRs by assignee +* `unlabeled` — List issues/PRs with no exclusive scoped label in `--scope` (e.g. `--scope type` flags items missing any `type/*` label). Generic — the scope is whatever the repo's label taxonomy actually uses, nothing hardcoded here + + + +## `hive-forge lint unassigned` + +List issues or PRs without an assignee + +**Usage:** `hive-forge lint unassigned [OPTIONS]` + +###### **Options:** + +* `--type <TYPE>` — Filter by item kind + + Default value: `all` + + Possible values: `issues`, `pulls`, `all` + +* `--state <STATE>` — Filter by item state + + Default value: `open` + + Possible values: `open`, `closed`, `all` + + + + +## `hive-forge lint no-reviewer` + +List PRs with no formally requested reviewer + +**Usage:** `hive-forge lint no-reviewer [OPTIONS]` + +###### **Options:** + +* `--state <STATE>` — Filter by PR state + + Default value: `open` + + Possible values: `open`, `closed`, `all` + +* `--reviewer <REVIEWER>` — Reviewer login to check for. Omit to flag any PR with zero formally requested reviewers; pass it to instead flag PRs where this specific login isn't among the requested reviewers + + + +## `hive-forge lint stale-branches` + +List remote branches with no commits in N days, each with its merge outcome (skips branches that are heads of open PRs) + +**Usage:** `hive-forge lint stale-branches [OPTIONS]` + +###### **Options:** + +* `--days <DAYS>` — Threshold in days since the last commit + + Default value: `14` + + + +## `hive-forge lint assignments` + +Group open issues + PRs by assignee + +**Usage:** `hive-forge lint assignments [OPTIONS]` + +###### **Options:** + +* `--user <USER>` — Restrict to a single user + + + +## `hive-forge lint unlabeled` + +List issues/PRs with no exclusive scoped label in `--scope` (e.g. `--scope type` flags items missing any `type/*` label). Generic — the scope is whatever the repo's label taxonomy actually uses, nothing hardcoded here + +**Usage:** `hive-forge lint unlabeled [OPTIONS] --scope <SCOPE>` + +###### **Options:** + +* `--scope <SCOPE>` — Label scope to check for — the part of a scoped label's name before the `/` (e.g. `type` for `type/bug`, `type/feature`). Required: this command has no built-in notion of a repo's label taxonomy, so there's no sane default to fall back to +* `--type <TYPE>` — Filter by item kind + + Default value: `all` + + Possible values: `issues`, `pulls`, `all` + +* `--state <STATE>` — Filter by item state + + Default value: `open` + + Possible values: `open`, `closed`, `all` + + + + +## `hive-forge list` + +List issues / PRs with filters (`--kind`, `--state`, `--assignee`, `--author`, `--label`, `--limit`). Pretty rows by default; pass `--json` for raw JSON + +**Usage:** `hive-forge list [OPTIONS]` + +**Command Aliases:** `issues`, `issue-list` + +###### **Options:** + +* `--kind <KIND>` — What to return: issues, PRs, or both (default: both) + + Default value: `both` + + Possible values: + - `issue`: + Issues only (excludes PRs) + - `pr`: + Pull requests only + - `both`: + Issues + pull requests (default) + +* `--state <STATE>` — Issue/PR state (default: open) + + Default value: `open` + + Possible values: `open`, `closed`, `all` + +* `--assignee <ASSIGNEE>` — Filter to items assigned to this user (single login) +* `--author <AUTHOR>` — Filter to items authored by this user (single login) +* `--mention <MENTION>` — Filter to items mentioning this user +* `--label <LABELS>` — Filter to items carrying any of these label names. Repeatable. Validated client-side: a name the forge can't resolve is dropped from the filter rather than rejected, which returns MORE results than asked for, not fewer +* `--milestone <MILESTONES>` — Filter to items in any of these milestones, by title or id. Repeatable. Validated client-side against the repo's milestones (closed ones included), since the forge would silently discard a name it can't resolve and return the UNFILTERED list +* `--search <SEARCH>` — Full-text search over title AND body, server-side. Composes with every filter above — this is the duplicate-hunting path that grepping `list` output can't cover, since grep only ever sees the titles +* `--limit <LIMIT>` — Page size — items per page (default: 30). The forge clamps this to its own `api.MAX_RESPONSE_ITEMS` (50 by default), so a large `--limit` silently returns a smaller page; the trailer reports the real total rather than trusting this number. Must be >= 1 + + Default value: `30` +* `--page <PAGE>` — Page number to fetch (1-based, default 1). Combine with `--limit` to page through large result sets incrementally + + Default value: `1` + + + +## `hive-forge milestone` + +Manage milestones (list / create / close) + +**Usage:** `hive-forge milestone [COMMAND]` + +###### **Subcommands:** + +* `list` — List open milestones as JSON +* `create` — Create a milestone, print {id,title} +* `close` — Close a milestone by id + + + +## `hive-forge milestone list` + +List open milestones as JSON + +**Usage:** `hive-forge milestone list` + + + +## `hive-forge milestone create` + +Create a milestone, print {id,title} + +**Usage:** `hive-forge milestone create [OPTIONS] --title <TITLE>` + +###### **Options:** + +* `--title <TITLE>` — Milestone title +* `--desc <DESC>` — Description +* `--due <DUE>` — Due date YYYY-MM-DD + + + +## `hive-forge milestone close` + +Close a milestone by id + +**Usage:** `hive-forge milestone close <ID>` + +###### **Arguments:** + +* `<ID>` — Milestone id + + + +## `hive-forge branches` + +List branches, optionally filtered + +**Usage:** `hive-forge branches [PATTERN]` + +###### **Arguments:** + +* `<PATTERN>` — Substring pattern to filter branch names + + + +## `hive-forge tree-sha` + +Print the tree SHA at a branch or commit + +**Usage:** `hive-forge tree-sha <REFERENCE>` + +###### **Arguments:** + +* `<REFERENCE>` — Branch name or commit SHA + + + +## `hive-forge subscription` + +Get/set this user's watch subscription on a repo, or --list all watched repos + +**Usage:** `hive-forge subscription [OPTIONS]` + +###### **Options:** + +* `--watch` — Subscribe (watch the repo) +* `--ignore` — Mute (mark ignored) +* `--unwatch` — Unsubscribe (clear watch + ignore) +* `--list` — List every repo the current user watches (ignores `[repo]`) + + + +## `hive-forge attach-issue` + +Upload a file as an attachment to an issue + +**Usage:** `hive-forge attach-issue <NUMBER> <FILE>` + +###### **Arguments:** + +* `<NUMBER>` — Issue number +* `<FILE>` — File path to upload + + + +## `hive-forge attach-comment` + +Upload a file as an attachment to a comment + +**Usage:** `hive-forge attach-comment <ID> <FILE>` + +###### **Arguments:** + +* `<ID>` — Comment id +* `<FILE>` — File path to upload + + + +## `hive-forge attachment-get` + +Download an attachment by UUID or URL. Saves to a temp file and prints the path (pass `-o -` to stream raw bytes to stdout) + +**Usage:** `hive-forge attachment-get [OPTIONS] <ATTACHMENT>` + +###### **Arguments:** + +* `<ATTACHMENT>` — Attachment UUID or URL. Accepts a bare UUID (`abc-123-...`), a root-relative path (`/attachments/abc-123-...`), or a full URL (`http://localhost:3000/attachments/abc-123-...`) + +###### **Options:** + +* `-o`, `--output <OUTPUT>` — Output path. Defaults to `/tmp/forge-attachment-<uuid>`. Pass `-` to write raw bytes to stdout (e.g. for piping to an image viewer) + + + +## `hive-forge artifact-get` + +Download a CI Actions artifact from a run (`<name> --run <n>`). Saves a zip, or pass `-o -` to stream to stdout + +**Usage:** `hive-forge artifact-get [OPTIONS] --run <RUN> <NAME>` + +###### **Arguments:** + +* `<NAME>` — Artifact name, as shown on the run page (e.g. `pr1ma-paper-pdf`) + +###### **Options:** + +* `--run <RUN>` — Workflow run number — the `runs/<n>` in the run-page URL, which `pr-status` surfaces as a CI context's `target_url`. (This is the per-repo run number, not the global run id; the verb translates.) +* `-o`, `--output <OUTPUT>` — Output path. Defaults to `/tmp/forge-artifact-<name>.zip` (Forgejo serves artifacts zipped). Pass `-` to stream raw bytes to stdout + + + +## `hive-forge ci-log` + +Print a CI Actions run's job step logs (`--run <n> [--job i] [--step i]`) + +**Usage:** `hive-forge ci-log [OPTIONS] --run <RUN>` + +###### **Options:** + +* `--run <RUN>` — Workflow run number — the `runs/<n>` in the run-page URL (shown by `pr-status`) +* `--job <JOB>` — Job index within the run (0-based, default 0) + + Default value: `0` +* `--step <STEP>` — Print only this step's log (0-based). Omit to print every step +* `--attempt <ATTEMPT>` — Run attempt number (re-runs increment it; default 1) + + Default value: `1` + + + +## `hive-forge ci-rerun` + +Re-run CI without an empty commit. Pass one of `--pr <n>`, `--run <n>`, or `--branch <name>`; `--workflow` defaults to `ci.yml` + +**Usage:** `hive-forge ci-rerun [OPTIONS]` + +###### **Options:** + +* `--pr <PR>` — Re-run CI for this PR (its head branch). Mutually exclusive with `--run` / `--branch` +* `--run <RUN>` — Re-run the same workflow on the same branch this run used. The run number is the `runs/<n>` in the run-page URL. Mutually exclusive with `--pr` / `--branch` +* `--branch <BRANCH>` — Re-run `--workflow` on this branch. Mutually exclusive with `--pr` / `--run` +* `--workflow <WORKFLOW>` — Workflow file to run (default `ci.yml`). Ignored for `--run`, which uses the run's own workflow + + Default value: `ci.yml` + + + +## `hive-forge ci-runs` + +List CI Actions runs, newest first (`--workflow`, `--branch`, `--limit`, `--page`) — the run numbers `ci-log`/`ci-rerun --run`/ `artifact-get --run` take + +**Usage:** `hive-forge ci-runs [OPTIONS]` + +###### **Options:** + +* `--workflow <WORKFLOW>` — Only runs of this workflow file (e.g. `ci.yml`) +* `--branch <BRANCH>` — Only runs on this ref. A branch name (`main`, `damocles/foo`) or a PR (`#N`) is qualified for you; a `refs/…` value is used as given. An all-digit value is read as a PR number — to filter a branch literally named that, pass `refs/heads/<name>` +* `--limit <LIMIT>` — How many runs to print (default 20) + + Default value: `20` +* `--page <PAGE>` — Page number (1-based, default 1). Combine with `--limit` to page through further back than the default window + + Default value: `1` + + + +<hr/> + +<small><i> + This document was generated automatically by + <a href="https://crates.io/crates/clap-markdown"><code>clap-markdown</code></a>. +</i></small> diff --git a/docs/tools/forge.md b/docs/tools/forge.md index b7f7d3fd..f0029e1e 100644 --- a/docs/tools/forge.md +++ b/docs/tools/forge.md @@ -4,6 +4,14 @@ container (installed via `nix/agent-modules/forge.nix`, on `PATH` as a proper Rust binary). Use it instead of ad-hoc curl pipelines. +This page is the curated guide. For the exhaustive flag-by-flag reference +auto-generated from the binary's own command tree, see +[`forge-cli.md`](forge-cli.md) — emitted by the hidden `hive-forge +markdown-docs` subcommand and kept in lockstep with the code by the +`hive-forge-docs` flake check (CI fails if the committed copy drifts). +Regenerate with `nix build .#hive-forge && ./result/bin/hive-forge +markdown-docs > docs/tools/forge-cli.md`. + ## Credentials and repo defaults - Credentials: `$HYPERHIVE_STATE_DIR/forge-token` diff --git a/hive-forge/Cargo.toml b/hive-forge/Cargo.toml index 6fd9de5b..34f75535 100644 --- a/hive-forge/Cargo.toml +++ b/hive-forge/Cargo.toml @@ -11,6 +11,7 @@ path = "src/main.rs" [dependencies] anyhow = { workspace = true } clap = { workspace = true } +clap-markdown = "0.1" # `sync` = blocking client (hive-forge is a blocking CLI). TLS backend comes # from feature unification on reqwest — which only works because forgejo-api # and this crate now resolve to the SAME reqwest version; cargo unifies diff --git a/hive-forge/src/main.rs b/hive-forge/src/main.rs index 5a04be79..91fb8103 100644 --- a/hive-forge/src/main.rs +++ b/hive-forge/src/main.rs @@ -195,6 +195,13 @@ enum Verb { /// remote URL. #[command(hide = true)] CredentialHelper(verbs::credential_helper::Args), + /// Emit the full CLI reference as Markdown, walking hive-forge's own + /// clap command tree. + /// + /// Hidden tooling command used by the docs build to keep the published + /// `hive-forge` reference in lockstep with the code. + #[command(hide = true)] + MarkdownDocs, } /// Wrapper over [`run`] that owns how a failure reaches the operator. @@ -245,6 +252,13 @@ fn run() -> Result<()> { if let Verb::CredentialHelper(args) = verb { return verbs::credential_helper::run(args, cli.forge.as_deref()); } + // Same reasoning as `credential-helper` above: no repo, no forge + // credentials — just a pure render of the clap tree the docs build + // pipes into `docs/tools/forge-cli.md`. + if let Verb::MarkdownDocs = verb { + print!("{}", clap_markdown::help_markdown::<Cli>()); + return Ok(()); + } let client = client::Client::from_env(cli.repo, cli.json, cli.forge) .context("initialize forge client")?; // Attach the resolved repo to every verb's error uniformly here, @@ -330,7 +344,7 @@ fn dispatch(client: &client::Client, verb: Verb) -> Result<()> { Verb::CiLog(a) => verbs::ci_log::run(client, a), Verb::CiRerun(a) => verbs::ci_rerun::run(client, a), Verb::CiRuns(a) => verbs::ci_runs::run(client, a), - Verb::CredentialHelper(_) => { + Verb::CredentialHelper(_) | Verb::MarkdownDocs => { unreachable!("handled in `run` before client construction") } } diff --git a/nix/checks.nix b/nix/checks.nix index 662c44aa..56ee05a0 100644 --- a/nix/checks.nix +++ b/nix/checks.nix @@ -241,4 +241,22 @@ in fi touch "$out" ''; + + # `hive-forge` CLI reference freshness check — same shape as + # `hivectl-docs` above, `hive-forge markdown-docs` (clap-markdown over + # its own command tree) instead. Reuses `packages.<system>.hive-forge` + # (already built as its own package, out of `daemonBins` — see + # nix/packages/default.nix's comment on it). + hive-forge-docs = + pkgs.runCommand "hive-forge-docs-fresh" { nativeBuildInputs = [ pkgs.diffutils ]; } + '' + ${self.packages.${system}.hive-forge}/bin/hive-forge markdown-docs > generated.md + if ! diff -u ${../docs/tools/forge-cli.md} generated.md; then + echo "" >&2 + echo "ERROR: docs/tools/forge-cli.md is out of date — regenerate it:" >&2 + echo " nix build .#hive-forge && ./result/bin/hive-forge markdown-docs > docs/tools/forge-cli.md" >&2 + exit 1 + fi + touch "$out" + ''; }