Installs into .claude/skills of the current project.
Are you the author of Draft Queue?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/builderio-draft-queue)
---
name: draft-queue
description: Use when queuing, reviewing, editing, opening, or sending email drafts requested by organization teammates, including Slack @agent-native intake.
---
# Draft Queue
The draft queue is for teammate-requested emails that need the owner to review before sending. It is durable SQL data in `queued_email_drafts`, not compose application state.
## Rules
- Use `queue-email-draft` when a teammate asks the agent to prepare an email for an organization member.
- The requester and reviewer must both be members of the active organization.
`requireQueueContext` throws if there's no active org, or if the caller isn't
a member — both surface as plain errors, not empty results.
- Slack requests should queue drafts, not send raw emails.
- Slack intake is the agent's Slack connection. It's set up and switched on
in Settings › Channels › Slack (`navigate --settingsSection=slack`); Mail's
Draft requests group there links to the queue.
- `queue-email-draft` returns `reviewUrl`; include that URL when replying to Slack so the owner can open the exact draft.
- Slack intake verifies the sender email via Slack `users.info` when the app has `users:read.email`, and passes verified sender name/email into the agent context. If that scope is missing, Slack intake cannot resolve a real email and will not queue anything — tell the requester to ask an admin to grant `users:read.email` rather than guessing their address from their Slack display name.
- Managed Slack installs request `users:read.email` through the generated OAuth
manifest; an existing install must be reconnected after the scope is granted.
Legacy bot-token installs must add the scope in Slack manually.
- `ownerEmail` accepts more than an exact email: `resolveOrgMemberEmail` also
matches an unambiguous local-part prefix (e.g. `"jane"` matches
`jane@co.com` if she's the only `jane*` member). If more than one member
matches the prefix, the action throws listing all org member emails instead
of guessing — pass the full email in that case.
- Use `send-queued-drafts` only when the queued draft owner explicitly asks to send.
- Use `open-queued-draft` when the user wants to manually tweak a queued draft in the compose panel.
## Status Lifecycle And Access
A queued draft moves through `queued -> in_review -> sent`, or `-> dismissed`
at any point before `sent`. Rules enforced in `server/lib/queued-drafts.ts`:
- **Ownership is strict.** Only the `ownerEmail` (or an org `owner`/`admin`
role) can call `update-queued-draft`, `open-queued-draft`, or
`send-queued-drafts` for a given draft — `requireQueuedDraft(id, {ownerOnly:
true})` rejects the original requester from editing or sending it, even
though they created it.
- **Sent drafts are frozen.** `updateQueuedDraft` throws
`"Sent queued drafts cannot be edited."` if `status` is already `sent` and
the caller isn't also setting it to `sent` again. Don't retry an edit on a
sent draft — create a new `queue-email-draft` instead.
- **`open-queued-draft` transitions status to `in_review`** and copies the
draft into a real `compose-{id}` application-state entry (auto-appending the
*owner's* configured signature, not the requester's). It also blocks
opening a draft that is already `sent` or `dismissed`.
- **`send-queued-drafts --all=true`** sends every `queued` or `in_review` draft
assigned to the caller (default limit 50, capped 50) by delegating to the
real `send-email` action per draft — each send still requires the standard
approval gate. Partial failures are reported per-draft in `{ sent, failed }`
rather than aborting the whole batch; report both lists back to the user.
- Queueing a draft for someone else fires a best-effort in-app notification to
the owner (skipped when self-queuing); a failed notify does not fail the
queue action itself.
## Actions
| Action | Purpose |
| ----------------------------- | ----------------------------------------------------------------------- |
| `list-org-members` | Resolve valid organization members for `ownerEmail` |
| `queue-email-draft` | Create a queued draft for a member to review |
| `list-queued-drafts` | List active, sent, dismissed, review, or requested drafts |
| `update-queued-draft` | Edit queued draft fields or set status |
| `open-queued-draft` | Open a queued draft as `compose-{id}` |
| `send-queued-drafts` | Send one queued draft or all active drafts assigned to the current user |
| `navigate --view=draft-queue` | Open the queue UI |
## Typical Flow
1. Resolve the target reviewer with `list-org-members` if the user gave a name.
2. Call `queue-email-draft` with `ownerEmail`, recipients, subject, body, and context.
3. Tell the requester it was queued and include the returned `reviewUrl`.
For review:
1. Call `list-queued-drafts --scope=review --status=active`.
2. Use `update-queued-draft` for tone/content changes.
3. Use `open-queued-draft` for manual compose edits, or `send-queued-drafts` when the owner asks to send.