| name | agmsg |
| description | Cross-agent messaging via SQLite. Send messages between Claude Code, Codex, Gemini CLI, and other agents. No daemon, no network, no dependencies beyond bash and sqlite3. |
Agent messaging command. IMPORTANT: Always use the provided scripts. NEVER directly read or edit config files, DB, or team data. There is NO register.sh — use join.sh to join a team.
Identity
If you already know your AGENT and TEAMS from a previous $agmsg call in this session, skip to Execute below.
Otherwise, run: ~/.agents/skills/agmsg/scripts/whoami.sh "$(pwd)" codex
Four possible outputs:
A) Single identity:
agent=<name> teams=<t1,t2,...> type=codex project=<path>
-> Remember AGENT and TEAMS, then go to Execute.
B) Multiple identities:
multiple=true agents=<n1,n2,...> teams=<t1,t2,...> type=codex project=<path>
-> Ask the user which agent name to use for this session, then go to Execute.
C) Not in a team:
not_joined=true available_teams=<t1,t2,...> (or available_teams=none)
-> Show the user the available teams from the output, then:
First-time setup required.
Joining a team so this agent can send and receive messages.
- Team name: a group of agents that can message each other (available: )
- Agent name: this agent's identity within the team
- Ask: "Enter a team name (joins existing or creates new)"
- Ask: "Enter a name for this agent"
- You MUST use join.sh — run:
~/.agents/skills/agmsg/scripts/join.sh <team> <agent_name> codex "$(pwd)"
- Show the result and explain:
Joined! You can now use $agmsg to check and send messages.
$agmsg — check inbox
$agmsg send <agent> <message> — send a message
$agmsg team — list team members
$agmsg history — message history
$agmsg mode <monitor|off> — switch delivery mode
$agmsg actas <name> — switch to another role in this project (creates if needed)
$agmsg drop <name> — remove a role from this project
$agmsg spawn <type> <name> — launch a new agent in a tmux pane / terminal and have it actas
$agmsg despawn <name> — tear down a member you spawned (graceful, or --force)
-
REQUIRED — Do NOT skip this step. Enable real-time delivery. Monitor is the only automatic mode used on this machine — do not offer or set turn/both. Run:
~/.agents/skills/agmsg/scripts/delivery.sh set monitor codex "$(pwd)"
- Read the
AGMSG-DIRECTIVE block printed by delivery.sh and follow it: use Codex's Monitor tools to start or stop the watcher as instructed.
$agmsg mode off disables automatic delivery later if the user asks.
-
Then check inbox for the newly joined team.
D) Suggestions for reuse:
suggest=true agents=<n1,n2,...> teams=<t1,t2,...> type=codex project=<path> available_teams=<t1,t2,...>
-> No exact registration exists for this project, but there are same-type agent names registered elsewhere.
- Show the suggested agent names to the user.
- Ask whether to reuse one of those names or choose a new one.
- Ask for the team name to join (existing or new).
- Run:
~/.agents/skills/agmsg/scripts/join.sh <team> <agent_name> codex "$(pwd)"
- Then continue with the normal post-join flow above.
Execute
Only use scripts in ~/.agents/skills/agmsg/scripts/ — do not read or modify files under teams/ or db/ directly.
Ensure monitor is running first. Before processing any subcommand below, check whether this session already has an agmsg inbox stream Monitor task. If not, and the project's delivery mode is monitor (check via ~/.agents/skills/agmsg/scripts/delivery.sh status codex "$(pwd)"), first run:
~/.agents/skills/agmsg/scripts/monitor-command.sh codex "$(pwd)"
Then invoke Codex's Monitor start tool with the command printed by that script:
- command:
<printed command>
- description:
agmsg inbox stream
- persistent: true
Pass the printed command verbatim. It already contains a literal session id; do not pass a command containing $CODEX_THREAD_ID to Monitor.
If this Codex build does not expose Monitor tools, say that native monitor delivery cannot run in this session and fall back to manual $agmsg checks.
Sandbox compatibility. When Codex sandboxing is enabled, watch.sh (monitor mode) needs write access under ~/.agents/skills/agmsg/ for pidfiles and SQLite WAL files. The direct installer configures Codex writable roots when ~/.codex/config.toml exists; if monitor fails with write/permission errors, allow writes to that skill directory.
If no arguments provided (DEFAULT action — always do this when the command is invoked without arguments):
- IMMEDIATELY run inbox check for each TEAM:
~/.agents/skills/agmsg/scripts/inbox.sh $TEAM $AGENT
- Do NOT ask the user what to do — just run the inbox check.
- If there are messages, read and respond appropriately. To reply:
~/.agents/skills/agmsg/scripts/send.sh $TEAM $AGENT <to_agent> "<message>"
If argument is "history":
- Run:
~/.agents/skills/agmsg/scripts/history.sh $TEAM $AGENT
If argument is "team":
- For each TEAM, run:
~/.agents/skills/agmsg/scripts/team.sh $TEAM
If argument starts with "send" (e.g. "send misaki check the server"):
- Parse target agent and message from the arguments
- Determine which team the target agent belongs to, then run:
~/.agents/skills/agmsg/scripts/send.sh $TEAM $AGENT <to_agent> "<message>"
If argument is "config":
- Run:
~/.agents/skills/agmsg/scripts/config.sh show
- Show the output to the user.
If argument starts with "config set" (e.g. "config set hook.check_interval 30"):
- Parse key and value from the arguments.
- Run:
~/.agents/skills/agmsg/scripts/config.sh set <key> <value>
If argument starts with "actas" followed by an agent name (e.g. "actas alice"):
- Parse the new role name.
- Run
~/.agents/skills/agmsg/scripts/identities.sh "$(pwd)" codex to see whether the role is already registered for this (project, type).
- If the name does not appear in the output, join under the existing team. Read TEAMS from the in-session whoami state (it may be a single team or comma-separated). For a single team, run
~/.agents/skills/agmsg/scripts/join.sh <team> <name> codex "$(pwd)". For multiple teams, ask the user which team to join the new role into.
- Resolve this session's agmsg instance id:
AGMSG_SESSION_ID="$(~/.agents/skills/agmsg/scripts/session-id.sh codex "$(pwd)")". Use this exact value for both the claim and the replacement Monitor command below.
- Pre-flight claim the actas exclusivity lock so this role isn't already owned by another live session:
~/.agents/skills/agmsg/scripts/actas-claim.sh "$(pwd)" codex <name> "$AGMSG_SESSION_ID". Read the status= line of the output:
status=ok ...: proceed to step 6.
status=held team=<team> owner=<sid>: another live session currently owns <name> in <team>. Tell the user: "Cannot actas as <name> — it is held by session <sid> in team <team>. Run $agmsg drop <name> in that session first, then retry." Then abort — do NOT touch the running Monitor.
status=not_registered: shouldn't happen if step 3 ran; treat as an error.
- Switch receive too — exclusive role mode.
a. Use Codex's Monitor list tool. Find any task whose description begins with "agmsg inbox stream".
b. If a matching task is found: stop it with Codex's Monitor stop tool.
c. If no matching task is found: skip the stop step entirely.
d. Invoke a fresh Monitor regardless of whether step b or c applied:
- first run:
~/.agents/skills/agmsg/scripts/monitor-command.sh --session-id "$AGMSG_SESSION_ID" codex "$(pwd)" <name>
- command:
<printed command>
- description:
agmsg inbox stream (acting as <name>)
- persistent: true
Pass the printed command verbatim; do not pass
$CODEX_THREAD_ID through Monitor.
The 4th argument to watch.sh restricts the subscription to messages addressed to <name> only — other roles' inbound messages stop reaching this session until another actas or session end.
- Set the session's active FROM to
<name> — use <name> in every send.sh call for the rest of this session.
- Tell the user: "Now acting as
<name>. Sends use <name> as from; receive restricted to <name> only."
If argument starts with "drop" followed by an agent name (e.g. "drop alice"):
- Parse the role name.
- Resolve this session's agmsg instance id:
AGMSG_SESSION_ID="$(~/.agents/skills/agmsg/scripts/session-id.sh codex "$(pwd)")".
- Run
~/.agents/skills/agmsg/scripts/reset.sh "$(pwd)" codex <name> "$AGMSG_SESSION_ID" to remove only that role's registration for this project. If the role has no other registrations left, reset.sh also drops it from the team config. The 4th argument releases any actas exclusivity locks this session held on the role so peers can pick it up immediately.
- If the session's active FROM was
<name>, clear that state. Then:
a. Use Codex's Monitor list tool. Find any task whose description begins with "agmsg inbox stream".
b. If a matching task is found: stop it with Codex's Monitor stop tool.
c. If no matching task is found: skip the stop step.
d. Invoke a fresh Monitor with the default subscription:
- first run:
~/.agents/skills/agmsg/scripts/monitor-command.sh --session-id "$AGMSG_SESSION_ID" codex "$(pwd)"
- command:
<printed command>
- description:
agmsg inbox stream
- persistent: true
- Tell the user: "Dropped role
<name> from this project."
If argument starts with "spawn" (e.g. "spawn claude-code alice", "spawn codex reviewer --window"):
- Parse
<type> (must be claude-code or codex), <name>, and any options (--project, --team, --window, --split h|v, --terminal, --no-wait, --ready-timeout <secs>).
- Run:
~/.agents/skills/agmsg/scripts/spawn.sh <type> <name> --project "$(pwd)" [options]
- spawn.sh pre-joins
<name>, then opens a tmux pane/window (when this session is inside tmux) or a new OS terminal, and launches the target CLI with that type's agmsg command ($agmsg actas <name> for Codex, /agmsg actas <name> for Claude Code) as its initial prompt.
- By default it BLOCKS until the new agent's watcher attaches and prints
status=ready — so you can message <name> right away. It prints status=timeout and exits 3 if not ready within --ready-timeout (default 90s); pass --no-wait for fire-and-forget.
- It refuses early if
<name> is already held by another live session, if the target CLI is not installed, or if there is no tmux and no usable terminal (headless).
- Show the script's output. Do NOT stop or relaunch this session's own Monitor — spawn affects a separate, newly launched agent, not this session's subscription.
If argument starts with "despawn" (e.g. "despawn reviewer", "despawn alice --force"):
- Parse
<name> and any options (--force, --timeout <secs>). despawn is the inverse of spawn — it tears down a member you previously spawned.
- Determine which team
<name> belongs to (as with send), then run:
~/.agents/skills/agmsg/scripts/despawn.sh <team> $AGENT <name> [--force] [--timeout <secs>]
- Default (graceful): sends a
ctrl:despawn control message to <name>. The member's watcher drops its own role (releasing the actas lock + registration) and closes its own tmux pane, which ends the agent CLI. Blocks until the lock releases, up to --timeout (default 30s), then prints status=ok. On timeout it prints status=timeout and exits 3 — retry with --force.
--force: skips the message and tears the member down from the placement recorded at spawn time — kills its tmux pane/window and drops its registration. Use when the member's watcher can't respond.
- Show the script's output. Do NOT stop or relaunch this session's own Monitor — despawn affects the spawned member, not this session's subscription.
If argument is "mode" (no further args):
- Run:
~/.agents/skills/agmsg/scripts/delivery.sh status codex "$(pwd)"
- Show the output to the user.
If argument starts with "mode" followed by a mode name (e.g. "mode monitor"):
- Parse the mode. Only
monitor and off are used on this machine — refuse turn and both with: "turn/both delivery is not used here; use monitor (real-time push) or off."
- Run:
~/.agents/skills/agmsg/scripts/delivery.sh set <mode> codex "$(pwd)"
- Read the
AGMSG-DIRECTIVE block in the command output and follow it using Codex's Monitor tools.
If argument is "hook on" (legacy alias):
- Run:
~/.agents/skills/agmsg/scripts/delivery.sh set monitor codex "$(pwd)"
- Tell the user: "Delivery mode set to 'monitor' (turn delivery is not used on this machine)."
If argument is "hook off" (legacy alias):
- Run:
~/.agents/skills/agmsg/scripts/delivery.sh set off codex "$(pwd)"
- Tell the user: "Delivery mode set to 'off'."
If argument is "version":
- Run:
~/.agents/skills/agmsg/scripts/version.sh
- Show the output — the installed version (git-describe provenance recorded at install time).
If argument is "reset":
- Run:
~/.agents/skills/agmsg/scripts/reset.sh "$(pwd)" codex
- Tell the user the result.