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.
139 lines
7.3 KiB
Markdown
139 lines
7.3 KiB
Markdown
# hive-forge CLI
|
|
|
|
`hive-forge` is the Forgejo API wrapper available in every agent
|
|
container (installed via `harness-base.nix`; lives in `/hive-forge`
|
|
as a proper Rust binary). Use it instead of ad-hoc curl pipelines.
|
|
|
|
## Credentials and repo defaults
|
|
|
|
- Credentials: `$HYPERHIVE_STATE_DIR/forge-token`
|
|
- Default repo: `$HIVE_FORGE_REPO`
|
|
- Per-invocation override: global `-r/--repo` flag
|
|
|
|
## Verbs
|
|
|
|
```bash
|
|
hive-forge view 42 # title + body + comments
|
|
hive-forge comments 42 # list all comments (human-readable)
|
|
hive-forge comments 42 --tail 10 # last 10 comments (count-then-page; efficient on long threads)
|
|
hive-forge --json comments 42 # same as above, JSON array (global flag)
|
|
hive-forge comment 42 --body "..." # post comment (inline body)
|
|
hive-forge comment 42 --body-file - <<EOF # ...or pipe a HEREDOC
|
|
multi-line body
|
|
EOF
|
|
hive-forge comment-show 18042 # fetch one comment by id
|
|
hive-forge comment-edit 18042 --body "..." # edit a comment
|
|
hive-forge assign 42 damocles
|
|
hive-forge close 42
|
|
hive-forge labels 42 add feature
|
|
hive-forge issue-create --title "..." --body "..."
|
|
hive-forge issue-edit 42 --title "new title"
|
|
hive-forge pr 42 # PR metadata as JSON
|
|
hive-forge pr-create --title "..." --head my-branch --push # also `git push forge my-branch`
|
|
hive-forge pr-reviews 42 # list reviews; inline comments included per review
|
|
hive-forge pr-reviews 42 --approve # submit APPROVED review
|
|
hive-forge pr-reviews 42 --request-changes -m "msg" # submit REQUEST_CHANGES review
|
|
hive-forge pr-reviews 42 --comment -m "msg" # submit COMMENT review
|
|
hive-forge diff 42 # unified diff (lockfile hunks collapsed by default)
|
|
hive-forge diff 42 --full # include unfiltered lockfile hunks
|
|
hive-forge list # open issues/PRs
|
|
hive-forge milestone # list milestones
|
|
hive-forge branches deployed/ # filter branches by pattern
|
|
hive-forge tree-sha main # git tree SHA for a ref
|
|
hive-forge -r other-org/other-repo pr 7 # target a different repo
|
|
hive-forge lint unassigned # open issues/PRs with no assignee
|
|
hive-forge lint no-reviewer --reviewer argus # PRs missing a reviewer comment from argus
|
|
hive-forge lint stale-branches --days 14 # branches with no recent activity
|
|
hive-forge lint assignments # per-assignee open item count
|
|
hive-forge pr-status --pr 42 # PR health: mergeable, CI, reviews, last comment (exit 0 = ready)
|
|
hive-forge pr-status --sha <sha> # CI-only fast path for an explicit commit sha
|
|
hive-forge pr-merge 42 # merge (refuses unless mergeable + CI not red + no changes-requested); deletes head branch
|
|
hive-forge pr-merge 42 --method rebase # rebase-merge instead of a merge commit (no squash option)
|
|
hive-forge pr-merge 42 --keep-branch --force # keep the head branch; override the readiness gate
|
|
hive-forge timeline 42 # audit trail: closes, label changes, assignments, commit refs
|
|
hive-forge attach-issue 42 /path/to/file # upload a file attachment to an issue; prints download URL
|
|
hive-forge attach-comment 18042 /path/to/file # upload a file attachment to a comment; prints download URL
|
|
hive-forge attachment-get <uuid> # download an attachment; prints resolved path to stdout
|
|
hive-forge artifact-get pr1ma-paper-pdf --run 51 # download a CI run's Actions artifact zip (run number from the run-page URL)
|
|
hive-forge subscription --watch # subscribe to repo notifications
|
|
hive-forge subscription --unwatch # unsubscribe
|
|
hive-forge -r internal/knowledge clone # clone with creds auto-injected
|
|
hive-forge -r internal/knowledge pr-create --agit --topic foo --title "..." # open PR via AGit (no fork)
|
|
```
|
|
|
|
### Contributing to a read-only repo (`clone` + `pr-create --agit`)
|
|
|
|
Agents are read-only collaborators on some repos (e.g.
|
|
`internal/knowledge`) and so can't push branches. Forgejo's AGit flow
|
|
lets a read-only user open a PR by pushing the current `HEAD` to the
|
|
magic ref `refs/for/<base>/<topic>`. Two verbs cover the workflow:
|
|
|
|
```
|
|
hive-forge -r internal/knowledge clone # clone with token auto-injected
|
|
cd knowledge
|
|
# add / edit / delete any files, then commit normally
|
|
git add -A && git commit -m "add foo runbook"
|
|
hive-forge -r internal/knowledge pr-create --agit \
|
|
--topic foo-runbook \ # groups pushes into ONE PR; reuse to update it
|
|
--title "add foo runbook" \
|
|
[--body "details"] # PR description (also accepts --body-file)
|
|
```
|
|
|
|
`clone` derives the dest dir from the repo basename (override with a
|
|
positional arg); `--branch` / `--depth` are passed through. The token
|
|
is injected into the clone's `origin` remote so `pr-create --agit`
|
|
(default remote `origin`) can push without re-auth.
|
|
|
|
`pr-create --agit` prints the PR URL. Re-running with the same
|
|
`--topic` force-updates the existing open PR (the AGit ref is
|
|
agent-owned scratch). Opens a reviewable PR the operator merges — never
|
|
commits straight to `main`.
|
|
|
|
`hive-forge <verb> --help` prints the full signature for any verb.
|
|
|
|
### `pr-status`
|
|
|
|
One-stop PR health view (`--pr <n>`): mergeable state, CI checks,
|
|
requested reviewers + review verdicts, and the last-comment timestamp —
|
|
the things you need to know whether a PR is ready to merge (CI must pass
|
|
before merge). `--sha <sha>` is a CI-only fast path for a raw commit.
|
|
|
|
A failing/erroring CI context prints its job link. The process exit code
|
|
is a **merge-readiness** verdict for `--pr` (0 only when CI is green AND
|
|
the PR is mergeable AND no review requests changes), so it composes:
|
|
`hive-forge pr-status --pr 42 && echo ready`. `--sha` mirrors the CI
|
|
verdict alone.
|
|
|
|
```
|
|
hive-forge pr-status --pr 42
|
|
# PR #42: feat(...): ...
|
|
# state: open (mergeable: yes)
|
|
# CI: e39a87ea3949: ✅ success (1 context(s))
|
|
# ✅ CI / nix flake check (pull_request): success — Successful in 1m50s
|
|
# reviewers: (none requested)
|
|
# reviews: ✅ argus: APPROVED
|
|
# last comment: 2026-06-05T19:13:28+02:00 by argus
|
|
```
|
|
|
|
Note: review verdicts come from *formal* Forgejo reviews (the
|
|
approve / request-changes API). Reviewers who post their verdict as a
|
|
plain comment show under `last comment`, not `reviews`.
|
|
|
|
## Notes
|
|
|
|
- `comment --body "..."` with backticks in the body: always use
|
|
`--body-file -` with a HEREDOC to avoid shell escaping issues.
|
|
- `pr-create --push` also runs `git push forge <head>` and suppresses
|
|
the post-push "Create a pull request" hint (we print the canonical
|
|
URL ourselves).
|
|
- `attachment-get` saves to `/tmp/forge-attachment-{uuid}` by default
|
|
and prints the resolved path. Pass `-o -` to stream to stdout.
|
|
- `artifact-get <name> --run <n>` downloads a CI Actions artifact. `<n>`
|
|
is the run number from the run-page URL (`/actions/runs/<n>`, which
|
|
`pr-status` surfaces as a CI context's target_url). Forgejo 15 serves
|
|
artifacts only via the web route, not REST, and that route is keyed by
|
|
the run's internal global id, so the verb translates the run number
|
|
first. Saves a zip to `/tmp/forge-artifact-<name>.zip` by default; pass
|
|
`-o -` to stream to stdout.
|
|
- Do NOT use raw `curl` for forge access -- the CLI handles auth,
|
|
error checking, and output formatting.
|