- Rust 67.6%
- Nix 15.4%
- JavaScript 8.3%
- CSS 3.7%
- TypeScript 3.4%
- Other 1.6%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| .forgejo/workflows | ||
| branding | ||
| docs | ||
| frontend | ||
| hive-ag3nt | ||
| hive-c0re | ||
| hive-forge | ||
| hive-matrix-mcp | ||
| hive-priv | ||
| hive-sh4re | ||
| nix | ||
| scripts | ||
| .gitignore | ||
| Cargo.lock | ||
| Cargo.toml | ||
| CLAUDE.md | ||
| flake.lock | ||
| flake.nix | ||
| README.md | ||
| TODO.md | ||
hyperhive
a swarm of claude-code agents, each in its own nspawn cage, gossiping over unix sockets. config changes flow as git commits, the operator approves them in a browser, every deploy is a tag. cyberpunk-themed dashboard included. 💜⚡
Claude code is great in one window, exponentielle across many — but only if you can keep the agents from stepping on each other, give them durable identity, and stop them from eating production. hyperhive is the substrate.
- identity = unix socket
- communication = sqlite-backed broker (
send/recv/ask/answer/remind) - config = git (manager proposes, operator approves, deploys land as tagged commits)
- blast radius = container
host (NixOS, runs hive-c0re.service)
│
├── operator
│ ├── browser → :7000 hive-c0re dashboard
│ ├── browser → :8100-8999 per-agent web UIs (all agents, FNV-1a hash)
│ └── CLI → /run/hyperhive/host.sock admin protocol
│
├── hive-c0re (Rust daemon: lifecycle / broker / approvals /
│ auto-update / dashboard / sockets)
│
└── nixos-containers
├── hm1nd manager agent (privileged MCP surface)
└── h-<name> sub-agent (vanilla MCP surface + per-agent extras)
Depth lives in docs/ — pick the one matching your task:
| reading path | doc |
|---|---|
| dashboard layout + endpoints | docs/web-ui.md (shape · dashboard · agent) |
| claude turn loop + MCP tools | docs/turn-loop.md |
| config-edit + approval state machine | docs/approvals.md |
| what survives destroy / purge / restart | docs/persistence.md |
| naming, wire protocol, commit style | docs/conventions.md |
| nginx vhost map + sub-domain routing | docs/gateway.md |
| NixOS / nspawn gotchas | docs/gotchas.md |
Host config
Minimal flake.nix for a host that runs hive-c0re:
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-26.05";
hyperhive.url = "git+https://forge.darkest.space/hyperhive/hyperhive";
};
outputs = { nixpkgs, hyperhive, ... }: {
nixosConfigurations.my-host = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [
hyperhive.nixosModules.default # hive-c0re + hive-forge + hive-gateway in one import
({ ... }: {
services.hyperhive.enable = true;
# services.hyperhive.c0re.operatorPronouns = "they/them"; # default: "she/her"
# ... rest of your host config
system.stateVersion = "25.11";
})
];
};
};
}
hive-c0re opens its admin socket + dashboard, auto-creates the
manager container, and auto-rebuilds any container whose hyperhive
rev goes stale. claude-code is unfree — hyperhive scopes the
whitelist to itself, nothing for the operator to set.
Optional: set services.hyperhive.gateway.enable = false; to bypass
the default nginx in front. By default (gateway.enable = true) every
request hits a small nginx in its own nixos-container that proxies
to hive-c0re's dashboard on the upstream port; /matrix/ is served
directly from services.hyperhive.matrix.gui.package when the matrix
GUI is on. v0 is HTTP-only (TLS lives in a follow-up); pair with
services.hyperhive.gateway.localHostsEntry = true; for local dev so
http://<services.hyperhive.domain> resolves to the host without
setting up real DNS.
Optional: set services.hyperhive.c0re.preBuildAgentTemplates = true;
to pre-fetch the per-container system closures into your host's
/nix/store as part of nixos-rebuild. First-agent-spawn then
completes in seconds instead of minutes (no nixpkgs/claude-code
fetch on the critical path), at the cost of a few GB extra in your
system closure. Off by default (the toplevels are pinned to
x86_64-linux, so non-x86 hosts would otherwise force a cross-build).
Alternatively warm the store manually:
nix build git+https://forge.darkest.space/hyperhive/hyperhive#agent-base-toplevel.
Optional: set services.hyperhive.domain = "example.com"; to define the
canonical hostname for hyperhive subsystems that need a stable public
name. No default — subsystems that require it (currently:
services.hyperhive.matrix) assert non-null at eval time with a clear
error message if it is missing.
Optional: set services.hyperhive.hiveName = "pr1ma"; and / or
services.hyperhive.swarmName = "constellat1on"; to give the hive and
the wider swarm human-readable display labels. Distinct from
services.hyperhive.domain (the DNS address): the names surface in
the dashboard chrome and the per-agent system prompt; the domain is
how things are addressed on the wire. Federated hives at different
domains can share a swarm name. Both default to null — chrome falls
back to the domain, the prompt simply doesn't mention them.
Optional: set services.hyperhive.matrix.enable = true; to spin up a
private matrix-tuwunel
homeserver in a nixos-container. Requires either
services.hyperhive.domain or services.hyperhive.matrix.serverName
to be set (eval fails with a clear error if both are absent). The
server_name (embedded irrevocably in every user and room ID)
defaults to <domain> (bare hive domain); the hive-gateway serves
.well-known/matrix/{client,server} endpoints so clients auto-discover the
homeserver without a subdomain. Existing homeservers must set
services.hyperhive.matrix.serverName = "matrix.<domain>"; explicitly to
preserve their existing user/room IDs (the server_name is embedded
into every ID). Override with
services.hyperhive.matrix.serverName = "chat.example.com"; for a custom
server name. State
lives at /var/lib/nixos-containers/hive-matrix/. Federation is
enabled with an empty trusted_servers list; e2ee is deferred to
a follow-up.
The hive-gateway nginx container serves a
fluffychat-web matrix client at /matrix/
when services.hyperhive.matrix.gui.enable is on. This defaults to
services.hyperhive.matrix.enable, so enabling the homeserver enables
the web client by default; set gui.enable = false explicitly to keep
the homeserver without the GUI. The ◆ M4TR1X ◆ → tab appears in
the dashboard chrome when enabled. The web client can
connect to any Matrix homeserver; enter the URL at first visit (e.g.
the local tuwunel instance if services.hyperhive.matrix.enable = true, or
any external homeserver).
Agent configuration
Per-agent settings live in each agent's agent.nix and are synced to
the container as environment variables. Common options:
-
hyperhive.model— Claude model for this agent (default:"haiku"). SetsHIVE_DEFAULT_MODELin the container; the harness applies it at boot and it takes priority over any persisted runtime override. The operator can still switch the model at runtime via the per-agent web UI, but that choice is reset by any rebuild that changes this option. -
hyperhive.allowedRecipients— List of agent names this agent can message (viasend). If unset, all agents are allowed. Useful to restrict an agent to talking only to the manager. -
hyperhive.forge.url— Base URL of the hyperhive-managed Forgejo (default:"http://localhost:3000"). Used to configure the agent's tea login at boot; no-op if/state/forge-tokenis missing. -
hyperhive.forge.keepSubscriptions— Boolean. Iftrue, the agent's forge repo subscriptions are never auto-cleaned during rebuild; useful for agents that want to watch specific repos. Rendered asHIVE_FORGE_KEEP_SUBSCRIPTIONS. -
hyperhive.forge.skipNotifyReasons— List of forge notificationreasonvalues to suppress (e.g.[ "subscribed" "participating" ]). Notifications matching these reasons are silently dropped; all others including direct mentions and reviews are delivered. Empty list (default) delivers all notifications. Rendered asHIVE_FORGE_NOTIFY_SKIP_REASONS(comma-separated). -
hyperhive.frontend.dist— Override the default frontend package (pkgs.hyperhive-frontend, built bynix/frontend.nix). Set to a custom derivation to ship a fully custom per-agent SPA. The JSON contract (/api/state,/events/stream, action endpoints) is the source of truth for any replacement. -
hyperhive.frontend.extraFiles— Attrset of extra files/directories to layer on top of the default agent dist. Each entry has asource(nix path) and an optionaltarget(URL prefix in the static tree, defaults to the attribute name). Example:{ bitburner.source = ./bitburner-dist; }serves that dist at/bitburner/. Pure additions only — overwriting an existing default file is a hard eval-time error; usefrontend.distto replace the whole dist. Paths with leading/or..segments are rejected at eval time. -
hyperhive.matrix.enable— Boolean (defaulttrue). When true, each agent container runshive-matrix-daemon(a long-running matrix-sdk process that holds the per-agent client + sync) and auto-injectshive-matrix-mcpas a stdio MCP server so claude can call the matrix tools (mcp__matrix__send_message,send_dm,send_reaction,send_reply,mark_read,list_rooms,list_room_members,read_room;roomargs accept both!id:serverand#alias:serverforms). Silently no-ops when<state>/matrix-tokenis absent (i.e., the host-levelhyperhive.matrixtuwunel container hasn't provisioned the account yet). Set tofalseto opt a specific agent out of matrix. -
hyperhive.user.name— Unix username the agent runs as inside the container (default: the agent's own label, injected by the meta-flake). Agents no longer run as root. Stand-alone module eval without the meta-flake falls back to"agent". -
hyperhive.user.passwordlessSudo— Boolean (defaulttrue). Grants the agent userNOPASSWD: ALLsudo so claude'sBashtool can still escalate when needed — same surface as the old root-user shape, just explicit. Setfalsefor strictly unprivileged agents.
See nix/templates/harness-base.nix for the full list of options and
their descriptions.
Operator CLI
hivectl is the operator-facing host CLI for ad-hoc administration that
doesn't go through the broker (built alongside hive-c0re when the host
module is enabled):
sudo hivectl forge create-user mara # provisions a forge user
sudo hivectl forge create-user mara --password 'hunter2' # … with a fixed password
sudo hivectl matrix create-user mara # provisions a matrix user
sudo hivectl matrix create-user mara --password-stdin # … reading one line from stdin
For agent names (i.e., a Coordinator::agent_state_root(name) exists),
hivectl persists the resulting token to the agent's state dir like the
boot sweep does. For non-agent names (e.g. the operator's own forge/matrix
account), it prints the token to stdout and writes nothing.
Build / deploy
nix develop -c cargo check
nix flake check # rust + nix + toml fmt + clippy
# deploy from a host config that imports hyperhive.nixosModules.hive-c0re
nix flake update --update-input hyperhive
sudo nixos-rebuild switch --flake .#<host>