| Filename | Latest commit message | Latest commit date |
|---|---|---|
| .. | ||
| src | ||
| Cargo.toml | ||
| README.md | ||
hive-forge
Typed CLI wrapper around the in-cluster Forgejo's REST API. Replaces
the prior bash script (hive-forge-tools.nix) so that agents and
operators get the same error handling, exit codes, and JSON shapes
regardless of how the bash mood was that day — this is the only
supported path to the forge from inside an agent container; never
curl it directly.
Single binary, one verb subcommand per forge operation (issues, PRs,
comments, labels, reviews, CI status, attachments, triage). Reads
credentials from the environment: HIVE_FORGE_URL (base URL),
HIVE_FORGE_REPO (default repo), HYPERHIVE_STATE_DIR (state dir —
forge-token lives here). The global -f/--forge <label> flag
retargets a dashboard-provisioned external forge account instead,
reading forge-<label>-token + forge-<label>.json from the state
dir rather than the internal-forge pair.
When to use it
Reach for this crate when you're adding a new forge verb or changing
how an existing one behaves — it's the single place issue/PR/comment/
CI logic lives for every agent and hivectl. If you're instead adding
a tool an agent's claude session calls, that's hive-agent-mcp
wrapping a shellout to this binary, not new logic here.
Shape
verbs/— one module per subcommand, each exposing a clap-derivedArgsstruct and arun(&Client, Args) -> Result<()>fn. Splitting one verb per module keeps each handler small and avoids the bash script's monolithiccasestatement. Notable ones:lint.rs—lint <subcommand>triage queries (unassigned, no-reviewer, stale-branches, assignments), always JSON-able via the global--jsonflag.pr_status.rs— the merge-readiness verdict command (pr-status --pr <n>/--sha <commit>); its exit code IS the verdict, not just a report.comment.rs/comments.rs— post (refuses on unread thread activity) / read (marks forge's own notification read as a side effect) — seenotify.rsfor why that's safe to rely on.
client.rs— the app-level Forgejo client wrapper. Identity is the per-agent token under${HYPERHIVE_STATE_DIR}/forge-token. REST calls go through the typedforgejo_api::sync::Forgejoclient (Client::api); a minimal rawreqwestclient remains for the few web-router routes Forgejo doesn't serve under/api/v1/(attachment downloads, Actions artifact/log routes).notify.rs— the read-before-comment guard, backed by forge's own notification read-state rather than a local mirror (which would drift across container restarts). "Is there unread activity here?" is just "does forge still have an unread notification for this thread?" — forge is the single source of truth.body.rs— body-input resolution shared by every verb that posts a body: exactly one source between--body,--body-file, and piped stdin (matches the old bashresolve_bodyhelper); passing both--bodyand--body-fileis a clear error.
Full verb reference (with worked examples): docs/tools/forge.md.