No description
  • Rust 49.5%
  • JavaScript 24.4%
  • HTML 9.8%
  • Shell 7.5%
  • CSS 6.1%
  • Other 2.7%
Find a file
2026-04-28 21:21:03 -04:00
.cargo feat(workspace): snapshot hero_collab → hero_assistance, rename, baseline build green 2026-04-28 15:45:55 -04:00
crates feat(transport): Phase 5 — auto:<port> overlay-bind + dispatcher 400::/7 filter 2026-04-28 21:19:55 -04:00
decisions feat(transport): Phase 5 — auto:<port> overlay-bind + dispatcher 400::/7 filter 2026-04-28 21:19:55 -04:00
deploy feat(workspace): snapshot hero_collab → hero_assistance, rename, baseline build green 2026-04-28 15:45:55 -04:00
docs feat(workspace): snapshot hero_collab → hero_assistance, rename, baseline build green 2026-04-28 15:45:55 -04:00
limitations feat(identity): Phase 3 — CallerIdentity newtype, magic-link enrollment, dispatcher boundary 2026-04-28 17:50:46 -04:00
plan feat(prune): drop huddles, canvases, reactions, mentions, voice rooms, Dioxus admin app 2026-04-28 16:29:28 -04:00
scripts feat(workspace): snapshot hero_collab → hero_assistance, rename, baseline build green 2026-04-28 15:45:55 -04:00
sessions chore(sessions): record Phase 5 commit SHA + write session 5 manifest 2026-04-28 21:21:03 -04:00
.gitignore feat(workspace): snapshot hero_collab → hero_assistance, rename, baseline build green 2026-04-28 15:45:55 -04:00
apikeys.db feat(workspace): snapshot hero_collab → hero_assistance, rename, baseline build green 2026-04-28 15:45:55 -04:00
buildenv.sh feat(workspace): snapshot hero_collab → hero_assistance, rename, baseline build green 2026-04-28 15:45:55 -04:00
Cargo.toml feat(prune): drop huddles, canvases, reactions, mentions, voice rooms, Dioxus admin app 2026-04-28 16:29:28 -04:00
CLAUDE.md feat(transport): Phase 5 — auto:<port> overlay-bind + dispatcher 400::/7 filter 2026-04-28 21:19:55 -04:00
IMPLEMENTATION_SUMMARY.md feat(workspace): snapshot hero_collab → hero_assistance, rename, baseline build green 2026-04-28 15:45:55 -04:00
LICENSE feat(workspace): snapshot hero_collab → hero_assistance, rename, baseline build green 2026-04-28 15:45:55 -04:00
Makefile feat(workspace): snapshot hero_collab → hero_assistance, rename, baseline build green 2026-04-28 15:45:55 -04:00
pipeline-config.yaml feat(workspace): snapshot hero_collab → hero_assistance, rename, baseline build green 2026-04-28 15:45:55 -04:00
PROJECT_STRUCTURE.md feat(prune): drop huddles, canvases, reactions, mentions, voice rooms, Dioxus admin app 2026-04-28 16:29:28 -04:00
prompt.md chore(sessions): record Phase 5 commit SHA + write session 5 manifest 2026-04-28 21:21:03 -04:00
README.md feat(prune): drop huddles, canvases, reactions, mentions, voice rooms, Dioxus admin app 2026-04-28 16:29:28 -04:00
TECH_SPEC.md feat(workspace): snapshot hero_collab → hero_assistance, rename, baseline build green 2026-04-28 15:45:55 -04:00

hero_assistance

A markdown-centric team collaboration platform built as a first-class Hero OS service. Channels and threads, real-time chat with reactions, @mentions, file attachments, full-text search, collaborative canvases (CRDT via Yjs/yrs), and voice huddles via LiveKit.

Service model: hero_assistance_server exposes JSON-RPC over a Unix domain socket (~/hero/var/sockets/hero_assistance/rpc.sock). hero_assistance_ui serves the HTML/JS frontend and proxies browser-originated RPC/WS (~/hero/var/sockets/hero_assistance/ui.sock). Both are run by hero_proc. Typical operator deploys them behind hero_proxyhero_router for identity injection and TLS.


Quick start (local development)

make devstart   # wipes DB + starts in dev mode + seeds 4 test users

That target:

  1. Stops any running hero_assistance service.
  2. Wipes ~/hero/var/data/hero_assistance/collab.db* and attachment files.
  3. cargo install --release into ~/hero/bin.
  4. hero_assistance --start --auth-mode=dev --seed-dev-users — registers both services under hero_proc, dev-mode identity, and seeds a canonical 4-user fixture (Alice=id 1, Bob=2, Carol=3, Dave=4) + one "General" workspace + one #general channel with all 4 users as members. Alice is the channel admin.

Then open http://localhost:9988/hero_assistance/ui — that's hero_router's port, which forwards to hero_assistance_ui's socket. The user picker appears; pick any of the 4 seeded users. Open another tab (or incognito) and pick a different user to simulate multi-user chat.

If you want a non-destructive start (keep existing DB, no seed):

make install                                       # release build + install
hero_assistance --start --auth-mode=dev                # dev mode, no seed
# Or proxy mode (default) for testing real auth:
hero_assistance --start

make devstart is destructive — intended for iterative dev where starting from a known clean slate every session is the point. Do not run it against a DB you care about.

Why --auth-mode=dev on the CLI instead of an env var? hero_proc spawns its children with a clean env — anything you export in the parent shell never reaches hero_assistance_server. CLI flags are the supported knob that survives the hero_proc spawn boundary. Env vars still work when you launch the binaries directly (handy for tests), but under hero_proc --start only flags propagate. See deploy/README.md for the full flag ↔ env ↔ precedence table.

Prerequisites

  • Rust 1.80+ with the 2024 edition (rustup update stable)
  • SQLite 3 installed (bundled via rusqlite feature, so system SQLite isn't strictly required)
  • A running hero_proc + hero_router + optional hero_proxy (install from their respective Forge repos)
  • Optional: LiveKit server for huddles — see deploy/README.md

Auth modes

Mode Behavior
proxy (default) Expect X-Hero-User from hero_proxy. Reject unauthenticated RPCs.
dev User picker fallback, no headers required. Logs a prominent warning at startup. Never ship to production.

Three ways to set the mode, most-specific wins:

  1. hero_assistance_server --auth-mode=<dev\|proxy> — direct-launch flag.
  2. hero_assistance --start --auth-mode=<dev\|proxy> — CLI wrapper; forwards to hero_assistance_server via the hero_proc action spec AND sets COLLAB_AUTH_MODE on the hero_assistance_ui action. Both processes agree.
  3. COLLAB_AUTH_MODE env var — fallback for tests and direct- binary launches. Ignored under hero_proc supervision (clean env).

Running the two binaries by hand (bypassing hero_proc), export COLLAB_AUTH_MODE=dev once and launch both; clap's env fallback picks it up transparently. If you mix the two paths (CLI flag on server, env on UI) you can drift — hero_assistance --start --auth-mode=X keeps them in sync.


Architecture (5 crates)

crates/
├── hero_assistance_server/   JSON-RPC service on rpc.sock (SQLite-backed)
├── hero_assistance_ui/       axum HTTP + WS relay serving static assets on ui.sock
├── hero_assistance_sdk/      Auto-generated typed Rust client (via openrpc_client!)
├── hero_assistance/          CLI (`hero_assistance --start`, --stop, --status)
└── hero_assistance_examples/ Runnable examples: basic_usage, health, load_test

Data layout:

  • ~/hero/var/data/hero_assistance/collab.db — SQLite DB (WAL mode)
  • ~/hero/var/data/hero_assistance/files/ — attachment blobs, namespaced by workspace then attachment id
  • ~/hero/var/logs/core/YYYY/DOY/logs.sqlite — structured logs via hero_proc's log aggregator

Wire protocol: JSON-RPC 2.0 over HTTP/1.1 over Unix Domain Socket. The openrpc.json spec at crates/hero_assistance_server/openrpc.json is the source of truth; hero_assistance_sdk is generated from it via the openrpc_client! macro. 80+ methods, stable error codes per src/rpc_error.rs.


Key features

  • Workspaces / channels / DMs — standard Slack topology, with public + private channels and direct-message kinds.
  • Messages — send, edit, delete (soft), pin, full-text search (SQLite FTS5), attachments with per-user ownership (B5), and threaded replies.
  • Reactions — atomic message.toggle_react returning {action: "added"|"removed"}; no reactions on tombstoned messages (H6).
  • @mentions — parsed on send, delivered via WS push (mention.created) and surfaced as OS-level browser notifications when the tab is backgrounded (H10).
  • Canvases — Yjs/yrs CRDT-backed collaborative docs with Tiptap editor; multi-client real-time sync over binary WS; role-gated (owner, editor, viewer); viewer mode enforces read-only in-browser (Phase 4-EXT 1A).
  • Voice huddles — LiveKit SFU integration, JWTs signed by livekit.rs::generate_token. deploy/docker-compose.yml stands up LiveKit + Redis for a self-hosted deployment.
  • Rate limiting — 60 RPC/min global + 10/min on message.send per authenticated caller, two-phase check-then-commit; bypasses dev-mode unauthenticated calls.
  • Observabilityrpc.dispatch tracing events on every call, atomic counters exposed via system.metrics, /health shows active WS connection count.
  • Federationcollab.users.available unions local users with hero_proxy's users.list; UI invite/DM pickers see system-wide identities (K-4-2).

Testing

# Unit tests (rate_limit, rpc_error, validation, activity)
cargo test -p hero_assistance_server --bin hero_assistance_server

# Integration tests (spawn real server per test, ephemeral sockets)
cargo test -p hero_assistance_server --test integration

# Full workspace
cargo test --workspace

As of the post-Plan-A P0/P1 sweep: 40 unit + 30 integration tests, with specific coverage of the ship-blocker regressions surfaced during hardening (B1B6), the 6.1c typed-error wire codes, pin/unpin

  • require_caller + claim_federated from the external-audit P0/P1 batch, and the channel.create auto-member fix.

Operations

Operational docs:

  • deploy/README.md — LiveKit setup, env vars, ports.
  • docs/BACKUP.md — online DB backup + restore; retention hints.
  • plan/known-issues.md — tracked issues deferred from Plan A, organized by phase of origin (H-3-, K-4-, K-6-, P-A-, P-B-, P-C-, P-D-*).

Metrics to watch in production:

  • /health on ui.sock: active_ws_connections (should be >0 when users are connected; rebooting the UI pulls it to 0 and it climbs back as clients reconnect).
  • system.metrics RPC: rpc_calls_total, rpc_errors_total, avg_latency_ms, workspaces, users, channels, messages.
  • Log stream (hero_proc's logs.sqlite): grep rpc.dispatch for per-call timing + error codes; grep task=huddle_reaper or task=attachment_cleanup for background-task activity; grep trace_id= to correlate user-reported issues with sanitized -32603 Internal responses.

Browser support

Minimum: Chrome/Edge 100+, Firefox 100+, Safari 15.4+. See crates/hero_assistance_ui/BROWSER_SUPPORT.md for the full API coverage rationale.


Plan + roadmap

The per-phase execution history lives in plan/:

  • phase-6x-plan-a.md — the consolidated backlog executed most recently (Sprint 13 + 6.1c + P2)
  • slack-feature-parity.md — the original 7-phase plan
  • feature-huddles.md, feature-huddles-v2.md, feature-voice-to-canvas.md — feature-specific design docs
  • known-issues.md — deferred items

Commit messages tag their plan step (Phase-6x Plan A / Phase B, etc.) so git log reads as a timeline of what was shipped when.


Contributing

  • Follow the established commit-message format: one header line describing the change + a body explaining why, with references to the plan step or known-issue ID. Use Co-Authored-By: for pair / AI-assisted work.
  • New handlers return RpcResult<Value>, not anyhow::Result — see src/rpc_error.rs for the typed-error contract.
  • Input validation uses the typed newtype pattern (Name, Email, ChannelName, MessageContent, etc.) from src/validation.rs. Handlers call parse_input::<T>(params) to deserialize + validate.
  • Run cargo test and the Python backend smoke before committing; run the Playwright browser smoke when touching chat-app.js or canvas-app.js.

License

See Cargo.toml.