api.ts 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. import { Context } from "effect"
  2. import { HttpApi, HttpApiGroup, HttpApiMiddleware, OpenApi } from "effect/unstable/httpapi"
  3. import { SchemaErrorMiddleware } from "./middleware/schema-error.js"
  4. import { GenerateGroup } from "./groups/generate.js"
  5. import { MessageGroup } from "./groups/message.js"
  6. import { ModelGroup } from "./groups/model.js"
  7. import { ProviderGroup } from "./groups/provider.js"
  8. import { makeSessionGroup } from "./groups/session.js"
  9. import { makePermissionGroup } from "./groups/permission.js"
  10. import { FileSystemGroup } from "./groups/fs.js"
  11. import { makeFormGroup } from "./groups/form.js"
  12. import { CommandGroup } from "./groups/command.js"
  13. import { SkillGroup } from "./groups/skill.js"
  14. import { EventGroup, makeEventGroup } from "./groups/event.js"
  15. import type { Definition } from "@opencode-ai/schema/event"
  16. import { AgentGroup } from "./groups/agent.js"
  17. import { PluginGroup } from "./groups/plugin.js"
  18. import { HealthGroup } from "./groups/health.js"
  19. import { ServerGroup } from "./groups/server.js"
  20. import { DebugGroup } from "./groups/debug.js"
  21. import { PtyGroup } from "./groups/pty.js"
  22. import { ShellGroup } from "./groups/shell.js"
  23. import { makeQuestionGroup } from "./groups/question.js"
  24. import { ReferenceGroup } from "./groups/reference.js"
  25. import { Authorization } from "./middleware/authorization.js"
  26. import { LocationGroup } from "./groups/location.js"
  27. import { IntegrationGroup } from "./groups/integration.js"
  28. import { McpGroup } from "./groups/mcp.js"
  29. import { CredentialGroup } from "./groups/credential.js"
  30. import { ProjectGroup } from "./groups/project.js"
  31. import { ProjectCopyGroup } from "./groups/project-copy.js"
  32. import { VcsGroup } from "./groups/vcs.js"
  33. type LocationGroups<LocationId extends HttpApiMiddleware.AnyId> =
  34. | HttpApiGroup.AddMiddleware<typeof LocationGroup, LocationId>
  35. | HttpApiGroup.AddMiddleware<typeof AgentGroup, LocationId>
  36. | HttpApiGroup.AddMiddleware<typeof PluginGroup, LocationId>
  37. | HttpApiGroup.AddMiddleware<typeof ModelGroup, LocationId>
  38. | HttpApiGroup.AddMiddleware<typeof GenerateGroup, LocationId>
  39. | HttpApiGroup.AddMiddleware<typeof ProviderGroup, LocationId>
  40. | HttpApiGroup.AddMiddleware<typeof IntegrationGroup, LocationId>
  41. | HttpApiGroup.AddMiddleware<typeof McpGroup, LocationId>
  42. | HttpApiGroup.AddMiddleware<typeof CredentialGroup, LocationId>
  43. | HttpApiGroup.AddMiddleware<typeof ProjectGroup, LocationId>
  44. | HttpApiGroup.AddMiddleware<typeof FileSystemGroup, LocationId>
  45. | HttpApiGroup.AddMiddleware<typeof CommandGroup, LocationId>
  46. | HttpApiGroup.AddMiddleware<typeof SkillGroup, LocationId>
  47. | HttpApiGroup.AddMiddleware<typeof PtyGroup, LocationId>
  48. | HttpApiGroup.AddMiddleware<typeof ShellGroup, LocationId>
  49. | HttpApiGroup.AddMiddleware<typeof ReferenceGroup, LocationId>
  50. | HttpApiGroup.AddMiddleware<typeof ProjectCopyGroup, LocationId>
  51. | HttpApiGroup.AddMiddleware<typeof VcsGroup, LocationId>
  52. type SessionGroups<SessionLocationId extends HttpApiMiddleware.AnyId, SessionLocationService> =
  53. | ReturnType<typeof makeSessionGroup<SessionLocationId, SessionLocationService>>
  54. | HttpApiGroup.AddMiddleware<typeof MessageGroup, SessionLocationId>
  55. type FormGroups<
  56. LocationId extends HttpApiMiddleware.AnyId,
  57. LocationService,
  58. FormLocationId extends HttpApiMiddleware.AnyId,
  59. FormLocationService,
  60. > = ReturnType<typeof makeFormGroup<LocationId, LocationService, FormLocationId, FormLocationService>>
  61. type MixedMiddlewareGroups<
  62. LocationId extends HttpApiMiddleware.AnyId,
  63. LocationService,
  64. SessionLocationId extends HttpApiMiddleware.AnyId,
  65. SessionLocationService,
  66. > =
  67. | ReturnType<typeof makePermissionGroup<LocationId, LocationService, SessionLocationId, SessionLocationService>>
  68. | ReturnType<typeof makeQuestionGroup<LocationId, LocationService, SessionLocationId, SessionLocationService>>
  69. type ApiGroups<
  70. LocationId extends HttpApiMiddleware.AnyId,
  71. LocationService,
  72. FormLocationId extends HttpApiMiddleware.AnyId,
  73. FormLocationService,
  74. SessionLocationId extends HttpApiMiddleware.AnyId,
  75. SessionLocationService,
  76. Event extends HttpApiGroup.Constraint,
  77. > =
  78. | typeof HealthGroup
  79. | typeof ServerGroup
  80. | typeof DebugGroup
  81. | LocationGroups<LocationId>
  82. | FormGroups<LocationId, LocationService, FormLocationId, FormLocationService>
  83. | SessionGroups<SessionLocationId, SessionLocationService>
  84. | MixedMiddlewareGroups<LocationId, LocationService, SessionLocationId, SessionLocationService>
  85. | Event
  86. type EventGroupFor<Definitions extends ReadonlyArray<Definition>> = ReturnType<typeof makeEventGroup<Definitions>>
  87. export type Api<
  88. LocationId extends HttpApiMiddleware.AnyId,
  89. LocationService,
  90. FormLocationId extends HttpApiMiddleware.AnyId,
  91. FormLocationService,
  92. SessionLocationId extends HttpApiMiddleware.AnyId,
  93. SessionLocationService,
  94. Event extends HttpApiGroup.Constraint,
  95. > = HttpApi.HttpApi<
  96. "server",
  97. HttpApiGroup.AddMiddleware<
  98. HttpApiGroup.AddMiddleware<
  99. ApiGroups<
  100. LocationId,
  101. LocationService,
  102. FormLocationId,
  103. FormLocationService,
  104. SessionLocationId,
  105. SessionLocationService,
  106. Event
  107. >,
  108. Authorization
  109. >,
  110. SchemaErrorMiddleware
  111. >
  112. >
  113. // Protocol owns middleware placement, while Server injects concrete keys so Core service identities stay downstream.
  114. const makeApiFromGroup = <
  115. const Group extends HttpApiGroup.Constraint,
  116. LocationId extends HttpApiMiddleware.AnyId,
  117. LocationService,
  118. FormLocationId extends HttpApiMiddleware.AnyId,
  119. FormLocationService,
  120. SessionLocationId extends HttpApiMiddleware.AnyId,
  121. SessionLocationService,
  122. >(
  123. eventGroup: Group,
  124. locationMiddleware: Context.Key<LocationId, LocationService>,
  125. formLocationMiddleware: Context.Key<FormLocationId, FormLocationService>,
  126. sessionLocationMiddleware: Context.Key<SessionLocationId, SessionLocationService>,
  127. ): Api<
  128. LocationId,
  129. LocationService,
  130. FormLocationId,
  131. FormLocationService,
  132. SessionLocationId,
  133. SessionLocationService,
  134. Group
  135. > =>
  136. HttpApi.make("server")
  137. .add(HealthGroup)
  138. .add(ServerGroup)
  139. .add(LocationGroup.middleware(locationMiddleware))
  140. .add(AgentGroup.middleware(locationMiddleware))
  141. .add(PluginGroup.middleware(locationMiddleware))
  142. .add(makeSessionGroup(sessionLocationMiddleware))
  143. .add(MessageGroup.middleware(sessionLocationMiddleware))
  144. .add(ModelGroup.middleware(locationMiddleware))
  145. .add(GenerateGroup.middleware(locationMiddleware))
  146. .add(ProviderGroup.middleware(locationMiddleware))
  147. .add(IntegrationGroup.middleware(locationMiddleware))
  148. .add(McpGroup.middleware(locationMiddleware))
  149. .add(CredentialGroup.middleware(locationMiddleware))
  150. .add(ProjectGroup.middleware(locationMiddleware))
  151. .add(makeFormGroup(locationMiddleware, formLocationMiddleware))
  152. .add(makePermissionGroup(locationMiddleware, sessionLocationMiddleware))
  153. .add(FileSystemGroup.middleware(locationMiddleware))
  154. .add(CommandGroup.middleware(locationMiddleware))
  155. .add(SkillGroup.middleware(locationMiddleware))
  156. .add(eventGroup)
  157. .add(PtyGroup.middleware(locationMiddleware))
  158. .add(ShellGroup.middleware(locationMiddleware))
  159. .add(makeQuestionGroup(locationMiddleware, sessionLocationMiddleware))
  160. .add(ReferenceGroup.middleware(locationMiddleware))
  161. .add(ProjectCopyGroup.middleware(locationMiddleware))
  162. .add(VcsGroup.middleware(locationMiddleware))
  163. .add(DebugGroup)
  164. .annotateMerge(
  165. OpenApi.annotations({
  166. title: "opencode HttpApi",
  167. version: "0.0.1",
  168. description: "Experimental HttpApi surface for selected instance routes.",
  169. }),
  170. )
  171. .middleware(Authorization)
  172. .middleware(SchemaErrorMiddleware)
  173. export const makeApi = <
  174. const Definitions extends ReadonlyArray<Definition>,
  175. LocationId extends HttpApiMiddleware.AnyId,
  176. LocationService,
  177. FormLocationId extends HttpApiMiddleware.AnyId,
  178. FormLocationService,
  179. SessionLocationId extends HttpApiMiddleware.AnyId,
  180. SessionLocationService,
  181. >(options: {
  182. readonly definitions: Definitions
  183. readonly locationMiddleware: Context.Key<LocationId, LocationService>
  184. readonly formLocationMiddleware: Context.Key<FormLocationId, FormLocationService>
  185. readonly sessionLocationMiddleware: Context.Key<SessionLocationId, SessionLocationService>
  186. }): Api<
  187. LocationId,
  188. LocationService,
  189. FormLocationId,
  190. FormLocationService,
  191. SessionLocationId,
  192. SessionLocationService,
  193. EventGroupFor<Definitions>
  194. > =>
  195. makeApiFromGroup(
  196. makeEventGroup(options.definitions),
  197. options.locationMiddleware,
  198. options.formLocationMiddleware,
  199. options.sessionLocationMiddleware,
  200. )
  201. export const makeDefaultApi = <
  202. LocationId extends HttpApiMiddleware.AnyId,
  203. LocationService,
  204. FormLocationId extends HttpApiMiddleware.AnyId,
  205. FormLocationService,
  206. SessionLocationId extends HttpApiMiddleware.AnyId,
  207. SessionLocationService,
  208. >(options: {
  209. readonly locationMiddleware: Context.Key<LocationId, LocationService>
  210. readonly formLocationMiddleware: Context.Key<FormLocationId, FormLocationService>
  211. readonly sessionLocationMiddleware: Context.Key<SessionLocationId, SessionLocationService>
  212. }): Api<
  213. LocationId,
  214. LocationService,
  215. FormLocationId,
  216. FormLocationService,
  217. SessionLocationId,
  218. SessionLocationService,
  219. typeof EventGroup
  220. > =>
  221. makeApiFromGroup(
  222. EventGroup,
  223. options.locationMiddleware,
  224. options.formLocationMiddleware,
  225. options.sessionLocationMiddleware,
  226. )