Skip to content

Commit d0ae710

Browse files
authored
Merge pull request #83 from Automattic/cursor-listing-flow
Document Cursor plugin listing flow
2 parents 98260b0 + 0c68893 commit d0ae710

6 files changed

Lines changed: 115 additions & 16 deletions

File tree

README.md

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -123,18 +123,22 @@ Cursor requires a standalone plugin repository. This repo remains the source of
123123

124124
https://github.com/Automattic/wordpress-cursor-plugin
125125

126-
Update `skills/` and the Cursor generator here, then export `plugins/cursor/`:
126+
Update `skills/` and the Cursor generator here, then verify the generated output:
127127

128128
```bash
129129
pnpm build
130130
pnpm verify
131-
pnpm export:cursor
131+
pnpm export:cursor -- --dry-run
132132
```
133133

134-
The export command runs `git subtree split --prefix=plugins/cursor` and pushes the result to `Automattic/wordpress-cursor-plugin` on `sync/from-build-with-wordpress`. Open or update a PR from that branch into the standalone repo's `main` branch, then submit the standalone repo to Cursor.
134+
The dry run prints the exact subtree split and push commands without creating a split branch, pushing to the standalone repository, or mutating the standalone checkout.
135135

136-
For a dry run:
136+
When maintainers are ready to update the standalone repository, run the non-dry-run export from a clean source worktree:
137137

138138
```bash
139-
pnpm export:cursor -- --dry-run
139+
pnpm export:cursor
140140
```
141+
142+
The export command runs `git subtree split --prefix=plugins/cursor` and pushes the result to `Automattic/wordpress-cursor-plugin` on `sync/from-build-with-wordpress`. Open or update a PR from that branch into the standalone repo's `main` branch.
143+
144+
Before submitting or updating the Cursor listing, confirm the standalone branch includes the expected generated files, review `.cursor-plugin/plugin.json` listing metadata, verify the README and MCP setup match the generated source, and submit to Cursor only after the standalone repository PR is accepted.

docs/contributor-workflows.md

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,20 +100,31 @@ Expected MCP server names are:
100100

101101
Cursor output has an additional publishing workflow because Cursor consumes a standalone plugin repository.
102102

103+
Reviewable dry run:
104+
103105
```bash
104106
pnpm build
105107
pnpm verify
106-
pnpm export:cursor
108+
pnpm export:cursor -- --dry-run
107109
```
108110

109-
Dry run:
111+
The dry run prints the subtree split, push target, and cleanup command without creating a local split branch, pushing to the standalone repository, or touching a standalone checkout.
112+
113+
Maintainer export:
110114

111115
```bash
112-
pnpm export:cursor -- --dry-run
116+
pnpm export:cursor
113117
```
114118

115119
The export script pushes a subtree split of `plugins/cursor` to `Automattic/wordpress-cursor-plugin` on `sync/from-build-with-wordpress`. Open or update a pull request from that branch to the standalone repository's `main` branch.
116120

121+
Before submitting or updating the Cursor listing:
122+
123+
1. Confirm the standalone branch contains `.cursor-plugin/plugin.json`, `README.md`, `mcp.json`, `rules/wordpress-studio.mdc`, and the generated `skills/` tree.
124+
2. Review `.cursor-plugin/plugin.json` for the listing-facing `name`, `displayName`, `version`, `description`, `author`, `homepage`, `repository`, `license`, `keywords`, `rules`, `skills`, and `mcpServers` fields.
125+
3. Confirm the standalone README describes the generated package, export source of truth, and MCP setup.
126+
4. Submit to Cursor only after the standalone repository PR is accepted.
127+
117128
## Manual smoke testing
118129

119130
After verification passes, manually test representative generated output when the change affects runtime behavior:
@@ -165,7 +176,7 @@ Before requesting review:
165176
- [ ] `pnpm verify` passes locally or in CI.
166177
- [ ] Generated package diffs are expected and bounded.
167178
- [ ] Documentation is updated for public contracts, setup commands, generated files, or integration behavior.
168-
- [ ] Cursor export has been run or intentionally not run when `plugins/cursor/` changes.
179+
- [ ] Cursor export dry run has been run when `plugins/cursor/` changes, and non-dry-run export is intentionally run or intentionally deferred.
169180

170181
## Contributor design principles
171182

docs/generated-outputs.md

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -172,26 +172,37 @@ The verifier checks generated files rather than source style. It should fail whe
172172

173173
When adding a new surface, add generator code and a verification function in the same change. The verification function should prove the public files that users or agent marketplaces consume.
174174

175-
## Cursor export contract
175+
## Cursor export and listing contract
176176

177177
Cursor requires a standalone plugin repository. Build with WordPress remains the source of truth and exports `plugins/cursor/` to `Automattic/wordpress-cursor-plugin`.
178178

179-
Normal export:
179+
Reviewable dry run:
180180

181181
```bash
182182
pnpm build
183183
pnpm verify
184-
pnpm export:cursor
184+
pnpm export:cursor -- --dry-run
185185
```
186186

187-
Dry run:
187+
The dry run prints the subtree split, push target, and cleanup command without creating a local split branch, pushing to the standalone repository, or touching a standalone checkout.
188+
189+
Maintainer export:
188190

189191
```bash
190-
pnpm export:cursor -- --dry-run
192+
pnpm export:cursor
191193
```
192194

193195
The export script uses `git subtree split --prefix=plugins/cursor` and pushes the result to the standalone repository branch `sync/from-build-with-wordpress`. Open or update a pull request from that branch into the standalone repository's `main` branch.
194196

197+
Listing/submission checklist:
198+
199+
1. Confirm `pnpm build` and `pnpm verify` pass in Build with WordPress.
200+
2. Confirm `pnpm export:cursor -- --dry-run` prints the expected `plugins/cursor` subtree split and `sync/from-build-with-wordpress` push target.
201+
3. Confirm the exported branch contains `.cursor-plugin/plugin.json`, `README.md`, `mcp.json`, `rules/wordpress-studio.mdc`, and every shared skill under `skills/`.
202+
4. Review Cursor listing metadata in `.cursor-plugin/plugin.json`: `name`, `displayName`, `version`, `description`, `author`, `homepage`, `repository`, `license`, `keywords`, `rules`, `skills`, and `mcpServers`.
203+
5. Open or update the standalone repository PR and wait for review before submitting or updating the Cursor listing.
204+
6. Submit to Cursor only from the accepted standalone repository state, not from unreviewed generated output.
205+
195206
## Maintenance checklist
196207

197208
Before opening a generated-output pull request:
@@ -201,7 +212,7 @@ Before opening a generated-output pull request:
201212
3. Run `pnpm build`.
202213
4. Run `pnpm verify`.
203214
5. Inspect generated package diffs for unexpected churn.
204-
6. If Cursor output changed, run the Cursor export flow when maintainers are ready to update the standalone plugin repository.
215+
6. If Cursor output changed, run the dry-run Cursor export flow for review and the non-dry-run export only when maintainers are ready to update the standalone plugin repository.
205216

206217
## Related documentation
207218

plugins/cursor/README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,22 @@ It is a Cursor plugin built from the same shared skills as the Codex and Claude
1111
- WordPress request routing stays shared across surfaces
1212
- Studio-backed site, theme, block, plugin, and audit workflows stay shared
1313

14+
## Standalone export and listing
15+
16+
Build with WordPress is the source of truth for this generated package. The standalone Cursor plugin repository is https://github.com/Automattic/wordpress-cursor-plugin and should be updated through the repository export script, not by manually editing exported files.
17+
18+
From the source repository, verify the generated output first:
19+
20+
```bash
21+
pnpm build
22+
pnpm verify
23+
pnpm export:cursor -- --dry-run
24+
```
25+
26+
When maintainers are ready to update the standalone repository, run `pnpm export:cursor` from a clean source worktree. The exporter creates a subtree split of `plugins/cursor/` and pushes it to `sync/from-build-with-wordpress` in the standalone repository.
27+
28+
Before submitting or updating the Cursor listing, confirm the exported standalone branch contains the expected `.cursor-plugin/plugin.json`, `README.md`, `mcp.json`, `rules/wordpress-studio.mdc`, and full `skills/` tree; review the listing-facing manifest fields for name, display name, version, description, author, homepage, repository, license, and keywords; then open or update the standalone repository pull request for review. Submit to Cursor only after the standalone repository PR is accepted.
29+
1430
It ships the shared skills from this repo so all supported surfaces stay aligned while we iterate on surface-specific packaging details.
1531

1632
## Included skills

scripts/build-plugins.mjs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2024,7 +2024,23 @@ const pluginTargets = [
20242024
- Cursor discovers persistent guidance from \`rules/\`
20252025
- Cursor discovers MCP servers from root \`mcp.json\`
20262026
- WordPress request routing stays shared across surfaces
2027-
- Studio-backed site, theme, block, plugin, and audit workflows stay shared`,
2027+
- Studio-backed site, theme, block, plugin, and audit workflows stay shared
2028+
2029+
## Standalone export and listing
2030+
2031+
Build with WordPress is the source of truth for this generated package. The standalone Cursor plugin repository is https://github.com/Automattic/wordpress-cursor-plugin and should be updated through the repository export script, not by manually editing exported files.
2032+
2033+
From the source repository, verify the generated output first:
2034+
2035+
\`\`\`bash
2036+
pnpm build
2037+
pnpm verify
2038+
pnpm export:cursor -- --dry-run
2039+
\`\`\`
2040+
2041+
When maintainers are ready to update the standalone repository, run \`pnpm export:cursor\` from a clean source worktree. The exporter creates a subtree split of \`plugins/cursor/\` and pushes it to \`sync/from-build-with-wordpress\` in the standalone repository.
2042+
2043+
Before submitting or updating the Cursor listing, confirm the exported standalone branch contains the expected \`.cursor-plugin/plugin.json\`, \`README.md\`, \`mcp.json\`, \`rules/wordpress-studio.mdc\`, and full \`skills/\` tree; review the listing-facing manifest fields for name, display name, version, description, author, homepage, repository, license, and keywords; then open or update the standalone repository pull request for review. Submit to Cursor only after the standalone repository PR is accepted.`,
20282044
includeMcpConfig: true,
20292045
mcpConfigPath: "mcp.json",
20302046
displayName: cursorPluginDisplayName,

scripts/verify-plugins.mjs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,17 @@ const pluginName = "wordpress-studio";
1919
const pluginDisplayName = "WordPress Studio";
2020
const cursorPluginName = pluginName;
2121
const cursorPluginDisplayName = pluginDisplayName;
22+
const cursorPluginRepository = "https://github.com/Automattic/wordpress-cursor-plugin";
23+
const cursorRequiredKeywords = [
24+
"wordpress",
25+
"studio",
26+
"wp-cli",
27+
"cursor",
28+
"site-creator",
29+
"theme-creator",
30+
"block-creator",
31+
"plugin-creator",
32+
];
2233
const codexRootDir = path.join(root, "plugins", "codex");
2334
const codexPluginDir = path.join(codexRootDir, "plugins", pluginName);
2435
const codexMarketplacePath = path.join(
@@ -226,6 +237,36 @@ async function verifyCursorPlugin(skillNames) {
226237
throw new Error("Cursor plugin manifest has the wrong display name");
227238
}
228239

240+
if (manifest.version !== "0.3.0") {
241+
throw new Error("Cursor plugin manifest has the wrong version");
242+
}
243+
244+
if (!manifest.description?.includes("WordPress sites and applications")) {
245+
throw new Error("Cursor plugin manifest is missing the listing description");
246+
}
247+
248+
if (manifest.author?.name !== "Automattic") {
249+
throw new Error("Cursor plugin manifest has the wrong author");
250+
}
251+
252+
if (manifest.homepage !== "https://developer.wordpress.com/") {
253+
throw new Error("Cursor plugin manifest has the wrong homepage");
254+
}
255+
256+
if (manifest.repository !== cursorPluginRepository) {
257+
throw new Error("Cursor plugin manifest has the wrong repository");
258+
}
259+
260+
if (manifest.license !== "GPL-2.0-or-later") {
261+
throw new Error("Cursor plugin manifest has the wrong license");
262+
}
263+
264+
for (const keyword of cursorRequiredKeywords) {
265+
if (!manifest.keywords?.includes(keyword)) {
266+
throw new Error(`Cursor plugin manifest is missing keyword ${keyword}`);
267+
}
268+
}
269+
229270
if (manifest.rules !== "./rules/") {
230271
throw new Error("Cursor plugin manifest is missing the rules path");
231272
}

0 commit comments

Comments
 (0)