subharness 0.0.4 → 0.0.7

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 (303) hide show
  1. package/README.md +95 -9
  2. package/dist/adapters/claude-process.d.ts +3 -0
  3. package/dist/adapters/claude-process.js +19 -2
  4. package/dist/adapters/claude-process.js.map +1 -1
  5. package/dist/adapters/claude-result.d.ts +2 -0
  6. package/dist/adapters/claude-result.js +22 -0
  7. package/dist/adapters/claude-result.js.map +1 -0
  8. package/dist/adapters/claude-tools.d.ts +6 -2
  9. package/dist/adapters/claude-tools.js +14 -12
  10. package/dist/adapters/claude-tools.js.map +1 -1
  11. package/dist/adapters/claude-worker-client.d.ts +49 -0
  12. package/dist/adapters/claude-worker-client.js +359 -0
  13. package/dist/adapters/claude-worker-client.js.map +1 -0
  14. package/dist/adapters/claude-worker-process.d.ts +20 -0
  15. package/dist/adapters/claude-worker-process.js +76 -0
  16. package/dist/adapters/claude-worker-process.js.map +1 -0
  17. package/dist/adapters/claude-worker-protocol.d.ts +38 -0
  18. package/dist/adapters/claude-worker-protocol.js +2 -0
  19. package/dist/adapters/claude-worker-protocol.js.map +1 -0
  20. package/dist/adapters/claude-worker.d.ts +1 -0
  21. package/dist/adapters/claude-worker.js +126 -0
  22. package/dist/adapters/claude-worker.js.map +1 -0
  23. package/dist/adapters/claude.d.ts +16 -6
  24. package/dist/adapters/claude.js +164 -75
  25. package/dist/adapters/claude.js.map +1 -1
  26. package/dist/adapters/codex.js +4 -1
  27. package/dist/adapters/codex.js.map +1 -1
  28. package/dist/adapters/copilot-permissions.d.ts +26 -0
  29. package/dist/adapters/copilot-permissions.js +121 -0
  30. package/dist/adapters/copilot-permissions.js.map +1 -0
  31. package/dist/adapters/copilot-tools.d.ts +12 -0
  32. package/dist/adapters/copilot-tools.js +61 -0
  33. package/dist/adapters/copilot-tools.js.map +1 -0
  34. package/dist/adapters/copilot.d.ts +108 -0
  35. package/dist/adapters/copilot.js +819 -0
  36. package/dist/adapters/copilot.js.map +1 -0
  37. package/dist/adapters/cursor-cli-approvals.d.ts +2 -0
  38. package/dist/adapters/cursor-cli-approvals.js +83 -0
  39. package/dist/adapters/cursor-cli-approvals.js.map +1 -0
  40. package/dist/adapters/cursor-cli-model.d.ts +4 -0
  41. package/dist/adapters/cursor-cli-model.js +64 -0
  42. package/dist/adapters/cursor-cli-model.js.map +1 -0
  43. package/dist/adapters/cursor-cli-session.d.ts +32 -0
  44. package/dist/adapters/cursor-cli-session.js +316 -0
  45. package/dist/adapters/cursor-cli-session.js.map +1 -0
  46. package/dist/adapters/cursor-cli-tools.d.ts +20 -0
  47. package/dist/adapters/cursor-cli-tools.js +181 -0
  48. package/dist/adapters/cursor-cli-tools.js.map +1 -0
  49. package/dist/adapters/cursor-cli.d.ts +2 -0
  50. package/dist/adapters/cursor-cli.js +306 -0
  51. package/dist/adapters/cursor-cli.js.map +1 -0
  52. package/dist/adapters/cursor-model.d.ts +7 -0
  53. package/dist/adapters/cursor-model.js +67 -0
  54. package/dist/adapters/cursor-model.js.map +1 -0
  55. package/dist/adapters/cursor-rpc.d.ts +42 -0
  56. package/dist/adapters/cursor-rpc.js +271 -0
  57. package/dist/adapters/cursor-rpc.js.map +1 -0
  58. package/dist/adapters/cursor-session.d.ts +4 -0
  59. package/dist/adapters/cursor-session.js +327 -0
  60. package/dist/adapters/cursor-session.js.map +1 -0
  61. package/dist/adapters/cursor-startup.d.ts +16 -0
  62. package/dist/adapters/cursor-startup.js +74 -0
  63. package/dist/adapters/cursor-startup.js.map +1 -0
  64. package/dist/adapters/cursor-tools.d.ts +11 -0
  65. package/dist/adapters/cursor-tools.js +49 -0
  66. package/dist/adapters/cursor-tools.js.map +1 -0
  67. package/dist/adapters/cursor.d.ts +6 -0
  68. package/dist/adapters/cursor.js +17 -0
  69. package/dist/adapters/cursor.js.map +1 -0
  70. package/dist/adapters/fx-auth.d.ts +12 -2
  71. package/dist/adapters/fx-auth.js +51 -61
  72. package/dist/adapters/fx-auth.js.map +1 -1
  73. package/dist/adapters/fx-profile.d.ts +8 -0
  74. package/dist/adapters/fx-profile.js +101 -0
  75. package/dist/adapters/fx-profile.js.map +1 -0
  76. package/dist/adapters/fx-rpc.d.ts +2 -0
  77. package/dist/adapters/fx-rpc.js +30 -4
  78. package/dist/adapters/fx-rpc.js.map +1 -1
  79. package/dist/adapters/fx-status.d.ts +2 -0
  80. package/dist/adapters/fx-status.js +96 -0
  81. package/dist/adapters/fx-status.js.map +1 -0
  82. package/dist/adapters/fx.js +28 -12
  83. package/dist/adapters/fx.js.map +1 -1
  84. package/dist/adapters/opencode-access.d.ts +13 -0
  85. package/dist/adapters/opencode-access.js +76 -0
  86. package/dist/adapters/opencode-access.js.map +1 -0
  87. package/dist/adapters/opencode-config.d.ts +11 -0
  88. package/dist/adapters/opencode-config.js +238 -0
  89. package/dist/adapters/opencode-config.js.map +1 -0
  90. package/dist/adapters/opencode-http.d.ts +28 -0
  91. package/dist/adapters/opencode-http.js +297 -0
  92. package/dist/adapters/opencode-http.js.map +1 -0
  93. package/dist/adapters/opencode-tools.d.ts +19 -0
  94. package/dist/adapters/opencode-tools.js +127 -0
  95. package/dist/adapters/opencode-tools.js.map +1 -0
  96. package/dist/adapters/opencode.d.ts +2 -0
  97. package/dist/adapters/opencode.js +569 -0
  98. package/dist/adapters/opencode.js.map +1 -0
  99. package/dist/adapters/rpc.d.ts +3 -0
  100. package/dist/adapters/rpc.js +45 -4
  101. package/dist/adapters/rpc.js.map +1 -1
  102. package/dist/adapters/types.d.ts +5 -0
  103. package/dist/adapters/types.js.map +1 -1
  104. package/dist/approvals/types.d.ts +1 -1
  105. package/dist/approvals/types.js.map +1 -1
  106. package/dist/cli/args.d.ts +1 -1
  107. package/dist/cli/args.js +4 -1
  108. package/dist/cli/args.js.map +1 -1
  109. package/dist/cli/catalog-worker.js.map +1 -1
  110. package/dist/cli/dashboard-client.js +20 -31
  111. package/dist/cli/dashboard-client.js.map +1 -1
  112. package/dist/cli/dashboard-controller.d.ts +7 -0
  113. package/dist/cli/dashboard-controller.js +27 -0
  114. package/dist/cli/dashboard-controller.js.map +1 -0
  115. package/dist/cli/dashboard-detail-view.d.ts +1 -1
  116. package/dist/cli/dashboard-detail-view.js +3 -4
  117. package/dist/cli/dashboard-detail-view.js.map +1 -1
  118. package/dist/cli/dashboard-history-view.js.map +1 -1
  119. package/dist/cli/dashboard-input.d.ts +1 -1
  120. package/dist/cli/dashboard-input.js +11 -1
  121. package/dist/cli/dashboard-input.js.map +1 -1
  122. package/dist/cli/dashboard-layout.js +3 -3
  123. package/dist/cli/dashboard-layout.js.map +1 -1
  124. package/dist/cli/dashboard-renderer.js.map +1 -1
  125. package/dist/cli/dashboard-style.js +2 -2
  126. package/dist/cli/dashboard-style.js.map +1 -1
  127. package/dist/cli/dashboard.d.ts +2 -2
  128. package/dist/cli/dashboard.js +7 -32
  129. package/dist/cli/dashboard.js.map +1 -1
  130. package/dist/cli/help.d.ts +1 -1
  131. package/dist/cli/help.js +30 -12
  132. package/dist/cli/help.js.map +1 -1
  133. package/dist/cli/main.js +55 -43
  134. package/dist/cli/main.js.map +1 -1
  135. package/dist/config/access-provenance.d.ts +10 -0
  136. package/dist/config/access-provenance.js +31 -0
  137. package/dist/config/access-provenance.js.map +1 -0
  138. package/dist/config/access.d.ts +12 -2
  139. package/dist/config/access.js +125 -27
  140. package/dist/config/access.js.map +1 -1
  141. package/dist/config/loader.js +1 -0
  142. package/dist/config/loader.js.map +1 -1
  143. package/dist/config/oidc.js +4 -2
  144. package/dist/config/oidc.js.map +1 -1
  145. package/dist/config/project.js +2 -1
  146. package/dist/config/project.js.map +1 -1
  147. package/dist/config/resolve-access.js +24 -10
  148. package/dist/config/resolve-access.js.map +1 -1
  149. package/dist/errors.d.ts +2 -2
  150. package/dist/errors.js.map +1 -1
  151. package/dist/index.d.ts +8 -2
  152. package/dist/index.js +4 -1
  153. package/dist/index.js.map +1 -1
  154. package/dist/process-diagnostics.d.ts +2 -0
  155. package/dist/process-diagnostics.js +11 -0
  156. package/dist/process-diagnostics.js.map +1 -0
  157. package/dist/runtime/access-errors.d.ts +4 -0
  158. package/dist/runtime/access-errors.js +25 -0
  159. package/dist/runtime/access-errors.js.map +1 -0
  160. package/dist/runtime/approval-registry.d.ts +9 -0
  161. package/dist/runtime/approval-registry.js +144 -5
  162. package/dist/runtime/approval-registry.js.map +1 -1
  163. package/dist/runtime/capture.d.ts +22 -0
  164. package/dist/runtime/capture.js +320 -0
  165. package/dist/runtime/capture.js.map +1 -0
  166. package/dist/runtime/catalog.d.ts +39 -0
  167. package/dist/runtime/catalog.js +84 -0
  168. package/dist/runtime/catalog.js.map +1 -0
  169. package/dist/runtime/client.d.ts +2 -1
  170. package/dist/runtime/client.js +74 -47
  171. package/dist/runtime/client.js.map +1 -1
  172. package/dist/runtime/coordinator.d.ts +44 -7
  173. package/dist/runtime/coordinator.js +265 -31
  174. package/dist/runtime/coordinator.js.map +1 -1
  175. package/dist/runtime/daemon.js +12 -6
  176. package/dist/runtime/daemon.js.map +1 -1
  177. package/dist/runtime/dashboard-sanitize.d.ts +2 -0
  178. package/dist/runtime/dashboard-sanitize.js +7 -0
  179. package/dist/runtime/dashboard-sanitize.js.map +1 -0
  180. package/dist/runtime/dashboard-workspace.js +5 -1
  181. package/dist/runtime/dashboard-workspace.js.map +1 -1
  182. package/dist/runtime/dashboard.d.ts +1 -1
  183. package/dist/runtime/dashboard.js +2 -3
  184. package/dist/runtime/dashboard.js.map +1 -1
  185. package/dist/runtime/definition.d.ts +6 -1
  186. package/dist/runtime/definition.js +42 -2
  187. package/dist/runtime/definition.js.map +1 -1
  188. package/dist/runtime/native-owner.js +7 -1
  189. package/dist/runtime/native-owner.js.map +1 -1
  190. package/dist/runtime/pagination.d.ts +9 -0
  191. package/dist/runtime/pagination.js +36 -0
  192. package/dist/runtime/pagination.js.map +1 -0
  193. package/dist/runtime/sdk-observation.d.ts +8 -0
  194. package/dist/runtime/sdk-observation.js +75 -0
  195. package/dist/runtime/sdk-observation.js.map +1 -0
  196. package/dist/runtime/sdk-projection.d.ts +8 -0
  197. package/dist/runtime/sdk-projection.js +19 -0
  198. package/dist/runtime/sdk-projection.js.map +1 -0
  199. package/dist/runtime/sdk-service.d.ts +11 -0
  200. package/dist/runtime/sdk-service.js +109 -0
  201. package/dist/runtime/sdk-service.js.map +1 -0
  202. package/dist/runtime/select-native.d.ts +4 -1
  203. package/dist/runtime/select-native.js +28 -13
  204. package/dist/runtime/select-native.js.map +1 -1
  205. package/dist/runtime/service.d.ts +11 -1
  206. package/dist/runtime/service.js +178 -3
  207. package/dist/runtime/service.js.map +1 -1
  208. package/dist/runtime/session-launcher.js +1 -1
  209. package/dist/runtime/session-launcher.js.map +1 -1
  210. package/dist/runtime/snapshots.d.ts +103 -0
  211. package/dist/runtime/snapshots.js +124 -0
  212. package/dist/runtime/snapshots.js.map +1 -0
  213. package/dist/runtime/state.d.ts +26 -0
  214. package/dist/runtime/state.js +86 -17
  215. package/dist/runtime/state.js.map +1 -1
  216. package/dist/runtime/task-data.d.ts +38 -0
  217. package/dist/runtime/task-data.js +2 -0
  218. package/dist/runtime/task-data.js.map +1 -0
  219. package/dist/runtime/transport.d.ts +13 -0
  220. package/dist/runtime/transport.js +166 -0
  221. package/dist/runtime/transport.js.map +1 -0
  222. package/dist/runtime/types.d.ts +28 -9
  223. package/dist/runtime/types.js.map +1 -1
  224. package/dist/runtime/worker-client.js +40 -13
  225. package/dist/runtime/worker-client.js.map +1 -1
  226. package/dist/runtime/worker-server.js +105 -24
  227. package/dist/runtime/worker-server.js.map +1 -1
  228. package/dist/sdk/connected-types.d.ts +42 -0
  229. package/dist/sdk/connected-types.js +2 -0
  230. package/dist/sdk/connected-types.js.map +1 -0
  231. package/dist/sdk/connected.d.ts +3 -0
  232. package/dist/sdk/connected.js +232 -0
  233. package/dist/sdk/connected.js.map +1 -0
  234. package/dist/sdk/definitions.d.ts +4 -1
  235. package/dist/sdk/definitions.js +16 -2
  236. package/dist/sdk/definitions.js.map +1 -1
  237. package/dist/sdk/execution-definition.d.ts +3 -0
  238. package/dist/sdk/execution-definition.js +59 -0
  239. package/dist/sdk/execution-definition.js.map +1 -0
  240. package/dist/sdk/execution-driver.d.ts +6 -0
  241. package/dist/sdk/execution-driver.js +86 -0
  242. package/dist/sdk/execution-driver.js.map +1 -0
  243. package/dist/sdk/execution-observation.d.ts +3 -0
  244. package/dist/sdk/execution-observation.js +35 -0
  245. package/dist/sdk/execution-observation.js.map +1 -0
  246. package/dist/sdk/execution-options.d.ts +17 -0
  247. package/dist/sdk/execution-options.js +115 -0
  248. package/dist/sdk/execution-options.js.map +1 -0
  249. package/dist/sdk/execution-types.d.ts +72 -0
  250. package/dist/sdk/execution-types.js +2 -0
  251. package/dist/sdk/execution-types.js.map +1 -0
  252. package/dist/sdk/execution.d.ts +3 -0
  253. package/dist/sdk/execution.js +3 -0
  254. package/dist/sdk/execution.js.map +1 -0
  255. package/dist/sdk/hosted-error.d.ts +3 -0
  256. package/dist/sdk/hosted-error.js +14 -0
  257. package/dist/sdk/hosted-error.js.map +1 -0
  258. package/dist/sdk/hosted.d.ts +23 -0
  259. package/dist/sdk/hosted.js +204 -0
  260. package/dist/sdk/hosted.js.map +1 -0
  261. package/dist/sdk/permission-validation.js +10 -1
  262. package/dist/sdk/permission-validation.js.map +1 -1
  263. package/dist/sdk/runner.d.ts +5 -0
  264. package/dist/sdk/runner.js +107 -0
  265. package/dist/sdk/runner.js.map +1 -0
  266. package/dist/sdk/tools.js +4 -1
  267. package/dist/sdk/tools.js.map +1 -1
  268. package/dist/sdk/types.d.ts +29 -1
  269. package/dist/sdk/types.js.map +1 -1
  270. package/package.json +6 -3
  271. package/sdk/access-config.md +60 -4
  272. package/sdk/adapter-contract.md +13 -3
  273. package/sdk/additional-harnesses.md +43 -0
  274. package/sdk/agent-skill.md +2 -2
  275. package/sdk/agent.md +6 -4
  276. package/sdk/approvals.md +5 -1
  277. package/sdk/authentication.md +1 -1
  278. package/sdk/cli/dashboard-design.md +6 -0
  279. package/sdk/cli/index.md +9 -6
  280. package/sdk/cli/output.md +3 -1
  281. package/sdk/completion-notifications.md +2 -0
  282. package/sdk/config.md +1 -1
  283. package/sdk/copilot.md +53 -0
  284. package/sdk/cursor.md +68 -0
  285. package/sdk/diagnostics.md +29 -0
  286. package/sdk/distribution.md +5 -3
  287. package/sdk/evals.md +1 -1
  288. package/sdk/examples/chat-tool.ts +126 -0
  289. package/sdk/execution.md +743 -0
  290. package/sdk/fx.md +50 -5
  291. package/sdk/harnesses.md +13 -13
  292. package/sdk/index.md +45 -20
  293. package/sdk/message-delivery.md +2 -0
  294. package/sdk/opencode.md +57 -0
  295. package/sdk/permissions.md +6 -2
  296. package/sdk/plugins/sub-agents.md +4 -2
  297. package/sdk/project-team.md +25 -1
  298. package/sdk/sessions.md +2 -0
  299. package/sdk/tools.md +4 -2
  300. package/sdk/v1-runtime.md +8 -6
  301. package/dist/cli/catalog.d.ts +0 -26
  302. package/dist/cli/catalog.js +0 -41
  303. package/dist/cli/catalog.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cursor-session.js","sourceRoot":"","sources":["../../src/adapters/cursor-session.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Run, RunStatus, SDKAgent, SDKMessage, SDKModel } from \"@cursor/sdk\";\nimport { AgentError } from \"../errors.js\";\nimport type { AdapterOptions, NativeSession } from \"./types.js\";\nimport type { CursorTools } from \"./cursor-tools.js\";\nimport { cursorTerminalText, isCursorTerminalStatus, validateCursorRunResult } from \"./cursor-model.js\";\n\ninterface ActiveTurn {\n run?: Run;\n runReady: Promise<void>;\n releaseRun(): void;\n terminal: Promise<Exclude<RunStatus, \"running\">>;\n terminalStatus?: Exclude<RunStatus, \"running\">;\n markTerminal(status: Exclude<RunStatus, \"running\">): void;\n stopSignal: Promise<void>;\n signalStop(): void;\n stopTask?: Promise<void>;\n stopFailure?: AgentError;\n completion: Promise<string>;\n interrupted: boolean;\n closing: boolean;\n cancellation?: Promise<void>;\n unsubscribe?: () => void;\n nativeFailure?: AgentError;\n}\n\nconst NATIVE_STOP_TIMEOUT_MS = 3_000;\n\nexport function createCursorSession(native: SDKAgent, selected: SDKModel, options: AdapterOptions, tools: CursorTools): NativeSession {\n let closed = false;\n let active: ActiveTurn | undefined;\n let first = true;\n let closing: Promise<void> | undefined;\n let sessionFailure: AgentError | undefined;\n\n const refreshTerminal = (current: ActiveTurn): void => {\n if (!current.run || current.terminalStatus) return;\n try {\n if (isCursorTerminalStatus(current.run.status)) current.markTerminal(current.run.status);\n } catch { /* A verified status event or result is still required. */ }\n };\n\n const stopNative = async (current: ActiveTurn): Promise<void> => {\n await bounded(current.runReady, NATIVE_STOP_TIMEOUT_MS, \"Cursor did not expose the active native run for cancellation.\");\n if (!current.run) {\n await tools.drain();\n return;\n }\n refreshTerminal(current);\n if (current.terminalStatus) {\n await tools.drain();\n return;\n }\n current.cancellation ??= Promise.resolve().then(() => current.run!.cancel());\n void current.cancellation.catch(() => {});\n await tools.drain();\n refreshTerminal(current);\n if (current.terminalStatus) return;\n const cancellation = current.cancellation.then(\n () => ({ kind: \"accepted\" as const }),\n error => ({ kind: \"rejected\" as const, error }),\n );\n const cancellationOutcome = await bounded(Promise.race([\n cancellation,\n current.terminal.then(() => ({ kind: \"terminal\" as const })),\n ]), NATIVE_STOP_TIMEOUT_MS, \"Cursor did not confirm the native cancellation request.\");\n if (cancellationOutcome.kind === \"terminal\") return;\n if (cancellationOutcome.kind === \"rejected\") {\n refreshTerminal(current);\n if (!current.terminalStatus) throw cancellationOutcome.error instanceof AgentError\n ? cancellationOutcome.error\n : new AgentError(\"CANCELLATION_FAILED\", \"Cursor did not confirm native cancellation.\");\n return;\n }\n refreshTerminal(current);\n if (!current.terminalStatus) {\n await bounded(current.terminal, NATIVE_STOP_TIMEOUT_MS, \"Cursor did not reach a terminal status after cancellation.\");\n }\n };\n\n const requestStop = (current: ActiveTurn): Promise<void> => {\n if (!current.stopTask) {\n current.stopTask = stopNative(current).catch(error => {\n const failure = error instanceof AgentError && error.code === \"CANCELLATION_FAILED\"\n ? error\n : new AgentError(\"CANCELLATION_FAILED\", \"Cursor did not confirm native cancellation.\");\n current.stopFailure = failure;\n sessionFailure = failure;\n tools.stopAdmission();\n throw failure;\n });\n void current.stopTask.catch(() => {});\n }\n current.signalStop();\n return current.stopTask;\n };\n\n const watchRun = async (current: ActiveTurn, run: Run): Promise<void> => {\n try {\n for await (const message of run.stream()) {\n observeMessage(current, message);\n }\n refreshTerminal(current);\n if (!current.terminalStatus && !current.interrupted && !current.closing) {\n current.nativeFailure = new AgentError(\"NATIVE_ERROR\", \"Cursor native event delivery stopped before terminal completion.\");\n tools.stopAdmission();\n void requestStop(current);\n }\n } catch {\n refreshTerminal(current);\n if (!current.terminalStatus && !current.interrupted && !current.closing) {\n current.nativeFailure = new AgentError(\"NATIVE_ERROR\", \"Cursor native event delivery failed.\");\n tools.stopAdmission();\n void requestStop(current);\n }\n }\n };\n\n const bindRun = (current: ActiveTurn, run: Run): void => {\n current.run = run;\n try {\n current.unsubscribe = run.onDidChangeStatus(status => {\n if (isCursorTerminalStatus(status)) current.markTerminal(status);\n });\n refreshTerminal(current);\n } catch {\n current.nativeFailure = new AgentError(\"NATIVE_ERROR\", \"Cursor native status observation failed.\");\n }\n current.releaseRun();\n void watchRun(current, run);\n if (current.nativeFailure) {\n tools.stopAdmission();\n void requestStop(current);\n }\n };\n\n const bindLateRun = (current: ActiveTurn, run: Run): void => {\n current.run = run;\n try {\n current.unsubscribe = run.onDidChangeStatus(status => {\n if (isCursorTerminalStatus(status)) current.markTerminal(status);\n });\n refreshTerminal(current);\n } catch { /* The poisoned session still owns and cancels the late run. */ }\n current.releaseRun();\n current.cancellation ??= Promise.resolve().then(() => run.cancel());\n void current.cancellation.catch(() => {});\n void watchRun(current, run).finally(() => current.unsubscribe?.());\n };\n\n const stoppedFailure = (current: ActiveTurn): AgentError => {\n if (current.closing) return new AgentError(\"SESSION_CLOSED\", \"The Cursor session closed during the turn.\");\n if (current.interrupted) return new AgentError(\"INTERRUPTED\", \"The Cursor turn was interrupted.\");\n return current.nativeFailure ?? new AgentError(\"NATIVE_ERROR\", \"Cursor stopped without a native terminal result.\");\n };\n\n const executeTurn = async (current: ActiveTurn, prompt: string): Promise<string> => {\n tools.start();\n try {\n const includeInstructions = first;\n const message = includeInstructions && options.agent.instructions\n ? firstPrompt(options.agent.instructions, prompt)\n : prompt;\n const admission = Promise.resolve().then(() => native.send(message, { model: { id: selected.id } })).then(\n run => {\n if (current.stopFailure) bindLateRun(current, run);\n else bindRun(current, run);\n if (includeInstructions) first = false;\n return { kind: \"run\" as const, run };\n },\n error => {\n current.releaseRun();\n return { kind: \"admission-failure\" as const, error };\n },\n );\n const stopped = current.stopSignal.then(async () => {\n try {\n await current.stopTask;\n return { kind: \"stopped\" as const };\n } catch (error) {\n return { kind: \"stop-failure\" as const, error };\n }\n });\n const admitted = await Promise.race([admission, stopped]);\n if (admitted.kind === \"stop-failure\") throw admitted.error;\n if (admitted.kind === \"stopped\") throw stoppedFailure(current);\n if (admitted.kind === \"admission-failure\") throw admitted.error;\n const waited = admitted.run.wait().then(\n result => ({ kind: \"result\" as const, result }),\n () => ({ kind: \"failure\" as const }),\n );\n const outcome = await Promise.race([waited, stopped]);\n if (outcome.kind === \"stop-failure\") throw outcome.error;\n if (outcome.kind === \"stopped\") throw stoppedFailure(current);\n if (outcome.kind === \"failure\") {\n current.nativeFailure = new AgentError(\"NATIVE_ERROR\", \"Cursor native result delivery failed.\");\n tools.stopAdmission();\n await requestStop(current);\n throw stoppedFailure(current);\n }\n validateCursorRunResult(outcome.result);\n current.markTerminal(outcome.result.status);\n if (current.stopTask) {\n await current.stopTask;\n throw stoppedFailure(current);\n }\n return cursorTerminalText(outcome.result, selected);\n } catch (error) {\n current.releaseRun();\n if (error instanceof AgentError) {\n if (error.code === \"INVALID_CONFIG\" || error.code === \"CANCELLATION_FAILED\") sessionFailure = error;\n throw error;\n }\n if (current.closing) throw new AgentError(\"SESSION_CLOSED\", \"The Cursor session closed during the turn.\");\n if (current.interrupted) throw new AgentError(\"INTERRUPTED\", \"The Cursor turn was interrupted.\");\n throw new AgentError(\"NATIVE_ERROR\", \"Cursor could not complete the turn.\");\n } finally {\n current.unsubscribe?.();\n tools.stopAdmission();\n await tools.drain();\n if (active === current && !current.stopFailure) active = undefined;\n }\n };\n\n return {\n async turn(prompt) {\n if (closed) throw new AgentError(\"SESSION_CLOSED\", \"The Cursor session has closed.\");\n if (sessionFailure) throw sessionFailure;\n if (active) throw new AgentError(\"SESSION_BUSY\", \"Cursor already has an active turn.\");\n let releaseRun!: () => void, markTerminal!: (status: Exclude<RunStatus, \"running\">) => void, signalStop!: () => void;\n const current: ActiveTurn = {\n runReady: new Promise<void>(resolve => { releaseRun = resolve; }),\n releaseRun: () => releaseRun(),\n terminal: new Promise<Exclude<RunStatus, \"running\">>(resolve => { markTerminal = resolve; }),\n markTerminal(status) {\n if (current.terminalStatus) return;\n current.terminalStatus = status;\n markTerminal(status);\n },\n stopSignal: new Promise<void>(resolve => { signalStop = resolve; }),\n signalStop: () => signalStop(),\n completion: undefined as unknown as Promise<string>,\n interrupted: false,\n closing: false,\n };\n active = current;\n current.completion = executeTurn(current, prompt);\n return await current.completion;\n },\n async steer() { throw new AgentError(\"UNSUPPORTED_DELIVERY\", \"Cursor does not expose verified active steering.\"); },\n async interrupt() {\n const current = active;\n if (!current) return;\n current.interrupted = true;\n tools.stopAdmission();\n try { await requestStop(current); }\n catch (error) {\n throw error instanceof AgentError ? error : new AgentError(\"CANCELLATION_FAILED\", \"Cursor did not confirm native cancellation.\");\n }\n await current.completion.catch(() => {});\n },\n async resume() { throw new AgentError(\"RECOVERY_UNSUPPORTED\", \"Cursor cannot retry failed execution without replaying input.\"); },\n async close() {\n if (closing) return await closing;\n closed = true;\n tools.stopAdmission();\n const current = active;\n if (current) current.closing = true;\n closing = (async () => {\n const disposal = Promise.resolve().then(() => native[Symbol.asyncDispose]());\n void disposal.catch(() => {});\n let stopFailure: unknown;\n if (current) {\n try { await requestStop(current); }\n catch (error) { stopFailure = error; }\n } else await tools.drain();\n try {\n await bounded(disposal, NATIVE_STOP_TIMEOUT_MS, \"Cursor did not confirm native session disposal.\");\n } catch (error) {\n if (error instanceof AgentError) throw error;\n throw new AgentError(\"CANCELLATION_FAILED\", \"Cursor did not confirm native session disposal.\");\n } finally {\n await tools.drain();\n if (active === current) active = undefined;\n }\n if (stopFailure) throw stopFailure instanceof AgentError\n ? stopFailure\n : new AgentError(\"CANCELLATION_FAILED\", \"Cursor did not confirm native cancellation during close.\");\n if (current) await current.completion.catch(() => {});\n })();\n return await closing;\n },\n };\n}\n\nfunction firstPrompt(instructions: string, prompt: string): string {\n return `<subharness-instructions>\\n${instructions}\\n</subharness-instructions>\\n\\n${prompt}`;\n}\n\nfunction observeMessage(current: ActiveTurn, message: SDKMessage): void {\n if (message.type !== \"status\") return;\n const status = message.status === \"FINISHED\" ? \"finished\"\n : message.status === \"ERROR\" ? \"error\"\n : message.status === \"CANCELLED\" || message.status === \"EXPIRED\" ? \"cancelled\"\n : undefined;\n if (status) current.markTerminal(status);\n}\n\nasync function bounded<T>(promise: Promise<T>, milliseconds: number, message: string): Promise<T> {\n let timer!: NodeJS.Timeout;\n const timeout = new Promise<never>((_resolve, reject) => {\n timer = setTimeout(() => reject(new AgentError(\"CANCELLATION_FAILED\", message)), milliseconds);\n timer.unref();\n });\n try { return await Promise.race([promise, timeout]); }\n finally { clearTimeout(timer); }\n}\n"]}
@@ -0,0 +1,16 @@
1
+ import { type AgentOptions, type LocalAgentOptions, type SDKAgent, type SDKModel, type SDKUser } from "@cursor/sdk";
2
+ import type { AdapterOptions } from "./types.js";
3
+ export interface CursorDependencies {
4
+ me(options: {
5
+ apiKey: string;
6
+ }): Promise<SDKUser>;
7
+ models(options: {
8
+ apiKey: string;
9
+ }): Promise<SDKModel[]>;
10
+ create(options: AgentOptions): Promise<SDKAgent>;
11
+ }
12
+ export declare const cursorDependencies: CursorDependencies;
13
+ export declare function startCursor(options: AdapterOptions, deps: CursorDependencies, toolConfig: Pick<LocalAgentOptions, "customTools">): Promise<{
14
+ native: SDKAgent;
15
+ selected: SDKModel;
16
+ }>;
@@ -0,0 +1,74 @@
1
+ import { Agent, AuthenticationError, ConfigurationError, Cursor, } from "@cursor/sdk";
2
+ import { AgentError } from "../errors.js";
3
+ import { resolveCursorModel, validateCursorAccount, validateCursorCatalog } from "./cursor-model.js";
4
+ export const cursorDependencies = {
5
+ me: options => Cursor.me(options),
6
+ models: options => Cursor.models.list(options),
7
+ create: options => Agent.create(options),
8
+ };
9
+ export async function startCursor(options, deps, toolConfig) {
10
+ const harness = options.harness;
11
+ if (harness.kind !== "cursor")
12
+ throw new AgentError("INVALID_CONFIG", "Cursor received configuration for a different harness.");
13
+ if (typeof harness.model !== "string" || !harness.model.trim()) {
14
+ throw new AgentError("INVALID_CONFIG", "Cursor requires an explicit nonempty model.");
15
+ }
16
+ if (harness.sandboxMode !== undefined && harness.sandboxMode !== "enabled" && harness.sandboxMode !== "disabled") {
17
+ throw new AgentError("INVALID_CONFIG", "Cursor sandbox mode must be enabled or disabled.");
18
+ }
19
+ if (options.access.type === "vercel-api-key" || options.access.type === "vercel-oidc") {
20
+ throw new AgentError("UNSUPPORTED_OPTION", "Cursor does not support Vercel Gateway access.");
21
+ }
22
+ if (options.access.type !== "api-key") {
23
+ throw new AgentError("ACCESS_UNAVAILABLE", "Cursor subscription access is unavailable; configure explicit API-key access.");
24
+ }
25
+ rejectEndpointOverrides(options.env);
26
+ const apiKey = options.access.token;
27
+ if (!apiKey?.trim())
28
+ throw new AgentError("ACCESS_UNAVAILABLE", "The selected Cursor credential is unavailable.");
29
+ let catalog;
30
+ try {
31
+ const [account, models] = await Promise.all([deps.me({ apiKey }), deps.models({ apiKey })]);
32
+ validateCursorAccount(account);
33
+ validateCursorCatalog(models);
34
+ catalog = models;
35
+ }
36
+ catch (error) {
37
+ if (error instanceof AgentError)
38
+ throw error;
39
+ throw startupFailure(error, "Cursor account and model discovery failed.");
40
+ }
41
+ const selected = resolveCursorModel(catalog, harness.model);
42
+ try {
43
+ const native = await deps.create({
44
+ apiKey,
45
+ model: { id: selected.id },
46
+ local: {
47
+ cwd: options.cwd,
48
+ ...toolConfig,
49
+ ...(harness.sandboxMode === undefined ? {} : { sandboxOptions: { enabled: harness.sandboxMode === "enabled" } }),
50
+ },
51
+ });
52
+ return { native, selected };
53
+ }
54
+ catch (error) {
55
+ throw startupFailure(error, "Cursor could not create a local agent.");
56
+ }
57
+ }
58
+ function rejectEndpointOverrides(env) {
59
+ for (const name of ["CURSOR_BACKEND_URL", "CURSOR_WEBSITE_URL"]) {
60
+ if (env[name]?.trim() || process.env[name]?.trim()) {
61
+ throw new AgentError("UNSUPPORTED_OPTION", "Cursor endpoint overrides are unsupported with explicit API-key access.");
62
+ }
63
+ }
64
+ }
65
+ function startupFailure(error, message) {
66
+ if (error instanceof AuthenticationError) {
67
+ return new AgentError("ACCESS_UNAVAILABLE", "Cursor rejected the selected API-key access.");
68
+ }
69
+ if (error instanceof ConfigurationError) {
70
+ return new AgentError("INVALID_CONFIG", "Cursor rejected the selected local configuration.");
71
+ }
72
+ return new AgentError("NATIVE_ERROR", message);
73
+ }
74
+ //# sourceMappingURL=cursor-startup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cursor-startup.js","sourceRoot":"","sources":["../../src/adapters/cursor-startup.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Agent,\n AuthenticationError,\n ConfigurationError,\n Cursor,\n type AgentOptions,\n type LocalAgentOptions,\n type SDKAgent,\n type SDKModel,\n type SDKUser,\n} from \"@cursor/sdk\";\nimport { AgentError } from \"../errors.js\";\nimport type { AdapterOptions } from \"./types.js\";\nimport { resolveCursorModel, validateCursorAccount, validateCursorCatalog } from \"./cursor-model.js\";\n\nexport interface CursorDependencies {\n me(options: { apiKey: string }): Promise<SDKUser>;\n models(options: { apiKey: string }): Promise<SDKModel[]>;\n create(options: AgentOptions): Promise<SDKAgent>;\n}\n\nexport const cursorDependencies: CursorDependencies = {\n me: options => Cursor.me(options),\n models: options => Cursor.models.list(options),\n create: options => Agent.create(options),\n};\n\nexport async function startCursor(\n options: AdapterOptions,\n deps: CursorDependencies,\n toolConfig: Pick<LocalAgentOptions, \"customTools\">,\n): Promise<{ native: SDKAgent; selected: SDKModel }> {\n const harness = options.harness;\n if (harness.kind !== \"cursor\") throw new AgentError(\"INVALID_CONFIG\", \"Cursor received configuration for a different harness.\");\n if (typeof harness.model !== \"string\" || !harness.model.trim()) {\n throw new AgentError(\"INVALID_CONFIG\", \"Cursor requires an explicit nonempty model.\");\n }\n if (harness.sandboxMode !== undefined && harness.sandboxMode !== \"enabled\" && harness.sandboxMode !== \"disabled\") {\n throw new AgentError(\"INVALID_CONFIG\", \"Cursor sandbox mode must be enabled or disabled.\");\n }\n if (options.access.type === \"vercel-api-key\" || options.access.type === \"vercel-oidc\") {\n throw new AgentError(\"UNSUPPORTED_OPTION\", \"Cursor does not support Vercel Gateway access.\");\n }\n if (options.access.type !== \"api-key\") {\n throw new AgentError(\"ACCESS_UNAVAILABLE\", \"Cursor subscription access is unavailable; configure explicit API-key access.\");\n }\n rejectEndpointOverrides(options.env);\n const apiKey = options.access.token;\n if (!apiKey?.trim()) throw new AgentError(\"ACCESS_UNAVAILABLE\", \"The selected Cursor credential is unavailable.\");\n\n let catalog: SDKModel[];\n try {\n const [account, models] = await Promise.all([deps.me({ apiKey }), deps.models({ apiKey })]);\n validateCursorAccount(account);\n validateCursorCatalog(models);\n catalog = models;\n } catch (error) {\n if (error instanceof AgentError) throw error;\n throw startupFailure(error, \"Cursor account and model discovery failed.\");\n }\n const selected = resolveCursorModel(catalog, harness.model);\n\n try {\n const native = await deps.create({\n apiKey,\n model: { id: selected.id },\n local: {\n cwd: options.cwd,\n ...toolConfig,\n ...(harness.sandboxMode === undefined ? {} : { sandboxOptions: { enabled: harness.sandboxMode === \"enabled\" } }),\n },\n });\n return { native, selected };\n } catch (error) {\n throw startupFailure(error, \"Cursor could not create a local agent.\");\n }\n}\n\nfunction rejectEndpointOverrides(env: NodeJS.ProcessEnv): void {\n for (const name of [\"CURSOR_BACKEND_URL\", \"CURSOR_WEBSITE_URL\"] as const) {\n if (env[name]?.trim() || process.env[name]?.trim()) {\n throw new AgentError(\"UNSUPPORTED_OPTION\", \"Cursor endpoint overrides are unsupported with explicit API-key access.\");\n }\n }\n}\n\nfunction startupFailure(error: unknown, message: string): AgentError {\n if (error instanceof AuthenticationError) {\n return new AgentError(\"ACCESS_UNAVAILABLE\", \"Cursor rejected the selected API-key access.\");\n }\n if (error instanceof ConfigurationError) {\n return new AgentError(\"INVALID_CONFIG\", \"Cursor rejected the selected local configuration.\");\n }\n return new AgentError(\"NATIVE_ERROR\", message);\n}\n"]}
@@ -0,0 +1,11 @@
1
+ import type { SDKCustomTool } from "@cursor/sdk";
2
+ import type { ExecutionDefinition } from "./types.js";
3
+ export type CursorTools = ReturnType<typeof cursorTools>;
4
+ export declare function cursorTools(agent: Pick<ExecutionDefinition, "tools">): {
5
+ config: {} | {
6
+ customTools: Record<string, SDKCustomTool>;
7
+ };
8
+ start(): void;
9
+ stopAdmission(): void;
10
+ drain(): Promise<void>;
11
+ };
@@ -0,0 +1,49 @@
1
+ import { AgentError } from "../errors.js";
2
+ import { executeTool, toolJsonSchema } from "../sdk/tools.js";
3
+ export function cursorTools(agent) {
4
+ const pending = new Set();
5
+ let accepting = false;
6
+ const entries = Object.entries(agent.tools ?? {});
7
+ const customTools = {};
8
+ for (const [name, definition] of entries) {
9
+ const inputSchema = toolJsonSchema(definition);
10
+ customTools[name] = {
11
+ description: definition.description,
12
+ inputSchema,
13
+ execute(args) {
14
+ if (!accepting)
15
+ return toolError("The task is not accepting tool calls.");
16
+ const execution = runTool(definition, args);
17
+ pending.add(execution);
18
+ void execution.finally(() => pending.delete(execution));
19
+ return execution;
20
+ },
21
+ };
22
+ }
23
+ return {
24
+ config: entries.length === 0 ? {} : { customTools },
25
+ start() { accepting = true; },
26
+ stopAdmission() { accepting = false; },
27
+ async drain() {
28
+ accepting = false;
29
+ await Promise.allSettled([...pending]);
30
+ },
31
+ };
32
+ }
33
+ async function runTool(definition, args) {
34
+ try {
35
+ return nativeResult(await executeTool(definition, args));
36
+ }
37
+ catch (error) {
38
+ return toolError(error instanceof AgentError ? error.message : "The custom tool failed.");
39
+ }
40
+ }
41
+ function nativeResult(result) {
42
+ if (typeof result === "string")
43
+ return result;
44
+ return { content: result.content.map(block => ({ ...block })) };
45
+ }
46
+ function toolError(text) {
47
+ return { isError: true, content: [{ type: "text", text }] };
48
+ }
49
+ //# sourceMappingURL=cursor-tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cursor-tools.js","sourceRoot":"","sources":["../../src/adapters/cursor-tools.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAO9D,MAAM,UAAU,WAAW,CAAC,KAAyC;IACnE,MAAM,OAAO,GAAG,IAAI,GAAG,EAAoB,CAAC;IAC5C,IAAI,SAAS,GAAG,KAAK,CAAC;IACtB,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;IAClD,MAAM,WAAW,GAAkC,EAAE,CAAC;IAEtD,KAAK,MAAM,CAAC,IAAI,EAAE,UAAU,CAAC,IAAI,OAAO,EAAE,CAAC;QACzC,MAAM,WAAW,GAAG,cAAc,CAAC,UAAU,CAAiC,CAAC;QAC/E,WAAW,CAAC,IAAI,CAAC,GAAG;YAClB,WAAW,EAAE,UAAU,CAAC,WAAW;YACnC,WAAW;YACX,OAAO,CAAC,IAAI;gBACV,IAAI,CAAC,SAAS;oBAAE,OAAO,SAAS,CAAC,uCAAuC,CAAC,CAAC;gBAC1E,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;gBAC5C,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;gBACvB,KAAK,SAAS,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC;gBACxD,OAAO,SAAS,CAAC;YACnB,CAAC;SACF,CAAC;IACJ,CAAC;IAED,OAAO;QACL,MAAM,EAAE,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE;QACnD,KAAK,KAAK,SAAS,GAAG,IAAI,CAAC,CAAC,CAAC;QAC7B,aAAa,KAAK,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC;QACtC,KAAK,CAAC,KAAK;YACT,SAAS,GAAG,KAAK,CAAC;YAClB,MAAM,OAAO,CAAC,UAAU,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;QACzC,CAAC;KACF,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,OAAO,CAAC,UAA0B,EAAE,IAAa;IAC9D,IAAI,CAAC;QACH,OAAO,YAAY,CAAC,MAAM,WAAW,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC,CAAC;IAC3D,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,SAAS,CAAC,KAAK,YAAY,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,yBAAyB,CAAC,CAAC;IAC5F,CAAC;AACH,CAAC;AAED,SAAS,YAAY,CAAC,MAA0B;IAC9C,IAAI,OAAO,MAAM,KAAK,QAAQ;QAAE,OAAO,MAAM,CAAC;IAC9C,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC;AAClE,CAAC;AAED,SAAS,SAAS,CAAC,IAAY;IAC7B,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;AAC9D,CAAC","sourcesContent":["import type { SDKCustomTool, SDKCustomToolResult, SDKJsonValue } from \"@cursor/sdk\";\nimport { AgentError } from \"../errors.js\";\nimport { executeTool, toolJsonSchema } from \"../sdk/tools.js\";\nimport type { ExecutedToolResult } from \"../sdk/tool-result.js\";\nimport type { ToolDefinition } from \"../sdk/types.js\";\nimport type { ExecutionDefinition } from \"./types.js\";\n\nexport type CursorTools = ReturnType<typeof cursorTools>;\n\nexport function cursorTools(agent: Pick<ExecutionDefinition, \"tools\">) {\n const pending = new Set<Promise<unknown>>();\n let accepting = false;\n const entries = Object.entries(agent.tools ?? {});\n const customTools: Record<string, SDKCustomTool> = {};\n\n for (const [name, definition] of entries) {\n const inputSchema = toolJsonSchema(definition) as Record<string, SDKJsonValue>;\n customTools[name] = {\n description: definition.description,\n inputSchema,\n execute(args) {\n if (!accepting) return toolError(\"The task is not accepting tool calls.\");\n const execution = runTool(definition, args);\n pending.add(execution);\n void execution.finally(() => pending.delete(execution));\n return execution;\n },\n };\n }\n\n return {\n config: entries.length === 0 ? {} : { customTools },\n start() { accepting = true; },\n stopAdmission() { accepting = false; },\n async drain() {\n accepting = false;\n await Promise.allSettled([...pending]);\n },\n };\n}\n\nasync function runTool(definition: ToolDefinition, args: unknown): Promise<SDKCustomToolResult> {\n try {\n return nativeResult(await executeTool(definition, args));\n } catch (error) {\n return toolError(error instanceof AgentError ? error.message : \"The custom tool failed.\");\n }\n}\n\nfunction nativeResult(result: ExecutedToolResult): SDKCustomToolResult {\n if (typeof result === \"string\") return result;\n return { content: result.content.map(block => ({ ...block })) };\n}\n\nfunction toolError(text: string): SDKCustomToolResult {\n return { isError: true, content: [{ type: \"text\", text }] };\n}\n"]}
@@ -0,0 +1,6 @@
1
+ import type { AdapterOptions, NativeSession } from "./types.js";
2
+ import { type CursorDependencies } from "./cursor-startup.js";
3
+ export type { CursorDependencies } from "./cursor-startup.js";
4
+ export declare function openCursor(options: AdapterOptions): Promise<NativeSession>;
5
+ /** Dependency injection is internal and replaces only the external SDK boundary in tests. */
6
+ export declare function createCursorOpener(deps: CursorDependencies): (options: AdapterOptions) => Promise<NativeSession>;
@@ -0,0 +1,17 @@
1
+ import { openCursorCli } from "./cursor-cli.js";
2
+ import { createCursorSession } from "./cursor-session.js";
3
+ import { cursorTools } from "./cursor-tools.js";
4
+ import { cursorDependencies, startCursor } from "./cursor-startup.js";
5
+ const openCursorSdk = createCursorOpener(cursorDependencies);
6
+ export async function openCursor(options) {
7
+ return options.access.type === "subscription" ? openCursorCli(options) : openCursorSdk(options);
8
+ }
9
+ /** Dependency injection is internal and replaces only the external SDK boundary in tests. */
10
+ export function createCursorOpener(deps) {
11
+ return async (options) => {
12
+ const tools = cursorTools(options.agent);
13
+ const { native, selected } = await startCursor(options, deps, tools.config);
14
+ return createCursorSession(native, selected, options, tools);
15
+ };
16
+ }
17
+ //# sourceMappingURL=cursor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cursor.js","sourceRoot":"","sources":["../../src/adapters/cursor.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAA2B,MAAM,qBAAqB,CAAC;AAI/F,MAAM,aAAa,GAAG,kBAAkB,CAAC,kBAAkB,CAAC,CAAC;AAE7D,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,OAAuB;IACtD,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,cAAc,CAAC,CAAC,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;AAClG,CAAC;AAED,6FAA6F;AAC7F,MAAM,UAAU,kBAAkB,CAAC,IAAwB;IACzD,OAAO,KAAK,EAAE,OAAuB,EAA0B,EAAE;QAC/D,MAAM,KAAK,GAAG,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACzC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,WAAW,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;QAC5E,OAAO,mBAAmB,CAAC,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;IAC/D,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import type { AdapterOptions, NativeSession } from \"./types.js\";\nimport { openCursorCli } from \"./cursor-cli.js\";\nimport { createCursorSession } from \"./cursor-session.js\";\nimport { cursorTools } from \"./cursor-tools.js\";\nimport { cursorDependencies, startCursor, type CursorDependencies } from \"./cursor-startup.js\";\n\nexport type { CursorDependencies } from \"./cursor-startup.js\";\n\nconst openCursorSdk = createCursorOpener(cursorDependencies);\n\nexport async function openCursor(options: AdapterOptions): Promise<NativeSession> {\n return options.access.type === \"subscription\" ? openCursorCli(options) : openCursorSdk(options);\n}\n\n/** Dependency injection is internal and replaces only the external SDK boundary in tests. */\nexport function createCursorOpener(deps: CursorDependencies) {\n return async (options: AdapterOptions): Promise<NativeSession> => {\n const tools = cursorTools(options.agent);\n const { native, selected } = await startCursor(options, deps, tools.config);\n return createCursorSession(native, selected, options, tools);\n };\n}\n"]}
@@ -1,4 +1,14 @@
1
1
  import type { AdapterOptions } from "./types.js";
2
- export declare function fxEnvironment(options: AdapterOptions): NodeJS.ProcessEnv;
3
- export declare function verifyFxAccess(cwd: string, env: NodeJS.ProcessEnv, accessType: string): Promise<void>;
2
+ export interface FxAccessRoute {
3
+ provider: string;
4
+ auth: string;
5
+ expanded: boolean;
6
+ modelSource?: string;
7
+ endpoint?: string;
8
+ keySlot?: string;
9
+ settingsFingerprint?: string;
10
+ }
11
+ export declare function fxAccessRoute(options: AdapterOptions): Promise<FxAccessRoute>;
12
+ export declare function fxEnvironment(options: AdapterOptions, route: FxAccessRoute): NodeJS.ProcessEnv;
13
+ export declare function verifyFxAccess(cwd: string, env: NodeJS.ProcessEnv, route: FxAccessRoute, requestedModel?: string): Promise<void>;
4
14
  export declare function fxSettingsFingerprint(env: NodeJS.ProcessEnv): Promise<string>;
@@ -1,38 +1,62 @@
1
- import { spawn } from "node:child_process";
2
1
  import { createHash } from "node:crypto";
3
2
  import { readFile } from "node:fs/promises";
4
3
  import { homedir } from "node:os";
5
4
  import { join } from "node:path";
6
5
  import { AgentError } from "../errors.js";
6
+ import { fxCustomConnection, readFxProfile } from "./fx-profile.js";
7
+ import { captureFxStatus } from "./fx-status.js";
8
+ export async function fxAccessRoute(options) {
9
+ const { access } = options;
10
+ if (access.type === "vercel-api-key" || access.type === "vercel-oidc") {
11
+ return { provider: "gateway", auth: access.type === "vercel-api-key" ? "AI_GATEWAY_API_KEY" : "VERCEL_OIDC_TOKEN", expanded: false };
12
+ }
13
+ if (access.type === "subscription" && ["gateway", "codex", "grok"].includes(access.provider ?? "")) {
14
+ const { settings, fingerprint } = await readFxProfile(options.env);
15
+ if (access.provider === "gateway") {
16
+ if (settings.credential_source !== "fx_login")
17
+ throw new AgentError("ACCESS_UNAVAILABLE", "fx saved Gateway login requires the native credential_source preference to select fx_login explicitly.");
18
+ return { provider: "gateway", auth: "fx login", expanded: true, settingsFingerprint: fingerprint };
19
+ }
20
+ const auth = access.provider === "codex" ? "Codex subscription" : "Grok subscription";
21
+ return { provider: access.provider, auth, modelSource: auth, expanded: true, settingsFingerprint: fingerprint };
22
+ }
23
+ if (access.type === "api-key" && access.provider) {
24
+ const { settings, fingerprint } = await readFxProfile(options.env);
25
+ return { provider: access.provider, auth: "configured provider", modelSource: access.provider, expanded: true,
26
+ settingsFingerprint: fingerprint, ...fxCustomConnection(settings, access.provider) };
27
+ }
28
+ throw new AgentError("UNSUPPORTED_OPTION", "fx requires a supported explicit access provider.");
29
+ }
7
30
  const unsafeEnvironment = [
8
31
  "FX_AUTH_MODE", "FX_GATEWAY_CHAT_URL", "FX_GATEWAY_BASE_URL", "FX_E2E_GATEWAY_CHAT_URL",
9
32
  "FX_E2E_GATEWAY_CREDITS_URL", "FX_E2E_GATEWAY_MODELS_URL", "FX_DEBUG_RECORD",
10
33
  "FX_DEBUG_RECORD_SILENT_BANNER", "FX_RECORD", "FX_RECORD_INPUT", "FX_TRACE", "FX_TRACE_LOG",
11
34
  "FX_TRACE_SCOPES", "FX_TRACE_STDERR", "FX_UI_OBSERVE_DIR",
12
35
  ];
13
- export function fxEnvironment(options) {
14
- if (options.access.type !== "vercel-api-key" && options.access.type !== "vercel-oidc") {
15
- throw new AgentError("UNSUPPORTED_OPTION", "fx supports only explicit Vercel AI Gateway API key or OIDC access.");
16
- }
17
- if (!options.access.token)
36
+ export function fxEnvironment(options, route) {
37
+ if (options.access.type !== "subscription" && !options.access.token)
18
38
  throw new AgentError("ACCESS_UNAVAILABLE", "The selected fx connection has no credential.");
19
39
  const env = { ...options.env };
20
40
  delete env.AI_GATEWAY_API_KEY;
21
41
  delete env.VERCEL_OIDC_TOKEN;
22
42
  for (const name of unsafeEnvironment)
23
43
  delete env[name];
24
- env.FX_PROVIDER = "gateway";
44
+ for (const name of Object.keys(env))
45
+ if (/^FX_(?:E2E_|TRACE|RECORD|DEBUG_RECORD)/u.test(name))
46
+ delete env[name];
47
+ env.FX_PROVIDER = route.provider;
25
48
  if (options.harness.model)
26
49
  env.FX_MODEL = options.harness.model;
27
50
  if (options.harness.kind === "fx" && options.harness.permissionMode !== undefined) {
28
51
  env.FX_PERMISSION_MODE = options.harness.permissionMode;
29
52
  }
30
- env[options.access.type === "vercel-api-key" ? "AI_GATEWAY_API_KEY" : "VERCEL_OIDC_TOKEN"] = options.access.token;
53
+ if (options.access.type !== "subscription")
54
+ env[route.keySlot ?? route.auth] = options.access.token;
31
55
  return env;
32
56
  }
33
- export async function verifyFxAccess(cwd, env, accessType) {
34
- const expected = accessType === "vercel-api-key" ? "AI_GATEWAY_API_KEY" : "VERCEL_OIDC_TOKEN";
35
- const stdout = await captureStatus(cwd, env);
57
+ export async function verifyFxAccess(cwd, env, route, requestedModel) {
58
+ const expected = route.auth;
59
+ const stdout = await captureFxStatus(cwd, env);
36
60
  let status;
37
61
  try {
38
62
  status = JSON.parse(stdout);
@@ -48,61 +72,27 @@ export async function verifyFxAccess(cwd, env, accessType) {
48
72
  throw new AgentError("PROTOCOL_ERROR", "fx returned an unrecognized credential source.");
49
73
  }
50
74
  if (actual !== expected) {
51
- throw new AgentError("ACCESS_UNAVAILABLE", `fx is not using ${expected}. Select the matching environment source in fx before starting this session.`);
75
+ throw new AgentError("ACCESS_UNAVAILABLE", "fx is not using the selected credential source. Select the matching source in fx before starting this session.");
76
+ }
77
+ if (route.expanded) {
78
+ const value = status;
79
+ if (typeof value.model !== "string" || !value.model.trim() || typeof value.auth_refreshable !== "boolean"
80
+ || (route.modelSource !== undefined && typeof value.model_source !== "string")
81
+ || (route.endpoint !== undefined && typeof value.provider_endpoint !== "string")
82
+ || (value.auth_expired !== undefined && typeof value.auth_expired !== "boolean")) {
83
+ throw new AgentError("PROTOCOL_ERROR", "fx did not expose compatible native access metadata. Use fx 0.0.11 or a compatible release.");
84
+ }
85
+ if (value.model_source !== route.modelSource || value.provider_endpoint !== route.endpoint
86
+ || value.auth_refreshable !== (route.keySlot === undefined)
87
+ || (requestedModel !== undefined && value.model !== requestedModel)) {
88
+ throw new AgentError("INVALID_CONFIG", "fx native status differs from the selected provider, endpoint, or model.");
89
+ }
52
90
  }
53
91
  }
54
92
  function knownAuthSource(value) {
55
93
  return value === "missing" || value === "AI_GATEWAY_API_KEY" || value === "VERCEL_OIDC_TOKEN"
56
94
  || value === "fx login" || value === "Codex subscription" || value === "Grok subscription"
57
- || value === "host managed" || /^stored API key \([^)]+\)$/u.test(value);
58
- }
59
- async function captureStatus(cwd, env) {
60
- return await new Promise((resolve, reject) => {
61
- const child = (() => {
62
- try {
63
- return spawn("fx", ["status", "--json"], { cwd, env, stdio: ["ignore", "pipe", "pipe"] });
64
- }
65
- catch {
66
- reject(new AgentError("INVALID_CONFIG", "fx credential-source verification could not start with the selected process configuration."));
67
- return undefined;
68
- }
69
- })();
70
- if (!child)
71
- return;
72
- let output = "";
73
- let settled = false;
74
- const finish = (error) => {
75
- if (settled)
76
- return;
77
- settled = true;
78
- clearTimeout(timer);
79
- if (error)
80
- reject(error);
81
- else
82
- resolve(output);
83
- };
84
- const timer = setTimeout(() => {
85
- child.kill("SIGKILL");
86
- finish(new AgentError("HARNESS_UNAVAILABLE", "fx credential-source verification did not finish."));
87
- }, 2_000);
88
- timer.unref();
89
- child.stdout.setEncoding("utf8");
90
- child.stdout.on("data", chunk => {
91
- output += chunk;
92
- if (output.length > 1024 * 1024)
93
- child.kill("SIGKILL");
94
- });
95
- child.stderr.resume();
96
- child.on("error", () => finish(new AgentError("HARNESS_UNAVAILABLE", "Cannot start fx. Install fx 0.0.9 or a compatible release and make it available on PATH.")));
97
- child.on("close", code => {
98
- if (output.length > 1024 * 1024)
99
- finish(new AgentError("PROTOCOL_ERROR", "fx returned oversized credential-source status."));
100
- else if (code !== 0)
101
- finish(new AgentError("ACCESS_UNAVAILABLE", "fx could not verify the selected Gateway credential source."));
102
- else
103
- finish();
104
- });
105
- });
95
+ || value === "host managed" || value === "configured provider" || /^stored API key \([^)]+\)$/u.test(value);
106
96
  }
107
97
  export async function fxSettingsFingerprint(env) {
108
98
  const path = join(env.HOME || homedir(), ".fx", "settings.json");
@@ -1 +1 @@
1
- {"version":3,"file":"fx-auth.js","sourceRoot":"","sources":["../../src/adapters/fx-auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAG1C,MAAM,iBAAiB,GAAG;IACxB,cAAc,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,yBAAyB;IACvF,4BAA4B,EAAE,2BAA2B,EAAE,iBAAiB;IAC5E,+BAA+B,EAAE,WAAW,EAAE,iBAAiB,EAAE,UAAU,EAAE,cAAc;IAC3F,iBAAiB,EAAE,iBAAiB,EAAE,mBAAmB;CACjD,CAAC;AAEX,MAAM,UAAU,aAAa,CAAC,OAAuB;IACnD,IAAI,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,gBAAgB,IAAI,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;QACtF,MAAM,IAAI,UAAU,CAAC,oBAAoB,EAAE,qEAAqE,CAAC,CAAC;IACpH,CAAC;IACD,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK;QAAE,MAAM,IAAI,UAAU,CAAC,oBAAoB,EAAE,+CAA+C,CAAC,CAAC;IACvH,MAAM,GAAG,GAAG,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAC/B,OAAO,GAAG,CAAC,kBAAkB,CAAC;IAC9B,OAAO,GAAG,CAAC,iBAAiB,CAAC;IAC7B,KAAK,MAAM,IAAI,IAAI,iBAAiB;QAAE,OAAO,GAAG,CAAC,IAAI,CAAC,CAAC;IACvD,GAAG,CAAC,WAAW,GAAG,SAAS,CAAC;IAC5B,IAAI,OAAO,CAAC,OAAO,CAAC,KAAK;QAAE,GAAG,CAAC,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC;IAChE,IAAI,OAAO,CAAC,OAAO,CAAC,IAAI,KAAK,IAAI,IAAI,OAAO,CAAC,OAAO,CAAC,cAAc,KAAK,SAAS,EAAE,CAAC;QAClF,GAAG,CAAC,kBAAkB,GAAG,OAAO,CAAC,OAAO,CAAC,cAAc,CAAC;IAC1D,CAAC;IACD,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,gBAAgB,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,mBAAmB,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC;IAClH,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,GAAW,EAAE,GAAsB,EAAE,UAAkB;IAC1F,MAAM,QAAQ,GAAG,UAAU,KAAK,gBAAgB,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,mBAAmB,CAAC;IAC9F,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAC7C,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QAAC,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC;QAAC,MAAM,IAAI,UAAU,CAAC,gBAAgB,EAAE,iDAAiD,CAAC,CAAC;IAAC,CAAC;IACzI,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAK,MAAc,CAAC,IAAI,KAAK,QAAQ,IAAI,OAAQ,MAAc,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QACpJ,MAAM,IAAI,UAAU,CAAC,gBAAgB,EAAE,iDAAiD,CAAC,CAAC;IAC5F,CAAC;IACD,MAAM,MAAM,GAAI,MAAc,CAAC,IAAI,CAAC;IACpC,IAAI,MAAM,KAAK,QAAQ,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,EAAE,CAAC;QACpD,MAAM,IAAI,UAAU,CAAC,gBAAgB,EAAE,gDAAgD,CAAC,CAAC;IAC3F,CAAC;IACD,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;QACxB,MAAM,IAAI,UAAU,CAAC,oBAAoB,EAAE,mBAAmB,QAAQ,8EAA8E,CAAC,CAAC;IACxJ,CAAC;AACH,CAAC;AAED,SAAS,eAAe,CAAC,KAAa;IACpC,OAAO,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,oBAAoB,IAAI,KAAK,KAAK,mBAAmB;WACxF,KAAK,KAAK,UAAU,IAAI,KAAK,KAAK,oBAAoB,IAAI,KAAK,KAAK,mBAAmB;WACvF,KAAK,KAAK,cAAc,IAAI,6BAA6B,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAC7E,CAAC;AAED,KAAK,UAAU,aAAa,CAAC,GAAW,EAAE,GAAsB;IAC9D,OAAO,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC3C,MAAM,KAAK,GAAG,CAAC,GAAG,EAAE;YAClB,IAAI,CAAC;gBAAC,OAAO,KAAK,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;YAAC,CAAC;YAClG,MAAM,CAAC;gBACL,MAAM,CAAC,IAAI,UAAU,CAAC,gBAAgB,EAAE,4FAA4F,CAAC,CAAC,CAAC;gBACvI,OAAO,SAAS,CAAC;YACnB,CAAC;QACH,CAAC,CAAC,EAAE,CAAC;QACL,IAAI,CAAC,KAAK;YAAE,OAAO;QACnB,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,IAAI,OAAO,GAAG,KAAK,CAAC;QACpB,MAAM,MAAM,GAAG,CAAC,KAAkB,EAAE,EAAE;YACpC,IAAI,OAAO;gBAAE,OAAO;YACpB,OAAO,GAAG,IAAI,CAAC;YACf,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,IAAI,KAAK;gBAAE,MAAM,CAAC,KAAK,CAAC,CAAC;;gBAAM,OAAO,CAAC,MAAM,CAAC,CAAC;QACjD,CAAC,CAAC;QACF,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;YAC5B,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACtB,MAAM,CAAC,IAAI,UAAU,CAAC,qBAAqB,EAAE,mDAAmD,CAAC,CAAC,CAAC;QACrG,CAAC,EAAE,KAAK,CAAC,CAAC;QACV,KAAK,CAAC,KAAK,EAAE,CAAC;QACd,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QACjC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE;YAC9B,MAAM,IAAI,KAAK,CAAC;YAChB,IAAI,MAAM,CAAC,MAAM,GAAG,IAAI,GAAG,IAAI;gBAAE,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACzD,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;QACtB,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,UAAU,CAAC,qBAAqB,EAAE,0FAA0F,CAAC,CAAC,CAAC,CAAC;QACnK,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE;YACvB,IAAI,MAAM,CAAC,MAAM,GAAG,IAAI,GAAG,IAAI;gBAAE,MAAM,CAAC,IAAI,UAAU,CAAC,gBAAgB,EAAE,iDAAiD,CAAC,CAAC,CAAC;iBACxH,IAAI,IAAI,KAAK,CAAC;gBAAE,MAAM,CAAC,IAAI,UAAU,CAAC,oBAAoB,EAAE,6DAA6D,CAAC,CAAC,CAAC;;gBAC5H,MAAM,EAAE,CAAC;QAChB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,GAAsB;IAChE,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,OAAO,EAAE,EAAE,KAAK,EAAE,eAAe,CAAC,CAAC;IACjE,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,CAAC;QAClC,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACzD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,SAAS,CAAC;QACzE,MAAM,IAAI,UAAU,CAAC,gBAAgB,EAAE,2CAA2C,CAAC,CAAC;IACtF,CAAC;AACH,CAAC","sourcesContent":["import { spawn } from \"node:child_process\";\nimport { createHash } from \"node:crypto\";\nimport { readFile } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { AgentError } from \"../errors.js\";\nimport type { AdapterOptions } from \"./types.js\";\n\nconst unsafeEnvironment = [\n \"FX_AUTH_MODE\", \"FX_GATEWAY_CHAT_URL\", \"FX_GATEWAY_BASE_URL\", \"FX_E2E_GATEWAY_CHAT_URL\",\n \"FX_E2E_GATEWAY_CREDITS_URL\", \"FX_E2E_GATEWAY_MODELS_URL\", \"FX_DEBUG_RECORD\",\n \"FX_DEBUG_RECORD_SILENT_BANNER\", \"FX_RECORD\", \"FX_RECORD_INPUT\", \"FX_TRACE\", \"FX_TRACE_LOG\",\n \"FX_TRACE_SCOPES\", \"FX_TRACE_STDERR\", \"FX_UI_OBSERVE_DIR\",\n] as const;\n\nexport function fxEnvironment(options: AdapterOptions): NodeJS.ProcessEnv {\n if (options.access.type !== \"vercel-api-key\" && options.access.type !== \"vercel-oidc\") {\n throw new AgentError(\"UNSUPPORTED_OPTION\", \"fx supports only explicit Vercel AI Gateway API key or OIDC access.\");\n }\n if (!options.access.token) throw new AgentError(\"ACCESS_UNAVAILABLE\", \"The selected fx connection has no credential.\");\n const env = { ...options.env };\n delete env.AI_GATEWAY_API_KEY;\n delete env.VERCEL_OIDC_TOKEN;\n for (const name of unsafeEnvironment) delete env[name];\n env.FX_PROVIDER = \"gateway\";\n if (options.harness.model) env.FX_MODEL = options.harness.model;\n if (options.harness.kind === \"fx\" && options.harness.permissionMode !== undefined) {\n env.FX_PERMISSION_MODE = options.harness.permissionMode;\n }\n env[options.access.type === \"vercel-api-key\" ? \"AI_GATEWAY_API_KEY\" : \"VERCEL_OIDC_TOKEN\"] = options.access.token;\n return env;\n}\n\nexport async function verifyFxAccess(cwd: string, env: NodeJS.ProcessEnv, accessType: string): Promise<void> {\n const expected = accessType === \"vercel-api-key\" ? \"AI_GATEWAY_API_KEY\" : \"VERCEL_OIDC_TOKEN\";\n const stdout = await captureStatus(cwd, env);\n let status: unknown;\n try { status = JSON.parse(stdout); } catch { throw new AgentError(\"PROTOCOL_ERROR\", \"fx returned malformed credential-source status.\"); }\n if (!status || typeof status !== \"object\" || Array.isArray(status) || (status as any).kind !== \"status\" || typeof (status as any).auth !== \"string\") {\n throw new AgentError(\"PROTOCOL_ERROR\", \"fx returned malformed credential-source status.\");\n }\n const actual = (status as any).auth;\n if (actual !== expected && !knownAuthSource(actual)) {\n throw new AgentError(\"PROTOCOL_ERROR\", \"fx returned an unrecognized credential source.\");\n }\n if (actual !== expected) {\n throw new AgentError(\"ACCESS_UNAVAILABLE\", `fx is not using ${expected}. Select the matching environment source in fx before starting this session.`);\n }\n}\n\nfunction knownAuthSource(value: string): boolean {\n return value === \"missing\" || value === \"AI_GATEWAY_API_KEY\" || value === \"VERCEL_OIDC_TOKEN\"\n || value === \"fx login\" || value === \"Codex subscription\" || value === \"Grok subscription\"\n || value === \"host managed\" || /^stored API key \\([^)]+\\)$/u.test(value);\n}\n\nasync function captureStatus(cwd: string, env: NodeJS.ProcessEnv): Promise<string> {\n return await new Promise((resolve, reject) => {\n const child = (() => {\n try { return spawn(\"fx\", [\"status\", \"--json\"], { cwd, env, stdio: [\"ignore\", \"pipe\", \"pipe\"] }); }\n catch {\n reject(new AgentError(\"INVALID_CONFIG\", \"fx credential-source verification could not start with the selected process configuration.\"));\n return undefined;\n }\n })();\n if (!child) return;\n let output = \"\";\n let settled = false;\n const finish = (error?: AgentError) => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n if (error) reject(error); else resolve(output);\n };\n const timer = setTimeout(() => {\n child.kill(\"SIGKILL\");\n finish(new AgentError(\"HARNESS_UNAVAILABLE\", \"fx credential-source verification did not finish.\"));\n }, 2_000);\n timer.unref();\n child.stdout.setEncoding(\"utf8\");\n child.stdout.on(\"data\", chunk => {\n output += chunk;\n if (output.length > 1024 * 1024) child.kill(\"SIGKILL\");\n });\n child.stderr.resume();\n child.on(\"error\", () => finish(new AgentError(\"HARNESS_UNAVAILABLE\", \"Cannot start fx. Install fx 0.0.9 or a compatible release and make it available on PATH.\")));\n child.on(\"close\", code => {\n if (output.length > 1024 * 1024) finish(new AgentError(\"PROTOCOL_ERROR\", \"fx returned oversized credential-source status.\"));\n else if (code !== 0) finish(new AgentError(\"ACCESS_UNAVAILABLE\", \"fx could not verify the selected Gateway credential source.\"));\n else finish();\n });\n });\n}\n\nexport async function fxSettingsFingerprint(env: NodeJS.ProcessEnv): Promise<string> {\n const path = join(env.HOME || homedir(), \".fx\", \"settings.json\");\n try {\n const data = await readFile(path);\n return createHash(\"sha256\").update(data).digest(\"hex\");\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return \"missing\";\n throw new AgentError(\"INVALID_CONFIG\", \"fx native settings could not be verified.\");\n }\n}\n"]}
1
+ {"version":3,"file":"fx-auth.js","sourceRoot":"","sources":["../../src/adapters/fx-auth.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash } from \"node:crypto\";\nimport { readFile } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { AgentError } from \"../errors.js\";\nimport type { AdapterOptions } from \"./types.js\";\nimport { fxCustomConnection, readFxProfile } from \"./fx-profile.js\";\nimport { captureFxStatus } from \"./fx-status.js\";\n\nexport interface FxAccessRoute {\n provider: string;\n auth: string;\n expanded: boolean;\n modelSource?: string;\n endpoint?: string;\n keySlot?: string;\n settingsFingerprint?: string;\n}\n\nexport async function fxAccessRoute(options: AdapterOptions): Promise<FxAccessRoute> {\n const { access } = options;\n if (access.type === \"vercel-api-key\" || access.type === \"vercel-oidc\") {\n return { provider: \"gateway\", auth: access.type === \"vercel-api-key\" ? \"AI_GATEWAY_API_KEY\" : \"VERCEL_OIDC_TOKEN\", expanded: false };\n }\n if (access.type === \"subscription\" && [\"gateway\", \"codex\", \"grok\"].includes(access.provider ?? \"\")) {\n const { settings, fingerprint } = await readFxProfile(options.env);\n if (access.provider === \"gateway\") {\n if (settings.credential_source !== \"fx_login\") throw new AgentError(\"ACCESS_UNAVAILABLE\", \"fx saved Gateway login requires the native credential_source preference to select fx_login explicitly.\");\n return { provider: \"gateway\", auth: \"fx login\", expanded: true, settingsFingerprint: fingerprint };\n }\n const auth = access.provider === \"codex\" ? \"Codex subscription\" : \"Grok subscription\";\n return { provider: access.provider!, auth, modelSource: auth, expanded: true, settingsFingerprint: fingerprint };\n }\n if (access.type === \"api-key\" && access.provider) {\n const { settings, fingerprint } = await readFxProfile(options.env);\n return { provider: access.provider, auth: \"configured provider\", modelSource: access.provider, expanded: true,\n settingsFingerprint: fingerprint, ...fxCustomConnection(settings, access.provider) };\n }\n throw new AgentError(\"UNSUPPORTED_OPTION\", \"fx requires a supported explicit access provider.\");\n}\n\nconst unsafeEnvironment = [\n \"FX_AUTH_MODE\", \"FX_GATEWAY_CHAT_URL\", \"FX_GATEWAY_BASE_URL\", \"FX_E2E_GATEWAY_CHAT_URL\",\n \"FX_E2E_GATEWAY_CREDITS_URL\", \"FX_E2E_GATEWAY_MODELS_URL\", \"FX_DEBUG_RECORD\",\n \"FX_DEBUG_RECORD_SILENT_BANNER\", \"FX_RECORD\", \"FX_RECORD_INPUT\", \"FX_TRACE\", \"FX_TRACE_LOG\",\n \"FX_TRACE_SCOPES\", \"FX_TRACE_STDERR\", \"FX_UI_OBSERVE_DIR\",\n] as const;\n\nexport function fxEnvironment(options: AdapterOptions, route: FxAccessRoute): NodeJS.ProcessEnv {\n if (options.access.type !== \"subscription\" && !options.access.token) throw new AgentError(\"ACCESS_UNAVAILABLE\", \"The selected fx connection has no credential.\");\n const env = { ...options.env };\n delete env.AI_GATEWAY_API_KEY;\n delete env.VERCEL_OIDC_TOKEN;\n for (const name of unsafeEnvironment) delete env[name];\n for (const name of Object.keys(env)) if (/^FX_(?:E2E_|TRACE|RECORD|DEBUG_RECORD)/u.test(name)) delete env[name];\n env.FX_PROVIDER = route.provider;\n if (options.harness.model) env.FX_MODEL = options.harness.model;\n if (options.harness.kind === \"fx\" && options.harness.permissionMode !== undefined) {\n env.FX_PERMISSION_MODE = options.harness.permissionMode;\n }\n if (options.access.type !== \"subscription\") env[route.keySlot ?? route.auth] = options.access.token;\n return env;\n}\n\nexport async function verifyFxAccess(cwd: string, env: NodeJS.ProcessEnv, route: FxAccessRoute, requestedModel?: string): Promise<void> {\n const expected = route.auth;\n const stdout = await captureFxStatus(cwd, env);\n let status: unknown;\n try { status = JSON.parse(stdout); } catch { throw new AgentError(\"PROTOCOL_ERROR\", \"fx returned malformed credential-source status.\"); }\n if (!status || typeof status !== \"object\" || Array.isArray(status) || (status as any).kind !== \"status\" || typeof (status as any).auth !== \"string\") {\n throw new AgentError(\"PROTOCOL_ERROR\", \"fx returned malformed credential-source status.\");\n }\n const actual = (status as any).auth;\n if (actual !== expected && !knownAuthSource(actual)) {\n throw new AgentError(\"PROTOCOL_ERROR\", \"fx returned an unrecognized credential source.\");\n }\n if (actual !== expected) {\n throw new AgentError(\"ACCESS_UNAVAILABLE\", \"fx is not using the selected credential source. Select the matching source in fx before starting this session.\");\n }\n if (route.expanded) {\n const value = status as Record<string, unknown>;\n if (typeof value.model !== \"string\" || !value.model.trim() || typeof value.auth_refreshable !== \"boolean\"\n || (route.modelSource !== undefined && typeof value.model_source !== \"string\")\n || (route.endpoint !== undefined && typeof value.provider_endpoint !== \"string\")\n || (value.auth_expired !== undefined && typeof value.auth_expired !== \"boolean\")) {\n throw new AgentError(\"PROTOCOL_ERROR\", \"fx did not expose compatible native access metadata. Use fx 0.0.11 or a compatible release.\");\n }\n if (value.model_source !== route.modelSource || value.provider_endpoint !== route.endpoint\n || value.auth_refreshable !== (route.keySlot === undefined)\n || (requestedModel !== undefined && value.model !== requestedModel)) {\n throw new AgentError(\"INVALID_CONFIG\", \"fx native status differs from the selected provider, endpoint, or model.\");\n }\n }\n}\n\nfunction knownAuthSource(value: string): boolean {\n return value === \"missing\" || value === \"AI_GATEWAY_API_KEY\" || value === \"VERCEL_OIDC_TOKEN\"\n || value === \"fx login\" || value === \"Codex subscription\" || value === \"Grok subscription\"\n || value === \"host managed\" || value === \"configured provider\" || /^stored API key \\([^)]+\\)$/u.test(value);\n}\n\nexport async function fxSettingsFingerprint(env: NodeJS.ProcessEnv): Promise<string> {\n const path = join(env.HOME || homedir(), \".fx\", \"settings.json\");\n try {\n const data = await readFile(path);\n return createHash(\"sha256\").update(data).digest(\"hex\");\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return \"missing\";\n throw new AgentError(\"INVALID_CONFIG\", \"fx native settings could not be verified.\");\n }\n}\n"]}
@@ -0,0 +1,8 @@
1
+ export declare function fxCustomConnection(settings: Record<string, unknown>, provider: string): {
2
+ endpoint: string;
3
+ keySlot: string;
4
+ };
5
+ export declare function readFxProfile(env: NodeJS.ProcessEnv): Promise<{
6
+ settings: Record<string, unknown>;
7
+ fingerprint: string;
8
+ }>;
@@ -0,0 +1,101 @@
1
+ import { constants } from "node:fs";
2
+ import { open } from "node:fs/promises";
3
+ import { createHash } from "node:crypto";
4
+ import { homedir } from "node:os";
5
+ import { join } from "node:path";
6
+ import { AgentError } from "../errors.js";
7
+ const profileLimit = 1024 * 1024;
8
+ function record(value) {
9
+ return value !== null && typeof value === "object" && !Array.isArray(value);
10
+ }
11
+ export function fxCustomConnection(settings, provider) {
12
+ if (!/^[A-Za-z][A-Za-z0-9_-]{0,63}$/u.test(provider) || ["gateway", "codex", "grok"].includes(provider.toLowerCase())) {
13
+ throw new AgentError("INVALID_CONFIG", "fx direct API keys require a valid native custom connection name.");
14
+ }
15
+ const definitions = settings.providers;
16
+ const selected = record(definitions) && Object.hasOwn(definitions, provider) ? definitions[provider] : undefined;
17
+ if (!record(selected))
18
+ throw new AgentError("INVALID_CONFIG", "The selected fx custom connection is not configured in the native profile.");
19
+ if (selected.protocol !== "openai-chat-completions" || !record(selected.auth) || selected.auth.type !== "bearer") {
20
+ throw new AgentError("UNSUPPORTED_OPTION", "fx direct API keys require a native Chat Completions connection with bearer environment authentication.");
21
+ }
22
+ const slot = selected.auth.env;
23
+ if (typeof slot !== "string" || !/^[A-Za-z_][A-Za-z0-9_]{0,127}$/u.test(slot) || unsafeCredentialSlot(slot)) {
24
+ throw new AgentError("INVALID_CONFIG", "The fx custom connection credential slot cannot control the process, routing, or diagnostics.");
25
+ }
26
+ const raw = selected.base_url;
27
+ try {
28
+ if (typeof raw !== "string" || raw.length > 2048 || /[^\x21-\x7e]|[\\?#]/u.test(raw) || !/^https?:\/\//iu.test(raw)
29
+ || /^https?:\/\/[^/]*@/iu.test(raw))
30
+ throw new Error();
31
+ const url = new URL(raw);
32
+ if (!url.hostname || url.username || url.password || url.port === "0"
33
+ || (url.protocol === "http:" && !["localhost", "127.0.0.1", "[::1]"].includes(url.hostname)))
34
+ throw new Error();
35
+ return { endpoint: raw.endsWith("/") ? raw.slice(0, -1) : raw, keySlot: slot };
36
+ }
37
+ catch {
38
+ throw new AgentError("INVALID_CONFIG", "The fx custom connection requires a valid HTTPS or loopback HTTP endpoint without credentials, query, or fragment.");
39
+ }
40
+ }
41
+ function unsafeCredentialSlot(slot) {
42
+ const upper = slot.toUpperCase();
43
+ return ["HOME", "PATH", "SHELL", "ENV", "BASH_ENV", "ZDOTDIR", "PWD", "OLDPWD", "USER", "LOGNAME", "TMPDIR", "TMP", "TEMP",
44
+ "AI_GATEWAY_API_KEY", "VERCEL_OIDC_TOKEN", "HTTP_PROXY", "HTTPS_PROXY", "ALL_PROXY", "NO_PROXY"].includes(upper)
45
+ || /^(?:FX_|NODE_|LD_|DYLD_|XDG_|SSL_|OPENSSL_|SUBHARNESS_)/u.test(upper);
46
+ }
47
+ export async function readFxProfile(env) {
48
+ let file;
49
+ try {
50
+ file = await open(join(env.HOME || homedir(), ".fx/settings.json"), constants.O_RDONLY | constants.O_NONBLOCK | (constants.O_NOFOLLOW ?? 0));
51
+ const stat = await file.stat();
52
+ if (!stat.isFile() || stat.size > profileLimit)
53
+ throw new Error("Invalid profile size or type");
54
+ const buffer = Buffer.alloc(profileLimit + 1);
55
+ let length = 0;
56
+ while (length < buffer.length) {
57
+ const { bytesRead } = await file.read(buffer, length, buffer.length - length, length);
58
+ if (!bytesRead)
59
+ break;
60
+ length += bytesRead;
61
+ }
62
+ if (length > profileLimit)
63
+ throw new Error("Profile exceeds limit");
64
+ const bytes = buffer.subarray(0, length);
65
+ const text = new TextDecoder("utf-8", { fatal: true }).decode(bytes);
66
+ const settings = JSON.parse(text);
67
+ rejectDuplicateKeys(text);
68
+ if (!settings || typeof settings !== "object" || Array.isArray(settings))
69
+ throw new Error("Invalid profile shape");
70
+ return { settings: settings, fingerprint: createHash("sha256").update(bytes).digest("hex") };
71
+ }
72
+ catch (error) {
73
+ if (error.code === "ENOENT")
74
+ return { settings: {}, fingerprint: "missing" };
75
+ throw new AgentError("INVALID_CONFIG", "fx native settings must be a valid bounded JSON object in a regular profile file.");
76
+ }
77
+ finally {
78
+ await file?.close();
79
+ }
80
+ }
81
+ /** JSON.parse validates syntax first; this scan retains duplicate-key evidence. */
82
+ function rejectDuplicateKeys(text) {
83
+ const containers = [];
84
+ for (const match of text.matchAll(/"(?:\\.|[^"\\])*"|[{}\[\]]/gu)) {
85
+ const token = match[0];
86
+ if (token === "{")
87
+ containers.push(new Set());
88
+ else if (token === "[")
89
+ containers.push(undefined);
90
+ else if (token === "}" || token === "]")
91
+ containers.pop();
92
+ else if (/^\s*:/u.test(text.slice(match.index + token.length))) {
93
+ const keys = containers.at(-1);
94
+ const key = JSON.parse(token);
95
+ if (keys.has(key))
96
+ throw new Error("Duplicate native profile key");
97
+ keys.add(key);
98
+ }
99
+ }
100
+ }
101
+ //# sourceMappingURL=fx-profile.js.map