source/skills/invite/SKILL.md
Resend the merchant's magic-link login, or invite a staff member with scoped permissions (pack orders, edit products, etc.).
npx skillsauth add mitcheman/bodega inviteInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Two modes: resend the merchant's login link (forgotten password case) or invite a staff member (partner-hires-a-packer case).
Read .bodega.md. Require state.admin: done.
What do you want to do?
a. Resend my [partner's] login link (they forgot it) b. Invite someone new (staff: packer, product-editor, etc.) c. Remove a staff member (revoke their access)
The SDK's /api/bodega/auth/magic-link endpoint is admin-protected —
it requires the BODEGA_ADMIN_SECRET value (provisioned during deploy)
in the x-bodega-admin-secret header. Without it, the endpoint
returns 403.
Pull the secret in-memory at the start of the skill, use it for any
calls in this run, and rm the env file at the end:
vercel env pull .env.production.local --environment=production --yes
# `--yes` skips the overwrite-confirmation prompt (would hang in
# non-TTY/agent shells if the file already exists).
# Use BODEGA_ADMIN_SECRET in-memory; never echo.
# ... (all magic-link / staff calls below) ...
rm .env.production.local
Identify the target email from .bodega.md (merchant.email if handoff,
else operator.email). Offer to override:
Send to [email]? (yes / no — different email)
Generate a fresh magic link via the SDK:
POST https://<url>/api/bodega/auth/magic-link
Headers:
Content-Type: application/json
x-bodega-admin-secret: <BODEGA_ADMIN_SECRET>
Body:
{ "email": "<target>", "role": "owner" }
Branch on the response's email_sent flag (same shape as the admin
skill — see admin/SKILL.md Step 1 for the security analysis):
email_sent: true — email delivered✓ Sent. They should see it in about a minute. Check spam if not.
✓ Magic link sent to <email>. Expires in 24h.
email_sent: false — email isn't configured yetThe response body has verify_url. Show it directly to the operator
(the link bypasses email entirely; safe because the endpoint is
admin-secret-gated):
Email isn't set up for this store yet, so I can't send the link automatically. Here's the URL — you'll need to forward it to them yourself (text, signal, in person, whatever feels right):
<verify_url>
One-time use, expires in 24 hours, full owner access. Don't paste it anywhere public.
Email unconfigured (RESEND_API_KEY / BODEGA_FROM_EMAIL unset). Bootstrap URL (24h TTL, single-use):
<verify_url>
Forward out-of-band. Configure Resend + redeploy when ready for automated email.
Ask what role:
What should this person be able to do?
a. Pack orders (see orders, mark shipped, print labels — no refunds, no product edits) b. Edit products (add/edit/publish products — no order or money access) c. Full manager (everything except destroying the store)
Ask for their email:
Their email?
Generate a staff magic link with the right role scope (same admin header as Step 2a):
POST https://<url>/api/bodega/auth/magic-link
Headers:
Content-Type: application/json
x-bodega-admin-secret: <BODEGA_ADMIN_SECRET>
Body:
{ "email": "<staff-email>", "role": "packer" | "product-editor" | "manager" }
Send a different email template (welcome-staff, not welcome-owner).
Same email_sent branching as Step 2a — if email_sent: false, show
the staff member's bootstrap URL to the operator and remind them to
forward it directly. Worth flagging that the role scope (packer /
product-editor / manager) is baked into the link's session, so giving
the URL to the wrong person grants whatever role you minted it for —
mint cautiously when bypassing email.
Record in .bodega.md:
admin:
staff:
- email: [email protected]
role: packer
invited_at: 2026-04-22T15:00:00Z
List existing staff from .bodega.md → admin.staff[]:
Who do you want to remove?
- [email protected] (packer)
- [email protected] (product-editor)
- ... (none if no staff yet)
Pick by number or email. Owners cannot be removed via this skill —
that's a settings-page operation in /studio. Refuse politely if the
user picks the owner.
Revoke via the SDK:
DELETE https://<url>/api/bodega/auth/staff/<staff-email>
Headers:
x-bodega-admin-secret: <BODEGA_ADMIN_SECRET>
Update .bodega.md:
admin:
staff:
# remove the matching entry
removed:
- email: [email protected]
role: packer
removed_at: 2026-04-23T10:00:00Z
Confirm:
✓ Removed [email]. Their login link no longer works. If they're in /studio right now, they'll be kicked to the login page on their next click.
✓ Revoked <email>. Existing session invalidated server-side.
✓ Invited [name/email] as [role]. They'll get an email in a minute.
✓ <email> invited as <role>. Magic link sent.
/studio middleware
enforces./studio. Prevents accidental lockout.development
Roll back a Bodega-provisioned project. Walks the user through removing the Vercel project, blob store, GitHub repo, Stripe webhook, and (optionally) `.bodega.md` itself. The merchant's Stripe account stays — that's their data.
business
Reports the current state of the store — what's set up, what's pending, what the URLs are, and what to do next.
testing
First-time Bodega setup. Detects whether the folder has an existing project (adapt) or is empty (greenfield), asks about voice and beneficiary, writes .bodega.md, and orchestrates the full flow through hosting, payments, deploy, and admin.
testing
Re-ask the voice and beneficiary questions and update .bodega.md. Useful when the user's preference changes or the store is being handed off to someone new.