From 29f8b0084035d22402c9ba1146baea7caac051ae Mon Sep 17 00:00:00 2001 From: Dean Rie Date: Thu, 8 Oct 2026 20:26:48 +0300 Subject: [PATCH 1/2] chore: point docs at agent-plugins.org, make lint run biome, document detected manifests and commands (cherry picked from commit 00c7536effcc35b65698dcb4267b10cc407333aa) --- README.md | 11 +++++++---- apps/cursor/package.json | 2 +- apps/cursor/src/app/plugins/new/page.tsx | 2 +- apps/cursor/src/components/forms/plugin-form.tsx | 2 +- apps/cursor/src/lib/github-plugin/parse.ts | 2 +- 5 files changed, 11 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 25bd9c7f..47a48c14 100644 --- a/README.md +++ b/README.md @@ -77,7 +77,7 @@ All content is submitted through the website — no pull requests needed for dat 1. Go to [cursor.directory/plugins/new](https://cursor.directory/plugins/new) 2. Sign in with GitHub or Google -3. Paste a GitHub repo URL — we auto-detect components following the [Open Plugins](https://open-plugins.com) standard +3. Paste a GitHub repo URL — we auto-detect components following the [Open Plugins](https://agent-plugins.org) standard 4. Click **Submit** Auto-detected components: @@ -85,13 +85,16 @@ Auto-detected components: | Component | Path | |-----------|------| | Rules | `rules/*.mdc` | -| MCP Servers | `.mcp.json` | +| MCP Servers | `.mcp.json` or `mcp.json` | | Skills | `skills/*/SKILL.md` | | Agents | `agents/*.md` | +| Commands | `commands/*.md` | | Hooks | `hooks/hooks.json` | | LSP Servers | `.lsp.json` | -See the [Open Plugins specification](https://open-plugins.com/plugin-builders/specification) and [plugin template](https://github.com/cursor/plugin-template) for details. +The manifest is read from `.plugin/plugin.json`, `.cursor-plugin/plugin.json` or `.claude-plugin/plugin.json` (first match wins). For monorepos, the same paths are also scanned inside every directory listed as `plugins[].source` in `.cursor-plugin/marketplace.json` and every directory that contains its own `.cursor-plugin/plugin.json`. + +See the [Open Plugins specification](https://agent-plugins.org/specification) and [plugin template](https://github.com/cursor/plugin-template) for details. --- @@ -104,7 +107,7 @@ See the [Open Plugins specification](https://open-plugins.com/plugin-builders/sp - **Styling**: [Tailwind CSS](https://tailwindcss.com) - **UI**: [Radix UI](https://radix-ui.com) + [shadcn/ui](https://ui.shadcn.com) - **Search**: [Fuse.js](https://fusejs.io) (client-side fuzzy search) -- **URL State**: [nuqs](https://nuqs.47ng.com) +- **URL State**: [nuqs](https://nuqs.dev) - **Linting**: [Biome](https://biomejs.dev) ## Plugin security scan diff --git a/apps/cursor/package.json b/apps/cursor/package.json index 811e9f34..d3c0bc16 100644 --- a/apps/cursor/package.json +++ b/apps/cursor/package.json @@ -6,7 +6,7 @@ "dev": "next dev --turbopack", "build": "next build", "start": "next start", - "lint": "next lint", + "lint": "biome check .", "typecheck": "tsc --noEmit", "seed:extract": "bun run --env-file=.env src/scripts/extract-from-github.ts", "seed:insert": "bun run --env-file=.env src/scripts/insert-from-jsonl.ts" diff --git a/apps/cursor/src/app/plugins/new/page.tsx b/apps/cursor/src/app/plugins/new/page.tsx index 116690e0..a51b2ca9 100644 --- a/apps/cursor/src/app/plugins/new/page.tsx +++ b/apps/cursor/src/app/plugins/new/page.tsx @@ -46,7 +46,7 @@ export default function Page() {
We follow the{" "} Date: Fri, 9 Oct 2026 09:38:09 +0300 Subject: [PATCH 2/2] chore: constant-time cron secret compare, least-privilege CI token, single biome version (cherry picked from commit 4b1a6ac61a58cd449c6d1a9e86d8306a27e82c04) --- .github/workflows/ci.yml | 7 +++++++ apps/cursor/package.json | 2 +- apps/cursor/src/lib/cron-auth.ts | 11 +++++++++-- bun.lock | 20 +------------------- 4 files changed, 18 insertions(+), 22 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9295e1d9..d0eb869f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -5,6 +5,13 @@ on: branches: [main] pull_request: +permissions: + contents: read + +concurrency: + group: ci-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: checks: name: Lint & typecheck diff --git a/apps/cursor/package.json b/apps/cursor/package.json index d3c0bc16..2526576d 100644 --- a/apps/cursor/package.json +++ b/apps/cursor/package.json @@ -54,7 +54,7 @@ "zod": "^4.4.3" }, "devDependencies": { - "@biomejs/biome": "2.4.14", + "@biomejs/biome": "2.4.15", "@tailwindcss/postcss": "^4.2.4", "@types/node": "^25.6.0", "@types/react": "^19", diff --git a/apps/cursor/src/lib/cron-auth.ts b/apps/cursor/src/lib/cron-auth.ts index c7c83838..350b29aa 100644 --- a/apps/cursor/src/lib/cron-auth.ts +++ b/apps/cursor/src/lib/cron-auth.ts @@ -1,3 +1,4 @@ +import { timingSafeEqual } from "node:crypto"; import { NextResponse } from "next/server"; /** @@ -24,8 +25,14 @@ export function requireCronAuth(request: Request): NextResponse | null { ); } - const header = request.headers.get("authorization"); - if (header !== `Bearer ${cronSecret}`) { + const header = request.headers.get("authorization") ?? ""; + const expected = Buffer.from(`Bearer ${cronSecret}`); + const received = Buffer.from(header); + // Constant-time compare so the response time does not leak how much of + // the secret matched. Lengths must match first or timingSafeEqual throws. + const authorized = + received.length === expected.length && timingSafeEqual(received, expected); + if (!authorized) { return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); } diff --git a/bun.lock b/bun.lock index 3ea1af40..59982553 100644 --- a/bun.lock +++ b/bun.lock @@ -55,7 +55,7 @@ "zod": "^4.4.3", }, "devDependencies": { - "@biomejs/biome": "2.4.14", + "@biomejs/biome": "2.4.15", "@tailwindcss/postcss": "^4.2.4", "@types/node": "^25.6.0", "@types/react": "^19", @@ -723,8 +723,6 @@ "zod": ["zod@4.4.3", "", {}, "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ=="], - "@directories/cursor/@biomejs/biome": ["@biomejs/biome@2.4.14", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "2.4.14", "@biomejs/cli-darwin-x64": "2.4.14", "@biomejs/cli-linux-arm64": "2.4.14", "@biomejs/cli-linux-arm64-musl": "2.4.14", "@biomejs/cli-linux-x64": "2.4.14", "@biomejs/cli-linux-x64-musl": "2.4.14", "@biomejs/cli-win32-arm64": "2.4.14", "@biomejs/cli-win32-x64": "2.4.14" }, "bin": { "biome": "bin/biome" } }, "sha512-TmAvxOEgrpLypzVGJ8FulIZnlyA9TxrO1hyqYrCz9r+bwma9xXxuLA5IuYnj55XQneFx460KjRbx6SWGLkg3bQ=="], - "@radix-ui/react-alert-dialog/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="], "@radix-ui/react-avatar/@radix-ui/react-context": ["@radix-ui/react-context@1.1.3", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-ieIFACdMpYfMEjF0rEf5KLvfVyIkOz6PDGyNnP+u+4xQ6jny3VCgA4OgXOwNx2aUkxn8zx9fiVcM8CfFYv9Lxw=="], @@ -799,22 +797,6 @@ "tar-fs/chownr": ["chownr@1.1.4", "", {}, "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg=="], - "@directories/cursor/@biomejs/biome/@biomejs/cli-darwin-arm64": ["@biomejs/cli-darwin-arm64@2.4.14", "", { "os": "darwin", "cpu": "arm64" }, "sha512-XvgoE9XOawUOQPdmvs4J7wPhi/DLwSCGks3AlPJDmh34O0awRTqCED1HRcRDdpf1Zrp4us4MGOOdIxNpbqNF5Q=="], - - "@directories/cursor/@biomejs/biome/@biomejs/cli-darwin-x64": ["@biomejs/cli-darwin-x64@2.4.14", "", { "os": "darwin", "cpu": "x64" }, "sha512-jE7hKBCFhOx3uUh+ZkWBfOHxAcILPfhFplNkuID/eZeSTLHzfZzoZxW8fbqY9xXRnPi7jGNAf1iPVR+0yWsM/Q=="], - - "@directories/cursor/@biomejs/biome/@biomejs/cli-linux-arm64": ["@biomejs/cli-linux-arm64@2.4.14", "", { "os": "linux", "cpu": "arm64" }, "sha512-2TELhZnW5RSLL063l9rc5xLpA0ZIw0Ccwy/0q384rvNAgFw3yI76bd59547yxowdQr5MNPET/xDLrLuvgSeeWQ=="], - - "@directories/cursor/@biomejs/biome/@biomejs/cli-linux-arm64-musl": ["@biomejs/cli-linux-arm64-musl@2.4.14", "", { "os": "linux", "cpu": "arm64" }, "sha512-/z+6gqAqqUQTHazwStxSXKHg9b8UvqBmDFRp+c4wYbq2KXhELQDon9EoC9RpmQ8JWkqQx/lIUy/cs+MhzDZp6A=="], - - "@directories/cursor/@biomejs/biome/@biomejs/cli-linux-x64": ["@biomejs/cli-linux-x64@2.4.14", "", { "os": "linux", "cpu": "x64" }, "sha512-zHrlQZDBDUz4OLAraYpWKcnLS6HOewBFWYOzY91d1ZjdqZwibOyb6BEu6WuWLugyo0P3riCmsbV9UqV1cSXwQg=="], - - "@directories/cursor/@biomejs/biome/@biomejs/cli-linux-x64-musl": ["@biomejs/cli-linux-x64-musl@2.4.14", "", { "os": "linux", "cpu": "x64" }, "sha512-R6BWgJdQOwW9ulJatuTVrQkjnODjqHZkKNOqb1sz++3Noe5LYd0i3PchnOBUCYAPHoPWHhjJqbdZlHEu0hpjdA=="], - - "@directories/cursor/@biomejs/biome/@biomejs/cli-win32-arm64": ["@biomejs/cli-win32-arm64@2.4.14", "", { "os": "win32", "cpu": "arm64" }, "sha512-M3EH5hqOI/F/FUA2u4xcLoUgmxd218mvuj/6JL7Hv2toQvr2/AdOvKSpGkoRuWFCtQPVa+ZqkEV3Q5xBA9+XSA=="], - - "@directories/cursor/@biomejs/biome/@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@2.4.14", "", { "os": "win32", "cpu": "x64" }, "sha512-WL0EG5qE+EAKomGXbf2g6VnSKJhTL3tXC0QRzWRwA5VpjxNYa6H4P7ZWfymbGE4IhZZQi1KXQ2R0YjwInmz2fA=="], - "cacache/minipass/yallist": ["yallist@4.0.0", "", {}, "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="], "cacache/tar/minipass": ["minipass@5.0.0", "", {}, "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ=="],