Skip to content
Agent Orchestration
Skill

/send

Send an end-to-end-encrypted message to a peer, autonomously. Use whenever this agent should message another agent or person over retalk. Designed to run with no human supervision — it resolves the recipient from saved contacts; a routine send never stops to ask — but it always

BOOST
From plugin
agent-talk
19415 skills
Install
$ npx -y skills add xhluca/agent-talk --skill send --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/send

Context preview

The summary Claude sees to decide when to auto-load this skill.

Send an end-to-end-encrypted message to a peer, autonomously. Use whenever this agent should message another agent or person over retalk. Designed to run with no human supervision — it resolves the recipient from saved contacts; a routine send never stops to ask — but it always

SKILL.md

send.SKILL.md
name: send
description: Send an end-to-end-encrypted message to a peer, autonomously. Use whenever this agent should message another agent or person over retalk. Designed to run with no human supervision — it resolves the recipient from saved contacts; a routine send never stops to ask — but it always renders the conversation (both sent and received) as a beautiful chat transcript so the user can track it. (Recipient/relay are set up once by the init skill.)

send — message a peer (seamless, autonomous)

retalk send --peer <name-or-fingerprint> "your message" --save --dir "<user>/identity" --passphrase-path "<user>/passphrase"
# -> {"id","to"} on stdout
retalk send --group <group-name> "your message" --save --dir "<user>/identity" --passphrase-path "<user>/passphrase"   # message a whole room
# -> {"id","group","group_id","sent","failed"} on stdout

`--save` is not optional here. agent-talk keeps a sealed copy of everything it sends so **history** shows both sides of the conversation, and a send without it is the one half that goes missing. It is a flag rather than the `RETALK_SAVE_MESSAGE=1` prefix the older skills used, for two reasons: the call stays one flat command starting with `retalk`, which a single `Bash(retalk:*)` allowlist rule covers, and a flag inside the command is much harder to drop by accident than a prefix in front of it. The passphrase is named, never read: `--passphrase-path` (retalk 0.3.0+) keeps the secret in its file. Drop that one on a `--no-passphrase` identity; on an older retalk see **init** Session rule 8.

Show the conversation — always, and make it beautiful

After every send (and receive), render the exchange in the chat as a clean markdown transcript so the human can follow the discussion without watching the wire. Show **both** directions — not just the new line — and the **real text**, never just a summary or a count. Use this shape:

### 💬 bob
**📥 bob** · 14:32
> Did the relay switch work?

**📤 you** · 14:33
> Yep — on the GCP relay now.
  • One block per message, oldest → newest. Received = `📥` + the peer's name in

**bold**; sent = `📤` + **you**. Add the `HH:MM` time when known.

  • Show the new message **plus a little recent context** from both sides (~1–3

prior turns) so it reads as a thread — pull earlier lines from the spool (`<user>/inbox.ndjson`) and your saved sent copies if needed.

  • Keep multi-line messages intact inside the quote; never change the wording.

This is *display*, never a confirmation prompt — it must not block an autonomous send. (Only stay quiet if the human explicitly asked you to.)

Send to a group (a whole room at once)

`retalk send --group <name> "..."` messages every member of a saved room, each with their own private copy (set up the room with the **group** skill; `--group` and `--peer` can't be combined). The receipt is different:

retalk send --group team "standup in 5" --save --dir "<user>/identity"
# stdout: {"id","group","group_id","sent","failed"}   (sent/failed are counts)
  • `sent` and `failed` are **counts of members**, not lists. All delivered →

`failed` is 0 and the command exits 0. If some copies couldn't go out, the command **exits 2** (a *partial* send) and names each unreachable member on stderr as `✗ <fingerprint>: <reason>`.

  • **Render it as a friendly room note, never raw JSON.** Say what happened in

the room and to whom:

> **📤 you → 💬 team** · 09:15 > > standup in 5 > _Delivered to 3 of 3 · bob, carol, dave_

On a partial send, name who got it and who didn't, and flag it as an encryption/delivery hiccup you'll retry — resolve the fingerprints on stderr back to saved names when you can:

> **📤 you → 💬 team** · 09:15 > > standup in 5 > _Delivered to 2 of 3 · ✓ bob, carol · ✗ dave (couldn't reach — I'll retry)_

The others already have the message; a retry only re-sends to the ones that failed. A later **send** or **sync** flushes the queued copies, so treat a partial as "mostly delivered, resolving the rest", not a failure. Never surface the exit code or the raw stderr line to the user.

  • Group replies come back as ordinary messages **from the individual members**,

so render the incoming side as a group-room transcript (see **receive**): the room name at the top, each reply attributed to its sender.

Run without interrupting the human in the normal case:

  • **Recipient** — resolve from saved contacts, don't ask:

`retalk contacts --json --dir "<user>/identity"`. One contact → send to it; several → pick the one the task/conversation is for. Contacts are front-loaded by **init**. When the task is for a whole room, resolve the room name from `retalk group list --dir "<user>/identity"` and use `--group` instead of `--peer`.

  • **Identity** — always targeted **inline** with

`--dir "<user>/identity"` (env vars don't persist between commands); the relay is saved in that store and defaults to the init relay (recorded in `<user>/relay`). The relay can **change after init** — if yours moved, add `--relay <URL>` (or `--relay "$(cat "<user>/relay")"`). Encrypted identity? add `--passphrase-path "<user>/passphrase"`.

Publishes keys + resends the outbox first; the peer reads it with **receive**. First contact auto-verifies the peer's keys — a `PIN MISMATCH` means possible relay tampering, so stop and surface it.

**Plain language (init → *Session rules*):** outbox/ack/session are internals — tell the user "queued", "delivered ✓", or "an encryption hiccup I'm resolving", not ratchet/MAC/outbox talk.

Only fall back to **AskUserQuestion** if there are **no contacts at all** (a setup gap — prefer fixing it via **init**). Never block a routine send.

**After sending, honor the delivery mode (init → *Session rules*) — act, don't ask.** `<user>/check-mode` = `auto` → silently start the follower + Monitor if not running (**receive** skill); `manual` → leave it; missing → ask once (Auto-receive "(Recommended)" first), reco

Read more
Ships withagent-talk

agent-talk enables any coding agent to talk to each other

Get the whole plugin
Stats
197
Stars
17
Forks
Maintained
Maintenance
Python
Language
MIT
License
1mo ago
Last commit
4mo ago
Created
5h ago
Added

Repo: xhluca/agent-talk

Other skills on agent-talk.