Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 26 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,13 +119,17 @@ The **command name** determines:

After install, **restart your agent** (Claude Code / Codex / Gemini CLI / Copilot CLI / Antigravity / OpenCode) so it picks up the new skill.

### Windows: Git Bash & Codex
### Windows: Git Bash

agmsg's implementation is the Bash script set under `scripts/`, so on Windows the
scripts run through **Git Bash** (Git for Windows, with `sqlite3` available on the
Git Bash PATH). There is no PowerShell reimplementation.

- In Windows environments, Claude Code naturally works with Bash/Git Bash for
- In Windows environments, Claude Code monitor delivery is verified through
Git Bash. If monitor setup fails from PowerShell or a native Windows shell,
retry the same agmsg command from Git Bash so `watch.sh` runs in the expected
Bash environment.
- Claude Code normally works with Bash/Git Bash for
these script calls, but native Windows Codex commands and hooks often start
from PowerShell. Keep the actual agmsg execution path pinned to Git Bash so
all agents share the same `$HOME` and SQLite database.
Expand Down Expand Up @@ -237,6 +241,26 @@ Settings are per-project. Each `<project>/.claude/settings.local.json` gets exac

**Monitor priming**: in `monitor` mode, the receiving agent doesn't react to its first inbound message until it has taken at least one turn this session. If you've just started a fresh session and a teammate has already sent something, nudge the agent with any short message ("hi") to prime it — subsequent messages stream in real time.

### Claude Code monitor verification

`delivery.sh status claude-code <project>` showing `mode: monitor` means the project is configured for monitor delivery. It does **not** prove that Claude Code has started the runtime Monitor task in the current session.

For real-time delivery, verify the Claude Code runtime state:

1. `ToolSearch select:Monitor` finds Claude Code's generic `Monitor` tool.
2. The session starts `Monitor(agmsg inbox stream)` with the `watch.sh ... claude-code` command from the `AGMSG-DIRECTIVE`.
3. The Claude Code footer shows `1 monitor`.
4. The transcript contains `Monitor event: "agmsg inbox stream"` when messages arrive.

These are failure states, even if `delivery.sh status` says `mode: monitor`:

- The footer shows `1 shell`.
- `watch.sh` is running only as a Bash/background/nohup shell process.
- Tool search finds Azure Monitor, an MCP monitor, or any other monitor-branded tool instead of Claude Code's generic `Monitor` tool.
- `ToolSearch select:Monitor` cannot find a generic `Monitor` tool.

If the Monitor tool is unavailable, use `turn` delivery or manual `/agmsg` inbox checks as a fallback. Those modes still deliver queued messages, but they are not real-time monitor delivery.

### Migrating from legacy `hook on/off`

`hook on` is now a thin alias for `mode turn` (with a one-line deprecation hint). To switch to real-time push:
Expand Down
10 changes: 10 additions & 0 deletions SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,16 @@ Do NOT manually edit config files. Always use join.sh.
~/.agents/skills/agmsg/scripts/delivery.sh set <mode> <type> "$(pwd)"
~/.agents/skills/agmsg/scripts/delivery.sh status <type> "$(pwd)"

# Claude Code monitor runtime check:
# `delivery.sh status ...` showing `mode: monitor` only confirms project hook
# configuration. Realtime success requires Claude Code's generic Monitor tool:
# ToolSearch select:Monitor finds Monitor, Monitor(agmsg inbox stream) starts,
# the footer shows `1 monitor`, and the transcript records
# `Monitor event: "agmsg inbox stream"`. A footer showing `1 shell`, a
# Bash/background/nohup watch.sh, or Azure/MCP/other monitor-branded tools are
# failure states. If generic Monitor is unavailable, use turn/manual inbox
# fallback, but do not call that realtime monitor delivery.

# Multiple roles per project (one CC = one active role).
# Claude Code: `actas` claims an exclusivity lock for <name> across sessions
# and restarts the Monitor filtered to <name> only; peer watchers stop
Expand Down
21 changes: 21 additions & 0 deletions scripts/delivery.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ set -euo pipefail
# both — monitor primary; turn as per-session safety net
# off — no automatic delivery
#
# `status` reports configured delivery hooks. For Claude Code, `mode: monitor`
# means the project is configured for monitor delivery; runtime success still
# requires Claude Code to start its generic Monitor tool for `agmsg inbox stream`.
#
# settings.json injection is idempotent: each `set` call first strips any
# existing agmsg-owned SessionStart/Stop entries, then re-adds whichever
# the new mode requires. Re-running with the same mode is a no-op.
Expand Down Expand Up @@ -307,6 +311,12 @@ AGMSG-DIRECTIVE: For this running session, invoke the Monitor tool now with:
persistent: true

Pass the command above verbatim — the session_id is already filled in.
Use Claude Code's generic Monitor tool only. Do not start this command with
Bash/background/nohup or a shell task; a footer that shows "1 shell" is not
real-time Monitor delivery. Success is "1 monitor" in the footer and transcript
events named Monitor event: "agmsg inbox stream". If ToolSearch cannot find
the generic Monitor tool, use turn/manual inbox as a fallback; that is not
real-time monitor delivery.
EOF
}

Expand Down Expand Up @@ -451,6 +461,17 @@ do_status() {
if [ -n "$TYPE" ] && [ -n "$PROJECT" ]; then
agmsg_delivery_load_plug "$TYPE"
agmsg_delivery_status "$TYPE" "$PROJECT"
case "$TYPE" in
claude-code)
cat <<'EOF'
note: status reports configured hooks only. For real-time delivery, Claude Code
must also have a generic Monitor task named "agmsg inbox stream" running in the
current session. Verify ToolSearch select:Monitor, footer "1 monitor", and
transcript Monitor event: "agmsg inbox stream"; footer "1 shell" means the
watcher was started as a shell/background task, not Monitor delivery.
EOF
;;
esac
fi

agmsg_delivery_runtime_status "$TYPE" "$PROJECT"
Expand Down
11 changes: 10 additions & 1 deletion scripts/drivers/types/claude-code/template.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,15 @@ Four possible outputs:
- description: `agmsg inbox stream`
- persistent: true

Important: `delivery.sh status` showing `mode: monitor` means monitor delivery is configured for the project; it does not prove the current Claude Code runtime has started Monitor. Treat monitor startup as successful only when all of these are true:

1. `ToolSearch select:Monitor` finds Claude Code's generic `Monitor` tool.
2. You start `Monitor(agmsg inbox stream)` with the command above or the command printed in the `AGMSG-DIRECTIVE`.
3. The Claude Code footer shows `1 monitor`.
4. The transcript later shows `Monitor event: "agmsg inbox stream"` for delivered messages.

Do not use Bash/background/nohup or a shell task as a substitute for Monitor. If the footer shows `1 shell`, that is a failed realtime monitor launch even if `watch.sh` is running. Azure Monitor, MCP monitor, or other monitor-branded tools are also not valid. If the generic Monitor tool is unavailable, tell the user that realtime monitor delivery cannot be started in this Claude Code runtime and use `turn` delivery or manual inbox checks as fallback; those fallbacks are not realtime monitor delivery.

Then continue with the user's subcommand. This catches the case where the user invokes `/__SKILL_NAME__` as the first prompt before the SessionStart-hook directive has been acted on.

**Sandbox compatibility.** When Claude Code's sandbox is enabled, `watch.sh` (monitor mode) runs inside the sandbox and needs to write pidfiles and SQLite WAL files under `~/.agents/skills/__SKILL_NAME__/`. If monitor mode fails with write/permission errors there, add an allowlist entry to `~/.claude/settings.json` (or project-level `.claude/settings.local.json`):
Expand Down Expand Up @@ -179,7 +188,7 @@ If argument starts with "despawn" (e.g. "despawn reviewer", "despawn alice --for

If argument is "mode" (no further args):
1. Run: `~/.agents/skills/__SKILL_NAME__/scripts/delivery.sh status claude-code "$(pwd)"`
2. Show the output to the user.
2. Show the output to the user. If it says `mode: monitor`, explicitly say this is only configuration status; runtime success still requires Claude Code's generic `Monitor(agmsg inbox stream)` task, footer `1 monitor`, and transcript `Monitor event: "agmsg inbox stream"`.

If argument starts with "mode" followed by a mode name (e.g. "mode monitor"):
1. Parse the mode (one of `monitor`, `turn`, `both`, `off`).
Expand Down
13 changes: 13 additions & 0 deletions scripts/session-start.sh
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,19 @@ This streams incoming agmsg messages into the session in real time. Each
output line is one message: \`<ts> | <team> | <from> → <to> | <body>\`.
React to messages as they arrive; reply with \`send.sh\`.

Use Claude Code's generic Monitor tool only. First confirm ToolSearch
select:Monitor finds that generic tool; Azure Monitor, MCP monitor, or other
monitor-branded tools are not valid for agmsg delivery. Do not start watch.sh
with Bash/background/nohup or a shell task. Success is:

- Monitor(agmsg inbox stream) starts
- the footer shows "1 monitor" (not "1 shell")
- the transcript later contains Monitor event: "agmsg inbox stream"

If the generic Monitor tool is unavailable, do not treat a background shell
watcher as success. Switch to turn delivery or run manual inbox checks instead;
those fallbacks are not real-time monitor delivery.

Note: On a /clear or --continue/--resume re-fire, you may shortly see a
"Monitor … stopped" notification for an earlier 'agmsg inbox stream'
task. That is the previous watcher being cleaned up to avoid duplicates
Expand Down