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
package/CHANGELOG.md ADDED
@@ -0,0 +1,39 @@
1
+ # Changelog
2
+
3
+ ## 0.3.0 - 2026-09-05
4
+
5
+ - Publish releases to npm from GitHub Actions when a `v*` tag is pushed; the
6
+ tag must match `package.json`
7
+ - Claude and Command Code no longer require their vendor CLI where OpenCode
8
+ runs: the client version comes from `ANTHROPIC_CLI_VERSION` /
9
+ `COMMAND_CODE_CLI_VERSION`, an installed binary, or the latest version
10
+ published on the npm registry; nothing is pinned in the package
11
+ - The Claude auth loader now takes over the `anthropic` provider whenever
12
+ credentials exist instead of silently yielding when `claude` is missing
13
+ - Added `credentialRefresh: { mode: "auto" | "never", leadMs }` so one machine
14
+ can own Claude token refresh while copies of the credential file stay
15
+ read-only and re-read the file after a 401
16
+
17
+ ## 0.2.0 - 2026-09-04
18
+
19
+ - Added Ollama as a fourth provider using the local daemon and existing
20
+ `ollama signin` Cloud subscription session
21
+ - Added automatic Cloud-only online catalog refresh, pulled-local model
22
+ discovery, local-first deduplication, and pull-on-first-use for Cloud tags
23
+ - Added `ollamaAuthServer` and the `opencode-ext-connector/ollama` SDK export
24
+ - **Breaking:** Removed the `opencode-ext-connector/server` package subpath;
25
+ import the named plugin functions from `opencode-ext-connector` instead
26
+ - Documented the direct `dist/index.js` plugin URL required for all named auth
27
+ hooks
28
+ - Cursor direct generation now uses a plugin-owned private Node >=22 child over
29
+ stdio and Cursor's unpublished AgentService Connect+protobuf/HTTP/2 protocol;
30
+ there is no plugin listening daemon and no `cursor-agent` generation fallback
31
+
32
+ ## 0.1.0 - 2026-08-20
33
+
34
+ - OpenCode plugin exposing Claude, Cursor, and Command Code from existing CLI logins
35
+ - Live model catalogs (Anthropic `/v1/models`, `cursor-agent models`, Command Code `/provider/v1/models`)
36
+ - Claude OAuth refresh. Optional writeback (`writeBackCredentials: true`) to Claude files, macOS Keychain, and OpenCode `auth.json`
37
+ - Cursor process pool, tool-call stream parts, `--resume`, `--list-models` fallback
38
+ - Command Code `/alpha/generate` CLI fingerprint request and NDJSON tool/text stream
39
+ - Catalog reload interval and process-exit dispose
package/LICENSE ADDED
@@ -0,0 +1,29 @@
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2026, kernalix7
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without
7
+ modification, are permitted provided that the following conditions are met:
8
+
9
+ 1. Redistributions of source code must retain the above copyright notice, this
10
+ list of conditions and the following disclaimer.
11
+
12
+ 2. Redistributions in binary form must reproduce the above copyright notice,
13
+ this list of conditions and the following disclaimer in the documentation
14
+ and/or other materials provided with the distribution.
15
+
16
+ 3. Neither the name of the copyright holder nor the names of its
17
+ contributors may be used to endorse or promote products derived from
18
+ this software without specific prior written permission.
19
+
20
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package/README.md ADDED
@@ -0,0 +1,207 @@
1
+ <div align="center">
2
+
3
+ # OpenCode External Provider Connector
4
+
5
+ **One OpenCode plugin configuration for Claude, Cursor, Command Code, and Ollama — using existing vendor sessions and the local Ollama daemon. No new OAuth.**
6
+
7
+ <p>
8
+ <img src="https://img.shields.io/badge/Bun-%3E%3D1.3.14-000000?style=for-the-badge" alt="Bun >=1.3.14" />
9
+ <img src="https://img.shields.io/badge/TypeScript-6.0.2-3178C6?style=for-the-badge" alt="TypeScript 6.0.2" />
10
+ <img src="https://img.shields.io/badge/OpenCode-E2E_tested-111111?style=for-the-badge" alt="OpenCode E2E tested" />
11
+ <img src="https://img.shields.io/badge/License-BSD--3--Clause-blue?style=for-the-badge" alt="BSD-3-Clause" />
12
+ </p>
13
+
14
+ **English** · [한국어](docs/README.ko.md) · [Documentation](#documentation)
15
+
16
+ [Status](#status) · [Requirements](#requirements) · [Quick Install](#quick-install) · [Configuration](#configuration) · [First-Time Connection](#first-time-connection) · [Providers](#providers) · [Troubleshooting](#troubleshooting) · [Documentation](#documentation) · [Testing](#testing) · [License and Disclaimer](#license-and-disclaimer)
17
+
18
+ </div>
19
+
20
+ ## Status
21
+
22
+ > Independent unofficial community plugin, version **0.3.0**. Package E2E tests exercise the legacy multi-function loader with the OpenCode CLI installed in CI. `@opencode-ai/plugin@1.18.18` is the compile-time plugin API target, not a runtime pin. Source is BSD-3-Clause. This project is not affiliated with, endorsed by, sponsored by, or authorized by OpenCode or any provider. Full terms are in [License and Disclaimer](#license-and-disclaimer).
23
+
24
+ Reuse the Claude, Cursor, Command Code, and Ollama sessions you already have. One `opencode.json` plugin entry publishes live catalogs into OpenCode. Claude and Cursor stay disconnected until OpenCode has a marker or OAuth record and the vendor session is present. Command Code may use an OpenCode-stored direct API key or an existing CLI session/key. Ollama requires the exact session marker plus a responsive localhost daemon.
25
+
26
+ ## Requirements
27
+
28
+ | Need | Detail |
29
+ | --- | --- |
30
+ | [Bun](https://bun.sh) | 1.3.14 or later |
31
+ | Node.js | 22 or later, for Cursor direct generation only |
32
+ | OpenCode | Runtime with the legacy multi-function plugin loader; package E2E tests the CLI installed in CI. `@opencode-ai/plugin@1.18.18` is the compile-time API target. |
33
+ | Claude | Existing Claude Code credentials (`~/.claude/.credentials.json` and/or macOS Keychain). The `claude` binary is optional. |
34
+ | Cursor | Existing Cursor CLI login (`~/.config/cursor/auth.json` or `CURSOR_ACCESS_TOKEN`) |
35
+ | Command Code | Existing API key (`COMMAND_CODE_API_KEY` or `~/.commandcode/auth.json`). The `command-code` binary is optional. |
36
+ | Ollama | Installed local daemon running on `localhost:11434`; trust that process; run `ollama signin` separately for Cloud |
37
+
38
+ No vendor CLI has to be installed where OpenCode runs. Claude and Command Code requests carry a client version: the connector takes `ANTHROPIC_CLI_VERSION` / `COMMAND_CODE_CLI_VERSION` when set, otherwise an installed `claude` / `command-code` binary, otherwise the latest version published on the npm registry (`@anthropic-ai/claude-code`, `command-code`). Nothing is pinned in the package.
39
+
40
+ ## Quick Install
41
+
42
+ Build this repository, then point OpenCode at the compiled module:
43
+
44
+ ```bash
45
+ bun install
46
+ bun run build
47
+ ```
48
+
49
+ In `opencode.json` / `opencode.jsonc` (official `plugin` field):
50
+
51
+ ```jsonc
52
+ {
53
+ "$schema": "https://opencode.ai/config.json",
54
+ "plugin": [
55
+ "file:///absolute/path/to/opencode-ext-connector/dist/index.js"
56
+ ]
57
+ }
58
+ ```
59
+
60
+ Use that direct `dist/index.js` URL from a trusted, user-owned `file://` build. A package-directory URL does not load this connector's named legacy auth hooks.
61
+
62
+ The one package entry exposes the catalog plugin plus the Claude, Cursor, Command Code, and Ollama auth hooks. Provider ids: `claude`, `cursor`, `command-code`, `ollama`. Model ids come from each provider's live catalog, with documented fallbacks `default` (Cursor) and `Qwen/Qwen3.8-Max` (Command Code) when a live list is empty.
63
+
64
+ ## Configuration
65
+
66
+ OpenCode passes plugin options as the second item of a two-element tuple.
67
+
68
+ Omitted `providers` enables all four. An explicit list is a strict allow-list. Explicit `[]` disables all.
69
+
70
+ | Option | Default | Meaning |
71
+ | --- | --- | --- |
72
+ | `providers` | all four | Provider ids to register: `claude`, `cursor`, `command-code`, `ollama`; explicit `[]` disables all |
73
+ | `writeBackCredentials` | `false` | After Claude OAuth refresh, write tokens to Claude files, Keychain (macOS), and OpenCode `auth.json` |
74
+ | `credentialRefresh.mode` | `"auto"` | `"auto"` refreshes Claude tokens before expiry; `"never"` sends only what the credential file contains and re-reads that file after a 401 |
75
+ | `credentialRefresh.leadMs` | `60000` | How long before expiry `"auto"` starts refreshing |
76
+ | `catalogReloadMs` | `300000` | Re-run catalog snapshots on this interval; `0` disables |
77
+ | `snapshotTimeoutMs` | `30000` | Per-provider snapshot deadline |
78
+ | `health.initialBackoffMs` | `1000` | Health backoff after a failed snapshot |
79
+ | `health.maximumBackoffMs` | `60000` | Health backoff cap |
80
+
81
+ Writeback is off by default so this plugin does not mutate credential stores unless asked. Enable it explicitly:
82
+
83
+ ```jsonc
84
+ {
85
+ "$schema": "https://opencode.ai/config.json",
86
+ "plugin": [
87
+ [
88
+ "file:///absolute/path/to/opencode-ext-connector/dist/index.js",
89
+ {
90
+ "writeBackCredentials": true
91
+ }
92
+ ]
93
+ ]
94
+ }
95
+ ```
96
+
97
+ Enabled providers remain disconnected until their provider-specific auth rule is met: Claude and Cursor need an OpenCode marker or OAuth record plus the vendor session; Command Code may use an OpenCode-stored direct API key or an existing CLI session/key; Ollama needs the exact session marker plus a responsive localhost daemon.
98
+
99
+ The connector always performs one initial catalog refresh. `snapshotTimeoutMs` applies to each provider snapshot, while `catalogReloadMs: 0` disables only periodic refresh. Periodic refreshes are fixed-delay and single-flight: the next delay begins after the current refresh settles. Health backoff suppresses repeated failures; transient failures retain the last-known catalog, while an explicit unavailable snapshot removes only connector-owned provider data.
100
+
101
+ OpenCode builds its active provider registry during instance setup. Periodic refresh updates the connector's retained catalog and health state, but new authentication or changed model membership becomes visible after normal OpenCode instance reconstruction. The connector never forces reconstruction or writes generated provider configuration. The `@opencode-ai/plugin@1.18.18` package is the plugin API this connector targets; it is not an OpenCode runtime pin.
102
+
103
+ With writeback off, refreshed Claude tokens stay in memory only. A stored refresh token that rotates can then stop working on the next process start — set `writeBackCredentials: true` if you want the files updated too.
104
+
105
+ ### Sharing one Claude login across machines
106
+
107
+ Anthropic rotates the refresh token on every refresh and invalidates the previous one. Two copies of `~/.claude/.credentials.json` that both refresh will therefore break each other. Copying the file works only if exactly one machine refreshes and every other machine receives the result before its own copy expires:
108
+
109
+ - **Owner** (where you log in): `writeBackCredentials: true` and a lead time large enough to publish the file before the copies expire, for example `credentialRefresh: { mode: "auto", leadMs: 1800000 }`.
110
+ - **Every copy**: `credentialRefresh: { mode: "never" }`. That machine never contacts the OAuth endpoint; when a request returns 401 it re-reads the file and retries once with whatever the owner pushed.
111
+ - Push `~/.claude/.credentials.json` from the owner to each copy whenever it changes (a file watcher is enough). OpenCode's own `auth.json` only needs the `anthropic` record once; leave its other providers alone.
112
+
113
+ Machines that refresh on their own — including a Claude Code install that is used interactively — must not share the file. Log in separately there.
114
+
115
+ ## First-Time Connection
116
+
117
+ 1. **Fully restart OpenCode** after adding the plugin URL. Quit the process and start it again so the named legacy auth hooks load. A reload or periodic catalog refresh is not instance reconstruction.
118
+ 2. **Confirm local prerequisites** for the providers you enabled. Claude and Cursor need their vendor sessions. Command Code needs either an API key you will store in OpenCode or an existing CLI session/key. Ollama needs a process you trust on `http://localhost:11434`; Cloud still requires a separate `ollama signin`.
119
+ 3. **Run `/connect`** for each provider you want. Claude and Cursor record a marker or OAuth entry only after the vendor session is available. Command Code can store a direct API key in OpenCode or reuse an existing CLI session/key. Ollama stores the exact session marker only when the localhost daemon responds. Models publish only after that provider-specific rule is met.
120
+ 4. **Verify the catalogs.** Confirm Claude, Cursor, and Command Code models appear in OpenCode. For Ollama, run `opencode models ollama` and confirm locally pulled models plus Cloud tags discovered unauthenticated, without connector-supplied credentials.
121
+
122
+ Ollama `/connect` probes the local daemon and stores the exact session marker. It does not run `ollama signin` or handle Ollama credentials.
123
+
124
+ ## Providers
125
+
126
+ | Provider | What it does |
127
+ | --- | --- |
128
+ | **Claude** | Reuses existing Claude Code credentials. Does not mint OAuth. Compatibility fetch sends CLI-compatible request metadata and streams Anthropic SSE on the built-in `anthropic` path. `writeBackCredentials` defaults to `false` (in-memory refresh only); `true` writes refreshed tokens to Claude files, macOS Keychain, and OpenCode `auth.json`. |
129
+ | **Cursor** | Calls Cursor's unpublished client protocol (`api2.cursor.sh` `AgentService`, Connect+protobuf over HTTP/2) with the CLI access token. A plugin-owned Node child communicates over private stdio, keeps tool results on the same bidi Run, never replays parked calls, opens no user-facing daemon, and never spawns `cursor-agent` for generation. Unofficial; not a public Cursor API. After protocol drift there is no implicit fallback — that provider fails. Requires Node.js 22 or later. Live catalog ids are used when present; otherwise the documented fallback is `default`. |
130
+ | **Command Code** | Calls `/alpha/generate` with CLI-compatible request metadata and streams provider-local NDJSON text and tool events. The client version comes from `COMMAND_CODE_CLI_VERSION`, an installed `command-code` binary, or the npm registry. Request metadata includes Node.js version, platform, architecture, and the absolute working directory. Live catalog ids are used when present; otherwise the documented fallback is `Qwen/Qwen3.8-Max`. |
131
+ | **Ollama** | Uses only the local daemon at `http://localhost:11434` with fixed `/api/tags`, `/api/pull`, and `/api/chat`. Trust the process bound to that port. Publishes models already pulled locally, plus exact Cloud tags discovered unauthenticated from Ollama's official Cloud search and library pages, without connector-supplied credentials. Local entries win exact duplicates. Incomplete Cloud refreshes retain the last complete list. Selecting an absent authorized Cloud tag pulls its lightweight remote reference on first use; concurrent pulls of the same tag share one in-flight request, and a failed pull can be retried later. The local daemon may then proxy Cloud-tag prompts under the user's Ollama Cloud subscription. The connector never uses an Ollama API key, the usage-billed direct Cloud API, `OLLAMA_HOST`, or a remote Cloud generation endpoint. |
132
+
133
+ Provider health is isolated: one provider failing does not remove the others.
134
+
135
+ The standalone SDK entry is `opencode-ext-connector/ollama`. It can generate with models already present in the local daemon; connector-managed Cloud auto-pull requires an active Ollama catalog lease.
136
+
137
+ ## Troubleshooting
138
+
139
+ | Symptom | What to check |
140
+ | --- | --- |
141
+ | `/connect` methods missing | The plugin URL must be a trusted, user-owned `file:///absolute/path/to/opencode-ext-connector/dist/index.js`. A package-directory URL does not load named legacy auth hooks. Fully restart OpenCode after changing it. |
142
+ | Provider enabled but no models | Omitted `providers` enables all four; an explicit list is a strict allow-list. Claude and Cursor need a marker or OAuth record plus the vendor session; Command Code may use an OpenCode-stored API key or a CLI session/key; Ollama needs the exact marker plus a responsive localhost daemon. Fully restart after `/connect` so instance reconstruction picks up new membership. |
143
+ | Claude works until the next start | Default `writeBackCredentials: false` keeps refreshed tokens in memory. A rotated refresh token then fails on the next process start unless writeback is enabled. |
144
+ | Claude reports `invalid_grant` on a copied credential file | Another copy of the same login already refreshed and rotated the refresh token. Give one machine ownership of refresh and set `credentialRefresh: { mode: "never" }` on the others, or log in separately. |
145
+ | `Claude Code client version is unavailable` | No `ANTHROPIC_CLI_VERSION`, no `claude` binary, and `registry.npmjs.org` was unreachable. Set the variable or allow registry access. |
146
+ | Cursor generation fails | Node.js 22 or later is required. Generation uses the unpublished protocol through a private Node child, not `cursor-agent`. Protocol drift fails that provider; there is no implicit fallback. |
147
+ | Command Code generation fails | The client version could not be resolved: set `COMMAND_CODE_CLI_VERSION`, install `command-code`, or allow access to `registry.npmjs.org`. Request metadata includes Node.js version, platform, architecture, and the absolute working directory. |
148
+ | Ollama missing from `opencode models ollama` | Start a process you trust on `localhost:11434`, then `/connect` so the exact session marker can be stored. Cloud tags are unauthenticated catalog entries without connector-supplied credentials; the local daemon may proxy Cloud-tag prompts. `OLLAMA_HOST`, API keys, and direct Cloud generation are not used. |
149
+ | One provider is down | Failures are isolated. Transient snapshot failures keep the last-known catalog; an unavailable snapshot removes only that connector-owned provider. |
150
+
151
+ ## Documentation
152
+
153
+ | Document | Contents |
154
+ | --- | --- |
155
+ | [docs/README.ko.md](docs/README.ko.md) | Korean README |
156
+ | [CHANGELOG.md](CHANGELOG.md) | Release notes |
157
+ | [LICENSE](LICENSE) | BSD 3-Clause License |
158
+ | [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md) | Derived upstream work |
159
+
160
+ ## Testing
161
+
162
+ ```bash
163
+ bun run check
164
+ bun test
165
+ bun run test:provider
166
+ bun run test:integration
167
+ bun run test:e2e
168
+ bun run verify:package
169
+ ```
170
+
171
+ The E2E suite runs real isolated `opencode serve` processes under temporary HOME/XDG directories. It must not inherit host credentials, proxy/token variables, or access external vendor endpoints.
172
+
173
+ ## License and Disclaimer
174
+
175
+ BSD-3-Clause. See [LICENSE](LICENSE). Derived upstream work is listed in [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md).
176
+
177
+ This is an independent and unofficial community project. It is not affiliated
178
+ with, endorsed by, sponsored by, or authorized by OpenCode or any third-party
179
+ service provider.
180
+
181
+ All product names, trademarks, and registered trademarks belong to their
182
+ respective owners. Their use in this project is solely for identification and
183
+ interoperability purposes and does not imply any affiliation or endorsement.
184
+
185
+ The license for this project applies only to the source code distributed in
186
+ this repository. It does not grant any right or permission to access, use,
187
+ modify, automate, or bypass restrictions imposed by third-party services.
188
+
189
+ This project is not intended to encourage circumvention of access controls,
190
+ usage restrictions, authentication requirements, or terms of service. Users
191
+ are solely responsible for determining whether their use is permitted and for
192
+ complying with all applicable laws, agreements, policies, and provider terms.
193
+
194
+ Third-party providers may change, restrict, suspend, or terminate their
195
+ interfaces, authentication mechanisms, accounts, or services at any time.
196
+ Using this software may result in service interruption, account restriction or
197
+ termination, data loss, unexpected charges, or credential exposure.
198
+
199
+ This software is provided "as is" and without warranties of any kind. To the
200
+ maximum extent permitted by applicable law, the authors and contributors are
201
+ not liable for any claim, damage, loss, account action, or other consequence
202
+ arising from the use or inability to use this software. Use this software
203
+ entirely at your own risk.
204
+
205
+ The BSD 3-Clause License in [LICENSE](LICENSE) governs the copying,
206
+ modification, and distribution of this software. If this disclaimer conflicts
207
+ with the license, the license controls.
@@ -0,0 +1,201 @@
1
+ # Third-Party Notices
2
+
3
+ This file lists third-party source that this repository may derive from.
4
+ The BSD-3-Clause license of this repository does not replace these notices.
5
+ Derived TypeScript files must include a header pointing here.
6
+
7
+ ## griffinmartin/opencode-claude-auth
8
+
9
+ - Repository: https://github.com/griffinmartin/opencode-claude-auth
10
+ - Commit: `0f0ff6f12c367339130cbfd250393863ed2c8d9e`
11
+ - License: MIT
12
+ - Copyright: Copyright (c) 2026 gmartin
13
+
14
+ ```
15
+ MIT License
16
+
17
+ Copyright (c) 2026 gmartin
18
+
19
+ Permission is hereby granted, free of charge, to any person obtaining a copy
20
+ of this software and associated documentation files (the "Software"), to deal
21
+ in the Software without restriction, including without limitation the rights
22
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
23
+ copies of the Software, and to permit persons to whom the Software is
24
+ furnished to do so, subject to the following conditions:
25
+
26
+ The above copyright notice and this permission notice shall be included in all
27
+ copies or substantial portions of the Software.
28
+
29
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
30
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
31
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
32
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
33
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
34
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
35
+ SOFTWARE.
36
+ ```
37
+
38
+ ## Rahularya01/pi-cursor
39
+
40
+ - Repository: https://github.com/Rahularya01/pi-cursor
41
+ - Version: `1.4.26`
42
+ - Commit: `d80c12704a5136b441e6d86d1cbbd5f05d5fbcf6`
43
+ - License: MIT
44
+ - Used for: Cursor CLI/IDE token cascade and Connect+protobuf `AgentService` patterns.
45
+
46
+ ```
47
+ MIT License
48
+
49
+ Copyright (c) Rahul Arya
50
+
51
+ Permission is hereby granted, free of charge, to any person obtaining a copy
52
+ of this software and associated documentation files (the "Software"), to deal
53
+ in the Software without restriction, including without limitation the rights
54
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
55
+ copies of the Software, and to permit persons to whom the Software is
56
+ furnished to do so, subject to the following conditions:
57
+
58
+ The above copyright notice and this permission notice shall be included in all
59
+ copies or substantial portions of the Software.
60
+
61
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
62
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
63
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
64
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
65
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
66
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
67
+ SOFTWARE.
68
+ ```
69
+
70
+ ## otto-assistant/opencode-cursor
71
+
72
+ - Repository: https://github.com/otto-assistant/opencode-cursor
73
+ - License: MIT
74
+ - Used for: Architectural reference for an OpenCode plugin talking to Cursor over HTTP/2 without `cursor-agent`; no current source file is directly derived from this repository.
75
+
76
+ ```
77
+ MIT License
78
+
79
+ Copyright (c) 2026 Otto Assistant contributors
80
+
81
+ Permission is hereby granted, free of charge, to any person obtaining a copy
82
+ of this software and associated documentation files (the "Software"), to deal
83
+ in the Software without restriction, including without limitation the rights
84
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
85
+ copies of the Software, and to permit persons to whom the Software is
86
+ furnished to do so, subject to the following conditions:
87
+
88
+ The above copyright notice and this permission notice shall be included in all
89
+ copies or substantial portions of the Software.
90
+
91
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
92
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
93
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
94
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
95
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
96
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
97
+ SOFTWARE.
98
+ ```
99
+
100
+ ## Nomadcxx/opencode-cursor
101
+
102
+ - Repository: https://github.com/Nomadcxx/opencode-cursor
103
+ - Commit: `8e14a26c1e080382f471a729436092ef72edf34e`
104
+ - License: BSD-3-Clause (repository `LICENSE`; `package.json` incorrectly says ISC — this notice keeps the LICENSE text)
105
+ - Copyright: Copyright (c) 2026, Nomadcxx
106
+
107
+ ```
108
+ BSD 3-Clause License
109
+
110
+ Copyright (c) 2026, Nomadcxx
111
+ All rights reserved.
112
+
113
+ Redistribution and use in source and binary forms, with or without
114
+ modification, are permitted provided that the following conditions are met:
115
+
116
+ 1. Redistributions of source code must retain the above copyright notice, this
117
+ list of conditions and the following disclaimer.
118
+
119
+ 2. Redistributions in binary form must reproduce the above copyright notice,
120
+ this list of conditions and the following disclaimer in the documentation
121
+ and/or other materials provided with the distribution.
122
+
123
+ 3. Neither the name of the copyright holder nor the names of its
124
+ contributors may be used to endorse or promote products derived from
125
+ this software without specific prior written permission.
126
+
127
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
128
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
129
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
130
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
131
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
132
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
133
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
134
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
135
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
136
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
137
+ ```
138
+
139
+ ## brent-weatherall/opencode-commandcode-provider
140
+
141
+ - Repository: https://github.com/brent-weatherall/opencode-commandcode-provider
142
+ - Commit: `6cf3f22d4aae469db3723e589291c736285373c1`
143
+ - License: MIT
144
+ - Copyright: Copyright (c) 2026 Brent Weatherall
145
+
146
+ ```
147
+ MIT License
148
+
149
+ Copyright (c) 2026 Brent Weatherall
150
+
151
+ Permission is hereby granted, free of charge, to any person obtaining a copy
152
+ of this software and associated documentation files (the "Software"), to deal
153
+ in the Software without restriction, including without limitation the rights
154
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
155
+ copies of the Software, and to permit persons to whom the Software is
156
+ furnished to do so, subject to the following conditions:
157
+
158
+ The above copyright notice and this permission notice shall be included in all
159
+ copies or substantial portions of the Software.
160
+
161
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
162
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
163
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
164
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
165
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
166
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
167
+ SOFTWARE.
168
+ ```
169
+
170
+ ## colinhacks/zod
171
+
172
+ - Repository: https://github.com/colinhacks/zod
173
+ - Version: `4.1.8`
174
+ - Commit: `a1726d53172ba52ecf90999df73778cf416264fd`
175
+ - License: MIT
176
+ - Copyright: Copyright (c) 2025 Colin McDonnell
177
+ - Used for: Runtime schema validation, including code bundled into the published Cursor HTTP/2 bridge.
178
+
179
+ ```
180
+ MIT License
181
+
182
+ Copyright (c) 2025 Colin McDonnell
183
+
184
+ Permission is hereby granted, free of charge, to any person obtaining a copy
185
+ of this software and associated documentation files (the "Software"), to deal
186
+ in the Software without restriction, including without limitation the rights
187
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
188
+ copies of the Software, and to permit persons to whom the Software is
189
+ furnished to do so, subject to the following conditions:
190
+
191
+ The above copyright notice and this permission notice shall be included in all
192
+ copies or substantial portions of the Software.
193
+
194
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
195
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
196
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
197
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
198
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
199
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
200
+ SOFTWARE.
201
+ ```
@@ -0,0 +1,2 @@
1
+ import type { AdapterModel } from "../core/models";
2
+ export declare function parseModelIdList(value: unknown): readonly AdapterModel[];
@@ -0,0 +1,49 @@
1
+ import { parseModelId } from "../core/ids";
2
+ function idFromUnknown(value) {
3
+ if (typeof value === "string" && value.length > 0) {
4
+ return value;
5
+ }
6
+ if (typeof value === "object" && value !== null && "id" in value) {
7
+ const id = Reflect.get(value, "id");
8
+ return typeof id === "string" && id.length > 0 ? id : null;
9
+ }
10
+ return null;
11
+ }
12
+ function collect(values) {
13
+ const models = [];
14
+ const seen = new Set();
15
+ for (const value of values) {
16
+ const id = idFromUnknown(value);
17
+ if (id === null || seen.has(id)) {
18
+ continue;
19
+ }
20
+ try {
21
+ const parsed = parseModelId(id);
22
+ seen.add(id);
23
+ models.push({ id: parsed });
24
+ }
25
+ catch { }
26
+ }
27
+ return models;
28
+ }
29
+ export function parseModelIdList(value) {
30
+ if (Array.isArray(value)) {
31
+ return collect(value);
32
+ }
33
+ if (typeof value !== "object" || value === null) {
34
+ return [];
35
+ }
36
+ if ("data" in value) {
37
+ const data = Reflect.get(value, "data");
38
+ if (Array.isArray(data)) {
39
+ return collect(data);
40
+ }
41
+ }
42
+ if ("models" in value) {
43
+ const models = Reflect.get(value, "models");
44
+ if (Array.isArray(models)) {
45
+ return collect(models);
46
+ }
47
+ }
48
+ return [];
49
+ }
@@ -0,0 +1,16 @@
1
+ import type { ProviderId } from "./ids";
2
+ import type { AsyncDisposableHandle } from "./lifecycle";
3
+ import type { ProviderSnapshot } from "./models";
4
+ export interface ProviderAdapter extends AsyncDisposableHandle {
5
+ readonly providerId: ProviderId;
6
+ snapshot(signal: AbortSignal): Promise<ProviderSnapshot>;
7
+ }
8
+ export interface CatalogPublisher {
9
+ publish(snapshot: ProviderSnapshot, signal: AbortSignal): Promise<void>;
10
+ }
11
+ export type RefreshProviderCatalogOptions = {
12
+ readonly adapter: ProviderAdapter;
13
+ readonly publisher: CatalogPublisher;
14
+ readonly signal: AbortSignal;
15
+ };
16
+ export declare function refreshProviderCatalog(options: RefreshProviderCatalogOptions): Promise<ProviderSnapshot>;
@@ -0,0 +1,20 @@
1
+ import { AdapterError, OperationCancelledError } from "./errors";
2
+ export async function refreshProviderCatalog(options) {
3
+ if (options.signal.aborted) {
4
+ throw new OperationCancelledError("refresh-provider-catalog");
5
+ }
6
+ const snapshot = await options.adapter.snapshot(options.signal);
7
+ if (snapshot.providerId !== options.adapter.providerId) {
8
+ throw new AdapterError({
9
+ operation: "snapshot-provider-mismatch",
10
+ retryable: false,
11
+ cause: null,
12
+ providerId: options.adapter.providerId,
13
+ });
14
+ }
15
+ if (options.signal.aborted) {
16
+ throw new OperationCancelledError("refresh-provider-catalog");
17
+ }
18
+ await options.publisher.publish(snapshot, options.signal);
19
+ return snapshot;
20
+ }
@@ -0,0 +1,7 @@
1
+ export interface ScheduledCallback extends Disposable {
2
+ cancel(): void;
3
+ }
4
+ export interface Clock {
5
+ nowMs(): number;
6
+ schedule(delayMs: number, callback: () => void): ScheduledCallback;
7
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,13 @@
1
+ import type { Clock } from "./clock";
2
+ import type { AsyncDisposableHandle } from "./lifecycle";
3
+ export type DeadlineOptions = {
4
+ readonly clock: Clock;
5
+ readonly timeoutMs: number;
6
+ readonly parentSignal: AbortSignal | null;
7
+ };
8
+ export interface Deadline extends AsyncDisposableHandle {
9
+ readonly signal: AbortSignal;
10
+ readonly expiresAtMs: number;
11
+ remainingMs(): number;
12
+ }
13
+ export declare function createDeadline(options: DeadlineOptions): Deadline;
@@ -0,0 +1,54 @@
1
+ import { DeadlineExceededError, InvalidArgumentError, OperationCancelledError, ResourceDisposedError, } from "./errors";
2
+ import { createAsyncDisposable } from "./lifecycle";
3
+ export function createDeadline(options) {
4
+ if (!Number.isSafeInteger(options.timeoutMs) || options.timeoutMs < 0) {
5
+ throw new InvalidArgumentError("timeoutMs");
6
+ }
7
+ const expiresAtMs = options.clock.nowMs() + options.timeoutMs;
8
+ if (!Number.isSafeInteger(expiresAtMs)) {
9
+ throw new InvalidArgumentError("timeoutMs");
10
+ }
11
+ const controller = new AbortController();
12
+ const onParentAbort = () => {
13
+ scheduled?.cancel();
14
+ if (!controller.signal.aborted) {
15
+ controller.abort(new OperationCancelledError("deadline-parent"));
16
+ }
17
+ };
18
+ let scheduled = options.timeoutMs > 0
19
+ ? options.clock.schedule(options.timeoutMs, () => {
20
+ if (options.parentSignal !== null) {
21
+ options.parentSignal.removeEventListener("abort", onParentAbort);
22
+ }
23
+ if (!controller.signal.aborted) {
24
+ controller.abort(new DeadlineExceededError(options.timeoutMs));
25
+ }
26
+ })
27
+ : null;
28
+ if (options.parentSignal?.aborted === true) {
29
+ onParentAbort();
30
+ }
31
+ else if (options.parentSignal !== null) {
32
+ options.parentSignal.addEventListener("abort", onParentAbort, { once: true });
33
+ }
34
+ if (options.timeoutMs === 0 && !controller.signal.aborted) {
35
+ controller.abort(new DeadlineExceededError(options.timeoutMs));
36
+ }
37
+ const disposal = createAsyncDisposable(() => {
38
+ scheduled?.cancel();
39
+ scheduled = null;
40
+ if (options.parentSignal !== null) {
41
+ options.parentSignal.removeEventListener("abort", onParentAbort);
42
+ }
43
+ if (!controller.signal.aborted) {
44
+ controller.abort(new ResourceDisposedError("deadline"));
45
+ }
46
+ });
47
+ return {
48
+ signal: controller.signal,
49
+ expiresAtMs,
50
+ remainingMs: () => Math.max(0, expiresAtMs - options.clock.nowMs()),
51
+ dispose: disposal.dispose,
52
+ [Symbol.asyncDispose]: disposal[Symbol.asyncDispose],
53
+ };
54
+ }