Hero - the sovereign everything app
  • Rust 55.1%
  • Shell 27.5%
  • JavaScript 9.1%
  • Makefile 3.6%
  • HTML 3.1%
  • Other 1.6%
Find a file
mik-tf 996ebb0084
Some checks failed
Build and Test / build (push) Failing after 1m14s
fix: fail loudly when seed data or service configs fail to copy in build-local.sh
Removed silent `|| true` on critical copy steps (seed data, service TOMLs).
Added file count validation after copy — build now fails if seed data or
service configs are empty. Added dist validation step checking for required
binaries and data before declaring success.

Previously, copy failures were silently swallowed, producing images without
service configs (hero_services_server can't find profiles) or seed data
(no admin user, no context data).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 13:39:14 -04:00
.forgejo/workflows fix: update CI zinit clone branch from development_check to development 2026-02-24 02:46:09 +01:00
crates lhumina_code/home#19 — Zinit SDK 0.4 migration, binary naming standardization, foundry rename 2026-03-11 14:21:00 -04:00
data feat(deploy): hero_biz socat bridge, books libraries, remove island-router 2026-03-11 18:53:07 -04:00
deploy/single-vm feat(deploy): add herodemo2 environment and herodev2 config examples 2026-03-12 10:48:38 -04:00
docker fix: fail loudly when seed data or service configs fail to copy in build-local.sh 2026-03-13 13:39:14 -04:00
docs docs: add ops deployment guide and update Makefile tags to :dev2/:demo2 2026-03-13 12:44:08 -04:00
examples rename hero_forge to hero_fossil, remove hero_launcher, and fogejo fixes 2026-02-19 07:46:25 +01:00
scripts refactor: rename crates to standard hero naming convention 2026-03-04 07:27:37 +02:00
services fix: add serve subcommand to hero_books_server exec 2026-03-13 12:03:58 -04:00
tests feat(tests): update smoke tests for current service names, add BASE_PATH checks 2026-03-11 19:36:53 -04:00
.dockerignore refactor: Use zinit client library, remove init module, add Docker support 2026-02-11 12:31:42 +01:00
.env.example Add CODEROOT/BUILDDIR env vars and replace raw git with herolib_os GitTree 2026-02-15 19:14:45 +01:00
.gitignore lhumina_code/home#12 — Fast local build pipeline + container naming fix 2026-03-10 20:59:42 -04:00
bootstrap.sh feat(bootstrap): add curl-friendly workspace bootstrap script 2026-03-11 17:08:10 -04:00
buildenv.sh fix: rename hero_fossil to hero_foundry in build paths and config 2026-03-08 18:38:34 -04:00
Cargo.toml home/issues/12 -- SSH→HTTPS migration, Docker patches, wasm-opt, service CLI fixes 2026-03-10 16:06:57 -04:00
Dockerfile.pack fix: correct hero_aibroker template path in Dockerfile.pack 2026-03-12 12:24:24 -04:00
LICENSE Initial commit 2026-01-09 21:39:18 +00:00
Makefile docs: add ops deployment guide and update Makefile tags to :dev2/:demo2 2026-03-13 12:44:08 -04:00
README.md feat(tests): update smoke tests for current service names, add BASE_PATH checks 2026-03-11 19:36:53 -04:00

Hero Services

Service orchestrator for the Hero OS ecosystem.

Hero OS is a suite of ~15 services (hero_books, hero_biz, hero_redis, hero_auth, hero_foundry, hero_embedder, hero_osis, hero_indexer, hero_voice, hero_cloud, and more) orchestrated by zinit inside a Docker container, with a Dioxus WASM frontend that embeds them via iframes or native islands.

Hero Services manages the lifecycle of all these services — building, installing, starting, stopping, and monitoring them via a unified JSON-RPC interface over Unix sockets. The hero_proxy reverse proxy routes HTTP traffic to each service's Unix socket, and the hero_os_app WASM frontend provides a unified desktop-like UI with a dock toolbar for switching between services.

Architecture

hero_services_sdk        (library: types + async Unix socket client)
     ↑         ↑          ↑           ↑
     |         |          |           |
  server     CLI         ui      examples
Crate Type Purpose
hero_services_sdk library Types, RPC client, shared protocol
hero_services_server binary Daemon, JSON-RPC over Unix socket
hero_services binary CLI client using SDK
hero_services_ui binary Axum admin panel using SDK
hero_services_examples examples Example programs demonstrating SDK usage

Quick Start

Full workspace (Docker build)

mkdir -p ~/hero/src/lhumina_code && cd ~/hero/src/lhumina_code
curl -sSfL https://forge.ourworld.tf/lhumina_code/hero_services/raw/branch/development/bootstrap.sh | bash
cd hero_services
make dist   # compile all binaries → dist/
make pack   # build Docker image
make push   # push to registry

bootstrap.sh clones all 18 repos (hero_services + 17 service repos + zinit) into the sibling layout that build-local.sh expects. Re-running pulls latest — safe to use for updates.

Local development (single service)

git clone -b development https://forge.ourworld.tf/lhumina_code/hero_services.git
cd hero_services
make run

Make Targets

make run           # Build release, install, and run via zinit
make rundev        # Build debug, install, and run via zinit (debug logging)
make stop          # Stop all services
make restart       # Restart all services
make status        # Show service status (zinit list)
make logs          # Show server logs
make logs-ui       # Show UI logs
make install       # Build release and install to ~/hero/bin
make installdev    # Build debug and install to ~/hero/bin
make build         # Standalone binary with embedded services
make check         # cargo check + clippy
make test          # Run unit tests
make test-all      # Full test pipeline (unit + integration)
make smoke         # Run gateway smoke tests against herodev (or GATEWAY_URL)
make smoke-basic   # Run basic smoke tests (health + UI pages)

Sockets

All Unix sockets are located in:

~/hero/var/sockets/
Service Socket
Server (JSON-RPC) ~/hero/var/sockets/hero_services_server.sock
Admin UI (HTTP) ~/hero/var/sockets/hero_services_ui.sock

No services bind TCP ports directly.

Accessing the Admin UI

Option 1 — hero_inspector (recommended for development):

hero_inspector can open any socket-based UI in your browser by spawning a local TCP→socket reverse proxy on a free port:

# Install and run hero_inspector with its own HTTP UI
cd ../hero_inspector && make install
hero_inspector_ui --http --port 8802 --open

Then use the inspector UI at http://localhost:8802 to discover all running services. Click Open on any web UI service (e.g. hero_services_ui) and the inspector will proxy it to a localhost port automatically.

Programmatically via JSON-RPC:

curl --unix-socket ~/hero/var/sockets/hero_inspector_ui.sock \
  -X POST http://localhost/rpc \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"inspector.open_website","params":{"service_id":"hero_services_ui"}}'

Returns { "port": 9100, "url": "http://127.0.0.1:9100" } — open that URL.

Option 2 — hero_proxy (production):

hero_proxy (port 8805) auto-discovers all sockets and routes by path:

http://localhost:8805/hero_services/

Option 3 — curl directly (quick debugging):

curl --unix-socket ~/hero/var/sockets/hero_services_ui.sock http://localhost/

Service Configuration Format

Each service is defined in a single TOML file under services/{profile}/. A service has a [server] component (required) and an optional [ui] component. Each component specifies how to install it — either by downloading a pre-built binary or building from source.

Minimal example (build from source)

[service]
name = "hero_redis"
description = "Redis — in-memory data store"

[server]
exec = "__HERO_BIN__/hero_redis_server"
build = "ssh://git@forge.ourworld.tf/lhumina_code/hero_redis.git"
install = { method = "build", branch = "development" }

[env]
RUST_LOG = "info"

[profile]
description = "Redis — in-memory data store"
actions = ["install", "run", "health"]

Full example (server + UI, download + build, shared build options)

[service]
name = "hero_os"
description = "Hero OS — web UI and backend"
depends_on = ["hero_osis_server"]

# Shared build options (features, source_deps) — applies to all components
[build]
features = ["web"]
base_features = ["core"]
required_features = ["island-archipelagos", "island-settings"]
available_features = ["island-ai", "island-chat", "island-calendar"]

[server]
exec = "__HERO_BIN__/hero_os_server"
download = "https://releases.ourworld.tf/hero_os/{version}/hero_os-{os}-{arch}"
build = "ssh://git@forge.ourworld.tf/lhumina_code/hero_os.git"
install = { method = "build", branch = "development" }

[ui]
exec = "__HERO_BIN__/hero_os_ui"
ports = [8804]
kill_others = true

[env]
RUST_LOG = "info"

[profile]
description = "Hero OS — web UI and backend"
actions = ["install", "run", "health"]

Component fields

Each component ([server] or [ui]) supports:

Field Type Description
exec string Command to run (required)
download string Release URL template with {version}, {os}, {arch} placeholders
build string Git repo URL for building from source
install inline table Install instructions (see below)
ports array TCP ports used
kill_others bool Kill processes on declared ports before starting
env table Component-specific environment variables
oneshot bool Run once and exit (for setup scripts)

Install instructions

# Download a specific version
install = { method = "download", version = "0.3.14" }

# Build from a branch
install = { method = "build", branch = "development" }

# Build from a specific commit
install = { method = "build", commit = "abc123" }

UI with its own build

When the UI comes from a different repo than the server, give it its own build and install:

[server]
exec = "__HERO_BIN__/hero_indexer"
build = "ssh://git@forge.ourworld.tf/lhumina_code/hero_index_server.git"
install = { method = "build", branch = "development" }

[ui]
exec = "__HERO_BIN__/hero_indexer_ui"
build = "ssh://git@forge.ourworld.tf/lhumina_code/hero_indexer_ui.git"
install = { method = "build", branch = "development" }

When the UI shares the server's build (same repo produces both binaries), omit build and install from [ui].

Placeholders

Placeholder Resolves to
__HERO_BIN__ ~/hero/bin/
__HERO_VAR__ ~/hero/var/
__HERO_ROOT__ ~/hero/
__HERO_SRC__ ~/hero/src/ (or $CODEROOT)

Naming convention

At load time, the unified TOML expands into zinit services:

  • [server]{name}_server (e.g. hero_redis_server)
  • [ui]{name}_ui (e.g. hero_redis_ui)

Cross-service dependencies use these expanded names:

depends_on = ["hero_redis_server", "hero_indexer_server"]

Services

User Profile

Service Socket / Port Purpose
hero_redis hero_redis.sock + port 3378 In-memory data store
hero_indexer hero_indexer.sock Full-text search
hero_indexer_ui hero_indexer_ui.sock Indexer admin panel
hero_embedder hero_embedder.sock Text embedding service
hero_embedder_ui hero_embedder_ui.sock Embedder admin panel
hero_osis hero_osis.sock Object storage API
hero_foundry hero_foundry.sock Code repositories
hero_auth hero_auth.sock OAuth2 authentication
hero_books port 8883 Book management
hero_os hero_os.sock Hero OS core
hero_proxy port 8080 Reverse proxy / API gateway

Admin Profile

Service Socket / Port Purpose
forgejo forgejo.sock + port 3393 Git forge
forgejo_mcp port 3395 MCP interface for Forgejo
hero_compute_manager hero_compute_manager.sock Compute resource manager
hero_embedder hero_embedder.sock Text embedding
my_router_path my_router_path.sock + port 2918 Path-based router

Beta Profile

Service Socket / Port Purpose
hero_aibroker hero_aibroker.sock AI model broker
hero_claude port 3780 Claude AI interface
hero_runner port 3391 Task runner
hero_shrimp hero_shrimp.sock Shrimp AI service
mycelium port 3392 Network mesh protocol

CLI Commands

hero_services health                    # Check server health
hero_services list                      # List all services
hero_services start|stop|restart <name> # Control a service
hero_services logs [name] [-n LINES]    # View logs
hero_services config [name]             # Show configuration
hero_services install <name>            # Install a service
hero_services install-all               # Install all services
hero_services build-status              # Show build progress

Runtime Directories

~/hero/
├── bin/                          # Service binaries
├── src/                          # Source code (for build method)
├── var/
│   ├── sockets/                  # Unix domain sockets
│   │   ├── hero_services_server.sock
│   │   ├── hero_services_ui.sock
│   │   ├── hero_redis.sock
│   │   ├── hero_osis.sock
│   │   └── ...
│   └── hero_zero/
│       └── installed/            # Install tracking
└── cfg/zinit/                    # Generated zinit configs

Docker — Build & Deploy

Compiles all 34 binaries inside rust:1.93-bookworm containers (correct glibc for Debian Bookworm), then packs into a thin runtime image.

# Full pipeline: compile → pack → push → deploy to herodev
make deploy

# Individual steps:
make dist            # Compile all binaries → dist/ (~10 min incremental, ~25 min cold)
make dist-quick      # Skip WASM + shrimp (faster iteration)
make pack            # Pack dist/ into thin Docker image (~10 sec)
make push            # Push :dev image to registry
make deploy          # dist + pack + push + deploy to herodev

# Promote to demo:
make demo            # Tag :dev as :demo, push to registry

# Deploy to a specific environment:
cd deploy/single-vm && make update ENV=herodev    # Pull + restart on VM
cd deploy/single-vm && make update ENV=herodemo
cd deploy/single-vm && make setup  ENV=herodev    # Full VM setup (first time)

Environment variables

Variable Default Description
SKIP_WASM 0 Set to 1 to skip WASM frontend builds
SKIP_SHRIMP 0 Set to 1 to skip hero_shrimp (Bun) build
DIST_DIR ./dist Output directory for compiled binaries

How it works

  1. docker/build-local.sh runs cargo build --release inside Bookworm containers with volume-mounted source code and persistent cargo caches (Docker volumes)
  2. Dockerfile.pack copies the pre-built binaries into a debian:bookworm-slim runtime image
  3. deploy/single-vm/ manages VM provisioning and container lifecycle via SSH

Deployment tiers

Tier Image tag Container name Port
dev :dev herodev 8805
demo :demo herodemo 8806
prod :prod heroprod 8805

Container names and ports are configured in deploy/single-vm/envs/<env>/app.env.

Requirements

  • Docker (for container-based compilation and deployment)
  • Git, Make
  • Bun (for hero_shrimp build, optional with SKIP_SHRIMP=1)

Add ~/hero/bin to your $PATH:

export PATH="$HOME/hero/bin:$PATH"

License

Apache-2.0