@rama_nigg/open-cursor 2.3.1 → 2.3.3

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.
package/README.md CHANGED
@@ -5,13 +5,24 @@
5
5
  <img src="https://img.shields.io/badge/macOS-000000?style=for-the-badge&logo=apple&logoColor=white" alt="macOS" />
6
6
  </p>
7
7
 
8
- No prompt limits. No broken streams. Full thinking + tool support in Opencode. Your Cursor subscription, properly integrated.
8
+ No prompt limits. No broken streams. Full thinking + tool support in OpenCode. Your Cursor subscription, properly integrated.
9
+
10
+ ## Prerequisites
11
+
12
+ Required: [OpenCode](https://opencode.ai/) + [cursor-agent](https://cursor.com/) (`curl -fsSL https://cursor.com/install | bash && cursor-agent login`)
13
+ Optional: [Bun](https://bun.sh/) (Options B-F), [Go 1.21+](https://go.dev/) (Option D)
9
14
 
10
15
  ## Installation
11
16
 
12
- **Option A — Add to opencode.json (Recommended)**
17
+ ### Option A — One-line installer
18
+
19
+ ```bash
20
+ curl -fsSL https://raw.githubusercontent.com/Nomadcxx/opencode-cursor/main/install.sh | bash
21
+ ```
13
22
 
14
- The simplest approachjust add the npm package to your OpenCode config:
23
+ ### Option B Add to opencode.json
24
+
25
+ Add to `~/.config/opencode/opencode.json`:
15
26
 
16
27
  ```json
17
28
  {
@@ -21,45 +32,57 @@ The simplest approach—just add the npm package to your OpenCode config:
21
32
  "name": "Cursor ACP",
22
33
  "npm": "@ai-sdk/openai-compatible",
23
34
  "models": {
24
- "cursor-acp/claude-sonnet": { "name": "Claude Sonnet" },
25
- "cursor-acp/gpt-4o": { "name": "GPT-4o" },
26
- "cursor-acp/gemini-2.5-pro": { "name": "Gemini 2.5 Pro" },
27
- "cursor-acp/cursor-small": { "name": "Cursor Small" }
35
+ "cursor-acp/auto": { "name": "Auto" },
36
+ "cursor-acp/composer-1.5": { "name": "Composer 1.5" },
37
+ "cursor-acp/composer-1": { "name": "Composer 1" },
38
+ "cursor-acp/gpt-5.3-codex": { "name": "GPT-5.3 Codex" },
39
+ "cursor-acp/gpt-5.3-codex-low": { "name": "GPT-5.3 Codex Low" },
40
+ "cursor-acp/gpt-5.3-codex-high": { "name": "GPT-5.3 Codex High" },
41
+ "cursor-acp/gpt-5.3-codex-xhigh": { "name": "GPT-5.3 Codex Extra High" },
42
+ "cursor-acp/gpt-5.3-codex-fast": { "name": "GPT-5.3 Codex Fast" },
43
+ "cursor-acp/gpt-5.3-codex-low-fast": { "name": "GPT-5.3 Codex Low Fast" },
44
+ "cursor-acp/gpt-5.3-codex-high-fast": { "name": "GPT-5.3 Codex High Fast" },
45
+ "cursor-acp/gpt-5.3-codex-xhigh-fast": { "name": "GPT-5.3 Codex Extra High Fast" },
46
+ "cursor-acp/gpt-5.2": { "name": "GPT-5.2" },
47
+ "cursor-acp/gpt-5.2-codex": { "name": "GPT-5.2 Codex" },
48
+ "cursor-acp/gpt-5.2-codex-high": { "name": "GPT-5.2 Codex High" },
49
+ "cursor-acp/gpt-5.2-codex-low": { "name": "GPT-5.2 Codex Low" },
50
+ "cursor-acp/gpt-5.2-codex-xhigh": { "name": "GPT-5.2 Codex Extra High" },
51
+ "cursor-acp/gpt-5.2-codex-fast": { "name": "GPT-5.2 Codex Fast" },
52
+ "cursor-acp/gpt-5.2-codex-high-fast": { "name": "GPT-5.2 Codex High Fast" },
53
+ "cursor-acp/gpt-5.2-codex-low-fast": { "name": "GPT-5.2 Codex Low Fast" },
54
+ "cursor-acp/gpt-5.2-codex-xhigh-fast": { "name": "GPT-5.2 Codex Extra High Fast" },
55
+ "cursor-acp/gpt-5.1-codex-max": { "name": "GPT-5.1 Codex Max" },
56
+ "cursor-acp/gpt-5.1-codex-max-high": { "name": "GPT-5.1 Codex Max High" },
57
+ "cursor-acp/opus-4.6-thinking": { "name": "Claude 4.6 Opus (Thinking)" },
58
+ "cursor-acp/sonnet-4.5-thinking": { "name": "Claude 4.5 Sonnet (Thinking)" },
59
+ "cursor-acp/gpt-5.2-high": { "name": "GPT-5.2 High" },
60
+ "cursor-acp/opus-4.6": { "name": "Claude 4.6 Opus" },
61
+ "cursor-acp/opus-4.5": { "name": "Claude 4.5 Opus" },
62
+ "cursor-acp/opus-4.5-thinking": { "name": "Claude 4.5 Opus (Thinking)" },
63
+ "cursor-acp/sonnet-4.5": { "name": "Claude 4.5 Sonnet" },
64
+ "cursor-acp/gpt-5.1-high": { "name": "GPT-5.1 High" },
65
+ "cursor-acp/gemini-3-pro": { "name": "Gemini 3 Pro" },
66
+ "cursor-acp/gemini-3-flash": { "name": "Gemini 3 Flash" },
67
+ "cursor-acp/grok": { "name": "Grok" }
28
68
  }
29
69
  }
30
70
  }
31
71
  }
32
72
  ```
33
73
 
34
- After authenticating with `cursor-agent login`, run `cursor-agent models` to see the full model list, or use one of the automated installers below to auto-discover models.
35
-
36
- **Prerequisites:** Only OpenCode required. OpenCode's Bun runtime resolves the npm package automatically.
37
-
38
- **Option B — One-line installer (curl)**
39
-
40
- ```bash
41
- curl -fsSL https://raw.githubusercontent.com/Nomadcxx/opencode-cursor/main/install.sh | bash
42
- ```
43
-
44
- This automated installer detects your environment and chooses the best installation method.
74
+ > Update models anytime: `cursor-agent models`
45
75
 
46
- **Option C — npm global install + CLI**
76
+ ### Option C — npm global + CLI
47
77
 
48
78
  ```bash
49
79
  npm install -g @rama_nigg/open-cursor
50
80
  open-cursor install
51
81
  ```
52
82
 
53
- Upgrade later with:
54
-
55
- ```bash
56
- npm update -g @rama_nigg/open-cursor
57
- open-cursor install
58
- ```
59
-
60
- **Option D — Go TUI installer**
83
+ Upgrade: `npm update -g @rama_nigg/open-cursor`
61
84
 
62
- Interactive visual installer with dual-mode support (quick install or build from source):
85
+ ### Option D Go TUI installer
63
86
 
64
87
  ```bash
65
88
  git clone https://github.com/Nomadcxx/opencode-cursor.git
@@ -67,148 +90,30 @@ cd opencode-cursor
67
90
  go build -o ./installer ./cmd/installer && ./installer
68
91
  ```
69
92
 
70
- **Option E — LLM instructions**
71
-
72
- Paste this into any LLM agent (Claude Code, OpenCode, Cursor, etc.):
93
+ ### Option E — LLM paste
73
94
 
74
95
  ```
75
- Install the cursor-acp plugin for OpenCode using the npm package approach:
76
-
77
- 1. Edit your opencode.json config file (usually at ~/.config/opencode/opencode.json)
78
- 2. Add "@rama_nigg/open-cursor@latest" to the plugin array
79
- 3. Add the cursor-acp provider configuration with models
80
- 4. Restart OpenCode
81
-
82
- Example configuration:
83
- {
84
- "plugin": ["@rama_nigg/open-cursor@latest"],
85
- "provider": {
86
- "cursor-acp": {
87
- "name": "Cursor ACP",
88
- "npm": "@ai-sdk/openai-compatible",
89
- "models": {
90
- "cursor-acp/claude-sonnet": { "name": "Claude Sonnet" }
91
- }
92
- }
93
- }
94
- }
95
-
96
- 5. Authenticate: cursor-agent login
97
- 6. Verify: opencode models | grep cursor-acp
96
+ Install open-cursor for OpenCode: edit ~/.config/opencode/opencode.json, add "@rama_nigg/open-cursor@latest" to "plugin", add a "cursor-acp" provider with npm "@ai-sdk/openai-compatible" and models from `cursor-agent models` prefixed with "cursor-acp/". Auth: `cursor-agent login`. Verify: `opencode models | grep cursor-acp`.
98
97
  ```
99
98
 
100
- **Option F — Manual (from source)**
101
-
102
- For developers and contributors who want full control:
99
+ ### Option F — Manual (from source)
103
100
 
104
101
  ```bash
105
- git clone https://github.com/Nomadcxx/opencode-cursor.git
106
- cd opencode-cursor
102
+ git clone https://github.com/Nomadcxx/opencode-cursor.git && cd opencode-cursor
107
103
  bun install && bun run build
108
- mkdir -p ~/.config/opencode/plugin
109
104
  ln -sf $(pwd)/dist/plugin-entry.js ~/.config/opencode/plugin/cursor-acp.js
110
- ```
111
-
112
- The automated installers handle configuration automatically. For manual installs, run the sync script to populate models:
113
-
114
- ```bash
115
105
  ./scripts/sync-models.sh
116
106
  ```
117
107
 
118
- Or configure manually by adding this to `~/.config/opencode/opencode.json` (then run `./scripts/sync-models.sh` to populate models):
119
-
120
- ```json
121
- {
122
- "plugin": ["cursor-acp"],
123
- "provider": {
124
- "cursor-acp": {
125
- "name": "Cursor",
126
- "npm": "@ai-sdk/openai-compatible",
127
- "options": { "baseURL": "http://127.0.0.1:32124/v1" },
128
- "models": {
129
- "auto": { "name": "Auto" },
130
- "composer-1.5": { "name": "Composer 1.5" },
131
- "composer-1": { "name": "Composer 1" },
132
- "gpt-5.3-codex": { "name": "GPT-5.3 Codex" },
133
- "gpt-5.3-codex-low": { "name": "GPT-5.3 Codex Low" },
134
- "gpt-5.3-codex-high": { "name": "GPT-5.3 Codex High" },
135
- "gpt-5.3-codex-xhigh": { "name": "GPT-5.3 Codex Extra High" },
136
- "gpt-5.3-codex-fast": { "name": "GPT-5.3 Codex Fast" },
137
- "gpt-5.3-codex-low-fast": { "name": "GPT-5.3 Codex Low Fast" },
138
- "gpt-5.3-codex-high-fast": { "name": "GPT-5.3 Codex High Fast" },
139
- "gpt-5.3-codex-xhigh-fast": { "name": "GPT-5.3 Codex Extra High Fast" },
140
- "gpt-5.2": { "name": "GPT-5.2" },
141
- "gpt-5.2-codex": { "name": "GPT-5.2 Codex" },
142
- "gpt-5.2-codex-high": { "name": "GPT-5.2 Codex High" },
143
- "gpt-5.2-codex-low": { "name": "GPT-5.2 Codex Low" },
144
- "gpt-5.2-codex-xhigh": { "name": "GPT-5.2 Codex Extra High" },
145
- "gpt-5.2-codex-fast": { "name": "GPT-5.2 Codex Fast" },
146
- "gpt-5.2-codex-high-fast": { "name": "GPT-5.2 Codex High Fast" },
147
- "gpt-5.2-codex-low-fast": { "name": "GPT-5.2 Codex Low Fast" },
148
- "gpt-5.2-codex-xhigh-fast": { "name": "GPT-5.2 Codex Extra High Fast" },
149
- "gpt-5.1-codex-max": { "name": "GPT-5.1 Codex Max" },
150
- "gpt-5.1-codex-max-high": { "name": "GPT-5.1 Codex Max High" },
151
- "opus-4.6-thinking": { "name": "Claude 4.6 Opus (Thinking)" },
152
- "sonnet-4.5-thinking": { "name": "Claude 4.5 Sonnet (Thinking)" },
153
- "gpt-5.2-high": { "name": "GPT-5.2 High" },
154
- "opus-4.6": { "name": "Claude 4.6 Opus" },
155
- "opus-4.5": { "name": "Claude 4.5 Opus" },
156
- "opus-4.5-thinking": { "name": "Claude 4.5 Opus (Thinking)" },
157
- "sonnet-4.5": { "name": "Claude 4.5 Sonnet" },
158
- "gpt-5.1-high": { "name": "GPT-5.1 High" },
159
- "gemini-3-pro": { "name": "Gemini 3 Pro" },
160
- "gemini-3-flash": { "name": "Gemini 3 Flash" },
161
- "grok": { "name": "Grok" }
162
- }
163
- }
164
- }
165
- }
166
- ```
167
-
168
- ### Plugin Configuration Reference
169
-
170
- Depending on your installation method, use the appropriate plugin identifier:
171
-
172
- **npm package (recommended for production):**
173
- ```json
174
- "plugin": ["@rama_nigg/open-cursor@latest"]
175
- ```
176
-
177
- **Local build (for development):**
178
- ```json
179
- "plugin": ["cursor-acp"]
180
- ```
181
-
182
- Both approaches work—the npm package is resolved automatically by OpenCode's Bun runtime, while the local build requires the symlink setup shown in Option F above.
108
+ Add `"cursor-acp"` to the `plugin` array and reuse the provider block from Option B.
183
109
 
184
110
  ## Authentication
185
111
 
186
- ### Option 1: Via OpenCode (Recommended)
187
-
188
- ```bash
189
- opencode auth login
190
- ```
191
-
192
- Then follow the prompts:
193
-
194
- 1. Select **"Other"** from the provider list
195
- 2. Enter provider id: **cursor-acp**
196
- 3. Browser will open automatically - click "Continue with Cursor"
197
- 4. Return to terminal when you see "Login successful"
198
-
199
- ### Option 2: Direct (CLI only)
200
-
201
112
  ```bash
202
- cursor-agent login
113
+ opencode auth login # provider id: cursor-acp
114
+ cursor-agent login # direct
203
115
  ```
204
116
 
205
- Then open the URL shown in your browser and complete authentication.
206
-
207
- Credential file locations:
208
-
209
- - macOS: `~/.cursor/cli-config.json` (current) or `~/.cursor/auth.json` (legacy)
210
- - Linux: `~/.config/cursor/cli-config.json` or `~/.config/cursor/auth.json` (or `$XDG_CONFIG_HOME/cursor/`)
211
-
212
117
  ## Usage
213
118
 
214
119
  ```bash
@@ -221,7 +126,7 @@ opencode run "your prompt" --model cursor-acp/sonnet-4.5
221
126
  ```mermaid
222
127
  flowchart TB
223
128
  OC["OpenCode"] --> SDK["@ai-sdk/openai-compatible"]
224
- SDK -->|"POST /v1/chat/completions"| PROXY["cursor-acp proxy :32124"]
129
+ SDK -->|"POST /v1/chat/completions"| PROXY["open-cursor proxy :32124"]
225
130
  PROXY -->|"spawn per request"| AGENT["cursor-agent --output-format stream-json"]
226
131
  AGENT -->|"HTTPS"| CURSOR["Cursor API"]
227
132
  CURSOR --> AGENT
@@ -238,101 +143,32 @@ flowchart TB
238
143
  SDK -->|"TOOL_RESULT prompt block"| AGENT
239
144
  ```
240
145
 
241
- Default mode is `CURSOR_ACP_TOOL_LOOP_MODE=opencode`: OpenCode owns tool execution, while cursor-acp intercepts and translates `cursor-agent` tool calls into OpenAI-compatible `tool_calls` responses.
242
- Legacy execution mode (`proxy-exec`) is still available for local/SDK/MCP execution through the internal router.
243
-
244
- Detailed architecture: [docs/architecture/runtime-tool-loop.md](docs/architecture/runtime-tool-loop.md).
146
+ Default mode: `CURSOR_ACP_TOOL_LOOP_MODE=opencode`. Legacy `proxy-exec` still available. Details: [docs/architecture/runtime-tool-loop.md](docs/architecture/runtime-tool-loop.md).
245
147
 
246
148
  ## Alternatives
247
149
 
248
- | | cursor-acp | [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) |
249
- | ----------------- | :-------------------------: | :--------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------: | :----------------------------------------------------------------------: |
150
+ | | 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) |
151
+ | ----------------- | :------------------------: | :--------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------: | :----------------------------------------------------------------------: |
250
152
  | **Architecture** | HTTP proxy via cursor-agent | Direct Connect-RPC | HTTP proxy via cursor-agent | Direct Connect-RPC/protobuf |
251
- | **Platform** | Linux, macOS | Linux, macOS | Linux, macOS | macOS only (Keychain) |
252
- | **Max Prompt** | Unlimited (HTTP body) | Unknown | ~128KB (ARG_MAX) | Unknown |
253
- | **Streaming** | ✓ SSE | ✓ SSE | Undocumented | ✓ |
254
- | **Error Parsing** | ✓ (quota/auth/model) | ✗ | ✗ | Debug logging |
255
- | **Installer** | ✓ TUI + one-liner | ✗ | ✗ | ✗ |
256
- | **OAuth Flow** | ✓ OpenCode integration | ✓ Native | Browser login | Keychain |
257
- | **Tool Calling** | ✓ OpenCode-owned loop (default) + proxy-exec mode | ✓ Native | ✓ Experimental | ✗ |
258
- | **Stability** | Stable (uses official CLI) | Experimental | Stable | Experimental |
259
- | **Dependencies** | bun, cursor-agent | npm | bun, cursor-agent | Node.js 18+ |
260
- | **Port** | 32124 | 18741 | 32123 | 4141 |
261
-
262
- ## Prerequisites
263
-
264
- **For Option A (npm-direct):** Only [OpenCode](https://opencode.ai/) required.
265
-
266
- **For Options B-F:**
267
- - [Bun](https://bun.sh/)
268
- - [cursor-agent](https://cursor.com/) - `curl -fsSL https://cursor.com/install | bash`
269
-
270
- **Option B (one-line install):** If Go is installed, the script runs the TUI installer; otherwise it performs a shell-only install (OpenCode + cursor-agent required). For syncing models without the TUI, install [jq](https://jq.org/) or run `./scripts/sync-models.sh` after install.
271
-
272
- **Option D (TUI installer):** Go 1.21+ required to build the installer.
273
-
274
- ## Features
275
-
276
- - HTTP proxy (avoids E2BIG errors)
277
- - Streaming responses with thinking and tool call support
278
- - OAuth authentication
279
- - Error parsing (quota/auth/network)
280
-
281
- ## Development
282
-
283
- Build and run tests locally:
284
-
285
- ```bash
286
- bun install
287
- bun run build
288
- bun run test:ci:unit
289
- bun run test:ci:integration
290
- ```
291
-
292
- CI runs split suites in `.github/workflows/ci.yml`:
293
-
294
- - `unit` job: `bun run test:ci:unit`
295
- - `integration` job: `bun run test:ci:integration`
296
-
297
- Integration CI pins OpenCode-owned loop mode to deterministic settings:
298
-
299
- - `CURSOR_ACP_TOOL_LOOP_MODE=opencode`
300
- - `CURSOR_ACP_PROVIDER_BOUNDARY=v1`
301
- - `CURSOR_ACP_PROVIDER_BOUNDARY_AUTOFALLBACK=false`
302
- - `CURSOR_ACP_TOOL_LOOP_MAX_REPEAT=3`
303
- - `CURSOR_ACP_ENABLE_OPENCODE_TOOLS=true`
304
- - `CURSOR_ACP_FORWARD_TOOL_CALLS=false`
305
- - `CURSOR_ACP_EMIT_TOOL_UPDATES=false`
153
+ | **Platform** | Linux, macOS | Linux, macOS | Linux, macOS | macOS only (Keychain) |
154
+ | **Max Prompt** | Unlimited (HTTP body) | Unknown | ~128KB (ARG_MAX) | Unknown |
155
+ | **Streaming** | ✓ SSE | ✓ SSE | Undocumented | ✓ |
156
+ | **Error Parsing** | ✓ (quota/auth/model) | ✗ | ✗ | Debug logging |
157
+ | **Installer** | ✓ TUI + one-liner | ✗ | ✗ | ✗ |
158
+ | **OAuth Flow** | ✓ OpenCode integration | ✓ Native | Browser login | Keychain |
159
+ | **Tool Calling** | ✓ OpenCode-owned loop + proxy-exec | ✓ Native | ✓ Experimental | ✗ |
160
+ | **Stability** | Stable (uses official CLI) | Experimental | Stable | Experimental |
161
+ | **Dependencies** | bun, cursor-agent | npm | bun, cursor-agent | Node.js 18+ |
162
+ | **Port** | 32124 | 18741 | 32123 | 4141 |
306
163
 
307
164
  ## Troubleshooting
308
165
 
309
- **"fetch() URL is invalid"** - Run `opencode auth login` without arguments
166
+ - `fetch() URL is invalid` `opencode auth login`
167
+ - Model not responding → `cursor-agent login`
168
+ - Quota exceeded → [cursor.com/settings](https://cursor.com/settings)
169
+ - Auth failed → `CURSOR_ACP_LOG_LEVEL=debug opencode auth login cursor-acp`
310
170
 
311
- **Model not responding** - Run `cursor-agent login` to re-authenticate
312
-
313
- **Quota exceeded** - Check [cursor.com/settings](https://cursor.com/settings)
314
-
315
- **Authentication failed or incomplete** - Enable debug logging to diagnose:
316
- ```bash
317
- CURSOR_ACP_LOG_LEVEL=debug opencode auth login cursor-acp
318
- ```
319
-
320
- Common causes:
321
- - Browser didn't open automatically - manually open the URL shown in the terminal
322
- - Auth file not created - ensure `cursor-agent login` works directly first
323
- - Timeout - authentication must complete within 5 minutes
324
-
325
- ### Debug Logging
326
-
327
- Enable verbose logs:
328
- ```bash
329
- CURSOR_ACP_LOG_LEVEL=debug opencode run "your prompt" --model cursor-acp/auto
330
- ```
331
-
332
- Disable log output entirely:
333
- ```bash
334
- CURSOR_ACP_LOG_SILENT=true opencode run "your prompt"
335
- ```
171
+ Debug logging: `CURSOR_ACP_LOG_LEVEL=debug opencode run "your prompt" --model cursor-acp/auto`
336
172
 
337
173
  ## License
338
174
 
@@ -1,21 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from "node:module";
3
- var __create = Object.create;
4
- var __getProtoOf = Object.getPrototypeOf;
5
3
  var __defProp = Object.defineProperty;
6
- var __getOwnPropNames = Object.getOwnPropertyNames;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __toESM = (mod, isNodeMode, target) => {
9
- target = mod != null ? __create(__getProtoOf(mod)) : {};
10
- const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
11
- for (let key of __getOwnPropNames(mod))
12
- if (!__hasOwnProp.call(to, key))
13
- __defProp(to, key, {
14
- get: () => mod[key],
15
- enumerable: true
16
- });
17
- return to;
18
- };
19
4
  var __export = (target, all) => {
20
5
  for (var name in all)
21
6
  __defProp(target, name, {
@@ -1,21 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from "node:module";
3
- var __create = Object.create;
4
- var __getProtoOf = Object.getPrototypeOf;
5
3
  var __defProp = Object.defineProperty;
6
- var __getOwnPropNames = Object.getOwnPropertyNames;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __toESM = (mod, isNodeMode, target) => {
9
- target = mod != null ? __create(__getProtoOf(mod)) : {};
10
- const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
11
- for (let key of __getOwnPropNames(mod))
12
- if (!__hasOwnProp.call(to, key))
13
- __defProp(to, key, {
14
- get: () => mod[key],
15
- enumerable: true
16
- });
17
- return to;
18
- };
19
4
  var __export = (target, all) => {
20
5
  for (var name in all)
21
6
  __defProp(target, name, {
@@ -236,9 +221,24 @@ function checkOpenCode() {
236
221
  };
237
222
  }
238
223
  }
239
- function checkPluginFile(pluginPath) {
224
+ function isNpmDirectInstalled(config) {
225
+ if (!config || typeof config !== "object")
226
+ return false;
227
+ const plugins = config.plugin;
228
+ if (!Array.isArray(plugins))
229
+ return false;
230
+ return plugins.some((p) => typeof p === "string" && p.startsWith(NPM_PACKAGE_PREFIX));
231
+ }
232
+ function checkPluginFile(pluginPath, config) {
240
233
  try {
241
234
  if (!existsSync(pluginPath)) {
235
+ if (isNpmDirectInstalled(config)) {
236
+ return {
237
+ name: "Plugin file",
238
+ passed: true,
239
+ message: "Installed via npm package (no symlink needed)"
240
+ };
241
+ }
242
242
  return {
243
243
  name: "Plugin file",
244
244
  passed: false,
@@ -308,17 +308,24 @@ function checkAiSdk(opencodeDir) {
308
308
  }
309
309
  function runDoctorChecks(configPath, pluginPath) {
310
310
  const opencodeDir = dirname(configPath);
311
+ let config;
312
+ try {
313
+ config = readConfig(configPath);
314
+ } catch {
315
+ config = undefined;
316
+ }
311
317
  return [
312
318
  checkBun(),
313
319
  checkCursorAgent(),
314
320
  checkCursorAgentLogin(),
315
321
  checkOpenCode(),
316
- checkPluginFile(pluginPath),
322
+ checkPluginFile(pluginPath, config),
317
323
  checkProviderConfig(configPath),
318
324
  checkAiSdk(opencodeDir)
319
325
  ];
320
326
  }
321
327
  var PROVIDER_ID = "cursor-acp";
328
+ var NPM_PACKAGE_PREFIX = "@rama_nigg/open-cursor";
322
329
  var DEFAULT_BASE_URL = "http://127.0.0.1:32124/v1";
323
330
  function printHelp() {
324
331
  const binName = basename(process.argv[1] || "open-cursor");
@@ -527,13 +534,20 @@ function commandSyncModels(options) {
527
534
  console.log(`Models synced: ${models.length}`);
528
535
  console.log(`Config path: ${configPath}`);
529
536
  }
537
+ var NPM_PACKAGE = "@rama_nigg/open-cursor";
530
538
  function commandUninstall(options) {
531
539
  const { configPath, pluginPath } = resolvePaths(options);
532
540
  rmSync(pluginPath, { force: true });
533
541
  if (existsSync(configPath)) {
534
542
  const config = readConfig(configPath);
535
543
  if (Array.isArray(config.plugin)) {
536
- config.plugin = config.plugin.filter((name) => name !== PROVIDER_ID);
544
+ config.plugin = config.plugin.filter((name) => {
545
+ if (name === PROVIDER_ID)
546
+ return false;
547
+ if (typeof name === "string" && name.startsWith(NPM_PACKAGE))
548
+ return false;
549
+ return true;
550
+ });
537
551
  }
538
552
  if (config.provider && typeof config.provider === "object") {
539
553
  delete config.provider[PROVIDER_ID];
@@ -565,22 +579,32 @@ function getStatusResult(configPath, pluginPath) {
565
579
  pluginTarget = undefined;
566
580
  }
567
581
  }
582
+ let config;
568
583
  let providerEnabled = false;
569
584
  let baseUrl = "http://127.0.0.1:32124/v1";
570
585
  let modelCount = 0;
571
586
  if (existsSync(configPath)) {
572
- const config = readConfig(configPath);
587
+ config = readConfig(configPath);
573
588
  const provider = config.provider?.["cursor-acp"];
574
589
  providerEnabled = !!provider;
575
590
  if (provider?.options?.baseURL) {
576
591
  baseUrl = provider.options.baseURL;
577
592
  }
578
593
  modelCount = Object.keys(provider?.models || {}).length;
594
+ } else {
595
+ config = undefined;
579
596
  }
580
597
  const opencodeDir = dirname(configPath);
581
598
  const sdkPath = join(opencodeDir, "node_modules", "@ai-sdk", "openai-compatible");
582
599
  const aiSdkInstalled = existsSync(sdkPath);
600
+ let installMethod = "none";
601
+ if (pluginType !== "missing") {
602
+ installMethod = "symlink";
603
+ } else if (isNpmDirectInstalled(config)) {
604
+ installMethod = "npm-direct";
605
+ }
583
606
  return {
607
+ installMethod,
584
608
  plugin: {
585
609
  path: pluginPath,
586
610
  type: pluginType,
@@ -615,6 +639,7 @@ function commandStatus(options) {
615
639
  } else {
616
640
  console.log(` Type: missing`);
617
641
  }
642
+ console.log(` Install method: ${result.installMethod}`);
618
643
  console.log("");
619
644
  console.log("Provider");
620
645
  console.log(` Config: ${result.provider.configPath}`);