From d0ae31c24c3c98ae89eebd67227c0c0d01606ed5 Mon Sep 17 00:00:00 2001 From: Clawd Date: Sat, 11 Apr 2026 20:43:41 -0700 Subject: Add ship-* Claude skills and plan Introduces a skills/ directory with 8 Claude skills that reimagine ship as a set of composable, human-driven deployment tools backed by Claude's reasoning rather than a rigid CLI. Skills: - ship-setup: one-time VPS config, saves host to ~/.config/ship/config.json - ship-status: derives live state from server, no local state file - ship-env: read/write env vars with merge semantics, never overwrites - ship-binary: deploy Go binaries with SQLite backup, correct restart behavior - ship-caddy: manage per-app Caddyfile with validate-before-reload - ship-service: systemd management and log inspection - ship-static: rsync static sites with SPA routing support - ship-deploy: orchestration runbook tying the others together Also adds SKILLS_PLAN.md documenting the architecture and rationale. Co-Authored-By: Claude Sonnet 4.6 --- SKILLS_PLAN.md | 135 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+) create mode 100644 SKILLS_PLAN.md (limited to 'SKILLS_PLAN.md') diff --git a/SKILLS_PLAN.md b/SKILLS_PLAN.md new file mode 100644 index 0000000..ded2b38 --- /dev/null +++ b/SKILLS_PLAN.md @@ -0,0 +1,135 @@ +# Ship Skills — Reimagining Ship as Claude Skills + +## The Idea + +Rather than a monolithic CLI that bakes in rigid assumptions, ship becomes a family of +narrow, composable Claude skills. Each skill knows how to do one thing well. Claude +provides the reasoning and orchestration. The server is the source of truth. + +Skills are completely generic — no hostnames, app names, or passwords baked in. The +same skills work for anyone. Share them with a friend, point them at a different VPS, +they just work. + +## Shared Configuration + +A single static file at `~/.config/ship/config.json` holds the VPS host (and little +else). All skills read from this file. No vault dependency — works for anyone. + +```json +{ + "host": "ubuntu@1.2.3.4", + "domain": "example.com" +} +``` + +The server itself is the source of truth for everything else — what services are +running, what ports are allocated, what Caddy configs exist. No local state file that +can go stale. + +## The Skills + +### `ship-setup` +One-time setup. Asks for VPS host if not configured, saves to `~/.config/ship/config.json`, +SSHes in and installs server dependencies (Caddy, directory structure, etc). +All other skills depend on this having been run once. + +### `ship-status` +Derives current state entirely from the server at runtime: +- Running apps → `systemctl list-units --type=service` +- Ports → `/etc/ship/ports/` or env files +- Domains → parse Caddy configs in `sites-enabled/` +- Static sites → list `/var/www/` + +No state file needed. Always accurate. Replaces the need for any local tracking. + +### `ship-env` +Read and write env vars with merge semantics. Never overwrites — reads existing file +first, merges new values on top, writes result. Old vars survive redeployments. + +### `ship-caddy` +Manage per-app Caddyfile config. Knows Caddy syntax. Diffs before writing. Validates +before reloading. Never regenerates from scratch — only touches what needs changing. + +### `ship-service` +Systemd management. Handles the difference between a new service (enable + start) and +an existing one (restart). Status, logs, restart, stop — all covered. + +### `ship-binary` +Upload and install a pre-built binary. SCP to `/tmp`, move to `/usr/local/bin/`, +chmod +x, set up work directory and service user. Calls `ship-service` and `ship-env` +to complete the deployment. + +### `ship-static` +Rsync a local dist folder to `/var/www/{name}` on the server. Calls `ship-caddy` to +configure serving. + +### `ship-deploy` +A runbook skill that orchestrates the others in the right order for a full deployment. +Not imperative code — just a checklist of steps with enough context for Claude to +reason about what to do. Adapts based on what the user tells it (binary vs static, +what env vars are needed, etc). + +## What the Server Knows + +All persistent state lives on the server in conventional locations: + +``` +/etc/caddy/sites-enabled/{name}.caddy # per-app Caddy config +/etc/ship/env/{name}.env # environment variables +/etc/ship/ports/{name} # allocated port number +/etc/systemd/system/{name}.service # systemd unit +/var/www/{name}/ # static site files +/var/lib/{name}/ # app work directory (binary, data) +/usr/local/bin/{name} # binary executable +``` + +## Why This Is Better Than the CLI + +- **Transparent** — Claude tells you what it's about to do before doing it +- **Flexible** — no rigid assumptions, Claude reasons about edge cases +- **Mergeable** — env files, Caddy configs never blindly overwritten +- **Debuggable** — if something goes wrong, just ask Claude to fix it +- **Shareable** — no app-specific knowledge baked in, works for anyone +- **No stale state** — server is always the source of truth + +## Per-App Notes (Optional) + +The server can't know things like "this app needs FOODTRACKER_PASSWORD on redeploy" +or "this app has SQLite at /var/lib/foodtracker/data/". That's documentation, not +state. Users can keep these as plain notes in whatever system they prefer — a vault, +a README, a comment in a script. The skills don't depend on it. + +## SQLite Backup + +Before swapping a binary, `ship-binary` checks `/var/lib/{name}/` for any `.db` files +and backs them up to `/var/lib/{name}/backups/{timestamp}.db` before proceeding. Silent +and automatic — you never lose data from a bad deploy. + +## Multi-Host Support + +Config supports multiple named hosts. One is marked as default. All skills use the +default unless told otherwise. + +```json +{ + "default": "prod", + "hosts": { + "prod": { + "host": "ubuntu@1.2.3.4", + "domain": "example.com" + }, + "staging": { + "host": "ubuntu@5.6.7.8", + "domain": "staging.example.com" + } + } +} +``` + +Usage is natural — "deploy foodtracker to staging" and Claude picks the right host. +`ship-setup` can be run multiple times to add new hosts. The default can be changed +at any time. + +## Out of Scope (For Now) + +- Health checks — skipping initially, can add later if needed -- cgit v1.2.3