@kindgi/api 0.0.0-bootstrap.0 → 0.1.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 (505) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +216 -1
  3. package/dist/adapter-binding.d.ts +177 -0
  4. package/dist/adapter-binding.d.ts.map +1 -0
  5. package/dist/adapter-binding.js +12 -0
  6. package/dist/adapter-binding.js.map +1 -0
  7. package/dist/agent-binding.d.ts +207 -0
  8. package/dist/agent-binding.d.ts.map +1 -0
  9. package/dist/agent-binding.js +4 -0
  10. package/dist/agent-binding.js.map +1 -0
  11. package/dist/app.d.ts +770 -0
  12. package/dist/app.d.ts.map +1 -0
  13. package/dist/app.js +396 -0
  14. package/dist/app.js.map +1 -0
  15. package/dist/capability-binding.d.ts +76 -0
  16. package/dist/capability-binding.d.ts.map +1 -0
  17. package/dist/capability-binding.js +4 -0
  18. package/dist/capability-binding.js.map +1 -0
  19. package/dist/cost-binding.d.ts +175 -0
  20. package/dist/cost-binding.d.ts.map +1 -0
  21. package/dist/cost-binding.js +13 -0
  22. package/dist/cost-binding.js.map +1 -0
  23. package/dist/deployment-binding.d.ts +201 -0
  24. package/dist/deployment-binding.d.ts.map +1 -0
  25. package/dist/deployment-binding.js +4 -0
  26. package/dist/deployment-binding.js.map +1 -0
  27. package/dist/env-binding.d.ts +132 -0
  28. package/dist/env-binding.d.ts.map +1 -0
  29. package/dist/env-binding.js +4 -0
  30. package/dist/env-binding.js.map +1 -0
  31. package/dist/errors.d.ts +37 -0
  32. package/dist/errors.d.ts.map +1 -0
  33. package/dist/errors.js +264 -0
  34. package/dist/errors.js.map +1 -0
  35. package/dist/eval-run-binding.d.ts +196 -0
  36. package/dist/eval-run-binding.d.ts.map +1 -0
  37. package/dist/eval-run-binding.js +16 -0
  38. package/dist/eval-run-binding.js.map +1 -0
  39. package/dist/eval-run-dispatcher.d.ts +131 -0
  40. package/dist/eval-run-dispatcher.d.ts.map +1 -0
  41. package/dist/eval-run-dispatcher.js +368 -0
  42. package/dist/eval-run-dispatcher.js.map +1 -0
  43. package/dist/eval-suite-binding.d.ts +227 -0
  44. package/dist/eval-suite-binding.d.ts.map +1 -0
  45. package/dist/eval-suite-binding.js +24 -0
  46. package/dist/eval-suite-binding.js.map +1 -0
  47. package/dist/event-bus-binding.d.ts +107 -0
  48. package/dist/event-bus-binding.d.ts.map +1 -0
  49. package/dist/event-bus-binding.js +5 -0
  50. package/dist/event-bus-binding.js.map +1 -0
  51. package/dist/flow-binding.d.ts +194 -0
  52. package/dist/flow-binding.d.ts.map +1 -0
  53. package/dist/flow-binding.js +4 -0
  54. package/dist/flow-binding.js.map +1 -0
  55. package/dist/guardrail-binding.d.ts +138 -0
  56. package/dist/guardrail-binding.d.ts.map +1 -0
  57. package/dist/guardrail-binding.js +4 -0
  58. package/dist/guardrail-binding.js.map +1 -0
  59. package/dist/handler-binding.d.ts +126 -0
  60. package/dist/handler-binding.d.ts.map +1 -0
  61. package/dist/handler-binding.js +4 -0
  62. package/dist/handler-binding.js.map +1 -0
  63. package/dist/hitl-binding.d.ts +115 -0
  64. package/dist/hitl-binding.d.ts.map +1 -0
  65. package/dist/hitl-binding.js +4 -0
  66. package/dist/hitl-binding.js.map +1 -0
  67. package/dist/identity-directory-binding.d.ts +116 -0
  68. package/dist/identity-directory-binding.d.ts.map +1 -0
  69. package/dist/identity-directory-binding.js +4 -0
  70. package/dist/identity-directory-binding.js.map +1 -0
  71. package/dist/identity-provider-binding.d.ts +184 -0
  72. package/dist/identity-provider-binding.d.ts.map +1 -0
  73. package/dist/identity-provider-binding.js +4 -0
  74. package/dist/identity-provider-binding.js.map +1 -0
  75. package/dist/image-registry-binding.d.ts +165 -0
  76. package/dist/image-registry-binding.d.ts.map +1 -0
  77. package/dist/image-registry-binding.js +4 -0
  78. package/dist/image-registry-binding.js.map +1 -0
  79. package/dist/index.d.ts +72 -0
  80. package/dist/index.d.ts.map +1 -0
  81. package/dist/index.js +26 -0
  82. package/dist/index.js.map +1 -0
  83. package/dist/key-management-binding.d.ts +101 -0
  84. package/dist/key-management-binding.d.ts.map +1 -0
  85. package/dist/key-management-binding.js +4 -0
  86. package/dist/key-management-binding.js.map +1 -0
  87. package/dist/mcp-endpoint-binding.d.ts +312 -0
  88. package/dist/mcp-endpoint-binding.d.ts.map +1 -0
  89. package/dist/mcp-endpoint-binding.js +12 -0
  90. package/dist/mcp-endpoint-binding.js.map +1 -0
  91. package/dist/memory-binding.d.ts +209 -0
  92. package/dist/memory-binding.d.ts.map +1 -0
  93. package/dist/memory-binding.js +4 -0
  94. package/dist/memory-binding.js.map +1 -0
  95. package/dist/middleware/auth.d.ts +168 -0
  96. package/dist/middleware/auth.d.ts.map +1 -0
  97. package/dist/middleware/auth.js +247 -0
  98. package/dist/middleware/auth.js.map +1 -0
  99. package/dist/middleware/authorize.d.ts +26 -0
  100. package/dist/middleware/authorize.d.ts.map +1 -0
  101. package/dist/middleware/authorize.js +65 -0
  102. package/dist/middleware/authorize.js.map +1 -0
  103. package/dist/middleware/error-mapper.d.ts +13 -0
  104. package/dist/middleware/error-mapper.d.ts.map +1 -0
  105. package/dist/middleware/error-mapper.js +32 -0
  106. package/dist/middleware/error-mapper.js.map +1 -0
  107. package/dist/middleware/idempotency.d.ts +43 -0
  108. package/dist/middleware/idempotency.d.ts.map +1 -0
  109. package/dist/middleware/idempotency.js +118 -0
  110. package/dist/middleware/idempotency.js.map +1 -0
  111. package/dist/middleware/principal.d.ts +4 -0
  112. package/dist/middleware/principal.d.ts.map +1 -0
  113. package/dist/middleware/principal.js +42 -0
  114. package/dist/middleware/principal.js.map +1 -0
  115. package/dist/middleware/public-run-routes.d.ts +16 -0
  116. package/dist/middleware/public-run-routes.d.ts.map +1 -0
  117. package/dist/middleware/public-run-routes.js +43 -0
  118. package/dist/middleware/public-run-routes.js.map +1 -0
  119. package/dist/middleware/request-id.d.ts +14 -0
  120. package/dist/middleware/request-id.d.ts.map +1 -0
  121. package/dist/middleware/request-id.js +24 -0
  122. package/dist/middleware/request-id.js.map +1 -0
  123. package/dist/middleware/sigv4-verify.d.ts +64 -0
  124. package/dist/middleware/sigv4-verify.d.ts.map +1 -0
  125. package/dist/middleware/sigv4-verify.js +286 -0
  126. package/dist/middleware/sigv4-verify.js.map +1 -0
  127. package/dist/middleware/sigv4.d.ts +25 -0
  128. package/dist/middleware/sigv4.d.ts.map +1 -0
  129. package/dist/middleware/sigv4.js +120 -0
  130. package/dist/middleware/sigv4.js.map +1 -0
  131. package/dist/openapi/generate.d.ts +15 -0
  132. package/dist/openapi/generate.d.ts.map +1 -0
  133. package/dist/openapi/generate.js +241 -0
  134. package/dist/openapi/generate.js.map +1 -0
  135. package/dist/openapi/operations.d.ts +70 -0
  136. package/dist/openapi/operations.d.ts.map +1 -0
  137. package/dist/openapi/operations.js +5051 -0
  138. package/dist/openapi/operations.js.map +1 -0
  139. package/dist/openapi/schemas.d.ts +590 -0
  140. package/dist/openapi/schemas.d.ts.map +1 -0
  141. package/dist/openapi/schemas.js +5820 -0
  142. package/dist/openapi/schemas.js.map +1 -0
  143. package/dist/provenance-binding.d.ts +116 -0
  144. package/dist/provenance-binding.d.ts.map +1 -0
  145. package/dist/provenance-binding.js +31 -0
  146. package/dist/provenance-binding.js.map +1 -0
  147. package/dist/provider-binding.d.ts +174 -0
  148. package/dist/provider-binding.d.ts.map +1 -0
  149. package/dist/provider-binding.js +4 -0
  150. package/dist/provider-binding.js.map +1 -0
  151. package/dist/public-run-token.d.ts +97 -0
  152. package/dist/public-run-token.d.ts.map +1 -0
  153. package/dist/public-run-token.js +167 -0
  154. package/dist/public-run-token.js.map +1 -0
  155. package/dist/retention-binding.d.ts +69 -0
  156. package/dist/retention-binding.d.ts.map +1 -0
  157. package/dist/retention-binding.js +4 -0
  158. package/dist/retention-binding.js.map +1 -0
  159. package/dist/reviewer-binding.d.ts +84 -0
  160. package/dist/reviewer-binding.d.ts.map +1 -0
  161. package/dist/reviewer-binding.js +4 -0
  162. package/dist/reviewer-binding.js.map +1 -0
  163. package/dist/rotation-status-store.d.ts +96 -0
  164. package/dist/rotation-status-store.d.ts.map +1 -0
  165. package/dist/rotation-status-store.js +106 -0
  166. package/dist/rotation-status-store.js.map +1 -0
  167. package/dist/routes/adapters.d.ts +29 -0
  168. package/dist/routes/adapters.d.ts.map +1 -0
  169. package/dist/routes/adapters.js +230 -0
  170. package/dist/routes/adapters.js.map +1 -0
  171. package/dist/routes/agents.d.ts +17 -0
  172. package/dist/routes/agents.d.ts.map +1 -0
  173. package/dist/routes/agents.js +342 -0
  174. package/dist/routes/agents.js.map +1 -0
  175. package/dist/routes/approvals.d.ts +37 -0
  176. package/dist/routes/approvals.d.ts.map +1 -0
  177. package/dist/routes/approvals.js +551 -0
  178. package/dist/routes/approvals.js.map +1 -0
  179. package/dist/routes/artifacts.d.ts +25 -0
  180. package/dist/routes/artifacts.d.ts.map +1 -0
  181. package/dist/routes/artifacts.js +265 -0
  182. package/dist/routes/artifacts.js.map +1 -0
  183. package/dist/routes/audit.d.ts +6 -0
  184. package/dist/routes/audit.d.ts.map +1 -0
  185. package/dist/routes/audit.js +162 -0
  186. package/dist/routes/audit.js.map +1 -0
  187. package/dist/routes/auth.d.ts +47 -0
  188. package/dist/routes/auth.d.ts.map +1 -0
  189. package/dist/routes/auth.js +630 -0
  190. package/dist/routes/auth.js.map +1 -0
  191. package/dist/routes/capabilities.d.ts +14 -0
  192. package/dist/routes/capabilities.d.ts.map +1 -0
  193. package/dist/routes/capabilities.js +62 -0
  194. package/dist/routes/capabilities.js.map +1 -0
  195. package/dist/routes/compliance.d.ts +37 -0
  196. package/dist/routes/compliance.d.ts.map +1 -0
  197. package/dist/routes/compliance.js +321 -0
  198. package/dist/routes/compliance.js.map +1 -0
  199. package/dist/routes/conversations.d.ts +13 -0
  200. package/dist/routes/conversations.d.ts.map +1 -0
  201. package/dist/routes/conversations.js +295 -0
  202. package/dist/routes/conversations.js.map +1 -0
  203. package/dist/routes/cost.d.ts +24 -0
  204. package/dist/routes/cost.d.ts.map +1 -0
  205. package/dist/routes/cost.js +243 -0
  206. package/dist/routes/cost.js.map +1 -0
  207. package/dist/routes/deployments.d.ts +122 -0
  208. package/dist/routes/deployments.d.ts.map +1 -0
  209. package/dist/routes/deployments.js +1036 -0
  210. package/dist/routes/deployments.js.map +1 -0
  211. package/dist/routes/env.d.ts +62 -0
  212. package/dist/routes/env.d.ts.map +1 -0
  213. package/dist/routes/env.js +311 -0
  214. package/dist/routes/env.js.map +1 -0
  215. package/dist/routes/eval-runs.d.ts +28 -0
  216. package/dist/routes/eval-runs.d.ts.map +1 -0
  217. package/dist/routes/eval-runs.js +479 -0
  218. package/dist/routes/eval-runs.js.map +1 -0
  219. package/dist/routes/eval-suites.d.ts +24 -0
  220. package/dist/routes/eval-suites.d.ts.map +1 -0
  221. package/dist/routes/eval-suites.js +381 -0
  222. package/dist/routes/eval-suites.js.map +1 -0
  223. package/dist/routes/event-triggers.d.ts +12 -0
  224. package/dist/routes/event-triggers.d.ts.map +1 -0
  225. package/dist/routes/event-triggers.js +218 -0
  226. package/dist/routes/event-triggers.js.map +1 -0
  227. package/dist/routes/flows.d.ts +23 -0
  228. package/dist/routes/flows.d.ts.map +1 -0
  229. package/dist/routes/flows.js +344 -0
  230. package/dist/routes/flows.js.map +1 -0
  231. package/dist/routes/guardrails.d.ts +33 -0
  232. package/dist/routes/guardrails.d.ts.map +1 -0
  233. package/dist/routes/guardrails.js +236 -0
  234. package/dist/routes/guardrails.js.map +1 -0
  235. package/dist/routes/identity.d.ts +39 -0
  236. package/dist/routes/identity.d.ts.map +1 -0
  237. package/dist/routes/identity.js +138 -0
  238. package/dist/routes/identity.js.map +1 -0
  239. package/dist/routes/mcp.d.ts +23 -0
  240. package/dist/routes/mcp.d.ts.map +1 -0
  241. package/dist/routes/mcp.js +727 -0
  242. package/dist/routes/mcp.js.map +1 -0
  243. package/dist/routes/memory.d.ts +16 -0
  244. package/dist/routes/memory.d.ts.map +1 -0
  245. package/dist/routes/memory.js +353 -0
  246. package/dist/routes/memory.js.map +1 -0
  247. package/dist/routes/observations.d.ts +19 -0
  248. package/dist/routes/observations.d.ts.map +1 -0
  249. package/dist/routes/observations.js +135 -0
  250. package/dist/routes/observations.js.map +1 -0
  251. package/dist/routes/orgs.d.ts +24 -0
  252. package/dist/routes/orgs.d.ts.map +1 -0
  253. package/dist/routes/orgs.js +208 -0
  254. package/dist/routes/orgs.js.map +1 -0
  255. package/dist/routes/pagination.d.ts +18 -0
  256. package/dist/routes/pagination.d.ts.map +1 -0
  257. package/dist/routes/pagination.js +35 -0
  258. package/dist/routes/pagination.js.map +1 -0
  259. package/dist/routes/policies.d.ts +23 -0
  260. package/dist/routes/policies.d.ts.map +1 -0
  261. package/dist/routes/policies.js +314 -0
  262. package/dist/routes/policies.js.map +1 -0
  263. package/dist/routes/projects.d.ts +45 -0
  264. package/dist/routes/projects.d.ts.map +1 -0
  265. package/dist/routes/projects.js +485 -0
  266. package/dist/routes/projects.js.map +1 -0
  267. package/dist/routes/proposals.d.ts +24 -0
  268. package/dist/routes/proposals.d.ts.map +1 -0
  269. package/dist/routes/proposals.js +581 -0
  270. package/dist/routes/proposals.js.map +1 -0
  271. package/dist/routes/provenance.d.ts +34 -0
  272. package/dist/routes/provenance.d.ts.map +1 -0
  273. package/dist/routes/provenance.js +274 -0
  274. package/dist/routes/provenance.js.map +1 -0
  275. package/dist/routes/providers.d.ts +32 -0
  276. package/dist/routes/providers.d.ts.map +1 -0
  277. package/dist/routes/providers.js +490 -0
  278. package/dist/routes/providers.js.map +1 -0
  279. package/dist/routes/public-run-tokens.d.ts +17 -0
  280. package/dist/routes/public-run-tokens.d.ts.map +1 -0
  281. package/dist/routes/public-run-tokens.js +69 -0
  282. package/dist/routes/public-run-tokens.js.map +1 -0
  283. package/dist/routes/retention.d.ts +19 -0
  284. package/dist/routes/retention.d.ts.map +1 -0
  285. package/dist/routes/retention.js +152 -0
  286. package/dist/routes/retention.js.map +1 -0
  287. package/dist/routes/reviewers.d.ts +5 -0
  288. package/dist/routes/reviewers.d.ts.map +1 -0
  289. package/dist/routes/reviewers.js +161 -0
  290. package/dist/routes/reviewers.js.map +1 -0
  291. package/dist/routes/runs.d.ts +34 -0
  292. package/dist/routes/runs.d.ts.map +1 -0
  293. package/dist/routes/runs.js +773 -0
  294. package/dist/routes/runs.js.map +1 -0
  295. package/dist/routes/s3.d.ts +31 -0
  296. package/dist/routes/s3.d.ts.map +1 -0
  297. package/dist/routes/s3.js +433 -0
  298. package/dist/routes/s3.js.map +1 -0
  299. package/dist/routes/schedules.d.ts +20 -0
  300. package/dist/routes/schedules.d.ts.map +1 -0
  301. package/dist/routes/schedules.js +234 -0
  302. package/dist/routes/schedules.js.map +1 -0
  303. package/dist/routes/scope-params.d.ts +57 -0
  304. package/dist/routes/scope-params.d.ts.map +1 -0
  305. package/dist/routes/scope-params.js +105 -0
  306. package/dist/routes/scope-params.js.map +1 -0
  307. package/dist/routes/secret-ref.d.ts +20 -0
  308. package/dist/routes/secret-ref.d.ts.map +1 -0
  309. package/dist/routes/secret-ref.js +42 -0
  310. package/dist/routes/secret-ref.js.map +1 -0
  311. package/dist/routes/secrets.d.ts +53 -0
  312. package/dist/routes/secrets.d.ts.map +1 -0
  313. package/dist/routes/secrets.js +715 -0
  314. package/dist/routes/secrets.js.map +1 -0
  315. package/dist/routes/signing-keys.d.ts +23 -0
  316. package/dist/routes/signing-keys.d.ts.map +1 -0
  317. package/dist/routes/signing-keys.js +212 -0
  318. package/dist/routes/signing-keys.js.map +1 -0
  319. package/dist/routes/sse.d.ts +58 -0
  320. package/dist/routes/sse.d.ts.map +1 -0
  321. package/dist/routes/sse.js +92 -0
  322. package/dist/routes/sse.js.map +1 -0
  323. package/dist/routes/teams.d.ts +30 -0
  324. package/dist/routes/teams.d.ts.map +1 -0
  325. package/dist/routes/teams.js +443 -0
  326. package/dist/routes/teams.js.map +1 -0
  327. package/dist/routes/tenant.d.ts +57 -0
  328. package/dist/routes/tenant.d.ts.map +1 -0
  329. package/dist/routes/tenant.js +352 -0
  330. package/dist/routes/tenant.js.map +1 -0
  331. package/dist/routes/tokens.d.ts +14 -0
  332. package/dist/routes/tokens.d.ts.map +1 -0
  333. package/dist/routes/tokens.js +231 -0
  334. package/dist/routes/tokens.js.map +1 -0
  335. package/dist/routes/tools.d.ts +33 -0
  336. package/dist/routes/tools.d.ts.map +1 -0
  337. package/dist/routes/tools.js +380 -0
  338. package/dist/routes/tools.js.map +1 -0
  339. package/dist/routes/webhook-endpoints.d.ts +10 -0
  340. package/dist/routes/webhook-endpoints.d.ts.map +1 -0
  341. package/dist/routes/webhook-endpoints.js +407 -0
  342. package/dist/routes/webhook-endpoints.js.map +1 -0
  343. package/dist/routes/webhooks.d.ts +21 -0
  344. package/dist/routes/webhooks.d.ts.map +1 -0
  345. package/dist/routes/webhooks.js +228 -0
  346. package/dist/routes/webhooks.js.map +1 -0
  347. package/dist/s3-credential-binding.d.ts +54 -0
  348. package/dist/s3-credential-binding.d.ts.map +1 -0
  349. package/dist/s3-credential-binding.js +4 -0
  350. package/dist/s3-credential-binding.js.map +1 -0
  351. package/dist/secrets-binding.d.ts +281 -0
  352. package/dist/secrets-binding.d.ts.map +1 -0
  353. package/dist/secrets-binding.js +10 -0
  354. package/dist/secrets-binding.js.map +1 -0
  355. package/dist/secrets-provider-binding.d.ts +164 -0
  356. package/dist/secrets-provider-binding.d.ts.map +1 -0
  357. package/dist/secrets-provider-binding.js +4 -0
  358. package/dist/secrets-provider-binding.js.map +1 -0
  359. package/dist/session-store-binding.d.ts +148 -0
  360. package/dist/session-store-binding.d.ts.map +1 -0
  361. package/dist/session-store-binding.js +4 -0
  362. package/dist/session-store-binding.js.map +1 -0
  363. package/dist/signing-key-binding.d.ts +210 -0
  364. package/dist/signing-key-binding.d.ts.map +1 -0
  365. package/dist/signing-key-binding.js +4 -0
  366. package/dist/signing-key-binding.js.map +1 -0
  367. package/dist/state-store-binding.d.ts +53 -0
  368. package/dist/state-store-binding.d.ts.map +1 -0
  369. package/dist/state-store-binding.js +38 -0
  370. package/dist/state-store-binding.js.map +1 -0
  371. package/dist/supervisor-binding.d.ts +526 -0
  372. package/dist/supervisor-binding.d.ts.map +1 -0
  373. package/dist/supervisor-binding.js +4 -0
  374. package/dist/supervisor-binding.js.map +1 -0
  375. package/dist/tenant-host-access.d.ts +41 -0
  376. package/dist/tenant-host-access.d.ts.map +1 -0
  377. package/dist/tenant-host-access.js +42 -0
  378. package/dist/tenant-host-access.js.map +1 -0
  379. package/dist/token-admin.d.ts +99 -0
  380. package/dist/token-admin.d.ts.map +1 -0
  381. package/dist/token-admin.js +4 -0
  382. package/dist/token-admin.js.map +1 -0
  383. package/dist/tool-binding.d.ts +247 -0
  384. package/dist/tool-binding.d.ts.map +1 -0
  385. package/dist/tool-binding.js +4 -0
  386. package/dist/tool-binding.js.map +1 -0
  387. package/dist/trigger-binding.d.ts +13 -0
  388. package/dist/trigger-binding.d.ts.map +1 -0
  389. package/dist/trigger-binding.js +4 -0
  390. package/dist/trigger-binding.js.map +1 -0
  391. package/dist/types.d.ts +71 -0
  392. package/dist/types.d.ts.map +1 -0
  393. package/dist/types.js +4 -0
  394. package/dist/types.js.map +1 -0
  395. package/dist/webhook-endpoint-binding.d.ts +230 -0
  396. package/dist/webhook-endpoint-binding.d.ts.map +1 -0
  397. package/dist/webhook-endpoint-binding.js +12 -0
  398. package/dist/webhook-endpoint-binding.js.map +1 -0
  399. package/dist/xml.d.ts +79 -0
  400. package/dist/xml.d.ts.map +1 -0
  401. package/dist/xml.js +115 -0
  402. package/dist/xml.js.map +1 -0
  403. package/openapi.json +29659 -0
  404. package/package.json +76 -4
  405. package/scripts/emit-openapi.mjs +44 -0
  406. package/src/adapter-binding.ts +204 -0
  407. package/src/agent-binding.ts +231 -0
  408. package/src/app.ts +1285 -0
  409. package/src/capability-binding.ts +83 -0
  410. package/src/cost-binding.ts +213 -0
  411. package/src/deployment-binding.ts +225 -0
  412. package/src/env-binding.ts +140 -0
  413. package/src/errors.ts +291 -0
  414. package/src/eval-run-binding.ts +209 -0
  415. package/src/eval-run-dispatcher.ts +497 -0
  416. package/src/eval-suite-binding.ts +257 -0
  417. package/src/event-bus-binding.ts +127 -0
  418. package/src/flow-binding.ts +213 -0
  419. package/src/guardrail-binding.ts +151 -0
  420. package/src/handler-binding.ts +132 -0
  421. package/src/hitl-binding.ts +172 -0
  422. package/src/identity-directory-binding.ts +128 -0
  423. package/src/identity-provider-binding.ts +203 -0
  424. package/src/image-registry-binding.ts +193 -0
  425. package/src/index.ts +606 -0
  426. package/src/key-management-binding.ts +91 -0
  427. package/src/mcp-endpoint-binding.ts +311 -0
  428. package/src/memory-binding.ts +239 -0
  429. package/src/middleware/auth.ts +437 -0
  430. package/src/middleware/authorize.ts +125 -0
  431. package/src/middleware/error-mapper.ts +37 -0
  432. package/src/middleware/idempotency.ts +160 -0
  433. package/src/middleware/principal.ts +64 -0
  434. package/src/middleware/public-run-routes.ts +50 -0
  435. package/src/middleware/request-id.ts +28 -0
  436. package/src/middleware/sigv4-verify.ts +374 -0
  437. package/src/middleware/sigv4.ts +165 -0
  438. package/src/openapi/generate.ts +307 -0
  439. package/src/openapi/operations.ts +5445 -0
  440. package/src/openapi/schemas.ts +6363 -0
  441. package/src/provenance-binding.ts +169 -0
  442. package/src/provider-binding.ts +196 -0
  443. package/src/public-run-token.ts +263 -0
  444. package/src/retention-binding.ts +78 -0
  445. package/src/reviewer-binding.ts +99 -0
  446. package/src/rotation-status-store.ts +209 -0
  447. package/src/routes/adapters.ts +319 -0
  448. package/src/routes/agents.ts +424 -0
  449. package/src/routes/approvals.ts +759 -0
  450. package/src/routes/artifacts.ts +317 -0
  451. package/src/routes/audit.ts +219 -0
  452. package/src/routes/auth.ts +806 -0
  453. package/src/routes/capabilities.ts +79 -0
  454. package/src/routes/compliance.ts +482 -0
  455. package/src/routes/conversations.ts +369 -0
  456. package/src/routes/cost.ts +327 -0
  457. package/src/routes/deployments.ts +1493 -0
  458. package/src/routes/env.ts +429 -0
  459. package/src/routes/eval-runs.ts +631 -0
  460. package/src/routes/eval-suites.ts +490 -0
  461. package/src/routes/event-triggers.ts +283 -0
  462. package/src/routes/flows.ts +423 -0
  463. package/src/routes/guardrails.ts +320 -0
  464. package/src/routes/identity.ts +203 -0
  465. package/src/routes/mcp.ts +940 -0
  466. package/src/routes/memory.ts +430 -0
  467. package/src/routes/observations.ts +175 -0
  468. package/src/routes/orgs.ts +273 -0
  469. package/src/routes/pagination.ts +51 -0
  470. package/src/routes/policies.ts +413 -0
  471. package/src/routes/projects.ts +634 -0
  472. package/src/routes/proposals.ts +719 -0
  473. package/src/routes/provenance.ts +406 -0
  474. package/src/routes/providers.ts +624 -0
  475. package/src/routes/public-run-tokens.ts +104 -0
  476. package/src/routes/retention.ts +193 -0
  477. package/src/routes/reviewers.ts +209 -0
  478. package/src/routes/runs.ts +981 -0
  479. package/src/routes/s3.ts +519 -0
  480. package/src/routes/schedules.ts +300 -0
  481. package/src/routes/scope-params.ts +133 -0
  482. package/src/routes/secret-ref.ts +52 -0
  483. package/src/routes/secrets.ts +975 -0
  484. package/src/routes/signing-keys.ts +259 -0
  485. package/src/routes/sse.ts +148 -0
  486. package/src/routes/teams.ts +584 -0
  487. package/src/routes/tenant.ts +530 -0
  488. package/src/routes/tokens.ts +285 -0
  489. package/src/routes/tools.ts +491 -0
  490. package/src/routes/webhook-endpoints.ts +534 -0
  491. package/src/routes/webhooks.ts +296 -0
  492. package/src/s3-credential-binding.ts +58 -0
  493. package/src/secrets-binding.ts +308 -0
  494. package/src/secrets-provider-binding.ts +167 -0
  495. package/src/session-store-binding.ts +163 -0
  496. package/src/signing-key-binding.ts +235 -0
  497. package/src/state-store-binding.ts +84 -0
  498. package/src/supervisor-binding.ts +554 -0
  499. package/src/tenant-host-access.ts +62 -0
  500. package/src/token-admin.ts +104 -0
  501. package/src/tool-binding.ts +274 -0
  502. package/src/trigger-binding.ts +38 -0
  503. package/src/types.ts +74 -0
  504. package/src/webhook-endpoint-binding.ts +246 -0
  505. package/src/xml.ts +196 -0
@@ -0,0 +1,320 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // Copyright (C) 2026 Kindgi Inc.
3
+
4
+ import { Hono } from 'hono';
5
+
6
+ import { type Principal, ref, tuplesForCreate } from '@kindgi/authz';
7
+ import { type Guardrail, validateGuardrailSpec } from '@kindgi/guardrails';
8
+ import type { Cursor, GuardrailId, ProjectId, TenantId, UserId } from '@kindgi/types';
9
+
10
+ import { statusFor, toWireError } from '../errors.js';
11
+ import type { GuardrailRegistryBinding } from '../guardrail-binding.js';
12
+ import type { Authorizer } from '../middleware/authorize.js';
13
+ import type { AppEnv } from '../types.js';
14
+ import { clampLimit } from './pagination.js';
15
+ import { parseScopeParams } from './scope-params.js';
16
+
17
+ /**
18
+ * Guardrails resource routes, paired with tools.
19
+ *
20
+ * Registry storage is caller-plugged via `GuardrailRegistryBinding`.
21
+ * The API package does not own persistence — deployments wire a durable
22
+ * store; tests can wrap an in-memory one.
23
+ *
24
+ * Registration is metadata-only: the body is a full `Guardrail` shape
25
+ * (id + kind + check-id + action). The actual `check` implementation
26
+ * must already be registered with the runtime — deployments publish
27
+ * guardrails whose check code is already bundled server-side. Check
28
+ * code is not uploaded over this surface.
29
+ */
30
+ /**
31
+ * Optional side-effect callback fired after a successful write
32
+ * (register, unregister) to a guardrail. Lets an in-process
33
+ * runtime cache (e.g. a per-tenant guardrail cache) invalidate
34
+ * its per-tenant snapshot so the next agent turn picks up the
35
+ * new/dropped guardrail without a process restart. Mirror of
36
+ * `ToolWriteHook` / `ProviderWriteHook`.
37
+ */
38
+ export type GuardrailWriteHook = (params: {
39
+ readonly tenantId: TenantId;
40
+ readonly guardrailId: GuardrailId;
41
+ readonly kind: 'register' | 'unregister';
42
+ }) => void | Promise<void>;
43
+
44
+ export function guardrailsRouter(
45
+ binding: GuardrailRegistryBinding,
46
+ authorizer?: Authorizer,
47
+ onWrite?: GuardrailWriteHook,
48
+ ): Hono<AppEnv> {
49
+ const r = new Hono<AppEnv>();
50
+
51
+ // Authorization (PEP) — mirrors agents. Cascade via `guardrail#parent@project`
52
+ // written in-tx by register; direct check via `ref('guardrail', id)`.
53
+ if (authorizer !== undefined) {
54
+ r.use('/', async (c, next) => {
55
+ if (c.req.method !== 'POST') return next();
56
+ const tenantId = c.get('tenantId') as TenantId;
57
+ const mw = authorizer.authorize('admin', async () => {
58
+ try {
59
+ const body = await c.req.json();
60
+ const pid =
61
+ body !== null && typeof body === 'object'
62
+ ? (body as Record<string, unknown>).projectId
63
+ : undefined;
64
+ if (typeof pid === 'string' && pid.length > 0) return ref('project', pid);
65
+ } catch {
66
+ // POST handler validates + returns 400
67
+ }
68
+ return ref('tenant', tenantId as unknown as string);
69
+ });
70
+ return mw(c, next);
71
+ });
72
+ r.use('/', async (c, next) => {
73
+ if (c.req.method !== 'GET') return next();
74
+ // A project filter needs read on that project. Parse it as the
75
+ // handler does (`?scopeKind=project&scopeId=`).
76
+ const s = parseScopeParams((n) => c.req.query(n), {
77
+ tenantId: c.get('tenantId') as TenantId,
78
+ });
79
+ if (s.kind !== 'ok' || s.scope?.kind !== 'project') return next();
80
+ const scopeProjectId = s.scope.projectId as unknown as string;
81
+ const mw = authorizer.authorize('read', () => ref('project', scopeProjectId));
82
+ return mw(c, next);
83
+ });
84
+ r.use('/:guardrailId/*', async (c, next) => {
85
+ const action = c.req.method === 'GET' ? 'read' : 'admin';
86
+ const guardrailId = c.req.param('guardrailId') ?? '';
87
+ const mw = authorizer.authorize(action, () => ref('guardrail', guardrailId));
88
+ return mw(c, next);
89
+ });
90
+ r.use('/:guardrailId', async (c, next) => {
91
+ if (c.req.method !== 'GET') return next();
92
+ const guardrailId = c.req.param('guardrailId') ?? '';
93
+ const mw = authorizer.authorize('read', () => ref('guardrail', guardrailId));
94
+ return mw(c, next);
95
+ });
96
+ }
97
+
98
+ // ---------- GET / (list, cursor-paginated) ----------
99
+ r.get('/', async (c) => {
100
+ const requestId = c.get('requestId');
101
+ const tenantId = c.get('tenantId') as TenantId;
102
+ const limit = clampLimit(c.req.query('limit'));
103
+
104
+ const cursorRaw = c.req.query('cursor');
105
+ const nameRaw = c.req.query('name');
106
+
107
+ const scopeParsed = parseScopeParams(c.req.query(), { tenantId });
108
+ if (scopeParsed.kind === 'err') {
109
+ c.status(statusFor('scope-invalid') as never);
110
+ return c.json(
111
+ toWireError({ code: 'scope-invalid', message: scopeParsed.message }, requestId),
112
+ );
113
+ }
114
+
115
+ const page = await binding.list({
116
+ tenantId,
117
+ limit,
118
+ ...(cursorRaw !== undefined && cursorRaw.length > 0 && { cursor: cursorRaw as Cursor }),
119
+ ...(nameRaw !== undefined && nameRaw.length > 0 && { nameFilter: nameRaw }),
120
+ ...(scopeParsed.scope !== undefined && { scope: scopeParsed.scope }),
121
+ ...(scopeParsed.inherit !== undefined && { inherit: scopeParsed.inherit }),
122
+ });
123
+ return c.json({
124
+ data: page.data.map(serializeGuardrail),
125
+ hasMore: page.nextCursor !== undefined,
126
+ ...(page.nextCursor !== undefined && { nextCursor: page.nextCursor as unknown as string }),
127
+ });
128
+ });
129
+
130
+ // ---------- GET /:guardrailId ----------
131
+ r.get('/:guardrailId', async (c) => {
132
+ const requestId = c.get('requestId');
133
+ const tenantId = c.get('tenantId') as TenantId;
134
+ const guardrailId = c.req.param('guardrailId') as GuardrailId;
135
+
136
+ const guardrail = await binding.get({ tenantId, guardrailId });
137
+ if (guardrail === null) {
138
+ c.status(statusFor('guardrail-not-found') as never);
139
+ return c.json(
140
+ toWireError(
141
+ {
142
+ code: 'guardrail-not-found',
143
+ message: `No guardrail registered with id "${guardrailId as unknown as string}"`,
144
+ guardrailId: guardrailId as unknown as string,
145
+ },
146
+ requestId,
147
+ ),
148
+ );
149
+ }
150
+ return c.json(serializeGuardrail(guardrail));
151
+ });
152
+
153
+ // ---------- POST / (register) ----------
154
+ r.post('/', async (c) => {
155
+ const requestId = c.get('requestId');
156
+ const tenantId = c.get('tenantId') as TenantId;
157
+
158
+ let body: unknown;
159
+ try {
160
+ body = await c.req.json();
161
+ } catch {
162
+ c.status(statusFor('bad-input') as never);
163
+ return c.json(
164
+ toWireError({ code: 'bad-input', message: 'Request body must be valid JSON' }, requestId),
165
+ );
166
+ }
167
+ if (body === null || typeof body !== 'object') {
168
+ c.status(statusFor('bad-input') as never);
169
+ return c.json(
170
+ toWireError({ code: 'bad-input', message: 'Request body must be an object' }, requestId),
171
+ );
172
+ }
173
+
174
+ // `projectId` is REQUIRED on the POST body.
175
+ // Missing / empty / non-string → 400 bad-input. Stripped from the
176
+ // spec before `validateGuardrailSpec` because the spec schema
177
+ // rejects unknown top-level keys (the guardrail definition itself
178
+ // is project-agnostic — the caller controls what project the
179
+ // guardrail lands in).
180
+ const bodyObj = body as Record<string, unknown>;
181
+ const projectIdRaw = bodyObj.projectId;
182
+ if (typeof projectIdRaw !== 'string' || projectIdRaw.length === 0) {
183
+ c.status(statusFor('bad-input') as never);
184
+ return c.json(
185
+ toWireError({ code: 'bad-input', message: '`projectId` is required' }, requestId),
186
+ );
187
+ }
188
+ const projectId = projectIdRaw as ProjectId;
189
+ const { projectId: _pid, ...bodyWithoutProjectId } = bodyObj;
190
+
191
+ const validated = validateGuardrailSpec(bodyWithoutProjectId);
192
+ if (validated.kind === 'err') {
193
+ c.status(statusFor('validation-failed') as never);
194
+ return c.json(
195
+ toWireError(
196
+ {
197
+ code: 'validation-failed',
198
+ message: validated.error.message,
199
+ issues: validated.error.issues as unknown as Record<string, unknown>[],
200
+ },
201
+ requestId,
202
+ ),
203
+ );
204
+ }
205
+
206
+ const principal = c.get('principal') as Principal | undefined;
207
+ const creatorUserId =
208
+ principal?.actor.kind === 'user' ? (principal.actor.id as UserId) : undefined;
209
+ const outcome = await binding.register({
210
+ tenantId,
211
+ projectId,
212
+ guardrail: validated.value,
213
+ enqueueTuples: (guardrailId) =>
214
+ tuplesForCreate(
215
+ { kind: 'guardrail', id: guardrailId as GuardrailId, tenantId, projectId },
216
+ creatorUserId,
217
+ ),
218
+ });
219
+ if (outcome.kind === 'already-registered') {
220
+ c.status(statusFor('guardrail-already-registered') as never);
221
+ return c.json(
222
+ toWireError(
223
+ {
224
+ code: 'guardrail-already-registered',
225
+ message: `Guardrail "${outcome.guardrailId as unknown as string}" is already registered`,
226
+ guardrailId: outcome.guardrailId as unknown as string,
227
+ },
228
+ requestId,
229
+ ),
230
+ );
231
+ }
232
+ if (outcome.kind === 'project-not-found') {
233
+ // Caller supplied a `projectId` that does not resolve within
234
+ // this tenant. Distinct signal from `already-registered` so the
235
+ // client can prompt for a valid project rather than assume the
236
+ // id was already used. `bad-input` is the closest existing
237
+ // error code — the shape (400 + code) is stable; the caller
238
+ // learns from the message which field was invalid.
239
+ c.status(statusFor('bad-input') as never);
240
+ return c.json(
241
+ toWireError(
242
+ {
243
+ code: 'bad-input',
244
+ message: `\`projectId\` "${outcome.projectId as unknown as string}" does not resolve to a project in this tenant`,
245
+ },
246
+ requestId,
247
+ ),
248
+ );
249
+ }
250
+ if (onWrite !== undefined) {
251
+ try {
252
+ await onWrite({
253
+ tenantId,
254
+ guardrailId: outcome.guardrailId,
255
+ kind: 'register',
256
+ });
257
+ } catch {
258
+ // Post-write hooks are advisory (cache invalidation etc.).
259
+ // A hook failure does NOT roll back the register — the row
260
+ // is durably stored; a stale in-memory cache will self-heal
261
+ // on the next boot.
262
+ }
263
+ }
264
+ c.status(201);
265
+ return c.json({
266
+ guardrailId: outcome.guardrailId as unknown as string,
267
+ });
268
+ });
269
+
270
+ // ---------- POST /:guardrailId/unregister ----------
271
+ r.post('/:guardrailId/unregister', async (c) => {
272
+ const requestId = c.get('requestId');
273
+ const tenantId = c.get('tenantId') as TenantId;
274
+ const guardrailId = c.req.param('guardrailId') as GuardrailId;
275
+
276
+ const outcome = await binding.unregister({ tenantId, guardrailId });
277
+ if (!outcome.unregistered) {
278
+ c.status(statusFor('guardrail-not-found') as never);
279
+ return c.json(
280
+ toWireError(
281
+ {
282
+ code: 'guardrail-not-found',
283
+ message: `No guardrail "${guardrailId as unknown as string}" to unregister`,
284
+ guardrailId: guardrailId as unknown as string,
285
+ },
286
+ requestId,
287
+ ),
288
+ );
289
+ }
290
+ if (onWrite !== undefined) {
291
+ try {
292
+ await onWrite({ tenantId, guardrailId, kind: 'unregister' });
293
+ } catch {
294
+ // See register path — hooks are advisory.
295
+ }
296
+ }
297
+ return c.json({
298
+ guardrailId: guardrailId as unknown as string,
299
+ unregistered: true,
300
+ });
301
+ });
302
+
303
+ return r;
304
+ }
305
+
306
+ function serializeGuardrail(i: Guardrail): Record<string, unknown> {
307
+ return {
308
+ id: i.id as unknown as string,
309
+ ...(i.name !== undefined && { name: i.name }),
310
+ ...(i.description !== undefined && { description: i.description }),
311
+ kind: i.kind,
312
+ ...(i.check !== undefined && { check: i.check }),
313
+ ...(i.config !== undefined && { config: i.config }),
314
+ action: i.action,
315
+ ...(i.severity !== undefined && { severity: i.severity }),
316
+ ...(i.scope !== undefined && { scope: i.scope }),
317
+ ...(i.budget !== undefined && { budget: i.budget }),
318
+ ...(i.judgeCapabilities !== undefined && { judgeCapabilities: i.judgeCapabilities }),
319
+ };
320
+ }
@@ -0,0 +1,203 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // Copyright (C) 2026 Kindgi Inc.
3
+
4
+ import { Hono } from 'hono';
5
+
6
+ import type { Cursor, SessionId, TenantId, UserId } from '@kindgi/types';
7
+
8
+ import { statusFor, toWireError } from '../errors.js';
9
+ import type {
10
+ IdentityDirectoryBinding,
11
+ SessionSummary,
12
+ UserRecord,
13
+ } from '../identity-directory-binding.js';
14
+ import type { SessionStoreBinding } from '../session-store-binding.js';
15
+ import type { AppEnv } from '../types.js';
16
+ import { clampLimit } from './pagination.js';
17
+
18
+ /**
19
+ * Identity routes — the canonical caller-identity surface.
20
+ *
21
+ * Hosts the user directory (`/users/*`) and the single canonical
22
+ * `whoami` endpoint, so clients have exactly one whoami endpoint to
23
+ * consume.
24
+ *
25
+ * Five routes:
26
+ * - `GET /v1/identity/whoami` (self — always mounted)
27
+ * - `GET /v1/identity/users` (cursor-paginated list)
28
+ * - `GET /v1/identity/users/:userId` (get)
29
+ * - `GET /v1/identity/users/:userId/sessions` (active sessions)
30
+ * - `POST /v1/identity/users/:userId/revoke-sessions` (admin op)
31
+ *
32
+ * `directory` is optional: deployments without an `IdentityDirectoryBinding`
33
+ * still get `whoami` (returning the minimal `{ tenantId, scopes, ... }` shape
34
+ * plus `sessionId`/`providerId` if the middleware attached them). When the
35
+ * directory is wired, `whoami` enriches the response with the fuller
36
+ * `UserRecord` and the four `/users/*` routes mount too.
37
+ */
38
+ export interface IdentityRouterOptions {
39
+ /**
40
+ * Optional. When present, the `/users/*` routes mount and `whoami`
41
+ * enriches with `UserRecord`. When absent, only `whoami` mounts.
42
+ */
43
+ readonly directory?: IdentityDirectoryBinding;
44
+ /**
45
+ * Optional. When present, `GET /v1/identity/whoami` also returns
46
+ * `expiresAt` for callers on a session token. Absent for
47
+ * deployments that don't wire an OAuth surface.
48
+ */
49
+ readonly sessionStore?: SessionStoreBinding;
50
+ }
51
+
52
+ export function identityRouter(options: IdentityRouterOptions = {}): Hono<AppEnv> {
53
+ const { directory, sessionStore } = options;
54
+ const r = new Hono<AppEnv>();
55
+
56
+ // ---------- GET / whoami ----------
57
+ // Mounted first so `/v1/identity/whoami` resolves here rather than
58
+ // being captured by the `:userId` param on subsequent routes.
59
+ r.get('/whoami', async (c) => {
60
+ const tenantId = c.get('tenantId') as TenantId;
61
+ const sessionId = c.get('sessionId') as SessionId | undefined;
62
+ const userId = c.get('userId') as UserId | undefined;
63
+ const providerId = c.get('providerId') as string | undefined;
64
+ const scopes = (c.get('scopes') as readonly string[] | undefined) ?? [];
65
+ const reviewerRole = c.get('reviewerRole') as string | undefined;
66
+
67
+ const body: Record<string, unknown> = { tenantId };
68
+ if (sessionId !== undefined) body.sessionId = sessionId;
69
+ if (providerId !== undefined) body.providerId = providerId;
70
+ body.scopes = scopes;
71
+ if (reviewerRole !== undefined) body.reviewerRole = reviewerRole;
72
+
73
+ if (userId !== undefined) {
74
+ body.userId = userId;
75
+ if (directory !== undefined) {
76
+ const user = await directory.getUser({ tenantId, userId });
77
+ if (user !== null) body.user = serializeUser(user);
78
+ }
79
+ }
80
+
81
+ if (sessionId !== undefined && sessionStore !== undefined) {
82
+ const session = await sessionStore.get({ tenantId, sessionId });
83
+ if (session !== null) body.expiresAt = session.expiresAt;
84
+ }
85
+ return c.json(body);
86
+ });
87
+
88
+ if (directory === undefined) {
89
+ // Deployments without a directory binding get whoami only.
90
+ // `/users/*` routes fall through to the app-level 404.
91
+ return r;
92
+ }
93
+
94
+ // ---------- GET /users (list) ----------
95
+ r.get('/users', async (c) => {
96
+ const tenantId = c.get('tenantId') as TenantId;
97
+ const limit = clampLimit(c.req.query('limit'));
98
+ const cursorRaw = c.req.query('cursor');
99
+ const queryRaw = c.req.query('query');
100
+
101
+ const page = await directory.listUsers({
102
+ tenantId,
103
+ limit,
104
+ ...(cursorRaw !== undefined && cursorRaw.length > 0 && { cursor: cursorRaw as Cursor }),
105
+ ...(queryRaw !== undefined && queryRaw.length > 0 && { query: queryRaw }),
106
+ });
107
+ return c.json({
108
+ data: page.data.map(serializeUser),
109
+ hasMore: page.nextCursor !== undefined,
110
+ ...(page.nextCursor !== undefined && { nextCursor: page.nextCursor as unknown as string }),
111
+ });
112
+ });
113
+
114
+ // ---------- GET /users/:userId (get) ----------
115
+ r.get('/users/:userId', async (c) => {
116
+ const requestId = c.get('requestId');
117
+ const tenantId = c.get('tenantId') as TenantId;
118
+ const userId = c.req.param('userId') as UserId;
119
+
120
+ const user = await directory.getUser({ tenantId, userId });
121
+ if (user === null) {
122
+ c.status(statusFor('identity-user-not-found') as never);
123
+ return c.json(
124
+ toWireError(
125
+ {
126
+ code: 'identity-user-not-found',
127
+ message: `No user with id "${userId as unknown as string}" under this tenant`,
128
+ userId: userId as unknown as string,
129
+ },
130
+ requestId,
131
+ ),
132
+ );
133
+ }
134
+ return c.json(serializeUser(user));
135
+ });
136
+
137
+ // ---------- GET /users/:userId/sessions (list active sessions) ----------
138
+ r.get('/users/:userId/sessions', async (c) => {
139
+ const tenantId = c.get('tenantId') as TenantId;
140
+ const userId = c.req.param('userId') as UserId;
141
+
142
+ const page = await directory.listSessions({ tenantId, userId });
143
+ return c.json({
144
+ data: page.data.map(serializeSession),
145
+ hasMore: page.nextCursor !== undefined,
146
+ ...(page.nextCursor !== undefined && { nextCursor: page.nextCursor as unknown as string }),
147
+ });
148
+ });
149
+
150
+ // ---------- POST /users/:userId/revoke-sessions (admin) ----------
151
+ r.post('/users/:userId/revoke-sessions', async (c) => {
152
+ const requestId = c.get('requestId');
153
+ const tenantId = c.get('tenantId') as TenantId;
154
+ const userId = c.req.param('userId') as UserId;
155
+
156
+ let outcome: Awaited<ReturnType<IdentityDirectoryBinding['revokeAllSessions']>>;
157
+ try {
158
+ outcome = await directory.revokeAllSessions({ tenantId, userId });
159
+ } catch (err) {
160
+ c.status(statusFor('identity-revoke-failed') as never);
161
+ return c.json(
162
+ toWireError(
163
+ {
164
+ code: 'identity-revoke-failed',
165
+ message: err instanceof Error ? err.message : 'session revocation failed',
166
+ userId: userId as unknown as string,
167
+ },
168
+ requestId,
169
+ ),
170
+ );
171
+ }
172
+ return c.json({
173
+ userId: outcome.userId as unknown as string,
174
+ revokedCount: outcome.revokedCount,
175
+ });
176
+ });
177
+
178
+ return r;
179
+ }
180
+
181
+ function serializeUser(u: UserRecord): Record<string, unknown> {
182
+ return {
183
+ userId: u.userId as unknown as string,
184
+ tenantId: u.tenantId as unknown as string,
185
+ ...(u.primaryEmail !== undefined && { primaryEmail: u.primaryEmail }),
186
+ ...(u.displayName !== undefined && { displayName: u.displayName }),
187
+ createdAt: u.createdAt as unknown as string,
188
+ ...(u.lastActiveAt !== undefined && { lastActiveAt: u.lastActiveAt as unknown as string }),
189
+ ...(u.metadata !== undefined && { metadata: u.metadata }),
190
+ };
191
+ }
192
+
193
+ function serializeSession(s: SessionSummary): Record<string, unknown> {
194
+ return {
195
+ sessionId: s.sessionId,
196
+ userId: s.userId as unknown as string,
197
+ providerId: s.providerId,
198
+ createdAt: s.createdAt as unknown as string,
199
+ expiresAt: s.expiresAt as unknown as string,
200
+ scopes: s.scopes,
201
+ ...(s.revokedAt !== undefined && { revokedAt: s.revokedAt as unknown as string }),
202
+ };
203
+ }