@aeolus-fleet/gateway 0.0.0-stage → 0.0.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 (474) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +104 -2
  3. package/dist/adapters/crypto/call-keys.d.ts +7 -0
  4. package/dist/adapters/crypto/call-keys.js +18 -0
  5. package/dist/adapters/crypto/call-keys.js.map +1 -0
  6. package/dist/adapters/crypto/oauth-secrets.d.ts +3 -0
  7. package/dist/adapters/crypto/oauth-secrets.js +10 -0
  8. package/dist/adapters/crypto/oauth-secrets.js.map +1 -0
  9. package/dist/adapters/crypto/request-hasher.d.ts +3 -0
  10. package/dist/adapters/crypto/request-hasher.js +4 -0
  11. package/dist/adapters/crypto/request-hasher.js.map +1 -0
  12. package/dist/adapters/crypto/request-ids.d.ts +4 -0
  13. package/dist/adapters/crypto/request-ids.js +14 -0
  14. package/dist/adapters/crypto/request-ids.js.map +1 -0
  15. package/dist/adapters/crypto/sealer.d.ts +14 -0
  16. package/dist/adapters/crypto/sealer.js +41 -0
  17. package/dist/adapters/crypto/sealer.js.map +1 -0
  18. package/dist/adapters/crypto/ship-aliases.d.ts +7 -0
  19. package/dist/adapters/crypto/ship-aliases.js +19 -0
  20. package/dist/adapters/crypto/ship-aliases.js.map +1 -0
  21. package/dist/adapters/crypto/sign-in-seals.d.ts +7 -0
  22. package/dist/adapters/crypto/sign-in-seals.js +27 -0
  23. package/dist/adapters/crypto/sign-in-seals.js.map +1 -0
  24. package/dist/adapters/crypto/waiting-seals.d.ts +3 -0
  25. package/dist/adapters/crypto/waiting-seals.js +24 -0
  26. package/dist/adapters/crypto/waiting-seals.js.map +1 -0
  27. package/dist/adapters/fleet/console-sessions.d.ts +2 -0
  28. package/dist/adapters/fleet/console-sessions.js +23 -0
  29. package/dist/adapters/fleet/console-sessions.js.map +1 -0
  30. package/dist/adapters/fleet/core-version.d.ts +11 -0
  31. package/dist/adapters/fleet/core-version.js +59 -0
  32. package/dist/adapters/fleet/core-version.js.map +1 -0
  33. package/dist/adapters/fleet/fleet-network.d.ts +2 -0
  34. package/dist/adapters/fleet/fleet-network.js +44 -0
  35. package/dist/adapters/fleet/fleet-network.js.map +1 -0
  36. package/dist/adapters/fleet/rest-fleet-door.d.ts +14 -0
  37. package/dist/adapters/fleet/rest-fleet-door.js +189 -0
  38. package/dist/adapters/fleet/rest-fleet-door.js.map +1 -0
  39. package/dist/adapters/http/html.d.ts +15 -0
  40. package/dist/adapters/http/html.js +53 -0
  41. package/dist/adapters/http/html.js.map +1 -0
  42. package/dist/adapters/http/live.d.ts +29 -0
  43. package/dist/adapters/http/live.js +100 -0
  44. package/dist/adapters/http/live.js.map +1 -0
  45. package/dist/adapters/http/mcp-endpoint.d.ts +20 -0
  46. package/dist/adapters/http/mcp-endpoint.js +164 -0
  47. package/dist/adapters/http/mcp-endpoint.js.map +1 -0
  48. package/dist/adapters/http/mcp-task.d.ts +45 -0
  49. package/dist/adapters/http/mcp-task.js +35 -0
  50. package/dist/adapters/http/mcp-task.js.map +1 -0
  51. package/dist/adapters/http/oauth-routes.d.ts +35 -0
  52. package/dist/adapters/http/oauth-routes.js +305 -0
  53. package/dist/adapters/http/oauth-routes.js.map +1 -0
  54. package/dist/adapters/http/outside-parties-page.d.ts +6 -0
  55. package/dist/adapters/http/outside-parties-page.js +149 -0
  56. package/dist/adapters/http/outside-parties-page.js.map +1 -0
  57. package/dist/adapters/http/overview-page.d.ts +16 -0
  58. package/dist/adapters/http/overview-page.js +255 -0
  59. package/dist/adapters/http/overview-page.js.map +1 -0
  60. package/dist/adapters/http/parties-page.d.ts +6 -0
  61. package/dist/adapters/http/parties-page.js +141 -0
  62. package/dist/adapters/http/parties-page.js.map +1 -0
  63. package/dist/adapters/http/person-tools.d.ts +22 -0
  64. package/dist/adapters/http/person-tools.js +98 -0
  65. package/dist/adapters/http/person-tools.js.map +1 -0
  66. package/dist/adapters/http/signal.d.ts +52 -0
  67. package/dist/adapters/http/signal.js +220 -0
  68. package/dist/adapters/http/signal.js.map +1 -0
  69. package/dist/adapters/http/version.d.ts +6 -0
  70. package/dist/adapters/http/version.js +12 -0
  71. package/dist/adapters/http/version.js.map +1 -0
  72. package/dist/adapters/mcp/mcp-servers.d.ts +2 -0
  73. package/dist/adapters/mcp/mcp-servers.js +154 -0
  74. package/dist/adapters/mcp/mcp-servers.js.map +1 -0
  75. package/dist/adapters/oauth/client-metadata-documents.d.ts +9 -0
  76. package/dist/adapters/oauth/client-metadata-documents.js +25 -0
  77. package/dist/adapters/oauth/client-metadata-documents.js.map +1 -0
  78. package/dist/adapters/pagasae/pagasae-client.d.ts +8 -0
  79. package/dist/adapters/pagasae/pagasae-client.js +90 -0
  80. package/dist/adapters/pagasae/pagasae-client.js.map +1 -0
  81. package/dist/adapters/prisma/account-grants.d.ts +4 -0
  82. package/dist/adapters/prisma/account-grants.js +27 -0
  83. package/dist/adapters/prisma/account-grants.js.map +1 -0
  84. package/dist/adapters/prisma/calls.d.ts +4 -0
  85. package/dist/adapters/prisma/calls.js +35 -0
  86. package/dist/adapters/prisma/calls.js.map +1 -0
  87. package/dist/adapters/prisma/changes.d.ts +21 -0
  88. package/dist/adapters/prisma/changes.js +86 -0
  89. package/dist/adapters/prisma/changes.js.map +1 -0
  90. package/dist/adapters/prisma/client-calls.d.ts +4 -0
  91. package/dist/adapters/prisma/client-calls.js +50 -0
  92. package/dist/adapters/prisma/client-calls.js.map +1 -0
  93. package/dist/adapters/prisma/client.d.ts +8 -0
  94. package/dist/adapters/prisma/client.js +11 -0
  95. package/dist/adapters/prisma/client.js.map +1 -0
  96. package/dist/adapters/prisma/connection-store.d.ts +4 -0
  97. package/dist/adapters/prisma/connection-store.js +28 -0
  98. package/dist/adapters/prisma/connection-store.js.map +1 -0
  99. package/dist/adapters/prisma/fleet-forgetter.d.ts +4 -0
  100. package/dist/adapters/prisma/fleet-forgetter.js +10 -0
  101. package/dist/adapters/prisma/fleet-forgetter.js.map +1 -0
  102. package/dist/adapters/prisma/fleet-switches.d.ts +4 -0
  103. package/dist/adapters/prisma/fleet-switches.js +10 -0
  104. package/dist/adapters/prisma/fleet-switches.js.map +1 -0
  105. package/dist/adapters/prisma/generated/browser.d.ts +108 -0
  106. package/dist/adapters/prisma/generated/browser.js +18 -0
  107. package/dist/adapters/prisma/generated/browser.js.map +1 -0
  108. package/dist/adapters/prisma/generated/client.d.ts +127 -0
  109. package/dist/adapters/prisma/generated/client.js +38 -0
  110. package/dist/adapters/prisma/generated/client.js.map +1 -0
  111. package/dist/adapters/prisma/generated/commonInputTypes.d.ts +490 -0
  112. package/dist/adapters/prisma/generated/commonInputTypes.js +11 -0
  113. package/dist/adapters/prisma/generated/commonInputTypes.js.map +1 -0
  114. package/dist/adapters/prisma/generated/enums.d.ts +1 -0
  115. package/dist/adapters/prisma/generated/enums.js +12 -0
  116. package/dist/adapters/prisma/generated/enums.js.map +1 -0
  117. package/dist/adapters/prisma/generated/internal/class.d.ts +319 -0
  118. package/dist/adapters/prisma/generated/internal/class.js +50 -0
  119. package/dist/adapters/prisma/generated/internal/class.js.map +1 -0
  120. package/dist/adapters/prisma/generated/internal/prismaNamespace.d.ts +2102 -0
  121. package/dist/adapters/prisma/generated/internal/prismaNamespace.js +294 -0
  122. package/dist/adapters/prisma/generated/internal/prismaNamespace.js.map +1 -0
  123. package/dist/adapters/prisma/generated/internal/prismaNamespaceBrowser.d.ts +273 -0
  124. package/dist/adapters/prisma/generated/internal/prismaNamespaceBrowser.js +264 -0
  125. package/dist/adapters/prisma/generated/internal/prismaNamespaceBrowser.js.map +1 -0
  126. package/dist/adapters/prisma/generated/models/AccountGrant.d.ts +1056 -0
  127. package/dist/adapters/prisma/generated/models/AccountGrant.js +2 -0
  128. package/dist/adapters/prisma/generated/models/AccountGrant.js.map +1 -0
  129. package/dist/adapters/prisma/generated/models/AuthorizationCode.d.ts +1171 -0
  130. package/dist/adapters/prisma/generated/models/AuthorizationCode.js +2 -0
  131. package/dist/adapters/prisma/generated/models/AuthorizationCode.js.map +1 -0
  132. package/dist/adapters/prisma/generated/models/Call.d.ts +994 -0
  133. package/dist/adapters/prisma/generated/models/Call.js +2 -0
  134. package/dist/adapters/prisma/generated/models/Call.js.map +1 -0
  135. package/dist/adapters/prisma/generated/models/ClientCall.d.ts +1119 -0
  136. package/dist/adapters/prisma/generated/models/ClientCall.js +2 -0
  137. package/dist/adapters/prisma/generated/models/ClientCall.js.map +1 -0
  138. package/dist/adapters/prisma/generated/models/ClientCallReply.d.ts +1129 -0
  139. package/dist/adapters/prisma/generated/models/ClientCallReply.js +2 -0
  140. package/dist/adapters/prisma/generated/models/ClientCallReply.js.map +1 -0
  141. package/dist/adapters/prisma/generated/models/Connection.d.ts +1011 -0
  142. package/dist/adapters/prisma/generated/models/Connection.js +2 -0
  143. package/dist/adapters/prisma/generated/models/Connection.js.map +1 -0
  144. package/dist/adapters/prisma/generated/models/FleetSwitch.d.ts +945 -0
  145. package/dist/adapters/prisma/generated/models/FleetSwitch.js +2 -0
  146. package/dist/adapters/prisma/generated/models/FleetSwitch.js.map +1 -0
  147. package/dist/adapters/prisma/generated/models/InstallationRequest.d.ts +1030 -0
  148. package/dist/adapters/prisma/generated/models/InstallationRequest.js +2 -0
  149. package/dist/adapters/prisma/generated/models/InstallationRequest.js.map +1 -0
  150. package/dist/adapters/prisma/generated/models/IssuedToken.d.ts +1224 -0
  151. package/dist/adapters/prisma/generated/models/IssuedToken.js +2 -0
  152. package/dist/adapters/prisma/generated/models/IssuedToken.js.map +1 -0
  153. package/dist/adapters/prisma/generated/models/OAuthClient.d.ts +1005 -0
  154. package/dist/adapters/prisma/generated/models/OAuthClient.js +2 -0
  155. package/dist/adapters/prisma/generated/models/OAuthClient.js.map +1 -0
  156. package/dist/adapters/prisma/generated/models/OpenedDelivery.d.ts +1087 -0
  157. package/dist/adapters/prisma/generated/models/OpenedDelivery.js +2 -0
  158. package/dist/adapters/prisma/generated/models/OpenedDelivery.js.map +1 -0
  159. package/dist/adapters/prisma/generated/models/OutsidePartySwitch.d.ts +942 -0
  160. package/dist/adapters/prisma/generated/models/OutsidePartySwitch.js +2 -0
  161. package/dist/adapters/prisma/generated/models/OutsidePartySwitch.js.map +1 -0
  162. package/dist/adapters/prisma/generated/models/OwnerQuestion.d.ts +1035 -0
  163. package/dist/adapters/prisma/generated/models/OwnerQuestion.js +2 -0
  164. package/dist/adapters/prisma/generated/models/OwnerQuestion.js.map +1 -0
  165. package/dist/adapters/prisma/generated/models/Party.d.ts +1338 -0
  166. package/dist/adapters/prisma/generated/models/Party.js +2 -0
  167. package/dist/adapters/prisma/generated/models/Party.js.map +1 -0
  168. package/dist/adapters/prisma/generated/models/PendingRequest.d.ts +1252 -0
  169. package/dist/adapters/prisma/generated/models/PendingRequest.js +2 -0
  170. package/dist/adapters/prisma/generated/models/PendingRequest.js.map +1 -0
  171. package/dist/adapters/prisma/generated/models/PersonCrew.d.ts +974 -0
  172. package/dist/adapters/prisma/generated/models/PersonCrew.js +2 -0
  173. package/dist/adapters/prisma/generated/models/PersonCrew.js.map +1 -0
  174. package/dist/adapters/prisma/generated/models/RequestOutcomeNotice.d.ts +1120 -0
  175. package/dist/adapters/prisma/generated/models/RequestOutcomeNotice.js +2 -0
  176. package/dist/adapters/prisma/generated/models/RequestOutcomeNotice.js.map +1 -0
  177. package/dist/adapters/prisma/generated/models/ToolMark.d.ts +947 -0
  178. package/dist/adapters/prisma/generated/models/ToolMark.js +2 -0
  179. package/dist/adapters/prisma/generated/models/ToolMark.js.map +1 -0
  180. package/dist/adapters/prisma/generated/models.d.ts +19 -0
  181. package/dist/adapters/prisma/generated/models.js +2 -0
  182. package/dist/adapters/prisma/generated/models.js.map +1 -0
  183. package/dist/adapters/prisma/installation-requests.d.ts +4 -0
  184. package/dist/adapters/prisma/installation-requests.js +25 -0
  185. package/dist/adapters/prisma/installation-requests.js.map +1 -0
  186. package/dist/adapters/prisma/migrate.d.ts +5 -0
  187. package/dist/adapters/prisma/migrate.js +53 -0
  188. package/dist/adapters/prisma/migrate.js.map +1 -0
  189. package/dist/adapters/prisma/oauth-stores.d.ts +5 -0
  190. package/dist/adapters/prisma/oauth-stores.js +82 -0
  191. package/dist/adapters/prisma/oauth-stores.js.map +1 -0
  192. package/dist/adapters/prisma/opened-deliveries.d.ts +4 -0
  193. package/dist/adapters/prisma/opened-deliveries.js +29 -0
  194. package/dist/adapters/prisma/opened-deliveries.js.map +1 -0
  195. package/dist/adapters/prisma/outcome-notices.d.ts +4 -0
  196. package/dist/adapters/prisma/outcome-notices.js +24 -0
  197. package/dist/adapters/prisma/outcome-notices.js.map +1 -0
  198. package/dist/adapters/prisma/outside-party-switches.d.ts +4 -0
  199. package/dist/adapters/prisma/outside-party-switches.js +10 -0
  200. package/dist/adapters/prisma/outside-party-switches.js.map +1 -0
  201. package/dist/adapters/prisma/owner-questions.d.ts +8 -0
  202. package/dist/adapters/prisma/owner-questions.js +54 -0
  203. package/dist/adapters/prisma/owner-questions.js.map +1 -0
  204. package/dist/adapters/prisma/party-store.d.ts +7 -0
  205. package/dist/adapters/prisma/party-store.js +73 -0
  206. package/dist/adapters/prisma/party-store.js.map +1 -0
  207. package/dist/adapters/prisma/pending-requests.d.ts +11 -0
  208. package/dist/adapters/prisma/pending-requests.js +122 -0
  209. package/dist/adapters/prisma/pending-requests.js.map +1 -0
  210. package/dist/adapters/prisma/person-crews.d.ts +4 -0
  211. package/dist/adapters/prisma/person-crews.js +18 -0
  212. package/dist/adapters/prisma/person-crews.js.map +1 -0
  213. package/dist/adapters/prisma/tool-marks.d.ts +4 -0
  214. package/dist/adapters/prisma/tool-marks.js +15 -0
  215. package/dist/adapters/prisma/tool-marks.js.map +1 -0
  216. package/dist/adapters/timers/sleep.d.ts +3 -0
  217. package/dist/adapters/timers/sleep.js +11 -0
  218. package/dist/adapters/timers/sleep.js.map +1 -0
  219. package/dist/adapters/trpc/router.d.ts +408 -0
  220. package/dist/adapters/trpc/router.js +367 -0
  221. package/dist/adapters/trpc/router.js.map +1 -0
  222. package/dist/app.d.ts +43 -0
  223. package/dist/app.js +400 -0
  224. package/dist/app.js.map +1 -0
  225. package/dist/bin/aeolus-gateway.d.ts +2 -0
  226. package/dist/bin/aeolus-gateway.js +65 -0
  227. package/dist/bin/aeolus-gateway.js.map +1 -0
  228. package/dist/config.d.ts +41 -0
  229. package/dist/config.js +65 -0
  230. package/dist/config.js.map +1 -0
  231. package/dist/core/actors/authenticate-actor.d.ts +38 -0
  232. package/dist/core/actors/authenticate-actor.js +30 -0
  233. package/dist/core/actors/authenticate-actor.js.map +1 -0
  234. package/dist/core/connection/connect.d.ts +26 -0
  235. package/dist/core/connection/connect.js +57 -0
  236. package/dist/core/connection/connect.js.map +1 -0
  237. package/dist/core/connection/ports.d.ts +87 -0
  238. package/dist/core/connection/ports.js +2 -0
  239. package/dist/core/connection/ports.js.map +1 -0
  240. package/dist/core/connection/read-connection.d.ts +14 -0
  241. package/dist/core/connection/read-connection.js +24 -0
  242. package/dist/core/connection/read-connection.js.map +1 -0
  243. package/dist/core/installation/delete-fleet.d.ts +21 -0
  244. package/dist/core/installation/delete-fleet.js +21 -0
  245. package/dist/core/installation/delete-fleet.js.map +1 -0
  246. package/dist/core/installation/ports.d.ts +43 -0
  247. package/dist/core/installation/ports.js +2 -0
  248. package/dist/core/installation/ports.js.map +1 -0
  249. package/dist/core/installation/read-fleet.d.ts +18 -0
  250. package/dist/core/installation/read-fleet.js +9 -0
  251. package/dist/core/installation/read-fleet.js.map +1 -0
  252. package/dist/core/installation/request-id.d.ts +8 -0
  253. package/dist/core/installation/request-id.js +10 -0
  254. package/dist/core/installation/request-id.js.map +1 -0
  255. package/dist/core/installation/served.d.ts +12 -0
  256. package/dist/core/installation/served.js +8 -0
  257. package/dist/core/installation/served.js.map +1 -0
  258. package/dist/core/installation/set-fleet-enabled.d.ts +25 -0
  259. package/dist/core/installation/set-fleet-enabled.js +22 -0
  260. package/dist/core/installation/set-fleet-enabled.js.map +1 -0
  261. package/dist/core/mcp-in/call-tool.d.ts +42 -0
  262. package/dist/core/mcp-in/call-tool.js +82 -0
  263. package/dist/core/mcp-in/call-tool.js.map +1 -0
  264. package/dist/core/mcp-in/client-call.d.ts +51 -0
  265. package/dist/core/mcp-in/client-call.js +39 -0
  266. package/dist/core/mcp-in/client-call.js.map +1 -0
  267. package/dist/core/mcp-in/collect-replies.d.ts +29 -0
  268. package/dist/core/mcp-in/collect-replies.js +44 -0
  269. package/dist/core/mcp-in/collect-replies.js.map +1 -0
  270. package/dist/core/mcp-in/list-tools.d.ts +44 -0
  271. package/dist/core/mcp-in/list-tools.js +70 -0
  272. package/dist/core/mcp-in/list-tools.js.map +1 -0
  273. package/dist/core/mcp-in/ports.d.ts +85 -0
  274. package/dist/core/mcp-in/ports.js +2 -0
  275. package/dist/core/mcp-in/ports.js.map +1 -0
  276. package/dist/core/mcp-in/read-client-call.d.ts +23 -0
  277. package/dist/core/mcp-in/read-client-call.js +15 -0
  278. package/dist/core/mcp-in/read-client-call.js.map +1 -0
  279. package/dist/core/mcp-out/content-types.d.ts +12 -0
  280. package/dist/core/mcp-out/content-types.js +28 -0
  281. package/dist/core/mcp-out/content-types.js.map +1 -0
  282. package/dist/core/mcp-out/hand-call.d.ts +103 -0
  283. package/dist/core/mcp-out/hand-call.js +116 -0
  284. package/dist/core/mcp-out/hand-call.js.map +1 -0
  285. package/dist/core/mcp-out/mark-tool.d.ts +20 -0
  286. package/dist/core/mcp-out/mark-tool.js +17 -0
  287. package/dist/core/mcp-out/mark-tool.js.map +1 -0
  288. package/dist/core/mcp-out/ports.d.ts +66 -0
  289. package/dist/core/mcp-out/ports.js +2 -0
  290. package/dist/core/mcp-out/ports.js.map +1 -0
  291. package/dist/core/mcp-out/run-party.d.ts +26 -0
  292. package/dist/core/mcp-out/run-party.js +62 -0
  293. package/dist/core/mcp-out/run-party.js.map +1 -0
  294. package/dist/core/mcp-out/state-party.d.ts +38 -0
  295. package/dist/core/mcp-out/state-party.js +30 -0
  296. package/dist/core/mcp-out/state-party.js.map +1 -0
  297. package/dist/core/mcp-out/statement.d.ts +26 -0
  298. package/dist/core/mcp-out/statement.js +32 -0
  299. package/dist/core/mcp-out/statement.js.map +1 -0
  300. package/dist/core/oauth/authenticate-access-token.d.ts +25 -0
  301. package/dist/core/oauth/authenticate-access-token.js +19 -0
  302. package/dist/core/oauth/authenticate-access-token.js.map +1 -0
  303. package/dist/core/oauth/exchange-token.d.ts +32 -0
  304. package/dist/core/oauth/exchange-token.js +98 -0
  305. package/dist/core/oauth/exchange-token.js.map +1 -0
  306. package/dist/core/oauth/issue-code.d.ts +23 -0
  307. package/dist/core/oauth/issue-code.js +34 -0
  308. package/dist/core/oauth/issue-code.js.map +1 -0
  309. package/dist/core/oauth/ports.d.ts +103 -0
  310. package/dist/core/oauth/ports.js +2 -0
  311. package/dist/core/oauth/ports.js.map +1 -0
  312. package/dist/core/oauth/read-authorization.d.ts +43 -0
  313. package/dist/core/oauth/read-authorization.js +74 -0
  314. package/dist/core/oauth/read-authorization.js.map +1 -0
  315. package/dist/core/oauth/redirect-uri.d.ts +6 -0
  316. package/dist/core/oauth/redirect-uri.js +20 -0
  317. package/dist/core/oauth/redirect-uri.js.map +1 -0
  318. package/dist/core/oauth/register-client.d.ts +22 -0
  319. package/dist/core/oauth/register-client.js +20 -0
  320. package/dist/core/oauth/register-client.js.map +1 -0
  321. package/dist/core/operator/authenticate-operator.d.ts +22 -0
  322. package/dist/core/operator/authenticate-operator.js +26 -0
  323. package/dist/core/operator/authenticate-operator.js.map +1 -0
  324. package/dist/core/operator/ports.d.ts +15 -0
  325. package/dist/core/operator/ports.js +2 -0
  326. package/dist/core/operator/ports.js.map +1 -0
  327. package/dist/core/outside-parties/ports.d.ts +21 -0
  328. package/dist/core/outside-parties/ports.js +2 -0
  329. package/dist/core/outside-parties/ports.js.map +1 -0
  330. package/dist/core/outside-parties/set-outside-parties.d.ts +34 -0
  331. package/dist/core/outside-parties/set-outside-parties.js +34 -0
  332. package/dist/core/outside-parties/set-outside-parties.js.map +1 -0
  333. package/dist/core/parties/approve-party.d.ts +55 -0
  334. package/dist/core/parties/approve-party.js +111 -0
  335. package/dist/core/parties/approve-party.js.map +1 -0
  336. package/dist/core/parties/crew-party.d.ts +21 -0
  337. package/dist/core/parties/crew-party.js +29 -0
  338. package/dist/core/parties/crew-party.js.map +1 -0
  339. package/dist/core/parties/list-parties.d.ts +8 -0
  340. package/dist/core/parties/list-parties.js +8 -0
  341. package/dist/core/parties/list-parties.js.map +1 -0
  342. package/dist/core/parties/party.d.ts +46 -0
  343. package/dist/core/parties/party.js +2 -0
  344. package/dist/core/parties/party.js.map +1 -0
  345. package/dist/core/parties/ports.d.ts +39 -0
  346. package/dist/core/parties/ports.js +2 -0
  347. package/dist/core/parties/ports.js.map +1 -0
  348. package/dist/core/parties/shown-party.d.ts +21 -0
  349. package/dist/core/parties/shown-party.js +10 -0
  350. package/dist/core/parties/shown-party.js.map +1 -0
  351. package/dist/core/people/answer-delivery.d.ts +24 -0
  352. package/dist/core/people/answer-delivery.js +28 -0
  353. package/dist/core/people/answer-delivery.js.map +1 -0
  354. package/dist/core/people/crew-person-ship.d.ts +42 -0
  355. package/dist/core/people/crew-person-ship.js +59 -0
  356. package/dist/core/people/crew-person-ship.js.map +1 -0
  357. package/dist/core/people/done-delivery.d.ts +16 -0
  358. package/dist/core/people/done-delivery.js +9 -0
  359. package/dist/core/people/done-delivery.js.map +1 -0
  360. package/dist/core/people/inbox-entry.d.ts +14 -0
  361. package/dist/core/people/inbox-entry.js +11 -0
  362. package/dist/core/people/inbox-entry.js.map +1 -0
  363. package/dist/core/people/open-delivery.d.ts +30 -0
  364. package/dist/core/people/open-delivery.js +40 -0
  365. package/dist/core/people/open-delivery.js.map +1 -0
  366. package/dist/core/people/opened-of.d.ts +29 -0
  367. package/dist/core/people/opened-of.js +30 -0
  368. package/dist/core/people/opened-of.js.map +1 -0
  369. package/dist/core/people/person-crew.d.ts +39 -0
  370. package/dist/core/people/person-crew.js +61 -0
  371. package/dist/core/people/person-crew.js.map +1 -0
  372. package/dist/core/people/ports.d.ts +102 -0
  373. package/dist/core/people/ports.js +2 -0
  374. package/dist/core/people/ports.js.map +1 -0
  375. package/dist/core/people/read-inbox.d.ts +37 -0
  376. package/dist/core/people/read-inbox.js +36 -0
  377. package/dist/core/people/read-inbox.js.map +1 -0
  378. package/dist/core/requests/ask-for-client.d.ts +45 -0
  379. package/dist/core/requests/ask-for-client.js +33 -0
  380. package/dist/core/requests/ask-for-client.js.map +1 -0
  381. package/dist/core/requests/ask-for-server.d.ts +32 -0
  382. package/dist/core/requests/ask-for-server.js +42 -0
  383. package/dist/core/requests/ask-for-server.js.map +1 -0
  384. package/dist/core/requests/ask-owners.d.ts +28 -0
  385. package/dist/core/requests/ask-owners.js +85 -0
  386. package/dist/core/requests/ask-owners.js.map +1 -0
  387. package/dist/core/requests/decide-request.d.ts +53 -0
  388. package/dist/core/requests/decide-request.js +75 -0
  389. package/dist/core/requests/decide-request.js.map +1 -0
  390. package/dist/core/requests/expire-requests.d.ts +14 -0
  391. package/dist/core/requests/expire-requests.js +21 -0
  392. package/dist/core/requests/expire-requests.js.map +1 -0
  393. package/dist/core/requests/list-to-decide.d.ts +11 -0
  394. package/dist/core/requests/list-to-decide.js +13 -0
  395. package/dist/core/requests/list-to-decide.js.map +1 -0
  396. package/dist/core/requests/open-request.d.ts +21 -0
  397. package/dist/core/requests/open-request.js +26 -0
  398. package/dist/core/requests/open-request.js.map +1 -0
  399. package/dist/core/requests/outcome-notice.d.ts +13 -0
  400. package/dist/core/requests/outcome-notice.js +26 -0
  401. package/dist/core/requests/outcome-notice.js.map +1 -0
  402. package/dist/core/requests/ports.d.ts +186 -0
  403. package/dist/core/requests/ports.js +2 -0
  404. package/dist/core/requests/ports.js.map +1 -0
  405. package/dist/core/requests/read-waiting.d.ts +46 -0
  406. package/dist/core/requests/read-waiting.js +41 -0
  407. package/dist/core/requests/read-waiting.js.map +1 -0
  408. package/dist/core/requests/request-state.d.ts +5 -0
  409. package/dist/core/requests/request-state.js +10 -0
  410. package/dist/core/requests/request-state.js.map +1 -0
  411. package/dist/core/requests/tell-outcomes.d.ts +24 -0
  412. package/dist/core/requests/tell-outcomes.js +39 -0
  413. package/dist/core/requests/tell-outcomes.js.map +1 -0
  414. package/dist/core/requests/watch-waiting.d.ts +32 -0
  415. package/dist/core/requests/watch-waiting.js +31 -0
  416. package/dist/core/requests/watch-waiting.js.map +1 -0
  417. package/dist/core/shared/clock.d.ts +4 -0
  418. package/dist/core/shared/clock.js +2 -0
  419. package/dist/core/shared/clock.js.map +1 -0
  420. package/dist/core/shared/errors.d.ts +10 -0
  421. package/dist/core/shared/errors.js +6 -0
  422. package/dist/core/shared/errors.js.map +1 -0
  423. package/dist/core/shared/result.d.ts +16 -0
  424. package/dist/core/shared/result.js +7 -0
  425. package/dist/core/shared/result.js.map +1 -0
  426. package/dist/core/sign-in/account-token.d.ts +38 -0
  427. package/dist/core/sign-in/account-token.js +46 -0
  428. package/dist/core/sign-in/account-token.js.map +1 -0
  429. package/dist/core/sign-in/complete-sign-in.d.ts +55 -0
  430. package/dist/core/sign-in/complete-sign-in.js +50 -0
  431. package/dist/core/sign-in/complete-sign-in.js.map +1 -0
  432. package/dist/core/sign-in/end-sign-ins.d.ts +19 -0
  433. package/dist/core/sign-in/end-sign-ins.js +17 -0
  434. package/dist/core/sign-in/end-sign-ins.js.map +1 -0
  435. package/dist/core/sign-in/ports.d.ts +85 -0
  436. package/dist/core/sign-in/ports.js +2 -0
  437. package/dist/core/sign-in/ports.js.map +1 -0
  438. package/dist/core/sign-in/start-sign-in.d.ts +30 -0
  439. package/dist/core/sign-in/start-sign-in.js +25 -0
  440. package/dist/core/sign-in/start-sign-in.js.map +1 -0
  441. package/dist/core/vault/credential.d.ts +18 -0
  442. package/dist/core/vault/credential.js +2 -0
  443. package/dist/core/vault/credential.js.map +1 -0
  444. package/dist/outcome-worker.d.ts +29 -0
  445. package/dist/outcome-worker.js +60 -0
  446. package/dist/outcome-worker.js.map +1 -0
  447. package/dist/party-workers.d.ts +32 -0
  448. package/dist/party-workers.js +57 -0
  449. package/dist/party-workers.js.map +1 -0
  450. package/package.json +70 -4
  451. package/prisma.config.ts +18 -0
  452. package/src/adapters/prisma/migrations/20261018200000_init/migration.sql +35 -0
  453. package/src/adapters/prisma/migrations/20261018210000_parties/migration.sql +19 -0
  454. package/src/adapters/prisma/migrations/20261018220000_tool_marks/migration.sql +8 -0
  455. package/src/adapters/prisma/migrations/20261018230000_calls/migration.sql +13 -0
  456. package/src/adapters/prisma/migrations/20261019090000_oauth/migration.sql +60 -0
  457. package/src/adapters/prisma/migrations/20261019100000_client_parties/migration.sql +8 -0
  458. package/src/adapters/prisma/migrations/20261019110000_oauth_parties/migration.sql +5 -0
  459. package/src/adapters/prisma/migrations/20261019120000_client_calls/migration.sql +15 -0
  460. package/src/adapters/prisma/migrations/20261019130000_client_call_replies/migration.sql +20 -0
  461. package/src/adapters/prisma/migrations/20261019140000_identity_providers/migration.sql +10 -0
  462. package/src/adapters/prisma/migrations/20261020090000_no_identity_providers/migration.sql +2 -0
  463. package/src/adapters/prisma/migrations/20261020100000_account_grants_in_tokens/migration.sql +5 -0
  464. package/src/adapters/prisma/migrations/20261020110000_account_grants/migration.sql +15 -0
  465. package/src/adapters/prisma/migrations/20261020120000_person_crews/migration.sql +9 -0
  466. package/src/adapters/prisma/migrations/20261020130000_opened_deliveries/migration.sql +13 -0
  467. package/src/adapters/prisma/migrations/20261020140000_pending_requests/migration.sql +26 -0
  468. package/src/adapters/prisma/migrations/20261020150000_outside_party_switches/migration.sql +8 -0
  469. package/src/adapters/prisma/migrations/20261020160000_pending_requests_told/migration.sql +2 -0
  470. package/src/adapters/prisma/migrations/20261020170000_request_outcome_notices/migration.sql +17 -0
  471. package/src/adapters/prisma/migrations/20261020180000_owner_questions/migration.sql +11 -0
  472. package/src/adapters/prisma/migrations/20261020190000_request_changes/migration.sql +12 -0
  473. package/src/adapters/prisma/migrations/migration_lock.toml +3 -0
  474. package/src/adapters/prisma/schema.prisma +311 -0
@@ -0,0 +1,32 @@
1
+ import type { Clock } from '../shared/clock.js';
2
+ import { type Result } from '../shared/result.js';
3
+ import type { AuthorizationCodes, IssuedTokens, OAuthClients, OAuthError, OAuthSecrets } from './ports.js';
4
+ /** An access token works one hour; its refresh token 30 days (orchestrator-1 on aeolus-fleet#877, Q13). */
5
+ export declare const ACCESS_TOKEN_LIFETIME_MS: number;
6
+ export declare const REFRESH_TOKEN_LIFETIME_MS: number;
7
+ /** The tokens a client gets. */
8
+ export interface IssuedPair {
9
+ readonly accessToken: string;
10
+ readonly refreshToken: string;
11
+ readonly expiresInSeconds: number;
12
+ readonly scope: string | null;
13
+ }
14
+ /** A token request's parameters, the client's credentials among them, however it sent them. */
15
+ export type TokenRequest = Readonly<Record<string, string | undefined>>;
16
+ export type ExchangeToken = (request: TokenRequest) => Promise<Result<IssuedPair, OAuthError>>;
17
+ /**
18
+ * Use case: a client takes its code for tokens, or refreshes them (OAuth
19
+ * 2.1). A confidential client proves its secret; a public one, or one known
20
+ * by its metadata document, needs none, as PKCE binds the code to it. A code
21
+ * is taken once: a second try revokes every token it gave. A refresh token
22
+ * is taken once too: the pair rotates, and a rotated one coming again
23
+ * revokes its whole family.
24
+ */
25
+ export declare function createExchangeToken(deps: {
26
+ clients: OAuthClients;
27
+ codes: AuthorizationCodes;
28
+ tokens: IssuedTokens;
29
+ secrets: OAuthSecrets;
30
+ clock: Clock;
31
+ resource: string;
32
+ }): ExchangeToken;
@@ -0,0 +1,98 @@
1
+ import { err, ok } from '../shared/result.js';
2
+ import { holderOf } from './authenticate-access-token.js';
3
+ /** An access token works one hour; its refresh token 30 days (orchestrator-1 on aeolus-fleet#877, Q13). */
4
+ export const ACCESS_TOKEN_LIFETIME_MS = 60 * 60_000;
5
+ export const REFRESH_TOKEN_LIFETIME_MS = 30 * 24 * 60 * 60_000;
6
+ const MS_PER_SECOND = 1000;
7
+ function refusal(error, description) {
8
+ return err({ error, description });
9
+ }
10
+ /**
11
+ * Use case: a client takes its code for tokens, or refreshes them (OAuth
12
+ * 2.1). A confidential client proves its secret; a public one, or one known
13
+ * by its metadata document, needs none, as PKCE binds the code to it. A code
14
+ * is taken once: a second try revokes every token it gave. A refresh token
15
+ * is taken once too: the pair rotates, and a rotated one coming again
16
+ * revokes its whole family.
17
+ */
18
+ export function createExchangeToken(deps) {
19
+ /** The client is who it says, as far as it has a secret. */
20
+ const isAuthenticated = async (request) => {
21
+ const clientId = request.client_id;
22
+ if (clientId === undefined) {
23
+ return false;
24
+ }
25
+ const secretHash = (await deps.clients.find(clientId))?.secretHash ?? null;
26
+ if (secretHash === null) {
27
+ return request.client_secret === undefined;
28
+ }
29
+ return request.client_secret !== undefined && deps.secrets.hashOf(request.client_secret) === secretHash;
30
+ };
31
+ const issue = async (from) => {
32
+ const accessToken = deps.secrets.newSecret();
33
+ const refreshToken = deps.secrets.newSecret();
34
+ const now = deps.clock.now().getTime();
35
+ await deps.tokens.save({
36
+ ...from,
37
+ accessHash: deps.secrets.hashOf(accessToken),
38
+ accessExpiresAt: new Date(now + ACCESS_TOKEN_LIFETIME_MS),
39
+ refreshHash: deps.secrets.hashOf(refreshToken),
40
+ refreshExpiresAt: new Date(now + REFRESH_TOKEN_LIFETIME_MS),
41
+ });
42
+ return { accessToken, refreshToken, expiresInSeconds: ACCESS_TOKEN_LIFETIME_MS / MS_PER_SECOND, scope: from.scope };
43
+ };
44
+ const fromCode = async (request) => {
45
+ const { code, code_verifier: verifier } = request;
46
+ if (code === undefined || verifier === undefined) {
47
+ return refusal('invalid_request', 'A code and its PKCE verifier are required');
48
+ }
49
+ if (request.resource !== undefined && request.resource !== deps.resource) {
50
+ return refusal('invalid_target', `The resource must be ${deps.resource}`);
51
+ }
52
+ const taken = await deps.codes.take(deps.secrets.hashOf(code));
53
+ if (!taken) {
54
+ return refusal('invalid_grant', 'No such code');
55
+ }
56
+ if (taken.wasUsed) {
57
+ await deps.tokens.revokeIssuedBy(taken.code.codeHash);
58
+ return refusal('invalid_grant', 'The code was used before; the tokens it gave are revoked');
59
+ }
60
+ const issued = taken.code;
61
+ const isValid = issued.expiresAt.getTime() > deps.clock.now().getTime() &&
62
+ issued.clientId === request.client_id &&
63
+ issued.redirectUri === request.redirect_uri &&
64
+ deps.secrets.challengeOf(verifier) === issued.codeChallenge;
65
+ if (!isValid) {
66
+ return refusal('invalid_grant', 'The code is expired, or was issued to another client, redirect URI or verifier');
67
+ }
68
+ const { codeHash, fleetId, clientId, resource, scope } = issued;
69
+ return ok(await issue({ familyId: codeHash, codeHash, fleetId, clientId, resource, scope, ...holderOf(issued) }));
70
+ };
71
+ const fromRefreshToken = async (request) => {
72
+ if (request.refresh_token === undefined) {
73
+ return refusal('invalid_request', 'A refresh token is required');
74
+ }
75
+ const refreshHash = deps.secrets.hashOf(request.refresh_token);
76
+ const pair = await deps.tokens.findByRefresh(refreshHash);
77
+ if (!pair || pair.clientId !== request.client_id || pair.refreshExpiresAt.getTime() <= deps.clock.now().getTime() || pair.state === 'revoked') {
78
+ return refusal('invalid_grant', 'No such refresh token for this client, or it expired');
79
+ }
80
+ if (!(await deps.tokens.rotate(refreshHash))) {
81
+ await deps.tokens.revokeFamily(pair.familyId);
82
+ return refusal('invalid_grant', 'The refresh token was used before; its tokens are revoked');
83
+ }
84
+ const { familyId, codeHash, fleetId, clientId, resource, scope } = pair;
85
+ return ok(await issue({ familyId, codeHash, fleetId, clientId, resource, scope, ...holderOf(pair) }));
86
+ };
87
+ return async (request) => {
88
+ const grantType = request.grant_type;
89
+ if (grantType !== 'authorization_code' && grantType !== 'refresh_token') {
90
+ return refusal('unsupported_grant_type', 'Only authorization_code and refresh_token are served');
91
+ }
92
+ if (!(await isAuthenticated(request))) {
93
+ return refusal('invalid_client', 'The client could not be authenticated');
94
+ }
95
+ return grantType === 'authorization_code' ? fromCode(request) : fromRefreshToken(request);
96
+ };
97
+ }
98
+ //# sourceMappingURL=exchange-token.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exchange-token.js","sourceRoot":"","sources":["../../../src/core/oauth/exchange-token.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import type { FleetId } from '@aeolus-fleet/common';
2
+ import type { Clock } from '../shared/clock.js';
3
+ import type { AuthorizationCodes, OAuthSecrets, TokenHolder } from './ports.js';
4
+ import type { AuthorizationRequest } from './read-authorization.js';
5
+ /** How long a code may be taken for tokens: one minute, within OAuth's ten (RFC 6749, 4.1.2). */
6
+ export declare const CODE_LIFETIME_MS = 60000;
7
+ /** The client's redirect URI with the answer's parameters added, its own query kept. */
8
+ export declare function redirectWith(redirectUri: string, parameters: Record<string, string | null>): string;
9
+ /**
10
+ * Issues a code bound to the client, its redirect URI, its PKCE challenge,
11
+ * the resource and whom it stands for, in the fleet; answers where the client
12
+ * is sent back with it and with the issuer (RFC 9207).
13
+ */
14
+ export declare function issueCode(deps: {
15
+ codes: AuthorizationCodes;
16
+ secrets: OAuthSecrets;
17
+ clock: Clock;
18
+ issuer: string;
19
+ }, issued: {
20
+ fleetId: FleetId;
21
+ authorization: AuthorizationRequest;
22
+ holder: TokenHolder;
23
+ }): Promise<string>;
@@ -0,0 +1,34 @@
1
+ /** How long a code may be taken for tokens: one minute, within OAuth's ten (RFC 6749, 4.1.2). */
2
+ export const CODE_LIFETIME_MS = 60_000;
3
+ /** The client's redirect URI with the answer's parameters added, its own query kept. */
4
+ export function redirectWith(redirectUri, parameters) {
5
+ const url = new URL(redirectUri);
6
+ for (const [name, value] of Object.entries(parameters)) {
7
+ if (value !== null) {
8
+ url.searchParams.append(name, value);
9
+ }
10
+ }
11
+ return url.toString();
12
+ }
13
+ /**
14
+ * Issues a code bound to the client, its redirect URI, its PKCE challenge,
15
+ * the resource and whom it stands for, in the fleet; answers where the client
16
+ * is sent back with it and with the issuer (RFC 9207).
17
+ */
18
+ export async function issueCode(deps, issued) {
19
+ const { fleetId, authorization, holder } = issued;
20
+ const code = deps.secrets.newSecret();
21
+ await deps.codes.save({
22
+ codeHash: deps.secrets.hashOf(code),
23
+ fleetId,
24
+ clientId: authorization.clientId,
25
+ redirectUri: authorization.redirectUri,
26
+ codeChallenge: authorization.codeChallenge,
27
+ resource: authorization.resource,
28
+ scope: authorization.scope,
29
+ expiresAt: new Date(deps.clock.now().getTime() + CODE_LIFETIME_MS),
30
+ ...holder,
31
+ });
32
+ return redirectWith(authorization.redirectUri, { code, state: authorization.state, iss: deps.issuer });
33
+ }
34
+ //# sourceMappingURL=issue-code.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"issue-code.js","sourceRoot":"","sources":["../../../src/core/oauth/issue-code.ts"],"names":[],"mappings":"AAMA,iGAAiG;AACjG,MAAM,CAAC,MAAM,gBAAgB,GAAG,MAAM,CAAC;AAEvC,wFAAwF;AACxF,MAAM,UAAU,YAAY,CAAC,WAAmB,EAAE,UAAyC;IACzF,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,WAAW,CAAC,CAAC;IACjC,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;QACvD,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YACnB,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACvC,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC,QAAQ,EAAE,CAAC;AACxB,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,IAAwF,EACxF,MAAsF;IAEtF,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC;IAClD,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;IACtC,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;QACpB,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC;QACnC,OAAO;QACP,QAAQ,EAAE,aAAa,CAAC,QAAQ;QAChC,WAAW,EAAE,aAAa,CAAC,WAAW;QACtC,aAAa,EAAE,aAAa,CAAC,aAAa;QAC1C,QAAQ,EAAE,aAAa,CAAC,QAAQ;QAChC,KAAK,EAAE,aAAa,CAAC,KAAK;QAC1B,SAAS,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,GAAG,gBAAgB,CAAC;QAClE,GAAG,MAAM;KACV,CAAC,CAAC;IACH,OAAO,YAAY,CAAC,aAAa,CAAC,WAAW,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,aAAa,CAAC,KAAK,EAAE,GAAG,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;AACzG,CAAC"}
@@ -0,0 +1,103 @@
1
+ /**
2
+ * The gateway's OAuth 2.1 authorization server for outside MCP clients
3
+ * (interop 3.1, MCP 2026-07-28 authorization): its clients, the codes it
4
+ * issues, the tokens it issues, and the secrets behind them.
5
+ */
6
+ import type { FleetId } from '@aeolus-fleet/common';
7
+ import type { Result } from '../shared/result.js';
8
+ /** A client argo pre-registered for its fleet. A confidential one has a secret, kept only as its hash. */
9
+ export interface OAuthClient {
10
+ readonly clientId: string;
11
+ readonly fleetId: FleetId;
12
+ readonly name: string;
13
+ readonly redirectUris: readonly string[];
14
+ readonly secretHash: string | null;
15
+ }
16
+ export interface OAuthClients {
17
+ find(clientId: string): Promise<OAuthClient | undefined>;
18
+ save(client: OAuthClient): Promise<void>;
19
+ }
20
+ /** Outbound port: a client's metadata document (CIMD), fetched from its client id URL, as JSON not yet read. */
21
+ export interface ClientMetadataDocuments {
22
+ fetch(url: string): Promise<Result<unknown, {
23
+ reason: string;
24
+ }>>;
25
+ }
26
+ /** A code argo's approval issued: used once, within its minute, by the client and redirect URI it was issued to. */
27
+ /**
28
+ * Whom a code and the tokens it leads to stand for: a party argo approved,
29
+ * the proxy ship its client calls the fleet as; or an account a person
30
+ * signed in as through pagasae, by its grant (decision 0054).
31
+ */
32
+ export type TokenHolder = {
33
+ readonly kind: 'party';
34
+ readonly party: string;
35
+ } | {
36
+ readonly kind: 'account';
37
+ readonly grantId: string;
38
+ };
39
+ export type AuthorizationCode = {
40
+ readonly codeHash: string;
41
+ readonly fleetId: FleetId;
42
+ readonly clientId: string;
43
+ readonly redirectUri: string;
44
+ /** The PKCE challenge, S256. */
45
+ readonly codeChallenge: string;
46
+ readonly resource: string;
47
+ readonly scope: string | null;
48
+ readonly expiresAt: Date;
49
+ } & TokenHolder;
50
+ export interface AuthorizationCodes {
51
+ save(code: AuthorizationCode): Promise<void>;
52
+ /** Marks the code used, at most once even under a race: the code, and whether it had been used before. */
53
+ take(codeHash: string): Promise<{
54
+ code: AuthorizationCode;
55
+ wasUsed: boolean;
56
+ } | undefined>;
57
+ }
58
+ /** An access token and its refresh token, issued together; a family is every pair one code led to. */
59
+ export type TokenPair = {
60
+ readonly familyId: string;
61
+ readonly codeHash: string;
62
+ readonly fleetId: FleetId;
63
+ readonly clientId: string;
64
+ readonly resource: string;
65
+ readonly scope: string | null;
66
+ readonly accessHash: string;
67
+ readonly accessExpiresAt: Date;
68
+ readonly refreshHash: string;
69
+ readonly refreshExpiresAt: Date;
70
+ } & TokenHolder;
71
+ export interface IssuedTokens {
72
+ /** A new pair, active. */
73
+ save(pair: TokenPair): Promise<void>;
74
+ findByAccess(accessHash: string): Promise<(TokenPair & {
75
+ state: TokenState;
76
+ }) | undefined>;
77
+ findByRefresh(refreshHash: string): Promise<(TokenPair & {
78
+ state: TokenState;
79
+ }) | undefined>;
80
+ /** Marks an active pair rotated, at most once even under a race: whether this call did. */
81
+ rotate(refreshHash: string): Promise<boolean>;
82
+ revokeFamily(familyId: string): Promise<void>;
83
+ revokeIssuedBy(codeHash: string): Promise<void>;
84
+ /** Revokes every pair that stands for the account grant in the fleet: its person signs in again. */
85
+ revokeGrant(fleetId: FleetId, grantId: string): Promise<void>;
86
+ }
87
+ /** active: in use; rotated: its refresh token was traded for a new pair; revoked: refused for good. */
88
+ export type TokenState = 'active' | 'rotated' | 'revoked';
89
+ /** Outbound port: the secrets the server issues, how it keeps them, and PKCE's S256. */
90
+ export interface OAuthSecrets {
91
+ /** A new random secret, safe in a URL. */
92
+ newSecret(): string;
93
+ /** The hash a secret is kept as, and looked up by. */
94
+ hashOf(secret: string): string;
95
+ /** PKCE S256: BASE64URL(SHA256(verifier)). */
96
+ challengeOf(verifier: string): string;
97
+ }
98
+ /** OAuth's error codes the gateway answers (RFC 6749, RFC 8707). */
99
+ export type OAuthErrorCode = 'invalid_request' | 'invalid_client' | 'invalid_grant' | 'unsupported_grant_type' | 'unsupported_response_type' | 'invalid_target' | 'access_denied';
100
+ export interface OAuthError {
101
+ readonly error: OAuthErrorCode;
102
+ readonly description: string;
103
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=ports.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ports.js","sourceRoot":"","sources":["../../../src/core/oauth/ports.ts"],"names":[],"mappings":""}
@@ -0,0 +1,43 @@
1
+ import type { FleetId } from '@aeolus-fleet/common';
2
+ import { type Result } from '../shared/result.js';
3
+ import type { ClientMetadataDocuments, OAuthClients, OAuthErrorCode } from './ports.js';
4
+ /** An authorization request the gateway read and found valid, for argo to approve or deny. */
5
+ export interface AuthorizationRequest {
6
+ readonly clientId: string;
7
+ readonly clientName: string;
8
+ /** The fleet a pre-registered client belongs to; null for a client known by its metadata document. */
9
+ readonly clientFleetId: FleetId | null;
10
+ readonly redirectUri: string;
11
+ readonly codeChallenge: string;
12
+ readonly resource: string;
13
+ readonly scope: string | null;
14
+ readonly state: string | null;
15
+ }
16
+ /**
17
+ * Why a request is refused:
18
+ * - invalidClient: the client or its redirect URI is not known, so the page says so and sends nobody anywhere (RFC 6749, 4.1.2.1);
19
+ * - redirect: the client is known, so it is sent back to its redirect URI with the error.
20
+ */
21
+ export type AuthorizationRefusal = {
22
+ readonly kind: 'invalidClient';
23
+ readonly message: string;
24
+ } | {
25
+ readonly kind: 'redirect';
26
+ readonly redirectUri: string;
27
+ readonly error: OAuthErrorCode;
28
+ readonly description: string;
29
+ readonly state: string | null;
30
+ };
31
+ export type ReadAuthorization = (request: Readonly<Record<string, string | undefined>>) => Promise<Result<AuthorizationRequest, AuthorizationRefusal>>;
32
+ /**
33
+ * Use case: the gateway reads an authorization request from an MCP client
34
+ * (OAuth 2.1 with PKCE, MCP 2026-07-28). The client is pre-registered, or
35
+ * known by its metadata document (CIMD), fetched from its client id. Only
36
+ * the S256 challenge is taken, and the resource must be the gateway's MCP
37
+ * endpoint (RFC 8707), so a token is bound to it.
38
+ */
39
+ export declare function createReadAuthorization(deps: {
40
+ clients: OAuthClients;
41
+ documents: ClientMetadataDocuments;
42
+ resource: string;
43
+ }): ReadAuthorization;
@@ -0,0 +1,74 @@
1
+ import { z } from 'zod';
2
+ import { err, ok } from '../shared/result.js';
3
+ import { isLoopback, isRedirectUri } from './redirect-uri.js';
4
+ /** A client's metadata document (CIMD), as far as the gateway reads it. */
5
+ const metadataDocumentSchema = z.object({
6
+ client_id: z.string(),
7
+ client_name: z.string().min(1).optional(),
8
+ redirect_uris: z.array(z.string()).min(1),
9
+ });
10
+ /** A client id that is a metadata document's URL: https, or http on this machine, with a path. */
11
+ function metadataDocumentUrl(clientId) {
12
+ let url;
13
+ try {
14
+ url = new URL(clientId);
15
+ }
16
+ catch {
17
+ return undefined;
18
+ }
19
+ const isSecure = url.protocol === 'https:' || (url.protocol === 'http:' && isLoopback(url));
20
+ return isSecure && url.pathname !== '/' && url.hash === '' ? url : undefined;
21
+ }
22
+ /**
23
+ * Use case: the gateway reads an authorization request from an MCP client
24
+ * (OAuth 2.1 with PKCE, MCP 2026-07-28). The client is pre-registered, or
25
+ * known by its metadata document (CIMD), fetched from its client id. Only
26
+ * the S256 challenge is taken, and the resource must be the gateway's MCP
27
+ * endpoint (RFC 8707), so a token is bound to it.
28
+ */
29
+ export function createReadAuthorization(deps) {
30
+ const knownClient = async (clientId) => {
31
+ const url = metadataDocumentUrl(clientId);
32
+ if (url === undefined) {
33
+ const client = await deps.clients.find(clientId);
34
+ return client ? ok({ name: client.name, fleetId: client.fleetId, redirectUris: client.redirectUris }) : err(`No client ${clientId} is registered`);
35
+ }
36
+ const fetched = await deps.documents.fetch(url.toString());
37
+ if (!fetched.isOk) {
38
+ return err(`The client's metadata document at ${clientId} could not be read: ${fetched.error.reason}`);
39
+ }
40
+ const document = metadataDocumentSchema.safeParse(fetched.value);
41
+ if (!document.success || document.data.client_id !== clientId || !document.data.redirect_uris.every(isRedirectUri)) {
42
+ return err(`The client's metadata document at ${clientId} does not name it, or names no valid redirect URI`);
43
+ }
44
+ return ok({ name: document.data.client_name ?? url.hostname, fleetId: null, redirectUris: document.data.redirect_uris });
45
+ };
46
+ return async (request) => {
47
+ const clientId = request.client_id;
48
+ if (clientId === undefined || clientId === '') {
49
+ return err({ kind: 'invalidClient', message: 'The request names no client' });
50
+ }
51
+ const client = await knownClient(clientId);
52
+ if (!client.isOk) {
53
+ return err({ kind: 'invalidClient', message: client.error });
54
+ }
55
+ const redirectUri = request.redirect_uri;
56
+ if (redirectUri === undefined || !client.value.redirectUris.includes(redirectUri)) {
57
+ return err({ kind: 'invalidClient', message: `${client.value.name} registered no such redirect URI` });
58
+ }
59
+ const state = request.state ?? null;
60
+ const sendBack = (error, description) => err({ kind: 'redirect', redirectUri, error, description, state });
61
+ if (request.response_type !== 'code') {
62
+ return sendBack('unsupported_response_type', 'Only the authorization code flow is served');
63
+ }
64
+ const codeChallenge = request.code_challenge;
65
+ if (codeChallenge === undefined || codeChallenge === '' || request.code_challenge_method !== 'S256') {
66
+ return sendBack('invalid_request', 'A PKCE code challenge with the S256 method is required');
67
+ }
68
+ if (request.resource !== deps.resource) {
69
+ return sendBack('invalid_target', `The resource must be ${deps.resource}`);
70
+ }
71
+ return ok({ clientId, clientName: client.value.name, clientFleetId: client.value.fleetId, redirectUri, codeChallenge, resource: deps.resource, scope: request.scope ?? null, state });
72
+ };
73
+ }
74
+ //# sourceMappingURL=read-authorization.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read-authorization.js","sourceRoot":"","sources":["../../../src/core/oauth/read-authorization.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /** The most redirect URIs one client registers. */
2
+ export declare const REDIRECT_URIS_MAX = 10;
3
+ /** Whether a URL is served on this machine: plain http is allowed only there (OAuth 2.1, 8.4.2). */
4
+ export declare function isLoopback(url: URL): boolean;
5
+ /** A redirect URI a client may register: an absolute https URL, or http on loopback, with no fragment. */
6
+ export declare function isRedirectUri(text: string): boolean;
@@ -0,0 +1,20 @@
1
+ /** The most redirect URIs one client registers. */
2
+ export const REDIRECT_URIS_MAX = 10;
3
+ const LOOPBACK_HOSTS = new Set(['localhost', '127.0.0.1', '[::1]']);
4
+ /** Whether a URL is served on this machine: plain http is allowed only there (OAuth 2.1, 8.4.2). */
5
+ export function isLoopback(url) {
6
+ return LOOPBACK_HOSTS.has(url.hostname);
7
+ }
8
+ /** A redirect URI a client may register: an absolute https URL, or http on loopback, with no fragment. */
9
+ export function isRedirectUri(text) {
10
+ let url;
11
+ try {
12
+ url = new URL(text);
13
+ }
14
+ catch {
15
+ return false;
16
+ }
17
+ const isSecure = url.protocol === 'https:' || (url.protocol === 'http:' && isLoopback(url));
18
+ return isSecure && url.hash === '' && !text.includes('#');
19
+ }
20
+ //# sourceMappingURL=redirect-uri.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redirect-uri.js","sourceRoot":"","sources":["../../../src/core/oauth/redirect-uri.ts"],"names":[],"mappings":"AAAA,mDAAmD;AACnD,MAAM,CAAC,MAAM,iBAAiB,GAAG,EAAE,CAAC;AAEpC,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,CAAC,WAAW,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC;AAEpE,oGAAoG;AACpG,MAAM,UAAU,UAAU,CAAC,GAAQ;IACjC,OAAO,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;AAC1C,CAAC;AAED,0GAA0G;AAC1G,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,IAAI,GAAQ,CAAC;IACb,IAAI,CAAC;QACH,GAAG,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC;IACtB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;IACD,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,KAAK,QAAQ,IAAI,CAAC,GAAG,CAAC,QAAQ,KAAK,OAAO,IAAI,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;IAC5F,OAAO,QAAQ,IAAI,GAAG,CAAC,IAAI,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;AAC5D,CAAC"}
@@ -0,0 +1,22 @@
1
+ import type { FleetId } from '@aeolus-fleet/common';
2
+ import { type DomainError } from '../shared/errors.js';
3
+ import { type Result } from '../shared/result.js';
4
+ import type { OAuthClients, OAuthSecrets } from './ports.js';
5
+ export type RegisterClient = (input: {
6
+ fleetId: FleetId;
7
+ name: string;
8
+ redirectUris: readonly string[];
9
+ isConfidential: boolean;
10
+ }) => Promise<Result<{
11
+ clientId: string;
12
+ clientSecret: string | null;
13
+ }, DomainError<'INVALID_REDIRECT_URIS'>>>;
14
+ /**
15
+ * Use case: argo pre-registers an MCP client for its fleet, as MCP
16
+ * 2026-07-28 deprecates dynamic registration. A confidential client gets a
17
+ * secret, answered this once and kept only as its hash.
18
+ */
19
+ export declare function createRegisterClient(deps: {
20
+ clients: OAuthClients;
21
+ secrets: OAuthSecrets;
22
+ }): RegisterClient;
@@ -0,0 +1,20 @@
1
+ import { refuse } from '../shared/errors.js';
2
+ import { ok } from '../shared/result.js';
3
+ import { isRedirectUri, REDIRECT_URIS_MAX } from './redirect-uri.js';
4
+ /**
5
+ * Use case: argo pre-registers an MCP client for its fleet, as MCP
6
+ * 2026-07-28 deprecates dynamic registration. A confidential client gets a
7
+ * secret, answered this once and kept only as its hash.
8
+ */
9
+ export function createRegisterClient(deps) {
10
+ return async ({ fleetId, name, redirectUris, isConfidential }) => {
11
+ if (redirectUris.length === 0 || redirectUris.length > REDIRECT_URIS_MAX || !redirectUris.every(isRedirectUri)) {
12
+ return refuse('INVALID_REDIRECT_URIS', `A client registers 1 to ${String(REDIRECT_URIS_MAX)} redirect URIs, each https, or http on this machine, with no fragment`);
13
+ }
14
+ const clientId = `client-${deps.secrets.newSecret()}`;
15
+ const clientSecret = isConfidential ? deps.secrets.newSecret() : null;
16
+ await deps.clients.save({ clientId, fleetId, name, redirectUris: [...redirectUris], secretHash: clientSecret === null ? null : deps.secrets.hashOf(clientSecret) });
17
+ return ok({ clientId, clientSecret });
18
+ };
19
+ }
20
+ //# sourceMappingURL=register-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register-client.js","sourceRoot":"","sources":["../../../src/core/oauth/register-client.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAoB,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EAAE,EAAE,EAAe,MAAM,qBAAqB,CAAC;AAEtD,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AASrE;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAAC,IAAsD;IACzF,OAAO,KAAK,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,cAAc,EAAE,EAAE,EAAE;QAC/D,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,IAAI,YAAY,CAAC,MAAM,GAAG,iBAAiB,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,aAAa,CAAC,EAAE,CAAC;YAC/G,OAAO,MAAM,CAAC,uBAAuB,EAAE,2BAA2B,MAAM,CAAC,iBAAiB,CAAC,uEAAuE,CAAC,CAAC;QACtK,CAAC;QACD,MAAM,QAAQ,GAAG,UAAU,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC;QACtD,MAAM,YAAY,GAAG,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;QACtE,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,GAAG,YAAY,CAAC,EAAE,UAAU,EAAE,YAAY,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;QACpK,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,YAAY,EAAE,CAAC,CAAC;IACxC,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,22 @@
1
+ import type { ConsoleSessionOutput, FleetId, Scope } from '@aeolus-fleet/common';
2
+ import { type DomainError } from '../shared/errors.js';
3
+ import { type Result } from '../shared/result.js';
4
+ import type { ConsoleSessions } from './ports.js';
5
+ export type AuthenticateOperator = (cookie: string | undefined) => Promise<Result<{
6
+ fleetId: FleetId;
7
+ kind: ConsoleSessionOutput['kind'];
8
+ scopes: readonly Scope[];
9
+ }, DomainError<'NOT_THE_OPERATOR'>>>;
10
+ /**
11
+ * Use case: whether a request comes from argo. The gateway has no login of
12
+ * its own: its page and the console's server forward the console session
13
+ * cookie, and the fleet says whose session it is (decision 0043). The gateway
14
+ * serves every fleet at its FLEET_URL, each with its own connection, so any
15
+ * signed-in operator there is let through as the operator of their own
16
+ * fleet. A viewer session is let through as a viewer, with the viewer ship's
17
+ * scopes, which the fleet answers; what each may call is the API's to check
18
+ * (decision 0022).
19
+ */
20
+ export declare function createAuthenticateOperator(deps: {
21
+ sessions: ConsoleSessions;
22
+ }): AuthenticateOperator;
@@ -0,0 +1,26 @@
1
+ import { refuse } from '../shared/errors.js';
2
+ import { ok } from '../shared/result.js';
3
+ /**
4
+ * Use case: whether a request comes from argo. The gateway has no login of
5
+ * its own: its page and the console's server forward the console session
6
+ * cookie, and the fleet says whose session it is (decision 0043). The gateway
7
+ * serves every fleet at its FLEET_URL, each with its own connection, so any
8
+ * signed-in operator there is let through as the operator of their own
9
+ * fleet. A viewer session is let through as a viewer, with the viewer ship's
10
+ * scopes, which the fleet answers; what each may call is the API's to check
11
+ * (decision 0022).
12
+ */
13
+ export function createAuthenticateOperator(deps) {
14
+ const refusal = refuse('NOT_THE_OPERATOR', 'Sign in to the console of your fleet');
15
+ return async (cookie) => {
16
+ if (cookie === undefined) {
17
+ return refusal;
18
+ }
19
+ const session = await deps.sessions.check(cookie);
20
+ if (!session.isOk) {
21
+ return refusal;
22
+ }
23
+ return ok(session.value);
24
+ };
25
+ }
26
+ //# sourceMappingURL=authenticate-operator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authenticate-operator.js","sourceRoot":"","sources":["../../../src/core/operator/authenticate-operator.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAoB,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EAAE,EAAE,EAAe,MAAM,qBAAqB,CAAC;AAOtD;;;;;;;;;GASG;AACH,MAAM,UAAU,0BAA0B,CAAC,IAAmC;IAC5E,MAAM,OAAO,GAAG,MAAM,CAAC,kBAAkB,EAAE,sCAAsC,CAAC,CAAC;IACnF,OAAO,KAAK,EAAE,MAAM,EAAE,EAAE;QACtB,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACzB,OAAO,OAAO,CAAC;QACjB,CAAC;QACD,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAClD,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YAClB,OAAO,OAAO,CAAC;QACjB,CAAC;QACD,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAC3B,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,15 @@
1
+ import type { ConsoleSessionOutput, FleetId, Scope } from '@aeolus-fleet/common';
2
+ import type { FleetRefusal } from '../connection/ports.js';
3
+ import type { Result } from '../shared/result.js';
4
+ /**
5
+ * Outbound port: asks the fleet whether a forwarded console session cookie is
6
+ * a signed-in operator's or a viewer's (`console.session`, decisions 0012,
7
+ * 0022 and 0043), with its ship's scopes.
8
+ */
9
+ export interface ConsoleSessions {
10
+ check(cookie: string): Promise<Result<{
11
+ fleetId: FleetId;
12
+ kind: ConsoleSessionOutput['kind'];
13
+ scopes: readonly Scope[];
14
+ }, FleetRefusal>>;
15
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=ports.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ports.js","sourceRoot":"","sources":["../../../src/core/operator/ports.ts"],"names":[],"mappings":""}
@@ -0,0 +1,21 @@
1
+ import type { FleetId } from '@aeolus-fleet/common';
2
+ import type { FleetRefusal } from '../connection/ports.js';
3
+ import type { Result } from '../shared/result.js';
4
+ /** Whether a fleet's outside parties are on, and when it was last set; off for a fleet never set (interop I-3). */
5
+ export interface OutsidePartySwitches {
6
+ isOn(fleetId: FleetId): Promise<boolean>;
7
+ set(fleetId: FleetId, switched: {
8
+ isOn: boolean;
9
+ at: Date;
10
+ }): Promise<void>;
11
+ }
12
+ /** The credential an actor called the gateway with, passed on so the fleet answers as that actor. */
13
+ export interface ActorCredential {
14
+ cookie?: string;
15
+ crewToken?: string;
16
+ }
17
+ /** Outbound port: the fleet's network, as the actor reads it. */
18
+ export interface FleetNetwork {
19
+ /** Whether the fleet applies no network rules, so every ship reaches every ship. */
20
+ isOpen(as: ActorCredential): Promise<Result<boolean, FleetRefusal>>;
21
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=ports.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ports.js","sourceRoot":"","sources":["../../../src/core/outside-parties/ports.ts"],"names":[],"mappings":""}