@antasphere/chassis-server 1.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 (798) hide show
  1. package/LICENSE +82 -0
  2. package/dist/accounts/deletion.d.ts +163 -0
  3. package/dist/accounts/deletion.d.ts.map +1 -0
  4. package/dist/accounts/deletion.js +360 -0
  5. package/dist/accounts/deletion.js.map +1 -0
  6. package/dist/accounts/erasure-log.d.ts +66 -0
  7. package/dist/accounts/erasure-log.d.ts.map +1 -0
  8. package/dist/accounts/erasure-log.js +117 -0
  9. package/dist/accounts/erasure-log.js.map +1 -0
  10. package/dist/accounts/index.d.ts +6 -0
  11. package/dist/accounts/index.d.ts.map +1 -0
  12. package/dist/accounts/index.js +6 -0
  13. package/dist/accounts/index.js.map +1 -0
  14. package/dist/accounts/mint-refusal.d.ts +47 -0
  15. package/dist/accounts/mint-refusal.d.ts.map +1 -0
  16. package/dist/accounts/mint-refusal.js +59 -0
  17. package/dist/accounts/mint-refusal.js.map +1 -0
  18. package/dist/accounts/signup-duplicate.d.ts +14 -0
  19. package/dist/accounts/signup-duplicate.d.ts.map +1 -0
  20. package/dist/accounts/signup-duplicate.js +25 -0
  21. package/dist/accounts/signup-duplicate.js.map +1 -0
  22. package/dist/accounts/superadmin.d.ts +27 -0
  23. package/dist/accounts/superadmin.d.ts.map +1 -0
  24. package/dist/accounts/superadmin.js +46 -0
  25. package/dist/accounts/superadmin.js.map +1 -0
  26. package/dist/api/apikeys.d.ts +14 -0
  27. package/dist/api/apikeys.d.ts.map +1 -0
  28. package/dist/api/apikeys.js +124 -0
  29. package/dist/api/apikeys.js.map +1 -0
  30. package/dist/api/audit.d.ts +4 -0
  31. package/dist/api/audit.d.ts.map +1 -0
  32. package/dist/api/audit.js +75 -0
  33. package/dist/api/audit.js.map +1 -0
  34. package/dist/api/break-glass.d.ts +48 -0
  35. package/dist/api/break-glass.d.ts.map +1 -0
  36. package/dist/api/break-glass.js +217 -0
  37. package/dist/api/break-glass.js.map +1 -0
  38. package/dist/api/cli-auth.d.ts +84 -0
  39. package/dist/api/cli-auth.d.ts.map +1 -0
  40. package/dist/api/cli-auth.js +177 -0
  41. package/dist/api/cli-auth.js.map +1 -0
  42. package/dist/api/create-api.d.ts +123 -0
  43. package/dist/api/create-api.d.ts.map +1 -0
  44. package/dist/api/create-api.js +1165 -0
  45. package/dist/api/create-api.js.map +1 -0
  46. package/dist/api/demo-passes.d.ts +45 -0
  47. package/dist/api/demo-passes.d.ts.map +1 -0
  48. package/dist/api/demo-passes.js +143 -0
  49. package/dist/api/demo-passes.js.map +1 -0
  50. package/dist/api/errors.d.ts +5 -0
  51. package/dist/api/errors.d.ts.map +1 -0
  52. package/dist/api/errors.js +5 -0
  53. package/dist/api/errors.js.map +1 -0
  54. package/dist/api/export.d.ts +63 -0
  55. package/dist/api/export.d.ts.map +1 -0
  56. package/dist/api/export.js +393 -0
  57. package/dist/api/export.js.map +1 -0
  58. package/dist/api/files.d.ts +40 -0
  59. package/dist/api/files.d.ts.map +1 -0
  60. package/dist/api/files.js +150 -0
  61. package/dist/api/files.js.map +1 -0
  62. package/dist/api/index.d.ts +17 -0
  63. package/dist/api/index.d.ts.map +1 -0
  64. package/dist/api/index.js +17 -0
  65. package/dist/api/index.js.map +1 -0
  66. package/dist/api/invitations.d.ts +50 -0
  67. package/dist/api/invitations.d.ts.map +1 -0
  68. package/dist/api/invitations.js +313 -0
  69. package/dist/api/invitations.js.map +1 -0
  70. package/dist/api/members.d.ts +25 -0
  71. package/dist/api/members.d.ts.map +1 -0
  72. package/dist/api/members.js +522 -0
  73. package/dist/api/members.js.map +1 -0
  74. package/dist/api/onboarding.d.ts +26 -0
  75. package/dist/api/onboarding.d.ts.map +1 -0
  76. package/dist/api/onboarding.js +23 -0
  77. package/dist/api/onboarding.js.map +1 -0
  78. package/dist/api/openapi-doc.d.ts +21 -0
  79. package/dist/api/openapi-doc.d.ts.map +1 -0
  80. package/dist/api/openapi-doc.js +25 -0
  81. package/dist/api/openapi-doc.js.map +1 -0
  82. package/dist/api/projects.d.ts +24 -0
  83. package/dist/api/projects.d.ts.map +1 -0
  84. package/dist/api/projects.js +624 -0
  85. package/dist/api/projects.js.map +1 -0
  86. package/dist/api/scope-routes.d.ts +12 -0
  87. package/dist/api/scope-routes.d.ts.map +1 -0
  88. package/dist/api/scope-routes.js +2 -0
  89. package/dist/api/scope-routes.js.map +1 -0
  90. package/dist/api/sso-connect.d.ts +70 -0
  91. package/dist/api/sso-connect.d.ts.map +1 -0
  92. package/dist/api/sso-connect.js +164 -0
  93. package/dist/api/sso-connect.js.map +1 -0
  94. package/dist/api/sso-logout.d.ts +41 -0
  95. package/dist/api/sso-logout.d.ts.map +1 -0
  96. package/dist/api/sso-logout.js +34 -0
  97. package/dist/api/sso-logout.js.map +1 -0
  98. package/dist/api/teams.d.ts +43 -0
  99. package/dist/api/teams.d.ts.map +1 -0
  100. package/dist/api/teams.js +447 -0
  101. package/dist/api/teams.js.map +1 -0
  102. package/dist/api/workspaces.d.ts +114 -0
  103. package/dist/api/workspaces.d.ts.map +1 -0
  104. package/dist/api/workspaces.js +462 -0
  105. package/dist/api/workspaces.js.map +1 -0
  106. package/dist/apikeys/index.d.ts +3 -0
  107. package/dist/apikeys/index.d.ts.map +1 -0
  108. package/dist/apikeys/index.js +3 -0
  109. package/dist/apikeys/index.js.map +1 -0
  110. package/dist/apikeys/peppers.d.ts +53 -0
  111. package/dist/apikeys/peppers.d.ts.map +1 -0
  112. package/dist/apikeys/peppers.js +97 -0
  113. package/dist/apikeys/peppers.js.map +1 -0
  114. package/dist/apikeys/service.d.ts +56 -0
  115. package/dist/apikeys/service.d.ts.map +1 -0
  116. package/dist/apikeys/service.js +196 -0
  117. package/dist/apikeys/service.js.map +1 -0
  118. package/dist/app.d.ts +65 -0
  119. package/dist/app.d.ts.map +1 -0
  120. package/dist/app.js +142 -0
  121. package/dist/app.js.map +1 -0
  122. package/dist/audit/filters.d.ts +38 -0
  123. package/dist/audit/filters.d.ts.map +1 -0
  124. package/dist/audit/filters.js +97 -0
  125. package/dist/audit/filters.js.map +1 -0
  126. package/dist/audit/index.d.ts +3 -0
  127. package/dist/audit/index.d.ts.map +1 -0
  128. package/dist/audit/index.js +3 -0
  129. package/dist/audit/index.js.map +1 -0
  130. package/dist/audit/service.d.ts +65 -0
  131. package/dist/audit/service.d.ts.map +1 -0
  132. package/dist/audit/service.js +103 -0
  133. package/dist/audit/service.js.map +1 -0
  134. package/dist/boot.d.ts +8 -0
  135. package/dist/boot.d.ts.map +1 -0
  136. package/dist/boot.js +822 -0
  137. package/dist/boot.js.map +1 -0
  138. package/dist/constant-time.d.ts +3 -0
  139. package/dist/constant-time.d.ts.map +1 -0
  140. package/dist/constant-time.js +10 -0
  141. package/dist/constant-time.js.map +1 -0
  142. package/dist/email/driver.d.ts +16 -0
  143. package/dist/email/driver.d.ts.map +1 -0
  144. package/dist/email/driver.js +136 -0
  145. package/dist/email/driver.js.map +1 -0
  146. package/dist/email/index.d.ts +4 -0
  147. package/dist/email/index.d.ts.map +1 -0
  148. package/dist/email/index.js +4 -0
  149. package/dist/email/index.js.map +1 -0
  150. package/dist/email/shell.d.ts +72 -0
  151. package/dist/email/shell.d.ts.map +1 -0
  152. package/dist/email/shell.js +146 -0
  153. package/dist/email/shell.js.map +1 -0
  154. package/dist/email/templates.d.ts +83 -0
  155. package/dist/email/templates.d.ts.map +1 -0
  156. package/dist/email/templates.js +96 -0
  157. package/dist/email/templates.js.map +1 -0
  158. package/dist/entitlements/check.d.ts +140 -0
  159. package/dist/entitlements/check.d.ts.map +1 -0
  160. package/dist/entitlements/check.js +276 -0
  161. package/dist/entitlements/check.js.map +1 -0
  162. package/dist/entitlements/clock-skew.d.ts +27 -0
  163. package/dist/entitlements/clock-skew.d.ts.map +1 -0
  164. package/dist/entitlements/clock-skew.js +58 -0
  165. package/dist/entitlements/clock-skew.js.map +1 -0
  166. package/dist/entitlements/gate.d.ts +113 -0
  167. package/dist/entitlements/gate.d.ts.map +1 -0
  168. package/dist/entitlements/gate.js +430 -0
  169. package/dist/entitlements/gate.js.map +1 -0
  170. package/dist/entitlements/hub-machine-token.d.ts +83 -0
  171. package/dist/entitlements/hub-machine-token.d.ts.map +1 -0
  172. package/dist/entitlements/hub-machine-token.js +175 -0
  173. package/dist/entitlements/hub-machine-token.js.map +1 -0
  174. package/dist/entitlements/hub-subject.d.ts +32 -0
  175. package/dist/entitlements/hub-subject.d.ts.map +1 -0
  176. package/dist/entitlements/hub-subject.js +68 -0
  177. package/dist/entitlements/hub-subject.js.map +1 -0
  178. package/dist/entitlements/index.d.ts +9 -0
  179. package/dist/entitlements/index.d.ts.map +1 -0
  180. package/dist/entitlements/index.js +9 -0
  181. package/dist/entitlements/index.js.map +1 -0
  182. package/dist/entitlements/poster.d.ts +81 -0
  183. package/dist/entitlements/poster.d.ts.map +1 -0
  184. package/dist/entitlements/poster.js +169 -0
  185. package/dist/entitlements/poster.js.map +1 -0
  186. package/dist/entitlements/profiles.d.ts +121 -0
  187. package/dist/entitlements/profiles.d.ts.map +1 -0
  188. package/dist/entitlements/profiles.js +212 -0
  189. package/dist/entitlements/profiles.js.map +1 -0
  190. package/dist/entitlements/slot.d.ts +33 -0
  191. package/dist/entitlements/slot.d.ts.map +1 -0
  192. package/dist/entitlements/slot.js +75 -0
  193. package/dist/entitlements/slot.js.map +1 -0
  194. package/dist/env.d.ts +293 -0
  195. package/dist/env.d.ts.map +1 -0
  196. package/dist/env.js +383 -0
  197. package/dist/env.js.map +1 -0
  198. package/dist/files/http.d.ts +23 -0
  199. package/dist/files/http.d.ts.map +1 -0
  200. package/dist/files/http.js +66 -0
  201. package/dist/files/http.js.map +1 -0
  202. package/dist/files/index.d.ts +5 -0
  203. package/dist/files/index.d.ts.map +1 -0
  204. package/dist/files/index.js +5 -0
  205. package/dist/files/index.js.map +1 -0
  206. package/dist/files/serve.d.ts +43 -0
  207. package/dist/files/serve.d.ts.map +1 -0
  208. package/dist/files/serve.js +71 -0
  209. package/dist/files/serve.js.map +1 -0
  210. package/dist/files/service.d.ts +69 -0
  211. package/dist/files/service.d.ts.map +1 -0
  212. package/dist/files/service.js +188 -0
  213. package/dist/files/service.js.map +1 -0
  214. package/dist/files/spool.d.ts +21 -0
  215. package/dist/files/spool.d.ts.map +1 -0
  216. package/dist/files/spool.js +47 -0
  217. package/dist/files/spool.js.map +1 -0
  218. package/dist/identity/better-auth.d.ts +3927 -0
  219. package/dist/identity/better-auth.d.ts.map +1 -0
  220. package/dist/identity/better-auth.js +896 -0
  221. package/dist/identity/better-auth.js.map +1 -0
  222. package/dist/identity/demo-pass-plugin.d.ts +29 -0
  223. package/dist/identity/demo-pass-plugin.d.ts.map +1 -0
  224. package/dist/identity/demo-pass-plugin.js +88 -0
  225. package/dist/identity/demo-pass-plugin.js.map +1 -0
  226. package/dist/identity/demo-pass-rules.d.ts +84 -0
  227. package/dist/identity/demo-pass-rules.d.ts.map +1 -0
  228. package/dist/identity/demo-pass-rules.js +223 -0
  229. package/dist/identity/demo-pass-rules.js.map +1 -0
  230. package/dist/identity/demo-pass.d.ts +159 -0
  231. package/dist/identity/demo-pass.d.ts.map +1 -0
  232. package/dist/identity/demo-pass.js +319 -0
  233. package/dist/identity/demo-pass.js.map +1 -0
  234. package/dist/identity/hub-grant.d.ts +182 -0
  235. package/dist/identity/hub-grant.d.ts.map +1 -0
  236. package/dist/identity/hub-grant.js +594 -0
  237. package/dist/identity/hub-grant.js.map +1 -0
  238. package/dist/identity/hub-jwt.d.ts +22 -0
  239. package/dist/identity/hub-jwt.d.ts.map +1 -0
  240. package/dist/identity/hub-jwt.js +77 -0
  241. package/dist/identity/hub-jwt.js.map +1 -0
  242. package/dist/identity/hub-live-gate.d.ts +17 -0
  243. package/dist/identity/hub-live-gate.d.ts.map +1 -0
  244. package/dist/identity/hub-live-gate.js +146 -0
  245. package/dist/identity/hub-live-gate.js.map +1 -0
  246. package/dist/identity/hub-logout.d.ts +88 -0
  247. package/dist/identity/hub-logout.d.ts.map +1 -0
  248. package/dist/identity/hub-logout.js +158 -0
  249. package/dist/identity/hub-logout.js.map +1 -0
  250. package/dist/identity/hub-projection.d.ts +103 -0
  251. package/dist/identity/hub-projection.d.ts.map +1 -0
  252. package/dist/identity/hub-projection.js +130 -0
  253. package/dist/identity/hub-projection.js.map +1 -0
  254. package/dist/identity/hub-reconcile.d.ts +151 -0
  255. package/dist/identity/hub-reconcile.d.ts.map +1 -0
  256. package/dist/identity/hub-reconcile.js +400 -0
  257. package/dist/identity/hub-reconcile.js.map +1 -0
  258. package/dist/identity/hub-sso.d.ts +363 -0
  259. package/dist/identity/hub-sso.d.ts.map +1 -0
  260. package/dist/identity/hub-sso.js +536 -0
  261. package/dist/identity/hub-sso.js.map +1 -0
  262. package/dist/identity/hub-user-client.d.ts +222 -0
  263. package/dist/identity/hub-user-client.d.ts.map +1 -0
  264. package/dist/identity/hub-user-client.js +406 -0
  265. package/dist/identity/hub-user-client.js.map +1 -0
  266. package/dist/identity/index.d.ts +13 -0
  267. package/dist/identity/index.d.ts.map +1 -0
  268. package/dist/identity/index.js +13 -0
  269. package/dist/identity/index.js.map +1 -0
  270. package/dist/identity/oauth-jwt.d.ts +32 -0
  271. package/dist/identity/oauth-jwt.d.ts.map +1 -0
  272. package/dist/identity/oauth-jwt.js +122 -0
  273. package/dist/identity/oauth-jwt.js.map +1 -0
  274. package/dist/identity/resolve-membership.d.ts +28 -0
  275. package/dist/identity/resolve-membership.d.ts.map +1 -0
  276. package/dist/identity/resolve-membership.js +69 -0
  277. package/dist/identity/resolve-membership.js.map +1 -0
  278. package/dist/identity/signing-key.d.ts +49 -0
  279. package/dist/identity/signing-key.d.ts.map +1 -0
  280. package/dist/identity/signing-key.js +144 -0
  281. package/dist/identity/signing-key.js.map +1 -0
  282. package/dist/index.d.ts +21 -0
  283. package/dist/index.d.ts.map +1 -0
  284. package/dist/index.js +11 -0
  285. package/dist/index.js.map +1 -0
  286. package/dist/invitations/index.d.ts +2 -0
  287. package/dist/invitations/index.d.ts.map +1 -0
  288. package/dist/invitations/index.js +2 -0
  289. package/dist/invitations/index.js.map +1 -0
  290. package/dist/invitations/service.d.ts +36 -0
  291. package/dist/invitations/service.d.ts.map +1 -0
  292. package/dist/invitations/service.js +122 -0
  293. package/dist/invitations/service.js.map +1 -0
  294. package/dist/jobs/index.d.ts +3 -0
  295. package/dist/jobs/index.d.ts.map +1 -0
  296. package/dist/jobs/index.js +3 -0
  297. package/dist/jobs/index.js.map +1 -0
  298. package/dist/jobs/pgboss.d.ts +119 -0
  299. package/dist/jobs/pgboss.d.ts.map +1 -0
  300. package/dist/jobs/pgboss.js +521 -0
  301. package/dist/jobs/pgboss.js.map +1 -0
  302. package/dist/jobs/timers.d.ts +127 -0
  303. package/dist/jobs/timers.d.ts.map +1 -0
  304. package/dist/jobs/timers.js +228 -0
  305. package/dist/jobs/timers.js.map +1 -0
  306. package/dist/logger.d.ts +17 -0
  307. package/dist/logger.d.ts.map +1 -0
  308. package/dist/logger.js +64 -0
  309. package/dist/logger.js.map +1 -0
  310. package/dist/mcp/errors.d.ts +37 -0
  311. package/dist/mcp/errors.d.ts.map +1 -0
  312. package/dist/mcp/errors.js +77 -0
  313. package/dist/mcp/errors.js.map +1 -0
  314. package/dist/mcp/http.d.ts +35 -0
  315. package/dist/mcp/http.d.ts.map +1 -0
  316. package/dist/mcp/http.js +80 -0
  317. package/dist/mcp/http.js.map +1 -0
  318. package/dist/mcp/index.d.ts +8 -0
  319. package/dist/mcp/index.d.ts.map +1 -0
  320. package/dist/mcp/index.js +8 -0
  321. package/dist/mcp/index.js.map +1 -0
  322. package/dist/mcp/inputs.d.ts +19 -0
  323. package/dist/mcp/inputs.d.ts.map +1 -0
  324. package/dist/mcp/inputs.js +28 -0
  325. package/dist/mcp/inputs.js.map +1 -0
  326. package/dist/mcp/projects.d.ts +31 -0
  327. package/dist/mcp/projects.d.ts.map +1 -0
  328. package/dist/mcp/projects.js +315 -0
  329. package/dist/mcp/projects.js.map +1 -0
  330. package/dist/mcp/server.d.ts +52 -0
  331. package/dist/mcp/server.d.ts.map +1 -0
  332. package/dist/mcp/server.js +93 -0
  333. package/dist/mcp/server.js.map +1 -0
  334. package/dist/mcp/teams.d.ts +7 -0
  335. package/dist/mcp/teams.d.ts.map +1 -0
  336. package/dist/mcp/teams.js +62 -0
  337. package/dist/mcp/teams.js.map +1 -0
  338. package/dist/mcp/tool-kit.d.ts +67 -0
  339. package/dist/mcp/tool-kit.d.ts.map +1 -0
  340. package/dist/mcp/tool-kit.js +74 -0
  341. package/dist/mcp/tool-kit.js.map +1 -0
  342. package/dist/members/removal.d.ts +95 -0
  343. package/dist/members/removal.d.ts.map +1 -0
  344. package/dist/members/removal.js +143 -0
  345. package/dist/members/removal.js.map +1 -0
  346. package/dist/middleware/auth-body.d.ts +25 -0
  347. package/dist/middleware/auth-body.d.ts.map +1 -0
  348. package/dist/middleware/auth-body.js +55 -0
  349. package/dist/middleware/auth-body.js.map +1 -0
  350. package/dist/middleware/auth-context.d.ts +170 -0
  351. package/dist/middleware/auth-context.d.ts.map +1 -0
  352. package/dist/middleware/auth-context.js +251 -0
  353. package/dist/middleware/auth-context.js.map +1 -0
  354. package/dist/middleware/body-cap.d.ts +17 -0
  355. package/dist/middleware/body-cap.d.ts.map +1 -0
  356. package/dist/middleware/body-cap.js +31 -0
  357. package/dist/middleware/body-cap.js.map +1 -0
  358. package/dist/middleware/body-refusal.d.ts +20 -0
  359. package/dist/middleware/body-refusal.d.ts.map +1 -0
  360. package/dist/middleware/body-refusal.js +5 -0
  361. package/dist/middleware/body-refusal.js.map +1 -0
  362. package/dist/middleware/cross-site.d.ts +61 -0
  363. package/dist/middleware/cross-site.d.ts.map +1 -0
  364. package/dist/middleware/cross-site.js +59 -0
  365. package/dist/middleware/cross-site.js.map +1 -0
  366. package/dist/middleware/hub-managed.d.ts +45 -0
  367. package/dist/middleware/hub-managed.d.ts.map +1 -0
  368. package/dist/middleware/hub-managed.js +56 -0
  369. package/dist/middleware/hub-managed.js.map +1 -0
  370. package/dist/middleware/idempotency.d.ts +14 -0
  371. package/dist/middleware/idempotency.d.ts.map +1 -0
  372. package/dist/middleware/idempotency.js +222 -0
  373. package/dist/middleware/idempotency.js.map +1 -0
  374. package/dist/middleware/index.d.ts +12 -0
  375. package/dist/middleware/index.d.ts.map +1 -0
  376. package/dist/middleware/index.js +12 -0
  377. package/dist/middleware/index.js.map +1 -0
  378. package/dist/middleware/json-depth.d.ts +32 -0
  379. package/dist/middleware/json-depth.d.ts.map +1 -0
  380. package/dist/middleware/json-depth.js +80 -0
  381. package/dist/middleware/json-depth.js.map +1 -0
  382. package/dist/middleware/no-store.d.ts +21 -0
  383. package/dist/middleware/no-store.d.ts.map +1 -0
  384. package/dist/middleware/no-store.js +32 -0
  385. package/dist/middleware/no-store.js.map +1 -0
  386. package/dist/middleware/oauth-public.d.ts +16 -0
  387. package/dist/middleware/oauth-public.d.ts.map +1 -0
  388. package/dist/middleware/oauth-public.js +50 -0
  389. package/dist/middleware/oauth-public.js.map +1 -0
  390. package/dist/middleware/rate-limit.d.ts +182 -0
  391. package/dist/middleware/rate-limit.d.ts.map +1 -0
  392. package/dist/middleware/rate-limit.js +277 -0
  393. package/dist/middleware/rate-limit.js.map +1 -0
  394. package/dist/middleware/request-id.d.ts +10 -0
  395. package/dist/middleware/request-id.d.ts.map +1 -0
  396. package/dist/middleware/request-id.js +42 -0
  397. package/dist/middleware/request-id.js.map +1 -0
  398. package/dist/middleware/scopes.d.ts +33 -0
  399. package/dist/middleware/scopes.d.ts.map +1 -0
  400. package/dist/middleware/scopes.js +139 -0
  401. package/dist/middleware/scopes.js.map +1 -0
  402. package/dist/middleware/security-headers.d.ts +53 -0
  403. package/dist/middleware/security-headers.d.ts.map +1 -0
  404. package/dist/middleware/security-headers.js +96 -0
  405. package/dist/middleware/security-headers.js.map +1 -0
  406. package/dist/observability/index.d.ts +3 -0
  407. package/dist/observability/index.d.ts.map +1 -0
  408. package/dist/observability/index.js +3 -0
  409. package/dist/observability/index.js.map +1 -0
  410. package/dist/observability/metrics.d.ts +17 -0
  411. package/dist/observability/metrics.d.ts.map +1 -0
  412. package/dist/observability/metrics.js +82 -0
  413. package/dist/observability/metrics.js.map +1 -0
  414. package/dist/observability/otel.d.ts +20 -0
  415. package/dist/observability/otel.d.ts.map +1 -0
  416. package/dist/observability/otel.js +54 -0
  417. package/dist/observability/otel.js.map +1 -0
  418. package/dist/pagination.d.ts +57 -0
  419. package/dist/pagination.d.ts.map +1 -0
  420. package/dist/pagination.js +90 -0
  421. package/dist/pagination.js.map +1 -0
  422. package/dist/platform/edition.d.ts +57 -0
  423. package/dist/platform/edition.d.ts.map +1 -0
  424. package/dist/platform/edition.js +90 -0
  425. package/dist/platform/edition.js.map +1 -0
  426. package/dist/platform/entitlements.d.ts +26 -0
  427. package/dist/platform/entitlements.d.ts.map +1 -0
  428. package/dist/platform/entitlements.js +28 -0
  429. package/dist/platform/entitlements.js.map +1 -0
  430. package/dist/platform/events.d.ts +87 -0
  431. package/dist/platform/events.d.ts.map +1 -0
  432. package/dist/platform/events.js +32 -0
  433. package/dist/platform/events.js.map +1 -0
  434. package/dist/platform/index.d.ts +8 -0
  435. package/dist/platform/index.d.ts.map +1 -0
  436. package/dist/platform/index.js +8 -0
  437. package/dist/platform/index.js.map +1 -0
  438. package/dist/platform/local-identity.d.ts +39 -0
  439. package/dist/platform/local-identity.d.ts.map +1 -0
  440. package/dist/platform/local-identity.js +87 -0
  441. package/dist/platform/local-identity.js.map +1 -0
  442. package/dist/platform/registry.d.ts +23 -0
  443. package/dist/platform/registry.d.ts.map +1 -0
  444. package/dist/platform/registry.js +5 -0
  445. package/dist/platform/registry.js.map +1 -0
  446. package/dist/platform/usage.d.ts +11 -0
  447. package/dist/platform/usage.d.ts.map +1 -0
  448. package/dist/platform/usage.js +12 -0
  449. package/dist/platform/usage.js.map +1 -0
  450. package/dist/platform/workspaces.d.ts +25 -0
  451. package/dist/platform/workspaces.d.ts.map +1 -0
  452. package/dist/platform/workspaces.js +44 -0
  453. package/dist/platform/workspaces.js.map +1 -0
  454. package/dist/projects/access.d.ts +40 -0
  455. package/dist/projects/access.d.ts.map +1 -0
  456. package/dist/projects/access.js +133 -0
  457. package/dist/projects/access.js.map +1 -0
  458. package/dist/projects/index.d.ts +2 -0
  459. package/dist/projects/index.d.ts.map +1 -0
  460. package/dist/projects/index.js +2 -0
  461. package/dist/projects/index.js.map +1 -0
  462. package/dist/route-label.d.ts +23 -0
  463. package/dist/route-label.d.ts.map +1 -0
  464. package/dist/route-label.js +29 -0
  465. package/dist/route-label.js.map +1 -0
  466. package/dist/routes/health.d.ts +30 -0
  467. package/dist/routes/health.d.ts.map +1 -0
  468. package/dist/routes/health.js +54 -0
  469. package/dist/routes/health.js.map +1 -0
  470. package/dist/routes/index.d.ts +3 -0
  471. package/dist/routes/index.d.ts.map +1 -0
  472. package/dist/routes/index.js +3 -0
  473. package/dist/routes/index.js.map +1 -0
  474. package/dist/routes/wellknown.d.ts +11 -0
  475. package/dist/routes/wellknown.d.ts.map +1 -0
  476. package/dist/routes/wellknown.js +45 -0
  477. package/dist/routes/wellknown.js.map +1 -0
  478. package/dist/secret.d.ts +30 -0
  479. package/dist/secret.d.ts.map +1 -0
  480. package/dist/secret.js +97 -0
  481. package/dist/secret.js.map +1 -0
  482. package/dist/setup-transport.d.ts +23 -0
  483. package/dist/setup-transport.d.ts.map +1 -0
  484. package/dist/setup-transport.js +52 -0
  485. package/dist/setup-transport.js.map +1 -0
  486. package/dist/state.d.ts +21 -0
  487. package/dist/state.d.ts.map +1 -0
  488. package/dist/state.js +4 -0
  489. package/dist/state.js.map +1 -0
  490. package/dist/storage/driver.d.ts +38 -0
  491. package/dist/storage/driver.d.ts.map +1 -0
  492. package/dist/storage/driver.js +14 -0
  493. package/dist/storage/driver.js.map +1 -0
  494. package/dist/storage/factory.d.ts +4 -0
  495. package/dist/storage/factory.d.ts.map +1 -0
  496. package/dist/storage/factory.js +20 -0
  497. package/dist/storage/factory.js.map +1 -0
  498. package/dist/storage/index.d.ts +4 -0
  499. package/dist/storage/index.d.ts.map +1 -0
  500. package/dist/storage/index.js +4 -0
  501. package/dist/storage/index.js.map +1 -0
  502. package/dist/storage/local.d.ts +21 -0
  503. package/dist/storage/local.d.ts.map +1 -0
  504. package/dist/storage/local.js +88 -0
  505. package/dist/storage/local.js.map +1 -0
  506. package/dist/storage/s3.d.ts +29 -0
  507. package/dist/storage/s3.d.ts.map +1 -0
  508. package/dist/storage/s3.js +82 -0
  509. package/dist/storage/s3.js.map +1 -0
  510. package/dist/testing/fake-hub.d.ts +425 -0
  511. package/dist/testing/fake-hub.d.ts.map +1 -0
  512. package/dist/testing/fake-hub.js +1074 -0
  513. package/dist/testing/fake-hub.js.map +1 -0
  514. package/dist/testing/helpers.d.ts +124 -0
  515. package/dist/testing/helpers.d.ts.map +1 -0
  516. package/dist/testing/helpers.js +174 -0
  517. package/dist/testing/helpers.js.map +1 -0
  518. package/dist/testing/index.d.ts +12 -0
  519. package/dist/testing/index.d.ts.map +1 -0
  520. package/dist/testing/index.js +12 -0
  521. package/dist/testing/index.js.map +1 -0
  522. package/dist/testing/setup-origins.d.ts +21 -0
  523. package/dist/testing/setup-origins.d.ts.map +1 -0
  524. package/dist/testing/setup-origins.js +57 -0
  525. package/dist/testing/setup-origins.js.map +1 -0
  526. package/dist/testing/sso-helpers.d.ts +43 -0
  527. package/dist/testing/sso-helpers.d.ts.map +1 -0
  528. package/dist/testing/sso-helpers.js +159 -0
  529. package/dist/testing/sso-helpers.js.map +1 -0
  530. package/dist/tool-definition.d.ts +382 -0
  531. package/dist/tool-definition.d.ts.map +1 -0
  532. package/dist/tool-definition.js +46 -0
  533. package/dist/tool-definition.js.map +1 -0
  534. package/dist/util/index.d.ts +8 -0
  535. package/dist/util/index.d.ts.map +1 -0
  536. package/dist/util/index.js +8 -0
  537. package/dist/util/index.js.map +1 -0
  538. package/package.json +161 -0
  539. package/src/accounts/deletion.ts +389 -0
  540. package/src/accounts/erasure-log.ts +140 -0
  541. package/src/accounts/index.ts +5 -0
  542. package/src/accounts/mint-refusal.ts +67 -0
  543. package/src/accounts/signup-duplicate.ts +21 -0
  544. package/src/accounts/superadmin.ts +46 -0
  545. package/src/api/apikeys.ts +147 -0
  546. package/src/api/audit.ts +83 -0
  547. package/src/api/break-glass.ts +294 -0
  548. package/src/api/cli-auth.ts +308 -0
  549. package/src/api/create-api.ts +1403 -0
  550. package/src/api/demo-passes.ts +207 -0
  551. package/src/api/errors.ts +13 -0
  552. package/src/api/export.ts +482 -0
  553. package/src/api/files.ts +200 -0
  554. package/src/api/index.ts +29 -0
  555. package/src/api/invitations.ts +396 -0
  556. package/src/api/members.ts +617 -0
  557. package/src/api/onboarding.ts +50 -0
  558. package/src/api/openapi-doc.ts +34 -0
  559. package/src/api/projects.ts +788 -0
  560. package/src/api/scope-routes.ts +12 -0
  561. package/src/api/sso-connect.ts +246 -0
  562. package/src/api/sso-logout.ts +76 -0
  563. package/src/api/teams.ts +575 -0
  564. package/src/api/workspaces.ts +649 -0
  565. package/src/apikeys/index.ts +2 -0
  566. package/src/apikeys/peppers.ts +118 -0
  567. package/src/apikeys/service.ts +223 -0
  568. package/src/app.ts +228 -0
  569. package/src/audit/filters.ts +101 -0
  570. package/src/audit/index.ts +9 -0
  571. package/src/audit/service.ts +154 -0
  572. package/src/boot.ts +953 -0
  573. package/src/constant-time.ts +9 -0
  574. package/src/email/driver.ts +139 -0
  575. package/src/email/index.ts +26 -0
  576. package/src/email/shell.ts +201 -0
  577. package/src/email/templates.ts +184 -0
  578. package/src/entitlements/check.ts +435 -0
  579. package/src/entitlements/clock-skew.ts +58 -0
  580. package/src/entitlements/gate.ts +636 -0
  581. package/src/entitlements/hub-machine-token.ts +205 -0
  582. package/src/entitlements/hub-subject.ts +77 -0
  583. package/src/entitlements/index.ts +37 -0
  584. package/src/entitlements/poster.ts +265 -0
  585. package/src/entitlements/profiles.ts +303 -0
  586. package/src/entitlements/slot.ts +105 -0
  587. package/src/env.ts +456 -0
  588. package/src/files/http.ts +77 -0
  589. package/src/files/index.ts +4 -0
  590. package/src/files/serve.ts +115 -0
  591. package/src/files/service.ts +209 -0
  592. package/src/files/spool.ts +58 -0
  593. package/src/identity/better-auth.ts +1103 -0
  594. package/src/identity/demo-pass-plugin.ts +121 -0
  595. package/src/identity/demo-pass-rules.ts +229 -0
  596. package/src/identity/demo-pass.ts +390 -0
  597. package/src/identity/hub-grant.ts +704 -0
  598. package/src/identity/hub-jwt.ts +78 -0
  599. package/src/identity/hub-live-gate.ts +167 -0
  600. package/src/identity/hub-logout.ts +174 -0
  601. package/src/identity/hub-projection.ts +251 -0
  602. package/src/identity/hub-reconcile.ts +572 -0
  603. package/src/identity/hub-sso.ts +696 -0
  604. package/src/identity/hub-user-client.ts +554 -0
  605. package/src/identity/index.ts +56 -0
  606. package/src/identity/oauth-jwt.ts +128 -0
  607. package/src/identity/resolve-membership.ts +104 -0
  608. package/src/identity/signing-key.ts +164 -0
  609. package/src/index.ts +65 -0
  610. package/src/invitations/index.ts +1 -0
  611. package/src/invitations/service.ts +171 -0
  612. package/src/jobs/index.ts +25 -0
  613. package/src/jobs/pgboss.ts +594 -0
  614. package/src/jobs/timers.ts +287 -0
  615. package/src/logger.ts +67 -0
  616. package/src/mcp/errors.ts +111 -0
  617. package/src/mcp/http.ts +129 -0
  618. package/src/mcp/index.ts +28 -0
  619. package/src/mcp/inputs.ts +33 -0
  620. package/src/mcp/projects.ts +480 -0
  621. package/src/mcp/server.ts +174 -0
  622. package/src/mcp/teams.ts +97 -0
  623. package/src/mcp/tool-kit.ts +148 -0
  624. package/src/members/removal.ts +216 -0
  625. package/src/middleware/auth-body.ts +58 -0
  626. package/src/middleware/auth-context.ts +384 -0
  627. package/src/middleware/body-cap.ts +33 -0
  628. package/src/middleware/body-refusal.ts +23 -0
  629. package/src/middleware/cross-site.ts +122 -0
  630. package/src/middleware/hub-managed.ts +61 -0
  631. package/src/middleware/idempotency.ts +264 -0
  632. package/src/middleware/index.ts +33 -0
  633. package/src/middleware/json-depth.ts +74 -0
  634. package/src/middleware/no-store.ts +30 -0
  635. package/src/middleware/oauth-public.ts +54 -0
  636. package/src/middleware/rate-limit.ts +432 -0
  637. package/src/middleware/request-id.ts +54 -0
  638. package/src/middleware/scopes.ts +150 -0
  639. package/src/middleware/security-headers.ts +129 -0
  640. package/src/observability/index.ts +2 -0
  641. package/src/observability/metrics.ts +102 -0
  642. package/src/observability/otel.ts +79 -0
  643. package/src/pagination.ts +118 -0
  644. package/src/platform/edition.ts +140 -0
  645. package/src/platform/entitlements.ts +47 -0
  646. package/src/platform/events.ts +71 -0
  647. package/src/platform/index.ts +7 -0
  648. package/src/platform/local-identity.ts +90 -0
  649. package/src/platform/registry.ts +28 -0
  650. package/src/platform/usage.ts +13 -0
  651. package/src/platform/workspaces.ts +41 -0
  652. package/src/projects/access.ts +160 -0
  653. package/src/projects/index.ts +7 -0
  654. package/src/route-label.ts +29 -0
  655. package/src/routes/health.ts +79 -0
  656. package/src/routes/index.ts +2 -0
  657. package/src/routes/wellknown.ts +67 -0
  658. package/src/secret.ts +115 -0
  659. package/src/setup-transport.ts +46 -0
  660. package/src/state.ts +23 -0
  661. package/src/storage/driver.ts +48 -0
  662. package/src/storage/factory.ts +34 -0
  663. package/src/storage/index.ts +3 -0
  664. package/src/storage/local.ts +93 -0
  665. package/src/storage/s3.ts +109 -0
  666. package/src/testing/fake-hub.ts +1316 -0
  667. package/src/testing/helpers.ts +254 -0
  668. package/src/testing/index.ts +11 -0
  669. package/src/testing/setup-origins.ts +58 -0
  670. package/src/testing/sso-helpers.ts +178 -0
  671. package/src/tool-definition.ts +463 -0
  672. package/src/util/index.ts +17 -0
  673. package/test/fixtures/onboarding-backfill.sql +13 -0
  674. package/test/fixtures/operator-user-id-backfill.sql +18 -0
  675. package/test/host/dr-lib.sh +253 -0
  676. package/test/host/drizzle/0000_chassis_baseline.sql +438 -0
  677. package/test/host/drizzle/0001_last_owner_guard.sql +42 -0
  678. package/test/host/drizzle/meta/0000_snapshot.json +3566 -0
  679. package/test/host/drizzle/meta/_journal.json +20 -0
  680. package/test/host/drizzle.config.ts +17 -0
  681. package/test/host/identity.ts +41 -0
  682. package/test/host/minimal-host.ts +35 -0
  683. package/test/host/minimal-tool.ts +123 -0
  684. package/test/integration/account-oracle-uniformity.test.ts +284 -0
  685. package/test/integration/account-recovery.test.ts +236 -0
  686. package/test/integration/account.test.ts +120 -0
  687. package/test/integration/api-quota.test.ts +208 -0
  688. package/test/integration/apikey-expiry.test.ts +178 -0
  689. package/test/integration/apikey-pepper-rotation.test.ts +190 -0
  690. package/test/integration/boot-posture.test.ts +169 -0
  691. package/test/integration/break-glass.test.ts +484 -0
  692. package/test/integration/cloud-lifecycle.test.ts +233 -0
  693. package/test/integration/credential-boundaries.test.ts +195 -0
  694. package/test/integration/default-workspace.test.ts +414 -0
  695. package/test/integration/demo-pass-rules.test.ts +332 -0
  696. package/test/integration/demo-pass.test.ts +1222 -0
  697. package/test/integration/dr-verify-real-dump.test.ts +154 -0
  698. package/test/integration/edition.test.ts +868 -0
  699. package/test/integration/email-change.test.ts +394 -0
  700. package/test/integration/empty-tool.test.ts +267 -0
  701. package/test/integration/entitlements-null-hook.test.ts +187 -0
  702. package/test/integration/entitlements.test.ts +693 -0
  703. package/test/integration/export-entries.test.ts +321 -0
  704. package/test/integration/files.test.ts +320 -0
  705. package/test/integration/first-boot-claim.test.ts +131 -0
  706. package/test/integration/gdpr.test.ts +532 -0
  707. package/test/integration/helpers.ts +29 -0
  708. package/test/integration/hub-grant.test.ts +505 -0
  709. package/test/integration/hub-live-gate.test.ts +612 -0
  710. package/test/integration/hub-managed-membership.test.ts +559 -0
  711. package/test/integration/hub-org-selector.test.ts +281 -0
  712. package/test/integration/hub-reconcile.test.ts +646 -0
  713. package/test/integration/hub-sso.test.ts +704 -0
  714. package/test/integration/hub-teams.test.ts +771 -0
  715. package/test/integration/idempotency.test.ts +261 -0
  716. package/test/integration/invite-verification.test.ts +210 -0
  717. package/test/integration/last-owner-race.test.ts +263 -0
  718. package/test/integration/m9-fixes.test.ts +290 -0
  719. package/test/integration/mcp-projects.test.ts +463 -0
  720. package/test/integration/member-removal-race.test.ts +466 -0
  721. package/test/integration/member-removal.test.ts +794 -0
  722. package/test/integration/oauth-mcp.test.ts +477 -0
  723. package/test/integration/oauth-workspace.test.ts +371 -0
  724. package/test/integration/observability.test.ts +183 -0
  725. package/test/integration/onboarding.test.ts +268 -0
  726. package/test/integration/orphan-purge.test.ts +451 -0
  727. package/test/integration/pagination.test.ts +344 -0
  728. package/test/integration/platform-core.test.ts +305 -0
  729. package/test/integration/platform.test.ts +246 -0
  730. package/test/integration/pool-survives-restart.test.ts +80 -0
  731. package/test/integration/projects-cloud.test.ts +193 -0
  732. package/test/integration/projects.test.ts +1310 -0
  733. package/test/integration/security-fixes.test.ts +190 -0
  734. package/test/integration/setup-transport.test.ts +118 -0
  735. package/test/integration/signin-wall.test.ts +103 -0
  736. package/test/integration/signing-key-rotation.test.ts +349 -0
  737. package/test/integration/sso-helpers.ts +15 -0
  738. package/test/integration/sso-logout.test.ts +283 -0
  739. package/test/integration/teams-cloud.test.ts +194 -0
  740. package/test/integration/teams.test.ts +551 -0
  741. package/test/integration/timers.test.ts +377 -0
  742. package/test/integration/two-factor.test.ts +301 -0
  743. package/test/integration/usage-window.test.ts +161 -0
  744. package/test/integration/workspace-create-cloud.test.ts +523 -0
  745. package/test/integration/workspace-create.test.ts +510 -0
  746. package/test/integration/workspace-scoping.test.ts +530 -0
  747. package/test/integration/zz-adv-replay-owner.test.ts +205 -0
  748. package/test/unit/apikey-peppers.test.ts +110 -0
  749. package/test/unit/apikey-prefix.test.ts +34 -0
  750. package/test/unit/audit-filters.test.ts +135 -0
  751. package/test/unit/auth-origins.test.ts +92 -0
  752. package/test/unit/body-cap.test.ts +84 -0
  753. package/test/unit/clock-skew.test.ts +68 -0
  754. package/test/unit/cross-site.test.ts +166 -0
  755. package/test/unit/declared-credits.test.ts +13 -0
  756. package/test/unit/demo-pass-rules.test.ts +192 -0
  757. package/test/unit/email-driver.test.ts +127 -0
  758. package/test/unit/end-pool.test.ts +181 -0
  759. package/test/unit/entitlement-check.test.ts +492 -0
  760. package/test/unit/entitlement-gate.test.ts +1333 -0
  761. package/test/unit/entitlement-profiles.test.ts +289 -0
  762. package/test/unit/erasure-log.test.ts +72 -0
  763. package/test/unit/error-mapping.test.ts +89 -0
  764. package/test/unit/export-entries.test.ts +85 -0
  765. package/test/unit/export-sanitize.test.ts +27 -0
  766. package/test/unit/files-head-route.test.ts +155 -0
  767. package/test/unit/files-http.test.ts +97 -0
  768. package/test/unit/head-rewrite.test.ts +72 -0
  769. package/test/unit/hub-create-org.test.ts +181 -0
  770. package/test/unit/hub-jwt.test.ts +93 -0
  771. package/test/unit/hub-sso-params.test.ts +39 -0
  772. package/test/unit/hub-subject.test.ts +83 -0
  773. package/test/unit/idempotency-crypto.test.ts +45 -0
  774. package/test/unit/json-depth.test.ts +88 -0
  775. package/test/unit/logger-redaction.test.ts +66 -0
  776. package/test/unit/mcp-errors.test.ts +110 -0
  777. package/test/unit/mcp-inputs.test.ts +106 -0
  778. package/test/unit/mcp-project-hints.test.ts +26 -0
  779. package/test/unit/no-store.test.ts +49 -0
  780. package/test/unit/no-tool-migration-filename.test.ts +70 -0
  781. package/test/unit/observability.test.ts +64 -0
  782. package/test/unit/openapi-doc.test.ts +93 -0
  783. package/test/unit/rate-limit-consume-on.test.ts +76 -0
  784. package/test/unit/rate-limit.test.ts +39 -0
  785. package/test/unit/readyz-storage.test.ts +157 -0
  786. package/test/unit/request-quota.test.ts +146 -0
  787. package/test/unit/scopes.test.ts +66 -0
  788. package/test/unit/security-headers.test.ts +131 -0
  789. package/test/unit/serve-content-type.test.ts +74 -0
  790. package/test/unit/setup-transport.test.ts +29 -0
  791. package/test/unit/storage-local.test.ts +53 -0
  792. package/test/unit/superadmin.test.ts +32 -0
  793. package/test/unit/timers.test.ts +287 -0
  794. package/test/unit/tool-definition-guards.test.ts +166 -0
  795. package/test/unit/tool-entitlements-guard.test.ts +168 -0
  796. package/test/unit/usage-poster.test.ts +542 -0
  797. package/test/unit/usage-window.test.ts +48 -0
  798. package/test/unit/workspace-create-audit.test.ts +48 -0
@@ -0,0 +1,554 @@
1
+ import { workspaceRoles, type WorkspaceRole } from '@antasphere/chassis-db';
2
+ import type { Logger } from '../logger.js';
3
+ import type { GrantAccess, HubGrantService } from './hub-grant.js';
4
+ import { placeholderWorkspaceName } from './hub-projection.js';
5
+
6
+ /**
7
+ * The as-the-user hub reader (internal/federation.md, live user-scoped
8
+ * federation): every org/membership read between logins is `GET
9
+ * <hub>/api/v1/orgs` presented with the USER's OWN grant token
10
+ * (identity/hub-grant.ts) — the hub only ever returns what that user may
11
+ * see, so a cross-tenant read is structurally impossible on this path.
12
+ * There is deliberately NO target-user parameter anywhere.
13
+ *
14
+ * Failure posture mirrors the retired H4 client: only a definitive 200
15
+ * list may drive reconciliation; network/timeout/5xx/malformed answers are
16
+ * one loud, fail-open 'inconclusive'. A 401/403 gets exactly ONE
17
+ * forced-refresh retry (the presented token may be stale or wrong-audience
18
+ * from a pre-flip row) — a second refusal is inconclusive, never a grant
19
+ * kill (only the token endpoint's `invalid_grant` kills a grant, inside
20
+ * HubGrantService).
21
+ */
22
+
23
+ /** The hub API resource identifier (RFC 8707 `aud`) — `<hub issuer>/mcp`. */
24
+ export function hubApiResource(issuerUrl: string): string {
25
+ return issuerUrl.replace(/\/+$/, '') + '/mcp';
26
+ }
27
+
28
+ /**
29
+ * One validated entry of the caller-scoped org list. Forward-compatible by
30
+ * construction: an absent `status` reads as 'active', an absent `isDefault`
31
+ * as false, an unknown `role` as null (keep-alive only — an unknown role
32
+ * must never read as absence).
33
+ */
34
+ export interface HubOrg {
35
+ /** The hub org id (uuid) — what `workspaces.centralAccountId` projects. */
36
+ id: string;
37
+ /** Org display name; null when absent/blank. */
38
+ name: string | null;
39
+ role: WorkspaceRole | null;
40
+ status: 'active' | 'suspended';
41
+ /** The caller's hub-level default org (at most one entry carries it). */
42
+ isDefault: boolean;
43
+ /**
44
+ * The CALLER's own teams in this org (never the org's whole roster: the
45
+ * hub answers as the person). An absent or malformed field reads as none
46
+ * (a hub that predates teams); an entry without a uuid id is dropped.
47
+ */
48
+ teams: HubTeam[];
49
+ }
50
+
51
+ /** One of the caller's teams in an org, as `GET /orgs` carries it. */
52
+ export interface HubTeam {
53
+ /** The hub's team id — what `workspace_teams.hub_team_id` projects. */
54
+ id: string;
55
+ slug: string;
56
+ name: string;
57
+ }
58
+
59
+ /**
60
+ * One of the caller's organizations that does NOT open this tool to them
61
+ * (the org restricts the tool to teams the caller is not in). The hub leaves
62
+ * such an org out of `orgs`; `denied` names it so the refusal page can say
63
+ * which organization to ask. A hint for the person, never an access input.
64
+ */
65
+ export interface HubDeniedOrg {
66
+ id: string;
67
+ /** Org display name; the projection's placeholder when absent/blank. */
68
+ name: string;
69
+ }
70
+
71
+ export type HubOrgsResult =
72
+ | { kind: 'ok'; orgs: HubOrg[]; denied: HubDeniedOrg[] }
73
+ | { kind: 'no_link' }
74
+ | { kind: 'grant_dead' }
75
+ | { kind: 'inconclusive' };
76
+
77
+ /**
78
+ * The organization's WHOLE team list as one member reads it (`GET
79
+ * <hub>/api/v1/teams`, PRDCT-2813), every team of the org whether or not the
80
+ * reader sits in it. `complete` is false when the drain stopped at its page
81
+ * cap with more pages left: the list is then a prefix, good for upserting,
82
+ * never for deleting what it does not name.
83
+ */
84
+ export type HubOrgTeamsResult =
85
+ | { kind: 'ok'; teams: HubTeam[]; complete: boolean }
86
+ | { kind: 'inconclusive' }
87
+ | { kind: 'no_link' }
88
+ | { kind: 'grant_dead' };
89
+
90
+ /** The page size of the team-list drain (the hub's own maximum). */
91
+ const ORG_TEAMS_PAGE_LIMIT = 100;
92
+ /** At most this many pages per read (1,000 teams), then the drain stops. */
93
+ const ORG_TEAMS_MAX_PAGES = 10;
94
+
95
+ /**
96
+ * The answer of one as-the-user org creation (PRDCT-2443):
97
+ * - 'created': the hub answered 201 with a well-formed org;
98
+ * - 'limit_reached': the hub's own per-user organization cap refused it;
99
+ * - 'reauth_required': the hub answered 403 `insufficient_scope` — THIS
100
+ * grant does not carry `orgs:create` (it predates the scope, or a CLI
101
+ * connect replaced it). Not a dead grant and not a policy refusal: a
102
+ * fresh browser sign-in mints a grant that has it;
103
+ * - 'invalid': the hub refused the NAME (its validation, not ours);
104
+ * - 'refused': any other definitive refusal (the hub does not let this
105
+ * grant create organizations) — `code` is the hub's, for the log only;
106
+ * - 'no_link' / 'grant_dead': the grant verdicts, verbatim from
107
+ * HubGrantService;
108
+ * - 'inconclusive': network/timeout/5xx/malformed. The organization MAY
109
+ * exist at the hub (it commits before it answers); the caller never
110
+ * retries by itself, and the next reconcile pass projects it if so.
111
+ */
112
+ export type HubCreateOrgResult =
113
+ | { kind: 'created'; org: { id: string; name: string | null; role: WorkspaceRole | null } }
114
+ | { kind: 'limit_reached' }
115
+ | { kind: 'reauth_required' }
116
+ | { kind: 'invalid' }
117
+ | { kind: 'refused'; status: number; code: string | null }
118
+ | { kind: 'no_link' }
119
+ | { kind: 'grant_dead' }
120
+ | { kind: 'inconclusive' };
121
+
122
+ /** The one-function boundary the workspace-creation route depends on (its test seam). */
123
+ export type HubOrgCreator = (localUserId: string, name: string) => Promise<HubCreateOrgResult>;
124
+
125
+ /** The hub's cap refusal codes — today's (`org_limit_reached`) and the `*_cap_reached` spelling. */
126
+ const HUB_ORG_LIMIT_CODES = new Set(['org_limit_reached', 'org_cap_reached']);
127
+
128
+ /**
129
+ * THE ONE PLACE that knows the shape of the hub's `POST /api/v1/orgs` answer
130
+ * (hub contract `orgCreatedSchema`: 201 `{ org: { id, name, role, … } }`;
131
+ * refusals in the common `{ error: { code } }` envelope). Pure, so the
132
+ * shape is adjustable — and testable — without touching the transport.
133
+ */
134
+ export function classifyHubOrgCreateAnswer(status: number, body: unknown): HubCreateOrgResult {
135
+ const code =
136
+ typeof (body as { error?: { code?: unknown } } | null)?.error?.code === 'string'
137
+ ? (body as { error: { code: string } }).error.code
138
+ : null;
139
+ if (status === 201 || status === 200) {
140
+ const raw = ((body as { org?: unknown } | null)?.org ?? null) as {
141
+ id?: unknown;
142
+ name?: unknown;
143
+ role?: unknown;
144
+ } | null;
145
+ // A 2xx without a valid org id is unusable AND ambiguous (something was
146
+ // probably created): inconclusive, never a guess at the id.
147
+ if (!raw || typeof raw.id !== 'string' || !UUID_RE.test(raw.id)) return { kind: 'inconclusive' };
148
+ return {
149
+ kind: 'created',
150
+ org: {
151
+ id: raw.id,
152
+ name: typeof raw.name === 'string' && raw.name.trim() ? raw.name : null,
153
+ role:
154
+ typeof raw.role === 'string' && (workspaceRoles as readonly string[]).includes(raw.role)
155
+ ? (raw.role as WorkspaceRole)
156
+ : null
157
+ }
158
+ };
159
+ }
160
+ if ((status === 403 || status === 409) && code !== null && HUB_ORG_LIMIT_CODES.has(code)) {
161
+ return { kind: 'limit_reached' };
162
+ }
163
+ // Exactly the hub's scope refusal — never any other 403 (a registry
164
+ // refusal, `forbidden`, stays 'refused': signing in again would not help).
165
+ if (status === 403 && code === 'insufficient_scope') return { kind: 'reauth_required' };
166
+ if (status === 400 || status === 422) return { kind: 'invalid' };
167
+ if (status >= 400 && status < 500) return { kind: 'refused', status, code };
168
+ return { kind: 'inconclusive' };
169
+ }
170
+
171
+ /**
172
+ * Strict UUID shape, the one id rule of every list this file parses (orgs,
173
+ * teams, denied orgs). The hub's org and team ids are uuids, and they are
174
+ * written to Postgres (`workspaces.central_account_id`,
175
+ * `workspace_teams.hub_team_id`) or shown to the person: an entry of any
176
+ * other shape is not a hub id, so it is dropped with a log line and never
177
+ * stored.
178
+ */
179
+ const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
180
+
181
+ /**
182
+ * An org entry's `teams` (forward-compatible: absent or not an array reads
183
+ * as none). An entry without a uuid id is dropped (UUID_RE); a missing slug
184
+ * or name reads as the empty string rather than dropping a seat the hub
185
+ * asserted.
186
+ */
187
+ export function parseTeams(raw: unknown, logger: Logger): HubTeam[] {
188
+ if (!Array.isArray(raw)) return [];
189
+ const teams: HubTeam[] = [];
190
+ const seen = new Set<string>();
191
+ for (const item of raw) {
192
+ const team = (item ?? {}) as { id?: unknown; slug?: unknown; name?: unknown };
193
+ if (typeof team.id !== 'string' || !UUID_RE.test(team.id)) {
194
+ logger.warn('hub /orgs carried a team without a valid id — entry dropped');
195
+ continue;
196
+ }
197
+ if (seen.has(team.id)) continue;
198
+ seen.add(team.id);
199
+ teams.push({
200
+ id: team.id,
201
+ slug: typeof team.slug === 'string' ? team.slug : '',
202
+ name: typeof team.name === 'string' ? team.name : ''
203
+ });
204
+ }
205
+ return teams;
206
+ }
207
+
208
+ /**
209
+ * The body's top-level `denied` (absent or malformed reads as none; an entry
210
+ * without a uuid id is dropped, UUID_RE). A missing or blank name reads as
211
+ * the projection's placeholder, so every reader gets a name to show.
212
+ */
213
+ export function parseDenied(raw: unknown, logger: Logger): HubDeniedOrg[] {
214
+ if (!Array.isArray(raw)) return [];
215
+ const denied: HubDeniedOrg[] = [];
216
+ for (const item of raw) {
217
+ const org = (item ?? {}) as { id?: unknown; name?: unknown };
218
+ if (typeof org.id !== 'string' || !UUID_RE.test(org.id)) {
219
+ logger.warn('hub /orgs carried a denied org without a valid id — entry dropped');
220
+ continue;
221
+ }
222
+ denied.push({
223
+ id: org.id,
224
+ name: typeof org.name === 'string' && org.name.trim() ? org.name : placeholderWorkspaceName(org.id)
225
+ });
226
+ }
227
+ return denied;
228
+ }
229
+
230
+ /** The SSO callback's access token, handed through by the login path. */
231
+ export interface LoginAccessToken {
232
+ accessToken: string;
233
+ expiresAt: Date | null;
234
+ }
235
+
236
+ export interface HubUserClientOptions {
237
+ grant: HubGrantService;
238
+ /** The hub origin (HUB_ISSUER_URL) — /api/v1/orgs lives under it. */
239
+ issuerUrl: string;
240
+ logger: Logger;
241
+ /** Per-fetch timeout — tight, because reconcile passes are awaited in the identity path. */
242
+ timeoutMs: number;
243
+ /**
244
+ * POST /orgs fetch timeout. A creation is a deliberate human act awaited
245
+ * once, not an identity-path read: it gets the token-endpoint budget
246
+ * rather than the tight reconcile one. Defaults to `timeoutMs`.
247
+ */
248
+ createTimeoutMs?: number | undefined;
249
+ /** Test seam. */
250
+ fetchImpl?: typeof fetch;
251
+ }
252
+
253
+ export class HubUserClient {
254
+ private readonly base: string;
255
+ private readonly fetchImpl: typeof fetch;
256
+ /** An older hub without `GET /teams` is said once per client, never on every pass. */
257
+ private warnedNoTeamsRoute = false;
258
+
259
+ constructor(private readonly opts: HubUserClientOptions) {
260
+ this.base = opts.issuerUrl.replace(/\/+$/, '');
261
+ this.fetchImpl = opts.fetchImpl ?? fetch;
262
+ }
263
+
264
+ /**
265
+ * The user's own org list, as the hub sees it RIGHT NOW. `login` carries
266
+ * the SSO callback's access token (already hub-audienced — the code
267
+ * exchange sends the same `resource`): the login path needs no refresh,
268
+ * and the token is primed into the grant cache for the requests that
269
+ * follow.
270
+ */
271
+ async orgs(localUserId: string, login?: LoginAccessToken): Promise<HubOrgsResult> {
272
+ let token: string;
273
+ if (login) {
274
+ this.opts.grant.prime(localUserId, login.accessToken, login.expiresAt);
275
+ token = login.accessToken;
276
+ } else {
277
+ const access = await this.opts.grant.accessToken(localUserId);
278
+ if (access.kind !== 'ok') return { kind: access.kind };
279
+ token = access.accessToken;
280
+ }
281
+
282
+ let res = await this.get(token);
283
+ if (res.kind === 'error') return { kind: 'inconclusive' };
284
+ if (res.response.status === 401 || res.response.status === 403) {
285
+ // The hub refused the token (expired mid-window, or a pre-flip row's
286
+ // wrong-audience stored token): ONE forced refresh, ONE retry. The
287
+ // refresh itself classifies the grant (invalid_grant → dead).
288
+ this.opts.grant.invalidateAccess(localUserId);
289
+ const refreshed: GrantAccess = await this.opts.grant.refresh(localUserId);
290
+ if (refreshed.kind !== 'ok') return { kind: refreshed.kind };
291
+ res = await this.get(refreshed.accessToken);
292
+ if (res.kind === 'error') return { kind: 'inconclusive' };
293
+ if (res.response.status === 401 || res.response.status === 403) {
294
+ this.opts.logger.error(
295
+ { status: res.response.status },
296
+ 'hub /orgs refused a FRESHLY refreshed token — the hub is rejecting this tool’s grants; failing open'
297
+ );
298
+ return { kind: 'inconclusive' };
299
+ }
300
+ }
301
+ const { response } = res;
302
+ if (!response.ok) {
303
+ this.opts.logger.warn({ status: response.status }, 'hub /orgs answered non-2xx — failing open');
304
+ return { kind: 'inconclusive' };
305
+ }
306
+ let body: unknown;
307
+ try {
308
+ body = await response.json();
309
+ } catch {
310
+ this.opts.logger.warn('hub /orgs body unparseable — failing open');
311
+ return { kind: 'inconclusive' };
312
+ }
313
+ const rawList = (body as { orgs?: unknown } | null)?.orgs;
314
+ if (!Array.isArray(rawList)) {
315
+ this.opts.logger.warn('hub /orgs body malformed — failing open');
316
+ return { kind: 'inconclusive' };
317
+ }
318
+ const orgs: HubOrg[] = [];
319
+ for (const raw of rawList) {
320
+ const entry = (raw ?? {}) as {
321
+ id?: unknown;
322
+ name?: unknown;
323
+ role?: unknown;
324
+ status?: unknown;
325
+ isDefault?: unknown;
326
+ teams?: unknown;
327
+ };
328
+ if (typeof entry.id !== 'string' || !UUID_RE.test(entry.id)) {
329
+ // One bad entry never poisons the list — but its org can neither be
330
+ // projected NOR protected by the keep-set, so say so loudly.
331
+ this.opts.logger.error('hub /orgs carried an entry without a valid id — entry dropped');
332
+ continue;
333
+ }
334
+ const role =
335
+ typeof entry.role === 'string' && (workspaceRoles as readonly string[]).includes(entry.role)
336
+ ? (entry.role as WorkspaceRole)
337
+ : null;
338
+ if (role === null) {
339
+ this.opts.logger.warn(
340
+ { hubOrgId: entry.id },
341
+ 'hub /orgs carried an unknown role — keeping the membership alive, skipping its sync'
342
+ );
343
+ }
344
+ orgs.push({
345
+ id: entry.id,
346
+ name: typeof entry.name === 'string' && entry.name.trim() ? entry.name : null,
347
+ role,
348
+ // Unknown/absent status reads as 'active' (forward-compat: status
349
+ // only ever narrows access; enforcement reads the synced column).
350
+ status: entry.status === 'suspended' ? 'suspended' : 'active',
351
+ isDefault: entry.isDefault === true,
352
+ teams: parseTeams(entry.teams, this.opts.logger)
353
+ });
354
+ }
355
+ return { kind: 'ok', orgs, denied: parseDenied((body as { denied?: unknown }).denied, this.opts.logger) };
356
+ }
357
+
358
+ /**
359
+ * The organization's whole team list, read AS THE USER (PRDCT-2813): `GET
360
+ * <hub>/api/v1/teams` with the person's own grant token and the hub org in
361
+ * `X-Workspace-Id`, which the hub answers for any member of that org. Same
362
+ * posture as `orgs()`: one forced refresh and one retry on a 401/403 (once
363
+ * for the whole drain), `inconclusive` on any doubt (network, non-2xx,
364
+ * unparseable or malformed page). The pages are drained through
365
+ * `nextCursor`, at most ORG_TEAMS_MAX_PAGES of them; a list cut there is
366
+ * returned with `complete: false`.
367
+ */
368
+ async orgTeams(localUserId: string, hubOrgId: string): Promise<HubOrgTeamsResult> {
369
+ const access = await this.opts.grant.accessToken(localUserId);
370
+ if (access.kind !== 'ok') return { kind: access.kind };
371
+ let token = access.accessToken;
372
+ let retried = false;
373
+ const teams: HubTeam[] = [];
374
+ const seen = new Set<string>();
375
+ let cursor: string | null = null;
376
+
377
+ for (let page = 0; page < ORG_TEAMS_MAX_PAGES; page++) {
378
+ let res = await this.getTeamsPage(token, hubOrgId, cursor);
379
+ if (res.kind === 'error') return { kind: 'inconclusive' };
380
+ if ((res.response.status === 401 || res.response.status === 403) && !retried) {
381
+ retried = true;
382
+ this.opts.grant.invalidateAccess(localUserId);
383
+ const refreshed: GrantAccess = await this.opts.grant.refresh(localUserId);
384
+ if (refreshed.kind !== 'ok') return { kind: refreshed.kind };
385
+ token = refreshed.accessToken;
386
+ res = await this.getTeamsPage(token, hubOrgId, cursor);
387
+ if (res.kind === 'error') return { kind: 'inconclusive' };
388
+ }
389
+ const { response } = res;
390
+ if (response.status === 404) {
391
+ if (!this.warnedNoTeamsRoute) {
392
+ this.warnedNoTeamsRoute = true;
393
+ this.opts.logger.warn(
394
+ 'hub /teams answered 404 — a hub without the team list; only the members’ own teams are projected'
395
+ );
396
+ }
397
+ return { kind: 'inconclusive' };
398
+ }
399
+ if (!response.ok) {
400
+ this.opts.logger.warn(
401
+ { status: response.status, hubOrgId },
402
+ 'hub /teams answered non-2xx — failing open'
403
+ );
404
+ return { kind: 'inconclusive' };
405
+ }
406
+ let body: unknown;
407
+ try {
408
+ body = await response.json();
409
+ } catch {
410
+ this.opts.logger.warn({ hubOrgId }, 'hub /teams body unparseable — failing open');
411
+ return { kind: 'inconclusive' };
412
+ }
413
+ const raw = (body as { teams?: unknown; nextCursor?: unknown } | null) ?? {};
414
+ if (!Array.isArray(raw.teams)) {
415
+ this.opts.logger.warn({ hubOrgId }, 'hub /teams body malformed — failing open');
416
+ return { kind: 'inconclusive' };
417
+ }
418
+ const pageTeams = parseTeams(raw.teams, this.opts.logger);
419
+ // The hub pages on the id of the last row alone, and its teams are
420
+ // hard-deleted: a cursor whose team went between two page reads answers
421
+ // an EMPTY page with no cursor, which reads exactly like the end of the
422
+ // list. It is not: what was never read must not be deleted here
423
+ // (verifier round 1, F1). A page reached THROUGH a cursor that carries
424
+ // nothing is a cut list, upserted and deleted from nothing.
425
+ if (page > 0 && pageTeams.length === 0) {
426
+ this.opts.logger.warn(
427
+ { hubOrgId, teams: teams.length },
428
+ 'hub /teams answered an empty page behind a cursor (the cursor’s team went) — upserting what was read, deleting nothing'
429
+ );
430
+ return { kind: 'ok', teams, complete: false };
431
+ }
432
+ for (const team of pageTeams) {
433
+ if (seen.has(team.id)) continue;
434
+ seen.add(team.id);
435
+ teams.push(team);
436
+ }
437
+ cursor = typeof raw.nextCursor === 'string' && raw.nextCursor !== '' ? raw.nextCursor : null;
438
+ if (cursor === null) return { kind: 'ok', teams, complete: true };
439
+ }
440
+ this.opts.logger.warn(
441
+ { hubOrgId, teams: teams.length },
442
+ 'hub /teams has more pages than one read drains — upserting what was read, deleting nothing'
443
+ );
444
+ return { kind: 'ok', teams, complete: false };
445
+ }
446
+
447
+ /**
448
+ * Create an organization at the hub AS THE USER (PRDCT-2443): `POST
449
+ * <hub>/api/v1/orgs` `{ name }` presented with the user's OWN grant token,
450
+ * obtained through the SAME HubGrantService path `orgs()` uses (cache →
451
+ * single-flighted refresh; the PRDCT-1370 presentation record and probe
452
+ * live inside it). No service key, no target-user parameter: the hub makes
453
+ * the BEARER the owner, so the only organization this can ever create is
454
+ * the caller's own.
455
+ *
456
+ * Retry posture, deliberately narrower than the read's: ONLY a 401 earns
457
+ * the one forced-refresh retry (the hub refused the token before doing
458
+ * anything, so nothing was created). A 403 is a definitive policy answer
459
+ * (the cap, or a hub that does not open creation to grants) and a
460
+ * network/timeout/5xx answer is NEVER retried — the hub commits before it
461
+ * answers, so a blind second POST could create a second organization.
462
+ */
463
+ async createOrg(localUserId: string, name: string): Promise<HubCreateOrgResult> {
464
+ const access = await this.opts.grant.accessToken(localUserId);
465
+ if (access.kind !== 'ok') return { kind: access.kind };
466
+
467
+ let res = await this.post(access.accessToken, name);
468
+ if (res.kind === 'error') return { kind: 'inconclusive' };
469
+ if (res.response.status === 401) {
470
+ this.opts.grant.invalidateAccess(localUserId);
471
+ const refreshed: GrantAccess = await this.opts.grant.refresh(localUserId);
472
+ if (refreshed.kind !== 'ok') return { kind: refreshed.kind };
473
+ res = await this.post(refreshed.accessToken, name);
474
+ if (res.kind === 'error') return { kind: 'inconclusive' };
475
+ if (res.response.status === 401) {
476
+ this.opts.logger.error(
477
+ 'hub POST /orgs refused a FRESHLY refreshed token — the hub is rejecting this tool’s grants'
478
+ );
479
+ return { kind: 'refused', status: 401, code: null };
480
+ }
481
+ }
482
+ let body: unknown = null;
483
+ try {
484
+ body = await res.response.json();
485
+ } catch {
486
+ body = null;
487
+ }
488
+ const result = classifyHubOrgCreateAnswer(res.response.status, body);
489
+ if (result.kind === 'inconclusive' || result.kind === 'refused') {
490
+ this.opts.logger.warn(
491
+ { status: res.response.status, code: result.kind === 'refused' ? result.code : undefined },
492
+ 'hub POST /orgs did not create the organization'
493
+ );
494
+ }
495
+ return result;
496
+ }
497
+
498
+ private async post(
499
+ token: string,
500
+ name: string
501
+ ): Promise<{ kind: 'ok'; response: Response } | { kind: 'error' }> {
502
+ try {
503
+ const response = await this.fetchImpl(`${this.base}/api/v1/orgs`, {
504
+ method: 'POST',
505
+ headers: {
506
+ authorization: `Bearer ${token}`,
507
+ accept: 'application/json',
508
+ 'content-type': 'application/json'
509
+ },
510
+ body: JSON.stringify({ name }),
511
+ signal: AbortSignal.timeout(this.opts.createTimeoutMs ?? this.opts.timeoutMs)
512
+ });
513
+ return { kind: 'ok', response };
514
+ } catch (err) {
515
+ this.opts.logger.warn({ err }, 'hub POST /orgs fetch failed — the organization may or may not exist');
516
+ return { kind: 'error' };
517
+ }
518
+ }
519
+
520
+ private async getTeamsPage(
521
+ token: string,
522
+ hubOrgId: string,
523
+ cursor: string | null
524
+ ): Promise<{ kind: 'ok'; response: Response } | { kind: 'error' }> {
525
+ const query = `limit=${ORG_TEAMS_PAGE_LIMIT}${cursor === null ? '' : `&cursor=${encodeURIComponent(cursor)}`}`;
526
+ try {
527
+ const response = await this.fetchImpl(`${this.base}/api/v1/teams?${query}`, {
528
+ headers: {
529
+ authorization: `Bearer ${token}`,
530
+ accept: 'application/json',
531
+ 'x-workspace-id': hubOrgId
532
+ },
533
+ signal: AbortSignal.timeout(this.opts.timeoutMs)
534
+ });
535
+ return { kind: 'ok', response };
536
+ } catch (err) {
537
+ this.opts.logger.warn({ err, hubOrgId }, 'hub /teams fetch failed — failing open');
538
+ return { kind: 'error' };
539
+ }
540
+ }
541
+
542
+ private async get(token: string): Promise<{ kind: 'ok'; response: Response } | { kind: 'error' }> {
543
+ try {
544
+ const response = await this.fetchImpl(`${this.base}/api/v1/orgs`, {
545
+ headers: { authorization: `Bearer ${token}`, accept: 'application/json' },
546
+ signal: AbortSignal.timeout(this.opts.timeoutMs)
547
+ });
548
+ return { kind: 'ok', response };
549
+ } catch (err) {
550
+ this.opts.logger.warn({ err }, 'hub /orgs fetch failed — failing open');
551
+ return { kind: 'error' };
552
+ }
553
+ }
554
+ }
@@ -0,0 +1,56 @@
1
+ export {
2
+ type AccountEvent,
3
+ type Auth,
4
+ createAuth,
5
+ mcpResourceUrl,
6
+ signInOriginRefused,
7
+ trustedOriginsFor
8
+ } from './better-auth.js';
9
+ export {
10
+ DEMO_PASS_DEFAULT_MINUTES,
11
+ DEMO_PASS_MAX_MINUTES,
12
+ DEMO_PASS_MAX_PATH_LENGTH,
13
+ DEMO_SESSION_REFUSED_API_ROUTES,
14
+ DEMO_SESSION_REFUSED_AUTH_PATHS,
15
+ type DemoSessionRefusedApiRoute,
16
+ demoSessionApiRefusalMessage,
17
+ demoSessionAuthRefusal,
18
+ isDemoAddress,
19
+ isDemoSignInHost,
20
+ isSafeDemoPath,
21
+ parseDemoEmailDomains,
22
+ parseDemoHosts
23
+ } from './demo-pass-rules.js';
24
+ export {
25
+ DEFAULT_GRANT_DIALS,
26
+ type GrantAccess,
27
+ HubGrantService,
28
+ LOCK_WATCHDOG_HEADROOM_MS
29
+ } from './hub-grant.js';
30
+ export { HubJwtVerifier } from './hub-jwt.js';
31
+ export { HubLogoutService, hintCookieClearHeader } from './hub-logout.js';
32
+ export { projectOrgMembership } from './hub-projection.js';
33
+ export {
34
+ DEFAULT_FEDERATION_DIALS,
35
+ type HubFederationDials,
36
+ HubOrgReconciler,
37
+ type ReconcilePassOutcome
38
+ } from './hub-reconcile.js';
39
+ export {
40
+ HUB_SSO_PROVIDER_ID,
41
+ HUB_SSO_SCOPES,
42
+ type HubConnectAssertion,
43
+ HubSsoLoginError,
44
+ HubSsoService,
45
+ ssoAuthorizationUrlParams
46
+ } from './hub-sso.js';
47
+ export {
48
+ type HubCreateOrgResult,
49
+ type HubOrgCreator,
50
+ HubUserClient,
51
+ classifyHubOrgCreateAnswer,
52
+ hubApiResource
53
+ } from './hub-user-client.js';
54
+ export { OauthJwtVerifier } from './oauth-jwt.js';
55
+ export { type OnWorkspaceMiss, resolveMembership } from './resolve-membership.js';
56
+ export { preflightSigningKey, retireSigningKey, runSigningKeyCli } from './signing-key.js';