Watch
0
0
Fork
You've already forked hyperhive
0

hivectl: the open verb is gone and the docs say what hivectl has

This commit is contained in:
damocles 2026-11-06 23:37:12 +01:00 • committed by mara
commit 06b303aff2
9 changed files with 7 additions and 139 deletions

View file

@ -36,7 +36,6 @@ This document contains the help content for the `hivectl` command-line program.
* [`hivectl stop`↴](#hivectl-stop) * [`hivectl stop`↴](#hivectl-stop)
* [`hivectl start`↴](#hivectl-start) * [`hivectl start`↴](#hivectl-start)
* [`hivectl restart`↴](#hivectl-restart) * [`hivectl restart`↴](#hivectl-restart)
* [`hivectl open`↴](#hivectl-open)
* [`hivectl completions`↴](#hivectl-completions) * [`hivectl completions`↴](#hivectl-completions)
## `hivectl` ## `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 * `stop` — Stop containers hive-wide in one operator action
* `start` — Start containers hive-wide — the inverse of `hivectl stop` * `start` — Start containers hive-wide — the inverse of `hivectl stop`
* `restart` — Restart containers hive-wide — `stop` then `start` over one scope * `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 * `completions` — Generate a shell completion script for `hivectl` and print it to stdout
###### **Options:** ###### **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:**
* `<TARGET>` — Which surface to open. Defaults to the operator dashboard
Default value: `home`
Possible values:
- `home`:
The operator dashboard (`https://<hive>.hives.<swarm domain>/`)
- `forge`:
The forge (Forgejo) web UI
- `matrix`:
The matrix GUI (fluffychat)
## `hivectl completions` ## `hivectl completions`
Generate a shell completion script for `hivectl` and print it to stdout. Generate a shell completion script for `hivectl` and print it to stdout.

View file

@ -21,13 +21,6 @@ markdown-docs` subcommand and kept in lockstep with the code by the
Regenerate with `nix build .#default && ./result/bin/hivectl Regenerate with `nix build .#default && ./result/bin/hivectl
markdown-docs > docs/2-handbook/reference/hivectl-cli.md`. 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 <name>` makes it
a site admin. swarm-controller makes an agent's, and `swarmctl agent
mint-forge-token <agent>` checks and, if needed, re-mints its token.
## Agents ## Agents
Container lifecycle shortcuts that go through the host admin socket. 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 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`) 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`. — 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://<hive>.hives.<swarm domain>/)
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.<domain>`. 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.

View file

@ -200,8 +200,7 @@ async fn dispatch(req: &HostRequest, coord: Arc<Coordinator>) -> HostResponse {
// The hive domain + per-surface public URLs are injected into // The hive domain + per-surface public URLs are injected into
// c0re's service env by the hyperhive module; surface them so the // c0re's service env by the hyperhive module; surface them so the
// operator CLI can fill in this hive's own identity (the // operator CLI can fill in this hive's own identity (the
// federation peer-config block) and open the web surfaces // federation peer-config block).
// (`hivectl open`).
HostRequest::Urls => HostResponse::urls(hive_urls()), HostRequest::Urls => HostResponse::urls(hive_urls()),
HostRequest::QuotaEnable => handle_quota_enable().await?, HostRequest::QuotaEnable => handle_quota_enable().await?,
HostRequest::QuotaLimit { name, limit } => { HostRequest::QuotaLimit { name, limit } => {

View file

@ -178,8 +178,8 @@ pub enum HostRequest {
/// forge / matrix URLs, daemon-sourced so custom forge/matrix /// forge / matrix URLs, daemon-sourced so custom forge/matrix
/// domains resolve correctly. Each URL is `None` when its subsystem /// domains resolve correctly. Each URL is `None` when its subsystem
/// is unreachable from a browser (e.g. forge `publicUrl` null, /// is unreachable from a browser (e.g. forge `publicUrl` null,
/// matrix `gatewayHost` null). Backs `hivectl open` + the federation /// matrix `gatewayHost` null). Backs the federation peer-config block
/// peer-config block (which reads the bare `domain`). /// (which reads the bare `domain`).
Urls, Urls,
/// Fetch one or more job-queue nodes plus their live subtrees, as /// Fetch one or more job-queue nodes plus their live subtrees, as
/// generic `hive-jobq-wire` nodes — `hivectl`'s wait/progress loop, /// generic `hive-jobq-wire` nodes — `hivectl`'s wait/progress loop,

View file

@ -25,11 +25,9 @@ dispatch:
- **`power.rs`** — restart/start/stop at the container level. - **`power.rs`** — restart/start/stop at the container level.
- **`choom.rs`** — drop into an interactive claude session in a - **`choom.rs`** — drop into an interactive claude session in a
container. container.
- **`forge.rs`** — reconciles an agent's config against its forge
repo.
- **`wg.rs`** — WireGuard mesh helpers. - **`wg.rs`** — WireGuard mesh helpers.
- **`subvol.rs`** — btrfs state-subvolume ops. - **`subvol.rs`** — btrfs state-subvolume ops.
- **`quota.rs`**, **`util.rs`**, **`completions.rs`**, **`open.rs`** — - **`quota.rs`**, **`util.rs`**, **`completions.rs`** — shared helpers
shared helpers, shell completions, browser-open. and shell completions.
Full verb reference: `docs/2-handbook/tools/hivectl.md`. Full verb reference: `docs/2-handbook/tools/hivectl.md`.

View file

@ -126,15 +126,6 @@ pub enum Cmd {
#[arg(long)] #[arg(long)]
graceful: bool, 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. /// Emit the full CLI reference as `CommonMark` to stdout.
/// ///
/// Hidden tooling command used by the docs build to keep the published /// 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://<hive>.hives.<swarm domain>/`).
Home,
/// The forge (Forgejo) web UI.
Forge,
/// The matrix GUI (fluffychat).
Matrix,
}
/// Shared scope flags for `hivectl stop` / `start` / `restart`. With no /// Shared scope flags for `hivectl stop` / `start` / `restart`. With no
/// flag set the verb targets **everything** (all sub-agents + the /// flag set the verb targets **everything** (all sub-agents + the
/// gateway). Setting any flag restricts to the selected classes, /// gateway). Setting any flag restricts to the selected classes,

View file

@ -31,8 +31,6 @@ mod completions;
mod quota; mod quota;
mod util; mod util;
use completions::generate_completions; use completions::generate_completions;
mod open;
use open::open_url;
mod wg; mod wg;
use wg::{peer_config, require_hive_domain, wg_init, wg_peer, wg_status}; use wg::{peer_config, require_hive_domain, wg_init, wg_peer, wg_status};
mod agents; mod agents;
@ -93,7 +91,6 @@ async fn main() -> Result<()> {
print!("{}", clap_markdown::help_markdown_custom::<Cli>(&options)); print!("{}", clap_markdown::help_markdown_custom::<Cli>(&options));
Ok(()) Ok(())
} }
Cmd::Open { target } => open_url(&socket, target).await,
Cmd::Completions { shell } => { Cmd::Completions { shell } => {
generate_completions(shell); generate_completions(shell);
Ok(()) Ok(())

View file

@ -1,46 +0,0 @@
//! `hivectl open <home|forge|matrix>` — 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 <home|forge|matrix>` — 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(())
}

View file

@ -73,7 +73,7 @@ in
} }
// lib.optionalAttrs (config.services.hyperhive.deploy.hive-controller.dashboardDomain != null) { // lib.optionalAttrs (config.services.hyperhive.deploy.hive-controller.dashboardDomain != null) {
# The host the dashboard and the agent UIs answer on, for the URLs c0re # 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; HYPERHIVE_DASHBOARD_DOMAIN = config.services.hyperhive.deploy.hive-controller.dashboardDomain;
} }
// lib.optionalAttrs (config.services.hyperhive.deploy.hive-controller.hiveName != null) { // lib.optionalAttrs (config.services.hyperhive.deploy.hive-controller.hiveName != null) {
@ -195,7 +195,7 @@ in
// lib.optionalAttrs (config.services.hyperhive.swarm.matrix.gatewayHost != null) { // lib.optionalAttrs (config.services.hyperhive.swarm.matrix.gatewayHost != null) {
# Browser-facing matrix GUI (fluffychat) URL — the gateway # Browser-facing matrix GUI (fluffychat) URL — the gateway
# vhost (`gatewayHost`, `chat.<swarm-domain>` by default). Surfaced via the daemon's `Urls` # vhost (`gatewayHost`, `chat.<swarm-domain>` 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). # set (no browser-reachable matrix vhost).
HIVE_MATRIX_PUBLIC_URL = "https://${config.services.hyperhive.swarm.matrix.gatewayHost}/"; HIVE_MATRIX_PUBLIC_URL = "https://${config.services.hyperhive.swarm.matrix.gatewayHost}/";
} }