diff --git a/CLAUDE.md b/CLAUDE.md index 1458ef4..7d6c4cb 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -56,6 +56,7 @@ CLAUDE.md er eneste startdokument. Alt annet ligger under `docs/`: - `api_grensesnitt.md` — Kommunikasjonskart: SvelteKit er web-API, Rust er worker - `jobbkø.md` — PostgreSQL-basert køsystem for bakgrunnsjobber - `synkronisering.md` — PostgreSQL ↔ SpacetimeDB dataflyt og eierskapsmodell + - `claude_agent.md` — Claude som chat-deltaker: arkitektur, triggere, sikkerhet - `docs/erfaringer/` — Lærdommer fra v1 (adapter-mønster, Svelte 5, SpacetimeDB, Authentik) - `reference/` — Kode fra v1 med gjenbruksverdi (Editor.svelte) - `ops/` — Repeterbare vedlikeholdsjobber (ryddejobb, doc-audit, drift-sjekk) @@ -66,13 +67,24 @@ CLAUDE.md er eneste startdokument. Alt annet ligger under `docs/`: - Begge har sudo + docker-tilgang på serveren. ## Stack -- **Orkestrator/Backend:** Rust (maskinrommet) +- **Orkestrator/Backend:** Rust (maskinrommet) — kjører native på hosten - **Frontend:** SvelteKit (TypeScript, PWA) - **Sanntid:** SpacetimeDB - **Database/Graf:** PostgreSQL (+Apache AGE ved behov) - **Binærlagring:** CAS (content-addressable store) -- **AI:** LiteLLM (AI Gateway), faster-whisper (STT), ElevenLabs (TTS) -- **Infra:** Docker Compose, Caddy, Authentik (SSO) +- **AI:** Claude Code (chat-agent), LiteLLM (AI Gateway), faster-whisper (STT) +- **Infra:** Docker Compose, Caddy, Authentik (SSO), systemd + +## Driftsmodell +- **Maskinrommet** kjører direkte på hosten som systemd-tjeneste (`maskinrommet.service`), + ikke i Docker. Dette gir tilgang til `claude` CLI for agent-chat. + Bygges med `cargo build --release`, startes med `sudo systemctl restart maskinrommet`. +- **Øvrige tjenester** (PG, STDB, Caddy, Authentik, Whisper, LiteLLM) kjører i Docker. +- **Caddy** bruker `host.docker.internal` for å nå maskinrommet på hosten. +- **Claude som chat-deltaker:** Agent-node (`d3eebc99-...-a44`) i grafen. Legg Claude + til som `member_of` i en kommunikasjonsnode → alle meldinger trigger `agent_respond`-jobb + → maskinrommet kaller `claude -p` → svar skrives tilbake i chatten. +- **Kill switch:** `UPDATE agent_identities SET is_active = false WHERE agent_key = 'claude-main'` ## Produksjonsserver - **IP:** 157.180.81.26 diff --git a/config/caddy/Caddyfile b/config/caddy/Caddyfile index 7128171..7846272 100644 --- a/config/caddy/Caddyfile +++ b/config/caddy/Caddyfile @@ -4,6 +4,22 @@ # Alt annet rutes internt via Docker-nettverket sidelinja-net. # Auto-TLS via Let's Encrypt for alle domener. +# === Felles favicon-snippet === +(favicon) { + handle /favicon.ico { + root * /srv/static + file_server + } + handle /apple-touch-icon.png { + root * /srv/static + file_server + } + handle /icon-*.png { + root * /srv/static + file_server + } +} + # === SSO === auth.sidelinja.org { reverse_proxy authentik-server:9000 @@ -11,6 +27,8 @@ auth.sidelinja.org { # === Sidelinja (hovedapplikasjon) === sidelinja.org { + import favicon + # SpacetimeDB (WebSocket) handle_path /spacetime/* { reverse_proxy spacetimedb:3000 @@ -28,18 +46,13 @@ sidelinja.org { # Aktiveres når SvelteKit-containeren er klar (fase 3) # reverse_proxy sveltekit:3000 - # Placeholder til SvelteKit er deployet - respond "sidelinja.org — Synops v2 under utvikling" 200 + header Content-Type text/html + respond `
sidelinja.org — underveis!
` 200 } # === Maskinrommet API === api.sidelinja.org { - # Rust/axum backend (fase 2) - # Aktiveres når maskinrommet-containeren er klar - # reverse_proxy maskinrommet:3001 - - # Placeholder til maskinrommet er deployet - respond "api.sidelinja.org — ikke tilgjengelig ennå" 503 + reverse_proxy host.docker.internal:3100 } # === Forgejo (Git) === @@ -47,7 +60,20 @@ git.sidelinja.org { reverse_proxy forgejo:3000 } +# === Synops (plattformdomene) === +# Subdomener (api.synops.no, auth.synops.no osv.) legges til individuelt +# etter behov — HTTP-challenge fungerer per subdomain uten DNS-plugin. +synops.no { + import favicon + + header Content-Type text/html + respond `synops.no — underveis!
` 200 +} + # === Vegard.info === vegard.info { - respond "vegard.info — under construction" 200 + import favicon + + header Content-Type text/html + respond `vegard.info — underveis!
` 200 } diff --git a/docs/infra/claude_agent.md b/docs/infra/claude_agent.md new file mode 100644 index 0000000..01c8558 --- /dev/null +++ b/docs/infra/claude_agent.md @@ -0,0 +1,104 @@ +# Infrastruktur: Claude som chat-deltaker + +## Oversikt + +Claude deltar i samtaler som en agent-node i grafen. Når en bruker sender +en melding i en kommunikasjonsnode der Claude er deltaker, trigger maskinrommet +en `agent_respond`-jobb som kaller `claude -p` CLI og skriver svaret tilbake. + +## Arkitektur + +``` +Bruker sender melding (via frontend) + → create_node() i maskinrommet + → sjekker: har kommunikasjonsnoden en agent-deltaker? + → ja: enqueue agent_respond-jobb (prioritet 8) + → jobbkø-worker plukker opp (poll hvert 2s) + → kaller: claude -p "