aboutsummaryrefslogtreecommitdiffstats
path: root/skills/ship-status/SKILL.md
diff options
context:
space:
mode:
authorClawd <ai@clawd.bot>2026-04-11 20:43:41 -0700
committerClawd <ai@clawd.bot>2026-04-11 20:43:41 -0700
commitd0ae31c24c3c98ae89eebd67227c0c0d01606ed5 (patch)
treec684469e0f7d3b65477cfc631ecdaafa3c6a218a /skills/ship-status/SKILL.md
parent5548b36e0953c17dbe30f6b63c892b7c83196b20 (diff)
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 <noreply@anthropic.com>
Diffstat (limited to 'skills/ship-status/SKILL.md')
-rw-r--r--skills/ship-status/SKILL.md85
1 files changed, 85 insertions, 0 deletions
diff --git a/skills/ship-status/SKILL.md b/skills/ship-status/SKILL.md
new file mode 100644
index 0000000..f47e081
--- /dev/null
+++ b/skills/ship-status/SKILL.md
@@ -0,0 +1,85 @@
1---
2name: ship-status
3description: Show what's running on a ship VPS. Derives state from the server — no local state file. Use when you want to know what apps are deployed, what ports they use, and whether they're running.
4argument-hint: "[host-nickname]"
5---
6
7# ship-status
8
9Show the current state of all deployments on a ship VPS by reading directly from the server.
10
11## Read Config
12
13Load the host from `~/.config/ship/config.json`. Use the default host unless a nickname was specified:
14
15```bash
16python3 -c "
17import json, os, sys
18cfg = json.load(open(os.path.expanduser('~/.config/ship/config.json')))
19nick = sys.argv[1] if len(sys.argv) > 1 else cfg['default']
20h = cfg['hosts'][nick]
21print(h['host'])
22print(h['domain'])
23" <nickname-or-blank>
24```
25
26## Gather Server State
27
28Run all of these in a single SSH session to minimize round trips:
29
30**Systemd services (binary/docker apps):**
31```bash
32ssh <host> "systemctl list-units --type=service --state=active --no-pager --no-legend | grep -v '@' | awk '{print \$1}' | xargs -I{} sh -c 'name=\$(echo {} | sed s/.service//); port=\$(cat /etc/ship/ports/\$name 2>/dev/null); env=\$(cat /etc/ship/env/\$name.env 2>/dev/null | grep SHIP_URL | cut -d= -f2); echo \"\$name|\$port|\$env\"' 2>/dev/null | grep '|'"
33```
34
35**Static sites:**
36```bash
37ssh <host> "ls /var/www/ 2>/dev/null"
38```
39
40**Caddy configs (domains):**
41```bash
42ssh <host> "ls /etc/caddy/sites-enabled/ 2>/dev/null | grep -v '^$'"
43```
44
45**Caddy status:**
46```bash
47ssh <host> "systemctl is-active caddy"
48```
49
50**Disk usage for app data dirs:**
51```bash
52ssh <host> "du -sh /var/lib/*/ 2>/dev/null"
53```
54
55## Present Results
56
57Format as a clean summary, for example:
58
59```
60HOST: prod (ubuntu@1.2.3.4)
61
62SERVICES
63 foodtracker running :9013 https://foodtracker.example.com
64 myapi running :9014 https://api.example.com
65
66STATIC SITES
67 mysite https://mysite.example.com
68
69CADDY: running
70
71DATA
72 /var/lib/foodtracker/ 48M
73 /var/lib/myapi/ 2M
74```
75
76If a service appears in `/etc/ship/ports/` but is not active in systemd, flag it as **stopped**.
77
78If a Caddy config exists for a name but no service or static site matches, flag it as **orphaned config**.
79
80## Notes
81
82- No local state file is consulted — everything comes from the server
83- If `~/.config/ship/config.json` doesn't exist, tell the user to run `/ship-setup` first
84- If a nickname is given that doesn't exist in config, list available nicknames
85- Use default host if no argument given