> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. **Goal:** Add a send-only `/claudex:email` skill that broadcasts the current brainstorm question + a short context snapshot to a configured panel (`~/.claude/claudex/panel.json`), and make it reliably invocable before 2026-05-29 15:00 ET. **Architecture:** A new auto-discov...
Scanned 9/7/2026
Install to Claude Code
npx -y skills add WillInvest/ClaudeX --skill plans --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Plans?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/willinvest-plans)More formats (shields.io, HTML) on the badges page.
# claudex:email Skill Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** Add a send-only `/claudex:email` skill that broadcasts the current brainstorm question + a short context snapshot to a configured panel (`~/.claude/claudex/panel.json`), and make it reliably invocable before 2026-05-29 15:00 ET.
**Architecture:** A new auto-discovered skill at `skills/email/SKILL.md` in the existing `claudex` plugin (model-driven, no executable script). The plugin version + descriptions are bumped to 0.7.0. Deployment is verified against the **actual installed path** read from `installed_plugins.json` (not a hardcoded version), gated by a real Gmail send and a fresh-session invocation.
**Tech Stack:** Markdown SKILL.md, JSON manifests, Gmail MCP `send_email` tool, `~/.claude/claudex/` user-local state. **Note:** the primary deliverable is a prompt file, not code — "tests" are deterministic verifications (JSON parse, grep, dry-run preview, real smoke send) rather than unit tests.
**Spec:** `docs/superpowers/specs/2026-05-28-claudex-email-panel-broadcast-design.md`
---
## Execution model (parallelization-safe)
- **Task 1** (skill file) and **Task 2** (manifests + README) touch disjoint files and may run as **parallel Codex agents** — but agents **must NOT run git** (no `git add`/`commit`). They only write/verify files. This avoids `.git/index` races (Codex review S1).
- **The coordinator** (main session) stages and commits both task outputs sequentially after they complete.
- **Task 3** (deploy + verify) is done by the **coordinator only** — it requires live harness judgment about the installed plugin path and a real Gmail send. Do not delegate it to a parallel agent.
- **Task 4** is host actions for meeting time.
## File structure
- **Create** `skills/email/SKILL.md` — the skill (sole behavioral artifact).
- **Modify** `.claude-plugin/plugin.json` — `version` → 0.7.0; description mentions 3rd skill; add `email`/`panel` keywords.
- **Modify** `.claude-plugin/marketplace.json` — same version + description (kept in sync with plugin.json).
- **Modify** `README.md` — `/claudex:email` table row + section.
- **Consumes (exists, not edited)** `~/.claude/claudex/panel.json` — recipients (user-local PII).
- **Writes at runtime** `~/.claude/claudex/state/panel-sends.jsonl` — append-only send log.
---
## Task 1: Create the `claudex:email` skill file *(parallel agent — NO git)*
**Files:**
- Create: `skills/email/SKILL.md`
- [ ] **Step 1: Write `skills/email/SKILL.md` with exactly this content**
````markdown
---
name: email
description: Broadcast the current brainstorm question plus a short context snapshot to a configured panel by email (SEND-ONLY), so people can read it on their own device during a screen-shared meeting and reply by email or aloud. Use when the user runs /claudex:email, or asks to "email the panel", "send this question to the panel", or "broadcast this to the panel". Reads recipients from ~/.claude/claudex/panel.json. Does not collect replies and does not modify claudex:think.
license: MIT
---
# claudex:email — broadcast a brainstorm question to your panel
**Send-only.** Emails the *current* question + a short context snapshot to a panel defined in
`~/.claude/claudex/panel.json`, so people can read it on their own device during a
screen-shared meeting and respond by email or aloud. It does NOT collect, match, or summarize
replies, and does NOT change `claudex:think`.
Canonical invocation: `/claudex:email [filter]`. Replies land in the connected Gmail account
(`agentfao@gmail.com`) and are not monitored live.
## Step 1 — Parse panel (true fail-fast)
Read `~/.claude/claudex/panel.json`. If it is missing or does not parse, STOP and tell the
host to create/fix it (point at the schema in the spec). This is the only hard stop before
drafting — everything else still produces a draft you can fall back to.
## Step 2 — Resolve recipients
- **No argument:** every member with `include: true`.
- **Argument contains a token with `@`:** treat each such token as an ad-hoc recipient email
address (used for smoke-tests / one-offs), e.g. `/claudex:email willinvest11@gmail.com`.
Ad-hoc emails are combined with any other (non-`@`) filter tokens.
- **Other tokens (case-insensitive):**
- `professor`/`professors` → `role: professor`; `student`/`students` → `role: student`.
- Name tokens (e.g. `florescu bozdog`) match against `name`. **Multiple tokens are OR** —
`florescu bozdog` resolves to BOTH people, not one person matching both.
- NEVER select a member with `include: false` unless explicitly named in the argument.
- If zero recipients resolve, STOP and show what matched / was excluded.
## Step 3 — Assemble the draft (always, even if Gmail later turns out unavailable)
**Context extraction rule (strict):** use ONLY the most recent host-facing brainstorm question
plus a 2–4 line summary of the immediate discussion. EXCLUDE tool output, hidden reasoning,
implementation/planning notes, local file paths, credentials, and unrelated earlier turns. If
which question is "current" is ambiguous, STOP and ask the host to confirm/paste it.
**Never** copy into the email: the Zoom link (`panel.meeting.location`), `panel.meeting.source`,
or any member `expertise`/`title` text. Internal context only.
- **Subject:** `[S.A.G.E.] <short question>` — single line, ≤ 80 chars, no newlines.
- **Body** (plain text, target ≤ ~250 words):
1. Identification line: *"This is Hao Fu's brainstorm assistant for the S.A.G.E. meeting —
sending the question we're on so you can follow along."*
2. **Where we are:** 2–4 line snapshot.
3. **Question:** the current question + its options if multiple-choice.
4. Closing: *"Reply here or raise it on the call."*
## Step 4 — Gmail availability check
Confirm a Gmail send tool (e.g. `mcp__gmail__send_email`) is available, and ensure
`~/.claude/claudex/state/` exists (`mkdir -p`). If the Gmail tool is NOT available, do not
fail blankly: present the fully-assembled draft (recipients, subject, body) under a
**"Manual send fallback"** heading so the host can paste it elsewhere, then stop.
## Step 5 — Preview & confirm (required)
Show the host: recipients as a list with count + class (e.g. "7 included panel members" or
"2 professors (Florescu, Bozdog)"); the line **"All recipients are in To: and will see each
other."**; and the exact subject + full body. Then ask a count-based confirm:
**"Send to N <class> from agentfao@gmail.com?"** Send ONLY on a clear yes. Declining aborts
with no send and no state write (the dry-run path).
## Step 6 — Send
Call the Gmail send tool once with all recipients in `to`, the subject, and the body. If the
send fails or hangs, STOP cleanly and display the draft so the host can paste it elsewhere.
## Step 7 — Record
Append one line to `~/.claude/claudex/state/panel-sends.jsonl`. Record whatever identifier the
send tool returns (the Gmail tool returns a message ID; use the returned id, do not invent a
field):
```json
{"ts":"<ISO8601>","sentId":"<id returned by send tool>","subject":"<subject>","question":"<question text>","recipients":["a@x","b@y"]}
```
If this append fails AFTER a successful send, report **"Sent but not recorded"** with the
subject and the returned id — not an outright failure.
## Step 8 — Report
Report `Sent` (plain ASCII, no emoji) and the returned id. Remind the host replies arrive in
agentfao@gmail.com and are not monitored live.
## Hard rules
1. **Send-only.** Never poll, match, or summarize replies here.
2. **Always preview + confirm** before sending to real people.
3. **Never leak** tool output, file paths, credentials, the Zoom link, or panel expertise
notes into the email body.
4. **Never touch `claudex:think`** or its gate.
````
- [ ] **Step 2: Verify frontmatter (name, description, license)**
```bash
cd "$(git rev-parse --show-toplevel)"
python3 - <<'PY'
import re
t=open("skills/email/SKILL.md").read()
m=re.match(r"^---\n(.*?)\n---\n",t,re.S); assert m,"no frontmatter"
fm=m.group(1)
assert "name: email" in fm,"name must be 'email'"
assert "description:" in fm and "/claudex:email" in fm,"description must mention /claudex:email"
assert "license: MIT" in fm,"license: MIT required"
print("frontmatter OK")
PY
```
Expected: `frontmatter OK`.
- [ ] **Step 3: Verify all 8 sections + ad-hoc-email rule present**
```bash
cd "$(git rev-parse --show-toplevel)"
for s in "Step 1 — Parse panel" "Step 2 — Resolve recipients" "Step 3 — Assemble the draft" \
"Step 4 — Gmail availability" "Step 5 — Preview & confirm" "Step 6 — Send" \
"Step 7 — Record" "Step 8 — Report" "Hard rules" "token with \`@\`"; do
grep -qF "$s" skills/email/SKILL.md && echo "OK: $s" || { echo "MISSING: $s"; exit 1; }
done
```
Expected: an `OK:` line for each, exit 0.
- [ ] **Step 4: STOP — report file written and verifications passed. Do NOT git commit (coordinator commits).**
---
## Task 2: Bump version + update manifests + README *(parallel agent — NO git)*
**Files:**
- Modify: `.claude-plugin/plugin.json`
- Modify: `.claude-plugin/marketplace.json`
- Modify: `README.md`
- [ ] **Step 1: `.claude-plugin/plugin.json`** — set `"version": "0.7.0"`; replace `description` with:
```
claudex — three Claude Code skills: think (brainstorming with an automatic Codex second opinion on every clarifying question), deep-research (subscription-only multi-agent deep research, a port of NVIDIA AI-Q's core with deterministic citation verification), and email (broadcast the current brainstorm question to a configured panel during screen-shared meetings).
```
Add `"email"` and `"panel"` to `keywords` (keep existing entries).
- [ ] **Step 2: `.claude-plugin/marketplace.json`** — in `plugins[0]`, set `"version": "0.7.0"` and replace its `description` with the **same** string (must match plugin.json exactly).
- [ ] **Step 3: Verify both JSON parse, versions = 0.7.0, descriptions match**
```bash
cd "$(git rev-parse --show-toplevel)"
python3 - <<'PY'
import json
p=json.load(open(".claude-plugin/plugin.json"))
m=json.load(open(".claude-plugin/marketplace.json"))
assert p["version"]=="0.7.0",p["version"]
assert m["plugins"][0]["version"]=="0.7.0",m["plugins"][0]["version"]
assert "email" in p["description"].lower()
assert p["description"]==m["plugins"][0]["description"],"descriptions must match"
assert "email" in p["keywords"] and "panel" in p["keywords"]
print("manifests OK")
PY
```
Expected: `manifests OK`.
- [ ] **Step 4: `README.md`** — add this row to the skills table (after the `deep-research` row):
```markdown
| `/claudex:email` | **Broadcast a brainstorm question to a panel.** Send-only: pushes the current question + a short context snapshot to people in `~/.claude/claudex/panel.json` so they can read on their own device during a screen-shared meeting and reply by email or aloud. |
```
And add this section immediately before `## Install`:
```markdown
## `/claudex:email` — broadcast a question to your panel
When you're hosting a screen-shared brainstorm and scrolling makes it hard for others to
follow, `/claudex:email` emails the current question (plus a 2–4 line context snapshot) to a
panel you define in `~/.claude/claudex/panel.json`. It previews and asks you to confirm, then
sends one group email and logs the thread so you can find replies later.
- **Send-only** — it does not collect or summarize replies.
- **Filter recipients:** `/claudex:email professors`, `/claudex:email florescu bozdog`, or an
ad-hoc address like `/claudex:email you@example.com` (smoke test / one-off).
- Sends from the connected Gmail account; replies arrive there and are not monitored live.
`panel.json` holds names, emails, roles, and short expertise notes; set `include: true` per
person to put them on the broadcast.
```
- [ ] **Step 5: Verify the exact row + section landed, section precedes Install**
```bash
cd "$(git rev-parse --show-toplevel)"
grep -qF '| `/claudex:email` | **Broadcast a brainstorm question to a panel.**' README.md \
&& grep -qF '## `/claudex:email` — broadcast a question to your panel' README.md \
&& awk '/^## `\/claudex:email`/{s=NR} /^## Install/{i=NR} END{exit !(s>0 && i>0 && s<i)}' README.md \
&& echo "README OK"
```
Expected: `README OK`.
- [ ] **Step 6: STOP — report files written and verifications passed. Do NOT git commit.**
---
## Coordinator commit (after Tasks 1 & 2 complete)
- [ ] Stage and commit both task outputs in the worktree:
```bash
cd "$(git rev-parse --show-toplevel)"
git add skills/email/SKILL.md .claude-plugin/plugin.json .claude-plugin/marketplace.json README.md
git status --short
git commit -m "feat(email): add send-only claudex:email skill; bump claudex to 0.7.0"
```
---
## Task 3: Deploy to the ACTUAL installed plugin and verify *(coordinator only)*
> Do NOT hardcode a cache version. The installed version of record and the cache the runtime
> loads can differ (observed: `installed_plugins.json` said 0.5.0 while a session loaded 0.6.0).
- [ ] **Step 1: Discover the real installed path**
```bash
python3 - <<'PY'
import json,os
d=json.load(open(os.path.expanduser("~/.claude/plugins/installed_plugins.json")))
entry=d["plugins"]["claudex@willinvest"][0]
print("installPath:",entry["installPath"])
print("version:",entry["version"])
PY
ls -d /home/agent/.claude/plugins/cache/willinvest/claudex/*/ # all cache dirs present
```
Record the `installPath`. Note: more than one cache dir may exist.
- [ ] **Step 2: Deploy the skill into every present claudex cache dir (covers version skew)**
```bash
cd "$(git rev-parse --show-toplevel)"
for d in /home/agent/.claude/plugins/cache/willinvest/claudex/*/; do
mkdir -p "$d/skills/email"
cp skills/email/SKILL.md "$d/skills/email/SKILL.md"
diff -q skills/email/SKILL.md "$d/skills/email/SKILL.md" >/dev/null && echo "deployed: $d"
done
```
Expected: a `deployed:` line per cache dir.
- [ ] **Step 3: Reload and prove DISCOVERABILITY by real invocation (not grep)**
Run `/reload-plugins`. Then in a fresh-enough context invoke `/claudex:email professors` and
confirm the skill procedure actually starts and reaches the preview. If the router still says
"skill not found", a fresh Claude Code session is required — start one and repeat. Treat a real
preview as the ONLY acceptable proof of discoverability.
- [ ] **Step 4: Dry-run with baseline (proves "decline sends/writes nothing")**
```bash
LOG=~/.claude/claudex/state/panel-sends.jsonl
touch "$LOG"; echo "before=$(wc -l < "$LOG")"
```
Invoke `/claudex:email professors`, confirm the preview lists exactly Florescu, Bozdog, Lonon,
Feinstein, Moriarty, then **decline**. Re-check:
```bash
echo "after=$(wc -l < "$LOG")" # MUST equal before
```
- [ ] **Step 5: Leak negative-checks on the previewed draft**
In the Step 4 preview, visually confirm the body contains NONE of: `stevens.zoom.us`,
`panel.meeting.source` text, member expertise/title phrases (e.g. "Research Professor",
"Teaching Associate Professor"), or local paths (`/home/agent`). Confirm subject ≤ 80 chars
and single-line.
- [ ] **Step 6: Real Gmail smoke send (auth + account + Sent visibility gate)**
Invoke `/claudex:email willinvest11@gmail.com`, confirm the preview shows the single ad-hoc
recipient, and **confirm the send**. Then verify:
- the message appears in `agentfao@gmail.com` Sent (and arrives at willinvest11@gmail.com; check spam);
- exactly one new line was appended to the log:
```bash
echo "after_send=$(wc -l < ~/.claude/claudex/state/panel-sends.jsonl)" # before+1
tail -1 ~/.claude/claudex/state/panel-sends.jsonl | python3 -c "import sys,json;r=json.loads(sys.stdin.read());print('sentId',r['sentId']);assert r['recipients']==['willinvest11@gmail.com']"
```
Expected: `after_send` = previous + 1, and a non-empty `sentId`. This proves Gmail is
authenticated as the right account and the record shape is correct.
---
## Task 4: Pre-meeting host checklist (manual, before 15:00 ET)
- [ ] **Trust pre-warning.** From Hao's Stevens address, email the panel: *"During today's
S.A.G.E. meeting you may receive notes/questions from agentfao@gmail.com — that's my
brainstorm assistant."* (Reduces phishing/spam dismissal; the send tool has no Reply-To.)
- [ ] **Confirm include flags.** Run `/claudex:email` (no arg) to the preview, read the default
recipient list aloud against who's actually attending, then decline. Adjust `include` flags
in `panel.json` if needed (Brian Moriarty is `include:true` but optional; Hanyue Shen is
present but `include:false`).
---
## Self-review
**Spec coverage:** send-only/group-To/recipients/filter → T1 S1–S2; ad-hoc email override
(enables C3 smoke test) → T1 S2; identification line + extraction exclusions + ≤80c subject +
bounded body + no leaks → T1 S3; Gmail check + manual fallback (no draft-less stop) → T1 S4;
preview + count confirm + dry-run → T1 S5; send + fallback → T1 S6; log + "sent but not
recorded" + id-agnostic field → T1 S7; plain "Sent" → T1 S8; matching semantics → T1 S2;
version/manifests/README → T2; deploy against real installPath + reload + real-invocation
discoverability + dry-run baseline + leak checks + real smoke send → T3; trust warning +
include-flag review → T4.
**Placeholder scan:** none — full SKILL.md, full JSON/README edits, exact commands + expected
outputs inline.
**Type/name consistency:** `~/.claude/claudex/panel.json`,
`~/.claude/claudex/state/panel-sends.jsonl`, `name: email`, `/claudex:email`, `0.7.0`, JSONL
fields (`ts`/`sentId`/`subject`/`question`/`recipients`) are identical across all tasks.
**Parallelization safety:** Tasks 1 & 2 author disjoint files and do NOT run git; coordinator
commits once; Task 3 (deploy/live judgment) is coordinator-only. No `.git/index` race.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!