@evanovation/open-cursor 2.4.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/LICENSE +28 -0
  2. package/README.md +270 -0
  3. package/dist/cli/discover.js +527 -0
  4. package/dist/cli/mcptool.js +10339 -0
  5. package/dist/cli/opencode-cursor.js +2989 -0
  6. package/dist/index.js +20588 -0
  7. package/dist/plugin-entry.js +19848 -0
  8. package/package.json +82 -0
  9. package/scripts/cursor-agent-runner.mjs +272 -0
  10. package/scripts/sdk-runner.mjs +412 -0
  11. package/src/acp/metrics.ts +83 -0
  12. package/src/acp/sessions.ts +107 -0
  13. package/src/acp/tools.ts +209 -0
  14. package/src/auth.ts +175 -0
  15. package/src/cli/discover.ts +53 -0
  16. package/src/cli/mcptool.ts +133 -0
  17. package/src/cli/model-discovery.ts +71 -0
  18. package/src/cli/opencode-cursor.ts +1195 -0
  19. package/src/client/cursor-agent-child.ts +459 -0
  20. package/src/client/sdk-child.ts +550 -0
  21. package/src/client/simple.ts +293 -0
  22. package/src/commands/status.ts +39 -0
  23. package/src/index.ts +39 -0
  24. package/src/mcp/client-manager.ts +166 -0
  25. package/src/mcp/config.ts +169 -0
  26. package/src/mcp/tool-bridge.ts +133 -0
  27. package/src/models/config.ts +64 -0
  28. package/src/models/discovery.ts +105 -0
  29. package/src/models/index.ts +3 -0
  30. package/src/models/pricing.ts +196 -0
  31. package/src/models/sync.ts +247 -0
  32. package/src/models/types.ts +11 -0
  33. package/src/models/variants.ts +446 -0
  34. package/src/plugin-entry.ts +28 -0
  35. package/src/plugin-toggle.ts +81 -0
  36. package/src/plugin.ts +2802 -0
  37. package/src/provider/backend.ts +71 -0
  38. package/src/provider/boundary.ts +168 -0
  39. package/src/provider/passthrough-tracker.ts +38 -0
  40. package/src/provider/runtime-interception.ts +818 -0
  41. package/src/provider/tool-loop-guard.ts +644 -0
  42. package/src/provider/tool-schema-compat.ts +800 -0
  43. package/src/provider.ts +268 -0
  44. package/src/proxy/formatter.ts +60 -0
  45. package/src/proxy/handler.ts +29 -0
  46. package/src/proxy/incremental-prompt.ts +74 -0
  47. package/src/proxy/prompt-builder.ts +204 -0
  48. package/src/proxy/server.ts +207 -0
  49. package/src/proxy/session-resume.ts +312 -0
  50. package/src/proxy/tool-loop.ts +359 -0
  51. package/src/proxy/types.ts +13 -0
  52. package/src/services/toast-service.ts +81 -0
  53. package/src/streaming/ai-sdk-parts.ts +109 -0
  54. package/src/streaming/delta-tracker.ts +89 -0
  55. package/src/streaming/line-buffer.ts +44 -0
  56. package/src/streaming/openai-sse.ts +118 -0
  57. package/src/streaming/parser.ts +22 -0
  58. package/src/streaming/types.ts +158 -0
  59. package/src/tools/core/executor.ts +25 -0
  60. package/src/tools/core/registry.ts +27 -0
  61. package/src/tools/core/types.ts +31 -0
  62. package/src/tools/defaults.ts +954 -0
  63. package/src/tools/discovery.ts +140 -0
  64. package/src/tools/executors/cli.ts +59 -0
  65. package/src/tools/executors/local.ts +25 -0
  66. package/src/tools/executors/mcp.ts +39 -0
  67. package/src/tools/executors/sdk.ts +39 -0
  68. package/src/tools/index.ts +8 -0
  69. package/src/tools/registry.ts +34 -0
  70. package/src/tools/router.ts +123 -0
  71. package/src/tools/schema.ts +58 -0
  72. package/src/tools/skills/loader.ts +61 -0
  73. package/src/tools/skills/resolver.ts +21 -0
  74. package/src/tools/types.ts +29 -0
  75. package/src/types.ts +8 -0
  76. package/src/usage.ts +112 -0
  77. package/src/utils/binary.ts +71 -0
  78. package/src/utils/errors.ts +224 -0
  79. package/src/utils/logger.ts +191 -0
  80. package/src/utils/perf.ts +76 -0
package/LICENSE ADDED
@@ -0,0 +1,28 @@
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2026, Nomadcxx
4
+
5
+ Redistribution and use in source and binary forms, with or without
6
+ modification, are permitted provided that the following conditions are met:
7
+
8
+ 1. Redistributions of source code must retain the above copyright notice, this
9
+ list of conditions and the following disclaimer.
10
+
11
+ 2. Redistributions in binary form must reproduce the above copyright notice,
12
+ this list of conditions and the following disclaimer in the documentation
13
+ and/or other materials provided with the distribution.
14
+
15
+ 3. Neither the name of the copyright holder nor the names of its
16
+ contributors may be used to endorse or promote products derived from
17
+ this software without specific prior written permission.
18
+
19
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package/README.md ADDED
@@ -0,0 +1,270 @@
1
+ ![header](docs/header.png)
2
+
3
+ <p align="center">
4
+ <img src="https://img.shields.io/badge/Linux-FCC624?style=for-the-badge&logo=linux&logoColor=black" alt="Linux" />
5
+ <img src="https://img.shields.io/badge/macOS-000000?style=for-the-badge&logo=apple&logoColor=white" alt="macOS" />
6
+ <img src="https://img.shields.io/badge/Windows-0078D6?style=for-the-badge&logo=windows&logoColor=white" alt="Windows" />
7
+ </p>
8
+
9
+ No prompt limits. No broken streams. Full thinking + tool support in OpenCode. Your Cursor subscription, properly integrated.
10
+
11
+ ## Installation
12
+
13
+ ### Option A — One-line installer
14
+
15
+ **Linux & macOS:**
16
+ ```bash
17
+ curl -fsSL https://raw.githubusercontent.com/EvanNotFound/opencode-cursor/main/install.sh | bash
18
+ ```
19
+
20
+ **Windows:**
21
+ ```powershell
22
+ npm install -g @evanovation/open-cursor
23
+ open-cursor install
24
+ ```
25
+
26
+ Then authenticate and verify:
27
+ ```bash
28
+ cursor-agent login
29
+ opencode models | grep cursor-acp
30
+ ```
31
+
32
+ ### Option B — npm global + CLI
33
+
34
+ ```bash
35
+ npm install -g @evanovation/open-cursor
36
+ open-cursor install
37
+ ```
38
+
39
+ Upgrade: `npm update -g @evanovation/open-cursor`
40
+
41
+ <details>
42
+ <summary><b>Option C</b> — Add to opencode.json</summary>
43
+
44
+ Add to `~/.config/opencode/opencode.json` (or `%USERPROFILE%\.config\opencode\opencode.json` on Windows):
45
+
46
+ ```json
47
+ {
48
+ "plugin": ["@evanovation/open-cursor@latest"],
49
+ "provider": {
50
+ "cursor-acp": {
51
+ "name": "Cursor ACP",
52
+ "npm": "@ai-sdk/openai-compatible",
53
+ "options": {
54
+ "baseURL": "http://127.0.0.1:32124/v1"
55
+ },
56
+ "models": {
57
+ "cursor-acp/auto": { "name": "Auto" },
58
+
59
+ "cursor-acp/claude-opus-4-7": { "name": "Claude 4.7 Opus" },
60
+ "cursor-acp/claude-4.6-opus": { "name": "Claude 4.6 Opus" },
61
+ "cursor-acp/claude-4.6-sonnet": { "name": "Claude 4.6 Sonnet" },
62
+ "cursor-acp/claude-4.5-opus": { "name": "Claude 4.5 Opus" },
63
+ "cursor-acp/claude-4.5-sonnet": { "name": "Claude 4.5 Sonnet" },
64
+ "cursor-acp/claude-4.5-haiku": { "name": "Claude 4.5 Haiku" },
65
+ "cursor-acp/claude-4-sonnet": { "name": "Claude 4 Sonnet" },
66
+
67
+ "cursor-acp/gpt-5.5": { "name": "GPT-5.5" },
68
+ "cursor-acp/gpt-5.4": { "name": "GPT-5.4" },
69
+ "cursor-acp/gpt-5.4-mini": { "name": "GPT-5.4 Mini" },
70
+ "cursor-acp/gpt-5.4-nano": { "name": "GPT-5.4 Nano" },
71
+ "cursor-acp/gpt-5.3-codex": { "name": "GPT-5.3 Codex" },
72
+ "cursor-acp/gpt-5.2": { "name": "GPT-5.2" },
73
+ "cursor-acp/gpt-5.2-codex": { "name": "GPT-5.2 Codex" },
74
+ "cursor-acp/gpt-5.1-codex": { "name": "GPT-5.1 Codex" },
75
+ "cursor-acp/gpt-5.1-codex-max": { "name": "GPT-5.1 Codex Max" },
76
+ "cursor-acp/gpt-5.1-codex-mini":{ "name": "GPT-5.1 Codex Mini" },
77
+ "cursor-acp/gpt-5-mini": { "name": "GPT-5 Mini" },
78
+
79
+ "cursor-acp/gemini-3.1-pro": { "name": "Gemini 3.1 Pro" },
80
+ "cursor-acp/gemini-3-pro": { "name": "Gemini 3 Pro" },
81
+ "cursor-acp/gemini-3-flash": { "name": "Gemini 3 Flash" },
82
+
83
+ "cursor-acp/composer-2": { "name": "Composer 2" },
84
+ "cursor-acp/composer-2-fast": { "name": "Composer 2 Fast" },
85
+ "cursor-acp/composer-1.5": { "name": "Composer 1.5" },
86
+
87
+ "cursor-acp/grok-4-20": { "name": "Grok 4.20" },
88
+ "cursor-acp/kimi-k2.5": { "name": "Kimi K2.5" }
89
+ }
90
+ }
91
+ }
92
+ }
93
+ ```
94
+
95
+ > **Refresh models anytime** with the bundled CLI:
96
+ > ```bash
97
+ > open-cursor sync-models # plain list
98
+ > open-cursor sync-models --variants --compact # group thinking / fast / -low/-high variants under each base
99
+ > ```
100
+ > The `--variants --compact` form is recommended — it folds dozens of `*-thinking-fast`, `*-high-fast`, etc. into a single entry per family with a `variants` map, and includes `cost` from the official Cursor pricing table so OpenCode TokenSpeed can render usage correctly.
101
+ </details>
102
+
103
+ <details>
104
+ <summary><b>Option D</b> — Go TUI installer</summary>
105
+
106
+ ```bash
107
+ git clone https://github.com/EvanNotFound/opencode-cursor.git
108
+ cd opencode-cursor
109
+ go build -o ./installer ./cmd/installer && ./installer
110
+ ```
111
+ </details>
112
+
113
+ <details>
114
+ <summary><b>Option E</b> — LLM paste</summary>
115
+
116
+ ```
117
+ Install open-cursor for OpenCode: edit ~/.config/opencode/opencode.json, add "@evanovation/open-cursor@latest" to "plugin", add a "cursor-acp" provider with npm "@ai-sdk/openai-compatible" and a baseURL of http://127.0.0.1:32124/v1. Populate models by running `open-cursor sync-models --variants --compact` after install (or copy the model list from the README). Auth: `cursor-agent login`. Verify: `opencode models | grep cursor-acp`.
118
+ ```
119
+ </details>
120
+
121
+ <details>
122
+ <summary><b>Option F</b> — Development (from source)</summary>
123
+
124
+ ```bash
125
+ git clone https://github.com/EvanNotFound/opencode-cursor.git
126
+ cd opencode-cursor
127
+ ./scripts/install-plugin.sh
128
+ ```
129
+
130
+ Verify: `opencode models | grep cursor-acp`
131
+ </details>
132
+
133
+ ## Authentication
134
+
135
+ Most users:
136
+ ```bash
137
+ cursor-agent login
138
+ ```
139
+
140
+ Or via OpenCode:
141
+ ```bash
142
+ opencode auth login --provider cursor-acp
143
+ ```
144
+
145
+ <details>
146
+ <summary><b>SDK backend auth</b> (only if using <code>CURSOR_ACP_BACKEND=sdk</code> or SDK fallback)</summary>
147
+
148
+ Set a real Cursor API key from [cursor.com/settings](https://cursor.com/settings):
149
+
150
+ ```bash
151
+ export CURSOR_API_KEY=<your-api-key>
152
+ ```
153
+
154
+ Other supported methods (priority order): OpenCode auth store (`opencode auth login --provider cursor-acp`), or `apiKey` in the `cursor-acp` provider options in `opencode.json`.
155
+
156
+ Do not use the historical `cursor-agent` placeholder string as an SDK key.
157
+ </details>
158
+
159
+ ## Usage
160
+
161
+ ```bash
162
+ opencode run "your prompt" --model cursor-acp/auto
163
+ opencode run "your prompt" --model cursor-acp/sonnet-4.5
164
+ ```
165
+
166
+ ## MCP Tool Bridge
167
+
168
+ Any MCP servers already configured in your `opencode.json` work automatically with cursor-acp models — no extra setup needed. The plugin discovers them at startup and injects usage instructions into the system prompt so the model calls them via cursor-agent's Shell tool.
169
+
170
+ `mcptool` is a shell CLI, so opencode applies your `bash` permission rules to `mcptool call ...`. If you rely on MCP tools asking for confirmation, keep `bash` as `ask` or add explicit `ask`/`deny` rules for `mcptool call *`.
171
+
172
+ ```bash
173
+ mcptool servers # list discovered servers
174
+ mcptool tools [server] # list available tools
175
+ mcptool call hybrid-memory memory_stats # call a tool manually
176
+ mcptool call playwright browser_navigate '{"url":"https://example.com"}'
177
+ ```
178
+
179
+ Any MCP server using stdio transport works. Tested with hybrid-memory, @modelcontextprotocol/server-filesystem, @playwright/mcp, and @modelcontextprotocol/server-everything.
180
+
181
+ ## Architecture
182
+
183
+ ```mermaid
184
+ flowchart TB
185
+ OC["OpenCode"] --> SDK["@ai-sdk/openai-compatible"]
186
+ SDK -->|"POST /v1/chat/completions"| PROXY["open-cursor proxy :32124"]
187
+ PROXY -->|"spawn persistent"| RUNNER["Node runner: sdk-runner.mjs"]
188
+ RUNNER -->|"stdin: {model, prompt, cwd}"| CURSORSDK["@cursor/sdk Agent.create + send()"]
189
+ CURSORSDK -->|"HTTPS"| CURSOR["Cursor API"]
190
+ CURSOR --> CURSORSDK
191
+
192
+ CURSORSDK -->|"stdout: NDJSON StreamJsonEvent"| PARSER["Parse + convert to SSE"]
193
+ PARSER -->|"assistant / thinking events"| SSE["SSE content chunks"]
194
+ PARSER -->|"tool_call event"| BOUNDARY["Provider boundary (v1 default)"]
195
+ BOUNDARY --> COMPAT["Schema compat + alias normalization"]
196
+ COMPAT --> GUARD["Tool-loop guard"]
197
+ GUARD -->|"emit tool_calls + finish_reason=tool_calls"| SDK
198
+ SDK --> OC
199
+
200
+ OC -->|"execute tool locally"| TOOLRUN["OpenCode tool runtime"]
201
+ TOOLRUN -->|"next request includes role:tool result"| SDK
202
+ SDK -->|"TOOL_RESULT prompt block"| RUNNER
203
+
204
+ RUNNER -->|"Shell tool_call"| MCPTOOL["mcptool CLI"]
205
+ MCPTOOL -->|"stdio"| MCP["MCP Servers"]
206
+ MCP --> MCPTOOL
207
+ MCPTOOL --> RUNNER
208
+ ```
209
+
210
+ <details>
211
+ <summary><b>How the proxy works</b></summary>
212
+
213
+ The proxy uses a dual-backend runtime. In `auto` mode (default) it prefers the `cursor-agent` binary when available. If `cursor-agent` is unavailable and a real Cursor API key is configured, or if `CURSOR_ACP_BACKEND=sdk` is set, a persistent Node.js child process (`scripts/sdk-runner.mjs`) runs `@cursor/sdk` on behalf of the proxy.
214
+
215
+ By default, the SDK Agent runs in isolated mode (`settingSources: []`). To load Cursor environment settings in SDK mode, set `CURSOR_ACP_SETTING_SOURCES=all`.
216
+
217
+ Default tool-loop mode: `CURSOR_ACP_TOOL_LOOP_MODE=opencode`. Details: [docs/architecture/runtime-tool-loop.md](docs/architecture/runtime-tool-loop.md).
218
+
219
+ Startup model refresh is additive by default. Use `CURSOR_ACP_MODEL_AUTO_REFRESH=false` to disable it, or `CURSOR_ACP_MODEL_AUTO_REFRESH=compact` to fold Cursor model variants into opencode variants.
220
+ </details>
221
+
222
+ ## Alternatives
223
+ THERE is currently not a single perfect plugin for cursor in opencode, my advice is stick with what is the LEAST worst option for you.
224
+ | | open-cursor | [yet-another-opencode-cursor-auth](https://github.com/Yukaii/yet-another-opencode-cursor-auth) | [opencode-cursor-auth](https://github.com/POSO-PocketSolutions/opencode-cursor-auth) | [cursor-opencode-auth](https://github.com/R44VC0RP/cursor-opencode-auth) |
225
+ | ----------------- | :------------------------: | :--------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------: | :----------------------------------------------------------------------: |
226
+ | **Architecture** | HTTP proxy via cursor-agent | Direct Connect-RPC | HTTP proxy via cursor-agent | Direct Connect-RPC/protobuf |
227
+ | **Platform** | Linux, macOS, Windows | Linux, macOS | Linux, macOS | macOS only (Keychain) |
228
+ | **Max Prompt** | Unlimited (HTTP body) | Unknown | ~128KB (ARG_MAX) | Unknown |
229
+ | **Streaming** | ✓ SSE | ✓ SSE | Undocumented | ✓ |
230
+ | **Error Parsing** | ✓ (quota/auth/model) | ✗ | ✗ | Debug logging |
231
+ | **Installer** | ✓ TUI + one-liner | ✗ | ✗ | ✗ |
232
+ | **OAuth Flow** | ✓ OpenCode integration | ✓ Native | Browser login | Keychain |
233
+ | **Tool Calling** | ✓ OpenCode-owned loop | ✓ Native | ✓ Experimental | ✗ |
234
+ | **MCP Bridge** | ✓ mcptool CLI (any MCP server) | ✗ | ✗ | ✗ |
235
+ | **Stability** | Stable (uses official CLI) | Experimental | Stable | Experimental |
236
+ | **Dependencies** | bun, cursor-agent | npm | bun, cursor-agent | Node.js 18+ |
237
+ | **Port** | 32124 | 18741 | 32123 | 4141 |
238
+
239
+ ## Troubleshooting
240
+
241
+ - `fetch() URL is invalid` or auth errors → `cursor-agent login` or `opencode auth login --provider cursor-acp`
242
+ - `CURSOR_API_KEY not set` in SDK mode → set a real API key from [cursor.com/settings](https://cursor.com/settings), or use `CURSOR_ACP_BACKEND=auto` with a working `cursor-agent`
243
+ - Model not responding → verify your API key/quota
244
+ - Quota exceeded → [cursor.com/settings](https://cursor.com/settings)
245
+ - Proxy not starting → ensure port 32124 is available
246
+
247
+ Debug logging: `CURSOR_ACP_LOG_LEVEL=debug opencode run "your prompt" --model cursor-acp/auto`
248
+
249
+ ## Roadmap
250
+
251
+ ```mermaid
252
+ flowchart LR
253
+ P1[/Stabilise/] --> P2[/MCP Bridge/] --> P3[/Simplify/] --> P4[/ACP + MCP/]
254
+
255
+ style P1 fill:#264653,stroke:#1d3557,color:#fff
256
+ style P2 fill:#264653,stroke:#1d3557,color:#fff
257
+ style P3 fill:#495057,stroke:#343a40,color:#adb5bd
258
+ style P4 fill:#495057,stroke:#343a40,color:#adb5bd
259
+ ```
260
+
261
+ [X] **Stabilise** — Clean up dead code, fix test isolation
262
+ [X] **MCP Bridge** — Bridge MCP servers into Cursor models via `mcptool` CLI
263
+ [ ] **Simplify** — Rip out serialisation layers
264
+ [ ] **ACP + MCP** — Structured protocols end-to-end
265
+
266
+ **ACP + MCP (deferred)** — End goal is a thin `OpenCode → Cursor ACP → MCP` plugin, not an evolved proxy. We ship the bridge until Cursor's ACP path passes MCP + headless approval re-validation. [Why and when →](docs/architecture/cursor-acp-mcp-future.md)
267
+
268
+ ## License
269
+
270
+ BSD-3-Clause