# Agent config knobs Optional per-agent knobs the meta flake wires into the container from `services.hyperhive.agents.`, read at boot or per turn by the harness. Absent means the default. (The claude spawn + compaction themselves live in [claude-invocation](claude-invocation.md).) ## Reference docs (`hyperhive.docs.enable`) ```nix hyperhive.docs.enable = true; # default: false (true for the manager agent) ``` Makes the hyperhive `docs/` tree available inside the container at a nix store path read from `$HIVE_DOCS_DIR`, and injects a single pointer sentence into the agent's system prompt so it knows the docs exist and where to find them. The tree is served by `claude --add-dir` so the full markdown is readable during every turn. Enabled by default only for the root/manager agent (`nix/templates/ruth.nix`). Any agent can opt in by adding the line above to its `agent.nix`. The `docs/` source is a narrow flake input (`hyperhive-docs`) tracked separately from the main `hyperhive` flake so editing docs re-locks only that input — not every agent's container gets rebuilt on a doc-only change. ## Agent icon ```nix hyperhive.icon = ./icon.svg; # default: null (falls back to shared hyperhive logo) ``` Path to an SVG file used as this agent's visual identity — shown in the per-agent page header, as the page favicon, and uploaded to the agent's Forgejo profile avatar (via the `forge-avatar-sync` boot unit) and Matrix profile avatar (set by `hive-matrix-daemon` over its live Client). Commit the SVG next to `agent.nix` in the config repo and reference it as a relative path. When `null` (the default), the agent falls back to the shared hyperhive branding mark. The harness serves whichever icon is active at `GET /icon` on the per-agent web port. ## `user.passwordlessSudo` ```nix hyperhive.user.passwordlessSudo = true; # default ``` Grants the per-agent unix user passwordless `sudo` (`NOPASSWD: ALL`). Enabled by default so claude's shell tools work for operations that need root inside the container (`systemctl`, package managers in dev shells, etc.) — the agent user gets root explicitly via `sudo` rather than running as root itself. Set to `false` for agents that should be strictly unprivileged. Any tool invocation that needs root then fails loudly with the standard sudo rejection rather than silently succeeding — easier to audit. `hyperhive.user.uid`, `hyperhive.user.gid`, and `hyperhive.user.name` are the companion options; see `docs/agent-hierarchy.md` — "Harness systemd unit shape" for the full `user.*` surface. ## Dashboard links ```nix hyperhive.dashboardLinks = [ { label = "Stats"; icon = "📊"; url = "http://localhost:9001/stats"; } { label = "Scratchpad"; url = "http://localhost:8080"; } ]; ``` Declares extra navigation links that appear in the per-agent page header alongside the built-in forge / config / container links. Each entry has: | Field | Required | Description | |-------|----------|-------------| | `label` | yes | Display text shown in the icon strip tooltip and meta-nav. | | `url` | yes | Absolute URL — may include a different port (the dashboard renders it as a plain anchor). | | `icon` | no | Emoji or short glyph prefix. Defaults to empty string. | The list is written to `/hyperhive-dashboard-links.json` by a one-shot systemd unit at container boot. The harness's own web UI (`agent_links` in `hive-agent/src/web_ui/state.rs`) reads the file on each `/api/state` snapshot and appends the entries to the per-agent nav as `kind = External` links — no `hive-c0re` / operator-dashboard involvement, and no code change needed to pick up a new entry. Omitting the option (default empty) produces no extra links. ## Custom static files ```nix hyperhive.frontend.extraFiles = { "games/bitburner" = { source = ./bitburner-dist; # path relative to agent.nix # target defaults to attribute name: "games/bitburner" }; "my-page" = { source = ./my-page.html; target = "my-page.html"; # explicit override }; }; ``` Layers additional files over the default per-agent web UI dist. Each attribute defines one overlay entry: - **`source`** — a Nix path (file or directory) copied into the merged static tree. Evaluated at nix build time; the resulting derivation is pointed at by `HIVE_STATIC_DIR`. - **`target`** — destination path within the merged tree, used as both the served URL prefix (`//…`) and the on-disk layout. Defaults to the attribute name. Forward slashes create nested layouts (`"games/bitburner"` serves at `/games/bitburner/…`). Constraints: `target` must start with an alphanumeric or `_` and contain only alphanumerics, `_`, `.`, `/`, `-`. `..` segments are rejected by a config assertion. The merge step refuses to overwrite files already present in the default dist — pick a target name that does not collide with existing paths (`static/`, `index.html`, etc.). The default dist ships at `hyperhive.frontend.dist` (the `hyperhive-frontend` package output, read-only). To replace the entire UI rather than layer on top, override `frontend.dist` directly. ## Connectivity overrides Two `hyperhive.forge.*` / `hyperhive.matrix.*` options override where the per-agent daemons connect. Both rarely need changing on a standard single-host deploy, but are useful for multi-hive or custom-network setups. ```nix hyperhive.forge.url = "http://forge.example:3000"; # default: null hyperhive.matrix.url = "https://matrix.example"; # default: null ``` **`hyperhive.forge.url`** — base URL of the Forgejo instance. Used by a one-shot boot unit (`tea-login`) that writes `~/.config/tea/config.yml` directly from the agent's `forge-token`, so `tea` and `hive-forge` work without an interactive auth step. The unit is a no-op when `forge-token` is absent. Override when the agent should connect to a Forgejo on a different host or port (e.g. a swarm peer's forge). Validated: must be an `http://` or `https://` URL, or `null`. **Defaults to `null`, meaning "no forge" — not a guessed address.** A loopback default would only ever be correct when the forge shares the agent's network namespace, and inside a container `localhost` is the agent itself, so the default was a value that built fine and then talked to the wrong machine. With `null` the `tea-login` and `forge-avatar-sync` units are not generated at all: an absent integration rather than a misdirected one. You do not normally set this — hive-c0re renders the host's real forge URL into every agent, and refuses to write a meta flake without one, so `null` only survives where the agent modules are evaluated outside a hive. **`hyperhive.matrix.url`** — homeserver URL used by `hive-matrix-daemon` when connecting via the matrix-sdk. hive-c0re writes it into every agent at deploy time as the gateway-routed `chat.` URL, so isolated agents can reach the homeserver. Override per-agent when an agent should talk to a different homeserver — for example a remote hive's tuwunel reached over a VPN, or an external Matrix server for a federation-only agent. **Defaults to `null`, meaning "no matrix" — same reasoning as `forge.url` above** (a loopback default would resolve inside the agent's own netns to the agent itself, not the homeserver). With `null` the daemon has no homeserver and no-ops exactly as it does without a token. The hive only forwards `HIVE_MATRIX_URL` when it actually has a matrix vhost to name, so `null` survives where a hive runs no homeserver, or where the agent modules are evaluated outside a hive. ## Claude Code plugins The harness installs Claude Code plugins before the serve loop opens. Three per-agent `agent.nix` options control this: ```nix hyperhive.claudeMarketplaces = [ # default "anthropics/claude-plugins-official" "${hyperhive.packages.claude-plugins}" # hive's own local marketplace, registered as `hyperhive` ]; hyperhive.claudePlugins = [ # default "skill-creator@claude-plugins-official" "base@hyperhive" ]; hyperhive.claudePluginsAutoUpdate = false; # default ``` - **`claudeMarketplaces`** — list of marketplace sources passed to `claude plugin marketplace add `. Defaults to Anthropic's official marketplace plus hyperhive's own `claude-plugins` nix package (see `nix/packages/claude-plugins.nix`) — a local-path marketplace registered under the name `hyperhive`, so a hive-authored skill needs no forge repo or git remote to ship. Override or extend to add custom marketplaces. Idempotent — re-adding an existing source is a no-op. - **`claudePlugins`** — list of plugin specs passed to `claude plugin install `. Each spec is installed on every boot (`install` is expected to be idempotent); failures log a warning but do not abort boot. Defaults to Anthropic's `skill-creator` (so every agent can author, refine, and evaluate its own skills) plus hyperhive's own `base` plugin — skills that apply to every agent regardless of role (currently just `state-hygiene`) — all without any per-agent wiring. > Both plugin lists follow ordinary NixOS list-option semantics: a > per-agent definition **replaces** the default, it does not extend it. > An agent that sets `claudePlugins` and still wants the defaults has > to list `skill-creator@claude-plugins-official` and `base@hyperhive` > explicitly alongside its own entries — likewise for the two default > entries in `claudeMarketplaces`. - **`claudePluginsAutoUpdate`** — when `true`, runs `claude plugin marketplace update` before installing plugins to pull the latest index. Disabled by default to keep boot times short and plugin versions pinned. ## `cargo.shortMessages` ```nix hyperhive.cargo.shortMessages = true; # default ``` When enabled (the default), the harness injects a `cargo` shell function into `/etc/hyperhive/bash-env.sh` that transparently appends `--message-format short` to compile subcommands (`build`, `check`, `clippy`, `test`, `run`, `doc`, `bench`, `install`, `rustc`, `fix`). This suppresses the per-crate progress lines that flood the response window, leaving only warnings and errors. The function handles `+toolchain` selectors (`cargo +nightly build`) and passes through cleanly when `--message-format` is already present. Non-compile subcommands (`new`, `add`, third-party `cargo-*`) are left untouched. Set to `false` for agents that parse cargo's JSON output programmatically and do not pass `--message-format json` themselves.