@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,584 @@
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 } from '@kindgi/authz';
7
+ import type { TenantHierarchyBinding } from '@kindgi/platform';
8
+ import type {
9
+ Team,
10
+ TeamBinding,
11
+ TeamMembership,
12
+ TeamMembershipBinding,
13
+ TeamPatch,
14
+ TeamRole,
15
+ TeamSpec,
16
+ } from '@kindgi/platform';
17
+ import type { Cursor, OrgId, TeamId, TenantId, UserId } from '@kindgi/types';
18
+
19
+ import { statusFor, toWireError } from '../errors.js';
20
+ import type { Authorizer } from '../middleware/authorize.js';
21
+ import type { AppEnv } from '../types.js';
22
+ import { clampLimit } from './pagination.js';
23
+
24
+ /**
25
+ * Teams resource routes — part of the multi-tenant hierarchy.
26
+ *
27
+ * Nine endpoints on `/v1/teams`:
28
+ * - `GET /` — cursor-paginated list;
29
+ * `?limit=` / `?cursor=` / `?orgId=` /
30
+ * `?nameContains=`.
31
+ * - `POST /` — create; body `{ name, slug,
32
+ * description?, orgId? }`; 201 `{ id }`.
33
+ * - `GET /:teamId` — get; 200 or 404 `team-not-found`.
34
+ * - `PATCH /:teamId` — partial update; 204 or 404.
35
+ * - `DELETE /:teamId` — 204 idempotent.
36
+ * - `GET /:teamId/memberships` — list; cursor-paginated.
37
+ * - `POST /:teamId/memberships` — add member; body `{ userId, role }`;
38
+ * 201. Idempotent — adding an existing
39
+ * member with a differing role is a
40
+ * no-op per the binding contract.
41
+ * - `DELETE /:teamId/memberships/:userId`
42
+ * — 204 idempotent.
43
+ * - `PATCH /:teamId/memberships/:userId`
44
+ * — updateRole via `{ role }`; 204 or
45
+ * 404 `team-membership-not-found`.
46
+ */
47
+ export function teamsRouter(
48
+ binding: TeamBinding,
49
+ membershipBinding: TeamMembershipBinding,
50
+ tenantHierarchy: TenantHierarchyBinding,
51
+ authorizer?: Authorizer,
52
+ ): Hono<AppEnv> {
53
+ const r = new Hono<AppEnv>();
54
+
55
+ // ---------- Authorization middleware ----------
56
+ // Full PEP surface:
57
+ // POST / → admin on tenant
58
+ // GET /:teamId → read on team
59
+ // PATCH /:teamId, DELETE /:teamId → admin on team
60
+ // * /:teamId/memberships → GET: read; else admin
61
+ // * /:teamId/memberships/:userId → same
62
+ // GET / → list-filter by can_read
63
+ //
64
+ // Note: POST / checks `admin on tenant` even when the body carries an
65
+ // orgId — a strictly stronger gate than `admin on org:$spec.orgId`
66
+ // (tenant admins can do anything an org admin can).
67
+ if (authorizer !== undefined) {
68
+ r.use('/', async (c, next) => {
69
+ if (c.req.method !== 'POST') return next();
70
+ const mw = authorizer.authorize('admin', (ctx) =>
71
+ ref('tenant', ctx.get('tenantId') as unknown as string),
72
+ );
73
+ return mw(c, next);
74
+ });
75
+ r.use('/:teamId', async (c, next) => {
76
+ const method = c.req.method;
77
+ if (method !== 'GET' && method !== 'PATCH' && method !== 'DELETE') return next();
78
+ const teamId = c.req.param('teamId');
79
+ const action = method === 'GET' ? 'read' : 'admin';
80
+ const mw = authorizer.authorize(action, () => ref('team', teamId));
81
+ return mw(c, next);
82
+ });
83
+ r.use('/:teamId/memberships', async (c, next) => {
84
+ const teamId = c.req.param('teamId');
85
+ const action = c.req.method === 'GET' ? 'read' : 'admin';
86
+ const mw = authorizer.authorize(action, () => ref('team', teamId));
87
+ return mw(c, next);
88
+ });
89
+ r.use('/:teamId/memberships/:userId', async (c, next) => {
90
+ const teamId = c.req.param('teamId');
91
+ const action = c.req.method === 'GET' ? 'read' : 'admin';
92
+ const mw = authorizer.authorize(action, () => ref('team', teamId));
93
+ return mw(c, next);
94
+ });
95
+ }
96
+
97
+ // ---------- GET / ----------
98
+ r.get('/', async (c) => {
99
+ const tenantId = c.get('tenantId') as TenantId;
100
+ const limit = clampLimit(c.req.query('limit'));
101
+ const cursorRaw = c.req.query('cursor');
102
+ const orgIdRaw = c.req.query('orgId');
103
+ const nameContainsRaw = c.req.query('nameContains');
104
+ const page = await binding.list(tenantId, {
105
+ limit,
106
+ ...(cursorRaw !== undefined && cursorRaw.length > 0 && { cursor: cursorRaw as Cursor }),
107
+ ...(orgIdRaw !== undefined && orgIdRaw.length > 0 && { orgId: orgIdRaw as OrgId }),
108
+ ...(nameContainsRaw !== undefined &&
109
+ nameContainsRaw.length > 0 && { nameContains: nameContainsRaw }),
110
+ });
111
+ // Authorization list-filter — strip teams the caller can't read.
112
+ const visible =
113
+ authorizer !== undefined
114
+ ? await authorizer.filterByCan(c, 'read', page.items, (t) =>
115
+ ref('team', t.id as unknown as string),
116
+ )
117
+ : [...page.items];
118
+ return c.json({
119
+ data: visible.map(serializeTeam),
120
+ hasMore: page.nextCursor !== undefined,
121
+ ...(page.nextCursor !== undefined && { nextCursor: page.nextCursor as unknown as string }),
122
+ });
123
+ });
124
+
125
+ // ---------- POST / ----------
126
+ r.post('/', async (c) => {
127
+ const requestId = c.get('requestId');
128
+ const tenantId = c.get('tenantId') as TenantId;
129
+
130
+ let body: unknown;
131
+ try {
132
+ body = await c.req.json();
133
+ } catch {
134
+ c.status(statusFor('bad-input') as never);
135
+ return c.json(
136
+ toWireError({ code: 'bad-input', message: 'Request body must be valid JSON' }, requestId),
137
+ );
138
+ }
139
+ if (body === null || typeof body !== 'object') {
140
+ c.status(statusFor('bad-input') as never);
141
+ return c.json(
142
+ toWireError({ code: 'bad-input', message: 'Request body must be an object' }, requestId),
143
+ );
144
+ }
145
+ const b = body as Record<string, unknown>;
146
+ if (typeof b.name !== 'string' || b.name.length === 0) {
147
+ c.status(statusFor('bad-input') as never);
148
+ return c.json(
149
+ toWireError(
150
+ { code: 'bad-input', message: '`name` is required and must be a non-empty string' },
151
+ requestId,
152
+ ),
153
+ );
154
+ }
155
+ if (typeof b.slug !== 'string' || b.slug.length === 0) {
156
+ c.status(statusFor('bad-input') as never);
157
+ return c.json(
158
+ toWireError(
159
+ { code: 'bad-input', message: '`slug` is required and must be a non-empty string' },
160
+ requestId,
161
+ ),
162
+ );
163
+ }
164
+ if (b.description !== undefined && typeof b.description !== 'string') {
165
+ c.status(statusFor('bad-input') as never);
166
+ return c.json(
167
+ toWireError(
168
+ { code: 'bad-input', message: '`description` must be a string when present' },
169
+ requestId,
170
+ ),
171
+ );
172
+ }
173
+ if (b.orgId !== undefined && typeof b.orgId !== 'string') {
174
+ c.status(statusFor('bad-input') as never);
175
+ return c.json(
176
+ toWireError(
177
+ { code: 'bad-input', message: '`orgId` must be a string when present' },
178
+ requestId,
179
+ ),
180
+ );
181
+ }
182
+ const spec: TeamSpec = {
183
+ name: b.name,
184
+ slug: b.slug,
185
+ ...(b.description !== undefined && { description: b.description as string }),
186
+ ...(b.orgId !== undefined && { orgId: b.orgId as unknown as OrgId }),
187
+ };
188
+ if (authorizer !== undefined) {
189
+ const principal = c.get('principal') as Principal | undefined;
190
+ const creatorUserId =
191
+ principal?.actor.kind === 'user'
192
+ ? (principal.actor.id as UserId)
193
+ : ('00000000-0000-0000-0000-000000000000' as UserId);
194
+ const result = await tenantHierarchy.createTeam({ tenantId, creatorUserId, spec });
195
+ if (result.kind === 'err') {
196
+ const code =
197
+ result.error.code === 'slug-conflict' ? 'slug-conflict' : 'internal-server-error';
198
+ c.status(statusFor(code) as never);
199
+ return c.json(toWireError({ code, message: result.error.message }, requestId));
200
+ }
201
+ c.status(201);
202
+ return c.json({ id: result.value.teamId as unknown as string });
203
+ }
204
+ const id = await binding.create(tenantId, spec);
205
+ c.status(201);
206
+ return c.json({ id: id as unknown as string });
207
+ });
208
+
209
+ // ---------- GET /:teamId/memberships ----------
210
+ // Mount BEFORE /:teamId so the `memberships` segment is not consumed by
211
+ // the `:teamId` param on the parent route table.
212
+ r.get('/:teamId/memberships', async (c) => {
213
+ const requestId = c.get('requestId');
214
+ const tenantId = c.get('tenantId') as TenantId;
215
+ const teamId = c.req.param('teamId') as TeamId;
216
+
217
+ // Preliminary get flips unknown teamId to a 404 so an empty list from
218
+ // the membership binding is unambiguous.
219
+ const team = await binding.get(tenantId, teamId);
220
+ if (team === undefined) {
221
+ c.status(statusFor('team-not-found') as never);
222
+ return c.json(
223
+ toWireError(
224
+ {
225
+ code: 'team-not-found',
226
+ message: `No team with id "${teamId as unknown as string}"`,
227
+ teamId: teamId as unknown as string,
228
+ },
229
+ requestId,
230
+ ),
231
+ );
232
+ }
233
+ const limit = clampLimit(c.req.query('limit'));
234
+ const cursorRaw = c.req.query('cursor');
235
+ const page = await membershipBinding.list(tenantId, teamId, {
236
+ limit,
237
+ ...(cursorRaw !== undefined && cursorRaw.length > 0 && { cursor: cursorRaw as Cursor }),
238
+ });
239
+ return c.json({
240
+ data: page.items.map(serializeTeamMembership),
241
+ hasMore: page.nextCursor !== undefined,
242
+ ...(page.nextCursor !== undefined && { nextCursor: page.nextCursor as unknown as string }),
243
+ });
244
+ });
245
+
246
+ // ---------- POST /:teamId/memberships ----------
247
+ r.post('/:teamId/memberships', async (c) => {
248
+ const requestId = c.get('requestId');
249
+ const tenantId = c.get('tenantId') as TenantId;
250
+ const teamId = c.req.param('teamId') as TeamId;
251
+
252
+ const team = await binding.get(tenantId, teamId);
253
+ if (team === undefined) {
254
+ c.status(statusFor('team-not-found') as never);
255
+ return c.json(
256
+ toWireError(
257
+ {
258
+ code: 'team-not-found',
259
+ message: `No team with id "${teamId as unknown as string}"`,
260
+ teamId: teamId as unknown as string,
261
+ },
262
+ requestId,
263
+ ),
264
+ );
265
+ }
266
+ let body: unknown;
267
+ try {
268
+ body = await c.req.json();
269
+ } catch {
270
+ c.status(statusFor('bad-input') as never);
271
+ return c.json(
272
+ toWireError({ code: 'bad-input', message: 'Request body must be valid JSON' }, requestId),
273
+ );
274
+ }
275
+ if (body === null || typeof body !== 'object') {
276
+ c.status(statusFor('bad-input') as never);
277
+ return c.json(
278
+ toWireError({ code: 'bad-input', message: 'Request body must be an object' }, requestId),
279
+ );
280
+ }
281
+ const b = body as Record<string, unknown>;
282
+ if (typeof b.userId !== 'string' || b.userId.length === 0) {
283
+ c.status(statusFor('bad-input') as never);
284
+ return c.json(
285
+ toWireError(
286
+ { code: 'bad-input', message: '`userId` is required and must be a non-empty string' },
287
+ requestId,
288
+ ),
289
+ );
290
+ }
291
+ if (!isTeamRole(b.role)) {
292
+ c.status(statusFor('bad-input') as never);
293
+ return c.json(
294
+ toWireError(
295
+ {
296
+ code: 'bad-input',
297
+ message: '`role` must be one of: member, admin',
298
+ },
299
+ requestId,
300
+ ),
301
+ );
302
+ }
303
+ try {
304
+ if (authorizer !== undefined) {
305
+ const res = await tenantHierarchy.addTeamMember({
306
+ tenantId,
307
+ teamId,
308
+ userId: b.userId as unknown as UserId,
309
+ role: b.role as TeamRole,
310
+ });
311
+ if (res.kind === 'err') throw new Error(res.error.message);
312
+ } else {
313
+ await membershipBinding.add(tenantId, {
314
+ teamId,
315
+ userId: b.userId as unknown as UserId,
316
+ role: b.role,
317
+ });
318
+ }
319
+ } catch (cause) {
320
+ const message = cause instanceof Error ? cause.message : String(cause);
321
+ if (message.startsWith('team-not-found')) {
322
+ // Racy — team was deleted between the preliminary get and the add.
323
+ c.status(statusFor('team-not-found') as never);
324
+ return c.json(
325
+ toWireError(
326
+ {
327
+ code: 'team-not-found',
328
+ message: `No team with id "${teamId as unknown as string}"`,
329
+ teamId: teamId as unknown as string,
330
+ },
331
+ requestId,
332
+ ),
333
+ );
334
+ }
335
+ throw cause;
336
+ }
337
+ c.status(201);
338
+ return c.json({
339
+ teamId: teamId as unknown as string,
340
+ userId: b.userId,
341
+ role: b.role,
342
+ });
343
+ });
344
+
345
+ // ---------- DELETE /:teamId/memberships/:userId ----------
346
+ r.delete('/:teamId/memberships/:userId', async (c) => {
347
+ const tenantId = c.get('tenantId') as TenantId;
348
+ const teamId = c.req.param('teamId') as TeamId;
349
+ const userId = c.req.param('userId') as UserId;
350
+ await membershipBinding.remove(tenantId, teamId, userId);
351
+ c.status(204);
352
+ return c.body(null);
353
+ });
354
+
355
+ // ---------- PATCH /:teamId/memberships/:userId ----------
356
+ r.patch('/:teamId/memberships/:userId', async (c) => {
357
+ const requestId = c.get('requestId');
358
+ const tenantId = c.get('tenantId') as TenantId;
359
+ const teamId = c.req.param('teamId') as TeamId;
360
+ const userId = c.req.param('userId') as UserId;
361
+
362
+ let body: unknown;
363
+ try {
364
+ body = await c.req.json();
365
+ } catch {
366
+ c.status(statusFor('bad-input') as never);
367
+ return c.json(
368
+ toWireError({ code: 'bad-input', message: 'Request body must be valid JSON' }, requestId),
369
+ );
370
+ }
371
+ if (body === null || typeof body !== 'object') {
372
+ c.status(statusFor('bad-input') as never);
373
+ return c.json(
374
+ toWireError({ code: 'bad-input', message: 'Request body must be an object' }, requestId),
375
+ );
376
+ }
377
+ const b = body as Record<string, unknown>;
378
+ if (!isTeamRole(b.role)) {
379
+ c.status(statusFor('bad-input') as never);
380
+ return c.json(
381
+ toWireError(
382
+ {
383
+ code: 'bad-input',
384
+ message: '`role` must be one of: member, admin',
385
+ },
386
+ requestId,
387
+ ),
388
+ );
389
+ }
390
+ try {
391
+ await membershipBinding.updateRole(tenantId, teamId, userId, b.role);
392
+ } catch (cause) {
393
+ const message = cause instanceof Error ? cause.message : String(cause);
394
+ if (message.startsWith('team-membership-not-found')) {
395
+ c.status(statusFor('team-membership-not-found') as never);
396
+ return c.json(
397
+ toWireError(
398
+ {
399
+ code: 'team-membership-not-found',
400
+ message: `No membership for team "${teamId as unknown as string}" + user "${userId as unknown as string}"`,
401
+ teamId: teamId as unknown as string,
402
+ userId: userId as unknown as string,
403
+ },
404
+ requestId,
405
+ ),
406
+ );
407
+ }
408
+ if (message.startsWith('team-not-found')) {
409
+ c.status(statusFor('team-not-found') as never);
410
+ return c.json(
411
+ toWireError(
412
+ {
413
+ code: 'team-not-found',
414
+ message: `No team with id "${teamId as unknown as string}"`,
415
+ teamId: teamId as unknown as string,
416
+ },
417
+ requestId,
418
+ ),
419
+ );
420
+ }
421
+ throw cause;
422
+ }
423
+ c.status(204);
424
+ return c.body(null);
425
+ });
426
+
427
+ // ---------- GET /:teamId ----------
428
+ r.get('/:teamId', async (c) => {
429
+ const requestId = c.get('requestId');
430
+ const tenantId = c.get('tenantId') as TenantId;
431
+ const teamId = c.req.param('teamId') as TeamId;
432
+
433
+ const team = await binding.get(tenantId, teamId);
434
+ if (team === undefined) {
435
+ c.status(statusFor('team-not-found') as never);
436
+ return c.json(
437
+ toWireError(
438
+ {
439
+ code: 'team-not-found',
440
+ message: `No team with id "${teamId as unknown as string}"`,
441
+ teamId: teamId as unknown as string,
442
+ },
443
+ requestId,
444
+ ),
445
+ );
446
+ }
447
+ return c.json(serializeTeam(team));
448
+ });
449
+
450
+ // ---------- PATCH /:teamId ----------
451
+ r.patch('/:teamId', async (c) => {
452
+ const requestId = c.get('requestId');
453
+ const tenantId = c.get('tenantId') as TenantId;
454
+ const teamId = c.req.param('teamId') as TeamId;
455
+
456
+ let body: unknown;
457
+ try {
458
+ body = await c.req.json();
459
+ } catch {
460
+ c.status(statusFor('bad-input') as never);
461
+ return c.json(
462
+ toWireError({ code: 'bad-input', message: 'Request body must be valid JSON' }, requestId),
463
+ );
464
+ }
465
+ if (body === null || typeof body !== 'object') {
466
+ c.status(statusFor('bad-input') as never);
467
+ return c.json(
468
+ toWireError({ code: 'bad-input', message: 'Request body must be an object' }, requestId),
469
+ );
470
+ }
471
+ const b = body as Record<string, unknown>;
472
+ const shaped: { -readonly [K in keyof TeamPatch]: TeamPatch[K] } = {};
473
+ if (b.name !== undefined) {
474
+ if (typeof b.name !== 'string') {
475
+ c.status(statusFor('bad-input') as never);
476
+ return c.json(
477
+ toWireError(
478
+ { code: 'bad-input', message: '`name` must be a string when present' },
479
+ requestId,
480
+ ),
481
+ );
482
+ }
483
+ shaped.name = b.name;
484
+ }
485
+ if (b.slug !== undefined) {
486
+ if (typeof b.slug !== 'string') {
487
+ c.status(statusFor('bad-input') as never);
488
+ return c.json(
489
+ toWireError(
490
+ { code: 'bad-input', message: '`slug` must be a string when present' },
491
+ requestId,
492
+ ),
493
+ );
494
+ }
495
+ shaped.slug = b.slug;
496
+ }
497
+ if (b.description !== undefined) {
498
+ if (typeof b.description !== 'string') {
499
+ c.status(statusFor('bad-input') as never);
500
+ return c.json(
501
+ toWireError(
502
+ { code: 'bad-input', message: '`description` must be a string when present' },
503
+ requestId,
504
+ ),
505
+ );
506
+ }
507
+ shaped.description = b.description;
508
+ }
509
+ if ('orgId' in b) {
510
+ const raw = b.orgId;
511
+ if (raw === null) {
512
+ shaped.orgId = null;
513
+ } else if (typeof raw === 'string') {
514
+ shaped.orgId = raw as unknown as OrgId;
515
+ } else {
516
+ c.status(statusFor('bad-input') as never);
517
+ return c.json(
518
+ toWireError(
519
+ { code: 'bad-input', message: '`orgId` must be a string or null when present' },
520
+ requestId,
521
+ ),
522
+ );
523
+ }
524
+ }
525
+ try {
526
+ await binding.update(tenantId, teamId, shaped);
527
+ } catch (cause) {
528
+ const message = cause instanceof Error ? cause.message : String(cause);
529
+ if (message.startsWith('team-not-found')) {
530
+ c.status(statusFor('team-not-found') as never);
531
+ return c.json(
532
+ toWireError(
533
+ {
534
+ code: 'team-not-found',
535
+ message: `No team with id "${teamId as unknown as string}"`,
536
+ teamId: teamId as unknown as string,
537
+ },
538
+ requestId,
539
+ ),
540
+ );
541
+ }
542
+ throw cause;
543
+ }
544
+ c.status(204);
545
+ return c.body(null);
546
+ });
547
+
548
+ // ---------- DELETE /:teamId ----------
549
+ r.delete('/:teamId', async (c) => {
550
+ const tenantId = c.get('tenantId') as TenantId;
551
+ const teamId = c.req.param('teamId') as TeamId;
552
+ await binding.delete(tenantId, teamId);
553
+ c.status(204);
554
+ return c.body(null);
555
+ });
556
+
557
+ return r;
558
+ }
559
+
560
+ function isTeamRole(x: unknown): x is 'member' | 'admin' {
561
+ return x === 'member' || x === 'admin';
562
+ }
563
+
564
+ function serializeTeam(t: Team): Record<string, unknown> {
565
+ return {
566
+ id: t.id as unknown as string,
567
+ tenantId: t.tenantId as unknown as string,
568
+ ...(t.orgId !== undefined && { orgId: t.orgId as unknown as string }),
569
+ name: t.name,
570
+ slug: t.slug,
571
+ ...(t.description !== undefined && { description: t.description }),
572
+ createdAt: t.createdAt as unknown as string,
573
+ updatedAt: t.updatedAt as unknown as string,
574
+ };
575
+ }
576
+
577
+ function serializeTeamMembership(m: TeamMembership): Record<string, unknown> {
578
+ return {
579
+ teamId: m.teamId as unknown as string,
580
+ userId: m.userId as unknown as string,
581
+ role: m.role,
582
+ joinedAt: m.joinedAt as unknown as string,
583
+ };
584
+ }