Group issue/PR operations under `pr` and `issue` parent commands
(`hive-forge pr close 42`, `issue create …`, `pr status --pr 42`) per the
operator decision — kind-namespaced verbs replace the flat surface.
- new `verbs::pr_cmd` / `verbs::issue_cmd` parent commands wrap the existing
per-verb modules (reuse their Args + run fns) under `#[command(subcommand)]`.
- kind-validation (the win over the old generic verbs): the generics that work
on both (view/comment/comments/close/labels/assign/timeline) call
`assert_kind` first, so `pr close <issue>` / `issue close <pr>` are rejected
with a 'use the other command' message. PR-only / issue-only verbs are
kind-correct by construction. `number` exposed `pub(crate)` on the shared
verbs so the wrappers can probe it.
- every flat kind verb (`close`, `pr-create`, `pr-status`, `issue-edit`, …)
kept as a `#[command(hide = true)]` back-compat alias — still parses, dropped
from --help; removed in a later sweep once usage migrates. (`pr`/`issue`
bare-show become `pr show` / `issue show` — the names are now parents.)
- docs/tools/forge.md documents the new surface + the deprecated aliases.
cargo build/clippy/fmt clean, 54 tests pass; --help surface + alias parsing
smoke-tested.
Forgejo 15 has no REST endpoint to download an Actions artifact — the
only path is the web UI download route, which is keyed by the run's
global id rather than the per-repo run number shown in run-page URLs.
The REST artifacts list route keys off the run number instead, so the
two can't be chained directly.
artifact-get takes the run number (what pr-status surfaces as a CI
context target_url), translates it to the global run id via the REST
runs list by matching each run's html_url tail, then GETs the web
download route with the agent's forge token. Saves the artifact zip to
a path (default /tmp/forge-artifact-<name>.zip) or streams to stdout
with -o -.
The artifact name is percent-encoded into the path. The encoder that
list already used for query-string filters is promoted to a shared
verbs::pct_encode helper so both call sites stay in sync.
Lets an agent pull a CI-built artifact (e.g. a paper PDF) into /shared
without host access.
Adds `hive-forge pr-merge <n> [--method merge|rebase] [--keep-branch]
[--force]` wrapping POST /repos/{owner}/{repo}/pulls/{n}/merge, so agents on
the peer-review-and-merge workflow have a CLI path instead of the raw API.
- Methods: merge (default) | rebase. Squash is intentionally not offered.
- Deletes the head branch after merge unless --keep-branch.
- Safe by default: refuses unless the PR is mergeable, CI is not red, and no
review's current verdict requests changes (latest-per-reviewer wins, so a
later approval clears an earlier request-changes). --force overrides and
also sets Forgejo's force_merge.
- New client helper post_no_content for the 200-empty-body merge response.