From b021f5903abb2488ca36534e49a6c8392c194aad Mon Sep 17 00:00:00 2001 From: Clawd Date: Sun, 15 Feb 2026 18:18:29 -0800 Subject: docs: rename to SHIP_V2.md, JSON output is default not a flag --- AGENT_MODE.md | 271 ---------------------------------------------------------- 1 file changed, 271 deletions(-) delete mode 100644 AGENT_MODE.md (limited to 'AGENT_MODE.md') diff --git a/AGENT_MODE.md b/AGENT_MODE.md deleted file mode 100644 index 1f00d61..0000000 --- a/AGENT_MODE.md +++ /dev/null @@ -1,271 +0,0 @@ -# Ship Agent Mode - -**Goal:** Make ship the default deployment tool for AI agents building and shipping code. - -## Why Ship for Agents? - -Agents need to go from "code on disk" to "live URL" with zero friction. Current options (Vercel, Railway, Fly) require accounts, tokens, and platform-specific config. Ship only needs SSH access to a VPS. - -**Ship's advantages:** -- SSH-only — no accounts, no API tokens, no vendor lock-in -- Auto HTTPS via Caddy — agents don't deal with certs -- Auto subdomains — `--name foo` → `foo.example.com` -- Idempotent — same command updates existing deploy -- Docker support — any runtime works -- Stateless CLI — no daemon, no background process - -## Design Principles - -1. **Machine-parseable output** — JSON by default in agent mode -2. **Fail loud and clear** — explicit error codes, not ambiguous messages -3. **Verify deploys** — health checks confirm the app is actually running -4. **Self-cleaning** — ephemeral deploys auto-expire -5. **One command** — no multi-step workflows - -## Agent Mode Flag - -```bash -ship --agent [other flags] -``` - -When `--agent` is set: -- Output is JSON (no need for separate `--json`) -- Errors include machine-readable codes -- Health checks are enabled by default -- Progress is suppressed (no spinners, no "Uploading...") - -Alternatively, detect via environment: -```bash -SHIP_AGENT=1 ship --static --dir ./site --name preview -``` - -## Output Schema - -### Success - -```json -{ - "status": "ok", - "name": "preview", - "url": "https://preview.example.com", - "type": "static", - "took_ms": 4200, - "health": { - "checked": true, - "status": 200, - "latency_ms": 45 - } -} -``` - -### Error - -```json -{ - "status": "error", - "code": "DEPLOY_FAILED", - "message": "health check failed: connection refused", - "name": "preview", - "url": "https://preview.example.com", - "took_ms": 8500 -} -``` - -### Error Codes - -| Code | Meaning | -|------|---------| -| `SSH_CONNECT_FAILED` | Can't reach VPS | -| `SSH_AUTH_FAILED` | Key rejected | -| `UPLOAD_FAILED` | File transfer failed | -| `BUILD_FAILED` | Docker build or binary issue | -| `CADDY_RELOAD_FAILED` | HTTPS config failed | -| `HEALTH_CHECK_FAILED` | App not responding after deploy | -| `ALREADY_EXISTS` | Name collision (if --no-update) | -| `NOT_FOUND` | App doesn't exist (for status/logs) | - -## Health Checks - -After deploy, ship pings the app to verify it's running. - -```bash -ship --agent --static --dir ./site --name preview --health / -ship --agent --binary ./api --name api --health /healthz -``` - -**Behavior:** -- Wait up to 30s for first successful response -- Retry every 2s -- Accept any 2xx/3xx as success -- Return `HEALTH_CHECK_FAILED` if timeout - -**Default health path:** -- Static sites: `/` (just check 200) -- Apps: none (opt-in with `--health`) - -## Ephemeral Deploys - -Agents create lots of previews. They should auto-clean. - -```bash -ship --agent --static --dir ./site --name pr-123 --ttl 24h -``` - -**Implementation options:** - -1. **Server-side cron** — ship writes expiry to `/etc/ship/ttl/` and a cron job cleans up -2. **At-style scheduling** — `echo "ship remove pr-123" | at now + 24 hours` -3. **Client-side tracking** — agent is responsible for cleanup (less ideal) - -Option 1 is cleanest. The TTL file contains: -``` -expires_at=1708123456 -``` - -A systemd timer runs hourly and removes expired deploys. - -## Unique Name Generation - -For true previews, agents may want auto-generated names: - -```bash -ship --agent --static --dir ./site --preview -``` - -Output: -```json -{ - "status": "ok", - "name": "ship-a1b2c3", - "url": "https://ship-a1b2c3.example.com", - ... -} -``` - -Combines well with TTL: -```bash -ship --agent --static --dir ./site --preview --ttl 1h -``` - -## Simplified Deploy Command - -For maximum simplicity: - -```bash -# Auto-detect: static site (has index.html) or Dockerfile -ship --agent --dir ./myproject --preview --ttl 24h -``` - -Detection logic: -1. Has `Dockerfile` → Docker build -2. Has `index.html` or is static-looking → static site -3. Has single binary → binary deploy -4. Else → error with helpful message - -## Status & Logs - -```bash -ship --agent status myapp -``` - -```json -{ - "status": "ok", - "name": "myapp", - "url": "https://myapp.example.com", - "type": "docker", - "running": true, - "uptime_seconds": 3600, - "memory_mb": 128, - "cpu_percent": 2.5 -} -``` - -```bash -ship --agent logs myapp --lines 50 -``` - -```json -{ - "status": "ok", - "name": "myapp", - "lines": [ - {"ts": "2024-02-15T18:00:00Z", "msg": "Server started on :8080"}, - ... - ] -} -``` - -## List Deploys - -```bash -ship --agent list -``` - -```json -{ - "status": "ok", - "deploys": [ - {"name": "api", "url": "https://api.example.com", "type": "docker", "running": true}, - {"name": "preview-abc", "url": "https://preview-abc.example.com", "type": "static", "ttl_expires": "2024-02-16T18:00:00Z"}, - ... - ] -} -``` - -## Environment Variables - -```bash -ship --agent env set myapp DB_URL=postgres://... -``` - -```json -{ - "status": "ok", - "name": "myapp", - "action": "env_set", - "key": "DB_URL", - "restarted": true -} -``` - -## Implementation Phases - -### Phase 1: Core Agent Mode -- [ ] `--agent` flag for JSON output -- [ ] Structured error codes -- [ ] Health check support (`--health`) -- [ ] Fix JSON output for all commands (list, status, logs, env) - -### Phase 2: Ephemeral & Previews -- [ ] `--ttl` flag with server-side cleanup -- [ ] `--preview` for auto-generated names -- [ ] Auto-detection of project type - -### Phase 3: Polish -- [ ] `ship --agent init` for first-time VPS setup with JSON output -- [ ] Rollback support (`ship --agent rollback myapp`) -- [ ] Deploy history (`ship --agent history myapp`) - -## Open Questions - -1. **Should `--agent` be the default eventually?** Human-readable output could move to `--human` or `--pretty`. - -2. **Log streaming?** Agents might want `ship logs --follow` with JSON lines. Worth it? - -3. **Webhooks?** Notify a URL on deploy success/failure. Useful for CI integration. - -4. **Multi-host?** Agents deploying to different VPSes. Current `--host` flag works but could be smoother. - -## Success Metrics - -Ship is successful for agents when: -- Zero-config deploy from code to URL in <30s -- Agent can parse every output without regex -- Failed deploys have clear, actionable errors -- Preview deploys don't accumulate garbage -- Any language/framework works via Docker - ---- - -*This is a living document. Update as we build.* -- cgit v1.2.3