Monorepo for Aesthetic.Computer aesthetic.computer
4
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 336 lines 9.1 kB view raw view rendered
1# help.aesthetic.computer — AI Agent Service Plan 2 3## Overview 4 5A Claude-powered AI assistant service for the Aesthetic Computer community. 6Users with AC handles can bring their own Anthropic API key and get AI help 7with pieces, KidLisp, creative computing, and more. 8 9**Domain:** `help.aesthetic.computer` 10**IP:** `146.190.150.173` 11**Droplet:** `help-aesthetic-computer` (ID: 552385566) 12**Specs:** 2 vCPU, 4GB RAM, Ubuntu 24.04, SFO3 (~$24/mo) 13**Status:** Live — landing page + Auth0 sign-in deployed 14 15--- 16 17## Architecture 18 19### No Container Isolation Needed 20 21Unlike NanoClaw (which runs Claude Code CLI with Bash/file access in containers), 22this service uses the Claude API with **server-controlled tools**. Users can't 23escape the defined tool set — no sandbox needed. 24 25### Stack 26 27- **Node.js 22 + Express** (same pattern as silo, oven) 28- **Caddy** (HTTPS reverse proxy, auto-certs) 29- **MongoDB** (via silo — user keys, conversation history, tool permissions) 30- **Systemd** (service management) 31- **Claude API** (`@anthropic-ai/sdk` npm package) 32 33### Auth Flow 34 351. User visits `help.aesthetic.computer` 362. Auth0 login (same as rest of AC) 373. User must have an `@handle` (registered AC user) 384. User provides their Anthropic API key in settings 395. Key stored encrypted in MongoDB 406. All Claude API calls use the user's own key 41 42### Landing Page 43 44The landing page explains: 45- What help.aesthetic.computer does 46- How to get an AC handle (if you don't have one) 47- How to get an Anthropic API key 48- How to connect your key 49- What tools/capabilities are available 50 51--- 52 53## Tool Allow/Deny Lists (RBAC) 54 55Tools are defined server-side and passed to the Claude API per-request 56based on user role. Users never see tools they don't have access to. 57 58### @jeffrey (admin) 59 60``` 61allow: [ 62 create-piece, # Create new .mjs or .lisp pieces 63 edit-piece, # Modify existing pieces 64 search-codebase, # Search AC source code 65 explain-piece, # Explain how a piece works 66 run-kidlisp, # Execute KidLisp code 67 system-status, # Check oven/silo/session health 68 manage-users, # View/manage user permissions 69 deploy, # Trigger deployments 70 raw-chat, # Unconstrained Claude conversation 71 search-docs, # Search AC documentation 72] 73deny: [] 74``` 75 76### Registered User (@handle) 77 78``` 79allow: [ 80 create-kidlisp, # Create KidLisp pieces in own namespace 81 fork-piece, # Fork existing pieces 82 search-docs, # Search AC documentation 83 explain-piece, # Explain how a piece works 84 raw-chat, # Claude conversation (with AC context) 85 my-pieces, # List/manage own published pieces 86] 87deny: [ 88 deploy, 89 system-status, 90 manage-users, 91 edit-piece (others'), 92 search-codebase, 93] 94``` 95 96### Anonymous (no handle, no key) 97 98``` 99allow: [ 100 search-docs, # Read-only doc search 101 explain-piece, # Explain public pieces 102] 103deny: [everything else] 104``` 105 106### Storage 107 108Tool permissions stored in MongoDB `help-permissions` collection. 109Editable from silo dashboard. Start with hardcoded defaults, 110make configurable later. 111 112--- 113 114## API Endpoints 115 116### Public 117 118| Endpoint | Method | Purpose | 119|----------|--------|---------| 120| `/` | GET | Landing page (HTML) | 121| `/health` | GET | Health check | 122| `/auth/config` | GET | Auth0 config for frontend | 123 124### Authenticated 125 126| Endpoint | Method | Purpose | 127|----------|--------|---------| 128| `/auth/me` | GET | Current user info + role | 129| `/api/settings` | GET/PUT | API key management | 130| `/api/chat` | POST | Send message to Claude (SSE streaming) | 131| `/api/conversations` | GET | List conversation history | 132| `/api/conversations/:id` | GET/DELETE | Get/delete conversation | 133| `/ws` | WebSocket | Real-time streaming (alternative to SSE) | 134 135### Admin Only (@jeffrey) 136 137| Endpoint | Method | Purpose | 138|----------|--------|---------| 139| `/api/admin/users` | GET | List users + their roles | 140| `/api/admin/permissions` | GET/PUT | Edit tool permissions | 141| `/api/admin/stats` | GET | Usage stats | 142 143--- 144 145## Claude API Integration 146 147### Per-Request Flow 148 149```javascript 150import Anthropic from '@anthropic-ai/sdk'; 151 152async function handleChat(user, message, conversationHistory) { 153 // Get user's API key from MongoDB (decrypted) 154 const apiKey = await getUserApiKey(user.sub); 155 156 // Get user's allowed tools based on role 157 const tools = getToolsForRole(user.role); 158 159 // Create client with user's key 160 const client = new Anthropic({ apiKey }); 161 162 // System prompt with AC context 163 const systemPrompt = buildSystemPrompt(user); 164 165 // Stream response 166 const stream = client.messages.stream({ 167 model: 'claude-sonnet-4-5-20250929', 168 max_tokens: 4096, 169 system: systemPrompt, 170 messages: [...conversationHistory, { role: 'user', content: message }], 171 tools, 172 }); 173 174 return stream; 175} 176``` 177 178### System Prompt 179 180The system prompt includes: 181- AC documentation context (from CLAUDE.md, piece API docs) 182- KidLisp reference (118 built-in functions) 183- User's role and permissions 184- Conversation instructions (be helpful, AC-aware) 185 186### Tool Definitions 187 188Each tool is a Claude API tool definition + a server-side handler: 189 190```javascript 191const TOOLS = { 192 'search-docs': { 193 definition: { 194 name: 'search_docs', 195 description: 'Search AC documentation and piece source code', 196 input_schema: { 197 type: 'object', 198 properties: { 199 query: { type: 'string', description: 'Search query' } 200 }, 201 required: ['query'] 202 } 203 }, 204 handler: async (input) => { 205 // Server-side: search docs, return results 206 // User can't escape this — it's just a search 207 } 208 }, 209 // ... more tools 210}; 211``` 212 213--- 214 215## Deployment 216 217### Provisioning Script 218 219Create `help/deploy.fish` following the judge/oven pattern: 220 2211. SSH into droplet (need to add SSH key first) 2222. Wipe judge files: `rm -rf /opt/judge`, stop ollama 2233. Install/update Node.js 22 2244. Create `/opt/help` directory 2255. Upload `server.mjs`, `dashboard.html`, `package.json`, `.env` 2266. Install npm dependencies 2277. Configure Caddy for `help.aesthetic.computer` 2288. Create systemd service `help` 2299. Start services 230 231### SSH Key 232 233The judge SSH key was generated on a different machine. Need to either: 234- Add the vault's `id_rsa.pub` to the droplet via DO API (console access) 235- Or destroy and recreate the droplet (fresh start, same IP not guaranteed) 236- Or use DO console to add a new key 237 238### Environment Variables 239 240```bash 241# MongoDB (via silo) 242MONGODB_CONNECTION_STRING=mongodb://aesthetic_app:...@silo.aesthetic.computer:27017/... 243MONGODB_NAME=aesthetic 244 245# Auth0 246AUTH0_DOMAIN=aesthetic.us.auth0.com 247AUTH0_CLIENT_ID=... 248AUTH0_CUSTOM_DOMAIN=hi.aesthetic.computer 249ADMIN_SUB=auth0|63effeeb2a7d55f8098d62f9 250 251# Encryption key for stored API keys 252ENCRYPTION_KEY=<generate new key> 253 254# Optional: fallback community API key 255ANTHROPIC_API_KEY=<for anonymous/shared use> 256``` 257 258--- 259 260## File Structure 261 262``` 263help/ 264├── server.mjs # Express API server 265├── dashboard.html # Landing page + chat UI 266├── tools/ # Tool definitions + handlers 267│ ├── search-docs.mjs 268│ ├── explain-piece.mjs 269│ ├── create-kidlisp.mjs 270│ ├── fork-piece.mjs 271│ └── system-status.mjs 272├── deploy.fish # Deployment script 273├── redeploy.fish # Quick update script 274├── package.json 275└── README.md 276``` 277 278Vault: 279``` 280aesthetic-computer-vault/help/ 281├── deploy.env # DO + Cloudflare credentials 282└── .env # MongoDB, Auth0, encryption keys 283``` 284 285--- 286 287## Relationship to NanoClaw 288 289The `/nanoclaw` submodule remains as **reference code** for: 290- Claude Agent SDK patterns (session management, tool execution) 291- How to build async message streams 292- IPC patterns between host and agent 293- Memory/context management via CLAUDE.md files 294 295We don't run NanoClaw — we build our own simpler service. 296 297--- 298 299## Infrastructure Summary 300 301| Service | Domain | IP | Purpose | 302|---------|--------|----|---------| 303| oven | oven.aesthetic.computer | 137.184.237.166 | Screenshot/video | 304| silo | silo.aesthetic.computer | 64.23.151.169 | DB dashboard | 305| session | session-server | 157.245.134.225 | Real-time multiplayer | 306| **help** | **help.aesthetic.computer** | **146.190.150.173** | **AI agent** | 307| system | aesthetic.computer | Netlify | Main site | 308 309--- 310 311## Phase Plan 312 313### Phase 1: Foundation (DONE) 314- [x] Recreated droplet with SSH key (destroyed old judge, new ID 552385566) 315- [x] Installed Node.js 22 + Caddy 2.10 316- [x] Built minimal Express server with Caddy reverse proxy 317- [x] Auth0 integration (same client as silo) 318- [x] Landing page with sign-in + API key input 319 320### Phase 2: Core Chat 321- [ ] API key storage (encrypted in MongoDB) 322- [ ] Claude API integration with streaming 323- [ ] Basic chat UI 324- [ ] Conversation history 325 326### Phase 3: Tools 327- [ ] search-docs tool 328- [ ] explain-piece tool 329- [ ] create-kidlisp tool 330- [ ] Role-based tool filtering 331 332### Phase 4: Community 333- [ ] Public launch 334- [ ] Usage analytics 335- [ ] Rate limiting 336- [ ] Admin dashboard in silo