$npx -y skills add Soul-Brews-Studio/arra-oracle-skills-cli --skill machinesFleet machines — discover nodes from contacts, ping to prove alive, create local shortcuts. Use when user says "machines", "nodes", "fleet", or wants to see/reach machines in the fleet.
| 1 | # /machines — Fleet Machines |
| 2 | |
| 3 | > Discover. Ping. Create shortcuts. All from contacts.json. |
| 4 | |
| 5 | ## Usage |
| 6 | |
| 7 | ``` |
| 8 | /machines # Discover nodes from contacts, ping all |
| 9 | /machines ping # Same — ping all, show who's alive |
| 10 | /machines list # List known nodes (no ping) |
| 11 | /machines setup # Ping → confirm → create /shortcuts for alive nodes |
| 12 | /machines <node> # Ping one node, show details |
| 13 | ``` |
| 14 | |
| 15 | --- |
| 16 | |
| 17 | ## Step 0: Discover Nodes from Contacts |
| 18 | |
| 19 | ```bash |
| 20 | date "+🕐 %H:%M %Z (%A %d %B %Y)" && ORACLE_ROOT=$(git rev-parse --show-toplevel 2>/dev/null) |
| 21 | if [ -n "$ORACLE_ROOT" ] && [ -f "$ORACLE_ROOT/CLAUDE.md" ] && { [ -d "$ORACLE_ROOT/ψ" ] || [ -L "$ORACLE_ROOT/ψ" ]; }; then |
| 22 | PSI="$ORACLE_ROOT/ψ" |
| 23 | else |
| 24 | ORACLE_ROOT="$(pwd)" |
| 25 | PSI="$ORACLE_ROOT/ψ" |
| 26 | fi |
| 27 | ``` |
| 28 | |
| 29 | Read `$PSI/contacts.json` and group contacts by node. The node is extracted from the `maw` field (everything before `:` in `maw hey node:agent`): |
| 30 | |
| 31 | ```bash |
| 32 | cat "$PSI/contacts.json" 2>/dev/null | python3 -c " |
| 33 | import json, sys |
| 34 | data = json.load(sys.stdin) |
| 35 | nodes = {} |
| 36 | for name, info in data.get('contacts', {}).items(): |
| 37 | maw = info.get('maw', name) |
| 38 | # Extract node: 'white:mawjs' → 'white', 'boonkeeper' → 'local' |
| 39 | node = maw.split(':')[0] if ':' in maw else 'local' |
| 40 | if node == name: |
| 41 | node = 'local' |
| 42 | if node not in nodes: |
| 43 | nodes[node] = [] |
| 44 | nodes[node].append({'name': name, 'notes': info.get('notes', '')}) |
| 45 | for node in sorted(nodes): |
| 46 | agents = ', '.join(a['name'] for a in nodes[node]) |
| 47 | print(f'{node} ({len(nodes[node])}): {agents}') |
| 48 | " |
| 49 | ``` |
| 50 | |
| 51 | **No hardcoded nodes.** Everything comes from contacts. |
| 52 | |
| 53 | --- |
| 54 | |
| 55 | ## Step 1: Ping (`/machines`, `/machines ping`) |
| 56 | |
| 57 | For each discovered node, pick one agent and send a ping via `maw hey`: |
| 58 | |
| 59 | ```bash |
| 60 | # For each non-local node, pick the first agent and ping |
| 61 | maw hey <node>:<first-agent> "ping from $(hostname) — alive?" 2>&1 |
| 62 | ``` |
| 63 | |
| 64 | For the local node, just run `maw ls`. |
| 65 | |
| 66 | Show results as a table: |
| 67 | |
| 68 | ``` |
| 69 | 🏗 Fleet Machines |
| 70 | |
| 71 | Node Status Oracles Ping Target |
| 72 | ────────────── ───────── ──────── ────────────── |
| 73 | local ✅ alive N maw ls |
| 74 | <node-1> ✅ alive N <agent> → delivered |
| 75 | <node-2> ⏳ waiting N <agent> → sent |
| 76 | <node-3> ❌ failed N <agent> → error |
| 77 | |
| 78 | Alive: X/Y confirmed |
| 79 | ``` |
| 80 | |
| 81 | If `maw hey` output contains "delivered", the node is alive. |
| 82 | |
| 83 | --- |
| 84 | |
| 85 | ## Step 2: Details (`/machines <node>`) |
| 86 | |
| 87 | Show all oracles on that node + how to talk: |
| 88 | |
| 89 | ``` |
| 90 | 🏗 <node> — N oracles |
| 91 | |
| 92 | Agent Notes Talk |
| 93 | ────────────── ───────────────────────────── ────────────────────────── |
| 94 | <agent-1> <notes from contacts> maw hey <node>:<agent-1> "..." |
| 95 | <agent-2> <notes from contacts> maw hey <node>:<agent-2> "..." |
| 96 | ``` |
| 97 | |
| 98 | --- |
| 99 | |
| 100 | ## Step 3: Setup (`/machines setup`) |
| 101 | |
| 102 | After pinging, offer to create local shortcuts: |
| 103 | |
| 104 | ``` |
| 105 | ✅ N nodes confirmed alive. Create machine shortcuts? |
| 106 | |
| 107 | /<node-1> → N oracles |
| 108 | /<node-2> → N oracles |
| 109 | ... |
| 110 | |
| 111 | Create all? [Y/n] |
| 112 | ``` |
| 113 | |
| 114 | **WAIT for user confirmation.** |
| 115 | |
| 116 | Then for each node, create `.claude/skills/<node>/SKILL.md` with: |
| 117 | - Node name + oracle list (from contacts) |
| 118 | - `maw hey <node>:<agent>` examples |
| 119 | - Notes from contacts.json |
| 120 | |
| 121 | These are LOCAL skills — gitignored, personal to each fleet. |
| 122 | |
| 123 | --- |
| 124 | |
| 125 | ## Step 4: List (`/machines list`) |
| 126 | |
| 127 | Show all known nodes without pinging: |
| 128 | |
| 129 | ``` |
| 130 | 🏗 Known Machines (from ψ/contacts.json) |
| 131 | |
| 132 | Node Oracles |
| 133 | ────────────── ──────────────────────────────── |
| 134 | local <comma-separated agents> |
| 135 | <node-1> <comma-separated agents> |
| 136 | <node-2> <comma-separated agents> |
| 137 | |
| 138 | 💡 /machines ping — check who's alive |
| 139 | 💡 /machines setup — create shortcuts |
| 140 | ``` |
| 141 | |
| 142 | --- |
| 143 | |
| 144 | ## Rules |
| 145 | |
| 146 | 1. **Discover from contacts** — never hardcode node names or IPs |
| 147 | 2. **Talk first** — always ping before claiming alive |
| 148 | 3. **Confirm before creating** — never auto-create without user approval |
| 149 | 4. **Local shortcuts** — created in .claude/skills/, gitignored |
| 150 | 5. **Generic** — works for ANY fleet, ANY nodes, ANY contacts.json |
| 151 | |
| 152 | --- |
| 153 | |
| 154 | ARGUMENTS: $ARGUMENTS |