$npx -y skills add Soul-Brews-Studio/arra-oracle-skills-cli --skill talk-toTalk to another Oracle agent via contacts + threads. Use when user says "talk to", "message", "chat with", or wants to communicate with another agent (e.g. "talk to pulse", "message neo"). Do NOT trigger for OracleNet social feed (use /oraclenet), skill management (use /oracle),
| 1 | # /talk-to - Agent Messaging |
| 2 | |
| 3 | Send messages to agents via Oracle threads. Each agent has a persistent channel thread. |
| 4 | |
| 5 | > **Messaging consolidation (2026-07-06):** /hey, /contacts, /mailbox, and /inbox were |
| 6 | > archived to the zombie tier — this skill is the one messaging verb now. For real-time |
| 7 | > tmux pings use `maw hey` directly (or `--maw` here). Archived skills remain installable |
| 8 | > via `arra install -s <name>`. |
| 9 | |
| 10 | ## Usage |
| 11 | |
| 12 | ``` |
| 13 | /talk-to arthur "What's your status?" # one-shot message |
| 14 | /talk-to arthur --new "Hey, starting fresh" # skip lookup, create new thread |
| 15 | /talk-to arthur loop ask about their work # autonomous conversation |
| 16 | /talk-to #42 "follow up on this" # post to thread by ID |
| 17 | /talk-to --list # show channels |
| 18 | /talk-to arthur --maw "quick ping" # force maw transport (real-time tmux) |
| 19 | /talk-to arthur --thread "async question" # force MCP thread transport |
| 20 | /talk-to arthur --inbox "offline message" # force inbox transport (file write) |
| 21 | ``` |
| 22 | |
| 23 | ## Mode 0: No arguments |
| 24 | |
| 25 | If ARGUMENTS is empty, show usage help then run --list. |
| 26 | |
| 27 | ## Step 0: Contacts Lookup |
| 28 | |
| 29 | **Always read contacts first.** This is the source of truth for agent routing. |
| 30 | |
| 31 | ```bash |
| 32 | date "+🕐 %H:%M %Z (%A %d %B %Y)" |
| 33 | CONTACTS="$(pwd)/ψ/contacts.json" |
| 34 | if [ ! -f "$CONTACTS" ]; then |
| 35 | # Fallback path |
| 36 | CONTACTS="$(pwd)/.oracle/contacts.json" |
| 37 | fi |
| 38 | |
| 39 | if [ -f "$CONTACTS" ]; then |
| 40 | MAW=$(jq -r ".contacts.\"$AGENT\".maw // empty" "$CONTACTS") |
| 41 | INBOX=$(jq -r ".contacts.\"$AGENT\".inbox // empty" "$CONTACTS") |
| 42 | THREAD=$(jq -r ".contacts.\"$AGENT\".thread // empty" "$CONTACTS") |
| 43 | REPO=$(jq -r ".contacts.\"$AGENT\".repo // empty" "$CONTACTS") |
| 44 | NOTES=$(jq -r ".contacts.\"$AGENT\".notes // empty" "$CONTACTS") |
| 45 | FOUND_IN_CONTACTS=true |
| 46 | else |
| 47 | FOUND_IN_CONTACTS=false |
| 48 | fi |
| 49 | ``` |
| 50 | |
| 51 | **If agent not found in contacts AND not found in maw ls**: |
| 52 | |
| 53 | ``` |
| 54 | I don't know "{agent}". |
| 55 | |
| 56 | /contacts add {agent} — register transport info |
| 57 | /talk-to {agent} --thread "message" — try MCP thread anyway |
| 58 | ``` |
| 59 | |
| 60 | Offer `/contacts add` first. If user insists, fall through to MCP thread. |
| 61 | |
| 62 | --- |
| 63 | |
| 64 | ## Transport Selection |
| 65 | |
| 66 | | Flag | Transport | Best For | |
| 67 | |------|-----------|----------| |
| 68 | | (none) | **auto** — detect best | Default | |
| 69 | | `--maw` | `maw hey` (tmux sendkeys) | Real-time, local fleet, low latency | |
| 70 | | `--thread` | MCP `oracle_thread` | Async, persistent, cross-machine | |
| 71 | | `--inbox` | File write to `ψ/inbox/` | Offline, no maw/MCP needed | |
| 72 | |
| 73 | **Auto-detect logic** (when no flag): |
| 74 | 1. Check `ψ/contacts.json` → has `maw` field? → use `maw hey` |
| 75 | 2. No contacts? → `maw ls 2>/dev/null | grep -q "{agent}"` fallback → use `maw hey` |
| 76 | 3. Neither? → use MCP thread (async, persistent) |
| 77 | |
| 78 | ```bash |
| 79 | # Auto-detect: contacts-first, maw ls fallback |
| 80 | if [ -n "$MAW" ]; then |
| 81 | echo "USE_MAW (from contacts: $MAW)" |
| 82 | elif maw ls 2>/dev/null | grep -q "{agent}"; then |
| 83 | echo "USE_MAW (from maw ls)" |
| 84 | else |
| 85 | echo "USE_THREAD" |
| 86 | fi |
| 87 | ``` |
| 88 | |
| 89 | When using `--maw`: |
| 90 | 1. Compose message from intent |
| 91 | 2. Use contacts maw name if available: `maw hey {MAW or agent-oracle} '{message}'` |
| 92 | 3. Optionally `maw peek {agent}` to check response |
| 93 | 4. Confirm: `Sent via maw to {agent}` |
| 94 | |
| 95 | When using `--inbox`: |
| 96 | 1. Compose message from intent |
| 97 | 2. Check contacts for inbox path — if empty, error: `No inbox path for {agent}. Run /contacts show {agent}` |
| 98 | 3. Write message file: |
| 99 | ```bash |
| 100 | SELF="$(basename $(pwd) | sed 's/-oracle$//')" |
| 101 | echo "$MESSAGE" > "$INBOX/$(date +%Y%m%d_%H%M)_from_${SELF}.md" |
| 102 | ``` |
| 103 | 4. Confirm: `Dropped to {agent}'s inbox` |
| 104 | |
| 105 | When using `--thread` (or auto-detected thread): |
| 106 | Fall through to Mode 3 (one-shot) below. |
| 107 | |
| 108 | ## Routing |
| 109 | |
| 110 | | Pattern | Use | |
| 111 | |---------|-----| |
| 112 | | `channel:{agent}` | Persistent per-agent channel | |
| 113 | | `topic:{agent}:{slug}` | Topic-specific thread (with `--topic`) | |
| 114 | | `#{id}` | Direct thread reference by ID | |
| 115 | |
| 116 | ## Mode 1: --list |
| 117 | |
| 118 | 1. `arra_threads()` (no status filter) |
| 119 | 2. Filter titles starting with `channel:` or `topic:`, exclude `closed` |
| 120 | 3. Display: `channel:arthur (#42) pending — 12 msgs` |
| 121 | |
| 122 | ## Mode 2: --new (fast create) |
| 123 | |
| 124 | Skip lookup. One MCP call. |
| 125 | |
| 126 | 1. Compose message from intent |
| 127 | 2. `arra_thread({ title: "channel:{agent}", message, role: "human" })` |
| 128 | 3. **Notify**: `Bash maw hey {MAW or agent-oracle} 'Thread #{id} from {self}: {preview}'` |
| 129 | - If `maw hey` fails → warn only, don't error (thread already sent) |
| 130 | 4. Confirm: `Created channel:{agent} (thread #{id})` |
| 131 | |
| 132 | ## Mode 3: One-shot (default) |
| 133 | |
| 134 | 1. Compose message from intent |
| 135 | 2. If first arg is `#{id}` → post directly to that thread ID |
| 136 | 3. Otherwise: `arra_threads()` → find `channel:{agent}`, create if |