-
Notifications
You must be signed in to change notification settings - Fork 611
feat(opencode): add OpenCode plugin support for all 65 Cursor plugins #327
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
b55db54
a8ede22
d7489a1
9eba4fa
4e461ad
ee00752
bb20d3d
c801023
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| { | ||
| "name": "cursor-plugins", | ||
| "interface": { "displayName": "Cursor plugins" }, | ||
| "plugins": [ | ||
| {"name": "teaching", "source": "./teaching", "policy": {"installation": "AVAILABLE", "authentication": "ON_INSTALL"}, "category": "Productivity"}, | ||
| {"name": "continual-learning", "source": "./continual-learning", "policy": {"installation": "AVAILABLE", "authentication": "ON_INSTALL"}, "category": "Productivity"}, | ||
| {"name": "cursor-team-kit", "source": "./cursor-team-kit", "policy": {"installation": "AVAILABLE", "authentication": "ON_INSTALL"}, "category": "Productivity"}, | ||
| {"name": "thermos", "source": "./thermos", "policy": {"installation": "AVAILABLE", "authentication": "ON_INSTALL"}, "category": "Productivity"}, | ||
| {"name": "create-plugin", "source": "./create-plugin", "policy": {"installation": "AVAILABLE", "authentication": "ON_INSTALL"}, "category": "Productivity"}, | ||
| {"name": "ralph-loop", "source": "./ralph-loop", "policy": {"installation": "AVAILABLE", "authentication": "ON_INSTALL"}, "category": "Productivity"}, | ||
| {"name": "agent-compatibility", "source": "./agent-compatibility", "policy": {"installation": "AVAILABLE", "authentication": "ON_INSTALL"}, "category": "Productivity"}, | ||
| {"name": "cli-for-agent", "source": "./cli-for-agent", "policy": {"installation": "AVAILABLE", "authentication": "ON_INSTALL"}, "category": "Productivity"}, | ||
| {"name": "pr-review-canvas", "source": "./pr-review-canvas", "policy": {"installation": "AVAILABLE", "authentication": "ON_INSTALL"}, "category": "Productivity"}, | ||
| {"name": "docs-canvas", "source": "./docs-canvas", "policy": {"installation": "AVAILABLE", "authentication": "ON_INSTALL"}, "category": "Productivity"}, | ||
| {"name": "cursor-sdk", "source": "./cursor-sdk", "policy": {"installation": "AVAILABLE", "authentication": "ON_INSTALL"}, "category": "Productivity"}, | ||
| {"name": "orchestrate", "source": "./orchestrate", "policy": {"installation": "AVAILABLE", "authentication": "ON_INSTALL"}, "category": "Productivity"}, | ||
| {"name": "pstack", "source": "./pstack", "policy": {"installation": "AVAILABLE", "authentication": "ON_INSTALL"}, "category": "Productivity"}, | ||
| {"name": "gmail", "source": "./third_party/gmail", "policy": {"installation": "AVAILABLE", "authentication": "ON_INSTALL"}, "category": "Productivity"}, | ||
| {"name": "google-drive", "source": "./third_party/google-drive", "policy": {"installation": "AVAILABLE", "authentication": "ON_INSTALL"}, "category": "Productivity"}, | ||
| {"name": "google-calendar", "source": "./third_party/google-calendar", "policy": {"installation": "AVAILABLE", "authentication": "ON_INSTALL"}, "category": "Productivity"}, | ||
| {"name": "gong", "source": "./third_party/gong", "policy": {"installation": "AVAILABLE", "authentication": "ON_INSTALL"}, "category": "Productivity"}, | ||
| {"name": "salesforce", "source": "./third_party/salesforce", "policy": {"installation": "AVAILABLE", "authentication": "ON_INSTALL"}, "category": "Productivity"}, | ||
| {"name": "playwright", "source": "./third_party/playwright", "policy": {"installation": "AVAILABLE", "authentication": "ON_INSTALL"}, "category": "Productivity"}, | ||
| {"name": "github", "source": "./third_party/github", "policy": {"installation": "AVAILABLE", "authentication": "ON_INSTALL"}, "category": "Productivity"}, | ||
| {"name": "ashby", "source": "./third_party/ashby", "policy": {"installation": "AVAILABLE", "authentication": "ON_INSTALL"}, "category": "Productivity"}, | ||
| {"name": "hubspot", "source": "./third_party/hubspot", "policy": {"installation": "AVAILABLE", "authentication": "ON_INSTALL"}, "category": "Productivity"}, | ||
| {"name": "intercom", "source": "./third_party/intercom", "policy": {"installation": "AVAILABLE", "authentication": "ON_INSTALL"}, "category": "Productivity"}, | ||
| {"name": "zoom", "source": "./third_party/zoom", "policy": {"installation": "AVAILABLE", "authentication": "ON_INSTALL"}, "category": "Productivity"}, | ||
| {"name": "x", "source": "./third_party/x", "policy": {"installation": "AVAILABLE", "authentication": "ON_INSTALL"}, "category": "Productivity"}, | ||
| {"name": "clay", "source": "./third_party/clay", "policy": {"installation": "AVAILABLE", "authentication": "ON_INSTALL"}, "category": "Productivity"}, | ||
| {"name": "circleback", "source": "./third_party/circleback", "policy": {"installation": "AVAILABLE", "authentication": "ON_INSTALL"}, "category": "Productivity"}, | ||
| {"name": "docusign", "source": "./third_party/docusign", "policy": {"installation": "AVAILABLE", "authentication": "ON_INSTALL"}, "category": "Productivity"}, | ||
| {"name": "navan", "source": "./third_party/navan", "policy": {"installation": "AVAILABLE", "authentication": "ON_INSTALL"}, "category": "Productivity"}, | ||
| {"name": "profound", "source": "./third_party/profound", "policy": {"installation": "AVAILABLE", "authentication": "ON_INSTALL"}, "category": "Productivity"}, | ||
| {"name": "juicebox", "source": "./third_party/juicebox", "policy": {"installation": "AVAILABLE", "authentication": "ON_INSTALL"}, "category": "Productivity"}, | ||
| {"name": "outreach", "source": "./third_party/outreach", "policy": {"installation": "AVAILABLE", "authentication": "ON_INSTALL"}, "category": "Productivity"}, | ||
| {"name": "amplemarket", "source": "./third_party/amplemarket", "policy": {"installation": "AVAILABLE", "authentication": "ON_INSTALL"}, "category": "Productivity"} | ||
| ] | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| { | ||
| "name": "cursor-plugins", | ||
| "description": "Cursor plugins.", | ||
| "owner": { "name": "Rudimar Ronsoni" }, | ||
| "plugins": [ | ||
| {"name": "teaching", "source": "./teaching", "strict": false}, | ||
| {"name": "continual-learning", "source": "./continual-learning", "strict": false}, | ||
| {"name": "cursor-team-kit", "source": "./cursor-team-kit", "strict": false}, | ||
| {"name": "thermos", "source": "./thermos", "strict": false}, | ||
| {"name": "create-plugin", "source": "./create-plugin", "strict": false}, | ||
| {"name": "ralph-loop", "source": "./ralph-loop", "strict": false}, | ||
| {"name": "agent-compatibility", "source": "./agent-compatibility", "strict": false}, | ||
| {"name": "cli-for-agent", "source": "./cli-for-agent", "strict": false}, | ||
| {"name": "pr-review-canvas", "source": "./pr-review-canvas", "strict": false}, | ||
| {"name": "docs-canvas", "source": "./docs-canvas", "strict": false}, | ||
| {"name": "cursor-sdk", "source": "./cursor-sdk", "strict": false}, | ||
| {"name": "orchestrate", "source": "./orchestrate", "strict": false}, | ||
| {"name": "pstack", "source": "./pstack", "strict": false}, | ||
| {"name": "gmail", "source": "./third_party/gmail", "strict": false, "mcpServers": "./mcp.json"}, | ||
| {"name": "google-drive", "source": "./third_party/google-drive", "strict": false, "mcpServers": "./mcp.json"}, | ||
| {"name": "google-calendar", "source": "./third_party/google-calendar", "strict": false, "mcpServers": "./mcp.json"}, | ||
| {"name": "gong", "source": "./third_party/gong", "strict": false, "mcpServers": "./mcp.json"}, | ||
| {"name": "salesforce", "source": "./third_party/salesforce", "strict": false, "mcpServers": "./mcp.json"}, | ||
| {"name": "playwright", "source": "./third_party/playwright", "strict": false, "mcpServers": "./mcp.json"}, | ||
| {"name": "github", "source": "./third_party/github", "strict": false, "mcpServers": "./mcp.json"}, | ||
| {"name": "ashby", "source": "./third_party/ashby", "strict": false, "mcpServers": "./mcp.json"}, | ||
| {"name": "hubspot", "source": "./third_party/hubspot", "strict": false, "mcpServers": "./mcp.json"}, | ||
| {"name": "intercom", "source": "./third_party/intercom", "strict": false, "mcpServers": "./mcp.json"}, | ||
| {"name": "zoom", "source": "./third_party/zoom", "strict": false, "mcpServers": "./mcp.json"}, | ||
| {"name": "x", "source": "./third_party/x", "strict": false, "mcpServers": "./mcp.json"}, | ||
| {"name": "clay", "source": "./third_party/clay", "strict": false, "mcpServers": "./mcp.json"}, | ||
| {"name": "circleback", "source": "./third_party/circleback", "strict": false, "mcpServers": "./mcp.json"}, | ||
| {"name": "docusign", "source": "./third_party/docusign", "strict": false, "mcpServers": "./mcp.json"}, | ||
| {"name": "navan", "source": "./third_party/navan", "strict": false, "mcpServers": "./mcp.json"}, | ||
| {"name": "profound", "source": "./third_party/profound", "strict": false, "mcpServers": "./mcp.json"}, | ||
| {"name": "juicebox", "source": "./third_party/juicebox", "strict": false, "mcpServers": "./mcp.json"}, | ||
| {"name": "outreach", "source": "./third_party/outreach", "strict": false, "mcpServers": "./mcp.json"}, | ||
| {"name": "amplemarket", "source": "./third_party/amplemarket", "strict": false, "mcpServers": "./mcp.json"} | ||
| ] | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| { | ||
| "name": "cursor-plugins", | ||
| "owner": { "name": "Rudimar Ronsoni" }, | ||
| "plugins": [ | ||
| {"name": "teaching", "source": "./teaching"}, | ||
| {"name": "continual-learning", "source": "./continual-learning"}, | ||
| {"name": "cursor-team-kit", "source": "./cursor-team-kit"}, | ||
| {"name": "thermos", "source": "./thermos"}, | ||
| {"name": "create-plugin", "source": "./create-plugin"}, | ||
| {"name": "ralph-loop", "source": "./ralph-loop"}, | ||
| {"name": "agent-compatibility", "source": "./agent-compatibility"}, | ||
| {"name": "cli-for-agent", "source": "./cli-for-agent"}, | ||
| {"name": "pr-review-canvas", "source": "./pr-review-canvas"}, | ||
| {"name": "docs-canvas", "source": "./docs-canvas"}, | ||
| {"name": "cursor-sdk", "source": "./cursor-sdk"}, | ||
| {"name": "orchestrate", "source": "./orchestrate"}, | ||
| {"name": "pstack", "source": "./pstack"}, | ||
| {"name": "gmail", "source": "./third_party/gmail"}, | ||
| {"name": "google-drive", "source": "./third_party/google-drive"}, | ||
| {"name": "google-calendar", "source": "./third_party/google-calendar"}, | ||
| {"name": "gong", "source": "./third_party/gong"}, | ||
| {"name": "salesforce", "source": "./third_party/salesforce"}, | ||
| {"name": "playwright", "source": "./third_party/playwright"}, | ||
| {"name": "github", "source": "./third_party/github"}, | ||
| {"name": "ashby", "source": "./third_party/ashby"}, | ||
| {"name": "hubspot", "source": "./third_party/hubspot"}, | ||
| {"name": "intercom", "source": "./third_party/intercom"}, | ||
| {"name": "zoom", "source": "./third_party/zoom"}, | ||
| {"name": "x", "source": "./third_party/x"}, | ||
| {"name": "clay", "source": "./third_party/clay"}, | ||
| {"name": "circleback", "source": "./third_party/circleback"}, | ||
| {"name": "docusign", "source": "./third_party/docusign"}, | ||
| {"name": "navan", "source": "./third_party/navan"}, | ||
| {"name": "profound", "source": "./third_party/profound"}, | ||
| {"name": "juicebox", "source": "./third_party/juicebox"}, | ||
| {"name": "outreach", "source": "./third_party/outreach"}, | ||
| {"name": "amplemarket", "source": "./third_party/amplemarket"} | ||
| ] | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| { | ||
| "name": "cursor-plugins", | ||
| "description": "Cursor plugins.", | ||
| "owner": { "name": "Rudimar Ronsoni" }, | ||
| "plugins": [ | ||
| {"name": "teaching", "source": "./teaching"}, | ||
| {"name": "continual-learning", "source": "./continual-learning"}, | ||
| {"name": "cursor-team-kit", "source": "./cursor-team-kit"}, | ||
| {"name": "thermos", "source": "./thermos"}, | ||
| {"name": "create-plugin", "source": "./create-plugin"}, | ||
| {"name": "ralph-loop", "source": "./ralph-loop"}, | ||
| {"name": "agent-compatibility", "source": "./agent-compatibility"}, | ||
| {"name": "cli-for-agent", "source": "./cli-for-agent"}, | ||
| {"name": "pr-review-canvas", "source": "./pr-review-canvas"}, | ||
| {"name": "docs-canvas", "source": "./docs-canvas"}, | ||
| {"name": "cursor-sdk", "source": "./cursor-sdk"}, | ||
| {"name": "orchestrate", "source": "./orchestrate"}, | ||
| {"name": "pstack", "source": "./pstack"}, | ||
| {"name": "gmail", "source": "./third_party/gmail"}, | ||
| {"name": "google-drive", "source": "./third_party/google-drive"}, | ||
| {"name": "google-calendar", "source": "./third_party/google-calendar"}, | ||
| {"name": "gong", "source": "./third_party/gong"}, | ||
| {"name": "salesforce", "source": "./third_party/salesforce"}, | ||
| {"name": "playwright", "source": "./third_party/playwright"}, | ||
| {"name": "github", "source": "./third_party/github"}, | ||
| {"name": "ashby", "source": "./third_party/ashby"}, | ||
| {"name": "hubspot", "source": "./third_party/hubspot"}, | ||
| {"name": "intercom", "source": "./third_party/intercom"}, | ||
| {"name": "zoom", "source": "./third_party/zoom"}, | ||
| {"name": "x", "source": "./third_party/x"}, | ||
| {"name": "clay", "source": "./third_party/clay"}, | ||
| {"name": "circleback", "source": "./third_party/circleback"}, | ||
| {"name": "docusign", "source": "./third_party/docusign"}, | ||
| {"name": "navan", "source": "./third_party/navan"}, | ||
| {"name": "profound", "source": "./third_party/profound"}, | ||
| {"name": "juicebox", "source": "./third_party/juicebox"}, | ||
| {"name": "outreach", "source": "./third_party/outreach"}, | ||
| {"name": "amplemarket", "source": "./third_party/amplemarket"} | ||
| ] | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| // advisor - OpenCode adapter for Cursor plugin | ||
| // Reads existing assets (skills/, agents/, rules/, hooks/) at runtime and registers via OpenCode plugin API. | ||
|
|
||
| import { fileURLToPath } from "node:url"; | ||
| import { join } from "node:path"; | ||
| import { readFile, readdir } from "node:fs/promises"; | ||
|
|
||
| const PLUGIN_DIR = fileURLToPath(new URL(".", import.meta.url)); | ||
|
|
||
| export const AdvisorPlugin = async ({ directory }) => ({ | ||
| config: async (config) => { | ||
| const skills = ["advisor"]; | ||
| config.permission ??= { skill: {} }; | ||
| for (const s of skills) config.permission.skill[s] = "allow"; | ||
| config.agent ??= {}; | ||
| const agentsDir = join(PLUGIN_DIR, "agents"); | ||
| for (const agentFile of ["advisor-subagent.md"]) { | ||
| const name = agentFile.replace(/\.md$/, ""); | ||
| const prompt = await readFile(join(agentsDir, agentFile), "utf-8"); | ||
| config.agent[name] = { description: name, mode: "subagent", prompt, permission: { edit: "deny", bash: "ask" } }; | ||
| } | ||
|
|
||
| }, | ||
|
|
||
| // afterFileEdit -> tool.execute.after (filter edit tools) | ||
| "tool.execute.after": async (input, output) => { | ||
| const editTools = ["edit", "write", "patch", "replace"]; | ||
| if (editTools.includes(input.tool)) { | ||
| // // Would run: mark-pending.sh | ||
| } | ||
| }, | ||
| // afterAgentResponse -> chat.message | ||
| "chat.message": async (input, output) => { | ||
| // // Would run: capture-response.sh | ||
| }, | ||
| // subagentStop -> event listener for subagent | ||
| event: async ({ event }) => { | ||
| if (event.type === "session.agent.stop" && event.agent === "advisor-subagent") { | ||
| // // Would run: record-consult.sh | ||
| } | ||
| }, | ||
| // stop -> session.idle | ||
| "session.idle": async (input, output) => { | ||
| // // Would run: stop-hook.sh | ||
| }, | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OpenCode hooks never run scriptsHigh Severity · Logic Bug Hook translations for Additional Locations (2)Reviewed by Cursor Bugbot for commit c801023. Configure here. |
||
| // No-op hooks for interface completeness | ||
| "tool.execute.before": async () => {}, | ||
| }); | ||
|
|
||
| export default AdvisorPlugin; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| { | ||
| "name": "agent-compatibility", | ||
| "version": "1.0.0", | ||
| "description": "CLI-backed repo compatibility scans plus agents that audit startup, validation, and docs against reality.", | ||
| "author": { | ||
| "name": "Cursor", | ||
| "email": "plugins@cursor.com" | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| { | ||
| "name": "agent-compatibility", | ||
| "version": "1.0.0", | ||
| "description": "CLI-backed repo compatibility scans plus agents that audit startup, validation, and docs against reality.", | ||
| "author": { | ||
| "name": "Cursor", | ||
| "email": "plugins@cursor.com" | ||
| }, | ||
| "skills": "./skills/" | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| { | ||
| "name": "agent-compatibility", | ||
| "version": "1.0.0", | ||
| "description": "CLI-backed repo compatibility scans plus agents that audit startup, validation, and docs against reality.", | ||
| "author": { | ||
| "name": "Cursor", | ||
| "email": "plugins@cursor.com" | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| // agent-compatibility - OpenCode adapter for Cursor plugin | ||
| // Reads existing assets (skills/, agents/, rules/, hooks/) at runtime and registers via OpenCode plugin API. | ||
|
|
||
| import { fileURLToPath } from "node:url"; | ||
| import { join } from "node:path"; | ||
| import { readFile, readdir } from "node:fs/promises"; | ||
|
|
||
| const PLUGIN_DIR = fileURLToPath(new URL(".", import.meta.url)); | ||
|
|
||
| export const AgentCompatibilityPlugin = async ({ directory }) => ({ | ||
| config: async (config) => { | ||
| const skills = ["check-agent-compatibility"]; | ||
| config.permission ??= { skill: {} }; | ||
| for (const s of skills) config.permission.skill[s] = "allow"; | ||
| config.agent ??= {}; | ||
| const agentsDir = join(PLUGIN_DIR, "agents"); | ||
| for (const agentFile of ["compatibility-scan-review.md","docs-reliability-review.md","startup-review.md","validation-review.md"]) { | ||
| const name = agentFile.replace(/\.md$/, ""); | ||
| const prompt = await readFile(join(agentsDir, agentFile), "utf-8"); | ||
| config.agent[name] = { description: name, mode: "subagent", prompt, permission: { edit: "deny", bash: "ask" } }; | ||
| } | ||
|
|
||
| }, | ||
|
|
||
|
|
||
| // No-op hooks for interface completeness | ||
| "tool.execute.before": async () => {}, | ||
| }); | ||
|
|
||
| export default AgentCompatibilityPlugin; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| { | ||
| "name": "cli-for-agent", | ||
| "version": "1.0.0", | ||
| "description": "Patterns for designing CLIs that coding agents can run reliably: non-interactive flags, layered help with examples, pipelines, actionable errors, idempotency, and dry-run.", | ||
| "author": { | ||
| "name": "Cursor", | ||
| "email": "plugins@cursor.com" | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| { | ||
| "name": "cli-for-agent", | ||
| "version": "1.0.0", | ||
| "description": "Patterns for designing CLIs that coding agents can run reliably: non-interactive flags, layered help with examples, pipelines, actionable errors, idempotency, and dry-run.", | ||
| "author": { | ||
| "name": "Cursor", | ||
| "email": "plugins@cursor.com" | ||
| }, | ||
| "skills": "./skills/" | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| { | ||
| "name": "cli-for-agent", | ||
| "version": "1.0.0", | ||
| "description": "Patterns for designing CLIs that coding agents can run reliably: non-interactive flags, layered help with examples, pipelines, actionable errors, idempotency, and dry-run.", | ||
| "author": { | ||
| "name": "Cursor", | ||
| "email": "plugins@cursor.com" | ||
| } | ||
| } |


There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Skill permission write can throw
Medium Severity · Logic Bug
config.permission ??= { skill: {} }only initializes whenpermissionis missing. If OpenCode or the user already setpermissionwithout askillobject, assigningconfig.permission.skill[s]throws and the plugin config hook fails. The same pattern is in every skill-first adapter.Additional Locations (2)
pstack/opencode.js#L12-L14teaching/opencode.js#L12-L14Reviewed by Cursor Bugbot for commit c801023. Configure here.