diff --git a/.claude-plugin/.upstream-base b/.claude-plugin/.upstream-base
index 72576671..0f2b9319 100644
--- a/.claude-plugin/.upstream-base
+++ b/.claude-plugin/.upstream-base
@@ -1 +1 @@
-45c66fde1f1681a902a30d1ae8bca1cc64465d6e
+15ef02d9719259476fbd13de1b2db35d79f04797
diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json
index db865fb2..ac853885 100644
--- a/.claude-plugin/marketplace.json
+++ b/.claude-plugin/marketplace.json
@@ -135,6 +135,66 @@
"author": {
"name": "Lauren Tan"
}
+ },
+ {
+ "name": "gmail",
+ "description": "Connect Cursor to Gmail via Google's remote MCP server — search, read, draft, label, and manage email.",
+ "source": "./gmail",
+ "category": "developer-tools",
+ "author": {
+ "name": "Cursor",
+ "email": "plugins@cursor.com"
+ }
+ },
+ {
+ "name": "google-calendar",
+ "description": "Connect Cursor to Google Calendar via Google's remote MCP server — list calendars, search events, and create or update meetings.",
+ "source": "./google-calendar",
+ "category": "developer-tools",
+ "author": {
+ "name": "Cursor",
+ "email": "plugins@cursor.com"
+ }
+ },
+ {
+ "name": "google-docs",
+ "description": "Connect Cursor to Google Docs via Google's remote MCP server — read and update documents.",
+ "source": "./google-docs",
+ "category": "developer-tools",
+ "author": {
+ "name": "Cursor",
+ "email": "plugins@cursor.com"
+ }
+ },
+ {
+ "name": "google-drive",
+ "description": "Connect Cursor to Google Drive via Google's remote MCP server — search, read, create, share, and manage files.",
+ "source": "./google-drive",
+ "category": "developer-tools",
+ "author": {
+ "name": "Cursor",
+ "email": "plugins@cursor.com"
+ }
+ },
+ {
+ "name": "google-sheets",
+ "description": "Connect Cursor to Google Sheets via Google's remote MCP server — read spreadsheets, update values and formulas.",
+ "source": "./google-sheets",
+ "category": "developer-tools",
+ "author": {
+ "name": "Cursor",
+ "email": "plugins@cursor.com"
+ }
+ },
+ {
+ "name": "google-slides",
+ "description": "Connect Cursor to Google Slides via Google's remote MCP server — read and update presentations.",
+ "source": "./google-slides",
+ "category": "developer-tools",
+ "author": {
+ "name": "Cursor",
+ "email": "plugins@cursor.com"
+ }
}
]
}
diff --git a/.cursor-plugin/marketplace.json b/.cursor-plugin/marketplace.json
index 49f6d8ec..1c242dd8 100644
--- a/.cursor-plugin/marketplace.json
+++ b/.cursor-plugin/marketplace.json
@@ -72,6 +72,36 @@
"name": "pstack",
"source": "pstack",
"description": "if you want to go fast, go deep first. pstack helps you write less, but higher quality code. rigorous agent workflows you can parallelize with confidence."
+ },
+ {
+ "name": "gmail",
+ "source": "gmail",
+ "description": "Connect Cursor to Gmail via Google's remote MCP server — search, read, draft, label, and manage email."
+ },
+ {
+ "name": "google-drive",
+ "source": "google-drive",
+ "description": "Connect Cursor to Google Drive via Google's remote MCP server — search, read, create, share, and manage files."
+ },
+ {
+ "name": "google-calendar",
+ "source": "google-calendar",
+ "description": "Connect Cursor to Google Calendar via Google's remote MCP server — list calendars, search events, and create or update meetings."
+ },
+ {
+ "name": "google-docs",
+ "source": "google-docs",
+ "description": "Connect Cursor to Google Docs via Google's remote MCP server — read and update documents."
+ },
+ {
+ "name": "google-sheets",
+ "source": "google-sheets",
+ "description": "Connect Cursor to Google Sheets via Google's remote MCP server — read spreadsheets, update values and formulas."
+ },
+ {
+ "name": "google-slides",
+ "source": "google-slides",
+ "description": "Connect Cursor to Google Slides via Google's remote MCP server — read and update presentations."
}
]
}
diff --git a/README.md b/README.md
index 22d2eaab..0e751275 100644
--- a/README.md
+++ b/README.md
@@ -38,6 +38,12 @@ You can install as many plugins as you need:
| `cursor-sdk` | [Cursor SDK](cursor-sdk/) | Cursor | Developer Tools | Build apps, scripts, CI pipelines, and automations on top of the Cursor TypeScript SDK (@cursor/sdk) — runtime selection, auth, streaming, MCP, error handling, and ready-to-extend integration patterns. |
| `orchestrate` | [Orchestrate](orchestrate/) | Cursor | Developer Tools | Fan large tasks out across parallel Cursor cloud agents with planners, workers, verifiers, and structured handoffs. |
| `pstack` | [pstack](pstack/) | Lauren Tan | Developer Tools | if you want to go fast, go deep first. pstack helps you write less, but higher quality code. rigorous agent workflows you can parallelize with confidence. |
+| `gmail` | [Gmail](gmail/) | Cursor | Developer Tools | Connect Cursor to Gmail via Google's remote MCP server — search, read, draft, label, and manage email. |
+| `google-calendar` | [Google Calendar](google-calendar/) | Cursor | Developer Tools | Connect Cursor to Google Calendar via Google's remote MCP server — list calendars, search events, and create or update meetings. |
+| `google-docs` | [Google Docs](google-docs/) | Cursor | Developer Tools | Connect Cursor to Google Docs via Google's remote MCP server — read and update documents. |
+| `google-drive` | [Google Drive](google-drive/) | Cursor | Developer Tools | Connect Cursor to Google Drive via Google's remote MCP server — search, read, create, share, and manage files. |
+| `google-sheets` | [Google Sheets](google-sheets/) | Cursor | Developer Tools | Connect Cursor to Google Sheets via Google's remote MCP server — read spreadsheets, update values and formulas. |
+| `google-slides` | [Google Slides](google-slides/) | Cursor | Developer Tools | Connect Cursor to Google Slides via Google's remote MCP server — read and update presentations. |
## What changed from upstream
diff --git a/gmail/.claude-plugin/plugin.json b/gmail/.claude-plugin/plugin.json
new file mode 100644
index 00000000..1f6a66f4
--- /dev/null
+++ b/gmail/.claude-plugin/plugin.json
@@ -0,0 +1,8 @@
+{
+ "name": "gmail",
+ "description": "Connect Cursor to Gmail via Google's remote MCP server — search, read, draft, label, and manage email.",
+ "author": {
+ "name": "Cursor",
+ "email": "plugins@cursor.com"
+ }
+}
diff --git a/gmail/.cursor-plugin/plugin.json b/gmail/.cursor-plugin/plugin.json
new file mode 100644
index 00000000..e18dfb96
--- /dev/null
+++ b/gmail/.cursor-plugin/plugin.json
@@ -0,0 +1,29 @@
+{
+ "name": "gmail",
+ "displayName": "Gmail",
+ "version": "1.0.0",
+ "description": "Connect Cursor to Gmail via Google's remote MCP server — search, read, draft, label, and manage email.",
+ "author": {
+ "name": "Cursor",
+ "email": "plugins@cursor.com"
+ },
+ "homepage": "https://github.com/cursor/plugins/tree/main/gmail",
+ "repository": "https://github.com/cursor/plugins",
+ "license": "MIT",
+ "logo": "assets/logo.svg",
+ "keywords": [
+ "gmail",
+ "email",
+ "google",
+ "mcp",
+ "workspace"
+ ],
+ "category": "productivity",
+ "tags": [
+ "gmail",
+ "email",
+ "mcp",
+ "google-workspace"
+ ],
+ "mcpServers": "./mcp.json"
+}
diff --git a/gmail/CHANGELOG.md b/gmail/CHANGELOG.md
new file mode 100644
index 00000000..cb029bd2
--- /dev/null
+++ b/gmail/CHANGELOG.md
@@ -0,0 +1,8 @@
+# Changelog
+
+All notable changes to this plugin will be documented here.
+
+## 1.0.0 — initial release
+
+- Logo: official Gmail 2026 product icon from Google productlogos.
+- Added the `gmail` MCP server pointing at `https://gmailmcp.googleapis.com/mcp/v1`.
diff --git a/gmail/LICENSE b/gmail/LICENSE
new file mode 100644
index 00000000..ca2bba77
--- /dev/null
+++ b/gmail/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2026 Cursor
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/gmail/README.md b/gmail/README.md
new file mode 100644
index 00000000..98b4d0b5
--- /dev/null
+++ b/gmail/README.md
@@ -0,0 +1,40 @@
+# Gmail
+
+Cursor plugin that connects agents to [Gmail](https://mail.google.com) through Google's remote [Model Context Protocol](https://modelcontextprotocol.io/) server.
+
+Search threads, read messages, manage labels and drafts, and compose mail in the signed-in Gmail account.
+
+## Install
+
+1. Open **Cursor Settings → Plugins**.
+2. Search for **Gmail**.
+3. Click **Install**, then complete the Google sign-in prompt.
+
+Or run `/add-plugin gmail` in chat.
+
+## MCP
+
+```json
+{
+ "mcpServers": {
+ "gmail": {
+ "type": "http",
+ "url": "https://gmailmcp.googleapis.com/mcp/v1"
+ }
+ }
+}
+```
+
+Auth is OAuth 2.0 against Google. Cursor prompts for Google sign-in when the plugin connects.
+
+## Docs
+
+- Google MCP setup: https://developers.google.com/workspace/gmail/api/guides/configure-mcp-server
+- Workspace MCP overview: https://developers.google.com/workspace/guides/configure-mcp-servers
+
+Logo is the official Gmail product icon:
+https://www.gstatic.com/images/branding/productlogos/gmail_2026/v1/192px.svg
+
+## License
+
+MIT
diff --git a/gmail/assets/logo.svg b/gmail/assets/logo.svg
new file mode 100644
index 00000000..7da6ca5b
--- /dev/null
+++ b/gmail/assets/logo.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/gmail/mcp.json b/gmail/mcp.json
new file mode 100644
index 00000000..466b82b2
--- /dev/null
+++ b/gmail/mcp.json
@@ -0,0 +1,8 @@
+{
+ "mcpServers": {
+ "gmail": {
+ "type": "http",
+ "url": "https://gmailmcp.googleapis.com/mcp/v1"
+ }
+ }
+}
diff --git a/google-calendar/.claude-plugin/plugin.json b/google-calendar/.claude-plugin/plugin.json
new file mode 100644
index 00000000..e1a569f4
--- /dev/null
+++ b/google-calendar/.claude-plugin/plugin.json
@@ -0,0 +1,8 @@
+{
+ "name": "google-calendar",
+ "description": "Connect Cursor to Google Calendar via Google's remote MCP server — list calendars, search events, and create or update meetings.",
+ "author": {
+ "name": "Cursor",
+ "email": "plugins@cursor.com"
+ }
+}
diff --git a/google-calendar/.cursor-plugin/plugin.json b/google-calendar/.cursor-plugin/plugin.json
new file mode 100644
index 00000000..f01c79b9
--- /dev/null
+++ b/google-calendar/.cursor-plugin/plugin.json
@@ -0,0 +1,30 @@
+{
+ "name": "google-calendar",
+ "displayName": "Google Calendar",
+ "version": "1.0.0",
+ "description": "Connect Cursor to Google Calendar via Google's remote MCP server — list calendars, search events, and create or update meetings.",
+ "author": {
+ "name": "Cursor",
+ "email": "plugins@cursor.com"
+ },
+ "homepage": "https://github.com/cursor/plugins/tree/main/google-calendar",
+ "repository": "https://github.com/cursor/plugins",
+ "license": "MIT",
+ "logo": "assets/logo.svg",
+ "keywords": [
+ "google-calendar",
+ "calendar",
+ "google",
+ "mcp",
+ "events",
+ "workspace"
+ ],
+ "category": "productivity",
+ "tags": [
+ "calendar",
+ "events",
+ "mcp",
+ "google-workspace"
+ ],
+ "mcpServers": "./mcp.json"
+}
diff --git a/google-calendar/CHANGELOG.md b/google-calendar/CHANGELOG.md
new file mode 100644
index 00000000..8d9ebf39
--- /dev/null
+++ b/google-calendar/CHANGELOG.md
@@ -0,0 +1,8 @@
+# Changelog
+
+All notable changes to this plugin will be documented here.
+
+## 1.0.0 — initial release
+
+- Logo: official Google Calendar 2026 product icon from Google productlogos.
+- Added the `google-calendar` MCP server pointing at `https://calendarmcp.googleapis.com/mcp/v1`.
diff --git a/google-calendar/LICENSE b/google-calendar/LICENSE
new file mode 100644
index 00000000..ca2bba77
--- /dev/null
+++ b/google-calendar/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2026 Cursor
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/google-calendar/README.md b/google-calendar/README.md
new file mode 100644
index 00000000..ca3f5028
--- /dev/null
+++ b/google-calendar/README.md
@@ -0,0 +1,40 @@
+# Google Calendar
+
+Cursor plugin that connects agents to [Google Calendar](https://calendar.google.com) through Google's remote [Model Context Protocol](https://modelcontextprotocol.io/) server.
+
+List calendars, search and inspect events, suggest times, and create, update, or respond to meetings.
+
+## Install
+
+1. Open **Cursor Settings → Plugins**.
+2. Search for **Google Calendar**.
+3. Click **Install**, then complete the Google sign-in prompt.
+
+Or run `/add-plugin google-calendar` in chat.
+
+## MCP
+
+```json
+{
+ "mcpServers": {
+ "google-calendar": {
+ "type": "http",
+ "url": "https://calendarmcp.googleapis.com/mcp/v1"
+ }
+ }
+}
+```
+
+Auth is OAuth 2.0 against Google. Cursor prompts for Google sign-in when the plugin connects.
+
+## Docs
+
+- Google MCP setup: https://developers.google.com/workspace/calendar/api/guides/configure-mcp-server
+- Workspace MCP overview: https://developers.google.com/workspace/guides/configure-mcp-servers
+
+Logo is the official Google Calendar product icon:
+https://www.gstatic.com/images/branding/productlogos/calendar_2026/v1/192px.svg
+
+## License
+
+MIT
diff --git a/google-calendar/assets/logo.svg b/google-calendar/assets/logo.svg
new file mode 100644
index 00000000..39359cab
--- /dev/null
+++ b/google-calendar/assets/logo.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/google-calendar/mcp.json b/google-calendar/mcp.json
new file mode 100644
index 00000000..4b50f26f
--- /dev/null
+++ b/google-calendar/mcp.json
@@ -0,0 +1,8 @@
+{
+ "mcpServers": {
+ "google-calendar": {
+ "type": "http",
+ "url": "https://calendarmcp.googleapis.com/mcp/v1"
+ }
+ }
+}
diff --git a/google-docs/.claude-plugin/plugin.json b/google-docs/.claude-plugin/plugin.json
new file mode 100644
index 00000000..1f3235b5
--- /dev/null
+++ b/google-docs/.claude-plugin/plugin.json
@@ -0,0 +1,8 @@
+{
+ "name": "google-docs",
+ "description": "Connect Cursor to Google Docs via Google's remote MCP server — read and update documents.",
+ "author": {
+ "name": "Cursor",
+ "email": "plugins@cursor.com"
+ }
+}
diff --git a/google-docs/.cursor-plugin/plugin.json b/google-docs/.cursor-plugin/plugin.json
new file mode 100644
index 00000000..cd5ae60a
--- /dev/null
+++ b/google-docs/.cursor-plugin/plugin.json
@@ -0,0 +1,30 @@
+{
+ "name": "google-docs",
+ "displayName": "Google Docs",
+ "version": "1.0.0",
+ "description": "Connect Cursor to Google Docs via Google's remote MCP server — read and update documents.",
+ "author": {
+ "name": "Cursor",
+ "email": "plugins@cursor.com"
+ },
+ "homepage": "https://github.com/cursor/plugins/tree/main/google-docs",
+ "repository": "https://github.com/cursor/plugins",
+ "license": "MIT",
+ "logo": "assets/logo.svg",
+ "keywords": [
+ "google-docs",
+ "docs",
+ "documents",
+ "google",
+ "mcp",
+ "workspace"
+ ],
+ "category": "productivity",
+ "tags": [
+ "docs",
+ "documents",
+ "mcp",
+ "google-workspace"
+ ],
+ "mcpServers": "./mcp.json"
+}
diff --git a/google-docs/CHANGELOG.md b/google-docs/CHANGELOG.md
new file mode 100644
index 00000000..6f9426ec
--- /dev/null
+++ b/google-docs/CHANGELOG.md
@@ -0,0 +1,8 @@
+# Changelog
+
+All notable changes to this plugin will be documented here.
+
+## 1.0.0 — initial release
+
+- Logo: official Google Docs 2026 product icon from Google productlogos.
+- Added the `google-docs` MCP server pointing at `https://docsmcp.googleapis.com/mcp/v1`.
diff --git a/google-docs/LICENSE b/google-docs/LICENSE
new file mode 100644
index 00000000..ca2bba77
--- /dev/null
+++ b/google-docs/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2026 Cursor
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/google-docs/README.md b/google-docs/README.md
new file mode 100644
index 00000000..9a6994aa
--- /dev/null
+++ b/google-docs/README.md
@@ -0,0 +1,40 @@
+# Google Docs
+
+Cursor plugin that connects agents to [Google Docs](https://docs.google.com) through Google's remote [Model Context Protocol](https://modelcontextprotocol.io/) server.
+
+Read Google Docs and apply updates in the signed-in Workspace account.
+
+## Install
+
+1. Open **Cursor Settings → Plugins**.
+2. Search for **Google Docs**.
+3. Click **Install**, then complete the Google sign-in prompt.
+
+Or run `/add-plugin google-docs` in chat.
+
+## MCP
+
+```json
+{
+ "mcpServers": {
+ "google-docs": {
+ "type": "http",
+ "url": "https://docsmcp.googleapis.com/mcp/v1"
+ }
+ }
+}
+```
+
+Auth is OAuth 2.0 against Google. Cursor prompts for Google sign-in when the plugin connects.
+
+## Docs
+
+- Google MCP setup: https://developers.google.com/workspace/docs/api/guides/configure-mcp-server
+- Workspace MCP overview: https://developers.google.com/workspace/guides/configure-mcp-servers
+
+Logo is the official Google Docs product icon:
+https://www.gstatic.com/images/branding/productlogos/docs_2026/v1/192px.svg
+
+## License
+
+MIT
diff --git a/google-docs/assets/logo.svg b/google-docs/assets/logo.svg
new file mode 100644
index 00000000..a74be962
--- /dev/null
+++ b/google-docs/assets/logo.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/google-docs/mcp.json b/google-docs/mcp.json
new file mode 100644
index 00000000..84325e7b
--- /dev/null
+++ b/google-docs/mcp.json
@@ -0,0 +1,8 @@
+{
+ "mcpServers": {
+ "google-docs": {
+ "type": "http",
+ "url": "https://docsmcp.googleapis.com/mcp/v1"
+ }
+ }
+}
diff --git a/google-drive/.claude-plugin/plugin.json b/google-drive/.claude-plugin/plugin.json
new file mode 100644
index 00000000..a15ba3d3
--- /dev/null
+++ b/google-drive/.claude-plugin/plugin.json
@@ -0,0 +1,8 @@
+{
+ "name": "google-drive",
+ "description": "Connect Cursor to Google Drive via Google's remote MCP server — search, read, create, share, and manage files.",
+ "author": {
+ "name": "Cursor",
+ "email": "plugins@cursor.com"
+ }
+}
diff --git a/google-drive/.cursor-plugin/plugin.json b/google-drive/.cursor-plugin/plugin.json
new file mode 100644
index 00000000..5cee94c9
--- /dev/null
+++ b/google-drive/.cursor-plugin/plugin.json
@@ -0,0 +1,30 @@
+{
+ "name": "google-drive",
+ "displayName": "Google Drive",
+ "version": "1.0.0",
+ "description": "Connect Cursor to Google Drive via Google's remote MCP server — search, read, create, share, and manage files.",
+ "author": {
+ "name": "Cursor",
+ "email": "plugins@cursor.com"
+ },
+ "homepage": "https://github.com/cursor/plugins/tree/main/google-drive",
+ "repository": "https://github.com/cursor/plugins",
+ "license": "MIT",
+ "logo": "assets/logo.svg",
+ "keywords": [
+ "google-drive",
+ "drive",
+ "google",
+ "mcp",
+ "files",
+ "workspace"
+ ],
+ "category": "productivity",
+ "tags": [
+ "drive",
+ "files",
+ "mcp",
+ "google-workspace"
+ ],
+ "mcpServers": "./mcp.json"
+}
diff --git a/google-drive/CHANGELOG.md b/google-drive/CHANGELOG.md
new file mode 100644
index 00000000..4ab245cf
--- /dev/null
+++ b/google-drive/CHANGELOG.md
@@ -0,0 +1,8 @@
+# Changelog
+
+All notable changes to this plugin will be documented here.
+
+## 1.0.0 — initial release
+
+- Logo: official Google Drive 2026 product icon from Google productlogos.
+- Added the `google-drive` MCP server pointing at `https://drivemcp.googleapis.com/mcp/v1`.
diff --git a/google-drive/LICENSE b/google-drive/LICENSE
new file mode 100644
index 00000000..ca2bba77
--- /dev/null
+++ b/google-drive/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2026 Cursor
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/google-drive/README.md b/google-drive/README.md
new file mode 100644
index 00000000..949375c1
--- /dev/null
+++ b/google-drive/README.md
@@ -0,0 +1,40 @@
+# Google Drive
+
+Cursor plugin that connects agents to [Google Drive](https://drive.google.com) through Google's remote [Model Context Protocol](https://modelcontextprotocol.io/) server.
+
+Search Drive, read file metadata and contents, create or update files, and manage sharing.
+
+## Install
+
+1. Open **Cursor Settings → Plugins**.
+2. Search for **Google Drive**.
+3. Click **Install**, then complete the Google sign-in prompt.
+
+Or run `/add-plugin google-drive` in chat.
+
+## MCP
+
+```json
+{
+ "mcpServers": {
+ "google-drive": {
+ "type": "http",
+ "url": "https://drivemcp.googleapis.com/mcp/v1"
+ }
+ }
+}
+```
+
+Auth is OAuth 2.0 against Google. Cursor prompts for Google sign-in when the plugin connects.
+
+## Docs
+
+- Google MCP setup: https://developers.google.com/workspace/drive/api/guides/configure-mcp-server
+- Workspace MCP overview: https://developers.google.com/workspace/guides/configure-mcp-servers
+
+Logo is the official Google Drive product icon:
+https://www.gstatic.com/images/branding/productlogos/drive_2026/v1/192px.svg
+
+## License
+
+MIT
diff --git a/google-drive/assets/logo.svg b/google-drive/assets/logo.svg
new file mode 100644
index 00000000..9144b20f
--- /dev/null
+++ b/google-drive/assets/logo.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/google-drive/mcp.json b/google-drive/mcp.json
new file mode 100644
index 00000000..a372f915
--- /dev/null
+++ b/google-drive/mcp.json
@@ -0,0 +1,8 @@
+{
+ "mcpServers": {
+ "google-drive": {
+ "type": "http",
+ "url": "https://drivemcp.googleapis.com/mcp/v1"
+ }
+ }
+}
diff --git a/google-sheets/.claude-plugin/plugin.json b/google-sheets/.claude-plugin/plugin.json
new file mode 100644
index 00000000..da89411d
--- /dev/null
+++ b/google-sheets/.claude-plugin/plugin.json
@@ -0,0 +1,8 @@
+{
+ "name": "google-sheets",
+ "description": "Connect Cursor to Google Sheets via Google's remote MCP server — read spreadsheets, update values and formulas.",
+ "author": {
+ "name": "Cursor",
+ "email": "plugins@cursor.com"
+ }
+}
diff --git a/google-sheets/.cursor-plugin/plugin.json b/google-sheets/.cursor-plugin/plugin.json
new file mode 100644
index 00000000..89ac90f9
--- /dev/null
+++ b/google-sheets/.cursor-plugin/plugin.json
@@ -0,0 +1,30 @@
+{
+ "name": "google-sheets",
+ "displayName": "Google Sheets",
+ "version": "1.0.0",
+ "description": "Connect Cursor to Google Sheets via Google's remote MCP server — read spreadsheets, update values and formulas.",
+ "author": {
+ "name": "Cursor",
+ "email": "plugins@cursor.com"
+ },
+ "homepage": "https://github.com/cursor/plugins/tree/main/google-sheets",
+ "repository": "https://github.com/cursor/plugins",
+ "license": "MIT",
+ "logo": "assets/logo.svg",
+ "keywords": [
+ "google-sheets",
+ "sheets",
+ "spreadsheet",
+ "google",
+ "mcp",
+ "workspace"
+ ],
+ "category": "productivity",
+ "tags": [
+ "sheets",
+ "spreadsheet",
+ "mcp",
+ "google-workspace"
+ ],
+ "mcpServers": "./mcp.json"
+}
diff --git a/google-sheets/CHANGELOG.md b/google-sheets/CHANGELOG.md
new file mode 100644
index 00000000..21441d9f
--- /dev/null
+++ b/google-sheets/CHANGELOG.md
@@ -0,0 +1,8 @@
+# Changelog
+
+All notable changes to this plugin will be documented here.
+
+## 1.0.0 — initial release
+
+- Logo: official Google Sheets 2026 product icon from Google productlogos.
+- Added the `google-sheets` MCP server pointing at `https://sheetsmcp.googleapis.com/mcp/v1`.
diff --git a/google-sheets/LICENSE b/google-sheets/LICENSE
new file mode 100644
index 00000000..ca2bba77
--- /dev/null
+++ b/google-sheets/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2026 Cursor
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/google-sheets/README.md b/google-sheets/README.md
new file mode 100644
index 00000000..a3b2a52c
--- /dev/null
+++ b/google-sheets/README.md
@@ -0,0 +1,40 @@
+# Google Sheets
+
+Cursor plugin that connects agents to [Google Sheets](https://sheets.google.com) through Google's remote [Model Context Protocol](https://modelcontextprotocol.io/) server.
+
+Read spreadsheet values, update cells and formulas, and copy sheets between spreadsheets.
+
+## Install
+
+1. Open **Cursor Settings → Plugins**.
+2. Search for **Google Sheets**.
+3. Click **Install**, then complete the Google sign-in prompt.
+
+Or run `/add-plugin google-sheets` in chat.
+
+## MCP
+
+```json
+{
+ "mcpServers": {
+ "google-sheets": {
+ "type": "http",
+ "url": "https://sheetsmcp.googleapis.com/mcp/v1"
+ }
+ }
+}
+```
+
+Auth is OAuth 2.0 against Google. Cursor prompts for Google sign-in when the plugin connects.
+
+## Docs
+
+- Google MCP setup: https://developers.google.com/workspace/sheets/api/guides/configure-mcp-server
+- Workspace MCP overview: https://developers.google.com/workspace/guides/configure-mcp-servers
+
+Logo is the official Google Sheets product icon:
+https://www.gstatic.com/images/branding/productlogos/sheets_2026/v1/192px.svg
+
+## License
+
+MIT
diff --git a/google-sheets/assets/logo.svg b/google-sheets/assets/logo.svg
new file mode 100644
index 00000000..64cac115
--- /dev/null
+++ b/google-sheets/assets/logo.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/google-sheets/mcp.json b/google-sheets/mcp.json
new file mode 100644
index 00000000..f6232435
--- /dev/null
+++ b/google-sheets/mcp.json
@@ -0,0 +1,8 @@
+{
+ "mcpServers": {
+ "google-sheets": {
+ "type": "http",
+ "url": "https://sheetsmcp.googleapis.com/mcp/v1"
+ }
+ }
+}
diff --git a/google-slides/.claude-plugin/plugin.json b/google-slides/.claude-plugin/plugin.json
new file mode 100644
index 00000000..ce495b80
--- /dev/null
+++ b/google-slides/.claude-plugin/plugin.json
@@ -0,0 +1,8 @@
+{
+ "name": "google-slides",
+ "description": "Connect Cursor to Google Slides via Google's remote MCP server — read and update presentations.",
+ "author": {
+ "name": "Cursor",
+ "email": "plugins@cursor.com"
+ }
+}
diff --git a/google-slides/.cursor-plugin/plugin.json b/google-slides/.cursor-plugin/plugin.json
new file mode 100644
index 00000000..43236a18
--- /dev/null
+++ b/google-slides/.cursor-plugin/plugin.json
@@ -0,0 +1,30 @@
+{
+ "name": "google-slides",
+ "displayName": "Google Slides",
+ "version": "1.0.0",
+ "description": "Connect Cursor to Google Slides via Google's remote MCP server — read and update presentations.",
+ "author": {
+ "name": "Cursor",
+ "email": "plugins@cursor.com"
+ },
+ "homepage": "https://github.com/cursor/plugins/tree/main/google-slides",
+ "repository": "https://github.com/cursor/plugins",
+ "license": "MIT",
+ "logo": "assets/logo.svg",
+ "keywords": [
+ "google-slides",
+ "slides",
+ "presentations",
+ "google",
+ "mcp",
+ "workspace"
+ ],
+ "category": "productivity",
+ "tags": [
+ "slides",
+ "presentations",
+ "mcp",
+ "google-workspace"
+ ],
+ "mcpServers": "./mcp.json"
+}
diff --git a/google-slides/CHANGELOG.md b/google-slides/CHANGELOG.md
new file mode 100644
index 00000000..3c3ff402
--- /dev/null
+++ b/google-slides/CHANGELOG.md
@@ -0,0 +1,8 @@
+# Changelog
+
+All notable changes to this plugin will be documented here.
+
+## 1.0.0 — initial release
+
+- Logo: official Google Slides 2026 product icon from Google productlogos.
+- Added the `google-slides` MCP server pointing at `https://slidesmcp.googleapis.com/mcp/v1`.
diff --git a/google-slides/LICENSE b/google-slides/LICENSE
new file mode 100644
index 00000000..ca2bba77
--- /dev/null
+++ b/google-slides/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2026 Cursor
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/google-slides/README.md b/google-slides/README.md
new file mode 100644
index 00000000..096ca3e5
--- /dev/null
+++ b/google-slides/README.md
@@ -0,0 +1,40 @@
+# Google Slides
+
+Cursor plugin that connects agents to [Google Slides](https://slides.google.com) through Google's remote [Model Context Protocol](https://modelcontextprotocol.io/) server.
+
+Read Google Slides presentations and apply updates in the signed-in Workspace account.
+
+## Install
+
+1. Open **Cursor Settings → Plugins**.
+2. Search for **Google Slides**.
+3. Click **Install**, then complete the Google sign-in prompt.
+
+Or run `/add-plugin google-slides` in chat.
+
+## MCP
+
+```json
+{
+ "mcpServers": {
+ "google-slides": {
+ "type": "http",
+ "url": "https://slidesmcp.googleapis.com/mcp/v1"
+ }
+ }
+}
+```
+
+Auth is OAuth 2.0 against Google. Cursor prompts for Google sign-in when the plugin connects.
+
+## Docs
+
+- Google MCP setup: https://developers.google.com/workspace/slides/api/guides/configure-mcp-server
+- Workspace MCP overview: https://developers.google.com/workspace/guides/configure-mcp-servers
+
+Logo is the official Google Slides product icon:
+https://www.gstatic.com/images/branding/productlogos/slides_2026/v1/192px.svg
+
+## License
+
+MIT
diff --git a/google-slides/assets/logo.svg b/google-slides/assets/logo.svg
new file mode 100644
index 00000000..73b2d362
--- /dev/null
+++ b/google-slides/assets/logo.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/google-slides/mcp.json b/google-slides/mcp.json
new file mode 100644
index 00000000..86def105
--- /dev/null
+++ b/google-slides/mcp.json
@@ -0,0 +1,8 @@
+{
+ "mcpServers": {
+ "google-slides": {
+ "type": "http",
+ "url": "https://slidesmcp.googleapis.com/mcp/v1"
+ }
+ }
+}
diff --git a/pstack/.cursor-plugin/plugin.json b/pstack/.cursor-plugin/plugin.json
index 7985be80..d66206bd 100644
--- a/pstack/.cursor-plugin/plugin.json
+++ b/pstack/.cursor-plugin/plugin.json
@@ -1,7 +1,7 @@
{
"name": "pstack",
"displayName": "pstack",
- "version": "0.11.13",
+ "version": "0.12.0",
"description": "if you want to go fast, go deep first. pstack helps you write less, but higher quality code. rigorous agent workflows you can parallelize with confidence.",
"author": {
"name": "Lauren Tan"
diff --git a/pstack/README.md b/pstack/README.md
index ad17785d..f4b44629 100644
--- a/pstack/README.md
+++ b/pstack/README.md
@@ -88,7 +88,7 @@ the full rules and playbooks live in [`skills/poteto-mode/SKILL.md`](./skills/po
## skills
-[`/poteto-mode`](./skills/poteto-mode/SKILL.md) runs most of these for you when a step needs them (`how`, `why`, `architect`, `arena`, `interrogate`, `unslop`, `tdd`, and the principles). the table below is for when you want one directly:
+[`/poteto-mode`](./skills/poteto-mode/SKILL.md) runs most of these for you when a step needs them (`how`, `why`, `architect`, `arena`, `swarm`, `interrogate`, `unslop`, `tdd`, and the principles). the table below is for when you want one directly:
```
/how do we cancel runs? do we have an n+1 when we look up every run to cancel?
@@ -110,6 +110,7 @@ the full rules and playbooks live in [`skills/poteto-mode/SKILL.md`](./skills/po
| [`/blast-radius`](./skills/blast-radius/SKILL.md) | you have a small-looking change and want to know what else it could break, with the one fact it's safe because of proven by running code, not asserted. |
| [`/architect`](./skills/architect/SKILL.md) | you're about to write code that crosses a function boundary and want the caller's usage, types, and module shape settled first. |
| [`/arena`](./skills/arena/SKILL.md) | you want N parallel attempts at the same thing, then to grab the best parts of each. |
+| [`/swarm`](./skills/swarm/SKILL.md) | you want N parallel workers across different slices or races, then one aggregated report. |
| [`/interrogate`](./skills/interrogate/SKILL.md) | you have a diff and want several different models to try to break it, including a strict code-quality lens. |
| [`/automate-me`](./skills/automate-me/SKILL.md) | you want your own `-mode` skill, drafted from how you've actually worked. |
| [`/setup-pstack`](./skills/setup-pstack/SKILL.md) | you want to pick which models pstack uses per role. detects your models and writes a config rule. |
@@ -158,6 +159,8 @@ architect: design this instrumentation to be high signal with no false p
this first.
arena: /arena take my prompt to the arena verbatim. i want to compare their proposals
with yours.
+swarm: /swarm check every package under packages/ against its check.sh. one worker per
+ package. one report.
interrogate: /interrogate review this pr.
tdd: /tdd implement
unslop: can we unslop and tighten the new changes?
diff --git a/pstack/docs/guide/01-setup.md b/pstack/docs/guide/01-setup.md
index e0269a01..8f30116c 100644
--- a/pstack/docs/guide/01-setup.md
+++ b/pstack/docs/guide/01-setup.md
@@ -24,7 +24,7 @@ Run:
You only override what you care about. A role with no line in the rule keeps the skill's default. To restore a default later, delete that role's line, or just run `/setup-pstack` again.
-You might be wondering what happens if you use Auto. Set a role to `inherit-parent` or `auto` and pstack omits the subagent `model` field, so the subagent inherits your parent chat model. Both values mean the same thing, and neither is a model slug. For a panel role the value is a list, and one subagent runs per entry, so the list length sets the panel size.
+You might be wondering what happens if you use Auto. Set a role to `inherit-parent` or `auto` and pstack omits the subagent `model` field, so the subagent inherits your parent chat model. Both values mean the same thing, and neither is a model slug. For a panel role the value is a list, and one subagent runs per entry, so the list length sets the panel size. Setup also configures `swarm workers`, the default model for every `/swarm` worker unless a race names a model for each arm.
## Accept the verification offer, or don't
diff --git a/pstack/docs/guide/04-design.md b/pstack/docs/guide/04-design.md
index b7fd716d..681d39cf 100644
--- a/pstack/docs/guide/04-design.md
+++ b/pstack/docs/guide/04-design.md
@@ -1,6 +1,6 @@
# Design before you write code
-One attempt at a hard design locks in the first shape the model thought of. These three skills exist so that doesn't happen. `/architect` settles types and boundaries before implementation. `/arena` runs several attempts in parallel and merges the best parts. `/interrogate` has other models try to break the result.
+One attempt at a hard design locks in the first shape the model thought of. `/architect` settles types and boundaries before implementation. `/arena` runs several attempts at the same brief and merges the best parts. `/interrogate` has other models try to break the result. When the job is coverage rather than design synthesis, `/swarm` fans out slices or races and aggregates their results.

@@ -24,7 +24,7 @@ By default it proceeds straight from the synthesized design into implementation.
/arena take my prompt to the arena verbatim. i want to compare their proposals with yours.
```
-[`/arena`](../../skills/arena/SKILL.md) is the general tool underneath. N subagents attempt the same task in parallel, each writing to its own worktree or directory. A read-only judge, on a different model family when your configuration allows one, scores every candidate against a rubric. The coordinator reads each candidate end to end, picks a base, grafts in the best ideas from the losers, and verifies the result.
+[`/arena`](../../skills/arena/SKILL.md) is the general tool underneath. N subagents attempt the same design or code brief in parallel, each writing to its own worktree or directory. A read-only judge, on a different model family when your configuration allows one, scores every candidate against a rubric. The coordinator reads each candidate end to end, picks a base, grafts in the best ideas from the losers, and verifies the result.
```mermaid
flowchart LR
@@ -46,6 +46,16 @@ The panel comes from your [`/setup-pstack`](../../skills/setup-pstack/SKILL.md)
/arena this, 5 candidates. the cache key format is expensive to change later.
```
+## Cover slices and races with `/swarm`
+
+```text
+/swarm check every package under packages/ against its check.sh. one worker per package. one report.
+```
+
+[`/swarm`](../../skills/swarm/SKILL.md) fans N workers across independent slices, coverage matrices, gauntlet lanes, exploration partitions, or declared race arms. Each worker gets its own scope and check, then reports `PASS`, `ISSUES`, or `BLOCKED`. The parent waits for the workers and returns one compact report with any gaps or dropouts.
+
+Reach for it when parallelism buys coverage or lets independent checks race. `/arena` gives every worker the same design or code brief, then picks a base and grafts the best parts. `/swarm` covers slices or runs a race with a selection rule declared up front. It does not use the base-selection and grafting ceremony.
+
## Break it with `/interrogate`
```text
@@ -63,6 +73,7 @@ You might be wondering whether every change needs this. No. Most changes need no
- A small, finished change you're unsure about needs `/interrogate` alone.
- A change that crosses function boundaries or moves ownership earns `/architect`, which brings `/arena` with it.
- A standalone decision where independent attempts would help, like naming, formats, or an algorithm, is `/arena` directly.
+- A coverage matrix, set of parallel checks, or race with declared arms is `/swarm`.
- A contested design that's expensive to reverse gets `/architect`, then `/interrogate` before shipping.
`/poteto-mode` already applies this ladder. Boundary-crossing work triggers `/architect` on its own, so you reach for these directly mainly when you want more or less scrutiny than the default.
diff --git a/pstack/docs/guide/06-verify-and-ship.md b/pstack/docs/guide/06-verify-and-ship.md
index e87418cf..2a84d2a8 100644
--- a/pstack/docs/guide/06-verify-and-ship.md
+++ b/pstack/docs/guide/06-verify-and-ship.md
@@ -34,10 +34,12 @@ The UI bullet above hides a real requirement. The agent needs a scripted way to
[`/create-verification-skill`](../../skills/create-verification-skill/SKILL.md) interviews the repository, not you. It works out what a user touches, how the app launches locally, what can drive it (an existing harness first, otherwise browser and CDP, a PTY, or plain HTTP), what evidence proves behavior, and whether two instances can run side by side. It asks you only what the code can't answer.
-It writes `.cursor/skills/verify-/`, agent-facing instructions with exact Launch, Doctor, Drive, Evidence, and Cleanup sections, plus a feature map under `features/` that indexes what the app does and what result proves each feature works. Before handing it over, the generator proves the skill once end to end: launch, doctor check, drive one feature, capture evidence, clean up. If that proof fails, don't use the output.
+It writes `.cursor/skills/verify-/`, agent-facing instructions with exact Launch, Doctor, Drive, Evidence, and Cleanup sections, plus a feature map under `features/` that indexes what the app does and what result proves each feature works. The skill ships a [worked feature-map example](../../skills/create-verification-skill/references/feature-map-example/) with a README index and one file per feature using the four required H2s. Before handing it over, the generator proves the skill once end to end: launch, doctor check, drive one feature, capture evidence, clean up. If that proof fails, don't use the output.
From then on, "verify it in the app" is a step any agent can execute, in this repo, with no setup conversation.
+Once the verify skill works, a [`/swarm`](../../skills/swarm/SKILL.md) can split a full pass by feature-map entry and aggregate the results.
+
## Keep the verification skill honest
Apps change and feature maps rot. When yours drifts, run:
diff --git a/pstack/docs/guide/10-recipes-and-pitfalls.md b/pstack/docs/guide/10-recipes-and-pitfalls.md
index 053401fc..81176d66 100644
--- a/pstack/docs/guide/10-recipes-and-pitfalls.md
+++ b/pstack/docs/guide/10-recipes-and-pitfalls.md
@@ -20,6 +20,14 @@ ask /arena for a second opinion on this thread and our approach
Your current design becomes one candidate among several, and the synthesis tells you whether the panel found something better or confirmed what you had. Cheap insurance before a costly commitment.
+## Check independent slices in parallel
+
+```text
+/swarm check every package under packages/ against its check.sh. one worker per package. one report.
+```
+
+Each worker owns one package. The parent waits for every slice and returns one `PASS`, `ISSUES`, or `BLOCKED` report instead of raw worker dumps.
+
## Review a branch skeptically
```text
@@ -67,6 +75,7 @@ You rarely need more words. You need the right name, and [the principles page](.
- **Enumerating skills in the prompt.** "use /how then /architect then /arena" reorders steps the playbook already sequences. State the goal and constraints. Name a skill only to override a default.
- **A vague finish condition.** "make it better" gives `/loop` nothing to check. Give a command or artifact that can pass or fail.
- **Parallel agents in one worktree.** They overwrite each other and the diff becomes archaeology. Say "own worktree per attempt" and the isolation is free.
+- **Using `/arena` for coverage.** `/arena` repeats one design or code brief, then picks a base and grafts the best parts. `/swarm` partitions slices or declared race arms and aggregates one report.
- **Accepting every review comment.** Bots and humans both file real catches and noise in one list. `/interrogate` sorts findings into act-on and dismissed buckets with reasons, and you can override either way.
- **Treating `auto` as a model slug.** `auto` and `inherit-parent` mean "omit the model field so the subagent inherits the parent chat model." [Setup](./01-setup.md) covers the roles.
- **Reporting success off a green build.** A build proves it compiles. Ask for the real command, flow, stored value, or profile, and expect the evidence in the reply.
diff --git a/pstack/docs/guide/README.md b/pstack/docs/guide/README.md
index ab39e21d..f6fd3e80 100644
--- a/pstack/docs/guide/README.md
+++ b/pstack/docs/guide/README.md
@@ -7,7 +7,7 @@ Here's what you'll learn:
1. [Set up pstack](./01-setup.md). Install the plugin and pick your models.
2. [Route work through `/poteto-mode`](./02-poteto-mode.md). Give it a goal and watch it pick a playbook.
3. [Understand the code](./03-understand.md). `/how`, `/why`, `/teach`, and `/recall` before you edit anything.
-4. [Design the change](./04-design.md). `/architect`, `/arena`, and `/interrogate` before code locks in a shape.
+4. [Design the change](./04-design.md). `/architect`, `/arena`, `/swarm`, and `/interrogate` before code locks in a shape.
5. [Build and clean the change](./05-build-and-clean.md). The build playbooks, `/tdd`, and `/unslop`.
6. [Verify and ship](./06-verify-and-ship.md). Prove behavior on the real app, then open a focused PR.
7. [Run work while you sleep](./07-overnight.md). An overnight contract and a decision log you can audit.
diff --git a/pstack/skills/create-verification-skill/SKILL.md b/pstack/skills/create-verification-skill/SKILL.md
index db06674d..f869e261 100644
--- a/pstack/skills/create-verification-skill/SKILL.md
+++ b/pstack/skills/create-verification-skill/SKILL.md
@@ -33,7 +33,7 @@ Write `.cursor/skills/verify-/SKILL.md` with YAML frontmatter (`name: verif
## 3. Seed the feature map
-Create `.cursor/skills/verify-/features/README.md` plus one file per user-facing feature you can identify (aim for the top 3-5 to start, from routes, commands, menus, or docs). Each file answers, from the user's point of view: what the feature is, how to reach it, how to drive it with the harness, and what observable end state proves it works. The map is the repo's maintained verification source; a proof that drives one convenient entry point is incomplete when the map lists others.
+Create `.cursor/skills/verify-/features/README.md` plus one file per user-facing feature you can identify (aim for the top 3-5 to start, from routes, commands, menus, or docs). Follow the shape in [`references/feature-map-example/`](references/feature-map-example/), with a README index and one file per feature. Each file answers, from the user's point of view: what the feature is, how to reach it, how to drive it with the harness, and what observable end state proves it works. The four H2s are `Sub-features`, `How to get to it (user POV)`, `Driving it with `, and `Gotchas`. The map is the repo's maintained verification source; a proof that drives one convenient entry point is incomplete when the map lists others.
## 4. Prove the generated skill before handing it over
diff --git a/pstack/skills/create-verification-skill/references/feature-map-example/README.md b/pstack/skills/create-verification-skill/references/feature-map-example/README.md
new file mode 100644
index 00000000..fb64570c
--- /dev/null
+++ b/pstack/skills/create-verification-skill/references/feature-map-example/README.md
@@ -0,0 +1,47 @@
+# Notes verification map
+
+This directory is the maintained source for verifying the user-facing behavior of Notes. Read the index before driving the app, then use the matching feature file as the recipe.
+
+## Baseline preconditions
+
+- Launch Notes at `http://127.0.0.1:4173` with a disposable data directory.
+- Set `NOTES_DATA_DIR=/tmp/notes-verify-$RUN_ID` so concurrent runs do not share state.
+- Seed notes titled `Quarterly plan` and `Grocery list`.
+- Put `control-notes` and the `notes` CLI on `PATH`.
+- Run `control-notes doctor` and require the expected URL, data directory, and build revision.
+- Never drive an instance that was not started by this verification run.
+
+## Driving conventions
+
+- Start every recipe from the baseline state unless its preconditions say otherwise.
+- Prefer ARIA roles and accessible names over CSS selectors or DOM position.
+- Treat every command as literal. Keep quoted names and flags unchanged.
+- Run browser actions through `control-notes browser`.
+- Run terminal actions through `control-notes cli -- `.
+- Restore seeded data after a mutation. Do not remove proof artifacts during cleanup.
+
+## Proof and skip reporting
+
+- Capture the user action and the resulting state, not only the final screen.
+- UI proof includes an ARIA snapshot and a screenshot with the app identity visible.
+- CLI proof includes the command, stdout, stderr, and exit code.
+- Mutation proof includes a read-only second view of the stored value.
+- Record the feature ID and entry point used with every artifact.
+- Report an unreachable path with the attempted command and the unmet precondition.
+- Do not report a skipped entry point as verified through a different path.
+
+## Feature entry contract
+
+Each feature file starts with an H1 title and one paragraph describing the user-visible behavior. It then uses exactly four H2 sections in this order.
+
+1. `Sub-features` lists short IDs with one line for each behavior.
+2. `How to get to it (user POV)` lists every user entry point.
+3. `Driving it with ` starts with `Preconditions:` and uses labeled bullets that pair each user action with an exact command and observable result.
+4. `Gotchas` lists traps that can waste or invalidate a verification run.
+
+Keep implementation details out of the map. Name only user paths, stable handles, required state, commands, and observable proof.
+
+## Features
+
+- [Create a note](./create-note.md) covers browser and CLI creation, cancellation, persistence, and cleanup.
+- [Search notes](./search.md) covers toolbar, keyboard, and CLI search with matching, empty, and clear states.
diff --git a/pstack/skills/create-verification-skill/references/feature-map-example/create-note.md b/pstack/skills/create-verification-skill/references/feature-map-example/create-note.md
new file mode 100644
index 00000000..21357566
--- /dev/null
+++ b/pstack/skills/create-verification-skill/references/feature-map-example/create-note.md
@@ -0,0 +1,39 @@
+# Create a note
+
+Create note lets a user save a titled note from the browser or CLI, cancel an unfinished draft, and confirm the saved note from a second user-facing view.
+
+## Sub-features
+
+- `create-open` opens a blank editor from each browser entry point.
+- `create-save` persists a title and body.
+- `create-cancel` discards an unfinished browser draft.
+- `create-cli` creates the same note shape from the terminal.
+
+## How to get to it (user POV)
+
+- Choose the `New note` button in the browser toolbar.
+- Press `n` in the browser while focus is outside an editable field.
+- Run `notes create --title --body ` in a terminal.
+
+## Driving it with control-notes
+
+Preconditions:
+
+- Notes is healthy at `http://127.0.0.1:4173`.
+- No note is titled `Release checklist`.
+- `control-notes doctor` reports the expected URL and disposable data directory.
+
+- **Open editor.** Choose `New note`. Run `control-notes browser click --role button --name "New note"`. A form named `Note editor` appears with focus in the `Title` textbox.
+- **Enter content.** Type the title and body. Run `control-notes browser fill --role textbox --name "Title" --value "Release checklist"` and `control-notes browser fill --role textbox --name "Body" --value "Tag and publish"`. The `Save note` button becomes enabled.
+- **Save note.** Choose `Save note`. Run `control-notes browser click --role button --name "Save note"`. A status named `Note saved` appears and the heading reads `Release checklist`.
+- **Confirm persistence.** Return to the note list and reopen the note. Run `control-notes browser click --role link --name "All notes"` and `control-notes browser click --role link --name "Release checklist"`. The editor shows both saved values.
+- **Cancel draft.** Open a new note, enter `Discard me`, and choose `Cancel`. Run `control-notes browser click --role button --name "New note"`, `control-notes browser fill --role textbox --name "Title" --value "Discard me"`, and `control-notes browser click --role button --name "Cancel"`. The note list returns and has no `Discard me` link.
+- **CLI entry.** Create a second note. Run `control-notes cli -- notes create --title "CLI note" --body "Created from terminal" --format json`. Exit code `0` and stdout contain the new note ID and title.
+- **Proof.** Reopen both saved notes from `All notes`. Run `control-notes browser snapshot --aria --path artifacts/create-note/list.aria.txt` and `control-notes browser screenshot --path artifacts/create-note/list.png`. The artifacts show `Release checklist` and `CLI note`.
+
+## Gotchas
+
+- Pressing `n` while a textbox has focus types the character instead of opening a new editor.
+- Titles are trimmed on save. Assert the rendered title, not the draft input value.
+- A save status alone is insufficient proof. Reopen the note from the list.
+- Remove `Release checklist` and `CLI note` during fixture cleanup, but retain their proof artifacts.
diff --git a/pstack/skills/create-verification-skill/references/feature-map-example/search.md b/pstack/skills/create-verification-skill/references/feature-map-example/search.md
new file mode 100644
index 00000000..1f8e57d3
--- /dev/null
+++ b/pstack/skills/create-verification-skill/references/feature-map-example/search.md
@@ -0,0 +1,45 @@
+# Search notes
+
+Search lets a user find notes by title or body text, inspect a matching note, and distinguish no matches from an unavailable search.
+
+## Sub-features
+
+- `search-open` opens search from each supported browser entry point.
+- `search-match` returns title and body matches without changing note data.
+- `search-open-result` opens a result in the note editor.
+- `search-empty` shows a complete empty state for a query with no matches.
+- `search-clear` removes the query and restores the recent-notes view.
+- `search-cli` returns the same matching notes from the terminal.
+
+## How to get to it (user POV)
+
+- Choose the `Search` button in the browser toolbar.
+- Press `/` in the browser while focus is outside an editable field.
+- Run `notes search ` in a terminal.
+
+## Driving it with control-notes
+
+Preconditions:
+
+- Notes is healthy at `http://127.0.0.1:4173`.
+- The disposable data directory contains `Quarterly plan` with body text `Draft budget`.
+- `control-notes doctor` reports the expected URL and data directory.
+
+- **Toolbar entry.** Choose the `Search` button. Run `control-notes browser click --role button --name "Search"`. A dialog named `Search notes` appears with focus in its searchbox.
+- **Keyboard entry.** Close the dialog, focus the page, and press `/`. Run `control-notes browser press --key "/"`. The same dialog appears and the page does not insert a slash.
+- **Title match.** Type `quarterly`. Run `control-notes browser fill --role searchbox --name "Search notes" --value "quarterly"`. The `Search results` list contains `Quarterly plan` and does not contain `Grocery list`.
+- **Body match.** Replace the query with `budget`. Run `control-notes browser fill --role searchbox --name "Search notes" --value "budget"`. The result `Quarterly plan` remains visible with a body-match excerpt.
+- **Open result.** Choose `Quarterly plan`. Run `control-notes browser click --role link --name "Quarterly plan"`. The dialog closes and the editor heading reads `Quarterly plan`.
+- **Empty state.** Reopen search and enter `volcano`. Run `control-notes browser fill --role searchbox --name "Search notes" --value "volcano"`. A status named `No matching notes` appears after search completes.
+- **Clear query.** Choose `Clear search`. Run `control-notes browser click --role button --name "Clear search"`. The searchbox is empty and the `Recent notes` region replaces the result list.
+- **CLI match.** Search from the terminal. Run `control-notes cli -- notes search "quarterly" --format json`. Exit code `0` and stdout contain one object whose title is `Quarterly plan`.
+- **CLI miss.** Search for an absent value. Run `control-notes cli -- notes search "volcano" --format json`. Exit code `0` and stdout are `[]`.
+- **Proof.** Capture the populated result state. Run `control-notes browser snapshot --aria --path artifacts/search/results.aria.txt` and `control-notes browser screenshot --path artifacts/search/results.png`. Both artifacts identify Notes, the query, and `Quarterly plan`.
+
+## Gotchas
+
+- Pressing `/` while the editor or searchbox has focus inserts text instead of opening search.
+- Results update after a short debounce. Wait for the results list or empty status, not a fixed sleep.
+- Archived notes are excluded unless the user enables `Include archived`.
+- The CLI defaults to human-readable output. Use `--format json` for stable assertions.
+- Opening a result changes browser state. Reopen search before proving another query.
diff --git a/pstack/skills/poteto-mode/SKILL.md b/pstack/skills/poteto-mode/SKILL.md
index 304f2b01..51a46341 100644
--- a/pstack/skills/poteto-mode/SKILL.md
+++ b/pstack/skills/poteto-mode/SKILL.md
@@ -20,6 +20,7 @@ Remaining triggers:
- About to `AskQuestion` on a "which approach", "how should I", or "what should this do" fork → classify it before you ask. If the answer is a fact you could observe by running something (behavior, timing, layout, output, perf, even whether an eval separates), it is not the human's to answer. Sketch it via the Prototype playbook (`playbooks/prototype.md`) and let the result decide. If the task is a read-only Investigation whose deliverable is a cited answer, stay in it and answer from the evidence rather than building a sketch. Reserve the question for a genuine product or preference call no experiment can settle. The ask is the slow path. A throwaway probe usually answers faster, and it hands the human a result to react to instead of a decision to make.
- Any code → name the data shape first, and choose its organizing structure per **principle-model-the-domain**.
- Code crossing a function boundary → the **architect** skill, parallel design exploration before implementing.
+- Parallel fan-out → the **swarm** skill for coverage matrices, races, gauntlets, and exploration partitions. Use **arena** for design or code bakeoffs with base selection and grafting.
- Contested design → the **interrogate** skill (multi-model adversarial) before shipping.
- Nontrivial multi-step → write the throughput checkpoint (Feature step 3).
- Any prose surface → the **unslop** skill. Your reply is a prose surface; write it per **Writing the reply**. Agent-facing prose also follows the **create-skill** skill (Cursor's built-in for authoring SKILL.md files).
@@ -82,9 +83,9 @@ Read the leaf skill in full for any principle you apply. Each entry names when i
## Subagents
-**Use `subagent_type: "poteto-agent"` for any subagent you spawn inside a playbook step** (code-writing delegates, ad-hoc helpers). `/poteto-mode` and `poteto-agent` route through the same wrapper. Routed workflow skills (`how`, `why`, `interrogate`, `reflect`) set their own `subagent_type` for diverse-model review; respect what the skill prescribes, don't override to `poteto-agent`.
+**Use `subagent_type: "poteto-agent"` for any subagent you spawn inside a playbook step** (code-writing delegates, ad-hoc helpers). `/poteto-mode` and `poteto-agent` route through the same wrapper. Routed workflow skills (`how`, `why`, `interrogate`, `reflect`, `swarm`) set their own `subagent_type` for diverse-model review; respect what the skill prescribes, don't override to `poteto-agent`.
-**Defaults for every `Task` call.** `run_in_background: true`, agent mode (readonly strips MCP), file pointers not inlined context, explicit model per role (configurable via `/setup-pstack`; defaults `grok-4.5-fast-xhigh` for code, `claude-fable-5-thinking-max` for prose and judgment). Code delegates tier by difficulty. The hardest changes (cross-cutting design, gnarly concurrency, subtle algorithms) go to your strongest judgment model (`claude-fable-5-thinking-max`) when the task needs judgment or the intent is vague, and to your strongest instruction-following model (`gpt-5.6-sol-max`) when the work is a precisely specified sequence of steps to execute to the letter; trivial mechanical edits go to your fast code model. Per-role lines in the `/setup-pstack` rule override these defaults and the model choices in the routed skills (`how`, `why`, `arena`, `architect`, `interrogate`, `reflect`); a role with no line keeps its default, and a role line of `inherit-parent` or `auto` runs that role on the parent chat model (omit Task `model`).
+**Defaults for every `Task` call.** `run_in_background: true`, agent mode (readonly strips MCP), file pointers not inlined context, explicit model per role (configurable via `/setup-pstack`; defaults `grok-4.5-fast-xhigh` for code, `claude-fable-5-thinking-max` for prose and judgment). Code delegates tier by difficulty. The hardest changes (cross-cutting design, gnarly concurrency, subtle algorithms) go to your strongest judgment model (`claude-fable-5-thinking-max`) when the task needs judgment or the intent is vague, and to your strongest instruction-following model (`gpt-5.6-sol-max`) when the work is a precisely specified sequence of steps to execute to the letter; trivial mechanical edits go to your fast code model. Per-role lines in the `/setup-pstack` rule override these defaults and the model choices in the routed skills (`how`, `why`, `arena`, `swarm`, `architect`, `interrogate`, `reflect`); a role with no line keeps its default, and a role line of `inherit-parent` or `auto` runs that role on the parent chat model (omit Task `model`).
You own every subagent's work. Review the diff and write your own summary, don't pass through what it said. Interrupt-chained resumes silently drop directives, so fire a fresh subagent with consolidated scope rather than trusting a "done" summary. A second opinion is the same prompt against a different model. Agreement is high-signal.
diff --git a/pstack/skills/setup-pstack/SKILL.md b/pstack/skills/setup-pstack/SKILL.md
index ddb10640..1ad24954 100644
--- a/pstack/skills/setup-pstack/SKILL.md
+++ b/pstack/skills/setup-pstack/SKILL.md
@@ -19,7 +19,7 @@ The default role-to-model mapping is the rule shape shown in step 5 below. If `~
### 3. Map and confirm
-Show every role with its current model, marking any real slug not in the detected set as needing a choice. Ask whether to accept as-is or change specific roles, offering the detected models plus `inherit-parent` and `auto` (both mean: this role runs on the parent chat model, which is how Auto users stay on Auto) as the options. Prefer AskQuestion over free text. For panel roles (how critics, arena runners, architect runners, interrogate reviewers) the value is a list, and one subagent runs per entry, alias entries included, so the list length sets the count. `arena cross-judge pool` is also a list, but Arena selects one value from it whose model family differs from the parent's when possible.
+Show every role with its current model, marking any real slug not in the detected set as needing a choice. Ask whether to accept as-is or change specific roles, offering the detected models plus `inherit-parent` and `auto` (both mean: this role runs on the parent chat model, which is how Auto users stay on Auto) as the options. Prefer AskQuestion over free text. For panel roles (how critics, arena runners, architect runners, interrogate reviewers) the value is a list, and one subagent runs per entry, alias entries included, so the list length sets the count. `arena cross-judge pool` is also a list, but Arena selects one value from it whose model family differs from the parent's when possible. `swarm workers` is the default model for every worker unless a race or comparison assigns another model per arm.
### 4. Validate
@@ -51,6 +51,7 @@ reflect tooling: gpt-5.6-sol-max
reflect judgment, divergent, synthesizer: claude-fable-5-thinking-max
arena runners: claude-fable-5-thinking-max, gpt-5.6-sol-max, grok-4.5-fast-xhigh, claude-opus-5-thinking-xhigh
arena cross-judge pool: claude-fable-5-thinking-max, gpt-5.6-sol-max, grok-4.5-fast-xhigh, claude-opus-5-thinking-xhigh
+swarm workers: grok-4.5-fast-xhigh
architect runners: claude-fable-5-thinking-max, gpt-5.6-sol-max, grok-4.5-fast-xhigh, claude-opus-5-thinking-xhigh
interrogate reviewers: claude-fable-5-thinking-max, gpt-5.6-sol-max, grok-4.5-fast-xhigh, claude-opus-5-thinking-xhigh
```
diff --git a/pstack/skills/swarm/SKILL.md b/pstack/skills/swarm/SKILL.md
new file mode 100644
index 00000000..13f9a412
--- /dev/null
+++ b/pstack/skills/swarm/SKILL.md
@@ -0,0 +1,46 @@
+---
+name: swarm
+description: "Fan out N parallel workers, drain them, and return one report. Use for /swarm, 'swarm this', or parallel coverage, races, gauntlets, and exploration."
+disable-model-invocation: true
+---
+
+# Swarm
+
+Fan out N parallel cloud workers. They may cover separate slices, race the same brief, or mix both. The parent waits, aggregates, and returns one report.
+
+## Start
+
+Open a todolist with one entry per phase before launching anything.
+
+1. Frame
+2. Fan out
+3. Aggregate
+4. Report
+
+## Phase A: Frame
+
+1. State the done predicate and the artifact or report the swarm must return.
+2. Choose the shape. Partition into slices, race N workers on identical briefs, or mix both. For a race or mixed shape, declare `first pass`, `rank all`, or `best-of` before spawning.
+3. Set N from the user or derive it from the shape. N is total workers, not the cloud concurrency limit.
+4. Pick the worker model from `swarm workers` in `~/.cursor/rules/pstack-models.mdc` when present. Otherwise use `grok-4.5-fast-xhigh`. For a model race, name each arm's model up front.
+5. Give each worker its own writable output when it writes. Use a worktree, branch, or `/tmp/swarm-/worker-/`.
+
+## Phase B: Fan out
+
+Spawn all N workers in one message with `subagent_type: generalPurpose`, `environment: "cloud"`, `run_in_background: true`, and the configured model. Use `environment: "local"` only when the worker needs access to something on the user's computer.
+
+When a worker must start from a non-default pushed branch, pass `cloud_base_branch`.
+
+Every brief stands alone. Include the goal, scope, exact slice or race arm, how to verify, and what to report. Reports use `PASS`, `ISSUES`, or `BLOCKED` with evidence.
+
+If a worker drops out, proceed with N-1 and note it.
+
+## Phase C: Aggregate
+
+Read the terminal results. For coverage, every required slice needs a result. For a race, apply the selection rule declared up front. Use first pass, rank all, or best-of. Do not paste raw worker dumps.
+
+Keep a compact result table, one-line evidenced issues, and explicit gaps or dropouts.
+
+## Phase D: Report
+
+Return one consolidated in-chat report with the table, issue one-liners, gaps or dropouts, and the race rule when used.