From f034ffb9d82d0d559465ba646e938c3516e49e9f Mon Sep 17 00:00:00 2001 From: damocles Date: Wed, 29 Jul 2026 18:37:37 +0200 Subject: [PATCH] hive-forge: infer active repo from cwd's git remote, demote HIVE_FORGE_REPO --- Cargo.lock | 1 + docs/tools/forge.md | 9 +- hive-agent/prompts/system.md | 2 +- hive-forge/Cargo.toml | 3 + hive-forge/README.md | 7 +- hive-forge/src/client.rs | 182 ++++++++++++++++-- hive-forge/src/main.rs | 10 +- hive-forge/src/verbs/clone.rs | 7 +- hive-forge/src/verbs/repo_add_collaborator.rs | 5 +- 9 files changed, 201 insertions(+), 25 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cbe1df47..99d06fef 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1689,6 +1689,7 @@ dependencies = [ "reqwest 0.13.1", "serde", "serde_json", + "tempfile", "time", "url", ] diff --git a/docs/tools/forge.md b/docs/tools/forge.md index b9f83ea6..2e50a5eb 100644 --- a/docs/tools/forge.md +++ b/docs/tools/forge.md @@ -7,8 +7,10 @@ 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 +- Active repo resolves, highest priority first: global `-r/--repo` flag + > the `origin` remote of the cwd's git checkout > `$HIVE_FORGE_REPO` + (last-resort override, unset by default) > a hard error. No single + repo is assumed by default — see `client::Client::from_env`. ## Verbs @@ -207,7 +209,8 @@ and print its URL. Key flags: - `--description ` — repo description **`repo-add-collaborator `** — grant a forge user access to the -active repo (`-r`/`HIVE_FORGE_REPO`). Companion to `repo-create`. The +active repo (see the repo-resolution chain above). Companion to +`repo-create`. The `--permission` flag accepts `read` / `write` (default) / `admin`. `hive-c0re` uses this internally when an agent's config repo is initialised. diff --git a/hive-agent/prompts/system.md b/hive-agent/prompts/system.md index b4bddaea..6aafb505 100644 --- a/hive-agent/prompts/system.md +++ b/hive-agent/prompts/system.md @@ -36,7 +36,7 @@ Claude session (OAuth credentials) lives at `/root/.claude/` and persists across **Code forge**: a private Forgejo at `http://localhost:3000` is available when `/agents/{label}/state/forge-token` exists. You have your own user account (named `{label}`). Use `hive-forge` (see below) for all forge operations — issues, PRs, comments, labels, etc. For git operations use plain `git` directly against `http://localhost:3000//.git` (credentials are pre-configured). -The `hive-forge` CLI is the supported interface to the Forgejo — issues, PRs, comments, labels, reviews, CI status, attachments, triage (`lint`). **Discover the verb list and each verb's full signature with `hive-forge --help` and `hive-forge --help`** rather than memorising them. Default repo comes from `HIVE_FORGE_REPO`; pass `-r ` (global flag, works before or after the verb) to target a different repo. A few conventions `--help` won't surface: **never `curl` the forge** — the CLI handles auth and is the only supported path; to check a PR's CI + mergeability use `hive-forge pr-status --pr ` (or `--sha ` for a CI-only fast path; exit code is a merge-readiness verdict), not curl. `--body-file -` reads the body from stdin, so a HEREDOC works for multi-line comments/issues: `hive-forge comment --body-file - < [--push]` opens a PR and prints its URL; `--push` `git push`es the head branch first (default remote `forge`). Forge notifications are delivered via the internal message daemon (sender `forge`), not polling. A `forge` notification stays unread **on the forge** until you actually read its thread — viewing the referenced issue/PR with `hive-forge comments ` or `view ` marks that notification read (it's the forge's own read-state, not a local mirror). So when a `forge` message points you at a thread, read the thread to clear the notification instead of letting the same one linger and re-surface. (`hive-forge comment` does the opposite — it *refuses* to post to a thread with unread activity until you've read it, so read first, then comment.) +The `hive-forge` CLI is the supported interface to the Forgejo — issues, PRs, comments, labels, reviews, CI status, attachments, triage (`lint`). **Discover the verb list and each verb's full signature with `hive-forge --help` and `hive-forge --help`** rather than memorising them. The active repo is whichever git checkout you're standing in (inferred from the `origin` remote), or pass `-r ` (global flag, works before or after the verb) to target a different one explicitly — there's no single hardcoded default repo, so don't assume one. A few conventions `--help` won't surface: **never `curl` the forge** — the CLI handles auth and is the only supported path; to check a PR's CI + mergeability use `hive-forge pr-status --pr ` (or `--sha ` for a CI-only fast path; exit code is a merge-readiness verdict), not curl. `--body-file -` reads the body from stdin, so a HEREDOC works for multi-line comments/issues: `hive-forge comment --body-file - < [--push]` opens a PR and prints its URL; `--push` `git push`es the head branch first (default remote `forge`). Forge notifications are delivered via the internal message daemon (sender `forge`), not polling. A `forge` notification stays unread **on the forge** until you actually read its thread — viewing the referenced issue/PR with `hive-forge comments ` or `view ` marks that notification read (it's the forge's own read-state, not a local mirror). So when a `forge` message points you at a thread, read the thread to clear the notification instead of letting the same one linger and re-surface. (`hive-forge comment` does the opposite — it *refuses* to post to a thread with unread activity until you've read it, so read first, then comment.) Keep messages short — a few sentences each. For anything big (file listings, long diffs, transcripts, analysis): write the payload to `/agents/{label}/state/` and `send` a short pointer ("dropped the cluster audit in /agents/{label}/state/cluster-audit-2026-05.md, headline: 3 nodes over 80% mem"). The operator can read your state from the host as `/agents/{label}/state/`. Sub-agent peers can't read each other's state directly — coordinate through shared space or a common parent. diff --git a/hive-forge/Cargo.toml b/hive-forge/Cargo.toml index 746d6b14..23f75d32 100644 --- a/hive-forge/Cargo.toml +++ b/hive-forge/Cargo.toml @@ -39,5 +39,8 @@ reqwest = { workspace = true, features = [ serde = { workspace = true } serde_json = { workspace = true } +[dev-dependencies] +tempfile = "3" + [lints] workspace = true diff --git a/hive-forge/README.md b/hive-forge/README.md index fbcb32ce..df32661c 100644 --- a/hive-forge/README.md +++ b/hive-forge/README.md @@ -8,8 +8,11 @@ consistent error handling, exit codes, and JSON shapes. This is the never `curl` it directly. Reads credentials from the environment (`HIVE_FORGE_URL`, -`HIVE_FORGE_REPO`, `HYPERHIVE_STATE_DIR`); `-f/--forge