@kindgi/api 0.0.0-bootstrap.0 → 0.1.1

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 +397 -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 +268 -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 +20 -0
  104. package/dist/middleware/error-mapper.d.ts.map +1 -0
  105. package/dist/middleware/error-mapper.js +34 -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 +5050 -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 +705 -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 +29649 -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 +1286 -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 +295 -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 +40 -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 +5444 -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 +892 -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,491 @@
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 ToolManifest, validateToolManifest } from '@kindgi/tools';
8
+ import type { Cursor, ProjectId, TenantId, ToolId, UserId } from '@kindgi/types';
9
+
10
+ import { statusFor, toWireError } from '../errors.js';
11
+ import type { Authorizer } from '../middleware/authorize.js';
12
+ import type { ToolRegistryBinding } from '../tool-binding.js';
13
+ import type { AppEnv } from '../types.js';
14
+ import { clampLimit } from './pagination.js';
15
+ import { parseScopeParams } from './scope-params.js';
16
+
17
+ /**
18
+ * Tools resource routes.
19
+ *
20
+ * Registry storage is caller-plugged via `ToolRegistryBinding`. The
21
+ * API package does not own persistence — deployments wire a durable
22
+ * store; tests can wrap the in-memory `@kindgi/tools` `ToolRegistry`.
23
+ *
24
+ * Registration is metadata-only: the body is a `ToolManifest` (a
25
+ * `Tool` minus its runtime `handler` closure). The actual handler
26
+ * must already be registered with the runtime — deployments publish
27
+ * tools whose code is already bundled server-side. Handler code is not
28
+ * uploaded over this surface.
29
+ */
30
+ /**
31
+ * Optional side-effect callback fired after a successful write
32
+ * (publish, unregister, reinstate) to a tool version. Lets an
33
+ * in-process runtime cache (e.g. a per-tenant tool cache)
34
+ * invalidate its per-tenant snapshot so the next agent run picks
35
+ * up the new manifest without a process restart.
36
+ */
37
+ export type ToolWriteHook = (params: {
38
+ readonly tenantId: TenantId;
39
+ readonly toolId: ToolId;
40
+ readonly version: string;
41
+ readonly kind: 'publish' | 'unregister' | 'reinstate';
42
+ }) => void | Promise<void>;
43
+
44
+ export function toolsRouter(
45
+ binding: ToolRegistryBinding,
46
+ authorizer?: Authorizer,
47
+ onWrite?: ToolWriteHook,
48
+ ): Hono<AppEnv> {
49
+ const r = new Hono<AppEnv>();
50
+
51
+ // Authorization (PEP) — mirrors agents. Cascade via `tool#parent@project`
52
+ // written in-tx by publish; direct check via `ref('tool', businessId)`.
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('/:toolId/*', async (c, next) => {
85
+ const action = c.req.method === 'GET' ? 'read' : 'admin';
86
+ const toolId = c.req.param('toolId') ?? '';
87
+ const mw = authorizer.authorize(action, () => ref('tool', toolId));
88
+ return mw(c, next);
89
+ });
90
+ r.use('/:toolId', async (c, next) => {
91
+ if (c.req.method !== 'GET') return next();
92
+ const toolId = c.req.param('toolId') ?? '';
93
+ const mw = authorizer.authorize('read', () => ref('tool', toolId));
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(serializeTool),
125
+ hasMore: page.nextCursor !== undefined,
126
+ ...(page.nextCursor !== undefined && { nextCursor: page.nextCursor as unknown as string }),
127
+ });
128
+ });
129
+
130
+ // ---------- GET /:toolId (latest version) ----------
131
+ r.get('/:toolId', async (c) => {
132
+ const requestId = c.get('requestId');
133
+ const tenantId = c.get('tenantId') as TenantId;
134
+ const toolId = c.req.param('toolId') as ToolId;
135
+
136
+ const tool = await binding.get({ tenantId, toolId });
137
+ if (tool === null) {
138
+ // Distinguish 410 gone (identity exists — head row present, no
139
+ // active version) from 404 not-found (never registered). Retirement
140
+ // is derived from the tool having no latest version; the head row is
141
+ // the identity marker.
142
+ const exists = await binding.headExists({ tenantId, toolId });
143
+ if (exists) {
144
+ c.status(statusFor('tool-gone') as never);
145
+ return c.json(
146
+ toWireError(
147
+ {
148
+ code: 'tool-gone',
149
+ message: `Tool "${toolId as unknown as string}" has no active versions; reinstate a tombstoned version or publish a new one`,
150
+ toolId: toolId as unknown as string,
151
+ },
152
+ requestId,
153
+ ),
154
+ );
155
+ }
156
+ c.status(statusFor('tool-not-found') as never);
157
+ return c.json(
158
+ toWireError(
159
+ {
160
+ code: 'tool-not-found',
161
+ message: `No tool registered with id "${toolId as unknown as string}"`,
162
+ toolId: toolId as unknown as string,
163
+ },
164
+ requestId,
165
+ ),
166
+ );
167
+ }
168
+ return c.json(serializeTool(tool));
169
+ });
170
+
171
+ // ---------- GET /:toolId/versions (list versions, cursor-paginated) ----------
172
+ r.get('/:toolId/versions', async (c) => {
173
+ const requestId = c.get('requestId');
174
+ const tenantId = c.get('tenantId') as TenantId;
175
+ const toolId = c.req.param('toolId') as ToolId;
176
+ const limit = clampLimit(c.req.query('limit'));
177
+ const cursorRaw = c.req.query('cursor');
178
+ // `?includeTombstoned=true` opts into surfacing tombstoned versions
179
+ // alongside active ones. Rows carry `unregisteredAt` (ISO string) iff
180
+ // tombstoned. Absent / `false` / any other string → active-only
181
+ // (the default).
182
+ const includeTombstoned = c.req.query('includeTombstoned') === 'true';
183
+
184
+ // Confirm the id exists at all. Retired tools (all versions
185
+ // tombstoned) still have a head row → 200 with a page listing the
186
+ // tombstoned versions. Never-registered ids → 404.
187
+ const exists = await binding.headExists({ tenantId, toolId });
188
+ if (!exists) {
189
+ c.status(statusFor('tool-not-found') as never);
190
+ return c.json(
191
+ toWireError(
192
+ {
193
+ code: 'tool-not-found',
194
+ message: `No tool registered with id "${toolId as unknown as string}"`,
195
+ toolId: toolId as unknown as string,
196
+ },
197
+ requestId,
198
+ ),
199
+ );
200
+ }
201
+
202
+ const page = await binding.listVersions({
203
+ tenantId,
204
+ toolId,
205
+ limit,
206
+ ...(cursorRaw !== undefined && cursorRaw.length > 0 && { cursor: cursorRaw as Cursor }),
207
+ ...(includeTombstoned && { includeTombstoned: true }),
208
+ });
209
+ return c.json({
210
+ data: page.data.map(serializeToolVersionRow),
211
+ hasMore: page.nextCursor !== undefined,
212
+ ...(page.nextCursor !== undefined && { nextCursor: page.nextCursor as unknown as string }),
213
+ });
214
+ });
215
+
216
+ // ---------- GET /:toolId/versions/:version ----------
217
+ r.get('/:toolId/versions/:version', async (c) => {
218
+ const requestId = c.get('requestId');
219
+ const tenantId = c.get('tenantId') as TenantId;
220
+ const toolId = c.req.param('toolId') as ToolId;
221
+ const version = c.req.param('version') as never;
222
+
223
+ const tool = await binding.getVersion({ tenantId, toolId, version });
224
+ if (tool === null) {
225
+ c.status(statusFor('tool-not-found') as never);
226
+ return c.json(
227
+ toWireError(
228
+ {
229
+ code: 'tool-not-found',
230
+ message: `No tool "${toolId as unknown as string}" at version "${version as unknown as string}"`,
231
+ toolId: toolId as unknown as string,
232
+ version: version as unknown as string,
233
+ },
234
+ requestId,
235
+ ),
236
+ );
237
+ }
238
+ return c.json(serializeTool(tool));
239
+ });
240
+
241
+ // ---------- POST / (register) ----------
242
+ r.post('/', async (c) => {
243
+ const requestId = c.get('requestId');
244
+ const tenantId = c.get('tenantId') as TenantId;
245
+
246
+ let body: unknown;
247
+ try {
248
+ body = await c.req.json();
249
+ } catch {
250
+ c.status(statusFor('bad-input') as never);
251
+ return c.json(
252
+ toWireError({ code: 'bad-input', message: 'Request body must be valid JSON' }, requestId),
253
+ );
254
+ }
255
+ if (body === null || typeof body !== 'object') {
256
+ c.status(statusFor('bad-input') as never);
257
+ return c.json(
258
+ toWireError({ code: 'bad-input', message: 'Request body must be an object' }, requestId),
259
+ );
260
+ }
261
+
262
+ // `projectId` is REQUIRED on the POST body.
263
+ // Missing / empty / non-string → 400 bad-input. Absent from the
264
+ // tool-manifest validator on purpose — the caller controls what
265
+ // project the tool lands in; the manifest itself is project-
266
+ // agnostic (validateToolManifest rejects unknown top-level keys).
267
+ const bodyObj = body as Record<string, unknown>;
268
+ const projectIdRaw = bodyObj.projectId;
269
+ if (typeof projectIdRaw !== 'string' || projectIdRaw.length === 0) {
270
+ c.status(statusFor('bad-input') as never);
271
+ return c.json(
272
+ toWireError({ code: 'bad-input', message: '`projectId` is required' }, requestId),
273
+ );
274
+ }
275
+ const projectId = projectIdRaw as ProjectId;
276
+ // Strip `projectId` before validation — the tool manifest itself
277
+ // is project-agnostic. `validateToolManifest` rejects unknown
278
+ // top-level keys via additionalProperties: false.
279
+ const { projectId: _pid, ...bodyWithoutProjectId } = bodyObj;
280
+
281
+ const validated = validateToolManifest(bodyWithoutProjectId);
282
+ if (validated.kind === 'err') {
283
+ const err = validated.error;
284
+ c.status(statusFor('validation-failed') as never);
285
+ const issues =
286
+ err.code === 'invalid-tool-definition'
287
+ ? (err.issues as unknown as Record<string, unknown>[])
288
+ : [{ path: err.code === 'invalid-schema' ? `/${err.where}` : '', message: err.message }];
289
+ return c.json(
290
+ toWireError(
291
+ {
292
+ code: 'validation-failed',
293
+ message: err.message,
294
+ issues,
295
+ },
296
+ requestId,
297
+ ),
298
+ );
299
+ }
300
+
301
+ const principal = c.get('principal') as Principal | undefined;
302
+ const creatorUserId =
303
+ principal?.actor.kind === 'user' ? (principal.actor.id as UserId) : undefined;
304
+ const outcome = await binding.publish({
305
+ tenantId,
306
+ projectId,
307
+ tool: validated.value,
308
+ enqueueTuples: (toolId) =>
309
+ tuplesForCreate({ kind: 'tool', id: toolId as ToolId, tenantId, projectId }, creatorUserId),
310
+ });
311
+ if (outcome.kind === 'already-registered') {
312
+ c.status(statusFor('tool-already-registered') as never);
313
+ return c.json(
314
+ toWireError(
315
+ {
316
+ code: 'tool-already-registered',
317
+ message: `Tool "${outcome.toolId as unknown as string}" version "${outcome.version as unknown as string}" is already registered`,
318
+ toolId: outcome.toolId as unknown as string,
319
+ version: outcome.version as unknown as string,
320
+ },
321
+ requestId,
322
+ ),
323
+ );
324
+ }
325
+ if (outcome.kind === 'project-not-found') {
326
+ // Caller supplied a `projectId` that does not resolve within
327
+ // this tenant. Distinct signal from `already-registered` so the
328
+ // client can prompt for a valid project rather than assume the
329
+ // tool was already registered. `bad-input` is the closest
330
+ // existing error code — the shape (400 + code) is stable; the
331
+ // caller learns from the message which field was invalid.
332
+ c.status(statusFor('bad-input') as never);
333
+ return c.json(
334
+ toWireError(
335
+ {
336
+ code: 'bad-input',
337
+ message: `\`projectId\` "${outcome.projectId as unknown as string}" does not resolve to a project in this tenant`,
338
+ },
339
+ requestId,
340
+ ),
341
+ );
342
+ }
343
+ if (onWrite !== undefined) {
344
+ try {
345
+ await onWrite({
346
+ tenantId,
347
+ toolId: outcome.toolId as ToolId,
348
+ version: outcome.version as unknown as string,
349
+ kind: 'publish',
350
+ });
351
+ } catch {
352
+ // Post-write hooks are advisory (cache invalidation etc.).
353
+ // A hook failure does NOT roll back the publish — the row
354
+ // is durably stored; a stale in-memory cache will self-heal
355
+ // on the next boot.
356
+ }
357
+ }
358
+ c.status(201);
359
+ return c.json({
360
+ toolId: outcome.toolId as unknown as string,
361
+ version: outcome.version as unknown as string,
362
+ });
363
+ });
364
+
365
+ // ---------- POST /:toolId/versions/:version/unregister ----------
366
+ r.post('/:toolId/versions/:version/unregister', async (c) => {
367
+ const requestId = c.get('requestId');
368
+ const tenantId = c.get('tenantId') as TenantId;
369
+ const toolId = c.req.param('toolId') as ToolId;
370
+ const version = c.req.param('version') as never;
371
+
372
+ const outcome = await binding.unregister({ tenantId, toolId, version });
373
+ if (!outcome.unregistered) {
374
+ c.status(statusFor('tool-not-found') as never);
375
+ return c.json(
376
+ toWireError(
377
+ {
378
+ code: 'tool-not-found',
379
+ message: `No tool "${toolId as unknown as string}" at version "${version as unknown as string}" to unregister`,
380
+ toolId: toolId as unknown as string,
381
+ version: version as unknown as string,
382
+ },
383
+ requestId,
384
+ ),
385
+ );
386
+ }
387
+ if (onWrite !== undefined) {
388
+ try {
389
+ await onWrite({ tenantId, toolId, version, kind: 'unregister' });
390
+ } catch {
391
+ // See publish path — hooks are advisory.
392
+ }
393
+ }
394
+ return c.json({
395
+ toolId: toolId as unknown as string,
396
+ version: version as unknown as string,
397
+ unregistered: true,
398
+ });
399
+ });
400
+
401
+ // ---------- POST /:toolId/versions/:version/reinstate ----------
402
+ // Un-tombstone a specific version — clears its `unregisteredAt` and
403
+ // recomputes the tool's latest version across active versions. Restores
404
+ // the manifest bytes verbatim (semver hygiene: reinstate never mutates).
405
+ // Idempotent: reinstating an active version returns
406
+ // `wasTombstoned: false`. Mirrors the agents/flows pattern.
407
+ r.post('/:toolId/versions/:version/reinstate', async (c) => {
408
+ const requestId = c.get('requestId');
409
+ const tenantId = c.get('tenantId') as TenantId;
410
+ const toolId = c.req.param('toolId') as ToolId;
411
+ const version = c.req.param('version') as never;
412
+
413
+ const outcome = await binding.reinstateVersion({ tenantId, toolId, version });
414
+ if (outcome.kind === 'not-found') {
415
+ c.status(statusFor('tool-not-found') as never);
416
+ return c.json(
417
+ toWireError(
418
+ {
419
+ code: 'tool-not-found',
420
+ message: `No tool "${toolId as unknown as string}" at version "${version as unknown as string}" to reinstate`,
421
+ toolId: toolId as unknown as string,
422
+ version: version as unknown as string,
423
+ },
424
+ requestId,
425
+ ),
426
+ );
427
+ }
428
+ if (onWrite !== undefined) {
429
+ try {
430
+ await onWrite({
431
+ tenantId,
432
+ toolId: outcome.toolId as ToolId,
433
+ version: outcome.version as unknown as string,
434
+ kind: 'reinstate',
435
+ });
436
+ } catch {
437
+ // See publish path — hooks are advisory.
438
+ }
439
+ }
440
+ return c.json({
441
+ toolId: outcome.toolId as unknown as string,
442
+ version: outcome.version as unknown as string,
443
+ wasTombstoned: outcome.wasTombstoned,
444
+ });
445
+ });
446
+
447
+ return r;
448
+ }
449
+
450
+ /**
451
+ * The manifest as the wire carries it: every `ToolManifest` field the
452
+ * `Tool` schema declares (a mirror of `@kindgi/specs/tool.schema.json`),
453
+ * including where the code runs (`codeArtifactRef`) and the declarative
454
+ * `spec`. A secret appears only as a reference (`secretRef`), never a value.
455
+ */
456
+ function serializeTool(t: ToolManifest): Record<string, unknown> {
457
+ return {
458
+ id: t.id as unknown as string,
459
+ description: t.description,
460
+ ...(t.version !== undefined && { version: t.version }),
461
+ input: t.input,
462
+ output: t.output,
463
+ ...(t.needs !== undefined && { needs: t.needs }),
464
+ ...(t.effects !== undefined && { effects: t.effects }),
465
+ ...(t.transport !== undefined && { transport: t.transport }),
466
+ ...(t.mcpEndpoint !== undefined && { mcpEndpoint: t.mcpEndpoint }),
467
+ ...(t.metadata !== undefined && { metadata: t.metadata }),
468
+ ...(t.mutating !== undefined && { mutating: t.mutating }),
469
+ ...(t.sandbox !== undefined && { sandbox: t.sandbox }),
470
+ ...(t.limits !== undefined && { limits: t.limits }),
471
+ ...(t.network !== undefined && { network: t.network }),
472
+ ...(t.needsSpec !== undefined && { needsSpec: t.needsSpec }),
473
+ ...(t.codeArtifactRef !== undefined && { codeArtifactRef: t.codeArtifactRef }),
474
+ ...(t.spec !== undefined && { spec: t.spec }),
475
+ };
476
+ }
477
+
478
+ /**
479
+ * Serializer for `listVersions` rows — the same shape as `serializeTool`
480
+ * plus `unregisteredAt` when the row carries it. Kept separate so the
481
+ * head-level `get` / `resolve` routes don't accidentally start emitting
482
+ * a field consumers don't expect.
483
+ */
484
+ function serializeToolVersionRow(
485
+ t: ToolManifest & { readonly unregisteredAt?: string },
486
+ ): Record<string, unknown> {
487
+ return {
488
+ ...serializeTool(t),
489
+ ...(t.unregisteredAt !== undefined && { unregisteredAt: t.unregisteredAt }),
490
+ };
491
+ }