- Rust 64.7%
- JavaScript 16.4%
- HTML 10.4%
- Shell 6.3%
- CSS 2.2%
Replace inline HERO_SOCKET_DIR/HOME fallback logic in server, admin, and CLI with herolib_core::base::resolve_socket_dir / resolve_socket_path. Remove duplicated BUILD_NR const blocks from server and admin; add startup banner to hero_codescalers CLI. Bump hero_proc_sdk and herolib_core lock entries to latest development commits. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> |
||
|---|---|---|
| crates | ||
| docs | ||
| scripts | ||
| .gitignore | ||
| Cargo.lock | ||
| Cargo.toml | ||
| Cargo.toml.hero_builder_backup | ||
| CLAUDE.md | ||
| PURPOSE.md | ||
| README.md | ||
hero_codescalers
Multi-user development session management for Linux servers, built on the Hero OS stack.
Overview
hero_codescalers manages Linux user accounts and SSH sessions across a fleet of nodes.
State (nodes, admins, groups) is stored in a local sled embedded database.
The dashboard UI is reachable over the mycelium overlay network.
Components
| Binary | Role |
|---|---|
hero_codescalers_server |
JSON-RPC 2.0 backend (Unix socket rpc.sock) |
hero_codescalers_admin |
Web dashboard (Unix socket admin.sock + optional HTTP) |
hero_codescalers |
CLI — lifecycle management and direct API calls |
Prerequisites — hero group bootstrap
The driver account (whoever runs hero_codescalers_server) needs to traverse each managed
user's ~/hero/var/sockets/ to reach their per-user hero_proc daemon. This requires
membership in a shared hero Unix group. Run once, as root:
sudo bash scripts/setup-driver-group.sh # creates the `hero` group, adds $SUDO_USER
# then log out and back in
The dashboard surfaces a yellow banner if this step is missing or incomplete; the banner
clears automatically once the driver process is in hero and you re-log in.
For users created before this requirement existed, retrofit them with the user.adopt
RPC. Note that user.adopt requires a root-actor daemon — see the Lifecycle section below.
New users created via user.create self-heal as part of the create job.
Quick start
# One-time: build and install binaries
lab service codescalers --install
# One-time: set the shared KVS secret (any passphrase)
proc secret set SECRET_CODESCALERS "my shared passphrase"
# Start the service (instance 0, port 5000, mycelium auto-detected)
lab service codescalers --start
# Check status
lab service codescalers --status
# Start as root (for user.create / user.delete / user.adopt)
sudo lab service codescalers --install
sudo lab service codescalers --start
Multi-instance support
Multiple instances can run side-by-side on the same machine — useful for staging/testing, or when you need isolated namespaces with different KVS secrets.
Port assignment
Ports are assigned automatically — no manual configuration needed:
| Instance | HTTP port | Override |
|---|---|---|
| 0 | 5000 | hero_codescalers --port 9090 --start |
| 1 | 5001 | hero_codescalers --instance 1 --port 9091 --start |
| N | 5000+N | --port <explicit> |
Unix socket directories
Each instance gets its own socket directory under $HERO_SOCKET_DIR
(default: ~/hero/var/sockets/):
| Instance | Socket directory | Paths inside |
|---|---|---|
| 0 | hero_codescalers/ |
rpc.sock, admin.sock |
| 1 | hero_codescalers_1/ |
rpc.sock, admin.sock |
| N | hero_codescalers_N/ |
rpc.sock, admin.sock |
hero_proc names
| Instance | Service name | Server action | UI action |
|---|---|---|---|
| 0 | hero_codescalers |
hero_codescalers_server |
hero_codescalers_admin |
| 1 | hero_codescalers_1 |
hero_codescalers_server_1 |
hero_codescalers_admin_1 |
| N | hero_codescalers_N |
hero_codescalers_server_N |
hero_codescalers_admin_N |
Example: two instances side-by-side
# Instance 0 — primary (port 5000)
hero_codescalers --start
# Instance 1 — secondary (port 5001)
hero_codescalers --instance 1 --start
# Status
proc service status hero_codescalers
proc service status hero_codescalers_1
# Stop secondary
hero_codescalers --instance 1 --stop
Mycelium network integration
All instances attach to the mycelium overlay network automatically when the mycelium daemon is reachable. The UI HTTP listener binds to the node's mycelium IPv6 address so the dashboard is accessible from any node on the overlay — not just localhost.
- Detection is attempted for every instance, regardless of
--root. - The mycelium address is in the
400::/7range; the script validates this. - If the daemon is unreachable, the service starts in Unix-socket-only mode
(no HTTP listener). Pass
--address <ipv6>to override.
# Auto-detect mycelium (recommended)
hero_codescalers --start
# Explicit address override
hero_codescalers --address 4f8:306f:d514:7dbd:: --start
# Explicit address + custom port
hero_codescalers --address 4f8:306f:d514:7dbd:: --port 5099 --start
UI Access Control
The admin dashboard HTTP listener can be restricted to a whitelist of Mycelium
IPv6 addresses. The whitelist is stored in hero_proc secrets under the key
ADMIN_SECRETS (context core) as a comma-separated list.
Unix-socket connections are always trusted — hero_router and local tooling are never blocked. Only direct TCP connections (from the Mycelium overlay) are subject to the whitelist.
If hero_proc is not running the whitelist feature is disabled and all TCP connections are allowed.
Managing the whitelist
Via the admin UI (recommended)
Open the dashboard → Admin tab → UI Access Control section.
Via the CLI
# Add an address
proc secret set ADMIN_SECRETS "4f8:306f:d514:7dbd:b27c:28aa:d12d:bdb6"
# Add multiple addresses (comma-separated, no spaces around commas)
proc secret set ADMIN_SECRETS "4f8:306f:d514:7dbd:b27c:28aa:d12d:bdb6,4f9:1234:abcd::1"
# View current whitelist
proc secret get ADMIN_SECRETS
# Disable enforcement (clear the list)
proc secret set ADMIN_SECRETS ""
CLI direct calls
The hero_codescalers binary proxies commands directly to the server:
hero_codescalers health
hero_codescalers stats
hero_codescalers user-list
hero_codescalers user-create alice --forge-token TOKEN
hero_codescalers user-delete alice
hero_codescalers session-list
hero_codescalers session-kill alice
# Query a non-default instance
hero_codescalers --instance 1 health
hero_codescalers --instance 1 user-list
# Or point at a specific socket
hero_codescalers --server ~/hero/var/sockets/hero_codescalers_1/rpc.sock health
Lifecycle via the CLI
hero_codescalers --start # instance 0, port 5000
hero_codescalers --instance 1 --start # instance 1, port 5001
hero_codescalers --instance 1 --stop
Building and installing
lab service codescalers --install # build + install all binaries to ~/hero/bin
lab service codescalers --start # register with hero_proc and start
lab service codescalers --stop # stop all binaries
lab service codescalers --status # show status
# For root/driver instances (user.create / user.adopt require root actor)
sudo lab service codescalers --install
sudo lab service codescalers --start
Developer checks (no install needed):
cargo check --workspace # fast type-check
cargo fmt --all # format
cargo clippy --workspace --all-targets # lint
cargo test --workspace --lib # unit tests
Smoke testing
SOCK=~/hero/var/sockets/hero_codescalers/rpc.sock
# Health
curl -s --unix-socket $SOCK http://localhost/health | jq .
# OpenRPC doc
curl -s --unix-socket $SOCK http://localhost/openrpc.json | jq '.methods[].name'
# JSON-RPC health call
curl -s --unix-socket $SOCK -X POST http://localhost/rpc \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"health","params":{}}'
Environment variables
| Variable | Default | Description |
|---|---|---|
HERO_SOCKET_DIR |
~/hero/var/sockets |
Base directory for Unix sockets |
HERO_CODESCALERS_SOCK_NAME |
hero_codescalers |
Socket subdirectory name |
HERO_CODESCALERS_DATA_DIR |
~/hero/var/hero_codescalers/db |
sled database directory |
HERO_CODESCALERS_ADDRESS |
— | UI HTTP bind address (IPv4 or IPv6) |
HERO_CODESCALERS_PORT |
9911 |
UI HTTP port |