feat(msg): /msg skill — read/write cross-session mailbox by @id (#42)
Thin skill over the kei-message jsonl mailbox: /msg reads inbox, /msg @name text sends (identity = cwd basename), /msg all broadcasts, /msg list|who. send now accepts leading @name. Mirror of keigit 7b453aac.
This commit is contained in:
parent
a299427367
commit
48b2f5cc1c
3 changed files with 67 additions and 2 deletions
|
|
@ -8,7 +8,7 @@ OpenClaw / Kimi from the same source-of-truth.
|
|||
|
||||
**Apache 2.0** — explicit patent grant + retaliation clause. 105 Rust
|
||||
crates [REAL: `grep -E '^\s*"[a-z-]+",' _primitives/_rust/Cargo.toml | wc -l`],
|
||||
68 skills [REAL: `ls skills/ | wc -l`], 54 hooks
|
||||
69 skills [REAL: `ls skills/ | wc -l`], 54 hooks
|
||||
[REAL: `ls hooks/*.sh | wc -l`], 38 agent manifests
|
||||
[REAL: `ls _manifests/*.toml | wc -l`], 85 substrate blocks
|
||||
[REAL: `find _blocks/ -name '*.md' | wc -l`], 18 capability atoms
|
||||
|
|
@ -83,7 +83,7 @@ The web installer (`web-install.sh` in this repo, served at
|
|||
repo and delegates to `bootstrap.sh` — single source of truth, no
|
||||
duplicated install logic.
|
||||
|
||||
38 agents + 68 skills + 54 hooks + nightly consolidation wired in
|
||||
38 agents + 69 skills + 54 hooks + nightly consolidation wired in
|
||||
~60 seconds. Twelve install profiles (`outcome-only`, `minimal`,
|
||||
`core`, `frontend`, `ops`, `dev`, `mcp`, `cortex`, `local-mirror`,
|
||||
`dashboard`, `full-hub`, `full`) defined in
|
||||
|
|
|
|||
|
|
@ -32,6 +32,9 @@ case "$cmd" in
|
|||
--to) to="$2"; shift; shift ;;
|
||||
--from) me="$2"; shift; shift ;;
|
||||
--) shift; body="$body $*"; break ;;
|
||||
# Leading @name = recipient (e.g. `send @frontend hi`). First token only;
|
||||
# a later @x stays literal text.
|
||||
@?*) if [ "$to" = "all" ] && [ -z "$body" ]; then to="${1#@}"; else body="$body $1"; fi; shift ;;
|
||||
*) body="$body $1"; shift ;;
|
||||
esac
|
||||
done
|
||||
|
|
|
|||
62
skills/msg/SKILL.md
Normal file
62
skills/msg/SKILL.md
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
---
|
||||
name: msg
|
||||
description: Read or write the cross-session mailbox by @id. Send a message to another Claude Code session (`/msg @name text`), read your own inbox (`/msg` with no args), broadcast to everyone (`/msg all text`), list the whole bus, or discover who is reachable. Thin wrapper over the `kei message` jsonl mailbox — messages land in the recipient's NEXT turn via the mailbox-inject hook (pull, not push). Use whenever the user wants sessions/agents to talk to each other.
|
||||
argument-hint: "[@name] <message> | (empty = read inbox) | list | who"
|
||||
---
|
||||
|
||||
# /msg — Inter-Session Mailbox
|
||||
|
||||
A persistent append-only bus so ANY Claude Code session can message ANY other —
|
||||
not just Agent-Teams teammates, no tmux, no daemon. Backed by
|
||||
`~/.claude/scripts/kei-message.sh` writing `~/.claude/mailbox/messages.jsonl`.
|
||||
The `mailbox-inject.sh` UserPromptSubmit hook pulls each session's unread into
|
||||
its context once per turn, so delivery is **pull** (arrives on the recipient's
|
||||
next turn), not instant push.
|
||||
|
||||
## Identity model
|
||||
|
||||
- **Your address** = the basename of this session's working directory (`$PWD`).
|
||||
So a session running in `~/Projects/frontend` is reachable as `@frontend`.
|
||||
- **`all`** is the broadcast channel — every session sees `to:"all"` messages.
|
||||
- You can override the sender with `--from <name>` and the reader identity with
|
||||
`--me <name>` if a session's cwd basename isn't the name you want to use.
|
||||
|
||||
## Command map
|
||||
|
||||
Interpret `$ARGUMENTS` and run the matching command via Bash, then show its
|
||||
output to the user. The launcher `kei message …` and the script path are
|
||||
equivalent — prefer the script path (always present after install):
|
||||
|
||||
| User typed | Run |
|
||||
|---|---|
|
||||
| `/msg` (no args) | `~/.claude/scripts/kei-message.sh inbox` |
|
||||
| `/msg @frontend ship it` | `~/.claude/scripts/kei-message.sh send @frontend ship it` |
|
||||
| `/msg all standup in 5` | `~/.claude/scripts/kei-message.sh send all standup in 5` |
|
||||
| `/msg list` | `~/.claude/scripts/kei-message.sh list` |
|
||||
| `/msg who` (or `channels`) | `~/.claude/scripts/kei-message.sh channels` |
|
||||
|
||||
Rules for parsing `$ARGUMENTS`:
|
||||
|
||||
1. **Empty** → read inbox (`inbox`). Show the messages addressed to this
|
||||
session or to `all`.
|
||||
2. **Starts with `@<name>`** → send to that recipient; the rest is the body.
|
||||
A `@x` that appears later in the body stays literal text.
|
||||
3. **Starts with `all `** → broadcast; the rest is the body.
|
||||
4. **`list`** → print the recent whole bus (every from→to line).
|
||||
5. **`who` / `channels`** → print known recipient names (use this to discover
|
||||
who is reachable before sending the first message).
|
||||
6. Anything else with no leading `@`/`all` → treat as a broadcast body, OR ask
|
||||
the user who the recipient is if it's ambiguous.
|
||||
|
||||
## Discovery (first-message problem)
|
||||
|
||||
A recipient only appears in `who` after it has sent or been sent a message, so
|
||||
for the very first contact either broadcast with `all`, or ask the user for the
|
||||
target session's cwd-basename. Don't invent a recipient name.
|
||||
|
||||
## Notes
|
||||
|
||||
- Sending never blocks and never notifies the recipient out-of-band — they see
|
||||
it on their next turn. For a time-sensitive ping, tell the user it's queued.
|
||||
- This is plain files: `cat ~/.claude/mailbox/messages.jsonl` is the raw bus.
|
||||
- Bypass the inject hook for a session with `KEI_MAILBOX_BYPASS=1`.
|
||||
Loading…
Reference in a new issue