opencode-ext-connector 0.3.0

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 (332) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/LICENSE +29 -0
  3. package/README.md +207 -0
  4. package/THIRD_PARTY_NOTICES.md +201 -0
  5. package/dist/catalog/parse-ids.d.ts +2 -0
  6. package/dist/catalog/parse-ids.js +49 -0
  7. package/dist/core/adapter.d.ts +16 -0
  8. package/dist/core/adapter.js +20 -0
  9. package/dist/core/clock.d.ts +7 -0
  10. package/dist/core/clock.js +1 -0
  11. package/dist/core/deadline.d.ts +13 -0
  12. package/dist/core/deadline.js +54 -0
  13. package/dist/core/errors.d.ts +57 -0
  14. package/dist/core/errors.js +81 -0
  15. package/dist/core/health.d.ts +22 -0
  16. package/dist/core/health.js +30 -0
  17. package/dist/core/http.d.ts +28 -0
  18. package/dist/core/http.js +1 -0
  19. package/dist/core/ids.d.ts +7 -0
  20. package/dist/core/ids.js +23 -0
  21. package/dist/core/lifecycle.d.ts +4 -0
  22. package/dist/core/lifecycle.js +16 -0
  23. package/dist/core/logger.d.ts +21 -0
  24. package/dist/core/logger.js +61 -0
  25. package/dist/core/models.d.ts +41 -0
  26. package/dist/core/models.js +59 -0
  27. package/dist/core/options.d.ts +31 -0
  28. package/dist/core/options.js +62 -0
  29. package/dist/core/process.d.ts +20 -0
  30. package/dist/core/process.js +1 -0
  31. package/dist/http/fetch-transport.d.ts +2 -0
  32. package/dist/http/fetch-transport.js +75 -0
  33. package/dist/http/package-version.d.ts +7 -0
  34. package/dist/http/package-version.js +46 -0
  35. package/dist/http/read-body.d.ts +9 -0
  36. package/dist/http/read-body.js +22 -0
  37. package/dist/index.d.ts +6 -0
  38. package/dist/index.js +5 -0
  39. package/dist/logging/logger.d.ts +4 -0
  40. package/dist/logging/logger.js +11 -0
  41. package/dist/opencode/auth-store.d.ts +19 -0
  42. package/dist/opencode/auth-store.js +107 -0
  43. package/dist/opencode/beta-api.d.ts +3 -0
  44. package/dist/opencode/beta-api.js +1 -0
  45. package/dist/opencode/catalog-bridge.d.ts +3 -0
  46. package/dist/opencode/catalog-bridge.js +85 -0
  47. package/dist/opencode/health-refresh.d.ts +16 -0
  48. package/dist/opencode/health-refresh.js +49 -0
  49. package/dist/opencode/host-options.d.ts +2 -0
  50. package/dist/opencode/host-options.js +49 -0
  51. package/dist/opencode/language-factory.d.ts +13 -0
  52. package/dist/opencode/language-factory.js +37 -0
  53. package/dist/opencode/ollama-probe.d.ts +2 -0
  54. package/dist/opencode/ollama-probe.js +15 -0
  55. package/dist/opencode/ollama-production.d.ts +4 -0
  56. package/dist/opencode/ollama-production.js +10 -0
  57. package/dist/opencode/plugin.d.ts +33 -0
  58. package/dist/opencode/plugin.js +40 -0
  59. package/dist/opencode/process-exit.d.ts +4 -0
  60. package/dist/opencode/process-exit.js +22 -0
  61. package/dist/opencode/provider-entry.d.ts +25 -0
  62. package/dist/opencode/provider-entry.js +1 -0
  63. package/dist/opencode/providers.d.ts +16 -0
  64. package/dist/opencode/providers.js +140 -0
  65. package/dist/opencode/register-integrations.d.ts +3 -0
  66. package/dist/opencode/register-integrations.js +8 -0
  67. package/dist/opencode/reload.d.ts +9 -0
  68. package/dist/opencode/reload.js +30 -0
  69. package/dist/opencode/v1-anthropic-auth.d.ts +9 -0
  70. package/dist/opencode/v1-anthropic-auth.js +55 -0
  71. package/dist/opencode/v1-catalog.d.ts +13 -0
  72. package/dist/opencode/v1-catalog.js +80 -0
  73. package/dist/opencode/v1-language.d.ts +3 -0
  74. package/dist/opencode/v1-language.js +64 -0
  75. package/dist/opencode/v1-module.d.ts +23 -0
  76. package/dist/opencode/v1-module.js +74 -0
  77. package/dist/opencode/v1-session-auth.d.ts +5 -0
  78. package/dist/opencode/v1-session-auth.js +98 -0
  79. package/dist/providers/claude/adapter.d.ts +7 -0
  80. package/dist/providers/claude/adapter.js +37 -0
  81. package/dist/providers/claude/atomic-private-file.d.ts +13 -0
  82. package/dist/providers/claude/atomic-private-file.js +94 -0
  83. package/dist/providers/claude/auth-json.d.ts +2 -0
  84. package/dist/providers/claude/auth-json.js +14 -0
  85. package/dist/providers/claude/auth.d.ts +24 -0
  86. package/dist/providers/claude/auth.js +200 -0
  87. package/dist/providers/claude/cli-version.d.ts +10 -0
  88. package/dist/providers/claude/cli-version.js +36 -0
  89. package/dist/providers/claude/compat-betas.d.ts +5 -0
  90. package/dist/providers/claude/compat-betas.js +54 -0
  91. package/dist/providers/claude/compat-config.d.ts +8 -0
  92. package/dist/providers/claude/compat-config.js +31 -0
  93. package/dist/providers/claude/compat-request.d.ts +12 -0
  94. package/dist/providers/claude/compat-request.js +151 -0
  95. package/dist/providers/claude/compat-response.d.ts +1 -0
  96. package/dist/providers/claude/compat-response.js +54 -0
  97. package/dist/providers/claude/compat-signing.d.ts +9 -0
  98. package/dist/providers/claude/compat-signing.js +24 -0
  99. package/dist/providers/claude/compat-transform.d.ts +3 -0
  100. package/dist/providers/claude/compat-transform.js +224 -0
  101. package/dist/providers/claude/credentials.d.ts +7 -0
  102. package/dist/providers/claude/credentials.js +37 -0
  103. package/dist/providers/claude/emit-stream.d.ts +2 -0
  104. package/dist/providers/claude/emit-stream.js +62 -0
  105. package/dist/providers/claude/keychain-account.d.ts +1 -0
  106. package/dist/providers/claude/keychain-account.js +14 -0
  107. package/dist/providers/claude/language-model.d.ts +8 -0
  108. package/dist/providers/claude/language-model.js +109 -0
  109. package/dist/providers/claude/models.d.ts +9 -0
  110. package/dist/providers/claude/models.js +24 -0
  111. package/dist/providers/claude/prompt.d.ts +42 -0
  112. package/dist/providers/claude/prompt.js +134 -0
  113. package/dist/providers/claude/refresh.d.ts +19 -0
  114. package/dist/providers/claude/refresh.js +85 -0
  115. package/dist/providers/claude/sse-convert.d.ts +6 -0
  116. package/dist/providers/claude/sse-convert.js +74 -0
  117. package/dist/providers/claude/sse.d.ts +71 -0
  118. package/dist/providers/claude/sse.js +123 -0
  119. package/dist/providers/claude/transform.d.ts +32 -0
  120. package/dist/providers/claude/transform.js +52 -0
  121. package/dist/providers/claude/writeback.d.ts +18 -0
  122. package/dist/providers/claude/writeback.js +140 -0
  123. package/dist/providers/command-code/adapter.d.ts +7 -0
  124. package/dist/providers/command-code/adapter.js +37 -0
  125. package/dist/providers/command-code/auth.d.ts +5 -0
  126. package/dist/providers/command-code/auth.js +88 -0
  127. package/dist/providers/command-code/cli-version.d.ts +10 -0
  128. package/dist/providers/command-code/cli-version.js +36 -0
  129. package/dist/providers/command-code/emit-stream.d.ts +2 -0
  130. package/dist/providers/command-code/emit-stream.js +226 -0
  131. package/dist/providers/command-code/errors.d.ts +33 -0
  132. package/dist/providers/command-code/errors.js +105 -0
  133. package/dist/providers/command-code/language-model.d.ts +15 -0
  134. package/dist/providers/command-code/language-model.js +203 -0
  135. package/dist/providers/command-code/models.d.ts +3 -0
  136. package/dist/providers/command-code/models.js +18 -0
  137. package/dist/providers/command-code/record-stream.d.ts +1 -0
  138. package/dist/providers/command-code/record-stream.js +61 -0
  139. package/dist/providers/command-code/request-lifecycle.d.ts +8 -0
  140. package/dist/providers/command-code/request-lifecycle.js +33 -0
  141. package/dist/providers/command-code/request.d.ts +14 -0
  142. package/dist/providers/command-code/request.js +167 -0
  143. package/dist/providers/command-code/session.d.ts +5 -0
  144. package/dist/providers/command-code/session.js +9 -0
  145. package/dist/providers/cursor/adapter.d.ts +7 -0
  146. package/dist/providers/cursor/adapter.js +37 -0
  147. package/dist/providers/cursor/auth.d.ts +6 -0
  148. package/dist/providers/cursor/auth.js +56 -0
  149. package/dist/providers/cursor/blob-store.d.ts +26 -0
  150. package/dist/providers/cursor/blob-store.js +119 -0
  151. package/dist/providers/cursor/bridge-client.d.ts +33 -0
  152. package/dist/providers/cursor/bridge-client.js +200 -0
  153. package/dist/providers/cursor/bridge-event-sanitize.d.ts +3 -0
  154. package/dist/providers/cursor/bridge-event-sanitize.js +49 -0
  155. package/dist/providers/cursor/bridge-limits.d.ts +3 -0
  156. package/dist/providers/cursor/bridge-limits.js +10 -0
  157. package/dist/providers/cursor/bridge-process.d.ts +45 -0
  158. package/dist/providers/cursor/bridge-process.js +211 -0
  159. package/dist/providers/cursor/bridge-protocol.d.ts +68 -0
  160. package/dist/providers/cursor/bridge-protocol.js +49 -0
  161. package/dist/providers/cursor/bridge-serialize.d.ts +3 -0
  162. package/dist/providers/cursor/bridge-serialize.js +53 -0
  163. package/dist/providers/cursor/bridge-wire.d.ts +3 -0
  164. package/dist/providers/cursor/bridge-wire.js +163 -0
  165. package/dist/providers/cursor/checkpoint-store.d.ts +28 -0
  166. package/dist/providers/cursor/checkpoint-store.js +94 -0
  167. package/dist/providers/cursor/connect-frame-stream.d.ts +19 -0
  168. package/dist/providers/cursor/connect-frame-stream.js +160 -0
  169. package/dist/providers/cursor/connect-frame.d.ts +31 -0
  170. package/dist/providers/cursor/connect-frame.js +121 -0
  171. package/dist/providers/cursor/credentials.d.ts +5 -0
  172. package/dist/providers/cursor/credentials.js +22 -0
  173. package/dist/providers/cursor/direct-run-types.d.ts +33 -0
  174. package/dist/providers/cursor/direct-run-types.js +1 -0
  175. package/dist/providers/cursor/direct-run.d.ts +5 -0
  176. package/dist/providers/cursor/direct-run.js +213 -0
  177. package/dist/providers/cursor/direct-runtime.d.ts +23 -0
  178. package/dist/providers/cursor/direct-runtime.js +111 -0
  179. package/dist/providers/cursor/direct-stream.d.ts +28 -0
  180. package/dist/providers/cursor/direct-stream.js +190 -0
  181. package/dist/providers/cursor/exec-reply.d.ts +13 -0
  182. package/dist/providers/cursor/exec-reply.js +102 -0
  183. package/dist/providers/cursor/h2-bridge-response.d.ts +9 -0
  184. package/dist/providers/cursor/h2-bridge-response.js +51 -0
  185. package/dist/providers/cursor/h2-bridge-session.d.ts +24 -0
  186. package/dist/providers/cursor/h2-bridge-session.js +197 -0
  187. package/dist/providers/cursor/h2-bridge.d.ts +2 -0
  188. package/dist/providers/cursor/h2-bridge.js +12865 -0
  189. package/dist/providers/cursor/http2.d.ts +18 -0
  190. package/dist/providers/cursor/http2.js +144 -0
  191. package/dist/providers/cursor/interaction-reply.d.ts +6 -0
  192. package/dist/providers/cursor/interaction-reply.js +52 -0
  193. package/dist/providers/cursor/language-generate.d.ts +2 -0
  194. package/dist/providers/cursor/language-generate.js +35 -0
  195. package/dist/providers/cursor/language-model.d.ts +13 -0
  196. package/dist/providers/cursor/language-model.js +77 -0
  197. package/dist/providers/cursor/legacy-stream.d.ts +11 -0
  198. package/dist/providers/cursor/legacy-stream.js +115 -0
  199. package/dist/providers/cursor/mcp-tools.d.ts +7 -0
  200. package/dist/providers/cursor/mcp-tools.js +15 -0
  201. package/dist/providers/cursor/models.d.ts +14 -0
  202. package/dist/providers/cursor/models.js +116 -0
  203. package/dist/providers/cursor/ndjson.d.ts +3 -0
  204. package/dist/providers/cursor/ndjson.js +100 -0
  205. package/dist/providers/cursor/prompt.d.ts +4 -0
  206. package/dist/providers/cursor/prompt.js +142 -0
  207. package/dist/providers/cursor/proto/checkpoint.d.ts +35 -0
  208. package/dist/providers/cursor/proto/checkpoint.js +114 -0
  209. package/dist/providers/cursor/proto/context.d.ts +64 -0
  210. package/dist/providers/cursor/proto/context.js +178 -0
  211. package/dist/providers/cursor/proto/errors.d.ts +16 -0
  212. package/dist/providers/cursor/proto/errors.js +26 -0
  213. package/dist/providers/cursor/proto/exec-control.d.ts +20 -0
  214. package/dist/providers/cursor/proto/exec-control.js +54 -0
  215. package/dist/providers/cursor/proto/exec.d.ts +47 -0
  216. package/dist/providers/cursor/proto/exec.js +154 -0
  217. package/dist/providers/cursor/proto/fields.d.ts +22 -0
  218. package/dist/providers/cursor/proto/fields.js +97 -0
  219. package/dist/providers/cursor/proto/interaction-query.d.ts +15 -0
  220. package/dist/providers/cursor/proto/interaction-query.js +79 -0
  221. package/dist/providers/cursor/proto/interaction-tool-update.d.ts +10 -0
  222. package/dist/providers/cursor/proto/interaction-tool-update.js +58 -0
  223. package/dist/providers/cursor/proto/interaction-turn-ended.d.ts +6 -0
  224. package/dist/providers/cursor/proto/interaction-turn-ended.js +18 -0
  225. package/dist/providers/cursor/proto/interaction.d.ts +65 -0
  226. package/dist/providers/cursor/proto/interaction.js +185 -0
  227. package/dist/providers/cursor/proto/kv.d.ts +25 -0
  228. package/dist/providers/cursor/proto/kv.js +109 -0
  229. package/dist/providers/cursor/proto/mcp-result.d.ts +40 -0
  230. package/dist/providers/cursor/proto/mcp-result.js +150 -0
  231. package/dist/providers/cursor/proto/mcp.d.ts +19 -0
  232. package/dist/providers/cursor/proto/mcp.js +78 -0
  233. package/dist/providers/cursor/proto/model.d.ts +11 -0
  234. package/dist/providers/cursor/proto/model.js +36 -0
  235. package/dist/providers/cursor/proto/output-location.d.ts +7 -0
  236. package/dist/providers/cursor/proto/output-location.js +53 -0
  237. package/dist/providers/cursor/proto/prewarm.d.ts +16 -0
  238. package/dist/providers/cursor/proto/prewarm.js +68 -0
  239. package/dist/providers/cursor/proto/request-context.d.ts +16 -0
  240. package/dist/providers/cursor/proto/request-context.js +58 -0
  241. package/dist/providers/cursor/proto/request.d.ts +44 -0
  242. package/dist/providers/cursor/proto/request.js +111 -0
  243. package/dist/providers/cursor/proto/run-request.d.ts +19 -0
  244. package/dist/providers/cursor/proto/run-request.js +68 -0
  245. package/dist/providers/cursor/proto/server.d.ts +35 -0
  246. package/dist/providers/cursor/proto/server.js +93 -0
  247. package/dist/providers/cursor/proto/unknown-field.d.ts +1 -0
  248. package/dist/providers/cursor/proto/unknown-field.js +22 -0
  249. package/dist/providers/cursor/proto-value.d.ts +3 -0
  250. package/dist/providers/cursor/proto-value.js +170 -0
  251. package/dist/providers/cursor/proto-wire.d.ts +22 -0
  252. package/dist/providers/cursor/proto-wire.js +224 -0
  253. package/dist/providers/cursor/protocol-failure.d.ts +18 -0
  254. package/dist/providers/cursor/protocol-failure.js +45 -0
  255. package/dist/providers/cursor/recovery.d.ts +48 -0
  256. package/dist/providers/cursor/recovery.js +102 -0
  257. package/dist/providers/cursor/request-blob-ownership.d.ts +15 -0
  258. package/dist/providers/cursor/request-blob-ownership.js +39 -0
  259. package/dist/providers/cursor/request-build.d.ts +18 -0
  260. package/dist/providers/cursor/request-build.js +123 -0
  261. package/dist/providers/cursor/request-history.d.ts +32 -0
  262. package/dist/providers/cursor/request-history.js +163 -0
  263. package/dist/providers/cursor/request-input.d.ts +75 -0
  264. package/dist/providers/cursor/request-input.js +123 -0
  265. package/dist/providers/cursor/run-events.d.ts +15 -0
  266. package/dist/providers/cursor/run-events.js +43 -0
  267. package/dist/providers/cursor/run-session-expiry.d.ts +15 -0
  268. package/dist/providers/cursor/run-session-expiry.js +21 -0
  269. package/dist/providers/cursor/run-session.d.ts +50 -0
  270. package/dist/providers/cursor/run-session.js +205 -0
  271. package/dist/providers/cursor/run.d.ts +9 -0
  272. package/dist/providers/cursor/run.js +151 -0
  273. package/dist/providers/cursor/runner.d.ts +1 -0
  274. package/dist/providers/cursor/runner.js +55 -0
  275. package/dist/providers/cursor/server-dispatch-types.d.ts +83 -0
  276. package/dist/providers/cursor/server-dispatch-types.js +1 -0
  277. package/dist/providers/cursor/server-dispatch.d.ts +3 -0
  278. package/dist/providers/cursor/server-dispatch.js +178 -0
  279. package/dist/providers/cursor/session-state.d.ts +21 -0
  280. package/dist/providers/cursor/session-state.js +118 -0
  281. package/dist/providers/cursor/session.d.ts +1 -0
  282. package/dist/providers/cursor/session.js +26 -0
  283. package/dist/providers/cursor/settle-cleanup.d.ts +1 -0
  284. package/dist/providers/cursor/settle-cleanup.js +11 -0
  285. package/dist/providers/cursor/stream-adapter.d.ts +17 -0
  286. package/dist/providers/cursor/stream-adapter.js +99 -0
  287. package/dist/providers/cursor/tool-continuation.d.ts +14 -0
  288. package/dist/providers/cursor/tool-continuation.js +134 -0
  289. package/dist/providers/cursor/tool-stream.d.ts +2 -0
  290. package/dist/providers/cursor/tool-stream.js +220 -0
  291. package/dist/providers/cursor/usage.d.ts +3 -0
  292. package/dist/providers/cursor/usage.js +35 -0
  293. package/dist/providers/ollama/adapter.d.ts +8 -0
  294. package/dist/providers/ollama/adapter.js +65 -0
  295. package/dist/providers/ollama/catalog-state.d.ts +17 -0
  296. package/dist/providers/ollama/catalog-state.js +40 -0
  297. package/dist/providers/ollama/cloud-catalog.d.ts +3 -0
  298. package/dist/providers/ollama/cloud-catalog.js +82 -0
  299. package/dist/providers/ollama/errors.d.ts +14 -0
  300. package/dist/providers/ollama/errors.js +19 -0
  301. package/dist/providers/ollama/generate.d.ts +2 -0
  302. package/dist/providers/ollama/generate.js +49 -0
  303. package/dist/providers/ollama/html-links.d.ts +1 -0
  304. package/dist/providers/ollama/html-links.js +30 -0
  305. package/dist/providers/ollama/http.d.ts +12 -0
  306. package/dist/providers/ollama/http.js +67 -0
  307. package/dist/providers/ollama/index.d.ts +8 -0
  308. package/dist/providers/ollama/index.js +8 -0
  309. package/dist/providers/ollama/language-model.d.ts +11 -0
  310. package/dist/providers/ollama/language-model.js +62 -0
  311. package/dist/providers/ollama/local-catalog.d.ts +3 -0
  312. package/dist/providers/ollama/local-catalog.js +38 -0
  313. package/dist/providers/ollama/ndjson.d.ts +3 -0
  314. package/dist/providers/ollama/ndjson.js +51 -0
  315. package/dist/providers/ollama/prompt.d.ts +8 -0
  316. package/dist/providers/ollama/prompt.js +141 -0
  317. package/dist/providers/ollama/protocol.d.ts +56 -0
  318. package/dist/providers/ollama/protocol.js +26 -0
  319. package/dist/providers/ollama/runtime.d.ts +11 -0
  320. package/dist/providers/ollama/runtime.js +128 -0
  321. package/dist/providers/ollama/stream.d.ts +8 -0
  322. package/dist/providers/ollama/stream.js +110 -0
  323. package/dist/sdk/command-code.d.ts +5 -0
  324. package/dist/sdk/command-code.js +6 -0
  325. package/dist/sdk/cursor.d.ts +5 -0
  326. package/dist/sdk/cursor.js +6 -0
  327. package/dist/sdk/ollama.d.ts +5 -0
  328. package/dist/sdk/ollama.js +6 -0
  329. package/dist/server.d.ts +12 -0
  330. package/dist/server.js +94 -0
  331. package/docs/README.ko.md +189 -0
  332. package/package.json +75 -0
@@ -0,0 +1,18 @@
1
+ export declare const CURSOR_API_URL = "https://api2.cursor.sh";
2
+ export declare const CURSOR_CLIENT_VERSION = "cli-2026.08.11-e8db854";
3
+ export type CursorHttp2Post = {
4
+ readonly path: string;
5
+ readonly token: string;
6
+ readonly body: Uint8Array;
7
+ readonly headers: Readonly<Record<string, string>>;
8
+ readonly signal: AbortSignal;
9
+ readonly keepOpen?: boolean;
10
+ readonly heartbeat?: Uint8Array;
11
+ readonly onWriter?: (write: (frame: Uint8Array) => void) => void;
12
+ };
13
+ export type CursorHttp2Response = {
14
+ readonly status: number;
15
+ readonly body: Uint8Array;
16
+ };
17
+ export declare function cursorHttp2Post(request: CursorHttp2Post): Promise<CursorHttp2Response>;
18
+ export declare function cursorHttp2Stream(request: CursorHttp2Post): AsyncIterable<Uint8Array>;
@@ -0,0 +1,144 @@
1
+ import http2 from "node:http2";
2
+ import { OperationCancelledError } from "../../core/errors";
3
+ export const CURSOR_API_URL = "https://api2.cursor.sh";
4
+ export const CURSOR_CLIENT_VERSION = "cli-2026.08.11-e8db854";
5
+ export async function cursorHttp2Post(request) {
6
+ if (request.signal.aborted) {
7
+ throw new OperationCancelledError("cursor-http2");
8
+ }
9
+ const client = http2.connect(CURSOR_API_URL);
10
+ try {
11
+ return await new Promise((resolve, reject) => {
12
+ const fail = (error) => {
13
+ reject(error);
14
+ };
15
+ const onAbort = () => {
16
+ fail(new OperationCancelledError("cursor-http2"));
17
+ };
18
+ request.signal.addEventListener("abort", onAbort, { once: true });
19
+ const req = client.request(requestHeaders(request));
20
+ const chunks = [];
21
+ let status = 0;
22
+ req.on("response", (headers) => {
23
+ const raw = headers[":status"];
24
+ status = typeof raw === "number" ? raw : Number(raw ?? 0);
25
+ });
26
+ req.on("data", (chunk) => {
27
+ chunks.push(chunk);
28
+ });
29
+ req.on("end", () => {
30
+ request.signal.removeEventListener("abort", onAbort);
31
+ resolve({ status, body: new Uint8Array(Buffer.concat(chunks)) });
32
+ });
33
+ req.on("error", (error) => {
34
+ request.signal.removeEventListener("abort", onAbort);
35
+ fail(error);
36
+ });
37
+ writeHttp2Body(req, request.body, true);
38
+ });
39
+ }
40
+ finally {
41
+ client.close();
42
+ }
43
+ }
44
+ function toBuffer(body) {
45
+ const payload = Buffer.alloc(body.length);
46
+ payload.set(body);
47
+ return payload;
48
+ }
49
+ function writeHttp2Body(req, body, endStream) {
50
+ if (body.length === 0) {
51
+ if (endStream) {
52
+ req.end();
53
+ }
54
+ return;
55
+ }
56
+ if (endStream) {
57
+ req.end(toBuffer(body));
58
+ return;
59
+ }
60
+ req.write(toBuffer(body));
61
+ }
62
+ function requestHeaders(request) {
63
+ return {
64
+ ":method": "POST",
65
+ ":path": request.path,
66
+ authorization: `Bearer ${request.token}`,
67
+ "x-ghost-mode": "true",
68
+ "x-cursor-client-version": CURSOR_CLIENT_VERSION,
69
+ "x-cursor-client-type": "cli",
70
+ ...request.headers,
71
+ };
72
+ }
73
+ export async function* cursorHttp2Stream(request) {
74
+ if (request.signal.aborted) {
75
+ throw new OperationCancelledError("cursor-http2");
76
+ }
77
+ const client = http2.connect(CURSOR_API_URL);
78
+ const pending = [];
79
+ let resume = null;
80
+ const push = (item) => {
81
+ pending.push(item);
82
+ resume?.();
83
+ };
84
+ const onAbort = () => {
85
+ push(new OperationCancelledError("cursor-http2"));
86
+ };
87
+ request.signal.addEventListener("abort", onAbort, { once: true });
88
+ try {
89
+ const req = client.request(requestHeaders(request));
90
+ req.on("data", (chunk) => {
91
+ push(new Uint8Array(chunk));
92
+ });
93
+ req.on("end", () => {
94
+ push(null);
95
+ });
96
+ req.on("error", (error) => {
97
+ push(error);
98
+ });
99
+ request.onWriter?.((frame) => {
100
+ if (!req.destroyed) {
101
+ req.write(toBuffer(frame));
102
+ }
103
+ });
104
+ writeHttp2Body(req, request.body, request.keepOpen !== true);
105
+ const heartbeat = request.heartbeat;
106
+ if (request.keepOpen === true && heartbeat !== undefined && heartbeat.length > 0) {
107
+ req.write(toBuffer(heartbeat));
108
+ }
109
+ const timer = request.keepOpen === true && heartbeat !== undefined && heartbeat.length > 0
110
+ ? setInterval(() => {
111
+ if (!req.destroyed) {
112
+ req.write(toBuffer(heartbeat));
113
+ }
114
+ }, 5_000)
115
+ : null;
116
+ timer?.unref();
117
+ try {
118
+ for (;;) {
119
+ while (pending.length === 0) {
120
+ await new Promise((resolve) => {
121
+ resume = resolve;
122
+ });
123
+ }
124
+ const next = pending.shift();
125
+ if (next === undefined || next === null) {
126
+ return;
127
+ }
128
+ if (next instanceof Error) {
129
+ throw next;
130
+ }
131
+ yield next;
132
+ }
133
+ }
134
+ finally {
135
+ if (timer !== null) {
136
+ clearInterval(timer);
137
+ }
138
+ }
139
+ }
140
+ finally {
141
+ request.signal.removeEventListener("abort", onAbort);
142
+ client.close();
143
+ }
144
+ }
@@ -0,0 +1,6 @@
1
+ import type { InteractionQuery, InteractionResponse } from "./proto/interaction-query";
2
+ export type CursorInteractionReply = {
3
+ readonly action: "acked" | "rejected";
4
+ readonly response: InteractionResponse;
5
+ };
6
+ export declare function buildCursorInteractionReply(query: InteractionQuery): CursorInteractionReply;
@@ -0,0 +1,52 @@
1
+ // Derived from Rahularya01/pi-cursor src/stream/interaction-query.ts. Licensed under MIT.
2
+ // See THIRD_PARTY_NOTICES.md.
3
+ import { unreachableVariant } from "./proto/errors";
4
+ import { encodeBytesField, encodeStringField } from "./proto-wire";
5
+ const REJECT_REASON = "Not available through the Pi Cursor provider. Use Pi tools (web_search, fetch, bash, etc.) instead.";
6
+ const ASK_QUESTION_ERROR = "Interactive questions are not available in Pi. Continue with a reasonable default or ask the user in chat.";
7
+ const CREATE_PLAN_ERROR = "Create-plan UI is not available in Pi. Write the plan with Pi file tools.";
8
+ function rejectionPayload() {
9
+ return encodeBytesField(2, encodeStringField(1, REJECT_REASON));
10
+ }
11
+ function askQuestionErrorPayload() {
12
+ return encodeBytesField(1, encodeBytesField(2, encodeStringField(1, ASK_QUESTION_ERROR)));
13
+ }
14
+ function createPlanErrorPayload() {
15
+ return encodeBytesField(1, encodeBytesField(2, encodeStringField(1, CREATE_PLAN_ERROR)));
16
+ }
17
+ function setupVmSuccessPayload() {
18
+ return encodeBytesField(1, new Uint8Array());
19
+ }
20
+ function rejectedResponse(query) {
21
+ return {
22
+ action: "rejected",
23
+ response: { kind: query.kind, id: query.id, payload: rejectionPayload() },
24
+ };
25
+ }
26
+ export function buildCursorInteractionReply(query) {
27
+ switch (query.kind) {
28
+ case "web-search":
29
+ case "switch-mode":
30
+ case "exa-search":
31
+ case "exa-fetch":
32
+ case "field-9":
33
+ return rejectedResponse(query);
34
+ case "ask-question":
35
+ return {
36
+ action: "rejected",
37
+ response: { kind: query.kind, id: query.id, payload: askQuestionErrorPayload() },
38
+ };
39
+ case "create-plan":
40
+ return {
41
+ action: "rejected",
42
+ response: { kind: query.kind, id: query.id, payload: createPlanErrorPayload() },
43
+ };
44
+ case "setup-vm":
45
+ return {
46
+ action: "acked",
47
+ response: { kind: query.kind, id: query.id, payload: setupVmSuccessPayload() },
48
+ };
49
+ default:
50
+ return unreachableVariant(query.kind, "InteractionQuery kind");
51
+ }
52
+ }
@@ -0,0 +1,2 @@
1
+ import type { LanguageModelV3GenerateResult, LanguageModelV3StreamPart } from "@ai-sdk/provider";
2
+ export declare function generateFromCursorStream(stream: ReadableStream<LanguageModelV3StreamPart>): Promise<LanguageModelV3GenerateResult>;
@@ -0,0 +1,35 @@
1
+ import { emptyCursorUsage } from "./usage";
2
+ export async function generateFromCursorStream(stream) {
3
+ const content = [];
4
+ const text = [];
5
+ const reasoning = [];
6
+ let finishReason = { unified: "stop", raw: "stop" };
7
+ let usage = emptyCursorUsage();
8
+ for await (const part of stream) {
9
+ if (part.type === "text-delta")
10
+ text.push(part.delta);
11
+ else if (part.type === "reasoning-delta")
12
+ reasoning.push(part.delta);
13
+ else if (part.type === "tool-call") {
14
+ content.push({
15
+ type: "tool-call",
16
+ toolCallId: part.toolCallId,
17
+ toolName: part.toolName,
18
+ input: part.input,
19
+ });
20
+ }
21
+ else if (part.type === "finish") {
22
+ finishReason = part.finishReason;
23
+ usage = part.usage;
24
+ }
25
+ else if (part.type === "error")
26
+ throw part.error;
27
+ }
28
+ const joinedText = text.join("");
29
+ if (joinedText.length > 0)
30
+ content.unshift({ type: "text", text: joinedText });
31
+ const joinedReasoning = reasoning.join("");
32
+ if (joinedReasoning.length > 0)
33
+ content.unshift({ type: "reasoning", text: joinedReasoning });
34
+ return { content, finishReason, usage, warnings: [] };
35
+ }
@@ -0,0 +1,13 @@
1
+ import type { LanguageModelV3, LanguageModelV3CallOptions, LanguageModelV3StreamPart } from "@ai-sdk/provider";
2
+ import { type CursorNdjsonStream } from "./legacy-stream";
3
+ export type CursorLanguageModelOptions = {
4
+ readonly modelId: string;
5
+ readonly runPrompt: (prompt: string, signal: AbortSignal) => Promise<string | null>;
6
+ readonly directRuntime?: {
7
+ readonly doStream: (call: LanguageModelV3CallOptions, modelId: string) => Promise<{
8
+ readonly stream: ReadableStream<LanguageModelV3StreamPart>;
9
+ }>;
10
+ };
11
+ readonly streamNdjson?: CursorNdjsonStream;
12
+ };
13
+ export declare function createCursorLanguageModel(options: CursorLanguageModelOptions): LanguageModelV3;
@@ -0,0 +1,77 @@
1
+ // Derived from Nomadcxx/opencode-cursor@8e14a26c1e080382f471a729436092ef72edf34e.
2
+ // Licensed under BSD-3-Clause. See THIRD_PARTY_NOTICES.md.
3
+ import { AdapterError, OperationCancelledError } from "../../core/errors";
4
+ import { parseProviderId } from "../../core/ids";
5
+ import { generateFromCursorStream } from "./language-generate";
6
+ import { createCursorLegacyStream } from "./legacy-stream";
7
+ import { cursorPromptText } from "./prompt";
8
+ import { emptyCursorUsage } from "./usage";
9
+ export function createCursorLanguageModel(options) {
10
+ const provider = parseProviderId("cursor");
11
+ const model = {
12
+ specificationVersion: "v3",
13
+ provider,
14
+ modelId: options.modelId,
15
+ supportedUrls: {},
16
+ doGenerate: async (call) => {
17
+ if (options.directRuntime !== undefined) {
18
+ return generateFromCursorStream((await options.directRuntime.doStream(call, options.modelId)).stream);
19
+ }
20
+ if (options.streamNdjson !== undefined) {
21
+ return generateFromCursorStream((await model.doStream(call)).stream);
22
+ }
23
+ const signal = call.abortSignal ?? new AbortController().signal;
24
+ if (signal.aborted) {
25
+ throw new OperationCancelledError("cursor-generate");
26
+ }
27
+ const text = await options.runPrompt(cursorPromptText(call), signal);
28
+ if (text === null) {
29
+ throw new AdapterError({
30
+ operation: "cursor-agent-unavailable",
31
+ retryable: false,
32
+ cause: null,
33
+ providerId: provider,
34
+ });
35
+ }
36
+ return {
37
+ content: [{ type: "text", text }],
38
+ finishReason: { unified: "stop", raw: "stop" },
39
+ usage: emptyCursorUsage(),
40
+ warnings: [],
41
+ };
42
+ },
43
+ doStream: async (call) => {
44
+ if (options.directRuntime !== undefined) {
45
+ return options.directRuntime.doStream(call, options.modelId);
46
+ }
47
+ const signal = call.abortSignal ?? new AbortController().signal;
48
+ if (signal.aborted) {
49
+ throw new OperationCancelledError("cursor-stream");
50
+ }
51
+ const streamNdjson = options.streamNdjson;
52
+ if (streamNdjson !== undefined) {
53
+ return { stream: createCursorLegacyStream({ call, signal, streamNdjson }) };
54
+ }
55
+ // Fallback to runPrompt (non-streaming)
56
+ const generated = await createCursorLanguageModel(options).doGenerate(call);
57
+ const textPart = generated.content.at(0);
58
+ const text = textPart !== undefined && textPart.type === "text" ? textPart.text : "";
59
+ const stream = new ReadableStream({
60
+ start(controller) {
61
+ controller.enqueue({ type: "stream-start", warnings: [] });
62
+ controller.enqueue({ type: "text-start", id: "text-1" });
63
+ controller.enqueue({ type: "text-delta", id: "text-1", delta: text });
64
+ controller.enqueue({ type: "text-end", id: "text-1" });
65
+ controller.enqueue({
66
+ type: "finish",
67
+ finishReason: generated.finishReason,
68
+ usage: generated.usage,
69
+ });
70
+ controller.close();
71
+ },
72
+ });
73
+ return { stream };
74
+ },
75
+ };
76
+ return model;
77
+ }
@@ -0,0 +1,11 @@
1
+ import type { LanguageModelV3CallOptions, LanguageModelV3StreamPart } from "@ai-sdk/provider";
2
+ export type CursorNdjsonStream = (prompt: string, signal: AbortSignal, sessionKey: string | null, incrementalPrompt: string | null, tools?: readonly {
3
+ readonly name: string;
4
+ readonly description?: string;
5
+ readonly inputSchema: unknown;
6
+ }[]) => AsyncIterable<string>;
7
+ export declare function createCursorLegacyStream(options: {
8
+ readonly call: LanguageModelV3CallOptions;
9
+ readonly signal: AbortSignal;
10
+ readonly streamNdjson: CursorNdjsonStream;
11
+ }): ReadableStream<LanguageModelV3StreamPart>;
@@ -0,0 +1,115 @@
1
+ import { OperationCancelledError } from "../../core/errors";
2
+ import { cursorResultError, cursorTextFromUnknown } from "./ndjson";
3
+ import { cursorIncrementalPrompt, cursorPromptText, cursorSessionKey } from "./prompt";
4
+ import { cursorToolParts } from "./tool-stream";
5
+ import { cursorUsage, emptyCursorUsage } from "./usage";
6
+ export function createCursorLegacyStream(options) {
7
+ const allowedTools = new Map((options.call.tools ?? [])
8
+ .filter((tool) => tool.type === "function")
9
+ .map((tool) => [tool.name, tool.inputSchema]));
10
+ return new ReadableStream({
11
+ async start(controller) {
12
+ try {
13
+ controller.enqueue({ type: "stream-start", warnings: [] });
14
+ let textStarted = false;
15
+ let reasoningStarted = false;
16
+ let reasoningText = "";
17
+ let assistantText = "";
18
+ let toolCalled = false;
19
+ let usage = emptyCursorUsage();
20
+ streamLoop: for await (const line of options.streamNdjson(cursorPromptText(options.call), options.signal, cursorSessionKey(options.call), cursorIncrementalPrompt(options.call), (options.call.tools ?? [])
21
+ .filter((tool) => tool.type === "function")
22
+ .map((tool) => ({
23
+ name: tool.name,
24
+ ...(tool.description === undefined ? {} : { description: tool.description }),
25
+ inputSchema: tool.inputSchema,
26
+ })))) {
27
+ if (options.signal.aborted)
28
+ throw new OperationCancelledError("cursor-stream");
29
+ const trimmed = line.trim();
30
+ if (trimmed.length === 0)
31
+ continue;
32
+ let parsed;
33
+ try {
34
+ parsed = JSON.parse(trimmed);
35
+ }
36
+ catch {
37
+ continue;
38
+ }
39
+ if (typeof parsed !== "object" || parsed === null)
40
+ continue;
41
+ const type = "type" in parsed && typeof parsed.type === "string" ? parsed.type : "";
42
+ if (type === "thinking") {
43
+ const text = cursorTextFromUnknown(parsed) ?? "";
44
+ const delta = text.startsWith(reasoningText) ? text.slice(reasoningText.length) : text;
45
+ reasoningText = text.startsWith(reasoningText) ? text : reasoningText + text;
46
+ if (delta.length > 0) {
47
+ if (!reasoningStarted) {
48
+ controller.enqueue({ type: "reasoning-start", id: "reasoning-1" });
49
+ reasoningStarted = true;
50
+ }
51
+ controller.enqueue({ type: "reasoning-delta", id: "reasoning-1", delta });
52
+ }
53
+ continue;
54
+ }
55
+ if (reasoningStarted) {
56
+ controller.enqueue({ type: "reasoning-end", id: "reasoning-1" });
57
+ reasoningStarted = false;
58
+ }
59
+ for (const part of cursorToolParts(parsed, allowedTools)) {
60
+ controller.enqueue(part);
61
+ if (part.type === "tool-call" && part.providerExecuted !== true) {
62
+ toolCalled = true;
63
+ break streamLoop;
64
+ }
65
+ }
66
+ if (!["assistant", "text", "text-delta", "result"].includes(type))
67
+ continue;
68
+ const text = cursorTextFromUnknown(parsed) ?? "";
69
+ let nextText = text;
70
+ if (type === "assistant") {
71
+ if (text === assistantText)
72
+ nextText = "";
73
+ else if (text.startsWith(assistantText)) {
74
+ nextText = text.slice(assistantText.length);
75
+ assistantText = text;
76
+ }
77
+ else
78
+ assistantText += text;
79
+ }
80
+ else if (type === "result") {
81
+ const resultError = cursorResultError(parsed);
82
+ if (resultError !== null)
83
+ throw resultError;
84
+ nextText = assistantText.length > 0 ? "" : text;
85
+ usage = cursorUsage(parsed) ?? usage;
86
+ }
87
+ if (nextText.length > 0) {
88
+ if (!textStarted) {
89
+ controller.enqueue({ type: "text-start", id: "text-1" });
90
+ textStarted = true;
91
+ }
92
+ controller.enqueue({ type: "text-delta", id: "text-1", delta: nextText });
93
+ }
94
+ }
95
+ if (options.signal.aborted)
96
+ throw new OperationCancelledError("cursor-stream");
97
+ if (reasoningStarted)
98
+ controller.enqueue({ type: "reasoning-end", id: "reasoning-1" });
99
+ if (textStarted)
100
+ controller.enqueue({ type: "text-end", id: "text-1" });
101
+ controller.enqueue({
102
+ type: "finish",
103
+ finishReason: toolCalled
104
+ ? { unified: "tool-calls", raw: "tool_calls" }
105
+ : { unified: "stop", raw: "stop" },
106
+ usage,
107
+ });
108
+ controller.close();
109
+ }
110
+ catch (error) {
111
+ controller.error(error);
112
+ }
113
+ },
114
+ });
115
+ }
@@ -0,0 +1,7 @@
1
+ export type CursorMcpTool = {
2
+ readonly name: string;
3
+ readonly description: string;
4
+ readonly inputSchema: unknown;
5
+ };
6
+ export declare function encodeMcpToolDefinition(tool: CursorMcpTool): Uint8Array;
7
+ export declare function encodeCursorMcpTools(tools: readonly CursorMcpTool[]): Uint8Array;
@@ -0,0 +1,15 @@
1
+ import { encodeProtobufValue } from "./proto-value";
2
+ import { concatBytes, encodeBytesField, encodeStringField } from "./proto-wire";
3
+ export function encodeMcpToolDefinition(tool) {
4
+ const schema = encodeProtobufValue(tool.inputSchema ?? { type: "object" });
5
+ return concatBytes([
6
+ encodeStringField(1, tool.name),
7
+ encodeStringField(2, tool.description),
8
+ encodeBytesField(3, schema),
9
+ encodeStringField(4, "opencode"),
10
+ encodeStringField(5, tool.name),
11
+ ]);
12
+ }
13
+ export function encodeCursorMcpTools(tools) {
14
+ return concatBytes(tools.map((tool) => encodeBytesField(1, encodeMcpToolDefinition(tool))));
15
+ }
@@ -0,0 +1,14 @@
1
+ import type { AdapterModel } from "../../core/models";
2
+ import { type CursorHttp2Post } from "./http2";
3
+ export declare function parseCursorModelOutput(stdout: string): readonly AdapterModel[];
4
+ export type CursorModelsRun = (agent: string, args: readonly string[], signal: AbortSignal) => Promise<{
5
+ readonly code: number;
6
+ readonly stdout: string;
7
+ }>;
8
+ export declare function listCursorModels(agent: string, signal: AbortSignal, run?: CursorModelsRun): Promise<readonly AdapterModel[]>;
9
+ export declare function parseCursorUsableModels(body: Uint8Array): readonly AdapterModel[];
10
+ export type CursorUsableModelsPost = (request: CursorHttp2Post) => Promise<{
11
+ readonly status: number;
12
+ readonly body: Uint8Array;
13
+ }>;
14
+ export declare function listCursorUsableModels(token: string, signal: AbortSignal, post?: CursorUsableModelsPost): Promise<readonly AdapterModel[]>;
@@ -0,0 +1,116 @@
1
+ import { spawn } from "node:child_process";
2
+ import { parseModelIdList } from "../../catalog/parse-ids";
3
+ import { OperationCancelledError } from "../../core/errors";
4
+ import { cursorHttp2Post } from "./http2";
5
+ import { decodeFields, decodeUtf8 } from "./proto-wire";
6
+ function stripAnsi(text) {
7
+ let output = "";
8
+ let index = 0;
9
+ while (index < text.length) {
10
+ if (text.charCodeAt(index) === 27 && text.at(index + 1) === "[") {
11
+ index += 2;
12
+ while (index < text.length && text.at(index) !== "m") {
13
+ index += 1;
14
+ }
15
+ index += 1;
16
+ continue;
17
+ }
18
+ output += text.at(index) ?? "";
19
+ index += 1;
20
+ }
21
+ return output;
22
+ }
23
+ export function parseCursorModelOutput(stdout) {
24
+ const text = stripAnsi(stdout).trim();
25
+ if (text.startsWith("{") || text.startsWith("[")) {
26
+ try {
27
+ return parseModelIdList(JSON.parse(text));
28
+ }
29
+ catch {
30
+ return [];
31
+ }
32
+ }
33
+ const ids = [];
34
+ for (const line of text.split("\n")) {
35
+ const trimmed = line.trim();
36
+ if (trimmed.length === 0 || trimmed.toLowerCase().startsWith("available")) {
37
+ continue;
38
+ }
39
+ const separator = trimmed.indexOf(" - ");
40
+ const id = separator === -1 ? trimmed.split(/\s+/)[0] : trimmed.slice(0, separator).trim();
41
+ if (id !== undefined && id.length > 0) {
42
+ ids.push(id);
43
+ }
44
+ }
45
+ return parseModelIdList(ids);
46
+ }
47
+ function runCursorModelsCommand(agent, args, signal) {
48
+ return new Promise((resolve, reject) => {
49
+ const child = spawn(agent, [...args], { signal, stdio: ["ignore", "pipe", "pipe"] });
50
+ const chunks = [];
51
+ child.stdout.on("data", (chunk) => {
52
+ chunks.push(chunk);
53
+ });
54
+ child.once("error", (error) => {
55
+ if (signal.aborted) {
56
+ reject(new OperationCancelledError("cursor-list-models"));
57
+ return;
58
+ }
59
+ reject(error);
60
+ });
61
+ child.once("close", (code) => {
62
+ if (signal.aborted) {
63
+ reject(new OperationCancelledError("cursor-list-models"));
64
+ return;
65
+ }
66
+ resolve({ code: code ?? 1, stdout: Buffer.concat(chunks).toString("utf8") });
67
+ });
68
+ });
69
+ }
70
+ export async function listCursorModels(agent, signal, run = runCursorModelsCommand) {
71
+ if (signal.aborted) {
72
+ throw new OperationCancelledError("cursor-list-models");
73
+ }
74
+ const attempts = [["models"], ["--list-models"]];
75
+ for (const args of attempts) {
76
+ const result = await run(agent, args, signal);
77
+ if (result.code !== 0) {
78
+ continue;
79
+ }
80
+ const models = parseCursorModelOutput(result.stdout);
81
+ if (models.length > 0) {
82
+ return models;
83
+ }
84
+ }
85
+ return [];
86
+ }
87
+ export function parseCursorUsableModels(body) {
88
+ const ids = [];
89
+ for (const model of decodeFields(body)) {
90
+ if (model.field !== 1) {
91
+ continue;
92
+ }
93
+ for (const inner of decodeFields(model.bytes)) {
94
+ if (inner.field === 1) {
95
+ ids.push(decodeUtf8(inner.bytes));
96
+ }
97
+ }
98
+ }
99
+ return parseModelIdList(ids);
100
+ }
101
+ export async function listCursorUsableModels(token, signal, post = cursorHttp2Post) {
102
+ if (signal.aborted) {
103
+ throw new OperationCancelledError("cursor-list-models");
104
+ }
105
+ const response = await post({
106
+ path: "/agent.v1.AgentService/GetUsableModels",
107
+ token,
108
+ body: new Uint8Array(),
109
+ headers: { "content-type": "application/proto", te: "trailers" },
110
+ signal,
111
+ });
112
+ if (response.status < 200 || response.status >= 300) {
113
+ return [];
114
+ }
115
+ return parseCursorUsableModels(response.body);
116
+ }
@@ -0,0 +1,3 @@
1
+ export declare function cursorTextFromUnknown(value: unknown): string | null;
2
+ export declare function cursorResultError(value: object): Error | null;
3
+ export declare function extractCursorNdjsonText(stream: string): string;