# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Project Overview **kvs-sh** is an interactive CLI shell for the KVS (Key-Value Store) distributed database. Think `mongosh`, `psql`, or `redis-cli` but for KVS. Single Go file implementation (~600 lines) with readline support for command history and auto-completion. ## KVS Server Reference The complete KVS server source code is located at `../kvs/` relative to this repository. Reference it when: - Understanding API contracts and response formats - Verifying authentication/authorization behavior - Checking endpoint paths and HTTP methods - Understanding data structures (StoredValue, Member, User, Group types) - Implementing new shell commands for backend features Key server locations: - `../kvs/server/handlers.go` - All API endpoint implementations - `../kvs/server/routes.go` - Route definitions and HTTP methods - `../kvs/types/types.go` - Canonical type definitions (StoredValue, etc.) - `../kvs/auth/` - JWT authentication and permission system details - `../kvs/README.md` - Complete API documentation with curl examples - `../kvs/CLAUDE.md` - Server architecture and development guidance When adding new commands to kvs-sh, always verify the actual backend implementation in `../kvs/` rather than making assumptions about API behavior. ## Build & Run ```bash # Build go build -o kvs-shell # Run ./kvs-shell # Install to system go install ``` ## Quick Start with Server ```bash # 1. Start KVS server (in ../kvs/) cd ../kvs && ./kvs config.yaml # 2. Run shell ./kvs-shell # 3. In shell: # connect http://localhost:8080 # auth $KVS_ROOT_TOKEN # put test/data '{"hello":"world"}' ``` **Important:** If auth fails with "token not found", the database has old data. Either: - Create a new token via the API, or - Wipe database: `rm -rf ../kvs/data && mkdir ../kvs/data` (restart server to generate root token) ## Testing ```bash go test ./... ``` ## Architecture ### Single-File Design Everything lives in `main.go` - intentionally kept simple. The shell is a stateful REPL that maintains: - HTTP client connection to KVS backend - Current JWT auth token - In-memory profile storage (username, token, server URL combinations) - Active profile selection ### Core Components **KVSClient (main.go:49)**: Central state container holding: - `baseURL`: KVS server endpoint - `currentToken`: JWT for authentication - `profiles`: In-memory map of saved user profiles (NOT persisted to disk yet) - `httpClient`: Reusable HTTP client with 30s timeout **Command Router (main.go:465)**: Main loop uses switch statement on first word of input, delegates to `handle*` methods **Command Parser (main.go:527)**: Custom parser respecting quotes - critical for JSON arguments like `put key '{"foo": "bar"}'` **Auto-completion (main.go:503)**: Prefix tree using readline library for tab completion of commands ### HTTP Communication Pattern All API calls go through `doRequest()` (main.go:85) which: 1. Serializes body to JSON if present 2. Sets `Authorization: Bearer ` header if token exists 3. Returns `(body, statusCode, error)` tuple 4. Delegates HTTP status interpretation to caller ### Key Backend API Mappings - `GET /kv/` → Returns `StoredValue` with UUID, timestamp, data - `PUT /kv/` → Accepts raw JSON, returns UUID + timestamp - `DELETE /kv/` → Returns 204 on success - `GET /members/` → Returns array of cluster `Member` objects - `GET /api/users/` → Returns `User` object - `GET /health` → Returns service status map ### Type Definitions (main.go:18-46) Backend response structures are mirrored in the client: - `StoredValue`: The core KV response with UUID, timestamp (int64 unix millis), and `json.RawMessage` data - `Member`: Cluster member info with ID, address, last_seen timestamp - `User`: User record with nickname hash, groups array, created/updated timestamps - `Group`: Group definition (defined but not yet used in commands) ### Profile System Profiles are in-memory only (see roadmap for persistence plan). When you `profile use `, it swaps the client's token, userUUID, and baseURL atomically. The `*` marker in profile listings indicates active profile. ### Color Scheme Uses fatih/color package with semantic coloring: - Cyan: labels, headers, structured data keys - Green: success messages, confirmations - Yellow: warnings, "not found" states - Red: errors, invalid usage - Magenta: banner/title text ### Command Parsing - Critical Implementation Details **parseCommand()** (main.go:527-570): Handles both single (`'`) and double (`"`) quotes intelligently. **Key behavior:** - Quotes are **only stripped** when they delimit an entire argument (start and end) - Supports both `'` and `"` as quote delimiters - Tracks which quote type started the argument to handle nesting correctly - Preserves quotes that appear mid-argument (for unquoted JSON) **Examples:** ```bash put key '{"foo":"bar"}' # ✅ Strips outer ', preserves inner " put key {"foo":"bar"} # ✅ Works (no spaces, compact JSON) put key {"foo": "bar"} # ❌ Fails - spaces split into multiple args put key "{\"foo\":\"bar\"}" # ✅ Works (escaped quotes in double-quoted arg) ``` **JSON Error Handling** (main.go:393-425): - `printJSONError()` provides user-friendly error messages with examples - Detects error type (invalid chars, incomplete JSON, etc.) and shows context-specific tips - Shows what input was received to help debug quoting issues ## Backend Assumptions The shell expects the KVS backend to: 1. Accept JWT tokens in `Authorization: Bearer ` header 2. Return timestamps as Unix milliseconds (int64) 3. Use standard REST semantics (404 for not found, 204 for delete, 200/201 for success) 4. Accept raw JSON payloads for PUT operations (not wrapped in metadata) ## Known Limitations & Roadmap Items 1. **No persistent profiles** - restart loses all `profile add` data (roadmap #1) 2. **No metadata commands** - backend supports owner/group/permissions but shell doesn't expose yet (roadmap #6) 3. **No group management** - `Group` type defined but no CRUD operations (roadmap #5) 4. **No TLS support** - HTTP only, no certificate handling (roadmap #8) 5. **No tab completion for keys** - only completes command names, not dynamic keys from server (roadmap #10) 6. **user create not implemented** - Listed in help but just shows "not implemented" message