docs: add CLI architecture and usage documentation

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Sprite 2026-02-08 00:49:09 +00:00
parent 26b70cc792
commit 9772fb5c02

366
cli/README.md Normal file
View file

@ -0,0 +1,366 @@
# Spawn CLI
The spawn CLI is a command-line tool for launching AI coding agents on cloud providers, pre-configured with OpenRouter.
## Overview
The spawn CLI provides a unified interface to:
- Launch any supported AI agent (Claude Code, Aider, etc.) on any supported cloud provider
- Interactively browse available agents and clouds
- View the agent × cloud compatibility matrix
- Self-update to the latest version
## Architecture
### Three-Tier Installation Strategy
The CLI uses a progressive fallback installation strategy to maximize compatibility:
```
┌─────────────────────────────────────────────────────────┐
│ Method 1: Bun (Preferred) │
│ - Fastest execution (native TypeScript runtime) │
│ - Full TypeScript support with minimal overhead │
│ - Falls back to compiled binary if global install fails │
└─────────────────────────────────────────────────────────┘
↓ (if bun not found)
┌─────────────────────────────────────────────────────────┐
│ Method 2: npm │
│ - Standard Node.js package manager │
│ - Transpiles TypeScript to JavaScript at install time │
│ - Requires Node.js runtime │
└─────────────────────────────────────────────────────────┘
↓ (if npm not found)
┌─────────────────────────────────────────────────────────┐
│ Method 3: Bash Fallback │
│ - Pure bash implementation (spawn.sh) │
│ - Zero runtime dependencies except curl + jq/python3 │
│ - Functional subset of TypeScript CLI │
└─────────────────────────────────────────────────────────┘
```
**Why this pattern?**
- **Universal compatibility**: Works on any system with bash and curl
- **Optimal performance**: Uses the fastest available runtime (bun > node > bash)
- **Zero friction**: No prerequisite installation required for basic usage
- **Graceful degradation**: Each tier provides full functionality with varying performance characteristics
### Directory Structure
```
cli/
├── src/
│ ├── index.ts # Entry point (routes commands to handlers)
│ ├── commands.ts # All command implementations
│ ├── manifest.ts # Manifest fetching and caching logic
│ └── version.ts # Version constant
├── install.sh # Multi-tier installer script
├── spawn.sh # Bash fallback CLI (full implementation)
├── package.json # npm package metadata
└── tsconfig.json # TypeScript configuration
```
### TypeScript Implementation
The TypeScript CLI (`src/*.ts`) provides:
- **Interactive mode**: Terminal UI with prompts for selecting agents and clouds
- **Manifest caching**: Local cache with TTL to minimize network requests
- **Progress indicators**: Spinners and colored output for better UX
- **Error handling**: Structured error messages and exit codes
**Key dependencies:**
- `@clack/prompts` — Interactive terminal prompts
- `picocolors` — Terminal color support
### Bash Fallback Implementation
The bash CLI (`spawn.sh`) is a standalone script that:
- Implements the same commands as the TypeScript version
- Uses `jq` or `python3` for JSON parsing (auto-detects which is available)
- Provides a numbered menu picker for interactive mode
- Maintains local manifest cache with TTL
- Supports all core commands: `list`, `agents`, `clouds`, `run`, `improve`, `update`
**Why maintain both implementations?**
- **Portability**: Bash version works on minimal systems (CI containers, embedded Linux, etc.)
- **Bootstrap**: Used by installer when bun/npm aren't available
- **Reference**: Demonstrates that the protocol is runtime-agnostic
## Installation
### Quick Install
```bash
curl -fsSL https://raw.githubusercontent.com/OpenRouterTeam/spawn/main/cli/install.sh | bash
```
The installer will:
1. Check for `bun` → install via `bun install -g` if found
2. Check for `npm` → install via `npm install -g` if found
3. Fallback → download `spawn.sh` to `$HOME/.local/bin` if neither found
### Environment Variables
- `SPAWN_INSTALL_DIR` — Override install directory (default: `$HOME/.local/bin` for fallback method)
### Manual Installation (Development)
```bash
cd cli
bun install
bun link
```
Or build a standalone binary:
```bash
bun run compile # Creates ./spawn executable
```
## Usage
### Interactive Mode
```bash
spawn
```
Launches an interactive picker to select an agent and cloud provider.
### Direct Launch
```bash
spawn <agent> <cloud>
```
Examples:
```bash
spawn claude sprite # Launch Claude Code on Sprite
spawn aider hetzner # Launch Aider on Hetzner Cloud
```
### Agent Information
```bash
spawn <agent>
```
Show which cloud providers support the specified agent.
Example:
```bash
spawn claude
# Output:
# Claude Code — AI coding agent from Anthropic
#
# Available clouds:
# Sprite spawn claude sprite
# Hetzner Cloud spawn claude hetzner
```
### List All Combinations
```bash
spawn list
```
Display the full agent × cloud compatibility matrix.
### List Agents
```bash
spawn agents
```
Show all available agents with descriptions.
### List Cloud Providers
```bash
spawn clouds
```
Show all available cloud providers with descriptions.
### Improve Command
```bash
spawn improve [--loop]
```
Clone (or update) the spawn repository and run the `improve.sh` script, which uses Claude to autonomously add missing matrix entries or new agents/clouds.
### Update CLI
```bash
spawn update
```
- **TypeScript version**: Displays update instructions (re-run installer)
- **Bash version**: Self-updates by downloading the latest `spawn.sh`
### Version
```bash
spawn version
```
Display the current CLI version.
## Development
### Prerequisites
- Bun 1.0+ (or Node.js 18+ with npm)
- TypeScript 5.0+
### Running Locally
```bash
bun run dev # Run TypeScript CLI directly
bun run build # Build to cli.js
bun run compile # Compile to standalone binary
```
### Testing
```bash
# Test TypeScript version
bun run dev list
bun run dev agents
bun run dev claude sprite
# Test bash version
bash spawn.sh list
bash spawn.sh agents
bash spawn.sh claude sprite
```
### Code Organization
**`src/index.ts`**
- Command-line argument parsing
- Routes to appropriate command handler
- Minimal logic (just dispatching)
**`src/commands.ts`**
- All command implementations
- Interactive picker UI
- Script execution logic
- Help text
**`src/manifest.ts`**
- Manifest fetching from GitHub
- Local caching with TTL
- Offline fallback to stale cache
- Typed manifest structure
**`src/version.ts`**
- Single source of truth for version number
- Imported by both TypeScript and bash implementations
### Adding a New Command
1. Add command handler in `src/commands.ts`:
```typescript
export async function cmdMyCommand() {
const manifest = await loadManifest();
// ... implementation
}
```
2. Add routing in `src/index.ts`:
```typescript
case "mycommand":
await cmdMyCommand();
break;
```
3. Update help text in `src/commands.ts``cmdHelp()`
4. (Optional) Add equivalent implementation to `spawn.sh` for bash fallback
## Design Rationale
### Why TypeScript?
- **Type safety**: Manifest structure is type-checked at compile time
- **Modern async/await**: Clean, readable asynchronous code
- **Rich ecosystem**: Access to high-quality CLI libraries (`@clack/prompts`, etc.)
- **Single codebase**: Same code runs on bun, node, or as a compiled binary
### Why Bash Fallback?
- **Universality**: Bash is available on virtually all Unix-like systems
- **Zero dependencies**: Only requires `curl` and `jq`/`python3` (one of which is usually installed)
- **CI/CD friendly**: Works in minimal Docker containers, GitHub Actions, etc.
- **Educational**: Demonstrates the protocol can be implemented in any language
### Why Bun → npm → Bash Tiering?
- **Performance gradient**: Bun is fastest, npm is widely available, bash always works
- **User experience**: Bun users get instant execution, others get working tool
- **Distribution**: Can be installed via package manager or curl | bash
- **Maintenance**: Single TypeScript codebase serves bun and npm, bash is separate but synchronized
## Manifest Caching
Both implementations cache the manifest locally to reduce network requests:
- **Cache location**: `$XDG_CACHE_HOME/spawn/manifest.json` (or `~/.cache/spawn/manifest.json`)
- **TTL**: 1 hour (3600 seconds)
- **Offline fallback**: If fetch fails, uses stale cache if available
- **Invalidation**: `spawn update` clears the cache
## Script Execution Flow
When you run `spawn <agent> <cloud>`:
1. **Load manifest**: Fetch from GitHub or use cached version
2. **Validate combination**: Check that `matrix["<cloud>/<agent>"]` is `"implemented"`
3. **Download script**: Fetch `https://openrouter.ai/lab/spawn/<cloud>/<agent>.sh`
- Fallback to GitHub raw URL if OpenRouter CDN fails
4. **Execute**: Pipe script to `bash -c` with inherited stdio
5. **Interactive handoff**: User interacts directly with the spawned agent
## Contributing
### Before Submitting Changes
1. Test both TypeScript and bash versions:
```bash
bun run dev --help
bash spawn.sh --help
```
2. Ensure version numbers are synchronized:
- `src/version.ts``VERSION`
- `spawn.sh``SPAWN_VERSION`
- `package.json``version`
3. Update this README if you add new commands or change behavior
4. Run the installer locally to verify the three-tier strategy works:
```bash
# Test with bun
bash install.sh
# Test without bun (rename temporarily)
mv $(which bun) $(which bun).bak
bash install.sh
mv $(which bun).bak $(which bun)
```
### Release Checklist
1. Bump version in all three locations (see above)
2. Update CHANGELOG (if exists)
3. Test installer on clean system
4. Tag release: `git tag -a cli-vX.Y.Z -m "Release vX.Y.Z"`
5. Push tag: `git push --tags`
## License
See repository root for license information.