Commit graph hyperhive/hive-forge
Author SHA1 Message Date
atlas
5a06d1156b hive-forge: add repo-labels verb to list a repo's full label set
`labels <number>` only lists an issue/PR's labels; there was no way to
list the project-wide label set, which triage/labelling needs to discover
valid names. Add `repo-labels [pattern]` hitting GET /repos/{owner}/{repo}/labels
(paginated), with optional name-substring filter. Default prints one label
per line (name + tab-separated description when set); --json emits the full
label objects.
2026-06-19 01:45:08 +02:00
atlas
1e39a6c12b feat(forge): trust the system CA store in the hive-forge client
Enable reqwest's rustls-tls-native-roots feature for hive-forge so its
HTTP client validates against the OS/system CA store (rustls-native-certs)
in addition to the bundled webpki roots. Once the hive CA is embedded into
agent system trust stores (via the meta flake's security.pki.certificateFiles
wiring), hive-forge validates the gateway's self-signed leaf with no extra
env plumbing.

Additive: the bundled webpki roots stay enabled, so public CAs still
validate; the native store adds the hive CA. On NixOS the system store
already includes the Mozilla bundle, so the effective trust set is a
superset. Cargo unifies features across the build, so native-root loading
is enabled for every reqwest client — harmless, since it only widens the
root set.

Final piece of the self-signed agent-trust chain (host CA + gateway leaf,
then CA embedded into agent flakes, now the forge client honouring it).
2026-06-17 21:09:16 +02:00
damocles
9f9c1167ae hive-forge: add pr-commits verb (PR commit list, survives rebase-rewritten shas) 2026-06-17 19:25:01 +02:00
damocles
8acf9dcd9b hive-forge: surface pr-reviews write flags in its --help summary (closes #1716) 2026-06-17 15:16:58 +02:00
damocles
f723806eae list: reject --page 0 and --limit 0 (1-based; clap range parser, per review) 2026-06-17 13:49:45 +02:00
damocles
2005b205e9 list: paging via --page instead of --all (token-bounded per call, per review) 2026-06-17 13:49:45 +02:00
damocles
0aef643797 hive-forge: add --all to list for full-pagination repo-wide sweeps 2026-06-17 13:49:45 +02:00
damocles
21e5233c1f ci-log: graceful message when a run's logs are gc'd (404/500) instead of raw http error 2026-06-17 10:05:21 +02:00
damocles
a69844d463 hive-forge: fix ci-log clippy cast_possible_truncation (use try_from) 2026-06-16 11:51:01 +02:00
damocles
2223af1b21 hive-forge: add ci-log verb for actions job step logs (closes #1674) 2026-06-16 11:34:31 +02:00
atlas
e6f9679ec9 hive-forge: add issues/issue-list discovery aliases for the list verb
The verb that lists issues/PRs with filters is `list`, but `issues` and
`issue-list` are the names people reach for first — and clap's
"did you mean" tip points at `issue` / `issue-create`, never at `list`.
Two agents independently failed to find it that way.

Add `issues` and `issue-list` as visible clap aliases so the verb is
discoverable under the names people actually type (and they show in
`--help`). No behaviour change; `list` stays canonical.
2026-06-16 00:18:32 +02:00
atlas
6490fc422e feat(hive-forge): add artifact-get verb to download CI run artifacts
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.
2026-06-15 17:59:38 +02:00
atlas
f633abbdc4 refactor(hive-forge): share latest-per-reviewer logic between pr-status and pr-merge
pr-status and pr-merge both computed 'latest non-comment review verdict per
reviewer' independently (identical oldest-first, COMMENT/PENDING-skipping,
supersede-by-later loop). Extract it to a shared verbs::latest_reviews helper
so the verdict semantics live in one place and can't drift between the
health view and the pre-merge changes-requested gate. Pure dedup, no
behaviour change.
2026-06-15 11:44:19 +02:00
atlas
9d8367bb24 feat(hive-forge): add pr-merge verb (#1670)
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.
2026-06-15 11:36:17 +02:00
atlas
c7ffe9336b docs(hive-forge): add # Errors to put_no_content (argus review) 2026-06-14 22:09:31 +02:00
atlas
3790faf318 feat(hive-forge): add repo-create + repo-add-collaborator verbs 2026-06-14 22:09:31 +02:00
atlas
ab1b07acce ci(#1555): prose-ify legacy tracker tags; add lint:allow escape hatch
Clean the legacy backlog so the tracker-tag lint can become a required
gate (mara's warn-during-cleanup -> full-tree-enforcement path). Rewrite
the ~33 real `closes/see #NNN` provenance refs in doc-comments to prose
across hive-forge, hive-c0re, hive-ag3nt, hive-matrix-mcp, hive-sh4re,
and add a `lint:allow` line marker to check-issue-refs.sh for genuine
non-tracker `#<digits>` (a hash-digit heading-detection test input).
Tree is now lint-clean; tracker-tag lint ready to promote to required.
2026-06-10 13:14:42 +02:00
damocles
7c9954ceec chore(#1474): add reason= to remaining bare clippy allows outside dashboard 2026-06-09 11:25:38 +02:00
damocles
05002acda4 chore(#1474): document the too_many_arguments keeps in hive-forge + hive-ag3nt 2026-06-08 21:01:32 +02:00
damocles
f9fe3280f9 chore: justify the remaining keep-only cast + serde-default allows with reasons 2026-06-06 14:25:41 +02:00
damocles
31d9cb561a fix: hive-forge agit pr-create sets multi-line body via rest patch 2026-06-06 00:36:29 +02:00
damocles
79101edc2f address argus: drop issue tags from clone/pr-create module docs, fix stale knowledge wording 2026-06-05 20:51:50 +02:00
damocles
c103ae5f10 feat(#1399): hive-forge clone verb + pr-create --agit for no-fork PRs 2026-06-05 20:51:50 +02:00
damocles
7031f57c14 feat(#1409): hive-forge pr-status verb (mergeable, CI, reviews, last comment) 2026-06-05 19:53:20 +02:00
iris
92b32d06fb fix(clippy): fix all clippy warnings in hive-ag3nt, hive-forge, hive-matrix-mcp, hive-sh4re
Fixes all clippy -D warnings errors in the crates iris owns:

hive-sh4re:
- doc_lazy_continuation: add blank /// separator in priv_proto.rs
- doc_markdown: backtick PRIVATE_NETWORK=0 / PRIVATE_NETWORK=1

hive-matrix-mcp:
- map_unwrap_or: map().unwrap_or_else() -> map_or_else() in paths.rs
- collapsible_if: if-let chains in wake.rs
- doc_markdown: backtick M_UNKNOWN_TOKEN in main.rs
- cast_possible_truncation: usize/u64 -> u32::try_from in handlers.rs
- map_unwrap_or: map_or_else() in handlers.rs
- manual_let_else: match Ok(r) => r, Err => return -> let Ok in handlers.rs
- unused_async: remove async from list_invites; update socket.rs call site

hive-forge:
- doc_markdown: backtick REQUEST_CHANGES / APPROVED / COMMENT in pr_reviews.rs
- unnecessary_wraps: list_reviews_text returns () not Result<()>
- doc_markdown: backtick start_page / last_page in comments.rs
- cast_possible_truncation: PAGE_SIZE u64 -> usize; remove as usize casts

hive-ag3nt:
- collapsible_if: if-let chains in events.rs and mcp.rs
- single_match_else: match -> if let in events.rs and mcp.rs
- items_after_statements: hoist STATUS_MAX_CHARS const in mcp.rs
- map_unwrap_or: map_or_else() in mcp.rs and mcp_loose_ends.rs
- cast_possible_truncation: usize -> u32::try_from in mcp.rs
- doc_markdown: backtick snake_case in mcp.rs, needs_update/deployed_sha
  in web_ui.rs, HISTORY_CAPACITY in web_ui.rs
- identical_match_arms: combine manage_root_agent | query_agent_state
- redundant_closure: |s| s.to_string() -> ToString::to_string in web_ui.rs
- duration_suboptimal_units: from_secs(3600) -> from_hours(1) in turn.rs

Remaining failures in hive-c0re (39), hive-priv (8), hive-bash-mcp (11)
are owned by damocles.
2026-06-05 14:35:12 +02:00
atlas
20c5039156 style: treefmt main — fix CI formatting check
Full `nix flake check` (CI) runs the treefmt formatting derivation. While the
hive-ci runner was offline (#1221), PRs merged without it, leaving 5 files
unformatted: hive-ag3nt/src/web_ui.rs, hive-c0re/src/bin/hivectl.rs,
hive-c0re/src/knowledge.rs, hive-c0re/src/matrix.rs,
hive-forge/src/verbs/attachment_get.rs. `nix fmt` output, pure formatting.
2026-06-05 13:09:56 +02:00
damocles
7f7ee7dbef fix: correct doc comment — path goes to stdout not stderr 2026-06-05 00:46:49 +02:00
damocles
98f96e5435 feat(#1315): hive-forge attachment-get verb - download attachments by uuid or url 2026-06-05 00:46:49 +02:00
damocles
41eb3f806c refactor: remove hyperhive.role option — there is only one role: agent 2026-06-04 14:31:44 +02:00
damocles
d3239fef35 fix(#1233): subscription --watch uses PUT, GET handles 404 as not-watching 2026-06-03 23:23:51 +02:00
damocles
aa91d0d30d refactor(#1141): split list_reviews into list_reviews_json + list_reviews_text 2026-06-03 16:04:07 +02:00
damocles
374e53d13e nit(#1141): suppress :line in text output when comment has no line number 2026-06-03 16:01:32 +02:00
damocles
b39967eb7a refactor(#1141): extract submit_review, list_reviews, fetch_inline_comments helpers 2026-06-03 16:00:35 +02:00
damocles
eae124a460 feat(#1141): pr-reviews list mode shows inline review comments 2026-06-03 15:24:34 +02:00
atlas
68e30b857c feat(#1137): rich unread summary in loose ends and wake signal
- hive-sh4re: UnreadMatrix gains summary: String field (per-room breakdown)
- hive-matrix-mcp/protocol: add RoomUnread struct + UnreadSummary request
- hive-matrix-mcp/handlers: collect_unread() fetches per-room data;
  single-unread rooms include truncated last-message body + sender;
  multi-unread rooms carry count only
- hive-matrix-mcp/wake: format_unread_summary() builds wake body from
  RoomUnread slice; terse one-liner for single-room/single-message,
  bulleted list for multi-room; always appends read-hint
- hive-matrix-mcp/timeline: wake body now covers all rooms with unread
  at fire time, not just the triggering event; falls back to per-event
  teaser if notification counts haven't updated yet
- hive-ag3nt/mcp: matrix_unread_summary() replaces matrix_unread_rooms();
  UnreadMatrix loose end carries per-room summary lines; render shows
  room breakdown with sender: body for single-unread rooms
2026-06-03 13:56:00 +02:00
damocles
817d94023d feat(#1081): add --approve/--request-changes/--comment to pr-reviews 2026-06-02 13:33:30 +02:00
atlas
4bff450343 feat(gateway): hivectl gateway user management + fix htpasswdFile assertion
Add `hivectl gateway {create-user,delete-user,list-users}` subcommands for
managing htpasswd files used by gateway Basic auth. Pure Rust bcrypt
(cost 12, $2y$ prefix nginx accepts). No external htpasswd binary required.

Also fix the NixOS module assertion: `cfg.auth ? htpasswdFile` is always
true in the module system (declared options always exist as keys); switch
to `nullOr path; default = null` + `!= null` check so the assertion
actually fires with a useful error when enable=true but no file is set.
Guard bind-mount and nginx config against null to prevent eval errors.

Update docs/gateway.md to show hivectl commands instead of raw htpasswd.
2026-06-01 23:25:28 +02:00
atlas
5c5ca38fe8 fix(#999): resolve all clippy warnings across the workspace
All crates now pass `cargo clippy --workspace -- -D warnings` cleanly.

Fixes span six crates (hive-sh4re, hive-ag3nt, hive-c0re, hive-forge,
hive-priv, hive-matrix-mcp was already clean):

- doc_markdown: wrap snake_case, type names, constants in backticks
- collapsible_if / collapsible_match: fold nested ifs into let-chains
- duration_suboptimal_units: Duration::from_secs(N) → from_mins/from_hours
- implicit_hasher: allow on HashMap-param fns where generalization is risky
- items_after_statements: hoist use to function tops
- map(f).unwrap_or(x) → map_or(x, f); map(f).unwrap_or_else(g) → map_or_else
- is_ok_and / is_none_or in place of map().unwrap_or(bool)
- needless_continue: {} instead of continue in loop match arms
- match_same_arms: Ok(None) | Err(_) merged
- format_push_str: write!() instead of push_str(&format!())
- while let replaces loop { let Some(..) = x else { break } }
- struct_excessive_bools / dead_code: allow on purpose-built structs
- too_many_lines / too_many_arguments: allow where refactor not worth it
- unused_async: remove async from poll_once in bash_runner
- needless_borrow: fix &repo deref in hive-forge comments verb
- cast_possible_truncation: allow u64→usize in fetch_tail

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 22:31:06 +02:00
damocles
d59bfb899f hive-forge: drop boilerplate # Errors from pure-GET verbs (mara on #827, option A)
mara: 'those comments seem very redundant'. true — the 16 pure-GET
verbs all got the same 'transport error + stdout I/O' boilerplate,
which just restates the Result<()> contract that's trivially
derivable from the type.

dropped # Errors from: assign, branches, close, comment_show,
comments, diff, issue, labels, lint, list, milestone, pr,
pr_reviews, subscription, timeline, tree_sha, view (17 files).

kept on the 7 verbs that have a non-Forgejo failure surface worth
documenting:
- comment, comment_edit, issue_create, issue_edit — body input I/O
  via --body-file / stdin
- pr_create — body input + --push shellout to git
- attach::run_issue, attach::run_comment — explicit bail! on
  missing file

net: 23 verbs touched in the original PR → 17 trimmed back to
no-doc, 6 kept (with the 7th call being attach::run_comment in the
same file). 38 tests still pass.
2026-05-31 16:22:05 +02:00
damocles
1195bfbe11 hive-forge: add # Errors docs on every verb's pub fn run (closes #816)
systemic gap argus flagged on PR #798 (timeline verb). every `pub fn
run` in hive-forge/src/verbs/*.rs lacked a `# Errors` block —
violates Rust API guidelines + obscures the failure surface for
operators reading the source.

uniform doc per verb category:
- pure GET + print verbs: "transport error from the Forgejo REST call
  + I/O error from stdout"
- body-from-file verbs (comment/comment_edit/issue_create/issue_edit/
  pr_create): adds 'I/O error from --body-file/stdin input'
- file-upload verbs (attach-issue, attach-comment): adds 'file
  read/exist check'
- pr_create: also mentions the --push shellout

23 `pub fn run` signatures touched. no behaviour change; pure
documentation sweep. cargo test green (38 tests).
2026-05-31 16:22:05 +02:00
damocles
224385af37 hive-forge: extract format_event helper; tests call it directly (argus 🟡 on #798)
was: `print_event` did the format + println inline; tests had a
parallel `captured` helper that re-implemented the dispatch and only
covered 4 of 14 event types. brittle — a new arm in `print_event`
silently went uncovered.

now: pure `format_event(ev: &Value) -> String` builds the line;
`print_event` is a thin wrapper that adds the trailing newline.
tests assert on `format_event` output directly so every new arm
gets test coverage by construction.

bonus: added 3 more test cases (assignees add/remove, pull_push
commit count + force-push, commit_ref sha truncation) since the
helper extraction made them cheap. 9 tests total, all green.
2026-05-31 15:14:08 +02:00
damocles
8f9866f5e1 hive-forge: timeline verb — issue/PR audit trail (closes #783)
last unstarted piece of the original #694 epic. agents kept falling
back to curl for 'who closed this?' / 'when was this labelled?'
archaeology because view + comments only surface the body + comments,
not the structured timeline events (label adds, assignments, closes,
reopens, pushes, commit refs, review submissions, milestone changes).

separate verb rather than view --timeline because:
- composes naturally with view <n> / comments <n>
- keeps existing verb output shapes stable (no script breakage)
- argus on #770 already noted view's output is busy

human-readable by default ('**actor @ ts**: <summary>'), --json for
raw piping. unknown event types fall through to a '[<type>]'
placeholder so a forge schema bump doesn't panic the verb.

--tail N is a follow-up: timeline endpoint doesn't expose a total-count
field so the count-then-page strategy from #770 doesn't apply
directly.

6 tests cover comment / label add/remove / close / unknown-type
placeholder / missing-user fallback.
2026-05-31 15:14:08 +02:00
damocles
7cc59c4338 hive-forge: update --tail field doc to match count-then-page impl (argus on #770) 2026-05-31 15:12:41 +02:00
damocles
f57cf916a1 hive-forge: count-then-page strategy for comments --tail (mara feedback #770)
read the issue's `comments` count first, compute which page contains the
tail, fetch only `ceil(n/50) + 1` pages. drops the TAIL_MAX_PAGES cap
entirely — it was paging from the WRONG end (first 1000 comments instead
of the last n) on long threads, defeating the whole purpose of --tail.
work is now bounded by n, not by thread length.
2026-05-31 15:12:41 +02:00
damocles
7d31b7def4 hive-forge: warn when --tail saturates the pagination cap (argus 🟡 on #770) 2026-05-31 15:12:41 +02:00
damocles
5f4494c239 hive-forge: comments --tail N flag (#694 part 3) — last N comments in chronological order 2026-05-31 15:12:41 +02:00
damocles
8f9c77df06 hive-forge: list verb — filter issues/PRs by kind/state/assignee/author/label (#694 part 2) 2026-05-31 14:02:54 +02:00
damocles
b43438d1a6 hive-forge: collapse autogenerated diffs to a single one-line summary (#222) 2026-05-29 01:16:51 +02:00
damocles
1d7feeb029 hive-forge: pr-create --push opts into branch push + hint suppression (#222) 2026-05-28 01:08:43 +02:00
damocles
f866f1822e hive-forge: require --reviewer explicitly for lint no-reviewer (mara nit on #507) 2026-05-27 12:01:54 +02:00