feat(plugin): package as a Claude Code marketplace plugin
- .claude-plugin/plugin.json v0.1.0 (auto_discover, MIT) - SessionStart hook: thin zero-dep .mjs wrapper (marketplace convention) around scripts/coord-inbox.sh, emitting the additionalContext envelope; always exits 0. Smoke-tested: empty mailbox -> bare continue, pending message -> injected with UNTRUSTED framing. - coord-send skill bundled; examples and description use generic repo names only (coordination metadata never reaches a public surface). - README (English; documents the deliver-until-done lifecycle correctly, review §7), CHANGELOG, LICENSE (MIT), CLAUDE.md, package.json + node --test wrapper around the bash selftest. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HBbjgS5A55RVavoyjJC4FX
This commit is contained in:
parent
77664e9e51
commit
0e6014fe98
10 changed files with 472 additions and 0 deletions
140
skills/coord-send/SKILL.md
Normal file
140
skills/coord-send/SKILL.md
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
---
|
||||
name: coord-send
|
||||
description: >-
|
||||
Send an inter-repo coordination message through the local coord mailbox — a
|
||||
natural-language front door over the `coord-send` script. Use this whenever the
|
||||
user wants to notify, tell, message, ping, or coordinate with another repository
|
||||
(or all repositories) about work happening in the current repo: "send info to all
|
||||
repos", "tell repo-x the bug is fixed", "let repo Y and Z know",
|
||||
"broadcast that the spec changed", "reply to that coord message", or a
|
||||
deferred/conditional notice like "when the build is green, notify repo X". Also
|
||||
triggers on Norwegian phrasings: "send info til alle repo", "varsle repo X", "gi
|
||||
beskjed til Y og Z", "kringkast at …", "svar på coord-meldingen", "når Z er ferdig,
|
||||
varsle X". Trigger even when the user names a repo plus something to convey without
|
||||
saying "coord" explicitly — routing a message to another repo IS this skill.
|
||||
version: "0.1.0"
|
||||
---
|
||||
|
||||
# coord-send — natural-language front door for inter-repo messages
|
||||
|
||||
This skill turns a plain request ("tell repo X that Y happened") into the right
|
||||
`coord-send` invocation. The script is the engine; this skill is only the mapping
|
||||
from intent to arguments. It never edits mailbox files by hand — always go through
|
||||
the script, because the script owns the filename grammar, frontmatter, and delivery
|
||||
guarantees.
|
||||
|
||||
## Boundary — why messages are thin
|
||||
|
||||
The mailbox is **transport, not state**. A coord message is a *notice*, not the
|
||||
source of truth. The durable record of any decision lives in the owning repo's
|
||||
state files / docs and its git history. So when you compose a body, write a
|
||||
self-contained heads-up and point at where the real record lives (a commit
|
||||
hash, a doc path) — don't try to make the message itself the canonical artifact.
|
||||
Coordination content is also private: it never belongs on a public surface.
|
||||
|
||||
## The engine
|
||||
|
||||
Resolve the script path portably — this one expression is correct both when the
|
||||
skill runs bundled inside the plugin and when the scripts are installed as
|
||||
personal scripts under `~/.claude/scripts/`:
|
||||
|
||||
CSEND="${CLAUDE_PLUGIN_ROOT:-$HOME/.claude}/scripts/coord-send.sh"
|
||||
|
||||
Interface (body comes from a quoted heredoc so nothing in it is shell-expanded):
|
||||
|
||||
# to one repo
|
||||
"$CSEND" --to <repo> --subject "<subject>" <<'BODY'
|
||||
<message body>
|
||||
BODY
|
||||
|
||||
# to every repo (accumulates; first-time newcomers see it too)
|
||||
"$CSEND" --broadcast --subject "<subject>" <<'BODY'
|
||||
<message body>
|
||||
BODY
|
||||
|
||||
# reply to a message this repo received (routes to the original sender and
|
||||
# marks the original handled; target + "Re: …" subject are inferred)
|
||||
"$CSEND" --reply-to <message-filename> <<'BODY'
|
||||
<message body>
|
||||
BODY
|
||||
|
||||
Sender identity (`--from`) defaults to the basename of the current git toplevel, so
|
||||
you almost never set it. Exit 0 = delivered; exit 2 = usage/IO error (read stderr and
|
||||
fix the arguments rather than retrying blindly).
|
||||
|
||||
## Choosing the target
|
||||
|
||||
- **One named repo** → `--to <repo>`. The repo name is its directory basename; use
|
||||
the name the user gave. No registration exists — sending to a new name just creates
|
||||
that repo's inbox, so a typo silently creates a dead mailbox. If unsure a name is
|
||||
real, check `~/repos/` or existing `~/.claude/coord/<repo>/` before sending.
|
||||
- **Several named repos** ("X and Y") → loop `--to` once per repo with the same
|
||||
subject and body. There is no multi-target flag; the loop is the mechanism:
|
||||
|
||||
for repo in repo-x repo-y; do
|
||||
"$CSEND" --to "$repo" --subject "<subject>" <<'BODY'
|
||||
<body>
|
||||
BODY
|
||||
done
|
||||
|
||||
- **All repos** → `--broadcast`. Prefer this only when the notice genuinely concerns
|
||||
everyone, because broadcasts accumulate and every future first-time repo sees the
|
||||
standing backlog. For a bounded, known set, loop `--to` instead so unrelated future
|
||||
repos don't inherit it.
|
||||
- **A reply to something received** → `--reply-to <filename>`. Use the filename from
|
||||
the injected inbox/archive; it resolves the sender and closes the original in one
|
||||
step.
|
||||
|
||||
## Composing the message
|
||||
|
||||
Derive a short, specific `--subject` from the intent if the user didn't give one
|
||||
("ingest bug fixed", not "update"). In the body, state what happened, what the
|
||||
recipient should know or do, and a pointer to the durable record (commit hash, doc
|
||||
path). Keep it to the point — this is a notice, not a report. Match the repo's
|
||||
language convention for message content; keep it sober and factual.
|
||||
|
||||
## Deferred and conditional sends
|
||||
|
||||
"When Z is done, notify X" means: do **not** send now. Hold the intent — the target,
|
||||
subject, and body — and continue the work. The moment condition Z is satisfied *in
|
||||
this session*, fire the send. This works because you carry the intent across turns
|
||||
within a session.
|
||||
|
||||
Be honest about the limit: a skill cannot persist intent across sessions. If the
|
||||
session is ending and the condition still hasn't been met, surface the pending
|
||||
message to the user so it isn't silently lost — don't imply it will fire later on
|
||||
its own.
|
||||
|
||||
## After sending
|
||||
|
||||
Report what actually happened: the target(s), the subject, and the delivered
|
||||
filename(s) from the script's stdout. If a send failed (exit 2), say so with the
|
||||
stderr reason rather than claiming success. Delivery reaches the recipient at *their*
|
||||
next session start (the receive side is a hook), so tell the user it's queued, not
|
||||
that the other repo has seen it.
|
||||
|
||||
## Examples
|
||||
|
||||
**Example 1 — single repo, composed body**
|
||||
Input: "tell repo-x the ingest bug is fixed, it was commit abc1234"
|
||||
Action: `--to repo-x --subject "ingest bug fixed"`, body naming the fix and
|
||||
pointing at commit abc1234 and the owning doc.
|
||||
|
||||
**Example 2 — broadcast**
|
||||
Input: "let all the repos know the shared spec grew a new validation rule"
|
||||
Action: `--broadcast --subject "spec: new validation rule"`, body summarizing
|
||||
the change and pointing at the spec's owning repo.
|
||||
|
||||
**Example 3 — bounded multi-target**
|
||||
Input: "gi beskjed til repo-x og repo-y om at gaten er re-pinnet"
|
||||
Action: loop `--to repo-x` then `--to repo-y`, same subject "shared gate re-pinned".
|
||||
|
||||
**Example 4 — deferred**
|
||||
Input: "når testene er grønne, varsle repo-y"
|
||||
Action: keep working; once the test run passes this session, send
|
||||
`--to repo-y` with the green result. If the session ends first, surface the
|
||||
pending notice to the user.
|
||||
|
||||
**Example 5 — reply**
|
||||
Input: "svar på coord-meldingen fra repo-x at vi tar det"
|
||||
Action: `--reply-to <that-message-filename>`, body acknowledging and stating the plan.
|
||||
Loading…
Add table
Add a link
Reference in a new issue