add resizing

This commit is contained in:
2026-01-20 15:31:41 -05:00
parent 66b4acaf42
commit b6f772f901
22 changed files with 1727 additions and 420 deletions
+63 -149
View File
@@ -1,190 +1,104 @@
# Spiceflow
AI Session Orchestration PWA for monitoring and interacting with Claude Code and OpenCode sessions.
> "The spice must flow."
## Architecture
A mobile-friendly web app for controlling AI coding assistants (Claude Code, OpenCode) remotely.
```
┌─────────────────┐ ┌─────────────────────────┐ ┌─────────────────┐
│ Claude Code │<--->│ Spiceflow Server │<--->│ PWA Client │
│ (CLI) │ │ (Clojure) │ │ (Svelte) │
└─────────────────┘ │ │ └─────────────────┘
│ ┌─────────────────┐ │
┌─────────────────┐ │ │ SQLite + DB │ │
│ OpenCode │<--->│ │ Abstraction │ │
│ (CLI) │ │ │ WebSocket/SSE │ │
└─────────────────┘ │ └─────────────────┘ │
└─────────────────────────┘
Your Phone/Browser <-> Spiceflow Server <-> Claude Code CLI (on your computer)
```
## Quick Start
### Prerequisites
- Clojure CLI (deps.edn)
- Node.js 18+ and pnpm
- SQLite
### Server
```bash
cd server
clj -M:run
./script/dev # Start everything
# Backend: http://localhost:3000
# Frontend: http://localhost:5173
```
The server will start on http://localhost:3000.
## Architecture
### Client
```bash
cd client
pnpm install
pnpm dev
```
┌─────────────────┐ HTTP/WS ┌──────────────────┐ stdin/stdout ┌─────────────────┐
│ Your Browser │ <──────────────> │ Spiceflow │ <─────────────────> │ Claude Code │
│ (SvelteKit) │ │ Server (Clojure)│ │ CLI │
└─────────────────┘ └────────┬─────────┘ └─────────────────┘
v
┌─────────────────┐
│ SQLite DB │
└─────────────────┘
```
The client dev server will start on http://localhost:5173 with proxy to the API.
## Project Structure
### Production Build
```bash
# Build client
cd client
pnpm build
# Run server (serves static files from client/build)
cd ../server
clj -M:run
```
spiceflow/
├── server/ # Clojure backend (API, database, CLI integration)
├── client/ # SvelteKit frontend (PWA, UI components)
└── e2e/ # Playwright tests
```
## Key Concepts
| Concept | Description |
|---------|-------------|
| **Session** | A conversation with Claude Code. Has messages, settings, and working directory. |
| **Adapter** | Code that talks to a CLI (Claude, OpenCode, tmux). |
| **Permission** | When Claude wants to edit files or run commands, you must approve. |
## How a Message Flows
1. Browser sends POST to `/api/sessions/:id/send`
2. Server saves user message, starts CLI with `--resume`
3. Server sends message to CLI stdin
4. CLI outputs JSONL (one JSON per line)
5. Server parses JSONL, broadcasts via WebSocket
6. Browser shows streaming response
7. Server saves assistant message when done
## Features
### Permission Handling
When Claude Code requests permission for tools, Spiceflow intercepts and presents them for approval:
- **Accept**: Grant permission and continue
- **Deny**: Reject the request
- **Steer ("No, and...")**: Redirect Claude with alternative instructions
Supported tool types with human-readable descriptions:
- `Bash` - Shell commands (shows the command)
- `Write` - File creation (shows file path + diff preview)
- `Edit` - File modification (shows file path + diff preview)
- `WebFetch` - URL fetching (shows URL)
- `WebSearch` - Web searches (shows query)
- `NotebookEdit` - Jupyter notebook edits
- `Skill` - Slash command execution
When Claude wants to edit files or run commands:
- **Accept**: Allow the action
- **Deny**: Block it
- **Steer**: Say "No, but do this instead..."
### Auto-Accept Edits
Claude sessions can enable "Auto-accept edits" via the settings gear icon to automatically grant file operation permissions:
Enable in session settings to auto-approve `Write` and `Edit` tools only. Does not auto-approve `Bash`, `WebFetch`, etc.
- **Applies to**: `Write` and `Edit` tools only (file create/modify)
- **Does NOT apply to**: `Bash`, `WebFetch`, `WebSearch`, or other tools
- **Behavior**: Permission is recorded in message history (green "accepted" status) without user interaction
- **Use case**: Reduces interruptions during coding sessions when you trust Claude to make file changes
## Tech Stack
### Real-time Streaming
Messages stream in real-time via WebSocket with:
- Content deltas as Claude types
- Permission request notifications
- Working directory updates
- Session status changes
## API Endpoints
| Method | Path | Description |
|--------|------|-------------|
| GET | `/api/health` | Health check |
| GET | `/api/sessions` | List all tracked sessions |
| POST | `/api/sessions` | Create/import a session |
| GET | `/api/sessions/:id` | Get session with messages |
| DELETE | `/api/sessions/:id` | Delete a session |
| POST | `/api/sessions/:id/send` | Send message to session |
| GET | `/api/discover/claude` | Discover Claude Code sessions |
| GET | `/api/discover/opencode` | Discover OpenCode sessions |
| POST | `/api/import` | Import a discovered session |
| WS | `/api/ws` | WebSocket for real-time updates |
| Layer | Technology |
|-------|------------|
| Backend | Clojure 1.11, Ring/Jetty, Reitit, SQLite |
| Frontend | SvelteKit 2.5, Svelte 4, TypeScript, Tailwind |
| Testing | Playwright, Kaocha |
## Development
### Running Tests
```bash
# Server tests
cd server
clj -M:test
# Backend
cd server && clj -M:dev # REPL: (go), (reset), (stop)
clj -M:test # Unit tests
# Client type checking
cd client
pnpm check
```
# Frontend
cd client && npm run dev # Dev server
npm run check # TypeScript
### Project Structure
```
spiceflow/
├── server/ # Clojure backend
│ ├── deps.edn
│ ├── src/spiceflow/
│ │ ├── core.clj # Entry point
│ │ ├── config.clj # Configuration
│ │ ├── db/
│ │ │ ├── protocol.clj # DataStore protocol
│ │ │ ├── sqlite.clj # SQLite implementation
│ │ │ └── memory.clj # In-memory impl for tests
│ │ ├── adapters/
│ │ │ ├── protocol.clj # AgentAdapter protocol
│ │ │ ├── claude.clj # Claude Code adapter
│ │ │ └── opencode.clj # OpenCode adapter
│ │ ├── api/
│ │ │ ├── routes.clj # REST endpoints
│ │ │ └── websocket.clj # WebSocket handlers
│ │ └── session/
│ │ └── manager.clj # Session lifecycle
│ └── test/spiceflow/
├── client/ # SvelteKit PWA
│ ├── src/
│ │ ├── routes/ # SvelteKit routes
│ │ └── lib/
│ │ ├── api.ts # API client
│ │ ├── stores/ # Svelte stores
│ │ └── components/ # UI components
│ └── static/ # PWA assets
└── README.md
# E2E
cd e2e && npm test # Run tests
npm run test:ui # Interactive
```
## Configuration
### Server
Configuration via `resources/config.edn` or environment variables:
Environment variables or `server/resources/config.edn`:
| 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 |
### PWA Icons
Generate PWA icons from the SVG favicon:
```bash
cd client/static
# Use a tool like svg2png or imagemagick to generate:
# - pwa-192x192.png
# - pwa-512x512.png
# - apple-touch-icon.png (180x180)
```
## License
MIT
| `SPICEFLOW_DB` | spiceflow.db | SQLite path |
| `CLAUDE_SESSIONS_DIR` | ~/.claude/projects | Claude sessions |