Hero - the sovereign everything app
  • Rust 54.7%
  • Shell 27.9%
  • JavaScript 9%
  • Makefile 3.7%
  • HTML 3.1%
  • Other 1.6%
Find a file
mik-tf 4b55548039
Some checks failed
Build and Test / build (push) Failing after 1m14s
feat: smoke tests to 49/50 pass, add make verify and make smoke-demo
- Fix false positives: skip hero_cloud_ui (intentionally inactive),
  accept 303 for hero_auth_ui (redirect to setup is valid)
- Add section 10: books library verification (3 libraries, books > 0)
- Add make verify: deploy + wait + smoke test in one command
- Add make smoke-demo: test herodemo2 directly
- Update default URLs from gent02 to gent04
- Add WAIT_SECS support for post-deploy settling
- Update docs/ops/deployment.md with full workflow reference

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-14 00:41:28 -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 chore: consolidate image tags from :dev2/:demo2 to :dev/:demo 2026-03-14 00:28:58 -04:00
docker fix: add GIT_TOKEN for private book repos + git credentials in entrypoint 2026-03-13 23:34:31 -04:00
docs feat: smoke tests to 49/50 pass, add make verify and make smoke-demo 2026-03-14 00:41:28 -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 GIT_TOKEN for private book repos + git credentials in entrypoint 2026-03-13 23:34:31 -04:00
tests feat: smoke tests to 49/50 pass, add make verify and make smoke-demo 2026-03-14 00:41:28 -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 feat: smoke tests to 49/50 pass, add make verify and make smoke-demo 2026-03-14 00:41:28 -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