Files
spiceflow/CLAUDE.md

6.1 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Project Overview

Spiceflow is an AI Session Orchestration PWA for monitoring and interacting with Claude Code and OpenCode CLI sessions from mobile devices or web browsers. It's a monorepo with three main components: a Clojure backend server, a SvelteKit frontend, and Playwright E2E tests.

Commands

Backend (Clojure)

cd server
clj -M:run          # Start server (port 3000)
clj -M:test         # Run tests with Kaocha
clj -M:repl         # Start REPL with nREPL for interactive development

Frontend (SvelteKit)

cd client
npm install         # Install dependencies
npm run dev         # Start dev server (port 5173, proxies /api to 3000)
npm run build       # Production build
npm run check       # Type checking with svelte-check
npm run check:watch # Watch mode for type checking

E2E Tests (Playwright)

cd e2e
npm test            # Run all tests (starts both servers automatically)
npm run test:headed # Run tests with visible browser
npm run test:ui     # Interactive Playwright UI mode

E2E tests use a separate database (server/test-e2e.db).

Development Scripts

./script/dev       # Start backend + frontend concurrently
./script/test      # Start servers and run E2E tests

The dev script starts both servers and waits for each to be ready before proceeding. The test script uses a separate test database and cleans up after tests complete.

Architecture

Claude Code/OpenCode CLI ↔ Spiceflow Server (Clojure) ↔ PWA Client (SvelteKit)
                          ↓
                       SQLite DB

Backend (/server)

  • Entry point: src/spiceflow/core.clj - Ring/Jetty server with mount lifecycle
  • Routing: src/spiceflow/api/routes.clj - Reitit-based REST API
  • Database: Protocol-based abstraction (db/protocol.clj) with SQLite (db/sqlite.clj) and in-memory (db/memory.clj) implementations
  • Adapters: Pluggable CLI integrations (adapters/protocol.clj) - Claude Code (adapters/claude.clj) and OpenCode (adapters/opencode.clj)
  • WebSocket: api/websocket.clj - Real-time message streaming
  • Session management: session/manager.clj - Session lifecycle

Frontend (/client)

  • Routes: SvelteKit file-based routing in src/routes/
  • State: Svelte stores in src/lib/stores/ (sessions, runtime selection)
  • API client: src/lib/api.ts - HTTP and WebSocket clients
  • Components: src/lib/components/ - UI components
    • MessageList.svelte - Displays messages with collapsible long content
    • PermissionRequest.svelte - Permission prompts with accept/deny/steer actions
    • FileDiff.svelte - Expandable file diffs for Write/Edit operations
    • SessionSettings.svelte - Session settings dropdown (auto-accept edits)
    • InputBar.svelte - Message input with steer mode support
  • PWA: vite-plugin-pwa with Workbox service worker
  • Responsive: Landscape mobile mode collapses header to hamburger menu

Key Protocols

DataStore (db/protocol.clj):

  • get-sessions, get-session, save-session, update-session, delete-session
  • get-messages, save-message

AgentAdapter (adapters/protocol.clj):

  • discover - Find existing CLI sessions
  • spawn - Start CLI process with session
  • send - Pipe message to stdin
  • read-stream - Parse JSONL output
  • Adding new runtimes requires implementing this protocol

Configuration

Server configuration via server/resources/config.edn or environment variables:

Variable Default Description
SPICEFLOW_PORT 3000 Server port
SPICEFLOW_HOST 0.0.0.0 Server host
SPICEFLOW_DB spiceflow.db SQLite database path
CLAUDE_SESSIONS_DIR ~/.claude/projects Claude sessions directory
OPENCODE_CMD opencode OpenCode command

Features

Permission Handling

When Claude Code requests permission for file operations (Write/Edit) or shell commands (Bash), Spiceflow intercepts these and presents them to the user:

  • Accept: Grant permission and continue
  • Deny: Reject the request
  • Steer ("No, and..."): Redirect Claude with alternative instructions

File operations show expandable diffs displaying the exact changes being made.

Auto-Accept Edits

Claude sessions can enable "Auto-accept edits" in session settings to automatically grant Write/Edit permissions, reducing interruptions during coding sessions.

Session Management

  • Rename: Click session title to rename
  • Delete: Remove sessions from the session list
  • Condense: Collapse long messages for easier scrolling

Mobile Optimization

  • Landscape mode collapses the header to a hamburger menu
  • Compact file diffs with minimal padding
  • Touch-friendly permission buttons

Session Flow

  1. User opens PWA → sees list of tracked sessions
  2. User selects session → loads message history
  3. User types message → POST to /api/sessions/:id/send
  4. Server spawns CLI process with --resume flag
  5. Server pipes user message to stdin
  6. CLI streams response via stdout (JSONL format)
  7. Server broadcasts to client via WebSocket
  8. If permission required → WebSocket sends permission request → User accepts/denies/steers
  9. Process completes → response saved to database

API Endpoints

Endpoint Method Description
/api/health GET Health check
/api/sessions GET List all sessions
/api/sessions POST Create new session
/api/sessions/:id GET Get session with messages
/api/sessions/:id PATCH Update session (title, auto-accept-edits)
/api/sessions/:id DELETE Delete session
/api/sessions/:id/send POST Send message to session
/api/sessions/:id/permission POST Respond to permission request
/ws WebSocket Real-time message streaming

Tech Stack

  • Backend: Clojure 1.11, Ring/Jetty, Reitit, next.jdbc, SQLite, mount, Kaocha
  • Frontend: SvelteKit 2.5, Svelte 4, TypeScript, Tailwind CSS, Vite, vite-plugin-pwa
  • E2E: Playwright