From 06b303aff20dfb753034edc816db1e8668d33bcc Mon Sep 17 00:00:00 2001 From: damocles Date: Fri, 6 Nov 2026 23:37:12 +0100 Subject: [PATCH] hivectl: the open verb is gone and the docs say what hivectl has --- docs/2-handbook/reference/hivectl-cli.md | 27 ------------- docs/2-handbook/tools/hivectl.md | 33 ---------------- hive-c0re/src/server.rs | 3 +- hive-host-sock/src/lib.rs | 4 +- hivectl/README.md | 6 +-- hivectl/src/cli.rs | 20 ---------- hivectl/src/main.rs | 3 -- hivectl/src/open.rs | 46 ---------------------- nix/host-modules/hive-c0re/environment.nix | 4 +- 9 files changed, 7 insertions(+), 139 deletions(-) delete mode 100644 hivectl/src/open.rs diff --git a/docs/2-handbook/reference/hivectl-cli.md b/docs/2-handbook/reference/hivectl-cli.md index 167eba48..d52fc4d0 100644 --- a/docs/2-handbook/reference/hivectl-cli.md +++ b/docs/2-handbook/reference/hivectl-cli.md @@ -36,7 +36,6 @@ This document contains the help content for the `hivectl` command-line program. * [`hivectl stop`↴](#hivectl-stop) * [`hivectl start`↴](#hivectl-start) * [`hivectl restart`↴](#hivectl-restart) -* [`hivectl open`↴](#hivectl-open) * [`hivectl completions`↴](#hivectl-completions) ## `hivectl` @@ -55,7 +54,6 @@ Sibling to the `hive-c0re` daemon binary. Covers host-side admin operations that * `stop` — Stop containers hive-wide in one operator action * `start` — Start containers hive-wide — the inverse of `hivectl stop` * `restart` — Restart containers hive-wide — `stop` then `start` over one scope -* `open` — Print (and best-effort open in a browser) a hive web surface URL * `completions` — Generate a shell completion script for `hivectl` and print it to stdout ###### **Options:** @@ -486,31 +484,6 @@ Bare `hivectl restart` restarts everything; scope flags narrow it. The swarm's f -## `hivectl open` - -Print (and best-effort open in a browser) a hive web surface URL. - -Resolves the URL from the running daemon so custom forge / matrix domains work. Bare `hivectl open` opens the operator dashboard. - -**Usage:** `hivectl open [TARGET]` - -###### **Arguments:** - -* `` — Which surface to open. Defaults to the operator dashboard - - Default value: `home` - - Possible values: - - `home`: - The operator dashboard (`https://.hives./`) - - `forge`: - The forge (Forgejo) web UI - - `matrix`: - The matrix GUI (fluffychat) - - - - ## `hivectl completions` Generate a shell completion script for `hivectl` and print it to stdout. diff --git a/docs/2-handbook/tools/hivectl.md b/docs/2-handbook/tools/hivectl.md index 2b7cf2e3..d4313f8e 100644 --- a/docs/2-handbook/tools/hivectl.md +++ b/docs/2-handbook/tools/hivectl.md @@ -21,13 +21,6 @@ markdown-docs` subcommand and kept in lockstep with the code by the Regenerate with `nix build .#default && ./result/bin/hivectl markdown-docs > docs/2-handbook/reference/hivectl-cli.md`. -## Forge - -`hivectl` has no forge verbs and makes no forge accounts: a human's first SSO -login to the forge makes theirs, and `swarmctl forge make-admin ` makes it -a site admin. swarm-controller makes an agent's, and `swarmctl agent -mint-forge-token ` checks and, if needed, re-mints its token. - ## Agents Container lifecycle shortcuts that go through the host admin socket. @@ -164,29 +157,3 @@ the harness already stamps onto stream-json events for the web UI glyph-prefixed lines instead of raw JSON. Not an attempt at the web UI's full collapsible-details rendering (`docs/4-implementation/web-ui/terminal-rendering.md`) — that's presentation for a browser, this is a `tail -f`. - -## Open - -Print (and best-effort open in a browser) one of the hive's web surfaces. -Requires the `hive-c0re` daemon to be running. - -```bash -hivectl open # operator dashboard (same as `open home`) -hivectl open home # operator dashboard (https://.hives./) -hivectl open forge # the forge (Forgejo) web UI -hivectl open matrix # the matrix GUI (fluffychat) -``` - -hivectl resolves the URL from the running daemon (`HostRequest::Urls`), which -reads the per-surface public URLs from c0re's service env — so custom -forge / matrix domains resolve correctly instead of assuming -`forge.`. The URL is **always printed** (the reliable core, since -the host is typically headless / driven over SSH), then hivectl tries -`xdg-open` as a convenience, reporting a missing or failing opener as a -note, not an error. - -A surface has no URL when it isn't browser-reachable: `home` needs -`services.hyperhive.domain`; `forge` needs -`services.hyperhive.swarm.forge.publicUrl` (set by default); `matrix` needs -`services.hyperhive.swarm.matrix.gatewayHost` (set by default). In those cases the command -exits with a hint naming the option to set. diff --git a/hive-c0re/src/server.rs b/hive-c0re/src/server.rs index a7413f1e..e260a280 100644 --- a/hive-c0re/src/server.rs +++ b/hive-c0re/src/server.rs @@ -200,8 +200,7 @@ async fn dispatch(req: &HostRequest, coord: Arc) -> HostResponse { // The hive domain + per-surface public URLs are injected into // c0re's service env by the hyperhive module; surface them so the // operator CLI can fill in this hive's own identity (the - // federation peer-config block) and open the web surfaces - // (`hivectl open`). + // federation peer-config block). HostRequest::Urls => HostResponse::urls(hive_urls()), HostRequest::QuotaEnable => handle_quota_enable().await?, HostRequest::QuotaLimit { name, limit } => { diff --git a/hive-host-sock/src/lib.rs b/hive-host-sock/src/lib.rs index e028f1c9..7f03dd29 100644 --- a/hive-host-sock/src/lib.rs +++ b/hive-host-sock/src/lib.rs @@ -178,8 +178,8 @@ pub enum HostRequest { /// forge / matrix URLs, daemon-sourced so custom forge/matrix /// domains resolve correctly. Each URL is `None` when its subsystem /// is unreachable from a browser (e.g. forge `publicUrl` null, - /// matrix `gatewayHost` null). Backs `hivectl open` + the federation - /// peer-config block (which reads the bare `domain`). + /// matrix `gatewayHost` null). Backs the federation peer-config block + /// (which reads the bare `domain`). Urls, /// Fetch one or more job-queue nodes plus their live subtrees, as /// generic `hive-jobq-wire` nodes — `hivectl`'s wait/progress loop, diff --git a/hivectl/README.md b/hivectl/README.md index a1808e5e..64c11e18 100644 --- a/hivectl/README.md +++ b/hivectl/README.md @@ -25,11 +25,9 @@ dispatch: - **`power.rs`** — restart/start/stop at the container level. - **`choom.rs`** — drop into an interactive claude session in a container. -- **`forge.rs`** — reconciles an agent's config against its forge - repo. - **`wg.rs`** — WireGuard mesh helpers. - **`subvol.rs`** — btrfs state-subvolume ops. -- **`quota.rs`**, **`util.rs`**, **`completions.rs`**, **`open.rs`** — - shared helpers, shell completions, browser-open. +- **`quota.rs`**, **`util.rs`**, **`completions.rs`** — shared helpers + and shell completions. Full verb reference: `docs/2-handbook/tools/hivectl.md`. diff --git a/hivectl/src/cli.rs b/hivectl/src/cli.rs index e1212e40..df44b23c 100644 --- a/hivectl/src/cli.rs +++ b/hivectl/src/cli.rs @@ -126,15 +126,6 @@ pub enum Cmd { #[arg(long)] graceful: bool, }, - /// Print (and best-effort open in a browser) a hive web surface URL. - /// - /// Resolves the URL from the running daemon so custom forge / matrix - /// domains work. Bare `hivectl open` opens the operator dashboard. - Open { - /// Which surface to open. Defaults to the operator dashboard. - #[arg(value_enum, default_value_t = OpenTarget::Home)] - target: OpenTarget, - }, /// Emit the full CLI reference as `CommonMark` to stdout. /// /// Hidden tooling command used by the docs build to keep the published @@ -153,17 +144,6 @@ pub enum Cmd { }, } -/// Which hive web surface `hivectl open` targets. -#[derive(Copy, Clone, Debug, clap::ValueEnum)] -pub enum OpenTarget { - /// The operator dashboard (`https://.hives./`). - Home, - /// The forge (Forgejo) web UI. - Forge, - /// The matrix GUI (fluffychat). - Matrix, -} - /// Shared scope flags for `hivectl stop` / `start` / `restart`. With no /// flag set the verb targets **everything** (all sub-agents + the /// gateway). Setting any flag restricts to the selected classes, diff --git a/hivectl/src/main.rs b/hivectl/src/main.rs index 69c07c32..6bdc7b67 100644 --- a/hivectl/src/main.rs +++ b/hivectl/src/main.rs @@ -31,8 +31,6 @@ mod completions; mod quota; mod util; use completions::generate_completions; -mod open; -use open::open_url; mod wg; use wg::{peer_config, require_hive_domain, wg_init, wg_peer, wg_status}; mod agents; @@ -93,7 +91,6 @@ async fn main() -> Result<()> { print!("{}", clap_markdown::help_markdown_custom::(&options)); Ok(()) } - Cmd::Open { target } => open_url(&socket, target).await, Cmd::Completions { shell } => { generate_completions(shell); Ok(()) diff --git a/hivectl/src/open.rs b/hivectl/src/open.rs deleted file mode 100644 index 0298d35d..00000000 --- a/hivectl/src/open.rs +++ /dev/null @@ -1,46 +0,0 @@ -//! `hivectl open ` — resolve a hive surface URL from the -//! daemon, print it, and best-effort `xdg-open` it. - -use std::path::Path; - -use anyhow::{Context as _, Result}; - -use crate::cli::OpenTarget; -use crate::util::query_hive_urls; - -/// `open ` — resolve the surface URL from the daemon, -/// print it, then best-effort `xdg-open` it. Printing is the reliable -/// core (headless / SSH hosts where no browser opener exists); the open -/// is convenience on top, so a missing/failed `xdg-open` is not an error. -pub(crate) async fn open_url(socket: &Path, target: OpenTarget) -> Result<()> { - // The connect error is already actionable (`client::request` classifies - // it), so propagate it rather than restating a guess about the cause. - let urls = query_hive_urls(socket) - .await - .context("could not read this hive's URLs from the daemon")? - .context("the daemon reported no URLs — `services.hyperhive.domain` is unset")?; - let (url, hint) = match target { - OpenTarget::Home => ( - urls.home, - "the dashboard URL needs `services.hyperhive.swarm.domain` set and this hive in `swarm.hives`", - ), - OpenTarget::Forge => ( - urls.forge, - "the public forge URL needs `services.hyperhive.swarm.forge.publicUrl` to be set", - ), - OpenTarget::Matrix => ( - urls.matrix, - "the matrix GUI URL needs `services.hyperhive.swarm.matrix.gatewayHost` set", - ), - }; - let url = url.with_context(|| format!("no URL available for this surface — {hint}"))?; - println!("{url}"); - // Best-effort: many hosts are headless, so a missing opener or a - // non-zero exit is fine — the URL is already printed. - match std::process::Command::new("xdg-open").arg(&url).status() { - Ok(status) if status.success() => {} - Ok(status) => eprintln!("note: xdg-open exited with {status} (URL printed above)"), - Err(e) => eprintln!("note: could not run xdg-open ({e}) (URL printed above)"), - } - Ok(()) -} diff --git a/nix/host-modules/hive-c0re/environment.nix b/nix/host-modules/hive-c0re/environment.nix index 09467268..2e80ac6e 100644 --- a/nix/host-modules/hive-c0re/environment.nix +++ b/nix/host-modules/hive-c0re/environment.nix @@ -73,7 +73,7 @@ in } // lib.optionalAttrs (config.services.hyperhive.deploy.hive-controller.dashboardDomain != null) { # The host the dashboard and the agent UIs answer on, for the URLs c0re - # hands out (`hivectl open home`, each agent's UI link). + # hands out (each agent's UI link). HYPERHIVE_DASHBOARD_DOMAIN = config.services.hyperhive.deploy.hive-controller.dashboardDomain; } // lib.optionalAttrs (config.services.hyperhive.deploy.hive-controller.hiveName != null) { @@ -195,7 +195,7 @@ in // lib.optionalAttrs (config.services.hyperhive.swarm.matrix.gatewayHost != null) { # Browser-facing matrix GUI (fluffychat) URL — the gateway # vhost (`gatewayHost`, `chat.` by default). Surfaced via the daemon's `Urls` - # request for `hivectl open matrix`. Absent when no gatewayHost is + # request. Absent when no gatewayHost is # set (no browser-reachable matrix vhost). HIVE_MATRIX_PUBLIC_URL = "https://${config.services.hyperhive.swarm.matrix.gatewayHost}/"; }