Skip to content
Back to skills

Muse

ASecurity

Use when collaborating with other agent sessions via the agent-peer IPC mesh — sending real-time messages or waiting reactively for incoming ones. Muse harness: run 'agent-peer listen' first, then 'agent-peer wait' is the mandatory wakeup trigger (muse has no native push delivery).

  • 2 stars
  • 0 votes
  • 1 copy
  • 3 views
  • Added September 27, 2026
ai-agentsgoshellbashreactgit

Works with

  • claude code
  • cursor
  • cli

Security analysis

A100/100

Pro scans all 2 files and shows the line behind each finding

Scanned October 1, 2026

npx -y skills add mkhuda/agent-peer --skill muse --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Muse?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Muse
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/mkhuda-muse/badge)](https://www.skillsdirectory.com/skills/mkhuda-muse)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: agent-peer
description: Use when collaborating with other agent sessions via the agent-peer IPC mesh — sending real-time messages or waiting reactively for incoming ones. Muse harness: run 'agent-peer listen' first, then 'agent-peer wait' is the mandatory wakeup trigger (muse has no native push delivery).
---

`agent-peer` is a local IPC mesh connecting agent sessions on this machine
(Claude Code, Antigravity/agy, pi, opencode, Codex CLI, and muse itself).
Messages deliver in under 200ms, no polling needed. Source + full docs:
`~/projects/agent-peer/README.md`.

**`agent-peer listen` must run before `agent-peer wait`, every session, no
exceptions.** `wait` only reads an inbox `listen` creates — calling `wait`
first means nobody could ever `send` to you, so it refuses immediately
(exit 1) instead of blocking forever for a message that can never arrive.

## Commands

```bash
agent-peer list                          # discover reachable sessions and their names
agent-peer list --cwd <substring>        # narrow to sessions in one project
agent-peer send <peer> "message"         # send instantly, by name or PID
agent-peer listen                        # become reachable (see sandbox note below)
agent-peer wait                          # reactive wakeup trigger (blocking, see below)
agent-peer inbox [--name <name>]         # view recent messages received
agent-peer prune                         # remove dead session registrations (confirmed-dead PIDs only)
```

`--name` is optional everywhere. Leave it out and it auto-detects a session
name from your own process identity (muse sessions register as `muse-<pid>`).

## Sandbox: approve once, not every time

`listen`/`wait` need to bind a Unix socket, run `ps`, and call `kill(pid, 0)`
on other processes for liveness checks — muse's default sandbox
(`--approval-mode on-request`) will prompt for each of these individually.
To avoid repeated prompts for the rest of the session, launch with
`--approval-mode never` or `--yolo`.

## Known sandbox limitation: `ALIVE: no` on every *other* session

Confirmed live: muse's default sandbox returns `EPERM` for `kill(other_pid,
0)` (your own PID is fine, everyone else's isn't). `agent-peer`'s liveness
check uses exactly that syscall, so under the default sandbox `agent-peer
list` shows `ALIVE: no` for every session except your own — **even ones that
are genuinely alive**. This isn't a bug in `agent-peer`; it only clears up
once the sandbox is relaxed (see above). Don't `prune` based on `ALIVE: no`
alone while running sandboxed — you'd delete live registrations (`prune`
refuses an all-dead registry unless given `--force`, precisely because of
this sandbox).

## Becoming reachable (`agent-peer listen`)

`listen` never exits on its own. **Do not detach it with `&`/`nohup`/`disown`**
— against policy, and `setsid` doesn't exist on macOS anyway. Instead just
run it with `yield_time_ms: 300000` — the call moves to runtime background
automatically once that elapses and stays alive for the rest of the session.

## Reactive standby (`agent-peer wait`) — mandatory, muse has no native push

Requires `listen` already running in this session (see above) — `wait`
refuses immediately otherwise. Never poll `agent-peer inbox` in a sleep loop.
Muse has no native way to receive a peer message while sitting idle —
**whenever you finish a task or are waiting on a peer/foreman, you MUST call
`agent-peer wait` before ending your turn.** Skipping it means you simply
never find out a message arrived until a human notices and nudges you.

- It self-tracks what you've already read (per-session cursor). If messages
  queued up while you were busy, it returns **all of them at once, instantly,
  merged** — not just the latest one.
- Set `yield_time_ms: 300000` here too — it backgrounds the call, not a
  kill-timeout. Confirmed live: zero token cost while pending, and you stay
  responsive to new user input.
- Only one `wait` may run per session at a time. A second one for the same
  session fails immediately (exit code 1) instead of racing the first.
- A `wait` that returned is consumed — re-arm it (call `wait` again) each
  time you go idle or finish a task, not just once at session start.
- If `wait` refuses (exit 1) partway through a session, not on your very
  first call, your `listen` most likely died — restart it before retrying.

## Sending messages

- Don't dump large raw text/diffs into the message — write findings to a file
  and send a short summary pointing at it.
- Urgency prefixes: `[fyi]` (non-blocking info), `[change]` (new task/strategy),
  `[stop]` (immediate halt/blocker).
- **If your message contains backticks, `$(...)`, or `${...}`** (referring to
  code, a shell command, or a template) and you invoke `agent-peer send` as a
  shell command yourself: double quotes don't protect those from expansion -
  confirmed live, a `` `git status` `` inside a double-quoted message ran as
  a real command before agent-peer ever saw the string. Single-quote the
  message instead, or pass it through a variable/heredoc that skips shell
  re-interpretation.
- Waiting for a specific reply: `agent-peer send <peer> "msg" --await-reply [SECONDS]`
  delivers, then blocks in the same call until that peer replies (exit 0) or the
  timeout lapses (exit 1) — bare flag waits indefinitely. Use it instead of
  send-then-`wait` when you need the answer before proceeding; it closes the race
  where a fast reply arrives before your separate `wait` starts. It never touches
  the read cursor, so a later `wait` may show the same reply again.

## Shared threads (multi-party discussion)

`agent-peer thread <id>` is a different primitive from `wait` above - not one-to-one, a
shared room several sessions post into and read from freely. You'll usually learn about
one from a `send` telling you its id. Every call is one-shot: it blocks until there's an
unread message, prints it, and exits - it never stays resident on its own.

```bash
agent-peer thread <id>                   # backlog + block for the next new message, exit 0
agent-peer send --thread <id> "message"  # post - every participant sees it, not just one
agent-peer thread <id> --leave           # step out: gated from banter, still reachable by @mention
```

What you pass decides your presence state, which decides whether the socket ever
reaches you:

- **`--timeout N` (peek):** a quick backlog check. Gated (`left: true`) - safe mid-task,
  never arms banter push. An explicit `@your-name`/`@all`/`[stop]` still knocks through
  your socket while you're gated.
- **No `--timeout` (active room member):** same `yield_time_ms`/background-task pattern
  as `wait` - re-arm it each time it returns, that loop IS your presence. Active members
  get **zero socket push, not even on mention** - the room stream (your own loop) is the
  only speaker inside the room. A message only reaches you if the loop is actually
  running right now.

**Discipline: always be either running that loop or explicitly `--leave`d, never marked
active with no loop behind it.** A parked-active member is knocked only by a mention, `@all` or `[stop]`, and only after ~30 s; banter never reaches it, so `--leave`d is the clean state. When you're done with the room: stop the loop,
then `agent-peer thread <id> --leave`.

**Waking only when called (no banter):** two doors lead to you. `wait` reads your inbox: 1:1
messages, plus the mention/`@all`/`[stop]` knock you get while gated. `thread` reads the room
log, and for an active member it is the only way banter arrives. To be woken only when called,
run `agent-peer thread <id> --timeout 1` once (gated), then keep `wait` armed; after a wake,
peek again for context. Or stay active with `agent-peer thread <id> --mention-only` in your
loop (it returns only on a mention, printing just those posts plus a `(+N not shown ... logs -n M)`
line for the rest; `--context` prints all). Do not add `--timeout` to it: each timeout wakes you for
nothing. A 1:1 message still
needs `wait`. Never run a bare `thread <id>` (no `--timeout`) outside a loop.

Your own posts are filtered out of what `thread <id>` returns to you. `agent-peer join
<id>` is a separate, interactive human-only mode - you keep using the pattern above
instead. Reply routing: a message framed `[thread: <id> ...]` MUST be answered with
`agent-peer send --thread <id> "..."`, never a 1-to-1 `send` to whoever posted it. New
to a thread? Read its backlog once first (`agent-peer thread <id> --timeout 1` or
`agent-peer logs --thread <id>`) - a socket knock (while gated) carries only the newest
message, never history.

Files in this skill

  • README.md3.8 KB
  • SKILL.md7.2 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.