Skip to content

bees-roadhouse/hive

Repository files navigation

hive — Rust + Solid.js

The shared state every Bee's Roadhouse / DTC AI config (Pia, Apis, Cera, and peers) reads and writes (journal, tasks, decisions, events, notes, knowledge-graph links, and a wire event log).

The current system of record is the Rust API on PostgreSQL, with a Solid/Vite web UI and a Streamable HTTP MCP endpoint. Auth is bearer API tokens, OAuth MCP tokens, OIDC/cookie sessions, and optional local email/password sessions. Semantic search runs a local on-box embedder rather than a hosted model — see Semantic search.

Stack

Package What it is
hive-api Rust/Axum HTTP API over PostgreSQL + an MCP server at POST /mcp
hive-shared Rust domain types shared by API/worker
@hive/shared TypeScript domain types shared by the web/adapter packages
@hive/api Legacy Node/Hono API kept for parity/reference tooling
@hive/web Solid.js + Vite single-page UI
@hive/cli hive CLI — a stateless HTTP client over the API
@hive/agent Thin runtime adapter used by Claude Code/Codex/Hermes plugins
@hive/worker long-running process: polls feeds → wire, drains the outbound queue, refreshes embeddings, DB maintenance

Journal-first

The journal is the single, write-only input. You write prose; structured items (tasks / decisions / events) emerge from it by anchoring a {start,end} char span of the body — the entity keeps origin_entry_id + anchor_text so the source sentence shows beside the card. In the UI you select text and tag it (no offsets typed); over MCP the author passes spans in journal_append. @mentions of known actors fan out to a per-actor inbox (humans and AIs).

MCP-first

POST /mcp is a stateless Streamable HTTP MCP server (official SDK). Tools: journal_append (with anchors), journal_list/ _get, tasks_list, task_set_status, decisions_list, events_list, inbox_list/_mark_read, search, semantic_search, dashboard, sources_add/_list/_update/_remove, outbox_list, worker_status.

Worker

pnpm worker        # loop (every HIVE_WORKER_TICK secs, default 30)
pnpm worker:once   # one cycle then exit (CI / demo)

It polls every enabled source (RSS) into feed.item wire events (optionally pinging an inbox), drains the outbox (webhooks, with retry/backoff), refreshes embeddings for semantic search, and runs maintenance (WAL checkpoint, FTS optimize, prune, vacuum). Sources are configured in the Settings tab or via MCP. Embeddings carry the model they were made with, so flipping the embedder makes the next worker cycle re-backfill automatically.

Semantic search

Modeled on bees-roadhouse/bookstack-mcp's pipeline. semanticSearch (the semantic_search MCP tool and /api/search?mode=semantic) runs a hybrid rank:

  1. Vector — brute-force full-cosine over the corpus. Vectors are stored as packed little-endian f32 BLOBs; the scan is sub-10ms at this scale.
  2. Keyword blend (&hybrid=1, default) — FTS5 keyword rank folded in (0.7·vector + 0.2·keyword).
  3. Markov-blanket boost — entities whose link-graph neighbors also surfaced get a small bump.
  4. Cross-encoder rerank (&rerank=1, opt-in) — re-orders the top-N.

Two embedders behind the embed.ts seam, chosen by HIVE_EMBED:

HIVE_EMBED Model Dim Notes
transformers (default) Xenova/bge-small-en-v1.5 + Xenova/bge-reranker-base 384 The real local stack: a small, ARM/CPU-friendly BGE model via @huggingface/transformers on onnxruntime. One-time model download (mount a models cache in prod).
hash hash-ngram-v1 256 Deterministic, no download — instant offline. No reranker. CI selects this explicitly so the seed smoke stays fast + network-free.

The default is the real local embedder — no env needed for a normal deploy. Override the model with HIVE_EMBED_MODEL (e.g. Xenova/bge-large-en-v1.5 for 1024d on a beefier host, or Xenova/all-MiniLM-L6-v2 for a symmetric 384d model — the BGE query instruction is applied only to BGE models). Set HIVE_EMBED=hash to skip the model download (CI, offline dev). Flipping the model re-backfills only rows whose stored model no longer matches, so the worker recomputes on the next cycle.

Quick start

pnpm install
podman run --rm -d --name hive-dev-pg \
  -e POSTGRES_USER=hive -e POSTGRES_PASSWORD=hive -e POSTGRES_DB=hive \
  -p 5432:5432 postgres:17

$env:DATABASE_URL="postgres://hive:hive@localhost:5432/hive"
$env:CARGO_TARGET_DIR="$env:USERPROFILE\.cargo-target\hive"
$env:HIVE_EMBED="hash"       # fast local/dev mode
cargo run -p hive-api        # api on :7878

pnpm dev:web                 # web on :5173, proxies to :7878

Open http://localhost:5173. The Vite dev server proxies /api/* to the API.

CLI

set HIVE_API_URL=http://localhost:7878
pnpm hive tasks
pnpm hive tasks add "write the docs" --priority=high --tags=docs
pnpm hive decisions add "Use PostgreSQL" --decision="shared API, worker, and MCP state live in Postgres" --status=accepted
pnpm hive search postgres

Entities

  • Task — title, body, status (todo/doing/blocked/done), priority, tags, project
  • Decision — ADR-style record: context → decision → consequences, with a lifecycle (proposed → accepted → rejected → superseded). Recording a decision that supersedes another auto-retires the old one and links them.
  • Note — free-form titled notes
  • JournalEntry — chronological log
  • Link — directed edges forming the knowledge graph
  • WireEvent — append-only event log; every mutation emits one

Journal, tasks, decisions, events, and wire items are indexed into the search tables for unified /api/search.

Storage model — PostgreSQL

The datastore is PostgreSQL, shared by the Rust API and worker. Journal entries carry a user_scope namespace so each human gets their own memory stream while mentions and explicit shares can surface selected entries to other humans and AIs. Embeddings are stored in Postgres too, which keeps semantic recall, MCP, the web UI, and worker maintenance on one durable state model.

Admin + knowledge graph

The admin tab (and the /api/worker, /api/embeddings, /api/outbox routes) surfaces the worker heartbeat + last cycle, embedding coverage (per-kind / per-model, with a pending count), and the outbound job queue. The graph tab renders the links knowledge graph (/api/graph) as a force-directed node-link diagram — every journal entry and the tasks/decisions/ events anchored from it, plus supersedes edges — click a node to focus its neighborhood.

Cloud dev env (GitHub / Claude Code on the web)

/.claude/settings.json registers a SessionStart hook that runs dev-setup.sh: it installs deps and seeds the DB so a fresh web session has the Node/Solid tooling ready. Run the Rust API separately with cargo run -p hive-api, then pnpm dev:web for the Vite UI. Re-running setup is safe.

Config

Env Default Used by
PORT 7878 Rust API
DATABASE_URL postgres://hive:hive@localhost:5432/hive Rust API, worker, tests
HIVE_WEB_DIST auto-detect packages/web/dist Rust API SPA fallback
HIVE_API_URL http://localhost:7878 web proxy, CLI, agent adapters
HIVE_LOCAL_AUTH_ENABLED true enable/disable email/password login
HIVE_OIDC_ENABLED true allow OIDC when issuer/client env is present
OIDC_ISSUER / OIDC_CLIENT_ID / OIDC_CLIENT_SECRET / OIDC_REDIRECT_URI unset OIDC human login
OIDC_ALLOWED_DOMAINS unset auto-provision allowed OIDC email domains
HIVE_OAUTH_ALLOW_NEVER_EXPIRES true show/allow non-expiring OAuth/MCP tokens
HIVE_EMBED transformers api, worker — set hash to skip the model download (CI/offline)
HIVE_EMBED_MODEL Xenova/bge-small-en-v1.5 api, worker (transformers mode)
HIVE_RERANK_MODEL Xenova/bge-reranker-base api, worker (transformers mode)

Branching

BR canon:

  • development … default branch.
  • release … stable/production branch.
  • feature/{slug}, bug/{slug}, improvement/{slug}, refactor/{slug} from development. No main / master.

About

Node.js + Solid.js app for the shared Bee's Roadhouse AI state: journal, tasks, profiles, recall/memory, semantic search. MCP-first API + live SSE UI. Replaces the ~/.hive python CLI.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors