@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,93 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import { mcpInputs } from './inputs.js';
3
+ import { jsonText, mergeErrorHints, wrapToolErrors } from './errors.js';
4
+ import { projectErrorHints, registerProjectTools } from './projects.js';
5
+ import { registerTeamTools } from './teams.js';
6
+ import { callApi, createScopeCheck, forWorkspace, pageQuery } from './tool-kit.js';
7
+ /**
8
+ * The ONE composition of an instance's hint table: the domain hints, then
9
+ * every chassis group (the projects today), then the tool's own last, so a
10
+ * tool may re-word a chassis code and never the reverse. A tool set that
11
+ * wraps its own errors reads the same composition (never a copy), so a
12
+ * chassis group added here reaches the tool's tools without a second edit.
13
+ */
14
+ export function composeErrorHints(toolHints, toolPrefix) {
15
+ return mergeErrorHints({ ...projectErrorHints(toolPrefix), ...toolHints });
16
+ }
17
+ export function buildMcpServer(ctx, info, tool, identity) {
18
+ // `<prefix>whoami` (the contract of `toolPrefix`), registered below: the other chassis tools point at it.
19
+ const whoami = `${identity.toolPrefix}whoami`;
20
+ const checkScope = createScopeCheck(tool.scopes);
21
+ const hints = composeErrorHints(tool.errorHints, identity.toolPrefix);
22
+ const server = new McpServer({ name: identity.serverName, version: info.version }, {
23
+ instructions: tool.instructions(info)
24
+ });
25
+ // The shared inputs (`inputs.ts`): the ones a tool's own set declares its tools with.
26
+ const { workspaceInput, cursorInput, limitInput } = mcpInputs(identity);
27
+ // ── Pattern 1: READ tool — the end-to-end whoami proof ────────────────────
28
+ server.registerTool('get_me', {
29
+ description: 'Who is connected: the user this MCP connection acts as, with all their organizations. ' +
30
+ 'Returns { user: { id, email, name }, workspace, role, via, scopes, workspaces }. ' +
31
+ `Everything done through this server happens as this user. (Alias of ${whoami}.)`,
32
+ inputSchema: { workspace: workspaceInput },
33
+ annotations: { readOnlyHint: true }
34
+ }, async ({ workspace }) => {
35
+ const denied = checkScope(ctx.principal, tool.scopes.read);
36
+ if (denied)
37
+ return denied;
38
+ const c = forWorkspace(ctx, workspace);
39
+ return wrapToolErrors(async () => jsonText(await callApi(c, '/api/v1/me')), hints);
40
+ });
41
+ // ── Pattern 2: LIST tool with cursor pagination passed through ────────────
42
+ server.registerTool('list_files', {
43
+ description: "List a workspace's files, newest first. Returns { files: [{ id, sha256, sizeBytes, " +
44
+ 'contentType, originalName, createdBy, createdAt }], nextCursor }. When nextCursor is ' +
45
+ 'non-null, call again with cursor set to it for the next page. Download or upload happen ' +
46
+ 'through the API, not through tools.',
47
+ inputSchema: {
48
+ workspace: workspaceInput,
49
+ limit: limitInput,
50
+ cursor: cursorInput
51
+ },
52
+ annotations: { readOnlyHint: true }
53
+ }, async ({ workspace, limit, cursor }) => {
54
+ const denied = checkScope(ctx.principal, tool.scopes.read);
55
+ if (denied)
56
+ return denied;
57
+ const c = forWorkspace(ctx, workspace);
58
+ return wrapToolErrors(async () => jsonText(await callApi(c, pageQuery('/api/v1/files', { cursor, limit }))), hints);
59
+ });
60
+ // ── Identity under the tool's own prefix ───────────────────────────────────
61
+ // Registered by the chassis (it reads `/me`, nothing of a domain) so that the
62
+ // name every `workspace` argument and `get_me` point at always exists. Third,
63
+ // right before the tool's set: `tools/list` keeps its order.
64
+ server.registerTool(whoami, {
65
+ description: 'Who is connected: the user this MCP connection acts as, plus ALL their organizations ' +
66
+ '(workspaces) with per-entry role/default/suspended flags. Returns { user: { id, email, ' +
67
+ 'name }, workspace, role, via, scopes, workspaces: [...], activeWorkspaceId }. The ' +
68
+ 'credential is the USER; the organization is a PER-CALL parameter: every tool accepts an ' +
69
+ 'optional `workspace` (an id from `workspaces[]`) — omitted, the entry flagged `default: ' +
70
+ 'true` is used (else the oldest membership). Call this first to discover the ids.',
71
+ inputSchema: { workspace: workspaceInput },
72
+ annotations: { readOnlyHint: true }
73
+ }, async ({ workspace }) => {
74
+ const denied = checkScope(ctx.principal, tool.scopes.read);
75
+ if (denied)
76
+ return denied;
77
+ const c = forWorkspace(ctx, workspace);
78
+ return wrapToolErrors(async () => jsonText(await callApi(c, '/api/v1/me')), hints);
79
+ });
80
+ // ── Projects: a chassis concept, so a chassis tool set ─────────────────────
81
+ // A project is a subgroup of a workspace with its own members and roles —
82
+ // the chassis owns it, and therefore owns the eleven tools over it. Registered
83
+ // under the tool's prefix, after whoami and before the tool's own set, so
84
+ // `tools/list` keeps one stable order across every instance.
85
+ registerProjectTools(server, ctx, identity, tool.scopes, checkScope, hints);
86
+ // Teams (PRDCT-2813): a chassis concept too, read-only over MCP, right after
87
+ // the projects they can be members of.
88
+ registerTeamTools(server, ctx, identity, tool.scopes, checkScope, hints);
89
+ // The product surface: the tool's own set, after the chassis tools.
90
+ tool.registerTools(server, ctx);
91
+ return server;
92
+ }
93
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import { type ErrorHints } from './errors.js';
3
+ import { type McpScopes, type McpToolContext, type ScopeCheck } from './tool-kit.js';
4
+ import type { McpIdentity } from './server.js';
5
+ /** Register the two team reads on a server, after the project tools. */
6
+ export declare function registerTeamTools(server: McpServer, ctx: McpToolContext, identity: McpIdentity, scopes: McpScopes, checkScope: ScopeCheck<string>, hints: ErrorHints): void;
7
+ //# sourceMappingURL=teams.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"teams.d.ts","sourceRoot":"","sources":["../../src/mcp/teams.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,EAA4B,KAAK,UAAU,EAAuB,MAAM,aAAa,CAAC;AAC7F,OAAO,EAIL,KAAK,SAAS,EACd,KAAK,cAAc,EACnB,KAAK,UAAU,EAChB,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AA8B/C,wEAAwE;AACxE,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,SAAS,EACjB,GAAG,EAAE,cAAc,EACnB,QAAQ,EAAE,WAAW,EACrB,MAAM,EAAE,SAAS,EACjB,UAAU,EAAE,UAAU,CAAC,MAAM,CAAC,EAC9B,KAAK,EAAE,UAAU,GAChB,IAAI,CA8CN"}
@@ -0,0 +1,62 @@
1
+ import { z } from 'zod';
2
+ import { mcpInputs } from './inputs.js';
3
+ import { jsonText, wrapToolErrors } from './errors.js';
4
+ import { callApi, forWorkspace, pageQuery } from './tool-kit.js';
5
+ /**
6
+ * The two TEAM reads (PRDCT-2813), registered by the chassis right after the
7
+ * project tools: a team is a chassis concept (a named group of a workspace's
8
+ * own members, on both editions), so the tools over it are the chassis'. Thin
9
+ * shims over the instance's own /api/v1/teams called IN-PROCESS with the
10
+ * caller's bearer forwarded verbatim, like every other chassis tool.
11
+ *
12
+ * READS ONLY, by design: shaping a team (creating it, seating people) is a
13
+ * person's act on the People page, or on the Antasphere account site for a
14
+ * workspace it manages; an agent puts a team on a project through
15
+ * `<toolPrefix>add_project_member` with `teamId`. Nothing here names a tool,
16
+ * a brand or a domain.
17
+ */
18
+ /** What a team IS, opening both descriptions. */
19
+ const WHAT_IS_A_TEAM = 'A team is a named group of the organization’s own members (for example "Design" or "Sales"). ' +
20
+ 'A team can be put on a project with a role, and every member of the team then holds that role ' +
21
+ 'on the project.';
22
+ /** Where teams come from and where they are shaped. */
23
+ const WHERE_TEAMS_LIVE = 'In an organization managed by the Antasphere account site, the teams come from there and are ' +
24
+ 'read-only here. Creating a team or adding people to one is done by a person on the People page, ' +
25
+ 'or on the Antasphere account site for an organization it manages, never through these tools.';
26
+ const teamIdInput = z.uuid().describe('The team id, from the teams list (never the team name or slug).');
27
+ /** Register the two team reads on a server, after the project tools. */
28
+ export function registerTeamTools(server, ctx, identity, scopes, checkScope, hints) {
29
+ const { workspaceInput, cursorInput, limitInput } = mcpInputs(identity);
30
+ const prefix = identity.toolPrefix;
31
+ const read = (workspace, path) => {
32
+ const denied = checkScope(ctx.principal, scopes.read);
33
+ if (denied)
34
+ return Promise.resolve(denied);
35
+ const c = forWorkspace(ctx, workspace);
36
+ return wrapToolErrors(async () => jsonText(await callApi(c, path)), hints);
37
+ };
38
+ server.registerTool(`${prefix}list_teams`, {
39
+ description: `List the teams of an organization, newest first. ${WHAT_IS_A_TEAM} ${WHERE_TEAMS_LIVE} ` +
40
+ 'Returns { teams: [{ id, slug, name, membersCount, isMember, hubTeamId, createdAt, ' +
41
+ 'updatedAt }], nextCursor } — `isMember` says whether YOU are in the team, and `hubTeamId` ' +
42
+ 'is set when the team comes from the Antasphere account site. Pass a team `id` as `teamId` ' +
43
+ `to ${prefix}list_team_members or ${prefix}add_project_member. When nextCursor is non-null, ` +
44
+ 'call again with cursor set to it.',
45
+ inputSchema: { workspace: workspaceInput, limit: limitInput, cursor: cursorInput },
46
+ annotations: { readOnlyHint: true }
47
+ }, async ({ workspace, limit, cursor }) => read(workspace, pageQuery('/api/v1/teams', { cursor, limit })));
48
+ server.registerTool(`${prefix}list_team_members`, {
49
+ description: `List the members of one team. ${WHAT_IS_A_TEAM} ${WHERE_TEAMS_LIVE} Returns { members: ` +
50
+ '[{ userId, email, name, role, isActive, addedAt }], nextCursor } — `role` is the person’s ' +
51
+ 'role in the ORGANIZATION (a team has no roles of its own). When nextCursor is non-null, call ' +
52
+ 'again with cursor set to it.',
53
+ inputSchema: {
54
+ workspace: workspaceInput,
55
+ teamId: teamIdInput,
56
+ limit: limitInput,
57
+ cursor: cursorInput
58
+ },
59
+ annotations: { readOnlyHint: true }
60
+ }, async ({ workspace, teamId, limit, cursor }) => read(workspace, pageQuery(`/api/v1/teams/${teamId}/members`, { cursor, limit })));
61
+ }
62
+ //# sourceMappingURL=teams.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"teams.js","sourceRoot":"","sources":["../../src/mcp/teams.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAwC,MAAM,aAAa,CAAC;AAC7F,OAAO,EACL,OAAO,EACP,YAAY,EACZ,SAAS,EAIV,MAAM,eAAe,CAAC;AAGvB;;;;;;;;;;;;GAYG;AAEH,iDAAiD;AACjD,MAAM,cAAc,GAClB,+FAA+F;IAC/F,gGAAgG;IAChG,iBAAiB,CAAC;AAEpB,uDAAuD;AACvD,MAAM,gBAAgB,GACpB,+FAA+F;IAC/F,kGAAkG;IAClG,8FAA8F,CAAC;AAEjG,MAAM,WAAW,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,iEAAiE,CAAC,CAAC;AAEzG,wEAAwE;AACxE,MAAM,UAAU,iBAAiB,CAC/B,MAAiB,EACjB,GAAmB,EACnB,QAAqB,EACrB,MAAiB,EACjB,UAA8B,EAC9B,KAAiB;IAEjB,MAAM,EAAE,cAAc,EAAE,WAAW,EAAE,UAAU,EAAE,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;IACxE,MAAM,MAAM,GAAG,QAAQ,CAAC,UAAU,CAAC;IAEnC,MAAM,IAAI,GAAG,CAAC,SAA6B,EAAE,IAAY,EAA2B,EAAE;QACpF,MAAM,MAAM,GAAG,UAAU,CAAC,GAAG,CAAC,SAAS,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;QACtD,IAAI,MAAM;YAAE,OAAO,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAC3C,MAAM,CAAC,GAAG,YAAY,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QACvC,OAAO,cAAc,CAAC,KAAK,IAAI,EAAE,CAAC,QAAQ,CAAC,MAAM,OAAO,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IAC7E,CAAC,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,GAAG,MAAM,YAAY,EACrB;QACE,WAAW,EACT,oDAAoD,cAAc,IAAI,gBAAgB,GAAG;YACzF,oFAAoF;YACpF,4FAA4F;YAC5F,4FAA4F;YAC5F,MAAM,MAAM,wBAAwB,MAAM,mDAAmD;YAC7F,mCAAmC;QACrC,WAAW,EAAE,EAAE,SAAS,EAAE,cAAc,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE;QAClF,WAAW,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE;KACpC,EACD,KAAK,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,eAAe,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,CACvG,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,GAAG,MAAM,mBAAmB,EAC5B;QACE,WAAW,EACT,iCAAiC,cAAc,IAAI,gBAAgB,sBAAsB;YACzF,4FAA4F;YAC5F,+FAA+F;YAC/F,8BAA8B;QAChC,WAAW,EAAE;YACX,SAAS,EAAE,cAAc;YACzB,MAAM,EAAE,WAAW;YACnB,KAAK,EAAE,UAAU;YACjB,MAAM,EAAE,WAAW;SACpB;QACD,WAAW,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE;KACpC,EACD,KAAK,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,CAC7C,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,iBAAiB,MAAM,UAAU,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,CACnF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,67 @@
1
+ import { type Principal } from '@antasphere/chassis-contract';
2
+ import { type ToolTextResult } from './errors.js';
3
+ /**
4
+ * Shared plumbing for MCP tools (used by the chassis examples in server.ts
5
+ * and the tool's own set). Every call goes through the
6
+ * instance's own /api/v1 IN-PROCESS with the caller's Authorization header
7
+ * forwarded verbatim — MCP is just another API client, no privileged path.
8
+ */
9
+ export interface McpToolContext {
10
+ /** In-process fetch against the root app (path → Response). */
11
+ fetchApi: (path: string, init?: RequestInit) => Promise<Response>;
12
+ /** The verified caller (OAuth token or API key principal). */
13
+ principal: Principal;
14
+ /** Forwarded verbatim on every in-process API call. */
15
+ authorizationHeader: string;
16
+ /**
17
+ * The instance's public origin (`PUBLIC_BASE_URL`), for the one thing a
18
+ * tool composes for a human rather than for the API: the page of the tool's
19
+ * resource that a push answers with (PRDCT-2280). Never used to reach the API.
20
+ */
21
+ publicBaseUrl: string;
22
+ /**
23
+ * Target workspace of THIS tool call (user-scoped credential model): set
24
+ * from the tool's optional `workspace` argument via {@link forWorkspace},
25
+ * it rides the in-process re-entry as the X-Workspace-Id header, where
26
+ * the API's own resolvers authorize it against the caller's live
27
+ * memberships — a tool argument can never grant what the credential's
28
+ * user does not hold. Absent = the caller's default workspace.
29
+ */
30
+ workspaceId?: string | undefined;
31
+ }
32
+ /**
33
+ * The per-call workspace seam: every workspace-scoped tool passes its
34
+ * optional `workspace` argument through here so the selection travels on
35
+ * the ONE header the whole platform authorizes.
36
+ */
37
+ export declare function forWorkspace(ctx: McpToolContext, workspace: string | undefined): McpToolContext;
38
+ /**
39
+ * Tool-level scope pre-check — UX only: the API's fail-closed allowlist
40
+ * (middleware/scopes.ts) is the enforcement point; this just gives the model
41
+ * a clean, actionable error instead of a raw 403.
42
+ */
43
+ export type ScopeCheck<TScope extends string> = (principal: Principal, scope: TScope) => ToolTextResult | null;
44
+ /** The tool's two MCP scope names: what a read tool and a write tool pre-check. */
45
+ export interface McpScopes<TRead extends string = string, TWrite extends string = string> {
46
+ read: TRead;
47
+ write: TWrite;
48
+ }
49
+ export declare function createScopeCheck<TRead extends string, TWrite extends string>(scopes: McpScopes<TRead, TWrite>): ScopeCheck<TRead | TWrite>;
50
+ /**
51
+ * In-process API call returning the raw Response (asset downloads, multipart
52
+ * uploads). A non-2xx answer is parsed into an ApiToolError so wrapToolErrors
53
+ * renders the code + `Next:` hint.
54
+ */
55
+ export declare function fetchApiRaw(ctx: McpToolContext, path: string, init?: RequestInit): Promise<Response>;
56
+ /** In-process JSON API call: parses the body, maps non-2xx to ApiToolError. */
57
+ export declare function callApi(ctx: McpToolContext, path: string, init?: RequestInit): Promise<unknown>;
58
+ /**
59
+ * Append cursor/limit list params to a path, after the route's own filters
60
+ * (`extra`, e.g. the `type` of the tool's resource list); an undefined filter is
61
+ * left out.
62
+ */
63
+ export declare function pageQuery(base: string, params: {
64
+ cursor?: string | undefined;
65
+ limit?: number | undefined;
66
+ }, extra?: Record<string, string | undefined>): string;
67
+ //# sourceMappingURL=tool-kit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-kit.d.ts","sourceRoot":"","sources":["../../src/mcp/tool-kit.ts"],"names":[],"mappings":"AAAA,OAAO,EAA2B,KAAK,SAAS,EAAE,MAAM,8BAA8B,CAAC;AACvF,OAAO,EAAsB,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AAEtE;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC7B,+DAA+D;IAC/D,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;IAClE,8DAA8D;IAC9D,SAAS,EAAE,SAAS,CAAC;IACrB,uDAAuD;IACvD,mBAAmB,EAAE,MAAM,CAAC;IAC5B;;;;OAIG;IACH,aAAa,EAAE,MAAM,CAAC;IACtB;;;;;;;OAOG;IACH,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAClC;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,cAAc,CAE/F;AAUD;;;;GAIG;AACH,MAAM,MAAM,UAAU,CAAC,MAAM,SAAS,MAAM,IAAI,CAC9C,SAAS,EAAE,SAAS,EACpB,KAAK,EAAE,MAAM,KACV,cAAc,GAAG,IAAI,CAAC;AAE3B,mFAAmF;AACnF,MAAM,WAAW,SAAS,CAAC,KAAK,SAAS,MAAM,GAAG,MAAM,EAAE,MAAM,SAAS,MAAM,GAAG,MAAM;IACtF,IAAI,EAAE,KAAK,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,gBAAgB,CAAC,KAAK,SAAS,MAAM,EAAE,MAAM,SAAS,MAAM,EAC1E,MAAM,EAAE,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,GAC/B,UAAU,CAAC,KAAK,GAAG,MAAM,CAAC,CAW5B;AAED;;;;GAIG;AACH,wBAAsB,WAAW,CAC/B,GAAG,EAAE,cAAc,EACnB,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE,WAAgB,GACrB,OAAO,CAAC,QAAQ,CAAC,CAiBnB;AAED,+EAA+E;AAC/E,wBAAsB,OAAO,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,WAAgB,GAAG,OAAO,CAAC,OAAO,CAAC,CAiBzG;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CACvB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,EACnE,KAAK,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAM,GAC7C,MAAM,CASR"}
@@ -0,0 +1,74 @@
1
+ import { ACTIVE_WORKSPACE_HEADER } from '@antasphere/chassis-contract';
2
+ import { ApiToolError, deny } from './errors.js';
3
+ /**
4
+ * The per-call workspace seam: every workspace-scoped tool passes its
5
+ * optional `workspace` argument through here so the selection travels on
6
+ * the ONE header the whole platform authorizes.
7
+ */
8
+ export function forWorkspace(ctx, workspace) {
9
+ return workspace ? { ...ctx, workspaceId: workspace } : ctx;
10
+ }
11
+ /** The re-entry headers: caller's bearer + the per-call workspace selector. */
12
+ function apiHeaders(ctx) {
13
+ return {
14
+ authorization: ctx.authorizationHeader,
15
+ ...(ctx.workspaceId ? { [ACTIVE_WORKSPACE_HEADER]: ctx.workspaceId } : {})
16
+ };
17
+ }
18
+ export function createScopeCheck(scopes) {
19
+ return (principal, scope) => {
20
+ if (principal.scopes && !principal.scopes.has(scope)) {
21
+ return deny(`Missing scope "${scope}": this connection was not granted ` +
22
+ (scope === scopes.write ? 'permission to create or edit data.' : 'permission to read data.') +
23
+ ' Reconnect the MCP server and approve the permission on the consent screen.');
24
+ }
25
+ return null;
26
+ };
27
+ }
28
+ /**
29
+ * In-process API call returning the raw Response (asset downloads, multipart
30
+ * uploads). A non-2xx answer is parsed into an ApiToolError so wrapToolErrors
31
+ * renders the code + `Next:` hint.
32
+ */
33
+ export async function fetchApiRaw(ctx, path, init = {}) {
34
+ const res = await ctx.fetchApi(path, {
35
+ ...init,
36
+ headers: { ...(init.headers ?? {}), ...apiHeaders(ctx) }
37
+ });
38
+ if (!res.ok) {
39
+ const body = (await res.json().catch(() => null));
40
+ throw new ApiToolError(res.status, body?.error?.code ?? null, body?.error?.message ?? `unexpected response from ${path}`, body?.error?.details);
41
+ }
42
+ return res;
43
+ }
44
+ /** In-process JSON API call: parses the body, maps non-2xx to ApiToolError. */
45
+ export async function callApi(ctx, path, init = {}) {
46
+ const res = await ctx.fetchApi(path, {
47
+ ...init,
48
+ headers: { ...(init.headers ?? {}), ...apiHeaders(ctx) }
49
+ });
50
+ const body = (await res.json().catch(() => null));
51
+ if (!res.ok) {
52
+ throw new ApiToolError(res.status, body?.error?.code ?? null, body?.error?.message ?? `unexpected response from ${path}`, body?.error?.details);
53
+ }
54
+ return body;
55
+ }
56
+ /**
57
+ * Append cursor/limit list params to a path, after the route's own filters
58
+ * (`extra`, e.g. the `type` of the tool's resource list); an undefined filter is
59
+ * left out.
60
+ */
61
+ export function pageQuery(base, params, extra = {}) {
62
+ const query = new URLSearchParams();
63
+ for (const [key, value] of Object.entries(extra)) {
64
+ if (value !== undefined)
65
+ query.set(key, value);
66
+ }
67
+ if (params.cursor)
68
+ query.set('cursor', params.cursor);
69
+ if (params.limit !== undefined)
70
+ query.set('limit', String(params.limit));
71
+ const qs = query.toString();
72
+ return qs ? `${base}?${qs}` : base;
73
+ }
74
+ //# sourceMappingURL=tool-kit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-kit.js","sourceRoot":"","sources":["../../src/mcp/tool-kit.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,95 @@
1
+ import { type DbConn } from '@antasphere/chassis-db';
2
+ /**
3
+ * The membership an ADD hangs a right on, re-read inside the add's own
4
+ * transaction and held FOR SHARE until it commits: true when the row is
5
+ * there, in that workspace, and active. Every add of something a removal
6
+ * takes (a project grant, a team seat, a demo pass) calls this before its
7
+ * insert, and refuses on false the way it refuses an inactive member.
8
+ *
9
+ * Why the lock (the end-to-end verification, finding 5): the add's first read
10
+ * is outside any transaction, and the insert's foreign key check takes only a
11
+ * KEY SHARE lock, which a removal's `UPDATE workspace_members` does not wait
12
+ * for. An add that read the row active, then waited on another lock (the
13
+ * project row, the team row), inserted after a removal had committed, on the
14
+ * now inactive row, and the right came back with the person at their
15
+ * re-invitation. Held FOR SHARE, the row makes the removal's update wait for
16
+ * the add to commit (the removal's second pass then takes what the add
17
+ * wrote, `deleteMembershipGrants`'s caller); an add that arrives after the
18
+ * update re-reads the row off and inserts nothing.
19
+ */
20
+ export declare function holdLiveMembership(tx: DbConn, workspaceId: string, who: {
21
+ memberId: string;
22
+ } | {
23
+ userId: string;
24
+ }): Promise<boolean>;
25
+ /** One membership a removal switched off. */
26
+ export interface RemovedMembership {
27
+ /** The `workspace_members` row. */
28
+ memberId: string;
29
+ workspaceId: string;
30
+ userId: string;
31
+ }
32
+ /**
33
+ * The tool's half of a removal (the `membershipRemoval` slot): what the TOOL
34
+ * hangs on a person in a workspace outside the chassis tables (an invite
35
+ * waiting for them, a grant on one of its resources). It runs in the
36
+ * removal's own transaction and answers what it ended, by name, for the
37
+ * audit record.
38
+ */
39
+ export type MembershipRemovalHook = (tx: DbConn, removed: readonly RemovedMembership[]) => Promise<Record<string, number>>;
40
+ export interface RemovalCounts {
41
+ projectGrants: number;
42
+ teamSeats: number;
43
+ /** Open workspace invitations revoked: the ones FOR the person and the ones they ISSUED. */
44
+ invitations: number;
45
+ /** Live demo passes revoked, their sessions ended: the ones opening the person and the ones they MINTED. */
46
+ demoPasses: number;
47
+ /** What the tool's hook ended, under the names it gave; empty without a hook. */
48
+ tool: Record<string, number>;
49
+ }
50
+ /**
51
+ * What a REMOVAL takes away beside the membership itself, stated once for
52
+ * both editions (PRDCT-2816): the person's project grants, their team seats
53
+ * (which is also every grant they held through a team), the open workspace
54
+ * invitations that name them or that they issued, and what the tool hangs
55
+ * on them in that workspace (`toolHook`).
56
+ *
57
+ * The demo passes are doors too (round 3, F1): a pass the person MINTED
58
+ * signs a demo person in, who could reactivate them; a pass minted FOR them
59
+ * works again the day they are re-invited, in whoever's hands it is. Both
60
+ * are revoked with the sessions they opened, the pass service's own way.
61
+ *
62
+ * ORDER (round 3, F2): the caller runs this BEFORE it switches the membership
63
+ * row off, inside the same transaction. An invitation's accept locks the
64
+ * invitation, then the membership row; a removal that locked the membership
65
+ * first and the invitation second met it head on and one of the two died
66
+ * of a deadlock. Same order on both sides, no deadlock.
67
+ *
68
+ * The invitations are doors, not rights (the verifier's round 2, N1 and N2).
69
+ * An invitation FOR the person that was open at the removal reactivates the
70
+ * row at the role it names: the person would come back alone, as admin if it
71
+ * says so. An invitation the person ISSUED is a way back in under another
72
+ * address. Both are revoked; an invitation made after the removal is the
73
+ * workspace's own act and brings the person back.
74
+ *
75
+ * A removal switches the membership row off and never deletes it (a re-add
76
+ * reactivates the very same row), so the foreign keys' cascade never fires:
77
+ * without these deletes, a person removed and added back later would find
78
+ * every old grant and seat waiting, and a door left open for them (a pending
79
+ * invite of the tool's) would let them switch the row back on themselves. A
80
+ * removal is a removal: only an act of the workspace brings the person back,
81
+ * and they come back with nothing. A PAUSE (`PATCH /members/{id}` with
82
+ * `isActive: false`) keeps everything, on purpose.
83
+ *
84
+ * The two callers: the hub reconcile's sweep (cloud, the hub removed the
85
+ * person) and `POST /members/{id}/remove` (a workspace managed here). Run it
86
+ * in the transaction that switches the rows off.
87
+ *
88
+ * Idempotent, so a caller may run it twice in one transaction: the deletes
89
+ * are by membership, the revokes filter on what is still open. The removal
90
+ * route does (a second pass after the row is off, `mergeRemovalCounts`).
91
+ */
92
+ export declare function deleteMembershipGrants(tx: DbConn, removed: readonly RemovedMembership[], toolHook?: MembershipRemovalHook): Promise<RemovalCounts>;
93
+ /** Two passes of `deleteMembershipGrants` as one record: every count summed, the tool's by name. */
94
+ export declare function mergeRemovalCounts(a: RemovalCounts, b: RemovalCounts): RemovalCounts;
95
+ //# sourceMappingURL=removal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"removal.d.ts","sourceRoot":"","sources":["../../src/members/removal.ts"],"names":[],"mappings":"AACA,OAAO,EAWL,KAAK,MAAM,EACZ,MAAM,wBAAwB,CAAC;AAEhC;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,kBAAkB,CACtC,EAAE,EAAE,MAAM,EACV,WAAW,EAAE,MAAM,EACnB,GAAG,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,GAC7C,OAAO,CAAC,OAAO,CAAC,CAclB;AAED,6CAA6C;AAC7C,MAAM,WAAW,iBAAiB;IAChC,mCAAmC;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;GAMG;AACH,MAAM,MAAM,qBAAqB,GAAG,CAClC,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,SAAS,iBAAiB,EAAE,KAClC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AAErC,MAAM,WAAW,aAAa;IAC5B,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,4FAA4F;IAC5F,WAAW,EAAE,MAAM,CAAC;IACpB,4GAA4G;IAC5G,UAAU,EAAE,MAAM,CAAC;IACnB,iFAAiF;IACjF,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,wBAAsB,sBAAsB,CAC1C,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,SAAS,iBAAiB,EAAE,EACrC,QAAQ,CAAC,EAAE,qBAAqB,GAC/B,OAAO,CAAC,aAAa,CAAC,CAwExB;AAED,oGAAoG;AACpG,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,aAAa,GAAG,aAAa,CAUpF"}
@@ -0,0 +1,143 @@
1
+ import { and, eq, inArray, isNull, or, sql } from 'drizzle-orm';
2
+ import { demoPasses, demoPassSessions, invitations, oauthAccessToken, oauthRefreshToken, projectMembers, session as sessionTable, user as userTable, workspaceMembers, workspaceTeamMembers } from '@antasphere/chassis-db';
3
+ /**
4
+ * The membership an ADD hangs a right on, re-read inside the add's own
5
+ * transaction and held FOR SHARE until it commits: true when the row is
6
+ * there, in that workspace, and active. Every add of something a removal
7
+ * takes (a project grant, a team seat, a demo pass) calls this before its
8
+ * insert, and refuses on false the way it refuses an inactive member.
9
+ *
10
+ * Why the lock (the end-to-end verification, finding 5): the add's first read
11
+ * is outside any transaction, and the insert's foreign key check takes only a
12
+ * KEY SHARE lock, which a removal's `UPDATE workspace_members` does not wait
13
+ * for. An add that read the row active, then waited on another lock (the
14
+ * project row, the team row), inserted after a removal had committed, on the
15
+ * now inactive row, and the right came back with the person at their
16
+ * re-invitation. Held FOR SHARE, the row makes the removal's update wait for
17
+ * the add to commit (the removal's second pass then takes what the add
18
+ * wrote, `deleteMembershipGrants`'s caller); an add that arrives after the
19
+ * update re-reads the row off and inserts nothing.
20
+ */
21
+ export async function holdLiveMembership(tx, workspaceId, who) {
22
+ const [row] = await tx
23
+ .select({ id: workspaceMembers.id })
24
+ .from(workspaceMembers)
25
+ .where(and('memberId' in who ? eq(workspaceMembers.id, who.memberId) : eq(workspaceMembers.userId, who.userId), eq(workspaceMembers.workspaceId, workspaceId), eq(workspaceMembers.isActive, true)))
26
+ .for('share')
27
+ .limit(1);
28
+ return row !== undefined;
29
+ }
30
+ /**
31
+ * What a REMOVAL takes away beside the membership itself, stated once for
32
+ * both editions (PRDCT-2816): the person's project grants, their team seats
33
+ * (which is also every grant they held through a team), the open workspace
34
+ * invitations that name them or that they issued, and what the tool hangs
35
+ * on them in that workspace (`toolHook`).
36
+ *
37
+ * The demo passes are doors too (round 3, F1): a pass the person MINTED
38
+ * signs a demo person in, who could reactivate them; a pass minted FOR them
39
+ * works again the day they are re-invited, in whoever's hands it is. Both
40
+ * are revoked with the sessions they opened, the pass service's own way.
41
+ *
42
+ * ORDER (round 3, F2): the caller runs this BEFORE it switches the membership
43
+ * row off, inside the same transaction. An invitation's accept locks the
44
+ * invitation, then the membership row; a removal that locked the membership
45
+ * first and the invitation second met it head on and one of the two died
46
+ * of a deadlock. Same order on both sides, no deadlock.
47
+ *
48
+ * The invitations are doors, not rights (the verifier's round 2, N1 and N2).
49
+ * An invitation FOR the person that was open at the removal reactivates the
50
+ * row at the role it names: the person would come back alone, as admin if it
51
+ * says so. An invitation the person ISSUED is a way back in under another
52
+ * address. Both are revoked; an invitation made after the removal is the
53
+ * workspace's own act and brings the person back.
54
+ *
55
+ * A removal switches the membership row off and never deletes it (a re-add
56
+ * reactivates the very same row), so the foreign keys' cascade never fires:
57
+ * without these deletes, a person removed and added back later would find
58
+ * every old grant and seat waiting, and a door left open for them (a pending
59
+ * invite of the tool's) would let them switch the row back on themselves. A
60
+ * removal is a removal: only an act of the workspace brings the person back,
61
+ * and they come back with nothing. A PAUSE (`PATCH /members/{id}` with
62
+ * `isActive: false`) keeps everything, on purpose.
63
+ *
64
+ * The two callers: the hub reconcile's sweep (cloud, the hub removed the
65
+ * person) and `POST /members/{id}/remove` (a workspace managed here). Run it
66
+ * in the transaction that switches the rows off.
67
+ *
68
+ * Idempotent, so a caller may run it twice in one transaction: the deletes
69
+ * are by membership, the revokes filter on what is still open. The removal
70
+ * route does (a second pass after the row is off, `mergeRemovalCounts`).
71
+ */
72
+ export async function deleteMembershipGrants(tx, removed, toolHook) {
73
+ if (removed.length === 0) {
74
+ return { projectGrants: 0, teamSeats: 0, invitations: 0, demoPasses: 0, tool: {} };
75
+ }
76
+ const ids = removed.map((row) => row.memberId);
77
+ const grants = await tx
78
+ .delete(projectMembers)
79
+ .where(inArray(projectMembers.memberId, ids))
80
+ .returning({ id: projectMembers.id });
81
+ const seats = await tx
82
+ .delete(workspaceTeamMembers)
83
+ .where(inArray(workspaceTeamMembers.memberId, ids))
84
+ .returning({ id: workspaceTeamMembers.id });
85
+ let revokedInvitations = 0;
86
+ let revokedPasses = 0;
87
+ for (const { workspaceId, userId } of removed) {
88
+ const passes = await tx
89
+ .update(demoPasses)
90
+ .set({ revokedAt: sql `now()` })
91
+ .where(and(eq(demoPasses.workspaceId, workspaceId), isNull(demoPasses.revokedAt), or(eq(demoPasses.userId, userId), eq(demoPasses.createdBy, userId))))
92
+ .returning({ id: demoPasses.id });
93
+ if (passes.length > 0) {
94
+ const passIds = passes.map((p) => p.id);
95
+ const sessions = (await tx
96
+ .select({ sessionId: demoPassSessions.sessionId })
97
+ .from(demoPassSessions)
98
+ .where(inArray(demoPassSessions.passId, passIds))).map((s) => s.sessionId);
99
+ if (sessions.length > 0) {
100
+ await tx.delete(oauthAccessToken).where(inArray(oauthAccessToken.sessionId, sessions));
101
+ await tx.delete(oauthRefreshToken).where(inArray(oauthRefreshToken.sessionId, sessions));
102
+ await tx.delete(demoPassSessions).where(inArray(demoPassSessions.sessionId, sessions));
103
+ await tx.delete(sessionTable).where(inArray(sessionTable.id, sessions));
104
+ }
105
+ revokedPasses += passes.length;
106
+ }
107
+ const [person] = await tx
108
+ .select({ email: userTable.email })
109
+ .from(userTable)
110
+ .where(eq(userTable.id, userId))
111
+ .limit(1);
112
+ const rows = await tx
113
+ .update(invitations)
114
+ .set({ revokedAt: sql `now()` })
115
+ .where(and(eq(invitations.workspaceId, workspaceId), isNull(invitations.acceptedAt), isNull(invitations.revokedAt), person
116
+ ? or(eq(invitations.invitedBy, userId), sql `lower(${invitations.email}) = lower(${person.email})`)
117
+ : eq(invitations.invitedBy, userId)))
118
+ .returning({ id: invitations.id });
119
+ revokedInvitations += rows.length;
120
+ }
121
+ const tool = toolHook ? await toolHook(tx, removed) : {};
122
+ return {
123
+ projectGrants: grants.length,
124
+ teamSeats: seats.length,
125
+ invitations: revokedInvitations,
126
+ demoPasses: revokedPasses,
127
+ tool
128
+ };
129
+ }
130
+ /** Two passes of `deleteMembershipGrants` as one record: every count summed, the tool's by name. */
131
+ export function mergeRemovalCounts(a, b) {
132
+ const tool = { ...a.tool };
133
+ for (const [key, n] of Object.entries(b.tool))
134
+ tool[key] = (tool[key] ?? 0) + n;
135
+ return {
136
+ projectGrants: a.projectGrants + b.projectGrants,
137
+ teamSeats: a.teamSeats + b.teamSeats,
138
+ invitations: a.invitations + b.invitations,
139
+ demoPasses: a.demoPasses + b.demoPasses,
140
+ tool
141
+ };
142
+ }
143
+ //# sourceMappingURL=removal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"removal.js","sourceRoot":"","sources":["../../src/members/removal.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import type { MiddlewareHandler } from 'hono';
2
+ /**
3
+ * Pre-validates JSON bodies bound for the Better Auth mount (AF-1 + the
4
+ * update-user half of SL-B4, PRDCT-1358).
5
+ *
6
+ * The load-bearing half is NUL: Better Auth's free-text sinks (`/update-user`'s
7
+ * `name`) are outside the contract, so a NUL rode through to Postgres (SQLSTATE
8
+ * 22021) and surfaced as Better Auth's OWN 500 — a response `app.onError` never
9
+ * sees, so the app-level 22021 backstop cannot reach `/auth/*`. Refusing it
10
+ * here, before the mount, is the only complete place.
11
+ *
12
+ * The malformed/empty-JSON half is defence in depth and a wire-shape
13
+ * normalizer: on the pinned Better Auth (better-call ≥ 1.3.7) a JSON parse
14
+ * error already answers 400 (`BAD_REQUEST`), not a 500 — but with better-call's
15
+ * own error code, not this API's. Answering `invalid_json` here keeps the auth
16
+ * surface's parse errors in the same envelope as every other route, and guards
17
+ * a future dependency change that reverts to a 500.
18
+ *
19
+ * A body under a JSON content-type must parse and carry no NUL anywhere;
20
+ * non-JSON content types pass untouched (the OAuth token endpoint is
21
+ * form-encoded), as do bodyless requests. The body is read from a clone — the
22
+ * mount consumes the original.
23
+ */
24
+ export declare function authBodyGuard(): MiddlewareHandler;
25
+ //# sourceMappingURL=auth-body.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-body.d.ts","sourceRoot":"","sources":["../../src/middleware/auth-body.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAO9C;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,aAAa,IAAI,iBAAiB,CA4BjD"}