@aeolus-fleet/gateway 0.0.0-stage → 0.28.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 (528) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +105 -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/page-sessions.d.ts +15 -0
  10. package/dist/adapters/crypto/page-sessions.js +40 -0
  11. package/dist/adapters/crypto/page-sessions.js.map +1 -0
  12. package/dist/adapters/crypto/request-hasher.d.ts +3 -0
  13. package/dist/adapters/crypto/request-hasher.js +4 -0
  14. package/dist/adapters/crypto/request-hasher.js.map +1 -0
  15. package/dist/adapters/crypto/request-ids.d.ts +4 -0
  16. package/dist/adapters/crypto/request-ids.js +7 -0
  17. package/dist/adapters/crypto/request-ids.js.map +1 -0
  18. package/dist/adapters/crypto/sealer.d.ts +14 -0
  19. package/dist/adapters/crypto/sealer.js +41 -0
  20. package/dist/adapters/crypto/sealer.js.map +1 -0
  21. package/dist/adapters/crypto/ship-aliases.d.ts +7 -0
  22. package/dist/adapters/crypto/ship-aliases.js +19 -0
  23. package/dist/adapters/crypto/ship-aliases.js.map +1 -0
  24. package/dist/adapters/crypto/sign-in-seals.d.ts +7 -0
  25. package/dist/adapters/crypto/sign-in-seals.js +25 -0
  26. package/dist/adapters/crypto/sign-in-seals.js.map +1 -0
  27. package/dist/adapters/crypto/waiting-seals.d.ts +3 -0
  28. package/dist/adapters/crypto/waiting-seals.js +24 -0
  29. package/dist/adapters/crypto/waiting-seals.js.map +1 -0
  30. package/dist/adapters/fleet/actor-door.d.ts +20 -0
  31. package/dist/adapters/fleet/actor-door.js +75 -0
  32. package/dist/adapters/fleet/actor-door.js.map +1 -0
  33. package/dist/adapters/fleet/console-sessions.d.ts +2 -0
  34. package/dist/adapters/fleet/console-sessions.js +23 -0
  35. package/dist/adapters/fleet/console-sessions.js.map +1 -0
  36. package/dist/adapters/fleet/core-version.d.ts +11 -0
  37. package/dist/adapters/fleet/core-version.js +18 -0
  38. package/dist/adapters/fleet/core-version.js.map +1 -0
  39. package/dist/adapters/fleet/fleet-network.d.ts +2 -0
  40. package/dist/adapters/fleet/fleet-network.js +34 -0
  41. package/dist/adapters/fleet/fleet-network.js.map +1 -0
  42. package/dist/adapters/fleet/logged-verified-facts.d.ts +13 -0
  43. package/dist/adapters/fleet/logged-verified-facts.js +18 -0
  44. package/dist/adapters/fleet/logged-verified-facts.js.map +1 -0
  45. package/dist/adapters/fleet/proxy-ship-reads.d.ts +7 -0
  46. package/dist/adapters/fleet/proxy-ship-reads.js +24 -0
  47. package/dist/adapters/fleet/proxy-ship-reads.js.map +1 -0
  48. package/dist/adapters/fleet/proxy-ships-as-actor.d.ts +3 -0
  49. package/dist/adapters/fleet/proxy-ships-as-actor.js +25 -0
  50. package/dist/adapters/fleet/proxy-ships-as-actor.js.map +1 -0
  51. package/dist/adapters/fleet/rest-fleet-door.d.ts +14 -0
  52. package/dist/adapters/fleet/rest-fleet-door.js +205 -0
  53. package/dist/adapters/fleet/rest-fleet-door.js.map +1 -0
  54. package/dist/adapters/http/add-server-page.d.ts +7 -0
  55. package/dist/adapters/http/add-server-page.js +175 -0
  56. package/dist/adapters/http/add-server-page.js.map +1 -0
  57. package/dist/adapters/http/delivery-page.d.ts +24 -0
  58. package/dist/adapters/http/delivery-page.js +115 -0
  59. package/dist/adapters/http/delivery-page.js.map +1 -0
  60. package/dist/adapters/http/html.d.ts +15 -0
  61. package/dist/adapters/http/html.js +53 -0
  62. package/dist/adapters/http/html.js.map +1 -0
  63. package/dist/adapters/http/live.d.ts +29 -0
  64. package/dist/adapters/http/live.js +100 -0
  65. package/dist/adapters/http/live.js.map +1 -0
  66. package/dist/adapters/http/mcp-endpoint.d.ts +20 -0
  67. package/dist/adapters/http/mcp-endpoint.js +164 -0
  68. package/dist/adapters/http/mcp-endpoint.js.map +1 -0
  69. package/dist/adapters/http/mcp-task.d.ts +45 -0
  70. package/dist/adapters/http/mcp-task.js +35 -0
  71. package/dist/adapters/http/mcp-task.js.map +1 -0
  72. package/dist/adapters/http/oauth-routes.d.ts +47 -0
  73. package/dist/adapters/http/oauth-routes.js +337 -0
  74. package/dist/adapters/http/oauth-routes.js.map +1 -0
  75. package/dist/adapters/http/outside-parties-page.d.ts +33 -0
  76. package/dist/adapters/http/outside-parties-page.js +153 -0
  77. package/dist/adapters/http/outside-parties-page.js.map +1 -0
  78. package/dist/adapters/http/outside-party-page.d.ts +7 -0
  79. package/dist/adapters/http/outside-party-page.js +212 -0
  80. package/dist/adapters/http/outside-party-page.js.map +1 -0
  81. package/dist/adapters/http/overview-page.d.ts +17 -0
  82. package/dist/adapters/http/overview-page.js +298 -0
  83. package/dist/adapters/http/overview-page.js.map +1 -0
  84. package/dist/adapters/http/parties-page.d.ts +7 -0
  85. package/dist/adapters/http/parties-page.js +139 -0
  86. package/dist/adapters/http/parties-page.js.map +1 -0
  87. package/dist/adapters/http/person-tools.d.ts +22 -0
  88. package/dist/adapters/http/person-tools.js +98 -0
  89. package/dist/adapters/http/person-tools.js.map +1 -0
  90. package/dist/adapters/http/scope-rows.d.ts +10 -0
  91. package/dist/adapters/http/scope-rows.js +30 -0
  92. package/dist/adapters/http/scope-rows.js.map +1 -0
  93. package/dist/adapters/http/signal.d.ts +61 -0
  94. package/dist/adapters/http/signal.js +263 -0
  95. package/dist/adapters/http/signal.js.map +1 -0
  96. package/dist/adapters/http/version.d.ts +6 -0
  97. package/dist/adapters/http/version.js +12 -0
  98. package/dist/adapters/http/version.js.map +1 -0
  99. package/dist/adapters/mcp/mcp-servers.d.ts +2 -0
  100. package/dist/adapters/mcp/mcp-servers.js +154 -0
  101. package/dist/adapters/mcp/mcp-servers.js.map +1 -0
  102. package/dist/adapters/oauth/client-metadata-documents.d.ts +9 -0
  103. package/dist/adapters/oauth/client-metadata-documents.js +25 -0
  104. package/dist/adapters/oauth/client-metadata-documents.js.map +1 -0
  105. package/dist/adapters/pagasae/pagasae-client.d.ts +8 -0
  106. package/dist/adapters/pagasae/pagasae-client.js +88 -0
  107. package/dist/adapters/pagasae/pagasae-client.js.map +1 -0
  108. package/dist/adapters/prisma/account-grants.d.ts +4 -0
  109. package/dist/adapters/prisma/account-grants.js +27 -0
  110. package/dist/adapters/prisma/account-grants.js.map +1 -0
  111. package/dist/adapters/prisma/calls.d.ts +4 -0
  112. package/dist/adapters/prisma/calls.js +35 -0
  113. package/dist/adapters/prisma/calls.js.map +1 -0
  114. package/dist/adapters/prisma/changes.d.ts +21 -0
  115. package/dist/adapters/prisma/changes.js +86 -0
  116. package/dist/adapters/prisma/changes.js.map +1 -0
  117. package/dist/adapters/prisma/client-calls.d.ts +4 -0
  118. package/dist/adapters/prisma/client-calls.js +59 -0
  119. package/dist/adapters/prisma/client-calls.js.map +1 -0
  120. package/dist/adapters/prisma/client.d.ts +8 -0
  121. package/dist/adapters/prisma/client.js +11 -0
  122. package/dist/adapters/prisma/client.js.map +1 -0
  123. package/dist/adapters/prisma/connection-store.d.ts +4 -0
  124. package/dist/adapters/prisma/connection-store.js +28 -0
  125. package/dist/adapters/prisma/connection-store.js.map +1 -0
  126. package/dist/adapters/prisma/fleet-forgetter.d.ts +4 -0
  127. package/dist/adapters/prisma/fleet-forgetter.js +10 -0
  128. package/dist/adapters/prisma/fleet-forgetter.js.map +1 -0
  129. package/dist/adapters/prisma/fleet-switches.d.ts +4 -0
  130. package/dist/adapters/prisma/fleet-switches.js +10 -0
  131. package/dist/adapters/prisma/fleet-switches.js.map +1 -0
  132. package/dist/adapters/prisma/generated/browser.d.ts +108 -0
  133. package/dist/adapters/prisma/generated/browser.js +18 -0
  134. package/dist/adapters/prisma/generated/browser.js.map +1 -0
  135. package/dist/adapters/prisma/generated/client.d.ts +127 -0
  136. package/dist/adapters/prisma/generated/client.js +38 -0
  137. package/dist/adapters/prisma/generated/client.js.map +1 -0
  138. package/dist/adapters/prisma/generated/commonInputTypes.d.ts +490 -0
  139. package/dist/adapters/prisma/generated/commonInputTypes.js +11 -0
  140. package/dist/adapters/prisma/generated/commonInputTypes.js.map +1 -0
  141. package/dist/adapters/prisma/generated/enums.d.ts +1 -0
  142. package/dist/adapters/prisma/generated/enums.js +12 -0
  143. package/dist/adapters/prisma/generated/enums.js.map +1 -0
  144. package/dist/adapters/prisma/generated/internal/class.d.ts +319 -0
  145. package/dist/adapters/prisma/generated/internal/class.js +50 -0
  146. package/dist/adapters/prisma/generated/internal/class.js.map +1 -0
  147. package/dist/adapters/prisma/generated/internal/prismaNamespace.d.ts +2102 -0
  148. package/dist/adapters/prisma/generated/internal/prismaNamespace.js +294 -0
  149. package/dist/adapters/prisma/generated/internal/prismaNamespace.js.map +1 -0
  150. package/dist/adapters/prisma/generated/internal/prismaNamespaceBrowser.d.ts +273 -0
  151. package/dist/adapters/prisma/generated/internal/prismaNamespaceBrowser.js +264 -0
  152. package/dist/adapters/prisma/generated/internal/prismaNamespaceBrowser.js.map +1 -0
  153. package/dist/adapters/prisma/generated/models/AccountGrant.d.ts +1088 -0
  154. package/dist/adapters/prisma/generated/models/AccountGrant.js +2 -0
  155. package/dist/adapters/prisma/generated/models/AccountGrant.js.map +1 -0
  156. package/dist/adapters/prisma/generated/models/AuthorizationCode.d.ts +1171 -0
  157. package/dist/adapters/prisma/generated/models/AuthorizationCode.js +2 -0
  158. package/dist/adapters/prisma/generated/models/AuthorizationCode.js.map +1 -0
  159. package/dist/adapters/prisma/generated/models/Call.d.ts +994 -0
  160. package/dist/adapters/prisma/generated/models/Call.js +2 -0
  161. package/dist/adapters/prisma/generated/models/Call.js.map +1 -0
  162. package/dist/adapters/prisma/generated/models/ClientCall.d.ts +1119 -0
  163. package/dist/adapters/prisma/generated/models/ClientCall.js +2 -0
  164. package/dist/adapters/prisma/generated/models/ClientCall.js.map +1 -0
  165. package/dist/adapters/prisma/generated/models/ClientCallReply.d.ts +1129 -0
  166. package/dist/adapters/prisma/generated/models/ClientCallReply.js +2 -0
  167. package/dist/adapters/prisma/generated/models/ClientCallReply.js.map +1 -0
  168. package/dist/adapters/prisma/generated/models/Connection.d.ts +1011 -0
  169. package/dist/adapters/prisma/generated/models/Connection.js +2 -0
  170. package/dist/adapters/prisma/generated/models/Connection.js.map +1 -0
  171. package/dist/adapters/prisma/generated/models/FleetSwitch.d.ts +945 -0
  172. package/dist/adapters/prisma/generated/models/FleetSwitch.js +2 -0
  173. package/dist/adapters/prisma/generated/models/FleetSwitch.js.map +1 -0
  174. package/dist/adapters/prisma/generated/models/InstallationRequest.d.ts +1030 -0
  175. package/dist/adapters/prisma/generated/models/InstallationRequest.js +2 -0
  176. package/dist/adapters/prisma/generated/models/InstallationRequest.js.map +1 -0
  177. package/dist/adapters/prisma/generated/models/IssuedToken.d.ts +1224 -0
  178. package/dist/adapters/prisma/generated/models/IssuedToken.js +2 -0
  179. package/dist/adapters/prisma/generated/models/IssuedToken.js.map +1 -0
  180. package/dist/adapters/prisma/generated/models/OAuthClient.d.ts +1005 -0
  181. package/dist/adapters/prisma/generated/models/OAuthClient.js +2 -0
  182. package/dist/adapters/prisma/generated/models/OAuthClient.js.map +1 -0
  183. package/dist/adapters/prisma/generated/models/OpenedDelivery.d.ts +1087 -0
  184. package/dist/adapters/prisma/generated/models/OpenedDelivery.js +2 -0
  185. package/dist/adapters/prisma/generated/models/OpenedDelivery.js.map +1 -0
  186. package/dist/adapters/prisma/generated/models/OutsidePartySwitch.d.ts +942 -0
  187. package/dist/adapters/prisma/generated/models/OutsidePartySwitch.js +2 -0
  188. package/dist/adapters/prisma/generated/models/OutsidePartySwitch.js.map +1 -0
  189. package/dist/adapters/prisma/generated/models/OwnerQuestion.d.ts +1035 -0
  190. package/dist/adapters/prisma/generated/models/OwnerQuestion.js +2 -0
  191. package/dist/adapters/prisma/generated/models/OwnerQuestion.js.map +1 -0
  192. package/dist/adapters/prisma/generated/models/Party.d.ts +1310 -0
  193. package/dist/adapters/prisma/generated/models/Party.js +2 -0
  194. package/dist/adapters/prisma/generated/models/Party.js.map +1 -0
  195. package/dist/adapters/prisma/generated/models/PendingRequest.d.ts +1252 -0
  196. package/dist/adapters/prisma/generated/models/PendingRequest.js +2 -0
  197. package/dist/adapters/prisma/generated/models/PendingRequest.js.map +1 -0
  198. package/dist/adapters/prisma/generated/models/PersonCrew.d.ts +974 -0
  199. package/dist/adapters/prisma/generated/models/PersonCrew.js +2 -0
  200. package/dist/adapters/prisma/generated/models/PersonCrew.js.map +1 -0
  201. package/dist/adapters/prisma/generated/models/RequestOutcomeNotice.d.ts +1120 -0
  202. package/dist/adapters/prisma/generated/models/RequestOutcomeNotice.js +2 -0
  203. package/dist/adapters/prisma/generated/models/RequestOutcomeNotice.js.map +1 -0
  204. package/dist/adapters/prisma/generated/models/ToolMark.d.ts +947 -0
  205. package/dist/adapters/prisma/generated/models/ToolMark.js +2 -0
  206. package/dist/adapters/prisma/generated/models/ToolMark.js.map +1 -0
  207. package/dist/adapters/prisma/generated/models.d.ts +19 -0
  208. package/dist/adapters/prisma/generated/models.js +2 -0
  209. package/dist/adapters/prisma/generated/models.js.map +1 -0
  210. package/dist/adapters/prisma/installation-requests.d.ts +4 -0
  211. package/dist/adapters/prisma/installation-requests.js +25 -0
  212. package/dist/adapters/prisma/installation-requests.js.map +1 -0
  213. package/dist/adapters/prisma/migrate.d.ts +5 -0
  214. package/dist/adapters/prisma/migrate.js +53 -0
  215. package/dist/adapters/prisma/migrate.js.map +1 -0
  216. package/dist/adapters/prisma/oauth-stores.d.ts +5 -0
  217. package/dist/adapters/prisma/oauth-stores.js +85 -0
  218. package/dist/adapters/prisma/oauth-stores.js.map +1 -0
  219. package/dist/adapters/prisma/opened-deliveries.d.ts +4 -0
  220. package/dist/adapters/prisma/opened-deliveries.js +29 -0
  221. package/dist/adapters/prisma/opened-deliveries.js.map +1 -0
  222. package/dist/adapters/prisma/outcome-notices.d.ts +4 -0
  223. package/dist/adapters/prisma/outcome-notices.js +24 -0
  224. package/dist/adapters/prisma/outcome-notices.js.map +1 -0
  225. package/dist/adapters/prisma/outside-party-switches.d.ts +4 -0
  226. package/dist/adapters/prisma/outside-party-switches.js +10 -0
  227. package/dist/adapters/prisma/outside-party-switches.js.map +1 -0
  228. package/dist/adapters/prisma/owner-questions.d.ts +8 -0
  229. package/dist/adapters/prisma/owner-questions.js +54 -0
  230. package/dist/adapters/prisma/owner-questions.js.map +1 -0
  231. package/dist/adapters/prisma/party-store.d.ts +7 -0
  232. package/dist/adapters/prisma/party-store.js +71 -0
  233. package/dist/adapters/prisma/party-store.js.map +1 -0
  234. package/dist/adapters/prisma/pending-requests.d.ts +11 -0
  235. package/dist/adapters/prisma/pending-requests.js +128 -0
  236. package/dist/adapters/prisma/pending-requests.js.map +1 -0
  237. package/dist/adapters/prisma/person-crews.d.ts +4 -0
  238. package/dist/adapters/prisma/person-crews.js +18 -0
  239. package/dist/adapters/prisma/person-crews.js.map +1 -0
  240. package/dist/adapters/prisma/tool-marks.d.ts +4 -0
  241. package/dist/adapters/prisma/tool-marks.js +15 -0
  242. package/dist/adapters/prisma/tool-marks.js.map +1 -0
  243. package/dist/adapters/timers/sleep.d.ts +3 -0
  244. package/dist/adapters/timers/sleep.js +11 -0
  245. package/dist/adapters/timers/sleep.js.map +1 -0
  246. package/dist/adapters/trpc/router.d.ts +606 -0
  247. package/dist/adapters/trpc/router.js +519 -0
  248. package/dist/adapters/trpc/router.js.map +1 -0
  249. package/dist/app.d.ts +43 -0
  250. package/dist/app.js +446 -0
  251. package/dist/app.js.map +1 -0
  252. package/dist/bin/aeolus-gateway.d.ts +2 -0
  253. package/dist/bin/aeolus-gateway.js +65 -0
  254. package/dist/bin/aeolus-gateway.js.map +1 -0
  255. package/dist/config.d.ts +41 -0
  256. package/dist/config.js +65 -0
  257. package/dist/config.js.map +1 -0
  258. package/dist/core/actors/authenticate-actor.d.ts +54 -0
  259. package/dist/core/actors/authenticate-actor.js +42 -0
  260. package/dist/core/actors/authenticate-actor.js.map +1 -0
  261. package/dist/core/actors/credential-of.d.ts +27 -0
  262. package/dist/core/actors/credential-of.js +25 -0
  263. package/dist/core/actors/credential-of.js.map +1 -0
  264. package/dist/core/connection/connect.d.ts +26 -0
  265. package/dist/core/connection/connect.js +58 -0
  266. package/dist/core/connection/connect.js.map +1 -0
  267. package/dist/core/connection/ports.d.ts +92 -0
  268. package/dist/core/connection/ports.js +2 -0
  269. package/dist/core/connection/ports.js.map +1 -0
  270. package/dist/core/connection/read-connection.d.ts +14 -0
  271. package/dist/core/connection/read-connection.js +24 -0
  272. package/dist/core/connection/read-connection.js.map +1 -0
  273. package/dist/core/installation/delete-fleet.d.ts +21 -0
  274. package/dist/core/installation/delete-fleet.js +21 -0
  275. package/dist/core/installation/delete-fleet.js.map +1 -0
  276. package/dist/core/installation/ports.d.ts +43 -0
  277. package/dist/core/installation/ports.js +2 -0
  278. package/dist/core/installation/ports.js.map +1 -0
  279. package/dist/core/installation/read-fleet.d.ts +18 -0
  280. package/dist/core/installation/read-fleet.js +9 -0
  281. package/dist/core/installation/read-fleet.js.map +1 -0
  282. package/dist/core/installation/request-id.d.ts +8 -0
  283. package/dist/core/installation/request-id.js +10 -0
  284. package/dist/core/installation/request-id.js.map +1 -0
  285. package/dist/core/installation/served.d.ts +12 -0
  286. package/dist/core/installation/served.js +8 -0
  287. package/dist/core/installation/served.js.map +1 -0
  288. package/dist/core/installation/set-fleet-enabled.d.ts +25 -0
  289. package/dist/core/installation/set-fleet-enabled.js +22 -0
  290. package/dist/core/installation/set-fleet-enabled.js.map +1 -0
  291. package/dist/core/mcp-in/call-tool.d.ts +42 -0
  292. package/dist/core/mcp-in/call-tool.js +82 -0
  293. package/dist/core/mcp-in/call-tool.js.map +1 -0
  294. package/dist/core/mcp-in/client-call.d.ts +51 -0
  295. package/dist/core/mcp-in/client-call.js +39 -0
  296. package/dist/core/mcp-in/client-call.js.map +1 -0
  297. package/dist/core/mcp-in/collect-replies.d.ts +22 -0
  298. package/dist/core/mcp-in/collect-replies.js +66 -0
  299. package/dist/core/mcp-in/collect-replies.js.map +1 -0
  300. package/dist/core/mcp-in/list-tools.d.ts +48 -0
  301. package/dist/core/mcp-in/list-tools.js +70 -0
  302. package/dist/core/mcp-in/list-tools.js.map +1 -0
  303. package/dist/core/mcp-in/ports.d.ts +108 -0
  304. package/dist/core/mcp-in/ports.js +2 -0
  305. package/dist/core/mcp-in/ports.js.map +1 -0
  306. package/dist/core/mcp-in/read-client-call.d.ts +23 -0
  307. package/dist/core/mcp-in/read-client-call.js +15 -0
  308. package/dist/core/mcp-in/read-client-call.js.map +1 -0
  309. package/dist/core/mcp-out/content-types.d.ts +12 -0
  310. package/dist/core/mcp-out/content-types.js +28 -0
  311. package/dist/core/mcp-out/content-types.js.map +1 -0
  312. package/dist/core/mcp-out/hand-call.d.ts +105 -0
  313. package/dist/core/mcp-out/hand-call.js +118 -0
  314. package/dist/core/mcp-out/hand-call.js.map +1 -0
  315. package/dist/core/mcp-out/mark-tool.d.ts +20 -0
  316. package/dist/core/mcp-out/mark-tool.js +17 -0
  317. package/dist/core/mcp-out/mark-tool.js.map +1 -0
  318. package/dist/core/mcp-out/ports.d.ts +66 -0
  319. package/dist/core/mcp-out/ports.js +2 -0
  320. package/dist/core/mcp-out/ports.js.map +1 -0
  321. package/dist/core/mcp-out/run-party.d.ts +26 -0
  322. package/dist/core/mcp-out/run-party.js +62 -0
  323. package/dist/core/mcp-out/run-party.js.map +1 -0
  324. package/dist/core/mcp-out/state-party.d.ts +39 -0
  325. package/dist/core/mcp-out/state-party.js +30 -0
  326. package/dist/core/mcp-out/state-party.js.map +1 -0
  327. package/dist/core/mcp-out/statement.d.ts +36 -0
  328. package/dist/core/mcp-out/statement.js +34 -0
  329. package/dist/core/mcp-out/statement.js.map +1 -0
  330. package/dist/core/oauth/authenticate-access-token.d.ts +25 -0
  331. package/dist/core/oauth/authenticate-access-token.js +19 -0
  332. package/dist/core/oauth/authenticate-access-token.js.map +1 -0
  333. package/dist/core/oauth/exchange-token.d.ts +32 -0
  334. package/dist/core/oauth/exchange-token.js +98 -0
  335. package/dist/core/oauth/exchange-token.js.map +1 -0
  336. package/dist/core/oauth/issue-code.d.ts +23 -0
  337. package/dist/core/oauth/issue-code.js +34 -0
  338. package/dist/core/oauth/issue-code.js.map +1 -0
  339. package/dist/core/oauth/ports.d.ts +105 -0
  340. package/dist/core/oauth/ports.js +2 -0
  341. package/dist/core/oauth/ports.js.map +1 -0
  342. package/dist/core/oauth/read-authorization.d.ts +43 -0
  343. package/dist/core/oauth/read-authorization.js +74 -0
  344. package/dist/core/oauth/read-authorization.js.map +1 -0
  345. package/dist/core/oauth/redirect-uri.d.ts +6 -0
  346. package/dist/core/oauth/redirect-uri.js +20 -0
  347. package/dist/core/oauth/redirect-uri.js.map +1 -0
  348. package/dist/core/oauth/register-client.d.ts +22 -0
  349. package/dist/core/oauth/register-client.js +20 -0
  350. package/dist/core/oauth/register-client.js.map +1 -0
  351. package/dist/core/operator/authenticate-operator.d.ts +22 -0
  352. package/dist/core/operator/authenticate-operator.js +26 -0
  353. package/dist/core/operator/authenticate-operator.js.map +1 -0
  354. package/dist/core/operator/ports.d.ts +15 -0
  355. package/dist/core/operator/ports.js +2 -0
  356. package/dist/core/operator/ports.js.map +1 -0
  357. package/dist/core/outside-parties/ports.d.ts +17 -0
  358. package/dist/core/outside-parties/ports.js +2 -0
  359. package/dist/core/outside-parties/ports.js.map +1 -0
  360. package/dist/core/outside-parties/set-outside-parties.d.ts +36 -0
  361. package/dist/core/outside-parties/set-outside-parties.js +38 -0
  362. package/dist/core/outside-parties/set-outside-parties.js.map +1 -0
  363. package/dist/core/parties/approve-party.d.ts +55 -0
  364. package/dist/core/parties/approve-party.js +127 -0
  365. package/dist/core/parties/approve-party.js.map +1 -0
  366. package/dist/core/parties/change-party.d.ts +42 -0
  367. package/dist/core/parties/change-party.js +49 -0
  368. package/dist/core/parties/change-party.js.map +1 -0
  369. package/dist/core/parties/check-server.d.ts +24 -0
  370. package/dist/core/parties/check-server.js +21 -0
  371. package/dist/core/parties/check-server.js.map +1 -0
  372. package/dist/core/parties/crew-party.d.ts +21 -0
  373. package/dist/core/parties/crew-party.js +29 -0
  374. package/dist/core/parties/crew-party.js.map +1 -0
  375. package/dist/core/parties/list-parties.d.ts +29 -0
  376. package/dist/core/parties/list-parties.js +39 -0
  377. package/dist/core/parties/list-parties.js.map +1 -0
  378. package/dist/core/parties/party.d.ts +52 -0
  379. package/dist/core/parties/party.js +24 -0
  380. package/dist/core/parties/party.js.map +1 -0
  381. package/dist/core/parties/ports.d.ts +74 -0
  382. package/dist/core/parties/ports.js +2 -0
  383. package/dist/core/parties/ports.js.map +1 -0
  384. package/dist/core/parties/read-party-tools.d.ts +22 -0
  385. package/dist/core/parties/read-party-tools.js +22 -0
  386. package/dist/core/parties/read-party-tools.js.map +1 -0
  387. package/dist/core/parties/retire-party.d.ts +29 -0
  388. package/dist/core/parties/retire-party.js +43 -0
  389. package/dist/core/parties/retire-party.js.map +1 -0
  390. package/dist/core/parties/shown-party.d.ts +27 -0
  391. package/dist/core/parties/shown-party.js +10 -0
  392. package/dist/core/parties/shown-party.js.map +1 -0
  393. package/dist/core/people/answer-delivery.d.ts +24 -0
  394. package/dist/core/people/answer-delivery.js +28 -0
  395. package/dist/core/people/answer-delivery.js.map +1 -0
  396. package/dist/core/people/crew-person-ship.d.ts +42 -0
  397. package/dist/core/people/crew-person-ship.js +59 -0
  398. package/dist/core/people/crew-person-ship.js.map +1 -0
  399. package/dist/core/people/done-delivery.d.ts +16 -0
  400. package/dist/core/people/done-delivery.js +9 -0
  401. package/dist/core/people/done-delivery.js.map +1 -0
  402. package/dist/core/people/inbox-entry.d.ts +14 -0
  403. package/dist/core/people/inbox-entry.js +11 -0
  404. package/dist/core/people/inbox-entry.js.map +1 -0
  405. package/dist/core/people/open-delivery.d.ts +30 -0
  406. package/dist/core/people/open-delivery.js +40 -0
  407. package/dist/core/people/open-delivery.js.map +1 -0
  408. package/dist/core/people/opened-of.d.ts +29 -0
  409. package/dist/core/people/opened-of.js +30 -0
  410. package/dist/core/people/opened-of.js.map +1 -0
  411. package/dist/core/people/person-crew.d.ts +39 -0
  412. package/dist/core/people/person-crew.js +61 -0
  413. package/dist/core/people/person-crew.js.map +1 -0
  414. package/dist/core/people/ports.d.ts +102 -0
  415. package/dist/core/people/ports.js +2 -0
  416. package/dist/core/people/ports.js.map +1 -0
  417. package/dist/core/people/read-inbox.d.ts +37 -0
  418. package/dist/core/people/read-inbox.js +36 -0
  419. package/dist/core/people/read-inbox.js.map +1 -0
  420. package/dist/core/requests/ask-for-client.d.ts +45 -0
  421. package/dist/core/requests/ask-for-client.js +33 -0
  422. package/dist/core/requests/ask-for-client.js.map +1 -0
  423. package/dist/core/requests/ask-for-server.d.ts +32 -0
  424. package/dist/core/requests/ask-for-server.js +42 -0
  425. package/dist/core/requests/ask-for-server.js.map +1 -0
  426. package/dist/core/requests/ask-owners.d.ts +28 -0
  427. package/dist/core/requests/ask-owners.js +85 -0
  428. package/dist/core/requests/ask-owners.js.map +1 -0
  429. package/dist/core/requests/decide-request.d.ts +53 -0
  430. package/dist/core/requests/decide-request.js +83 -0
  431. package/dist/core/requests/decide-request.js.map +1 -0
  432. package/dist/core/requests/expire-requests.d.ts +14 -0
  433. package/dist/core/requests/expire-requests.js +21 -0
  434. package/dist/core/requests/expire-requests.js.map +1 -0
  435. package/dist/core/requests/list-mine.d.ts +16 -0
  436. package/dist/core/requests/list-mine.js +20 -0
  437. package/dist/core/requests/list-mine.js.map +1 -0
  438. package/dist/core/requests/list-to-decide.d.ts +11 -0
  439. package/dist/core/requests/list-to-decide.js +13 -0
  440. package/dist/core/requests/list-to-decide.js.map +1 -0
  441. package/dist/core/requests/open-request.d.ts +21 -0
  442. package/dist/core/requests/open-request.js +26 -0
  443. package/dist/core/requests/open-request.js.map +1 -0
  444. package/dist/core/requests/outcome-notice.d.ts +13 -0
  445. package/dist/core/requests/outcome-notice.js +26 -0
  446. package/dist/core/requests/outcome-notice.js.map +1 -0
  447. package/dist/core/requests/ports.d.ts +191 -0
  448. package/dist/core/requests/ports.js +2 -0
  449. package/dist/core/requests/ports.js.map +1 -0
  450. package/dist/core/requests/read-waiting.d.ts +46 -0
  451. package/dist/core/requests/read-waiting.js +41 -0
  452. package/dist/core/requests/read-waiting.js.map +1 -0
  453. package/dist/core/requests/request-state.d.ts +5 -0
  454. package/dist/core/requests/request-state.js +10 -0
  455. package/dist/core/requests/request-state.js.map +1 -0
  456. package/dist/core/requests/tell-outcomes.d.ts +24 -0
  457. package/dist/core/requests/tell-outcomes.js +39 -0
  458. package/dist/core/requests/tell-outcomes.js.map +1 -0
  459. package/dist/core/requests/watch-waiting.d.ts +32 -0
  460. package/dist/core/requests/watch-waiting.js +31 -0
  461. package/dist/core/requests/watch-waiting.js.map +1 -0
  462. package/dist/core/shared/clock.d.ts +4 -0
  463. package/dist/core/shared/clock.js +2 -0
  464. package/dist/core/shared/clock.js.map +1 -0
  465. package/dist/core/shared/errors.d.ts +10 -0
  466. package/dist/core/shared/errors.js +6 -0
  467. package/dist/core/shared/errors.js.map +1 -0
  468. package/dist/core/shared/result.d.ts +16 -0
  469. package/dist/core/shared/result.js +7 -0
  470. package/dist/core/shared/result.js.map +1 -0
  471. package/dist/core/sign-in/account-token.d.ts +42 -0
  472. package/dist/core/sign-in/account-token.js +46 -0
  473. package/dist/core/sign-in/account-token.js.map +1 -0
  474. package/dist/core/sign-in/complete-sign-in.d.ts +66 -0
  475. package/dist/core/sign-in/complete-sign-in.js +73 -0
  476. package/dist/core/sign-in/complete-sign-in.js.map +1 -0
  477. package/dist/core/sign-in/end-sign-ins.d.ts +19 -0
  478. package/dist/core/sign-in/end-sign-ins.js +17 -0
  479. package/dist/core/sign-in/end-sign-ins.js.map +1 -0
  480. package/dist/core/sign-in/ports.d.ts +115 -0
  481. package/dist/core/sign-in/ports.js +2 -0
  482. package/dist/core/sign-in/ports.js.map +1 -0
  483. package/dist/core/sign-in/sign-out.d.ts +10 -0
  484. package/dist/core/sign-in/sign-out.js +9 -0
  485. package/dist/core/sign-in/sign-out.js.map +1 -0
  486. package/dist/core/sign-in/start-page-sign-in.d.ts +25 -0
  487. package/dist/core/sign-in/start-page-sign-in.js +30 -0
  488. package/dist/core/sign-in/start-page-sign-in.js.map +1 -0
  489. package/dist/core/sign-in/start-sign-in.d.ts +30 -0
  490. package/dist/core/sign-in/start-sign-in.js +25 -0
  491. package/dist/core/sign-in/start-sign-in.js.map +1 -0
  492. package/dist/core/vault/credential.d.ts +18 -0
  493. package/dist/core/vault/credential.js +2 -0
  494. package/dist/core/vault/credential.js.map +1 -0
  495. package/dist/outcome-worker.d.ts +29 -0
  496. package/dist/outcome-worker.js +60 -0
  497. package/dist/outcome-worker.js.map +1 -0
  498. package/dist/party-workers.d.ts +32 -0
  499. package/dist/party-workers.js +57 -0
  500. package/dist/party-workers.js.map +1 -0
  501. package/package.json +70 -4
  502. package/prisma.config.ts +18 -0
  503. package/src/adapters/prisma/migrations/20261018200000_init/migration.sql +35 -0
  504. package/src/adapters/prisma/migrations/20261018210000_parties/migration.sql +19 -0
  505. package/src/adapters/prisma/migrations/20261018220000_tool_marks/migration.sql +8 -0
  506. package/src/adapters/prisma/migrations/20261018230000_calls/migration.sql +13 -0
  507. package/src/adapters/prisma/migrations/20261019090000_oauth/migration.sql +60 -0
  508. package/src/adapters/prisma/migrations/20261019100000_client_parties/migration.sql +8 -0
  509. package/src/adapters/prisma/migrations/20261019110000_oauth_parties/migration.sql +5 -0
  510. package/src/adapters/prisma/migrations/20261019120000_client_calls/migration.sql +15 -0
  511. package/src/adapters/prisma/migrations/20261019130000_client_call_replies/migration.sql +20 -0
  512. package/src/adapters/prisma/migrations/20261019140000_identity_providers/migration.sql +10 -0
  513. package/src/adapters/prisma/migrations/20261020090000_no_identity_providers/migration.sql +2 -0
  514. package/src/adapters/prisma/migrations/20261020100000_account_grants_in_tokens/migration.sql +5 -0
  515. package/src/adapters/prisma/migrations/20261020110000_account_grants/migration.sql +15 -0
  516. package/src/adapters/prisma/migrations/20261020120000_person_crews/migration.sql +9 -0
  517. package/src/adapters/prisma/migrations/20261020130000_opened_deliveries/migration.sql +13 -0
  518. package/src/adapters/prisma/migrations/20261020140000_pending_requests/migration.sql +26 -0
  519. package/src/adapters/prisma/migrations/20261020150000_outside_party_switches/migration.sql +8 -0
  520. package/src/adapters/prisma/migrations/20261020160000_pending_requests_told/migration.sql +2 -0
  521. package/src/adapters/prisma/migrations/20261020170000_request_outcome_notices/migration.sql +17 -0
  522. package/src/adapters/prisma/migrations/20261020180000_owner_questions/migration.sql +11 -0
  523. package/src/adapters/prisma/migrations/20261020190000_request_changes/migration.sql +12 -0
  524. package/src/adapters/prisma/migrations/20261020200000_account_grant_scopes/migration.sql +2 -0
  525. package/src/adapters/prisma/migrations/20261020210000_party_owner_from_fleet/migration.sql +2 -0
  526. package/src/adapters/prisma/migrations/20261020220000_client_call_deadline_optional/migration.sql +2 -0
  527. package/src/adapters/prisma/migrations/migration_lock.toml +3 -0
  528. package/src/adapters/prisma/schema.prisma +312 -0
@@ -0,0 +1,7 @@
1
+ import type { FastifyInstance } from 'fastify';
2
+ import { type Context } from '../trpc/router.js';
3
+ import { type SignInWay } from './signal.js';
4
+ export declare function registerAddServerPage(server: FastifyInstance, deps: {
5
+ contextFor: (cookie: string | undefined) => Context;
6
+ signIn: SignInWay;
7
+ }): void;
@@ -0,0 +1,175 @@
1
+ /**
2
+ * Adding an outside MCP server (design B, Signal, screen 7; flow F10), for
3
+ * an actor holding fleet:manage, in three steps: its address and
4
+ * credential, the gateway's check of the tools it answers with, then its
5
+ * owner, when it is approved. The check keeps nothing, so the owner step
6
+ * carries the address and credential on in its form, on a page no cache
7
+ * keeps. Each step calls the gateway's own API as the caller, so the pages
8
+ * check nothing the API does not; they refuse a form sent from another
9
+ * origin.
10
+ */
11
+ import { randomUUID } from 'node:crypto';
12
+ import { idSchema } from '@aeolus-fleet/common';
13
+ import { TRPCError } from '@trpc/server';
14
+ import { getHTTPStatusCodeFromError } from '@trpc/server/http';
15
+ import { z } from 'zod';
16
+ import { gatewayRouter } from '../trpc/router.js';
17
+ import { acceptForms, escaped, isSameOrigin } from './html.js';
18
+ import { icon, ring, signalPage, signInPrompt, statusBadge } from './signal.js';
19
+ const HTTP_FORBIDDEN = 403;
20
+ const HTTP_SEE_OTHER = 303;
21
+ const HTTP_INTERNAL_ERROR = 500;
22
+ const LIST = '/outside-parties';
23
+ const PAGE = `${LIST}/add`;
24
+ const TITLE = 'Add MCP server';
25
+ const CONCURRENCY_LIMIT_DEFAULT = 4;
26
+ const formSchema = z.record(z.string(), z.string());
27
+ /** The credential fields a form sends, in the order the address step asks for them. */
28
+ const CREDENTIAL_FIELDS = ['credentialKind', 'token', 'clientId', 'clientSecret', 'issuer', 'scope'];
29
+ /** The steps of adding a server, as the design numbers them. */
30
+ const STEPS = ['Address', 'Check', 'Owner'];
31
+ function field(form, name) {
32
+ return form[name] ?? '';
33
+ }
34
+ function steps(current) {
35
+ const at = STEPS.indexOf(current);
36
+ const items = STEPS.map((step, index) => `<li class="${index <= at ? 'done' : ''}"${index === at ? ' aria-current="step"' : ''}>${String(index + 1)} ${step}</li>`).join('');
37
+ return `<ol class="steps">${items}</ol>`;
38
+ }
39
+ function head(current) {
40
+ return `<a class="back" href="${LIST}">${icon('arrowLeft', 14)}Outside parties</a><div class="lead"><h1>${TITLE}</h1></div>${steps(current)}`;
41
+ }
42
+ function alert(message) {
43
+ return message === undefined ? '' : `<section class="card alert tone-attention" role="alert"><p>${escaped(message)}</p></section>`;
44
+ }
45
+ function credentialOf(form) {
46
+ if (field(form, 'credentialKind') === 'clientCredentials') {
47
+ const scope = field(form, 'scope');
48
+ return { kind: 'clientCredentials', clientId: field(form, 'clientId'), clientSecret: field(form, 'clientSecret'), issuer: field(form, 'issuer'), ...(scope === '' ? {} : { scope }) };
49
+ }
50
+ return { kind: 'bearer', token: field(form, 'token') };
51
+ }
52
+ function addressBody(form, refusal) {
53
+ const isClient = field(form, 'credentialKind') === 'clientCredentials';
54
+ return `${head('Address')}${alert(refusal)}<section class="card"><form method="post" action="${PAGE}/check" style="display:grid;gap:12px">
55
+ <label class="field"><span>Streamable HTTP address</span><input type="url" name="url" value="${escaped(field(form, 'url'))}" placeholder="https://mcp.example.com/mcp" required></label>
56
+ <fieldset><legend>The server's credential</legend>
57
+ <label class="field"><span>Credential</span><select name="credentialKind"><option value="bearer">Bearer token</option><option value="clientCredentials"${isClient ? ' selected' : ''}>OAuth client credentials</option></select></label>
58
+ <label class="field"><span>Bearer token</span><input type="password" name="token"></label>
59
+ <label class="field"><span>Client id</span><input type="text" name="clientId" value="${escaped(field(form, 'clientId'))}"></label>
60
+ <label class="field"><span>Client secret</span><input type="password" name="clientSecret"></label>
61
+ <label class="field"><span>Issuer</span><input type="url" name="issuer" value="${escaped(field(form, 'issuer'))}"></label>
62
+ <label class="field"><span>Scope</span><input type="text" name="scope" value="${escaped(field(form, 'scope'))}"></label>
63
+ </fieldset>
64
+ <div class="actions"><button class="primary">${icon('check', 14)}Check the server</button></div></form></section>`;
65
+ }
66
+ /** A proxy ship's name offered from the server's address: its host's first name that says whose it is. */
67
+ function suggestedName(url) {
68
+ try {
69
+ const labels = new URL(url).hostname.split('.').filter((label) => label !== 'mcp' && label !== 'www');
70
+ return (labels[0] ?? '').toLowerCase().replaceAll(/[^a-z0-9]+/g, '-').replaceAll(/^-+|-+$/g, '');
71
+ }
72
+ catch {
73
+ return '';
74
+ }
75
+ }
76
+ /** The address and credential, carried on in the owner step's form. */
77
+ function carried(form) {
78
+ return ['url', ...CREDENTIAL_FIELDS].map((name) => `<input type="hidden" name="${name}" value="${escaped(field(form, name))}">`).join('');
79
+ }
80
+ function toolsCard(tools) {
81
+ const count = tools.length;
82
+ const rows = tools.map((tool) => `<li><span class="mono">${escaped(tool.name)}</span>${tool.description === undefined ? '' : `<span class="muted">${escaped(tool.description)}</span>`}</li>`).join('');
83
+ return `<section class="card" style="justify-items:center;text-align:center">${ring({ tone: 'ok', center: { count }, label: `${String(count)} ${count === 1 ? 'tool' : 'tools'}` })}${statusBadge({ tone: 'ok', icon: 'check', label: 'Server answers' })}<ul class="tool-rows">${rows}</ul></section>`;
84
+ }
85
+ function ownerBody(form, shown) {
86
+ const requestId = field(form, 'requestId') === '' ? randomUUID() : field(form, 'requestId');
87
+ const name = field(form, 'name') === '' ? suggestedName(field(form, 'url')) : field(form, 'name');
88
+ const limit = field(form, 'concurrencyLimit') === '' ? String(CONCURRENCY_LIMIT_DEFAULT) : field(form, 'concurrencyLimit');
89
+ return `${head(shown.tools === undefined ? 'Owner' : 'Check')}${alert(shown.refusal)}${shown.tools === undefined ? '' : toolsCard(shown.tools)}<section class="card"><h2>Its owner</h2>
90
+ <form method="post" action="${PAGE}" style="display:grid;gap:12px"><input type="hidden" name="requestId" value="${escaped(requestId)}">${carried(form)}
91
+ <p class="muted mono">${escaped(field(form, 'url'))}</p>
92
+ <label class="field"><span>Proxy ship's name</span><input type="text" name="name" value="${escaped(name)}" required></label>
93
+ <label class="field"><span>Owner</span><input type="text" name="ownerShipId" value="${escaped(field(form, 'ownerShipId'))}" placeholder="shp_..." required><span class="muted">A person ship. It answers for this server.</span></label>
94
+ <label class="field"><span>Calls at once</span><input type="number" name="concurrencyLimit" min="1" max="10" value="${escaped(limit)}"></label>
95
+ <div class="actions"><button class="primary">${icon('check', 14)}Add ${escaped(name === '' ? 'server' : name)}</button><a class="button" href="${PAGE}">Back to the address</a></div></form></section>`;
96
+ }
97
+ function html(reply, page) {
98
+ return reply
99
+ .code(page.status)
100
+ .type('text/html; charset=utf-8')
101
+ .header('cache-control', 'no-store')
102
+ .send(signalPage({ title: TITLE, tab: 'outsideParties', body: page.body, isSignedIn: page.isSignedIn }));
103
+ }
104
+ export function registerAddServerPage(server, deps) {
105
+ acceptForms(server);
106
+ /** Renders a step as the caller; a refusal shows the step it came from again, with why, or asks to sign in. */
107
+ const answer = async (exchange, step) => {
108
+ const { request, reply } = exchange;
109
+ const context = deps.contextFor(request.headers.cookie);
110
+ const actor = await context.authenticateActor({ cookie: context.cookie, crewToken: context.crewToken });
111
+ const isSignedIn = actor.isOk && actor.value.kind === 'account';
112
+ try {
113
+ if (!actor.isOk) {
114
+ throw new TRPCError({ code: 'UNAUTHORIZED', message: actor.error.message });
115
+ }
116
+ return await step.render(gatewayRouter.createCaller(context));
117
+ }
118
+ catch (error) {
119
+ if (!(error instanceof TRPCError)) {
120
+ throw error;
121
+ }
122
+ if (error.code === 'UNAUTHORIZED') {
123
+ return reply.code(getHTTPStatusCodeFromError(error)).type('text/html; charset=utf-8').send(signalPage({ title: TITLE, body: signInPrompt({ message: error.message, way: deps.signIn, returnTo: PAGE }) }));
124
+ }
125
+ const isInternal = error.code === 'INTERNAL_SERVER_ERROR';
126
+ return html(reply, { status: isInternal ? HTTP_INTERNAL_ERROR : getHTTPStatusCodeFromError(error), body: step.refused(isInternal ? 'Internal error' : error.message), isSignedIn });
127
+ }
128
+ };
129
+ const formOf = (request) => {
130
+ const form = formSchema.safeParse(request.body);
131
+ return form.success ? form.data : {};
132
+ };
133
+ server.get(PAGE, (request, reply) => answer({ request, reply }, {
134
+ render: () => html(reply, { status: 200, body: addressBody({}), isSignedIn: true }),
135
+ refused: (message) => addressBody({}, message),
136
+ }));
137
+ server.post(`${PAGE}/check`, (request, reply) => {
138
+ if (!isSameOrigin(request)) {
139
+ return reply.code(HTTP_FORBIDDEN).type('text/plain; charset=utf-8').send('A form for this page is sent only from this page.');
140
+ }
141
+ const form = formOf(request);
142
+ return answer({ request, reply }, {
143
+ render: async (caller) => {
144
+ const { tools } = await caller.parties.check({ url: field(form, 'url'), credential: credentialOf(form) });
145
+ return html(reply, { status: 200, body: ownerBody(form, { tools }), isSignedIn: true });
146
+ },
147
+ refused: (message) => addressBody(form, message),
148
+ });
149
+ });
150
+ server.post(PAGE, (request, reply) => {
151
+ if (!isSameOrigin(request)) {
152
+ return reply.code(HTTP_FORBIDDEN).type('text/plain; charset=utf-8').send('A form for this page is sent only from this page.');
153
+ }
154
+ const form = formOf(request);
155
+ return answer({ request, reply }, {
156
+ render: async (caller) => {
157
+ const ownerShipId = idSchema('ship').safeParse(field(form, 'ownerShipId').trim());
158
+ if (!ownerShipId.success) {
159
+ throw new TRPCError({ code: 'BAD_REQUEST', message: "The owner's ship id is not a ship id (shp_...)" });
160
+ }
161
+ const approved = await caller.parties.approve({
162
+ requestId: field(form, 'requestId'),
163
+ name: field(form, 'name'),
164
+ url: field(form, 'url'),
165
+ credential: credentialOf(form),
166
+ ownerShipId: ownerShipId.data,
167
+ concurrencyLimit: Number(field(form, 'concurrencyLimit')),
168
+ });
169
+ return reply.code(HTTP_SEE_OTHER).header('location', `${LIST}/${encodeURIComponent(approved.name)}`).send();
170
+ },
171
+ refused: (message) => ownerBody(form, { refusal: message }),
172
+ });
173
+ });
174
+ }
175
+ //# sourceMappingURL=add-server-page.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"add-server-page.js","sourceRoot":"","sources":["../../../src/adapters/http/add-server-page.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import type { FastifyInstance, FastifyReply, FastifyRequest } from 'fastify';
2
+ import { type Context } from '../trpc/router.js';
3
+ /** Where the person goes once a delivery is dealt with, or when it no longer waits. */
4
+ export declare const OVERVIEW = "/overview";
5
+ /** A delivery the inbox lists, as the Overview shows it: opening it is a form, as it acknowledges the delivery. */
6
+ export declare function waitingItem(entry: {
7
+ deliveryId: string;
8
+ from: string;
9
+ title: string;
10
+ }): string;
11
+ /** How the Overview answers a page of its own: it renders as the caller, and says why the API refused, or asks to sign in. */
12
+ export type PageAnswer = (exchange: {
13
+ request: FastifyRequest;
14
+ reply: FastifyReply;
15
+ render: (context: Context) => Promise<FastifyReply>;
16
+ onRefused?: (context: Context, refused: {
17
+ status: number;
18
+ message: string;
19
+ }) => FastifyReply | Promise<FastifyReply>;
20
+ }) => Promise<FastifyReply>;
21
+ /** The delivery forms, posted from the Overview, answered as the Overview answers its own pages. */
22
+ export declare function registerDeliveryPages(server: FastifyInstance, deps: {
23
+ answer: PageAnswer;
24
+ }): void;
@@ -0,0 +1,115 @@
1
+ /**
2
+ * A delivery that waits on a person, opened from the Overview (design B,
3
+ * Signal): one item in focus. Opening is the person's own act, so it is a
4
+ * form, never a link: the gateway acknowledges the delivery for them, and
5
+ * the page shows it whole once. A question is answered with one tap on a
6
+ * button that names the option it sends, the asker's pick on a dashed edge;
7
+ * any delivery may get a note as its answer, or be done with. Each form
8
+ * calls the gateway's own API as the person.
9
+ */
10
+ import { ANSWER_CONTENT_TYPE, answerSchema, isQuestionContentType, questionSchema } from '@aeolus-fleet/common';
11
+ import { TRPCError } from '@trpc/server';
12
+ import { z } from 'zod';
13
+ import { gatewayRouter } from '../trpc/router.js';
14
+ import { escaped, isSameOrigin } from './html.js';
15
+ import { icon, signalPage } from './signal.js';
16
+ /** Where the person goes once a delivery is dealt with, or when it no longer waits. */
17
+ export const OVERVIEW = '/overview';
18
+ const HTTP_FORBIDDEN = 403;
19
+ const HTTP_SEE_OTHER = 303;
20
+ const TITLE = 'Overview';
21
+ const formSchema = z.record(z.string(), z.string());
22
+ function deliveryPath(deliveryId, action) {
23
+ return `${OVERVIEW}/deliveries/${encodeURIComponent(deliveryId)}/${action}`;
24
+ }
25
+ /** A delivery the inbox lists, as the Overview shows it: opening it is a form, as it acknowledges the delivery. */
26
+ export function waitingItem(entry) {
27
+ return `<form method="post" action="${deliveryPath(entry.deliveryId, 'open')}"><button class="item"><span class="text"><span>${escaped(entry.title)}</span><span class="tag">${icon('users', 12)}${escaped(entry.from)}</span></span></button></form>`;
28
+ }
29
+ function parsedQuestion(opened) {
30
+ if (!isQuestionContentType(opened.contentType)) {
31
+ return undefined;
32
+ }
33
+ try {
34
+ const question = questionSchema.safeParse(JSON.parse(opened.payload));
35
+ return question.success ? question.data : undefined;
36
+ }
37
+ catch {
38
+ return undefined;
39
+ }
40
+ }
41
+ const NOTE_FIELD = '<label class="field"><span>Note</span><textarea name="note" rows="2" placeholder="Optional, sent with your answer"></textarea></label>';
42
+ function questionCard(opened, question) {
43
+ const picked = question.options.find((option) => option.key === question.pick.option);
44
+ const buttons = question.options
45
+ .map((option) => {
46
+ const isPick = option.key === question.pick.option;
47
+ return `<button class="${isPick ? 'primary pick' : ''}" name="option" value="${String(option.key)}" title="${escaped(option.detail)}">${icon(isPick ? 'check' : 'x', 14)}${escaped(option.label)}</button>`;
48
+ })
49
+ .join('');
50
+ const pickLine = picked === undefined ? '' : `<p class="muted">${escaped(picked.label)} is the pick of ${escaped(opened.from)}: ${escaped(question.pick.why)}</p>`;
51
+ return `<form method="post" action="${deliveryPath(opened.deliveryId, 'answer')}" style="display:grid;gap:12px"><input type="hidden" name="questionId" value="${escaped(question.id)}">
52
+ <p class="payload">${escaped(question.context)}</p>
53
+ <div class="answers">${buttons}</div>${pickLine}${NOTE_FIELD}<div class="actions"><button name="option" value="">Send the note alone</button></div></form>`;
54
+ }
55
+ function messageCard(opened) {
56
+ return `<pre class="payload">${escaped(opened.payload)}</pre>
57
+ <form method="post" action="${deliveryPath(opened.deliveryId, 'answer')}" style="display:grid;gap:12px">${NOTE_FIELD.replace('Optional, sent with your answer', 'Your answer')}<div class="actions"><button class="primary">Answer</button></div></form>
58
+ <form method="post" action="${deliveryPath(opened.deliveryId, 'done')}"><div class="actions"><button>${icon('check', 14)}Done</button></div></form>`;
59
+ }
60
+ function deliveryBody(opened) {
61
+ const question = parsedQuestion(opened);
62
+ const card = question === undefined ? messageCard(opened) : questionCard(opened, question);
63
+ return `<section class="card"><span class="tag">${icon('users', 12)}${escaped(opened.from)} · ${escaped(new Date(opened.sentAt).toUTCString())}</span><h2>${escaped(question?.title ?? opened.title)}</h2>${card}</section>`;
64
+ }
65
+ /** The answer a form sends: an option and a note, or a note alone, for a question; a note as plain text otherwise. */
66
+ function answerOf(form) {
67
+ const note = (form.note ?? '').trim();
68
+ const questionId = form.questionId;
69
+ if (questionId === undefined) {
70
+ if (note === '') {
71
+ throw new TRPCError({ code: 'BAD_REQUEST', message: 'Write your answer first' });
72
+ }
73
+ return { contentType: 'text/plain', payload: note };
74
+ }
75
+ const option = form.option ?? '';
76
+ const answer = answerSchema.safeParse({ questionId, ...(option === '' ? {} : { option: Number(option) }), ...(note === '' ? {} : { note }) });
77
+ if (!answer.success) {
78
+ throw new TRPCError({ code: 'BAD_REQUEST', message: 'Tap an option, or write a note' });
79
+ }
80
+ return { contentType: ANSWER_CONTENT_TYPE, payload: JSON.stringify(answer.data) };
81
+ }
82
+ function html(reply, page) {
83
+ return reply.code(page.status).type('text/html; charset=utf-8').header('cache-control', 'no-store').send(signalPage({ title: TITLE, tab: 'overview', body: page.body, isSignedIn: true }));
84
+ }
85
+ const HTTP_NOT_FOUND = 404;
86
+ function noLongerWaits(refused) {
87
+ return `<section class="card"><h2>This no longer waits for you</h2><p class="muted">${escaped(refused.message)}</p><div class="actions"><a class="button" href="${OVERVIEW}">Back to the overview</a></div></section>`;
88
+ }
89
+ /** The delivery forms, posted from the Overview, answered as the Overview answers its own pages. */
90
+ export function registerDeliveryPages(server, deps) {
91
+ const act = (action, run) => {
92
+ server.post(`${OVERVIEW}/deliveries/:deliveryId/${action}`, (request, reply) => {
93
+ if (!isSameOrigin(request)) {
94
+ return reply.code(HTTP_FORBIDDEN).type('text/plain; charset=utf-8').send('A form for this page is sent only from this page.');
95
+ }
96
+ const form = formSchema.safeParse(request.body);
97
+ return deps.answer({
98
+ request,
99
+ reply,
100
+ render: (context) => run({ caller: gatewayRouter.createCaller(context), deliveryId: request.params.deliveryId, form: form.success ? form.data : {}, reply }),
101
+ onRefused: (_context, refused) => html(reply, refused.status === HTTP_NOT_FOUND ? { status: refused.status, body: noLongerWaits(refused) } : { status: refused.status, body: `<section class="card alert tone-attention" role="alert"><p>${escaped(refused.message)}</p></section>` }),
102
+ });
103
+ });
104
+ };
105
+ act('open', async ({ caller, deliveryId, reply }) => html(reply, { status: 200, body: deliveryBody(await caller.people.open({ deliveryId })) }));
106
+ act('answer', async ({ caller, deliveryId, form, reply }) => {
107
+ await caller.people.answer({ deliveryId, ...answerOf(form) });
108
+ return reply.code(HTTP_SEE_OTHER).header('location', OVERVIEW).send();
109
+ });
110
+ act('done', async ({ caller, deliveryId, reply }) => {
111
+ await caller.people.done({ deliveryId });
112
+ return reply.code(HTTP_SEE_OTHER).header('location', OVERVIEW).send();
113
+ });
114
+ }
115
+ //# sourceMappingURL=delivery-page.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delivery-page.js","sourceRoot":"","sources":["../../../src/adapters/http/delivery-page.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * What the gateway's server-rendered pages share: escaping, the page
3
+ * layout and its style, forms, and the check that a form came from them.
4
+ */
5
+ import type { TRPCError } from '@trpc/server';
6
+ import type { FastifyInstance, FastifyRequest } from 'fastify';
7
+ export declare function escaped(text: string): string;
8
+ /** A whole page of the gateway's: its title, its body, and the shared style. */
9
+ export declare function layout(title: string, body: string): string;
10
+ /** A form from the gateway's own pages: its Origin is the gateway's, so no other site can send one with argo's cookie. */
11
+ export declare function isSameOrigin(request: FastifyRequest): boolean;
12
+ /** Parses form posts into their fields, once per server whichever page asks first. */
13
+ export declare function acceptForms(server: FastifyInstance): void;
14
+ /** Why the API refused, as a page says it: the form's fields that are not valid, or the API's message. */
15
+ export declare function refusalMessage(error: TRPCError): string;
@@ -0,0 +1,53 @@
1
+ import { z } from 'zod';
2
+ export function escaped(text) {
3
+ return text.replaceAll('&', '&amp;').replaceAll('<', '&lt;').replaceAll('>', '&gt;').replaceAll('"', '&quot;').replaceAll("'", '&#39;');
4
+ }
5
+ const STYLE = `
6
+ :root { color-scheme: light dark; --ink: #1b1f24; --muted: #5b6470; --line: #d5dae0; --paper: #ffffff; --accent: #0b5cad; --warn: #a3261b; }
7
+ @media (prefers-color-scheme: dark) { :root { --ink: #e6e9ed; --muted: #9aa3ad; --line: #39414a; --paper: #14181c; --accent: #6aa8ec; --warn: #f08a7e; } }
8
+ body { margin: 0 auto; max-width: 960px; padding: 24px 16px; font: 15px/1.5 system-ui, sans-serif; color: var(--ink); background: var(--paper); }
9
+ h1 { font-size: 22px; } h2 { font-size: 17px; margin-top: 32px; }
10
+ table { width: 100%; border-collapse: collapse; } th, td { text-align: left; padding: 8px; border-bottom: 1px solid var(--line); vertical-align: top; overflow-wrap: anywhere; }
11
+ form { display: grid; gap: 8px; margin: 8px 0; } form.inline { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
12
+ label { display: grid; gap: 2px; color: var(--muted); } input, select, button { font: inherit; padding: 6px 8px; }
13
+ button { color: var(--paper); background: var(--accent); border: 0; border-radius: 4px; cursor: pointer; }
14
+ .error { color: var(--warn); border: 1px solid var(--warn); padding: 8px 12px; border-radius: 4px; } .muted { color: var(--muted); }
15
+ `;
16
+ /** A whole page of the gateway's: its title, its body, and the shared style. */
17
+ export function layout(title, body) {
18
+ return documentOf({ title, head: '', body });
19
+ }
20
+ /** A page of the gateway: its title, its head and its body, with the shared style. */
21
+ function documentOf(page) {
22
+ return `<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1">${page.head}<title>${escaped(page.title)}</title><style>${STYLE}</style></head><body>${page.body}</body></html>`;
23
+ }
24
+ /** A form from the gateway's own pages: its Origin is the gateway's, so no other site can send one with argo's cookie. */
25
+ export function isSameOrigin(request) {
26
+ const origin = request.headers.origin;
27
+ if (origin === undefined) {
28
+ return false;
29
+ }
30
+ try {
31
+ return new URL(origin).host === request.headers.host;
32
+ }
33
+ catch {
34
+ return false;
35
+ }
36
+ }
37
+ /** Parses form posts into their fields, once per server whichever page asks first. */
38
+ export function acceptForms(server) {
39
+ if (!server.hasContentTypeParser('application/x-www-form-urlencoded')) {
40
+ // eslint-disable-next-line @typescript-eslint/max-params -- Fastify's parser signature.
41
+ server.addContentTypeParser('application/x-www-form-urlencoded', { parseAs: 'string' }, (_request, body, done) => {
42
+ done(null, Object.fromEntries(new URLSearchParams(String(body))));
43
+ });
44
+ }
45
+ }
46
+ /** Why the API refused, as a page says it: the form's fields that are not valid, or the API's message. */
47
+ export function refusalMessage(error) {
48
+ if (error.cause instanceof z.ZodError) {
49
+ return `The form is not valid: ${error.cause.issues.map((issue) => `${issue.path.join('.') || 'form'}: ${issue.message}`).join('; ')}`;
50
+ }
51
+ return error.code === 'INTERNAL_SERVER_ERROR' ? 'Internal error' : error.message;
52
+ }
53
+ //# sourceMappingURL=html.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"html.js","sourceRoot":"","sources":["../../../src/adapters/http/html.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,UAAU,OAAO,CAAC,IAAY;IAClC,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,UAAU,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;AAC1I,CAAC;AAED,MAAM,KAAK,GAAG;;;;;;;;;;CAUb,CAAC;AAEF,gFAAgF;AAChF,MAAM,UAAU,MAAM,CAAC,KAAa,EAAE,IAAY;IAChD,OAAO,UAAU,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;AAC/C,CAAC;AAED,sFAAsF;AACtF,SAAS,UAAU,CAAC,IAAmD;IACrE,OAAO,kIAAkI,IAAI,CAAC,IAAI,UAAU,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,kBAAkB,KAAK,wBAAwB,IAAI,CAAC,IAAI,gBAAgB,CAAC;AAC1P,CAAC;AAED,0HAA0H;AAC1H,MAAM,UAAU,YAAY,CAAC,OAAuB;IAClD,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC;IACtC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,CAAC;QACH,OAAO,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC;IACvD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,sFAAsF;AACtF,MAAM,UAAU,WAAW,CAAC,MAAuB;IACjD,IAAI,CAAC,MAAM,CAAC,oBAAoB,CAAC,mCAAmC,CAAC,EAAE,CAAC;QACtE,wFAAwF;QACxF,MAAM,CAAC,oBAAoB,CAAC,mCAAmC,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,CAAC,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE;YAC/G,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,WAAW,CAAC,IAAI,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QACpE,CAAC,CAAC,CAAC;IACL,CAAC;AACH,CAAC;AAED,0GAA0G;AAC1G,MAAM,UAAU,cAAc,CAAC,KAAgB;IAC7C,IAAI,KAAK,CAAC,KAAK,YAAY,CAAC,CAAC,QAAQ,EAAE,CAAC;QACtC,OAAO,0BAA0B,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,MAAM,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;IACzI,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,KAAK,uBAAuB,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC;AACnF,CAAC"}
@@ -0,0 +1,29 @@
1
+ import type { FleetId } from '@aeolus-fleet/common';
2
+ import type { FastifyInstance } from 'fastify';
3
+ import type { Change } from '../prisma/changes.js';
4
+ import type { Context } from '../trpc/router.js';
5
+ /** A page the live channel serves: its sections' HTML by name, read as the caller, from the page's query. */
6
+ export interface LivePage {
7
+ render(context: Context, params: URLSearchParams): Promise<Record<string, string>>;
8
+ }
9
+ interface Listener {
10
+ readonly fleetId: FleetId;
11
+ readonly read: () => void;
12
+ }
13
+ /** Hands each change to the sockets of its fleet, on this gateway. */
14
+ export interface ChangeHub {
15
+ publish: (change: Change) => void;
16
+ /** Every socket reads its page again: changes may have been missed. */
17
+ resync: () => void;
18
+ subscribe: (listener: Listener) => () => void;
19
+ listeners: () => number;
20
+ }
21
+ export declare function createChangeHub(): ChangeHub;
22
+ /** Serves websockets on the server, once whichever route asks first; its routes register once it is loaded. */
23
+ export declare function acceptWebsockets(server: FastifyInstance, routes: () => void): void;
24
+ export declare function registerLive(server: FastifyInstance, deps: {
25
+ contextFor: (cookie: string | undefined) => Context;
26
+ hub: ChangeHub;
27
+ pages: Record<string, LivePage>;
28
+ }): void;
29
+ export {};
@@ -0,0 +1,100 @@
1
+ /**
2
+ * The pages' live channel: a page whose content changes opens a websocket
3
+ * on /live naming itself, and is sent its sections again whenever its
4
+ * fleet's requests change, so it never reloads itself or polls. A change
5
+ * carries no content: each socket reads its page again through the
6
+ * gateway's API as its own caller, so it is never sent what its actor may
7
+ * not see. Only the gateway's own pages open it: a socket from another
8
+ * origin, with no session, or for a page that is not live is closed.
9
+ */
10
+ import websocket from '@fastify/websocket';
11
+ import { isSameOrigin } from './html.js';
12
+ /** Why a socket was closed, as the page reads it: it does not open again for these. */
13
+ const CLOSE_NO_SESSION = 4401;
14
+ const CLOSE_OTHER_ORIGIN = 4403;
15
+ const CLOSE_NOT_LIVE = 4404;
16
+ export function createChangeHub() {
17
+ const listening = new Set();
18
+ return {
19
+ publish: (change) => {
20
+ for (const listener of listening) {
21
+ if (listener.fleetId === change.fleetId) {
22
+ listener.read();
23
+ }
24
+ }
25
+ },
26
+ resync: () => {
27
+ for (const listener of listening) {
28
+ listener.read();
29
+ }
30
+ },
31
+ subscribe: (listener) => {
32
+ listening.add(listener);
33
+ return () => listening.delete(listener);
34
+ },
35
+ listeners: () => listening.size,
36
+ };
37
+ }
38
+ /** Reads a page again and sends it, one read at a time per socket, so an older read never lands after a newer one. */
39
+ function reader(send) {
40
+ let isReading = false;
41
+ let isWanted = false;
42
+ const run = async () => {
43
+ isReading = true;
44
+ while (isWanted) {
45
+ isWanted = false;
46
+ try {
47
+ const sections = await send.read();
48
+ if (send.socket.readyState === send.socket.OPEN) {
49
+ send.socket.send(JSON.stringify({ sections }));
50
+ }
51
+ }
52
+ catch {
53
+ // A read that failed leaves the page as it was; the next change reads it again.
54
+ }
55
+ }
56
+ isReading = false;
57
+ };
58
+ return () => {
59
+ isWanted = true;
60
+ if (!isReading) {
61
+ void run();
62
+ }
63
+ };
64
+ }
65
+ const servingWebsockets = new WeakSet();
66
+ /** Serves websockets on the server, once whichever route asks first; its routes register once it is loaded. */
67
+ export function acceptWebsockets(server, routes) {
68
+ if (!servingWebsockets.has(server)) {
69
+ servingWebsockets.add(server);
70
+ void server.register(websocket);
71
+ }
72
+ void server.after(routes);
73
+ }
74
+ export function registerLive(server, deps) {
75
+ acceptWebsockets(server, () => {
76
+ server.get('/live', { websocket: true }, async (socket, request) => {
77
+ if (!isSameOrigin(request)) {
78
+ socket.close(CLOSE_OTHER_ORIGIN, 'Opened only from the gateway pages');
79
+ return;
80
+ }
81
+ const params = new URLSearchParams(request.url.slice(request.url.indexOf('?') + 1));
82
+ const page = deps.pages[params.get('page') ?? ''];
83
+ if (page === undefined) {
84
+ socket.close(CLOSE_NOT_LIVE, 'No such live page');
85
+ return;
86
+ }
87
+ const context = deps.contextFor(request.headers.cookie);
88
+ const actor = await context.authenticateActor({ cookie: context.cookie, crewToken: context.crewToken });
89
+ if (!actor.isOk) {
90
+ socket.close(CLOSE_NO_SESSION, 'Sign in again');
91
+ return;
92
+ }
93
+ const read = reader({ socket, read: () => page.render(context, params) });
94
+ const unsubscribe = deps.hub.subscribe({ fleetId: actor.value.fleetId, read });
95
+ socket.on('close', unsubscribe);
96
+ read();
97
+ });
98
+ });
99
+ }
100
+ //# sourceMappingURL=live.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"live.js","sourceRoot":"","sources":["../../../src/adapters/http/live.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import type { FastifyInstance } from 'fastify';
2
+ import type { FleetId } from '@aeolus-fleet/common';
3
+ import type { AuthenticateAccessToken } from '../../core/oauth/authenticate-access-token.js';
4
+ import type { CallTool } from '../../core/mcp-in/call-tool.js';
5
+ import type { ListTools } from '../../core/mcp-in/list-tools.js';
6
+ import type { ReadClientCall } from '../../core/mcp-in/read-client-call.js';
7
+ import { type PersonToolsDeps } from './person-tools.js';
8
+ export interface McpEndpointDeps {
9
+ /** The MCP endpoint's URL, as tokens are bound to it. */
10
+ resource: string;
11
+ authenticateAccessToken: AuthenticateAccessToken;
12
+ listTools: ListTools;
13
+ callTool: CallTool;
14
+ readClientCall: ReadClientCall;
15
+ /** Whether the fleet's outside parties are on (interop I-3). */
16
+ servesOutsideParties: (fleetId: FleetId) => Promise<boolean>;
17
+ /** A signed-in person's tools, where people sign in (decision 0054). */
18
+ person?: PersonToolsDeps;
19
+ }
20
+ export declare function registerMcpEndpoint(server: FastifyInstance, deps: McpEndpointDeps): void;