Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

README.md

CatCode hub (web/)

Thin Rust HTTP + WebSocket shell around catcode-core. Leptos CSR UI. One binary. No agent loop.

The browser is a render surface. Cores are server-owned and stay live when you close a tab or sign out.

Run

./scripts/build-web-frontend.sh
cargo run --manifest-path web/Cargo.toml -- --host 127.0.0.1 --port 49283

Or via the launcher (builds the WASM UI if frontend/dist is missing, points CATCODE_CORE at the in-repo release core):

./scripts/run-web.sh

Open http://127.0.0.1:49283.

Flag / env Default Meaning
--host / HOST 127.0.0.1 Bind address
--port / PORT 49283 Bind port
--origin / CATCODE_WEB_ORIGIN http://<host>:<port> Public origin for cookies (Secure when https)
--core / CATCODE_CORE TUI resolution Core binary, used as-is when set

Core resolution matches the TUI: CATCODE_CORE as-is → sibling catcode-corecore/target/release/corePATH.

Persistence guarantee

Cores live in the hub process, keyed by absolute session JSONL path.

  • Close the tab: WebSocket subscribers detach. Live cores keep running.
  • Sign out: this device cookie is revoked. Cores and hub-layout.json stay.
  • Sign back in on any device: restore layout → reopen project tabs + last session → reattach mid-turn.
  • Idle GC: only after 2h with zero viewers and not mid-turn. Never reap streaming or blocked (approval / ask / sudo / intercom / oauth) sessions.
  • A core dies only on idle GC, explicit session delete, or hub process exit. On-disk JSONL still resumes.

Account files under ~/.config/catalyst-code/ (mode 0600, atomic tmp+rename):

account.json          { name, password_hash, created_at }
devices.json          [{ id, name, token_hash, user_agent, created, last_seen, revoked }]
hub-layout.json       { version: 1, projects: [{ path, session, title? }], active_path }
projects.json         [{ path, name, added_at }]
web-settings.json     { theme, desktop_notifications }
sessions/<fnv64a-hex>/<2006-01-02_15-04-05_NNNNNNNNN>.jsonl

Session identity is the TUI's: FNV-1a 64 (0xcbf29ce484222325 / 0x100000001b3) over filepath.Abs(cwd) bytes, printed as %x.

First-run setup is display name + password (min 8). Reset: delete account.json + devices.json and restart. See .catalyst-code/skills/reset-webui-password/SKILL.md.

Protocol

One WebSocket GET /ws (cookie required). Fan-in of every live core. Commands on stdin, events on stdout, protocol v2, client name catcode-hub.

The hub reconstructs AgentState in Rust (src/reduce.rs). The Leptos client applies the same reducer on live events and always re-attaches after reconnect.

Tests

# Rust: HTTP + WebSocket + frontend contract + fake-core bridge
cargo test --manifest-path web/Cargo.toml

# Leptos crate: markdown + helpers
cargo test --manifest-path web/frontend/Cargo.toml --lib

# WASM package (needs trunk + wasm32-unknown-unknown)
./scripts/build-web-frontend.sh

# Browser: Playwright against catcode-web + fake-core
(cd web/e2e && npm install && npx playwright install chromium && npm test)

cargo build --manifest-path web/Cargo.toml

Release packaging

Local/dev uses this Rust binary. If an installer or release-web.sh still mentions node_modules / Next tarballs, that packaging path is a follow-up — do not mix two frontends.