@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
package/src/app.ts ADDED
@@ -0,0 +1,1286 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // Copyright (C) 2026 Kindgi Inc.
3
+
4
+ import { Scalar } from '@scalar/hono-api-reference';
5
+ import { Hono } from 'hono';
6
+
7
+ import type { ConversationBinding, RunSnapshotBinding } from '@kindgi/agents';
8
+ import type { AuditEventBinding } from '@kindgi/audit-events';
9
+ import type { AuthzCheckBinding } from '@kindgi/authz';
10
+ import type { AdapterFactoryRegistry } from '@kindgi/capabilities';
11
+ import type { ComplianceEvidenceGenerator, LoadedClassifier } from '@kindgi/compliance';
12
+ import type { SigningKeyBinding } from '@kindgi/crypto';
13
+ import type { TenantHierarchyBinding } from '@kindgi/platform';
14
+ import type {
15
+ OrgBinding,
16
+ ProjectBinding,
17
+ ProjectMembershipBinding,
18
+ TeamBinding,
19
+ TeamMembershipBinding,
20
+ TeamProjectGrantBinding,
21
+ } from '@kindgi/platform';
22
+ import type { KernelBinding } from '@kindgi/runtime';
23
+
24
+ import type { BlobStorageBinding } from '@kindgi/blob-binding';
25
+ import type { MemoryQueryBinding } from '@kindgi/memory';
26
+ import type { PolicyRegistryBinding } from '@kindgi/policy-contract';
27
+ import type { AdapterRegistryBinding } from './adapter-binding.js';
28
+ import type { AgentRegistryBinding } from './agent-binding.js';
29
+ import type { CapabilityRegistryBinding } from './capability-binding.js';
30
+ import type { CostBinding } from './cost-binding.js';
31
+ import type { DeploymentBinding } from './deployment-binding.js';
32
+ import type { EnvBinding } from './env-binding.js';
33
+ import type { WireErrorBody } from './errors.js';
34
+ import type { EvalRunBinding } from './eval-run-binding.js';
35
+ import type { EvalSuiteRegistryBinding } from './eval-suite-binding.js';
36
+ import type { EventBusBinding } from './event-bus-binding.js';
37
+ import type { FlowRegistryBinding } from './flow-binding.js';
38
+ import type { GuardrailRegistryBinding } from './guardrail-binding.js';
39
+ import type { RunHandlerBinding } from './handler-binding.js';
40
+ import type { HitlBinding } from './hitl-binding.js';
41
+ import type { IdentityDirectoryBinding } from './identity-directory-binding.js';
42
+ import type {
43
+ ExchangeCodeFn,
44
+ IdentityProviderBinding,
45
+ RefreshTokenFn,
46
+ } from './identity-provider-binding.js';
47
+ import type { ImageRegistryBinding } from './image-registry-binding.js';
48
+ import type { MCPClientProbeBinding, MCPEndpointRegistryBinding } from './mcp-endpoint-binding.js';
49
+ import type { MemoryBinding } from './memory-binding.js';
50
+ import { type TokenResolver, bearerAuthMiddleware } from './middleware/auth.js';
51
+ import { type Authorizer, createAuthorizer } from './middleware/authorize.js';
52
+ import { mapThrownError } from './middleware/error-mapper.js';
53
+ import {
54
+ type IdempotencyStore,
55
+ createInMemoryIdempotencyStore,
56
+ idempotencyMiddleware,
57
+ } from './middleware/idempotency.js';
58
+ import { principalMiddleware } from './middleware/principal.js';
59
+ import { publicRunCorsMiddleware, publicRunRouteMatcher } from './middleware/public-run-routes.js';
60
+ import { requestIdMiddleware } from './middleware/request-id.js';
61
+ import { sigv4Middleware } from './middleware/sigv4.js';
62
+ import { type GenerateOptions, generateOpenApiDocument } from './openapi/generate.js';
63
+ import type { ProvenanceBinding } from './provenance-binding.js';
64
+ import type { ProviderRegistryBinding } from './provider-binding.js';
65
+ import {
66
+ type PublicRunTokenConfig,
67
+ mintPublicRunToken,
68
+ resolvePublicRunTokenConfig,
69
+ } from './public-run-token.js';
70
+ import type { RetentionBinding } from './retention-binding.js';
71
+ import type { ReviewerBinding, ReviewerRegistryBinding } from './reviewer-binding.js';
72
+ import {
73
+ type RotationStatusStore,
74
+ createInMemoryRotationStatusStore,
75
+ } from './rotation-status-store.js';
76
+ import { adaptersRouter } from './routes/adapters.js';
77
+ import { agentsRouter } from './routes/agents.js';
78
+ import { approvalsRouter } from './routes/approvals.js';
79
+ import { artifactsRouter } from './routes/artifacts.js';
80
+ import { auditRouter } from './routes/audit.js';
81
+ import { authRouters } from './routes/auth.js';
82
+ import { capabilitiesRouter } from './routes/capabilities.js';
83
+ import { complianceRouter } from './routes/compliance.js';
84
+ import { conversationsRouter } from './routes/conversations.js';
85
+ import { costRouter } from './routes/cost.js';
86
+ import { deploymentsRouter } from './routes/deployments.js';
87
+ import { envRouter } from './routes/env.js';
88
+ import { evalRunsRouters } from './routes/eval-runs.js';
89
+ import { evalSuitesRouter } from './routes/eval-suites.js';
90
+ import { eventTriggersRouter } from './routes/event-triggers.js';
91
+ import { flowsRouter } from './routes/flows.js';
92
+ import { guardrailsRouter } from './routes/guardrails.js';
93
+ import { identityRouter } from './routes/identity.js';
94
+ import { mcpRouter } from './routes/mcp.js';
95
+ import { memoryRouter } from './routes/memory.js';
96
+ import { observationsRouter } from './routes/observations.js';
97
+ import { orgsRouter } from './routes/orgs.js';
98
+ import { policiesRouter } from './routes/policies.js';
99
+ import { projectsRouter } from './routes/projects.js';
100
+ import { proposalsRouter } from './routes/proposals.js';
101
+ import { provenanceRouter } from './routes/provenance.js';
102
+ import { providersRouter } from './routes/providers.js';
103
+ import { publicRunTokensRouter } from './routes/public-run-tokens.js';
104
+ import { retentionRouter } from './routes/retention.js';
105
+ import { reviewersRouter } from './routes/reviewers.js';
106
+ import { runsRouter } from './routes/runs.js';
107
+ import { s3Router } from './routes/s3.js';
108
+ import { schedulesRouter } from './routes/schedules.js';
109
+ import { secretsRouter } from './routes/secrets.js';
110
+ import { signingKeysRouter } from './routes/signing-keys.js';
111
+ import { teamsRouter } from './routes/teams.js';
112
+ import { tenantRouter } from './routes/tenant.js';
113
+ import { tokensRouter } from './routes/tokens.js';
114
+ import { toolsRouter } from './routes/tools.js';
115
+ import { webhookEndpointsRouter } from './routes/webhook-endpoints.js';
116
+ import { webhooksRouter } from './routes/webhooks.js';
117
+ import type { S3CredentialBinding } from './s3-credential-binding.js';
118
+ import type { SecretBinding } from './secrets-binding.js';
119
+ import type { SessionStoreBinding } from './session-store-binding.js';
120
+ import type { SigningKeyBinding as SigningKeyRegistryBinding } from './signing-key-binding.js';
121
+ import { type OauthStateStore, createInMemoryOauthStateStore } from './state-store-binding.js';
122
+ import type { SupervisorBinding } from './supervisor-binding.js';
123
+ import type { TenantHostAccess } from './tenant-host-access.js';
124
+ import type { TokenAdmin } from './token-admin.js';
125
+ import type { ToolRegistryBinding } from './tool-binding.js';
126
+ import type { TriggerRegistryBinding } from './trigger-binding.js';
127
+ import type { AppEnv } from './types.js';
128
+ import type { WebhookEndpointBinding } from './webhook-endpoint-binding.js';
129
+
130
+ /**
131
+ * Assemble the platform HTTP app. Caller-injectable dependencies:
132
+ *
133
+ * - `resolveToken`: `(token) → Promise<{ tenantId, … } | null>`. Caller
134
+ * plugs in the actual token store — this package doesn't own auth
135
+ * persistence.
136
+ * - `runHandler`: bridge from `POST /v1/runs` requests into the
137
+ * agent/flow invocation stack. See `RunHandlerBinding` for shape.
138
+ *
139
+ * The returned app is a plain Hono instance; callers mount it on a
140
+ * server (e.g. `@hono/node-server`) or invoke `.request(...)` directly
141
+ * for tests.
142
+ */
143
+ export interface CreateAppInput {
144
+ readonly resolveToken: TokenResolver;
145
+ readonly runHandler: RunHandlerBinding;
146
+ /**
147
+ * Conversation store binding — openConversation / getConversation /
148
+ * listConversations / listConversationsPage / closeConversation /
149
+ * deleteConversation / appendMessage / readMessages. Every
150
+ * conversation-touching route (conversations, approvals audit
151
+ * bundle, provenance signed export) routes through this binding.
152
+ * The Kindgi runtime supplies an implementation. Required.
153
+ */
154
+ readonly conversationBinding: ConversationBinding;
155
+ /**
156
+ * Run-snapshot store binding — write / read on the run reconstruction
157
+ * envelope. Not called by this package's routes; required so the host
158
+ * can assemble a complete `InvokeAgentBindings` (`@kindgi/agents`)
159
+ * when it constructs the agent-runtime handler. The Kindgi runtime
160
+ * supplies an implementation.
161
+ */
162
+ readonly runSnapshotBinding: RunSnapshotBinding;
163
+ /**
164
+ * Kernel binding (`@kindgi/runtime`) for run lifecycle + scheduler /
165
+ * waitpoint / retention / trigger-registry / event-bus sub-bindings.
166
+ * The Kindgi runtime supplies one (or pass a bespoke implementation).
167
+ *
168
+ * Required — @kindgi/api holds no reference to the kernel
169
+ * itself, so the caller owns the construction.
170
+ */
171
+ readonly kernelBinding: KernelBinding;
172
+
173
+ /**
174
+ * Tenant-hierarchy CRUD binding — atomic entity writes + FGA
175
+ * parent/owner tuple emission. Used by the always-mounted
176
+ * `/v1/tenant` route and by `/v1/orgs`, `/v1/teams`, `/v1/projects`
177
+ * when the corresponding platform bindings are supplied. The Kindgi
178
+ * runtime supplies an implementation.
179
+ *
180
+ * Required — same rationale as `kernelBinding`.
181
+ */
182
+ readonly tenantHierarchyBinding: TenantHierarchyBinding;
183
+
184
+ /**
185
+ * Memory data-access binding — listFacts / searchByKeyword /
186
+ * searchBySemantic / appendLog / readLog. Every agent-runtime memory
187
+ * read and log write routes through this binding. This package's
188
+ * routes don't call it (conversation transcripts are read through
189
+ * `conversationBinding`). The Kindgi runtime supplies an
190
+ * implementation (or pass a bespoke one).
191
+ *
192
+ * Required — same rationale as `kernelBinding` / `provenanceBinding`.
193
+ */
194
+ readonly memoryBinding: MemoryQueryBinding;
195
+
196
+ /**
197
+ * Provenance data-access binding — list summaries + full-DAG reads
198
+ * over stored provenance records. Used by the always-mounted
199
+ * `/v1/provenance` routes. The Kindgi runtime supplies an
200
+ * implementation (or pass a bespoke one).
201
+ *
202
+ * Required — @kindgi/api never touches the provenance schema or
203
+ * domain functions directly, so the caller owns the default
204
+ * construction.
205
+ */
206
+ readonly provenanceBinding: ProvenanceBinding;
207
+ /**
208
+ * Optional authz enforcement config. When present, route handlers get
209
+ * an `Authorizer` (`authorize()` / `can()` / `check()` /
210
+ * `filterByCan()`) backed by `authzCheckBinding`. `principalMiddleware`
211
+ * runs on `/v1/*` either way. When absent (e.g. dev deployments),
212
+ * routes still work but authz is not enforced — bearer + capability
213
+ * gates are the only checks.
214
+ */
215
+ readonly authz?: {
216
+ readonly fgaApiUrl: string;
217
+ /**
218
+ * PDP binding (`@kindgi/authz`) — `check(principal, action,
219
+ * resource, ctx?)` + `checkBatch(...)`. The Kindgi runtime supplies
220
+ * one (or pass a bespoke implementation).
221
+ */
222
+ readonly authzCheckBinding: AuthzCheckBinding;
223
+ };
224
+ /**
225
+ * Optional unified audit substrate. When present:
226
+ * - `GET /v1/audit/authz` is mounted (admin@tenant only) as a
227
+ * view filtered to `kind='authz-decision'`. Those events are
228
+ * written by the authz check binding (wired to this same sink),
229
+ * correlated with the request's `x-request-id` — the `Authorizer`
230
+ * passes it as `correlationId` on every `check()`.
231
+ * - `/v1/compliance/*` is mounted as a view filtered to
232
+ * classifier-marked exportable kinds (needs
233
+ * `complianceClassifier` too).
234
+ * Absent = no durable audit trail; every subsystem's audit
235
+ * writes become no-ops.
236
+ *
237
+ * One write surface — authz decisions and compliance evidence share
238
+ * this single binding.
239
+ */
240
+ readonly auditEvents?: AuditEventBinding;
241
+ /**
242
+ * Optional classification lens over `auditEvents`. Drives which
243
+ * audit-event kinds appear in the `/v1/compliance/*` view and (at
244
+ * export time) which get an Ed25519 signature. Absent =
245
+ * `/v1/compliance/*` is not mounted.
246
+ */
247
+ readonly complianceClassifier?: LoadedClassifier;
248
+ /**
249
+ * Optional compliance-evidence generator. Required when
250
+ * `auditEvents` + `complianceClassifier` are provided (i.e., when
251
+ * `/v1/compliance/*` mounts). The Kindgi runtime supplies the
252
+ * generator (or pass a bespoke implementation). The public interface
253
+ * has recordFromRun / exportSigned / describe; implementations may add
254
+ * more (e.g. subscriptions), which @kindgi/api doesn't use.
255
+ */
256
+ readonly complianceGenerator?: ComplianceEvidenceGenerator;
257
+ /**
258
+ * Optional. When omitted, a per-app in-memory store is used —
259
+ * appropriate for dev + tests, NOT for production (retries after a
260
+ * process restart won't dedupe). Prod deployments pass a persistent
261
+ * store (Postgres, Redis, etc.).
262
+ */
263
+ readonly idempotencyStore?: IdempotencyStore;
264
+ /**
265
+ * Optional. When present, mounts the API-key routes: `POST /v1/tokens`
266
+ * (mint), `GET /v1/tokens` (list), `GET /v1/tokens/:tokenId` and
267
+ * `POST /v1/tokens/:tokenId/revoke`. Omit if the deployment manages
268
+ * keys out-of-band (e.g. via a separate admin console).
269
+ */
270
+ readonly tokenAdmin?: TokenAdmin;
271
+ /**
272
+ * Optional. When present, mounts the HITL surface:
273
+ * - `GET /v1/approvals` (list, role-scoped)
274
+ * - `GET /v1/approvals/:approvalId`
275
+ * - `POST /v1/approvals/:approvalId/complete`
276
+ *
277
+ * Requires a `ReviewerBinding` because `hitl.submitReview` needs the
278
+ * reviewer's id (not their user id). Deployments plug in the
279
+ * `UserId → ReviewerId` lookup here.
280
+ *
281
+ * Also requires `hitlBinding` — the data-access surface. The Kindgi
282
+ * runtime supplies one (or pass a bespoke implementation); the api
283
+ * package holds no reference to the HITL domain functions.
284
+ */
285
+ readonly reviewerBinding?: ReviewerBinding;
286
+ /**
287
+ * Required alongside `reviewerBinding`. The approvals data-access
288
+ * binding (`getApproval` / `listApprovals` / `submitReview` /
289
+ * `loadReviewDecision`) — `@kindgi/api` never touches the HITL
290
+ * domain functions or their storage directly. The Kindgi runtime
291
+ * supplies an implementation.
292
+ */
293
+ readonly hitlBinding?: HitlBinding;
294
+ /**
295
+ * Optional. When present, mounts the reviewer roster sub-resource
296
+ * at `/v1/approvals/reviewers` — list / get / register / unregister.
297
+ * Caller-plugged, same pattern as `agentRegistry`. Distinct from
298
+ * `reviewerBinding` (which resolves a token's `UserId` to a
299
+ * `ReviewerId` for decision routing) so a deployment can wire the
300
+ * two independently.
301
+ */
302
+ readonly reviewerRegistry?: ReviewerRegistryBinding;
303
+ /**
304
+ * Optional. When `true` AND `supervisor` is wired, mounts
305
+ * `GET /v1/observations` (supervisor readback). Both are needed —
306
+ * the flag is the deploy-time opt-in, the binding is the query seam.
307
+ * Without a `supervisor`
308
+ * binding this flag is a no-op.
309
+ */
310
+ readonly enableObservations?: boolean;
311
+ /**
312
+ * Optional. When present, mounts the agents catalog surface
313
+ * (`/v1/agents` list/get/publish, `/v1/agents/:agentId/versions/*`).
314
+ * Same caller-plugged pattern as `TokenAdmin` — the API package does
315
+ * NOT own registry persistence. Deployments plug in any
316
+ * implementation, e.g. one over `@kindgi/agents`' in-memory
317
+ * `AgentRegistry`.
318
+ */
319
+ readonly agentRegistry?: AgentRegistryBinding;
320
+ /**
321
+ * Optional. When present, mounts the flows catalog surface
322
+ * (`/v1/flows` list/get/publish, `/v1/flows/:flowId/versions/*`).
323
+ * Caller-plugged pattern mirrors `agentRegistry` 1:1. Publish
324
+ * validates the wire body via `@kindgi/flow.loadFlow` — a flow
325
+ * published through the API is byte-identical to one constructed
326
+ * in-process. Enables non-agent workflows (webhook processors, ETL
327
+ * jobs, ingest pipelines) via HTTP.
328
+ */
329
+ readonly flowRegistry?: FlowRegistryBinding;
330
+ /**
331
+ * Optional. When present, mounts the tools catalog surface
332
+ * (`/v1/tools` list/get/register/unregister). Caller-plugged
333
+ * pattern mirrors `agentRegistry`. Registration here is metadata-only
334
+ * — handler code is bundled with the runtime or shipped in a signed
335
+ * deployment (`POST /v1/deployments`).
336
+ */
337
+ readonly toolRegistry?: ToolRegistryBinding;
338
+ /**
339
+ * Optional post-write hook fired after a successful tool publish /
340
+ * unregister / reinstate. The caller wires this to invalidate any
341
+ * in-process runtime cache that mirrors the persisted registry
342
+ * (e.g. the runtime's tool bridge, invalidated per tenant).
343
+ * Without it, a re-published tool's schema / description edits
344
+ * are silently ignored until the server process restarts.
345
+ */
346
+ readonly onToolWrite?: import('./routes/tools.js').ToolWriteHook;
347
+ /**
348
+ * Optional. When present, mounts the guardrails catalog surface
349
+ * (`/v1/guardrails` list/get/register/unregister). Caller-plugged
350
+ * pattern mirrors `agentRegistry`. Registration here is metadata-only
351
+ * — the check implementation is bundled with the runtime or shipped
352
+ * in a signed deployment.
353
+ */
354
+ readonly guardrailRegistry?: GuardrailRegistryBinding;
355
+ /**
356
+ * Optional post-write hook fired after a successful guardrail
357
+ * register / unregister. Caller wires this to invalidate any
358
+ * in-process runtime cache that mirrors the persisted registry
359
+ * (e.g. the runtime's guardrail bridge, invalidated per tenant).
360
+ * Without it, a newly-registered guardrail is stored but doesn't
361
+ * reach agent turns until the server process restarts. Same
362
+ * cache-invalidation concern as `onToolWrite` / `onProviderWrite`.
363
+ */
364
+ readonly onGuardrailWrite?: import('./routes/guardrails.js').GuardrailWriteHook;
365
+ /**
366
+ * Optional. When present, mounts the retention surface
367
+ * (`/v1/retention/scheduled`, `/v1/retention/sweep`,
368
+ * `/v1/retention/sweep/:domain`). Caller-plugged; the Kindgi runtime
369
+ * supplies an implementation over its per-domain retention sweeps.
370
+ */
371
+ readonly retention?: RetentionBinding;
372
+ /**
373
+ * Optional. When present, mounts the memory surface
374
+ * (`/v1/memory/facts` list/get/write/supersede, `/v1/memory/retrieve`).
375
+ * Caller-plugged pattern mirrors the other registry bindings — the
376
+ * API package doesn't hardwire an embedding provider or a retrieval
377
+ * policy registry. Deployments plug in a binding that wraps
378
+ * the memory subsystem runtime + their embedding registry.
379
+ */
380
+ readonly memory?: MemoryBinding;
381
+ /**
382
+ * Optional. When present, mounts the supervisor proposals surface
383
+ * (`/v1/proposals` list/get/draft, plus lifecycle actions
384
+ * dry-run / submit-review / apply / rollback / withdraw). Every
385
+ * route requires an `X-Supervisor-Id` request header — the API
386
+ * package doesn't own the supervisor registry, so the binding
387
+ * receives that scope explicitly.
388
+ *
389
+ * The binding wraps the supervisor runtime primitives +
390
+ * the deployment's `AgentRegistry` + `HITL` wiring + eval dataset
391
+ * registry. See `supervisor-binding.ts` for the full contract.
392
+ */
393
+ readonly supervisor?: SupervisorBinding;
394
+ /**
395
+ * Optional. Caller-plugged key store for signed provenance exports
396
+ * (`POST /v1/provenance/:runId/export`). When omitted, the export
397
+ * route responds `404 signing-not-configured` — the read routes
398
+ * (`GET /v1/provenance`, `GET /v1/provenance/:runId`) remain mounted
399
+ * either way because they read through `provenanceBinding` and do not
400
+ * need signing material.
401
+ *
402
+ * Same caller-plugged pattern as the other bindings — the API package
403
+ * does NOT own key persistence. Deployments plug in a binding that
404
+ * wraps their KMS / HSM / env-var store; see `SigningKeyBinding` in
405
+ * `@kindgi/crypto`.
406
+ */
407
+ readonly signingKey?: SigningKeyBinding;
408
+ /**
409
+ * Optional. Issue and accept public run tokens (`kgi_pt_…`):
410
+ * short-lived, read-only tokens a browser uses to follow specific runs
411
+ * (`GET /v1/runs/:runId/progress` and its stream: status and steps, no data). When
412
+ * present, `POST /v1/runs` returns a `publicAccessToken`,
413
+ * `POST /v1/tokens/public` mints them, and `allowedOrigins` get CORS
414
+ * on those two read routes. Checked at startup: the key must be an
415
+ * Ed25519 key in `signingKey`. Use a key for this purpose alone.
416
+ */
417
+ readonly publicRunTokens?: PublicRunTokenConfig;
418
+ /**
419
+ * Optional. When present, mounts the artifacts surface
420
+ * (`/v1/artifacts` list / multipart upload; `/v1/artifacts/:blobId`
421
+ * GET stream / HEAD / DELETE). Caller-plugged pattern mirrors the
422
+ * other registry bindings — the API package doesn't own storage.
423
+ * Deployments plug in a `BlobStorageBinding` implementation, e.g.
424
+ * filesystem-backed for development or object-store-backed in
425
+ * production.
426
+ */
427
+ readonly blobStorage?: BlobStorageBinding;
428
+ /**
429
+ * Optional. When present, mounts the read-only capabilities catalog
430
+ * surface (`/v1/capabilities` list, `/v1/capabilities/:capabilityId`
431
+ * get). Capabilities are framework-declared (`FEATURES` enum in
432
+ * `@kindgi/capabilities` + `@kindgi/specs/capability.schema.json`) and
433
+ * deployment-extended at boot time via the binding — tenants do NOT
434
+ * author capabilities via HTTP.
435
+ */
436
+ readonly capabilityRegistry?: CapabilityRegistryBinding;
437
+ /**
438
+ * Optional. When present, mounts the model-providers catalog surface
439
+ * (`/v1/providers` list, `/v1/providers/:providerId` get, `POST
440
+ * /v1/providers` register, `POST /v1/providers/:providerId/unregister`,
441
+ * `GET /v1/providers/:providerId/capabilities` sub-resource). Full
442
+ * CRUD — tenants register their own providers. `ProviderMetadata` is
443
+ * the wire shape; secrets never cross the wire (they stay inside the
444
+ * binding).
445
+ */
446
+ readonly providerRegistry?: ProviderRegistryBinding;
447
+ /**
448
+ * Optional post-write hook fired after a successful provider
449
+ * register / unregister. The caller wires this to invalidate any
450
+ * in-process runtime cache that mirrors the persisted registry
451
+ * (e.g. the runtime's provider bridge, invalidated per tenant).
452
+ * Without it, a provider registered after boot is stored but the
453
+ * runtime keeps serving its boot-time snapshot — routing continues
454
+ * to pick whatever was seeded at boot even after the operator
455
+ * registered another provider.
456
+ */
457
+ readonly onProviderWrite?: import('./routes/providers.js').ProviderWriteHook;
458
+ /**
459
+ * Optional. When present, mounts the MCP-endpoint registry surface at
460
+ * `/v1/mcp/endpoints/*` — `GET /v1/mcp/endpoints` (list, cursor-paginated,
461
+ * optional `?transport=` filter), `GET /v1/mcp/endpoints/:endpointId`,
462
+ * `POST /v1/mcp/endpoints` (register), `POST /v1/mcp/endpoints/:endpointId/unregister`.
463
+ * Full CRUD — tenants declare the remote MCP servers they want the
464
+ * runtime to consume. `MCPEndpoint` is the wire shape; its `secretRef`
465
+ * names a secret in the deployment's store, never the credential.
466
+ * The runtime can discover each endpoint's tools at boot and register
467
+ * them into the tool registry under the same tenant.
468
+ */
469
+ readonly mcpEndpointRegistry?: MCPEndpointRegistryBinding;
470
+ /**
471
+ * How far tenant configuration may reach into the server's host
472
+ * (`KINDGI_TENANT_HOST_ACCESS`, see `tenant-host-access.ts`): under
473
+ * `deployed`, registering a stdio MCP endpoint answers `403
474
+ * host-access-denied`. Default `deployed`; the runtime passes `local`
475
+ * only for a development server.
476
+ */
477
+ readonly tenantHostAccess?: TenantHostAccess;
478
+ /**
479
+ * Optional. Backs the MCP resources + prompts routes, which mount with
480
+ * `mcpEndpointRegistry`:
481
+ * `GET /v1/mcp/endpoints/:endpointId/resources`,
482
+ * `GET /v1/mcp/endpoints/:endpointId/resources/:uri`,
483
+ * `GET /v1/mcp/endpoints/:endpointId/prompts`,
484
+ * `POST /v1/mcp/endpoints/:endpointId/prompts/:name`.
485
+ *
486
+ * A typical implementation opens a fresh MCP client against the
487
+ * endpoint per request, runs the operation, and closes. When absent,
488
+ * the resources + prompts routes 404 with `mcp-endpoint-not-found`.
489
+ */
490
+ readonly mcpClientProbe?: MCPClientProbeBinding;
491
+ /**
492
+ * Optional. When present, mounts the cost readback surface at
493
+ * `/v1/cost/*` — `GET /v1/cost/records` (paginated list with
494
+ * `runId` / `agentId` / `conversationId` / `category` / `providerId` /
495
+ * time-window filters), `GET /v1/cost/records/:recordId` (single),
496
+ * `GET /v1/cost/aggregate` (multi-dimensional rollup over a required
497
+ * time window; default "last 30 days"). Read-only over HTTP —
498
+ * records are written by the runtime's agent / tool / sandbox
499
+ * instrumentation, not through this surface.
500
+ *
501
+ * Budgets are NOT part of this surface.
502
+ */
503
+ readonly cost?: CostBinding;
504
+ /**
505
+ * Optional. When present, mounts the unified adapters catalog surface
506
+ * at `/v1/adapters/*` — `GET /v1/adapters` (paginated list with
507
+ * optional `kind` / `status` filters), `GET /v1/adapters/:adapterId`
508
+ * (single), `POST /v1/adapters/:adapterId/test` (kind-specific smoke
509
+ * probe). Read-only + test-only over HTTP; adapter lifecycle
510
+ * (register / unregister / reconfigure) is a deployment concern
511
+ * — the runtime learns about adapters at `CreateAppInput` time.
512
+ *
513
+ * Deployments implement the binding by aggregating their wired
514
+ * adapters (they know which ones are active because they wire them).
515
+ * See `AdapterRegistryBinding` for the full contract.
516
+ */
517
+ readonly adapterRegistry?: AdapterRegistryBinding;
518
+ /**
519
+ * Optional. In-process factory registry that maps `adapter_id` →
520
+ * factory function + optional `prepare()` for adapter warmup /
521
+ * download. Backs `POST /v1/adapters/:adapterId/prepare` (mounted
522
+ * with `adapterRegistry`) — an SSE endpoint that iterates
523
+ * `entry.prepare()` and streams `PrepareEvent`s to the caller.
524
+ *
525
+ * The runtime builds this at boot alongside the adapter registry so
526
+ * registry entries and in-process factories stay coherent.
527
+ * Deployments without in-process adapter factories (e.g. a custom
528
+ * runHandler) can leave this undefined — the `prepare` route then
529
+ * answers `400 bad-input` for every adapter id.
530
+ */
531
+ readonly adapterFactories?: AdapterFactoryRegistry;
532
+ /**
533
+ * Optional. When present, mounts the trigger admin surfaces at
534
+ * `/v1/schedules/*`, `/v1/event-triggers/*`, and `/v1/webhooks/*`.
535
+ * Kernel runtime primitives (cron/event/webhook schedulers) do the
536
+ * firing; this binding satisfies the CRUD surface over the stored
537
+ * triggers.
538
+ *
539
+ * The Kindgi runtime supplies an implementation. Deployments that
540
+ * want bespoke persistence substitute their own binding.
541
+ */
542
+ readonly triggerRegistry?: TriggerRegistryBinding;
543
+ /**
544
+ * Optional. When present, mounts the outbound webhook surface at
545
+ * `/v1/webhook-endpoints/*`: endpoints the platform sends signed
546
+ * events to (`run.finished`), their delivery log, redelivery and a test
547
+ * event. The runtime supplies storage, secrets and the sender; see
548
+ * `WebhookEndpointBinding`.
549
+ */
550
+ readonly webhookEndpoints?: WebhookEndpointBinding;
551
+ /**
552
+ * Optional. When present, mounts the tenant policies catalog surface
553
+ * (`/v1/policies` list/get/publish, `/v1/policies/:policyId/versions/*`).
554
+ * Full versioned CRUD — mirrors `flows` 1:1. Registry-only:
555
+ * enforcement is out of scope. Runtime consumers (e.g. the kernel
556
+ * router for `model-routing`, an adapter-allowlist check for
557
+ * `adapter-allowlist`, retention sweepers for `retention`) read
558
+ * policies from this store and apply them at their own boundary.
559
+ * `policyKind` is enumerated + extensible — new kinds require a spec +
560
+ * validator update in tandem.
561
+ */
562
+ readonly policyRegistry?: PolicyRegistryBinding;
563
+ /**
564
+ * Optional. When present, mounts the evaluation-suite catalog surface
565
+ * (`/v1/eval-suites` list/get/publish, `/v1/eval-suites/:suiteId/versions/*`).
566
+ * Full versioned CRUD — mirrors `policies` 1:1. Registry-only:
567
+ * eval-run execution + per-kind grader dispatch (eval-judge adapter
568
+ * for `accuracy` / `pairwise` / `regression`, HITL bridge for
569
+ * `human-review`, sandbox handler for `custom`) is out of scope
570
+ * here (see `evalRunBinding`). `evalKind` is enumerated + extensible
571
+ * — new kinds require a spec + validator update in tandem.
572
+ */
573
+ readonly evalSuiteRegistry?: EvalSuiteRegistryBinding;
574
+ /**
575
+ * Optional. When present alongside `evalSuiteRegistry`, mounts the
576
+ * evaluation-run data-plane surface: `POST /v1/eval-suites/:suiteId/runs`
577
+ * (start), `GET /v1/eval-runs` (list, cursor-paginated),
578
+ * `GET /v1/eval-runs/:runId` (get), `POST /v1/eval-runs/:runId/cancel`,
579
+ * `GET /v1/eval-runs/:runId/events` (SSE). Caller-plugged binding —
580
+ * the API package doesn't own eval-run persistence. The reference
581
+ * `createInProcessEvalRunBinding` (`packages/api/src/eval-run-dispatcher.ts`)
582
+ * implements the pattern end-to-end for the `accuracy` kind; a suite
583
+ * of a kind with no registered dispatcher answers
584
+ * `422 dispatcher-not-registered`.
585
+ */
586
+ readonly evalRunBinding?: EvalRunBinding;
587
+ /**
588
+ * Optional. Push-based pub/sub binding used by SSE endpoints to
589
+ * deliver run events without polling. When present, `GET
590
+ * /v1/runs/:runId/stream` subscribes on channel
591
+ * `kernel:run:<runId>` and delivers push-mode; when absent, the
592
+ * route falls back to a 200 ms journal poll — wire shape identical
593
+ * either way, so callers can't tell.
594
+ *
595
+ * The Kindgi runtime supplies an implementation. Wire the same bus
596
+ * into the kernel behind `CreateAppInput.runHandler` so the kernel
597
+ * publishes on each journal write; without that, the subscription
598
+ * receives nothing (the kernel never posts).
599
+ *
600
+ * See `packages/api/src/event-bus-binding.ts` for the contract.
601
+ */
602
+ readonly eventBus?: EventBusBinding;
603
+ /**
604
+ * Optional. When present alongside `blobStorage`, mounts the
605
+ * AWS S3-compat wire surface at `/s3/*`. SigV4-authenticated
606
+ * per request against the credentials this binding resolves. Requests
607
+ * for buckets the credential is not authorized for return
608
+ * `403 AccessDenied`. Storage flows through the same
609
+ * `BlobStorageBinding` as the bespoke `/v1/artifacts/*` surface —
610
+ * cross-surface interop is a first-class guardrail. Includes the
611
+ * S3 multipart-upload operations (initiate / upload part / complete /
612
+ * list parts / abort).
613
+ */
614
+ readonly s3Credentials?: S3CredentialBinding;
615
+ /**
616
+ * Optional. When present, mounts the OAuth session persistence
617
+ * surface. Combined with `identityProvider` + `exchangeCode` (below),
618
+ * this activates the full `/v1/auth/*` route family. The static
619
+ * bearer-token flow remains available on the same routes byte-
620
+ * shape-identical; the middleware detects `kgi_sk_*` prefixed
621
+ * tokens and routes them through this store.
622
+ *
623
+ * Caller-plugged — the API package does NOT own session persistence.
624
+ * The Kindgi runtime supplies a durable implementation; deployments
625
+ * can also plug in their own (Redis, SQLite, memory, etc.).
626
+ */
627
+ readonly sessionStore?: SessionStoreBinding;
628
+ /**
629
+ * Optional. When present, tunes session-token lifecycle enforcement
630
+ * in the auth middleware. Absent → sensible defaults (absolute TTL
631
+ * from the stored session's `expiresAt`; inactivity timeout disabled).
632
+ * Only applies to `kgi_sk_*` session tokens; static bearer tokens are
633
+ * unaffected.
634
+ */
635
+ readonly session?: SessionConfig;
636
+ /**
637
+ * Optional. When present alongside `sessionStore` + `exchangeCode`,
638
+ * mounts the identity-provider catalog + auth flow at `/v1/auth/*`.
639
+ *
640
+ * Deployments register their OAuth/OIDC providers at boot (or via
641
+ * `POST /v1/auth/providers`); the framework does NOT bake in a
642
+ * provider list.
643
+ */
644
+ readonly identityProvider?: IdentityProviderBinding;
645
+ /**
646
+ * Required alongside `identityProvider`. Called by
647
+ * `POST /v1/auth/callback/:providerId` to exchange the authorization
648
+ * code for provider tokens + userinfo. Deployments implementing
649
+ * `IdentityProviderBinding` typically pair it with their own
650
+ * `exchangeCode` that speaks OAuth 2.0 + PKCE against the provider's
651
+ * `tokenEndpoint`.
652
+ */
653
+ readonly exchangeCode?: ExchangeCodeFn;
654
+ /**
655
+ * Optional. When present, `POST /v1/auth/refresh` rotates the
656
+ * underlying provider tokens via this callback before re-issuing a
657
+ * session token. When absent, refresh only rotates the framework's
658
+ * session token (still useful for scoping expiry to the framework
659
+ * boundary; the provider tokens keep their original TTL).
660
+ */
661
+ readonly refreshToken?: RefreshTokenFn;
662
+ /**
663
+ * Optional. Short-lived CSRF-`state` + PKCE-`code_verifier` cache
664
+ * used between login initiation and callback. When absent, a per-app
665
+ * in-memory store is used — appropriate for single-process dev + tests.
666
+ * Multi-pod deployments MUST plug in a shared store (Redis, Postgres)
667
+ * because the callback frequently lands on a different pod than the
668
+ * login. Mirror of the `idempotencyStore` caller-plugged pattern.
669
+ */
670
+ readonly oauthStateStore?: OauthStateStore;
671
+ /**
672
+ * Optional. Signed-deployment ledger — the audit anchor for every
673
+ * `POST /v1/deployments` landing. Caller-plugged per the pattern
674
+ * (e.g. in-memory for tests, a durable store in production). Mount
675
+ * happens only when this + `signingKeyRegistry` + `imageRegistry` are
676
+ * ALL wired.
677
+ */
678
+ readonly deploymentRegistry?: DeploymentBinding;
679
+ /**
680
+ * Optional. Tenant-scoped signing-key trust registry.
681
+ * Higher-level than `SigningKeyBinding` (which is
682
+ * KMS-shaped): answers "for tenant T, is this public key allowed to
683
+ * sign deploys?" and performs signature verification against the
684
+ * registered trust list. Aliased on import to avoid the local name
685
+ * collision with the crypto binding.
686
+ */
687
+ readonly signingKeyRegistry?: SigningKeyRegistryBinding;
688
+ /**
689
+ * Optional. OCI image registry client — Docker
690
+ * Registry HTTP API v2 seam. The deploy route calls `head` + one
691
+ * `extractFile('/app/index.json')` to verify pullability + integrity;
692
+ * `push` is for build tooling, not the API routes. Caller-plugged
693
+ * so deployments route different tenants at different registries.
694
+ */
695
+ readonly imageRegistry?: ImageRegistryBinding;
696
+ /**
697
+ * Optional. When present, mounts the tenant-scoped identity
698
+ * directory surface (`/v1/identity/users` list/get,
699
+ * `/v1/identity/users/:userId/sessions` list-active,
700
+ * `/v1/identity/users/:userId/revoke-sessions` admin op,
701
+ * `/v1/identity/whoami` self) — part of the admin control plane.
702
+ * Registry-only over HTTP; deployments plug in an
703
+ * LDAP / SCIM / bespoke user store behind
704
+ * `IdentityDirectoryBinding`. `whoami` returns the fuller
705
+ * `UserRecord` shape when the binding is wired and the token
706
+ * carries a `userId`; otherwise it falls back to the minimal
707
+ * `{ tenantId, ... }` shape.
708
+ */
709
+ readonly identityDirectory?: IdentityDirectoryBinding;
710
+ /**
711
+ * Optional. Overrides the default `info` + `servers` in the emitted
712
+ * OpenAPI document (`GET /v1/openapi.json`) and — via the `docs`
713
+ * sub-config — opts the deployment into an interactive Scalar-rendered
714
+ * API reference UI. Deployments typically set `servers[0].url` to their
715
+ * public base URL.
716
+ */
717
+ readonly openapi?: OpenApiConfig;
718
+ // ---------- platform hierarchy ----------
719
+ /**
720
+ * Optional. When present, mounts the `/v1/orgs` resource surface
721
+ * (list/create/get/patch/delete) of the multi-tenant hierarchy.
722
+ * Caller-plugged: the reference in-memory implementation is
723
+ * `makeInMemoryOrgBinding` in `@kindgi/platform`; the Kindgi runtime
724
+ * supplies a durable one.
725
+ */
726
+ readonly orgBinding?: OrgBinding;
727
+ /**
728
+ * Optional. When present, mounts the `/v1/teams` resource surface —
729
+ * team CRUD plus `/v1/teams/:teamId/memberships` sub-resource. Both
730
+ * `teamBinding` AND `teamMembershipBinding` MUST be supplied together
731
+ * (otherwise `/v1/teams` is not mounted) — the reference
732
+ * in-memory adapter returns them as a combined `{teams, memberships}`
733
+ * factory, and durable implementations mirror that shape.
734
+ */
735
+ readonly teamBinding?: TeamBinding;
736
+ readonly teamMembershipBinding?: TeamMembershipBinding;
737
+ /**
738
+ * Optional. When present, mounts the `/v1/projects` resource surface —
739
+ * project CRUD (including `/v1/projects/default`) plus
740
+ * `/v1/projects/:projectId/memberships` sub-resource. Both
741
+ * `projectBinding` AND `projectMembershipBinding` MUST be supplied
742
+ * together — same combined-factory pattern as teams.
743
+ */
744
+ readonly projectBinding?: ProjectBinding;
745
+ readonly projectMembershipBinding?: ProjectMembershipBinding;
746
+ /**
747
+ * Optional. The team↔project grant binding. Not consumed by this
748
+ * package's routes; the authz backend uses it to resolve
749
+ * team-mediated project grants.
750
+ */
751
+ readonly teamProjectGrantBinding?: TeamProjectGrantBinding;
752
+ /**
753
+ * Optional. Non-sensitive per-env values. When present alongside or
754
+ * separately from `secretsBinding`, mounts the `/v1/tenant/config`
755
+ * sub-routes at tenant scope. The base `GET /v1/tenant` route is
756
+ * always mounted; the `/config` surface is gated on at least one of
757
+ * `envBinding` / `secretsBinding` being present.
758
+ */
759
+ readonly envBinding?: EnvBinding;
760
+ /**
761
+ * Optional. Sensitive per-env values. Same mount rule as
762
+ * `envBinding` — either binding present is enough to mount
763
+ * `/v1/tenant/config`. Writes to `/v1/tenant/config` with
764
+ * `sensitive: true` (or `kind: 'secret'`) route to this binding; the
765
+ * routes 400 when a secret write is attempted but this binding is
766
+ * absent.
767
+ *
768
+ * When present, ALSO mounts `/v1/secrets/*` — the dedicated
769
+ * secrets HTTP surface. Same for `envBinding` and `/v1/env/*`.
770
+ */
771
+ readonly secretsBinding?: SecretBinding;
772
+ /**
773
+ * Optional. Backs the async-rotation wire (`POST /v1/secrets/:name/rotate`
774
+ * → 202 Accepted; poll via `GET /v1/secrets/:name/rotations/:rotationId`;
775
+ * subscribe via `GET /v1/secrets/:name/rotations/:rotationId/events`).
776
+ * When `secretsBinding` is present AND this is absent, a per-app
777
+ * in-memory reference store is used — appropriate for dev + tests
778
+ * only; multi-pod production deployments MUST plug in a durable
779
+ * adapter (rotations can take minutes to hours; the row must
780
+ * survive process restarts and reach pods handling later polls /
781
+ * subscribes).
782
+ */
783
+ readonly rotationStatusStore?: RotationStatusStore;
784
+ }
785
+
786
+ /**
787
+ * OpenAPI configuration. Extends `GenerateOptions` (info + servers) with
788
+ * an optional `docs` sub-config that opts the deployment into mounting
789
+ * an interactive Scalar-rendered API reference UI alongside the JSON
790
+ * spec at `/v1/openapi.json`.
791
+ *
792
+ * `docs` is opt-in (default off). Deployments that want the docs UI set
793
+ * `docs: true` (mounts at `/docs`) or `docs: { path: '/reference' }` for
794
+ * a custom mount path.
795
+ */
796
+ export interface OpenApiConfig extends GenerateOptions {
797
+ /**
798
+ * When set, mounts a Scalar-rendered interactive API reference UI
799
+ * that reads from `GET /v1/openapi.json`. Pass `true` for defaults
800
+ * (mounted at `/docs`, default theme, page title from the OpenAPI
801
+ * `info.title`) or an object to customize the mount path / title /
802
+ * theme. Absent = docs UI not mounted.
803
+ */
804
+ readonly docs?: boolean | ScalarDocsConfig;
805
+ }
806
+
807
+ /**
808
+ * Session lifecycle configuration. All fields optional; defaults keep
809
+ * the baseline behavior (absolute TTL from the stored session's
810
+ * `expiresAt`, inactivity enforcement disabled). Only applies to
811
+ * `kgi_sk_*` session tokens; static bearer tokens are unaffected.
812
+ * Milliseconds throughout — compared against `Date.now()` on the hot
813
+ * path.
814
+ */
815
+ export interface SessionConfig {
816
+ /**
817
+ * Recommended default for deployment-issued sessions. The framework
818
+ * itself uses the provider's `expiresAt` verbatim on OAuth callback;
819
+ * this default surfaces only when a downstream helper opts into it.
820
+ * 24h = `24 * 60 * 60 * 1000`.
821
+ */
822
+ readonly ttl?: number;
823
+ /**
824
+ * Inactivity timeout — requests whose session `lastActiveAt` is older
825
+ * than `Date.now() - inactivityTimeout` receive `401 session-inactive`.
826
+ * Absent → inactivity enforcement disabled. Recommended: 4 hours.
827
+ */
828
+ readonly inactivityTimeout?: number;
829
+ /**
830
+ * How often the middleware calls `sessionStore.touch()` to bump
831
+ * `lastActiveAt`. Defaults to 60_000 ms. Higher values ⇒ fewer writes
832
+ * but coarser inactivity enforcement.
833
+ */
834
+ readonly touchThrottle?: number;
835
+ }
836
+
837
+ /**
838
+ * Optional overrides for the Scalar-rendered docs UI. All fields are
839
+ * optional; sensible defaults are applied.
840
+ */
841
+ export interface ScalarDocsConfig {
842
+ /** Mount path. Default: `/docs`. */
843
+ readonly path?: string;
844
+ /** Browser tab title. Default: `Kindgi API`. */
845
+ readonly title?: string;
846
+ /**
847
+ * Scalar theme name — string-typed so it stays open to whatever
848
+ * themes Scalar ships without a version-lock. Default: Scalar's
849
+ * built-in default theme.
850
+ */
851
+ readonly theme?: string;
852
+ }
853
+
854
+ export function createApp(input: CreateAppInput): Hono<AppEnv> {
855
+ const app = new Hono<AppEnv>();
856
+
857
+ const runBinding = input.kernelBinding.run;
858
+
859
+ // ---------- global middleware ----------
860
+ app.use('*', requestIdMiddleware());
861
+ // A thrown exception: a 500 wire error with its message and request id.
862
+ app.onError(mapThrownError);
863
+
864
+ // Public run tokens: checked once at startup; CORS for the two routes
865
+ // they can call, ahead of authentication so preflights pass.
866
+ const publicRunTokens = input.publicRunTokens;
867
+ const publicRunTokenLimits =
868
+ publicRunTokens !== undefined ? resolvePublicRunTokenConfig(publicRunTokens) : undefined;
869
+ const mintPublicRunTokenFor = (
870
+ tenantId: import('@kindgi/types').TenantId,
871
+ runIds: readonly import('@kindgi/types').RunId[],
872
+ ttlSeconds: number,
873
+ ) =>
874
+ mintPublicRunToken({
875
+ signingKey: (publicRunTokens as PublicRunTokenConfig).signingKey,
876
+ keyId: (publicRunTokens as PublicRunTokenConfig).keyId,
877
+ tenantId,
878
+ runIds,
879
+ ttlSeconds,
880
+ });
881
+ if (publicRunTokens?.allowedOrigins !== undefined && publicRunTokens.allowedOrigins.length > 0) {
882
+ app.use('/v1/*', publicRunCorsMiddleware(publicRunTokens.allowedOrigins));
883
+ }
884
+
885
+ // ---------- public routes ----------
886
+ app.get('/health', (c) => c.json({ ok: true }));
887
+ // The spec document is public (per API-ROUTE-CONVENTIONS.md §2.2) so
888
+ // it's mounted before the /v1/* auth chain rather than inside it.
889
+ const openApiDoc = generateOpenApiDocument(input.openapi ?? {});
890
+ app.get('/v1/openapi.json', (c) => c.json(openApiDoc));
891
+
892
+ // Optional Scalar-rendered interactive API reference UI. Opt-in via
893
+ // `openapi.docs`; when absent the docs path is unmounted (404). Also
894
+ // public — the reference reads the (already-public) `/v1/openapi.json`
895
+ // in the browser, so it doesn't need to sit inside the bearer chain.
896
+ if (input.openapi?.docs !== undefined && input.openapi.docs !== false) {
897
+ const docsConfig: ScalarDocsConfig = input.openapi.docs === true ? {} : input.openapi.docs;
898
+ const docsPath = docsConfig.path ?? '/docs';
899
+ app.get(
900
+ docsPath,
901
+ Scalar({
902
+ url: '/v1/openapi.json',
903
+ pageTitle: docsConfig.title ?? 'Kindgi API',
904
+ ...(docsConfig.theme !== undefined && {
905
+ theme: docsConfig.theme as never,
906
+ }),
907
+ }),
908
+ );
909
+ }
910
+
911
+ // ---------- authenticated `/v1/*` routes ----------
912
+ const v1 = new Hono<AppEnv>();
913
+ const sessionCfg = input.session;
914
+ const inactivityTimeoutMs = sessionCfg?.inactivityTimeout;
915
+ v1.use(
916
+ '*',
917
+ bearerAuthMiddleware(input.resolveToken, {
918
+ ...(publicRunTokens !== undefined && {
919
+ publicRunTokens: {
920
+ signingKey: publicRunTokens.signingKey,
921
+ isAllowed: publicRunRouteMatcher(),
922
+ },
923
+ }),
924
+ ...(input.sessionStore !== undefined && { sessionStore: input.sessionStore }),
925
+ ...(inactivityTimeoutMs !== undefined && { inactivityTimeoutMs }),
926
+ ...(sessionCfg?.touchThrottle !== undefined && {
927
+ touchThrottleMs: sessionCfg.touchThrottle,
928
+ }),
929
+ }),
930
+ );
931
+ // Principal construction — runs after bearer so it can read the
932
+ // resolved tenantId/userId/sessionId. If `authz` is not configured,
933
+ // still populate the principal (cheap, and lets `can`/`check` work
934
+ // as inspection helpers even when authorize() enforcement is off).
935
+ v1.use('*', principalMiddleware());
936
+ const authorizer: Authorizer | undefined =
937
+ input.authz !== undefined ? createAuthorizer(input.authz.authzCheckBinding) : undefined;
938
+
939
+ const tenantHierarchyBinding: TenantHierarchyBinding = input.tenantHierarchyBinding;
940
+ v1.use('*', idempotencyMiddleware(input.idempotencyStore ?? createInMemoryIdempotencyStore()));
941
+ v1.route(
942
+ '/runs',
943
+ runsRouter(
944
+ input.runHandler,
945
+ runBinding,
946
+ {
947
+ ...(input.eventBus !== undefined && { eventBus: input.eventBus }),
948
+ ...(publicRunTokenLimits !== undefined && {
949
+ publicRunTokens: {
950
+ mint: (tenantId, runIds) =>
951
+ mintPublicRunTokenFor(tenantId, runIds, publicRunTokenLimits.defaultTtlSeconds),
952
+ },
953
+ }),
954
+ },
955
+ authorizer,
956
+ ),
957
+ );
958
+ v1.route('/conversations', conversationsRouter(input.conversationBinding, runBinding));
959
+ if (publicRunTokenLimits !== undefined) {
960
+ v1.route(
961
+ '/tokens/public',
962
+ publicRunTokensRouter(
963
+ runBinding,
964
+ { mint: mintPublicRunTokenFor, ...publicRunTokenLimits },
965
+ authorizer,
966
+ ),
967
+ );
968
+ }
969
+ if (input.tokenAdmin !== undefined) {
970
+ v1.route('/tokens', tokensRouter(input.tokenAdmin, authorizer));
971
+ }
972
+ // Mount the reviewer roster sub-resource BEFORE the approvals router
973
+ // so `/v1/approvals/reviewers/*` resolves here rather than being
974
+ // captured by the `:approvalId` param on the approvals router.
975
+ if (input.reviewerRegistry !== undefined) {
976
+ v1.route('/approvals/reviewers', reviewersRouter(input.reviewerRegistry));
977
+ }
978
+ if (input.reviewerBinding !== undefined && input.hitlBinding !== undefined) {
979
+ v1.route(
980
+ '/approvals',
981
+ approvalsRouter(
982
+ input.conversationBinding,
983
+ input.reviewerBinding,
984
+ input.hitlBinding,
985
+ runBinding,
986
+ {
987
+ ...(input.signingKey !== undefined && { signingKey: input.signingKey }),
988
+ // Inline resume after approval-complete drives
989
+ // completeToken. Passing the runHandler here means the route
990
+ // calls `runHandler.resumeRun(...)` synchronously in the same
991
+ // request so the reviewer's response reflects the resumed run's
992
+ // new state (running / completed / re-suspended).
993
+ runHandler: input.runHandler,
994
+ },
995
+ ),
996
+ );
997
+ }
998
+ if (input.enableObservations === true && input.supervisor !== undefined) {
999
+ v1.route('/observations', observationsRouter(input.supervisor));
1000
+ }
1001
+ if (input.agentRegistry !== undefined) {
1002
+ v1.route('/agents', agentsRouter(input.agentRegistry, authorizer));
1003
+ }
1004
+ if (input.flowRegistry !== undefined) {
1005
+ v1.route('/flows', flowsRouter(input.flowRegistry, authorizer));
1006
+ }
1007
+ if (input.toolRegistry !== undefined) {
1008
+ v1.route('/tools', toolsRouter(input.toolRegistry, authorizer, input.onToolWrite));
1009
+ }
1010
+ if (input.guardrailRegistry !== undefined) {
1011
+ v1.route(
1012
+ '/guardrails',
1013
+ guardrailsRouter(input.guardrailRegistry, authorizer, input.onGuardrailWrite),
1014
+ );
1015
+ }
1016
+ if (input.retention !== undefined) {
1017
+ v1.route('/retention', retentionRouter(input.retention, authorizer));
1018
+ }
1019
+ if (input.memory !== undefined) {
1020
+ v1.route('/memory', memoryRouter(input.memory));
1021
+ }
1022
+ if (input.supervisor !== undefined) {
1023
+ v1.route('/proposals', proposalsRouter(input.supervisor));
1024
+ }
1025
+ v1.route(
1026
+ '/provenance',
1027
+ provenanceRouter(input.provenanceBinding, {
1028
+ conversationBinding: input.conversationBinding,
1029
+ ...(input.signingKey !== undefined && { signingKey: input.signingKey }),
1030
+ }),
1031
+ );
1032
+ if (
1033
+ input.auditEvents !== undefined &&
1034
+ input.complianceClassifier !== undefined &&
1035
+ input.complianceGenerator !== undefined
1036
+ ) {
1037
+ v1.route(
1038
+ '/compliance',
1039
+ complianceRouter({
1040
+ auditEvents: input.auditEvents,
1041
+ classifier: input.complianceClassifier,
1042
+ complianceGenerator: input.complianceGenerator,
1043
+ ...(input.signingKey !== undefined && { signingKey: input.signingKey }),
1044
+ }),
1045
+ );
1046
+ }
1047
+ if (input.blobStorage !== undefined) {
1048
+ v1.route('/artifacts', artifactsRouter(input.blobStorage));
1049
+ }
1050
+ if (input.capabilityRegistry !== undefined) {
1051
+ v1.route('/capabilities', capabilitiesRouter(input.capabilityRegistry));
1052
+ }
1053
+ if (input.providerRegistry !== undefined) {
1054
+ v1.route('/providers', providersRouter(input.providerRegistry, input.onProviderWrite));
1055
+ }
1056
+ if (input.mcpEndpointRegistry !== undefined) {
1057
+ v1.route(
1058
+ '/mcp',
1059
+ mcpRouter(input.mcpEndpointRegistry, input.mcpClientProbe, authorizer, {
1060
+ hostAccess: input.tenantHostAccess ?? 'deployed',
1061
+ }),
1062
+ );
1063
+ }
1064
+ // Identity mounts unconditionally so `/v1/identity/whoami` is always
1065
+ // reachable. `/users/*` routes register only when an
1066
+ // `identityDirectory` binding is provided (deployments without a
1067
+ // directory adapter still get whoami).
1068
+ v1.route(
1069
+ '/identity',
1070
+ identityRouter({
1071
+ ...(input.identityDirectory !== undefined && { directory: input.identityDirectory }),
1072
+ ...(input.sessionStore !== undefined && { sessionStore: input.sessionStore }),
1073
+ }),
1074
+ );
1075
+ if (input.cost !== undefined) {
1076
+ v1.route('/cost', costRouter(input.cost));
1077
+ }
1078
+ if (input.adapterRegistry !== undefined) {
1079
+ v1.route('/adapters', adaptersRouter(input.adapterRegistry, input.adapterFactories));
1080
+ }
1081
+ // Trigger admin surfaces. Three sibling routers over the same
1082
+ // `TriggerRegistryBinding` — each pins its own kind. There is no
1083
+ // external webhook receiver route here (it would need
1084
+ // unauthenticated tenant resolution).
1085
+ if (input.triggerRegistry !== undefined) {
1086
+ v1.route('/schedules', schedulesRouter(input.triggerRegistry));
1087
+ v1.route('/event-triggers', eventTriggersRouter(input.triggerRegistry));
1088
+ v1.route('/webhooks', webhooksRouter(input.triggerRegistry));
1089
+ }
1090
+ if (input.webhookEndpoints !== undefined) {
1091
+ v1.route('/webhook-endpoints', webhookEndpointsRouter(input.webhookEndpoints));
1092
+ }
1093
+ if (input.policyRegistry !== undefined) {
1094
+ v1.route('/policies', policiesRouter(input.policyRegistry));
1095
+ }
1096
+ if (input.evalSuiteRegistry !== undefined) {
1097
+ v1.route('/eval-suites', evalSuitesRouter(input.evalSuiteRegistry, authorizer));
1098
+ }
1099
+ // ---------- platform hierarchy ----------
1100
+ // Mounts are independent: `/v1/orgs`, `/v1/teams`, `/v1/projects`,
1101
+ // `/v1/tenant`. Each requires its own binding. Team + Project
1102
+ // sub-resources (`/memberships`) require both bindings supplied.
1103
+ if (input.orgBinding !== undefined) {
1104
+ v1.route('/orgs', orgsRouter(input.orgBinding, tenantHierarchyBinding, authorizer));
1105
+ }
1106
+ if (input.teamBinding !== undefined && input.teamMembershipBinding !== undefined) {
1107
+ v1.route(
1108
+ '/teams',
1109
+ teamsRouter(
1110
+ input.teamBinding,
1111
+ input.teamMembershipBinding,
1112
+ tenantHierarchyBinding,
1113
+ authorizer,
1114
+ ),
1115
+ );
1116
+ }
1117
+ if (input.projectBinding !== undefined && input.projectMembershipBinding !== undefined) {
1118
+ v1.route(
1119
+ '/projects',
1120
+ projectsRouter(
1121
+ input.projectBinding,
1122
+ input.projectMembershipBinding,
1123
+ tenantHierarchyBinding,
1124
+ authorizer,
1125
+ ),
1126
+ );
1127
+ }
1128
+ // `/v1/tenant` is always mounted (reads the tenant through the
1129
+ // tenant-hierarchy binding);
1130
+ // `/config` sub-routes are gated on the presence of at least one of
1131
+ // `envBinding` / `secretsBinding`.
1132
+ v1.route(
1133
+ '/tenant',
1134
+ tenantRouter({
1135
+ tenantHierarchyBinding: input.tenantHierarchyBinding,
1136
+ ...(input.envBinding !== undefined && { envBinding: input.envBinding }),
1137
+ ...(input.secretsBinding !== undefined && { secretsBinding: input.secretsBinding }),
1138
+ ...(authorizer !== undefined && { authorizer }),
1139
+ }),
1140
+ );
1141
+ // ---------- env + secrets ----------
1142
+ // Dedicated env/secrets HTTP surface. `/v1/env/*` mounts iff
1143
+ // `envBinding` is wired; `/v1/secrets/*` iff `secretsBinding` is
1144
+ // wired. `secretsBinding` also drives the async-rotation status
1145
+ // store — an in-memory reference is used when the caller doesn't
1146
+ // plug in a durable one.
1147
+ if (input.envBinding !== undefined) {
1148
+ v1.route('/env', envRouter(input.envBinding, authorizer));
1149
+ }
1150
+ // Audit query surface. Admin-only PEP applied inside the router
1151
+ // (self-contained; no plumbing here).
1152
+ if (input.auditEvents !== undefined) {
1153
+ v1.route('/audit', auditRouter(input.auditEvents, authorizer));
1154
+ }
1155
+ if (input.secretsBinding !== undefined) {
1156
+ v1.route(
1157
+ '/secrets',
1158
+ secretsRouter({
1159
+ secretsBinding: input.secretsBinding,
1160
+ rotationStatusStore: input.rotationStatusStore ?? createInMemoryRotationStatusStore(),
1161
+ ...(authorizer !== undefined && { authorizer }),
1162
+ }),
1163
+ );
1164
+ }
1165
+ // ---------- deployments ----------
1166
+ // Requires all three of: DeploymentBinding + SigningKeyRegistryBinding +
1167
+ // ImageRegistryBinding. Optional tool/guardrail/agent/flow registries
1168
+ // are threaded through so the atomic transaction upserts primitives
1169
+ // from the deployment's index.json into the same catalogs the SDK
1170
+ // publish surfaces consume — a deploy is just a bulk publish + ledger
1171
+ // record, signed end-to-end.
1172
+ // The trust list `POST /v1/deployments` verifies signers against.
1173
+ // Mounted on its own: a deployment can trust keys before it accepts
1174
+ // deployments.
1175
+ if (input.signingKeyRegistry !== undefined) {
1176
+ v1.route('/signing-keys', signingKeysRouter(input.signingKeyRegistry));
1177
+ }
1178
+ if (
1179
+ input.deploymentRegistry !== undefined &&
1180
+ input.signingKeyRegistry !== undefined &&
1181
+ input.imageRegistry !== undefined
1182
+ ) {
1183
+ v1.route(
1184
+ '/deployments',
1185
+ deploymentsRouter({
1186
+ deploymentRegistry: input.deploymentRegistry,
1187
+ signingKeyRegistry: input.signingKeyRegistry,
1188
+ imageRegistry: input.imageRegistry,
1189
+ ...(input.toolRegistry !== undefined && { toolRegistry: input.toolRegistry }),
1190
+ ...(input.guardrailRegistry !== undefined && {
1191
+ guardrailRegistry: input.guardrailRegistry,
1192
+ }),
1193
+ ...(input.agentRegistry !== undefined && { agentRegistry: input.agentRegistry }),
1194
+ ...(input.flowRegistry !== undefined && { flowRegistry: input.flowRegistry }),
1195
+ // The deployments router's agents publish loop resolves the
1196
+ // Default project through this binding. Optional at wiring so
1197
+ // app compositions without a project binding still boot; the loop
1198
+ // fails fast at runtime if agents are in the deployment index
1199
+ // but the binding is absent.
1200
+ ...(input.projectBinding !== undefined && { projectBinding: input.projectBinding }),
1201
+ // POST /v1/deployments/:deploymentId/secrets needs the
1202
+ // secretsBinding. Absent binding → the route answers 500 with an
1203
+ // operator-actionable message.
1204
+ ...(input.secretsBinding !== undefined && { secretsBinding: input.secretsBinding }),
1205
+ // A deploy registers tools and guardrails: the same cache hooks
1206
+ // `POST /v1/tools` / `POST /v1/guardrails` call.
1207
+ ...(input.onToolWrite !== undefined && { onToolWrite: input.onToolWrite }),
1208
+ ...(input.onGuardrailWrite !== undefined && { onGuardrailWrite: input.onGuardrailWrite }),
1209
+ }),
1210
+ );
1211
+ }
1212
+ if (input.evalRunBinding !== undefined) {
1213
+ // Mount the start route under `/v1/eval-suites/:suiteId/runs` and
1214
+ // the readback surface under `/v1/eval-runs/*`. Both share one
1215
+ // binding — the start-route registration happens even without an
1216
+ // `evalSuiteRegistry` binding: the dispatcher itself surfaces
1217
+ // `suite-not-found` when the caller-plugged binding can't resolve
1218
+ // the suite id, so the API layer stays consumer-neutral.
1219
+ const evalRuns = evalRunsRouters(input.evalRunBinding);
1220
+ v1.route('/eval-suites', evalRuns.start);
1221
+ v1.route('/eval-runs', evalRuns.readback);
1222
+ }
1223
+ // ---------- auth routes ----------
1224
+ // Requires all three bindings: session store + identity-provider
1225
+ // catalog + code exchange. When wired, the authed sub-router mounts
1226
+ // under `/v1/auth/*` (protected by the same bearer chain, so callers
1227
+ // authenticate with either a static bearer or a session token to
1228
+ // reach it), and the callback sub-router mounts OUTSIDE the bearer
1229
+ // chain at `/v1/auth/callback/*` because the redirect from the
1230
+ // provider carries no framework token yet.
1231
+ if (
1232
+ input.sessionStore !== undefined &&
1233
+ input.identityProvider !== undefined &&
1234
+ input.exchangeCode !== undefined
1235
+ ) {
1236
+ const routers = authRouters({
1237
+ sessionStore: input.sessionStore,
1238
+ identityProvider: input.identityProvider,
1239
+ exchangeCode: input.exchangeCode,
1240
+ ...(input.refreshToken !== undefined && { refreshToken: input.refreshToken }),
1241
+ stateStore: input.oauthStateStore ?? createInMemoryOauthStateStore(),
1242
+ });
1243
+ v1.route('/auth', routers.authed);
1244
+ // Callback mounts on the parent `app` under /v1/auth/callback so it
1245
+ // bypasses the bearer chain. The v1 router's use('*', bearer) has
1246
+ // already been installed above, so we mount at the parent scope.
1247
+ app.route('/v1/auth/callback', routers.callback);
1248
+ }
1249
+ app.route('/v1', v1);
1250
+
1251
+ // ---------- S3-compat surface (/s3/*, SigV4 auth) ----------
1252
+ // Mounted OUTSIDE the /v1/* Bearer chain — S3 clients authenticate
1253
+ // with SigV4, not bearer tokens. Requires both a resolved
1254
+ // `blobStorage` binding (storage) and an `s3Credentials` binding
1255
+ // (auth); omitting either leaves /s3/* unmounted (Hono 404).
1256
+ if (input.blobStorage !== undefined && input.s3Credentials !== undefined) {
1257
+ const s3 = new Hono<AppEnv>();
1258
+ s3.use('*', sigv4Middleware(input.s3Credentials));
1259
+ s3.route('/', s3Router(input.blobStorage));
1260
+ app.route('/s3', s3);
1261
+ }
1262
+
1263
+ // Terminal 404 handler — every unmatched route returns the standard
1264
+ // `{ error: { code, message, requestId } }` envelope instead of Hono's
1265
+ // plaintext default. Rationale: routes mount conditionally on optional
1266
+ // bindings (e.g. `secretsBinding`, `blobStorage`), so "route not
1267
+ // registered" is a routine caller-facing outcome, not a bug. Serving a
1268
+ // naked 404 makes SDKs report "HTTP 404 without recognizable error
1269
+ // envelope", which reads as a bug at the SDK layer when the real
1270
+ // signal is "this deployment didn't wire that binding." The
1271
+ // `requestIdMiddleware` above runs for unmatched paths too, so the
1272
+ // id is always available.
1273
+ app.notFound((c) => {
1274
+ const requestId = (c.get('requestId') as string | undefined) ?? 'req-unknown';
1275
+ const body: WireErrorBody = {
1276
+ error: {
1277
+ code: 'route-not-found',
1278
+ message: `No route registered for ${c.req.method} ${c.req.path}. If this endpoint is expected, verify the deployment wired the required binding.`,
1279
+ requestId,
1280
+ },
1281
+ };
1282
+ return c.json(body, 404);
1283
+ });
1284
+
1285
+ return app;
1286
+ }