@kindgi/api 0.0.0-bootstrap.0 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (505) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +216 -1
  3. package/dist/adapter-binding.d.ts +177 -0
  4. package/dist/adapter-binding.d.ts.map +1 -0
  5. package/dist/adapter-binding.js +12 -0
  6. package/dist/adapter-binding.js.map +1 -0
  7. package/dist/agent-binding.d.ts +207 -0
  8. package/dist/agent-binding.d.ts.map +1 -0
  9. package/dist/agent-binding.js +4 -0
  10. package/dist/agent-binding.js.map +1 -0
  11. package/dist/app.d.ts +770 -0
  12. package/dist/app.d.ts.map +1 -0
  13. package/dist/app.js +396 -0
  14. package/dist/app.js.map +1 -0
  15. package/dist/capability-binding.d.ts +76 -0
  16. package/dist/capability-binding.d.ts.map +1 -0
  17. package/dist/capability-binding.js +4 -0
  18. package/dist/capability-binding.js.map +1 -0
  19. package/dist/cost-binding.d.ts +175 -0
  20. package/dist/cost-binding.d.ts.map +1 -0
  21. package/dist/cost-binding.js +13 -0
  22. package/dist/cost-binding.js.map +1 -0
  23. package/dist/deployment-binding.d.ts +201 -0
  24. package/dist/deployment-binding.d.ts.map +1 -0
  25. package/dist/deployment-binding.js +4 -0
  26. package/dist/deployment-binding.js.map +1 -0
  27. package/dist/env-binding.d.ts +132 -0
  28. package/dist/env-binding.d.ts.map +1 -0
  29. package/dist/env-binding.js +4 -0
  30. package/dist/env-binding.js.map +1 -0
  31. package/dist/errors.d.ts +37 -0
  32. package/dist/errors.d.ts.map +1 -0
  33. package/dist/errors.js +264 -0
  34. package/dist/errors.js.map +1 -0
  35. package/dist/eval-run-binding.d.ts +196 -0
  36. package/dist/eval-run-binding.d.ts.map +1 -0
  37. package/dist/eval-run-binding.js +16 -0
  38. package/dist/eval-run-binding.js.map +1 -0
  39. package/dist/eval-run-dispatcher.d.ts +131 -0
  40. package/dist/eval-run-dispatcher.d.ts.map +1 -0
  41. package/dist/eval-run-dispatcher.js +368 -0
  42. package/dist/eval-run-dispatcher.js.map +1 -0
  43. package/dist/eval-suite-binding.d.ts +227 -0
  44. package/dist/eval-suite-binding.d.ts.map +1 -0
  45. package/dist/eval-suite-binding.js +24 -0
  46. package/dist/eval-suite-binding.js.map +1 -0
  47. package/dist/event-bus-binding.d.ts +107 -0
  48. package/dist/event-bus-binding.d.ts.map +1 -0
  49. package/dist/event-bus-binding.js +5 -0
  50. package/dist/event-bus-binding.js.map +1 -0
  51. package/dist/flow-binding.d.ts +194 -0
  52. package/dist/flow-binding.d.ts.map +1 -0
  53. package/dist/flow-binding.js +4 -0
  54. package/dist/flow-binding.js.map +1 -0
  55. package/dist/guardrail-binding.d.ts +138 -0
  56. package/dist/guardrail-binding.d.ts.map +1 -0
  57. package/dist/guardrail-binding.js +4 -0
  58. package/dist/guardrail-binding.js.map +1 -0
  59. package/dist/handler-binding.d.ts +126 -0
  60. package/dist/handler-binding.d.ts.map +1 -0
  61. package/dist/handler-binding.js +4 -0
  62. package/dist/handler-binding.js.map +1 -0
  63. package/dist/hitl-binding.d.ts +115 -0
  64. package/dist/hitl-binding.d.ts.map +1 -0
  65. package/dist/hitl-binding.js +4 -0
  66. package/dist/hitl-binding.js.map +1 -0
  67. package/dist/identity-directory-binding.d.ts +116 -0
  68. package/dist/identity-directory-binding.d.ts.map +1 -0
  69. package/dist/identity-directory-binding.js +4 -0
  70. package/dist/identity-directory-binding.js.map +1 -0
  71. package/dist/identity-provider-binding.d.ts +184 -0
  72. package/dist/identity-provider-binding.d.ts.map +1 -0
  73. package/dist/identity-provider-binding.js +4 -0
  74. package/dist/identity-provider-binding.js.map +1 -0
  75. package/dist/image-registry-binding.d.ts +165 -0
  76. package/dist/image-registry-binding.d.ts.map +1 -0
  77. package/dist/image-registry-binding.js +4 -0
  78. package/dist/image-registry-binding.js.map +1 -0
  79. package/dist/index.d.ts +72 -0
  80. package/dist/index.d.ts.map +1 -0
  81. package/dist/index.js +26 -0
  82. package/dist/index.js.map +1 -0
  83. package/dist/key-management-binding.d.ts +101 -0
  84. package/dist/key-management-binding.d.ts.map +1 -0
  85. package/dist/key-management-binding.js +4 -0
  86. package/dist/key-management-binding.js.map +1 -0
  87. package/dist/mcp-endpoint-binding.d.ts +312 -0
  88. package/dist/mcp-endpoint-binding.d.ts.map +1 -0
  89. package/dist/mcp-endpoint-binding.js +12 -0
  90. package/dist/mcp-endpoint-binding.js.map +1 -0
  91. package/dist/memory-binding.d.ts +209 -0
  92. package/dist/memory-binding.d.ts.map +1 -0
  93. package/dist/memory-binding.js +4 -0
  94. package/dist/memory-binding.js.map +1 -0
  95. package/dist/middleware/auth.d.ts +168 -0
  96. package/dist/middleware/auth.d.ts.map +1 -0
  97. package/dist/middleware/auth.js +247 -0
  98. package/dist/middleware/auth.js.map +1 -0
  99. package/dist/middleware/authorize.d.ts +26 -0
  100. package/dist/middleware/authorize.d.ts.map +1 -0
  101. package/dist/middleware/authorize.js +65 -0
  102. package/dist/middleware/authorize.js.map +1 -0
  103. package/dist/middleware/error-mapper.d.ts +13 -0
  104. package/dist/middleware/error-mapper.d.ts.map +1 -0
  105. package/dist/middleware/error-mapper.js +32 -0
  106. package/dist/middleware/error-mapper.js.map +1 -0
  107. package/dist/middleware/idempotency.d.ts +43 -0
  108. package/dist/middleware/idempotency.d.ts.map +1 -0
  109. package/dist/middleware/idempotency.js +118 -0
  110. package/dist/middleware/idempotency.js.map +1 -0
  111. package/dist/middleware/principal.d.ts +4 -0
  112. package/dist/middleware/principal.d.ts.map +1 -0
  113. package/dist/middleware/principal.js +42 -0
  114. package/dist/middleware/principal.js.map +1 -0
  115. package/dist/middleware/public-run-routes.d.ts +16 -0
  116. package/dist/middleware/public-run-routes.d.ts.map +1 -0
  117. package/dist/middleware/public-run-routes.js +43 -0
  118. package/dist/middleware/public-run-routes.js.map +1 -0
  119. package/dist/middleware/request-id.d.ts +14 -0
  120. package/dist/middleware/request-id.d.ts.map +1 -0
  121. package/dist/middleware/request-id.js +24 -0
  122. package/dist/middleware/request-id.js.map +1 -0
  123. package/dist/middleware/sigv4-verify.d.ts +64 -0
  124. package/dist/middleware/sigv4-verify.d.ts.map +1 -0
  125. package/dist/middleware/sigv4-verify.js +286 -0
  126. package/dist/middleware/sigv4-verify.js.map +1 -0
  127. package/dist/middleware/sigv4.d.ts +25 -0
  128. package/dist/middleware/sigv4.d.ts.map +1 -0
  129. package/dist/middleware/sigv4.js +120 -0
  130. package/dist/middleware/sigv4.js.map +1 -0
  131. package/dist/openapi/generate.d.ts +15 -0
  132. package/dist/openapi/generate.d.ts.map +1 -0
  133. package/dist/openapi/generate.js +241 -0
  134. package/dist/openapi/generate.js.map +1 -0
  135. package/dist/openapi/operations.d.ts +70 -0
  136. package/dist/openapi/operations.d.ts.map +1 -0
  137. package/dist/openapi/operations.js +5051 -0
  138. package/dist/openapi/operations.js.map +1 -0
  139. package/dist/openapi/schemas.d.ts +590 -0
  140. package/dist/openapi/schemas.d.ts.map +1 -0
  141. package/dist/openapi/schemas.js +5820 -0
  142. package/dist/openapi/schemas.js.map +1 -0
  143. package/dist/provenance-binding.d.ts +116 -0
  144. package/dist/provenance-binding.d.ts.map +1 -0
  145. package/dist/provenance-binding.js +31 -0
  146. package/dist/provenance-binding.js.map +1 -0
  147. package/dist/provider-binding.d.ts +174 -0
  148. package/dist/provider-binding.d.ts.map +1 -0
  149. package/dist/provider-binding.js +4 -0
  150. package/dist/provider-binding.js.map +1 -0
  151. package/dist/public-run-token.d.ts +97 -0
  152. package/dist/public-run-token.d.ts.map +1 -0
  153. package/dist/public-run-token.js +167 -0
  154. package/dist/public-run-token.js.map +1 -0
  155. package/dist/retention-binding.d.ts +69 -0
  156. package/dist/retention-binding.d.ts.map +1 -0
  157. package/dist/retention-binding.js +4 -0
  158. package/dist/retention-binding.js.map +1 -0
  159. package/dist/reviewer-binding.d.ts +84 -0
  160. package/dist/reviewer-binding.d.ts.map +1 -0
  161. package/dist/reviewer-binding.js +4 -0
  162. package/dist/reviewer-binding.js.map +1 -0
  163. package/dist/rotation-status-store.d.ts +96 -0
  164. package/dist/rotation-status-store.d.ts.map +1 -0
  165. package/dist/rotation-status-store.js +106 -0
  166. package/dist/rotation-status-store.js.map +1 -0
  167. package/dist/routes/adapters.d.ts +29 -0
  168. package/dist/routes/adapters.d.ts.map +1 -0
  169. package/dist/routes/adapters.js +230 -0
  170. package/dist/routes/adapters.js.map +1 -0
  171. package/dist/routes/agents.d.ts +17 -0
  172. package/dist/routes/agents.d.ts.map +1 -0
  173. package/dist/routes/agents.js +342 -0
  174. package/dist/routes/agents.js.map +1 -0
  175. package/dist/routes/approvals.d.ts +37 -0
  176. package/dist/routes/approvals.d.ts.map +1 -0
  177. package/dist/routes/approvals.js +551 -0
  178. package/dist/routes/approvals.js.map +1 -0
  179. package/dist/routes/artifacts.d.ts +25 -0
  180. package/dist/routes/artifacts.d.ts.map +1 -0
  181. package/dist/routes/artifacts.js +265 -0
  182. package/dist/routes/artifacts.js.map +1 -0
  183. package/dist/routes/audit.d.ts +6 -0
  184. package/dist/routes/audit.d.ts.map +1 -0
  185. package/dist/routes/audit.js +162 -0
  186. package/dist/routes/audit.js.map +1 -0
  187. package/dist/routes/auth.d.ts +47 -0
  188. package/dist/routes/auth.d.ts.map +1 -0
  189. package/dist/routes/auth.js +630 -0
  190. package/dist/routes/auth.js.map +1 -0
  191. package/dist/routes/capabilities.d.ts +14 -0
  192. package/dist/routes/capabilities.d.ts.map +1 -0
  193. package/dist/routes/capabilities.js +62 -0
  194. package/dist/routes/capabilities.js.map +1 -0
  195. package/dist/routes/compliance.d.ts +37 -0
  196. package/dist/routes/compliance.d.ts.map +1 -0
  197. package/dist/routes/compliance.js +321 -0
  198. package/dist/routes/compliance.js.map +1 -0
  199. package/dist/routes/conversations.d.ts +13 -0
  200. package/dist/routes/conversations.d.ts.map +1 -0
  201. package/dist/routes/conversations.js +295 -0
  202. package/dist/routes/conversations.js.map +1 -0
  203. package/dist/routes/cost.d.ts +24 -0
  204. package/dist/routes/cost.d.ts.map +1 -0
  205. package/dist/routes/cost.js +243 -0
  206. package/dist/routes/cost.js.map +1 -0
  207. package/dist/routes/deployments.d.ts +122 -0
  208. package/dist/routes/deployments.d.ts.map +1 -0
  209. package/dist/routes/deployments.js +1036 -0
  210. package/dist/routes/deployments.js.map +1 -0
  211. package/dist/routes/env.d.ts +62 -0
  212. package/dist/routes/env.d.ts.map +1 -0
  213. package/dist/routes/env.js +311 -0
  214. package/dist/routes/env.js.map +1 -0
  215. package/dist/routes/eval-runs.d.ts +28 -0
  216. package/dist/routes/eval-runs.d.ts.map +1 -0
  217. package/dist/routes/eval-runs.js +479 -0
  218. package/dist/routes/eval-runs.js.map +1 -0
  219. package/dist/routes/eval-suites.d.ts +24 -0
  220. package/dist/routes/eval-suites.d.ts.map +1 -0
  221. package/dist/routes/eval-suites.js +381 -0
  222. package/dist/routes/eval-suites.js.map +1 -0
  223. package/dist/routes/event-triggers.d.ts +12 -0
  224. package/dist/routes/event-triggers.d.ts.map +1 -0
  225. package/dist/routes/event-triggers.js +218 -0
  226. package/dist/routes/event-triggers.js.map +1 -0
  227. package/dist/routes/flows.d.ts +23 -0
  228. package/dist/routes/flows.d.ts.map +1 -0
  229. package/dist/routes/flows.js +344 -0
  230. package/dist/routes/flows.js.map +1 -0
  231. package/dist/routes/guardrails.d.ts +33 -0
  232. package/dist/routes/guardrails.d.ts.map +1 -0
  233. package/dist/routes/guardrails.js +236 -0
  234. package/dist/routes/guardrails.js.map +1 -0
  235. package/dist/routes/identity.d.ts +39 -0
  236. package/dist/routes/identity.d.ts.map +1 -0
  237. package/dist/routes/identity.js +138 -0
  238. package/dist/routes/identity.js.map +1 -0
  239. package/dist/routes/mcp.d.ts +23 -0
  240. package/dist/routes/mcp.d.ts.map +1 -0
  241. package/dist/routes/mcp.js +727 -0
  242. package/dist/routes/mcp.js.map +1 -0
  243. package/dist/routes/memory.d.ts +16 -0
  244. package/dist/routes/memory.d.ts.map +1 -0
  245. package/dist/routes/memory.js +353 -0
  246. package/dist/routes/memory.js.map +1 -0
  247. package/dist/routes/observations.d.ts +19 -0
  248. package/dist/routes/observations.d.ts.map +1 -0
  249. package/dist/routes/observations.js +135 -0
  250. package/dist/routes/observations.js.map +1 -0
  251. package/dist/routes/orgs.d.ts +24 -0
  252. package/dist/routes/orgs.d.ts.map +1 -0
  253. package/dist/routes/orgs.js +208 -0
  254. package/dist/routes/orgs.js.map +1 -0
  255. package/dist/routes/pagination.d.ts +18 -0
  256. package/dist/routes/pagination.d.ts.map +1 -0
  257. package/dist/routes/pagination.js +35 -0
  258. package/dist/routes/pagination.js.map +1 -0
  259. package/dist/routes/policies.d.ts +23 -0
  260. package/dist/routes/policies.d.ts.map +1 -0
  261. package/dist/routes/policies.js +314 -0
  262. package/dist/routes/policies.js.map +1 -0
  263. package/dist/routes/projects.d.ts +45 -0
  264. package/dist/routes/projects.d.ts.map +1 -0
  265. package/dist/routes/projects.js +485 -0
  266. package/dist/routes/projects.js.map +1 -0
  267. package/dist/routes/proposals.d.ts +24 -0
  268. package/dist/routes/proposals.d.ts.map +1 -0
  269. package/dist/routes/proposals.js +581 -0
  270. package/dist/routes/proposals.js.map +1 -0
  271. package/dist/routes/provenance.d.ts +34 -0
  272. package/dist/routes/provenance.d.ts.map +1 -0
  273. package/dist/routes/provenance.js +274 -0
  274. package/dist/routes/provenance.js.map +1 -0
  275. package/dist/routes/providers.d.ts +32 -0
  276. package/dist/routes/providers.d.ts.map +1 -0
  277. package/dist/routes/providers.js +490 -0
  278. package/dist/routes/providers.js.map +1 -0
  279. package/dist/routes/public-run-tokens.d.ts +17 -0
  280. package/dist/routes/public-run-tokens.d.ts.map +1 -0
  281. package/dist/routes/public-run-tokens.js +69 -0
  282. package/dist/routes/public-run-tokens.js.map +1 -0
  283. package/dist/routes/retention.d.ts +19 -0
  284. package/dist/routes/retention.d.ts.map +1 -0
  285. package/dist/routes/retention.js +152 -0
  286. package/dist/routes/retention.js.map +1 -0
  287. package/dist/routes/reviewers.d.ts +5 -0
  288. package/dist/routes/reviewers.d.ts.map +1 -0
  289. package/dist/routes/reviewers.js +161 -0
  290. package/dist/routes/reviewers.js.map +1 -0
  291. package/dist/routes/runs.d.ts +34 -0
  292. package/dist/routes/runs.d.ts.map +1 -0
  293. package/dist/routes/runs.js +773 -0
  294. package/dist/routes/runs.js.map +1 -0
  295. package/dist/routes/s3.d.ts +31 -0
  296. package/dist/routes/s3.d.ts.map +1 -0
  297. package/dist/routes/s3.js +433 -0
  298. package/dist/routes/s3.js.map +1 -0
  299. package/dist/routes/schedules.d.ts +20 -0
  300. package/dist/routes/schedules.d.ts.map +1 -0
  301. package/dist/routes/schedules.js +234 -0
  302. package/dist/routes/schedules.js.map +1 -0
  303. package/dist/routes/scope-params.d.ts +57 -0
  304. package/dist/routes/scope-params.d.ts.map +1 -0
  305. package/dist/routes/scope-params.js +105 -0
  306. package/dist/routes/scope-params.js.map +1 -0
  307. package/dist/routes/secret-ref.d.ts +20 -0
  308. package/dist/routes/secret-ref.d.ts.map +1 -0
  309. package/dist/routes/secret-ref.js +42 -0
  310. package/dist/routes/secret-ref.js.map +1 -0
  311. package/dist/routes/secrets.d.ts +53 -0
  312. package/dist/routes/secrets.d.ts.map +1 -0
  313. package/dist/routes/secrets.js +715 -0
  314. package/dist/routes/secrets.js.map +1 -0
  315. package/dist/routes/signing-keys.d.ts +23 -0
  316. package/dist/routes/signing-keys.d.ts.map +1 -0
  317. package/dist/routes/signing-keys.js +212 -0
  318. package/dist/routes/signing-keys.js.map +1 -0
  319. package/dist/routes/sse.d.ts +58 -0
  320. package/dist/routes/sse.d.ts.map +1 -0
  321. package/dist/routes/sse.js +92 -0
  322. package/dist/routes/sse.js.map +1 -0
  323. package/dist/routes/teams.d.ts +30 -0
  324. package/dist/routes/teams.d.ts.map +1 -0
  325. package/dist/routes/teams.js +443 -0
  326. package/dist/routes/teams.js.map +1 -0
  327. package/dist/routes/tenant.d.ts +57 -0
  328. package/dist/routes/tenant.d.ts.map +1 -0
  329. package/dist/routes/tenant.js +352 -0
  330. package/dist/routes/tenant.js.map +1 -0
  331. package/dist/routes/tokens.d.ts +14 -0
  332. package/dist/routes/tokens.d.ts.map +1 -0
  333. package/dist/routes/tokens.js +231 -0
  334. package/dist/routes/tokens.js.map +1 -0
  335. package/dist/routes/tools.d.ts +33 -0
  336. package/dist/routes/tools.d.ts.map +1 -0
  337. package/dist/routes/tools.js +380 -0
  338. package/dist/routes/tools.js.map +1 -0
  339. package/dist/routes/webhook-endpoints.d.ts +10 -0
  340. package/dist/routes/webhook-endpoints.d.ts.map +1 -0
  341. package/dist/routes/webhook-endpoints.js +407 -0
  342. package/dist/routes/webhook-endpoints.js.map +1 -0
  343. package/dist/routes/webhooks.d.ts +21 -0
  344. package/dist/routes/webhooks.d.ts.map +1 -0
  345. package/dist/routes/webhooks.js +228 -0
  346. package/dist/routes/webhooks.js.map +1 -0
  347. package/dist/s3-credential-binding.d.ts +54 -0
  348. package/dist/s3-credential-binding.d.ts.map +1 -0
  349. package/dist/s3-credential-binding.js +4 -0
  350. package/dist/s3-credential-binding.js.map +1 -0
  351. package/dist/secrets-binding.d.ts +281 -0
  352. package/dist/secrets-binding.d.ts.map +1 -0
  353. package/dist/secrets-binding.js +10 -0
  354. package/dist/secrets-binding.js.map +1 -0
  355. package/dist/secrets-provider-binding.d.ts +164 -0
  356. package/dist/secrets-provider-binding.d.ts.map +1 -0
  357. package/dist/secrets-provider-binding.js +4 -0
  358. package/dist/secrets-provider-binding.js.map +1 -0
  359. package/dist/session-store-binding.d.ts +148 -0
  360. package/dist/session-store-binding.d.ts.map +1 -0
  361. package/dist/session-store-binding.js +4 -0
  362. package/dist/session-store-binding.js.map +1 -0
  363. package/dist/signing-key-binding.d.ts +210 -0
  364. package/dist/signing-key-binding.d.ts.map +1 -0
  365. package/dist/signing-key-binding.js +4 -0
  366. package/dist/signing-key-binding.js.map +1 -0
  367. package/dist/state-store-binding.d.ts +53 -0
  368. package/dist/state-store-binding.d.ts.map +1 -0
  369. package/dist/state-store-binding.js +38 -0
  370. package/dist/state-store-binding.js.map +1 -0
  371. package/dist/supervisor-binding.d.ts +526 -0
  372. package/dist/supervisor-binding.d.ts.map +1 -0
  373. package/dist/supervisor-binding.js +4 -0
  374. package/dist/supervisor-binding.js.map +1 -0
  375. package/dist/tenant-host-access.d.ts +41 -0
  376. package/dist/tenant-host-access.d.ts.map +1 -0
  377. package/dist/tenant-host-access.js +42 -0
  378. package/dist/tenant-host-access.js.map +1 -0
  379. package/dist/token-admin.d.ts +99 -0
  380. package/dist/token-admin.d.ts.map +1 -0
  381. package/dist/token-admin.js +4 -0
  382. package/dist/token-admin.js.map +1 -0
  383. package/dist/tool-binding.d.ts +247 -0
  384. package/dist/tool-binding.d.ts.map +1 -0
  385. package/dist/tool-binding.js +4 -0
  386. package/dist/tool-binding.js.map +1 -0
  387. package/dist/trigger-binding.d.ts +13 -0
  388. package/dist/trigger-binding.d.ts.map +1 -0
  389. package/dist/trigger-binding.js +4 -0
  390. package/dist/trigger-binding.js.map +1 -0
  391. package/dist/types.d.ts +71 -0
  392. package/dist/types.d.ts.map +1 -0
  393. package/dist/types.js +4 -0
  394. package/dist/types.js.map +1 -0
  395. package/dist/webhook-endpoint-binding.d.ts +230 -0
  396. package/dist/webhook-endpoint-binding.d.ts.map +1 -0
  397. package/dist/webhook-endpoint-binding.js +12 -0
  398. package/dist/webhook-endpoint-binding.js.map +1 -0
  399. package/dist/xml.d.ts +79 -0
  400. package/dist/xml.d.ts.map +1 -0
  401. package/dist/xml.js +115 -0
  402. package/dist/xml.js.map +1 -0
  403. package/openapi.json +29659 -0
  404. package/package.json +76 -4
  405. package/scripts/emit-openapi.mjs +44 -0
  406. package/src/adapter-binding.ts +204 -0
  407. package/src/agent-binding.ts +231 -0
  408. package/src/app.ts +1285 -0
  409. package/src/capability-binding.ts +83 -0
  410. package/src/cost-binding.ts +213 -0
  411. package/src/deployment-binding.ts +225 -0
  412. package/src/env-binding.ts +140 -0
  413. package/src/errors.ts +291 -0
  414. package/src/eval-run-binding.ts +209 -0
  415. package/src/eval-run-dispatcher.ts +497 -0
  416. package/src/eval-suite-binding.ts +257 -0
  417. package/src/event-bus-binding.ts +127 -0
  418. package/src/flow-binding.ts +213 -0
  419. package/src/guardrail-binding.ts +151 -0
  420. package/src/handler-binding.ts +132 -0
  421. package/src/hitl-binding.ts +172 -0
  422. package/src/identity-directory-binding.ts +128 -0
  423. package/src/identity-provider-binding.ts +203 -0
  424. package/src/image-registry-binding.ts +193 -0
  425. package/src/index.ts +606 -0
  426. package/src/key-management-binding.ts +91 -0
  427. package/src/mcp-endpoint-binding.ts +311 -0
  428. package/src/memory-binding.ts +239 -0
  429. package/src/middleware/auth.ts +437 -0
  430. package/src/middleware/authorize.ts +125 -0
  431. package/src/middleware/error-mapper.ts +37 -0
  432. package/src/middleware/idempotency.ts +160 -0
  433. package/src/middleware/principal.ts +64 -0
  434. package/src/middleware/public-run-routes.ts +50 -0
  435. package/src/middleware/request-id.ts +28 -0
  436. package/src/middleware/sigv4-verify.ts +374 -0
  437. package/src/middleware/sigv4.ts +165 -0
  438. package/src/openapi/generate.ts +307 -0
  439. package/src/openapi/operations.ts +5445 -0
  440. package/src/openapi/schemas.ts +6363 -0
  441. package/src/provenance-binding.ts +169 -0
  442. package/src/provider-binding.ts +196 -0
  443. package/src/public-run-token.ts +263 -0
  444. package/src/retention-binding.ts +78 -0
  445. package/src/reviewer-binding.ts +99 -0
  446. package/src/rotation-status-store.ts +209 -0
  447. package/src/routes/adapters.ts +319 -0
  448. package/src/routes/agents.ts +424 -0
  449. package/src/routes/approvals.ts +759 -0
  450. package/src/routes/artifacts.ts +317 -0
  451. package/src/routes/audit.ts +219 -0
  452. package/src/routes/auth.ts +806 -0
  453. package/src/routes/capabilities.ts +79 -0
  454. package/src/routes/compliance.ts +482 -0
  455. package/src/routes/conversations.ts +369 -0
  456. package/src/routes/cost.ts +327 -0
  457. package/src/routes/deployments.ts +1493 -0
  458. package/src/routes/env.ts +429 -0
  459. package/src/routes/eval-runs.ts +631 -0
  460. package/src/routes/eval-suites.ts +490 -0
  461. package/src/routes/event-triggers.ts +283 -0
  462. package/src/routes/flows.ts +423 -0
  463. package/src/routes/guardrails.ts +320 -0
  464. package/src/routes/identity.ts +203 -0
  465. package/src/routes/mcp.ts +940 -0
  466. package/src/routes/memory.ts +430 -0
  467. package/src/routes/observations.ts +175 -0
  468. package/src/routes/orgs.ts +273 -0
  469. package/src/routes/pagination.ts +51 -0
  470. package/src/routes/policies.ts +413 -0
  471. package/src/routes/projects.ts +634 -0
  472. package/src/routes/proposals.ts +719 -0
  473. package/src/routes/provenance.ts +406 -0
  474. package/src/routes/providers.ts +624 -0
  475. package/src/routes/public-run-tokens.ts +104 -0
  476. package/src/routes/retention.ts +193 -0
  477. package/src/routes/reviewers.ts +209 -0
  478. package/src/routes/runs.ts +981 -0
  479. package/src/routes/s3.ts +519 -0
  480. package/src/routes/schedules.ts +300 -0
  481. package/src/routes/scope-params.ts +133 -0
  482. package/src/routes/secret-ref.ts +52 -0
  483. package/src/routes/secrets.ts +975 -0
  484. package/src/routes/signing-keys.ts +259 -0
  485. package/src/routes/sse.ts +148 -0
  486. package/src/routes/teams.ts +584 -0
  487. package/src/routes/tenant.ts +530 -0
  488. package/src/routes/tokens.ts +285 -0
  489. package/src/routes/tools.ts +491 -0
  490. package/src/routes/webhook-endpoints.ts +534 -0
  491. package/src/routes/webhooks.ts +296 -0
  492. package/src/s3-credential-binding.ts +58 -0
  493. package/src/secrets-binding.ts +308 -0
  494. package/src/secrets-provider-binding.ts +167 -0
  495. package/src/session-store-binding.ts +163 -0
  496. package/src/signing-key-binding.ts +235 -0
  497. package/src/state-store-binding.ts +84 -0
  498. package/src/supervisor-binding.ts +554 -0
  499. package/src/tenant-host-access.ts +62 -0
  500. package/src/token-admin.ts +104 -0
  501. package/src/tool-binding.ts +274 -0
  502. package/src/trigger-binding.ts +38 -0
  503. package/src/types.ts +74 -0
  504. package/src/webhook-endpoint-binding.ts +246 -0
  505. package/src/xml.ts +196 -0
@@ -0,0 +1,246 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // Copyright (C) 2026 Kindgi Inc.
3
+
4
+ import type {
5
+ Cursor,
6
+ EnvName,
7
+ ProjectId,
8
+ RunId,
9
+ TenantId,
10
+ Timestamp,
11
+ WebhookDeliveryId,
12
+ WebhookEndpointId,
13
+ WebhookEventId,
14
+ } from '@kindgi/types';
15
+
16
+ /**
17
+ * Outbound webhook endpoints: URLs the platform sends signed events to,
18
+ * such as `run.finished` when a run completes, fails or is cancelled.
19
+ * The inverse of `/v1/webhooks`, which are inbound triggers.
20
+ *
21
+ * Caller-plugged: the runtime owns storage, secrets, the delivery queue
22
+ * and the HTTP sender. This package defines the contract and the wire
23
+ * shapes, and mounts `/v1/webhook-endpoints` when a binding is supplied.
24
+ *
25
+ * **Secrets.** An endpoint's signing secret is shared with the receiver,
26
+ * so it lives where the deployment's other secrets do: the endpoint holds
27
+ * a reference (`secretRef`, like a provider's `secret_ref`), never the
28
+ * value. The caller stores the secret first (its own `.env` in
29
+ * development, the secrets store in production; `generate-secret` makes
30
+ * a strong one) and registers the endpoint with its name. The binding
31
+ * resolves it at tenant scope to sign each delivery, and checks on
32
+ * create and update that it exists and is strong (`whsec_` + base64 of
33
+ * at least 24 bytes, or the bare base64). Rotating is rotating that
34
+ * secret; while a store keeps the previous version, deliveries carry a
35
+ * signature for each version less than a day old. Deliveries are signed
36
+ * per `@kindgi/crypto` `signWebhook`; receivers verify with
37
+ * `verifyWebhook` or any Standard Webhooks library.
38
+ *
39
+ * **Delivery.** At least once: receivers deduplicate on the event id
40
+ * (the `webhook-id` header). Every method is tenant-scoped.
41
+ */
42
+ export interface WebhookEndpointBinding {
43
+ /**
44
+ * Register an endpoint. The route has checked the body's shape and
45
+ * that `url` is an absolute http(s) URL; the binding applies the
46
+ * deployment's URL policy (e.g. https only, no private addresses) and
47
+ * answers `url-refused` with a reason, and checks the secret behind
48
+ * `secretRef` (`secret-not-found`, `secret-too-weak`).
49
+ */
50
+ create(input: WebhookEndpointCreateInput): Promise<WebhookEndpointCreateOutcome>;
51
+ list(input: WebhookEndpointListInput): Promise<WebhookEndpointPage>;
52
+ /** `null` when unknown or unregistered; the route answers 404. */
53
+ get(input: WebhookEndpointRef): Promise<WebhookEndpoint | null>;
54
+ update(input: WebhookEndpointUpdateInput): Promise<WebhookEndpointUpdateOutcome>;
55
+ /**
56
+ * Soft delete: the endpoint stops receiving events and its pending
57
+ * deliveries are abandoned. `{ unregistered: false }` when it was
58
+ * unknown or already unregistered.
59
+ */
60
+ unregister(input: WebhookEndpointRef): Promise<{ readonly unregistered: boolean }>;
61
+ /** The endpoint's deliveries, newest first. */
62
+ listDeliveries(input: WebhookDeliveryListInput): Promise<WebhookDeliveryListOutcome>;
63
+ /** Queue a delivery again now, whatever its status; attempts start over. */
64
+ redeliver(input: WebhookDeliveryRef): Promise<WebhookDeliveryOutcome>;
65
+ /** Queue a `webhook.test` event to the endpoint, to check the receiver end to end. */
66
+ sendTest(input: WebhookEndpointRef): Promise<WebhookDeliveryOutcome>;
67
+ }
68
+
69
+ /** Event types an endpoint can subscribe to. */
70
+ export const WEBHOOK_EVENT_TYPES = ['run.finished'] as const;
71
+ export type WebhookEventType = (typeof WEBHOOK_EVENT_TYPES)[number];
72
+
73
+ /**
74
+ * Which events reach the endpoint. Every field narrows; absent fields
75
+ * don't. `run.finished` is sent for top-level runs only (never for a
76
+ * child run, such as an agent step's turn).
77
+ */
78
+ export interface WebhookEndpointFilter {
79
+ /** Only runs in this project. */
80
+ readonly projectId?: ProjectId;
81
+ /** Only runs of these flows (`flowId`, any version). */
82
+ readonly flowIds?: readonly string[];
83
+ /** Dry runs are left out unless this is `true`. */
84
+ readonly includeDryRuns?: boolean;
85
+ }
86
+
87
+ export interface WebhookEndpoint {
88
+ readonly endpointId: WebhookEndpointId;
89
+ readonly url: string;
90
+ readonly events: readonly WebhookEventType[];
91
+ readonly filter: WebhookEndpointFilter;
92
+ readonly description: string | null;
93
+ /** Where the signing secret is kept; the value never leaves the store. */
94
+ readonly secretRef: WebhookSecretRef;
95
+ readonly createdAt: Timestamp;
96
+ readonly updatedAt: Timestamp;
97
+ }
98
+
99
+ /**
100
+ * A secret by name in the deployment's secrets store, resolved at tenant
101
+ * scope — the same shape as a provider's `secret_ref`.
102
+ */
103
+ export interface WebhookSecretRef {
104
+ readonly envName: EnvName;
105
+ readonly name: string;
106
+ }
107
+
108
+ export interface WebhookEndpointRef {
109
+ readonly tenantId: TenantId;
110
+ readonly endpointId: WebhookEndpointId;
111
+ }
112
+
113
+ export interface WebhookEndpointCreateInput {
114
+ readonly tenantId: TenantId;
115
+ readonly url: string;
116
+ readonly events: readonly WebhookEventType[];
117
+ readonly filter: WebhookEndpointFilter;
118
+ readonly secretRef: WebhookSecretRef;
119
+ readonly description?: string;
120
+ }
121
+
122
+ export interface WebhookEndpointListInput {
123
+ readonly tenantId: TenantId;
124
+ readonly limit: number;
125
+ readonly cursor?: Cursor;
126
+ }
127
+
128
+ export interface WebhookEndpointPage {
129
+ readonly data: readonly WebhookEndpoint[];
130
+ readonly nextCursor?: Cursor;
131
+ }
132
+
133
+ /** Fields to change; absent fields are kept. `description: null` clears it. */
134
+ export interface WebhookEndpointUpdateInput extends WebhookEndpointRef {
135
+ readonly url?: string;
136
+ readonly events?: readonly WebhookEventType[];
137
+ readonly filter?: WebhookEndpointFilter;
138
+ readonly secretRef?: WebhookSecretRef;
139
+ readonly description?: string | null;
140
+ }
141
+
142
+ /** Why an endpoint can't be saved as asked. */
143
+ export type WebhookEndpointRefusal =
144
+ | { readonly kind: 'url-refused'; readonly reason: string }
145
+ | { readonly kind: 'project-not-found'; readonly projectId: ProjectId }
146
+ /** No secret by that name (at tenant scope) in the store. */
147
+ | { readonly kind: 'secret-not-found'; readonly secretRef: WebhookSecretRef }
148
+ /** The secret is not `whsec_` + base64 of at least 24 bytes (or that base64 alone). */
149
+ | { readonly kind: 'secret-too-weak'; readonly secretRef: WebhookSecretRef };
150
+
151
+ export type WebhookEndpointCreateOutcome =
152
+ | { readonly kind: 'ok'; readonly endpoint: WebhookEndpoint }
153
+ | WebhookEndpointRefusal;
154
+
155
+ export type WebhookEndpointUpdateOutcome =
156
+ | { readonly kind: 'ok'; readonly endpoint: WebhookEndpoint }
157
+ | { readonly kind: 'not-found' }
158
+ | WebhookEndpointRefusal;
159
+
160
+ // ---------- events (what endpoints receive) ----------
161
+
162
+ /**
163
+ * A finished top-level run, as `run.finished` carries it: the run's
164
+ * identity and outcome, never its input or output. Field names match
165
+ * `GET /v1/runs/:runId`.
166
+ */
167
+ export interface FinishedRun {
168
+ readonly id: RunId;
169
+ readonly projectId: ProjectId;
170
+ readonly flowId: string;
171
+ readonly flowVersion: string;
172
+ readonly status: 'completed' | 'failed' | 'cancelled';
173
+ readonly dryRun: boolean;
174
+ /** Why the run failed or was cancelled; `null` when it completed. */
175
+ readonly failureMessage: string | null;
176
+ readonly createdAt: Timestamp;
177
+ readonly completedAt: Timestamp;
178
+ }
179
+
180
+ export interface RunFinishedEvent {
181
+ readonly id: WebhookEventId;
182
+ readonly type: 'run.finished';
183
+ readonly createdAt: Timestamp;
184
+ readonly data: { readonly run: FinishedRun };
185
+ }
186
+
187
+ /** Sent only by `POST /v1/webhook-endpoints/:endpointId/test`. */
188
+ export interface WebhookTestEvent {
189
+ readonly id: WebhookEventId;
190
+ readonly type: 'webhook.test';
191
+ readonly createdAt: Timestamp;
192
+ readonly data: { readonly endpointId: WebhookEndpointId };
193
+ }
194
+
195
+ /** The JSON body of every webhook request. */
196
+ export type WebhookEvent = RunFinishedEvent | WebhookTestEvent;
197
+
198
+ // ---------- deliveries ----------
199
+
200
+ /**
201
+ * `pending`: waiting for its next attempt. `delivered`: the endpoint
202
+ * answered 2xx. `failed`: every attempt failed, or the endpoint was
203
+ * unregistered first; `redeliver` queues it again.
204
+ */
205
+ export const WEBHOOK_DELIVERY_STATUSES = ['pending', 'delivered', 'failed'] as const;
206
+ export type WebhookDeliveryStatus = (typeof WEBHOOK_DELIVERY_STATUSES)[number];
207
+
208
+ export interface WebhookDelivery {
209
+ readonly deliveryId: WebhookDeliveryId;
210
+ readonly endpointId: WebhookEndpointId;
211
+ readonly event: WebhookEvent;
212
+ readonly status: WebhookDeliveryStatus;
213
+ readonly attempts: number;
214
+ /** When the next attempt is due; `null` unless `pending`. */
215
+ readonly nextAttemptAt: Timestamp | null;
216
+ readonly lastAttemptAt: Timestamp | null;
217
+ /** HTTP status of the last attempt; `null` when it got no response. */
218
+ readonly lastResponseStatus: number | null;
219
+ /** Why the last attempt failed (`timeout`, `connection-refused`, `url-refused`, …). */
220
+ readonly lastError: string | null;
221
+ readonly createdAt: Timestamp;
222
+ readonly deliveredAt: Timestamp | null;
223
+ }
224
+
225
+ export interface WebhookDeliveryRef extends WebhookEndpointRef {
226
+ readonly deliveryId: WebhookDeliveryId;
227
+ }
228
+
229
+ export interface WebhookDeliveryListInput extends WebhookEndpointRef {
230
+ readonly limit: number;
231
+ readonly cursor?: Cursor;
232
+ readonly status?: WebhookDeliveryStatus;
233
+ }
234
+
235
+ export type WebhookDeliveryListOutcome =
236
+ | {
237
+ readonly kind: 'ok';
238
+ readonly data: readonly WebhookDelivery[];
239
+ readonly nextCursor?: Cursor;
240
+ }
241
+ | { readonly kind: 'not-found' };
242
+
243
+ export type WebhookDeliveryOutcome =
244
+ | { readonly kind: 'ok'; readonly delivery: WebhookDelivery }
245
+ | { readonly kind: 'not-found' }
246
+ | { readonly kind: 'delivery-not-found' };
package/src/xml.ts ADDED
@@ -0,0 +1,196 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // Copyright (C) 2026 Kindgi Inc.
3
+
4
+ /**
5
+ * Minimal hand-rolled XML serialization for the S3-compat wire
6
+ * surface. S3 response shapes are shallow (5 or so total across the
7
+ * surface); pulling in a full XML library would be overkill.
8
+ *
9
+ * Every serializer emits a single top-level element with the XML prolog
10
+ * and the S3-standard namespace (`http://s3.amazonaws.com/doc/2006-03-01/`).
11
+ * Escaping is applied to text content and attribute values.
12
+ */
13
+
14
+ const XML_PROLOG = '<?xml version="1.0" encoding="UTF-8"?>';
15
+ const S3_NS = 'http://s3.amazonaws.com/doc/2006-03-01/';
16
+
17
+ /**
18
+ * S3-standard error body. `<Error><Code>...</Code><Message>...</Message>...</Error>`.
19
+ */
20
+ export function errorXml(
21
+ code: string,
22
+ message: string,
23
+ extra: Readonly<Record<string, string>> = {},
24
+ ): string {
25
+ const extraTags = Object.entries(extra)
26
+ .map(([k, v]) => tag(k, v))
27
+ .join('');
28
+ return `${XML_PROLOG}<Error>${tag('Code', code)}${tag('Message', message)}${extraTags}</Error>`;
29
+ }
30
+
31
+ /**
32
+ * S3 `ListObjectsV2` result envelope. `contents` are the matched keys
33
+ * with metadata; `CommonPrefixes` is never emitted — delimiters are not
34
+ * supported.
35
+ */
36
+ export interface ListBucketResultInput {
37
+ readonly bucket: string;
38
+ readonly prefix: string;
39
+ readonly maxKeys: number;
40
+ readonly isTruncated: boolean;
41
+ readonly continuationToken?: string;
42
+ readonly nextContinuationToken?: string;
43
+ readonly contents: ReadonlyArray<{
44
+ readonly key: string;
45
+ readonly lastModified: string;
46
+ readonly etag: string;
47
+ readonly size: number;
48
+ }>;
49
+ }
50
+
51
+ export function listBucketResultXml(input: ListBucketResultInput): string {
52
+ const contents = input.contents
53
+ .map(
54
+ (c) =>
55
+ `<Contents>${tag('Key', c.key)}${tag('LastModified', c.lastModified)}${tag('ETag', quote(c.etag))}${tag('Size', String(c.size))}${tag('StorageClass', 'STANDARD')}</Contents>`,
56
+ )
57
+ .join('');
58
+ const parts = [
59
+ tag('Name', input.bucket),
60
+ tag('Prefix', input.prefix),
61
+ tag('KeyCount', String(input.contents.length)),
62
+ tag('MaxKeys', String(input.maxKeys)),
63
+ tag('IsTruncated', input.isTruncated ? 'true' : 'false'),
64
+ ...(input.continuationToken !== undefined
65
+ ? [tag('ContinuationToken', input.continuationToken)]
66
+ : []),
67
+ ...(input.nextContinuationToken !== undefined
68
+ ? [tag('NextContinuationToken', input.nextContinuationToken)]
69
+ : []),
70
+ contents,
71
+ ];
72
+ return `${XML_PROLOG}<ListBucketResult xmlns="${S3_NS}">${parts.join('')}</ListBucketResult>`;
73
+ }
74
+
75
+ /**
76
+ * S3 `InitiateMultipartUpload` result envelope.
77
+ */
78
+ export interface InitiateMultipartUploadResultInput {
79
+ readonly bucket: string;
80
+ readonly key: string;
81
+ readonly uploadId: string;
82
+ }
83
+
84
+ export function initiateMultipartUploadResultXml(
85
+ input: InitiateMultipartUploadResultInput,
86
+ ): string {
87
+ const parts = [
88
+ tag('Bucket', input.bucket),
89
+ tag('Key', input.key),
90
+ tag('UploadId', input.uploadId),
91
+ ];
92
+ return `${XML_PROLOG}<InitiateMultipartUploadResult xmlns="${S3_NS}">${parts.join('')}</InitiateMultipartUploadResult>`;
93
+ }
94
+
95
+ /**
96
+ * S3 `CompleteMultipartUpload` result envelope.
97
+ */
98
+ export interface CompleteMultipartUploadResultInput {
99
+ readonly bucket: string;
100
+ readonly key: string;
101
+ readonly etag: string;
102
+ readonly location: string;
103
+ }
104
+
105
+ export function completeMultipartUploadResultXml(
106
+ input: CompleteMultipartUploadResultInput,
107
+ ): string {
108
+ const parts = [
109
+ tag('Location', input.location),
110
+ tag('Bucket', input.bucket),
111
+ tag('Key', input.key),
112
+ tag('ETag', quote(input.etag)),
113
+ ];
114
+ return `${XML_PROLOG}<CompleteMultipartUploadResult xmlns="${S3_NS}">${parts.join('')}</CompleteMultipartUploadResult>`;
115
+ }
116
+
117
+ /**
118
+ * S3 `ListParts` result envelope.
119
+ */
120
+ export interface ListPartsResultInput {
121
+ readonly bucket: string;
122
+ readonly key: string;
123
+ readonly uploadId: string;
124
+ readonly parts: ReadonlyArray<{
125
+ readonly partNumber: number;
126
+ readonly etag: string;
127
+ readonly size: number;
128
+ readonly lastModified: string;
129
+ }>;
130
+ }
131
+
132
+ export function listPartsResultXml(input: ListPartsResultInput): string {
133
+ const parts = input.parts
134
+ .map(
135
+ (p) =>
136
+ `<Part>${tag('PartNumber', String(p.partNumber))}${tag('LastModified', p.lastModified)}${tag('ETag', quote(p.etag))}${tag('Size', String(p.size))}</Part>`,
137
+ )
138
+ .join('');
139
+ return `${XML_PROLOG}<ListPartsResult xmlns="${S3_NS}">${tag('Bucket', input.bucket)}${tag('Key', input.key)}${tag('UploadId', input.uploadId)}${parts}</ListPartsResult>`;
140
+ }
141
+
142
+ // -------------------- parsing (CompleteMultipartUpload body) --------------------
143
+
144
+ /**
145
+ * Parse the `CompleteMultipartUpload` request body:
146
+ *
147
+ * <CompleteMultipartUpload>
148
+ * <Part>
149
+ * <PartNumber>1</PartNumber>
150
+ * <ETag>"..."</ETag>
151
+ * </Part>
152
+ * ...
153
+ * </CompleteMultipartUpload>
154
+ *
155
+ * Returns the declared parts in body order (S3 REQUIRES ascending
156
+ * PartNumber; the completer verifies before assembling). Hand-rolled
157
+ * regex — the shape is trivial and the input is machine-generated by
158
+ * AWS SDKs.
159
+ */
160
+ export function parseCompleteMultipartUploadXml(
161
+ body: string,
162
+ ): { partNumber: number; etag: string }[] | null {
163
+ const parts: { partNumber: number; etag: string }[] = [];
164
+ const partRe =
165
+ /<Part>\s*(?:<PartNumber>(\d+)<\/PartNumber>\s*<ETag>([^<]+)<\/ETag>|<ETag>([^<]+)<\/ETag>\s*<PartNumber>(\d+)<\/PartNumber>)\s*<\/Part>/g;
166
+ let match: RegExpExecArray | null = partRe.exec(body);
167
+ while (match !== null) {
168
+ const partNumber = Number.parseInt((match[1] ?? match[4]) as string, 10);
169
+ const etagRaw = (match[2] ?? match[3]) as string;
170
+ const etag = etagRaw.replace(/^"|"$/g, '');
171
+ if (!Number.isFinite(partNumber) || partNumber < 1) return null;
172
+ parts.push({ partNumber, etag });
173
+ match = partRe.exec(body);
174
+ }
175
+ if (parts.length === 0) return null;
176
+ return parts;
177
+ }
178
+
179
+ // -------------------- primitives --------------------
180
+
181
+ function tag(name: string, value: string): string {
182
+ return `<${name}>${escapeXml(value)}</${name}>`;
183
+ }
184
+
185
+ function quote(s: string): string {
186
+ return s.startsWith('"') ? s : `"${s}"`;
187
+ }
188
+
189
+ // In XML text content, only `&` and `<` MUST be escaped (`>` is only
190
+ // required inside `]]>`). `"` and `'` need escaping only in attribute
191
+ // values. S3 responses don't use attribute values, so we escape the
192
+ // minimum set — matching what real S3 emits (e.g. `<ETag>"abc"</ETag>`
193
+ // with literal quotes).
194
+ function escapeXml(s: string): string {
195
+ return s.replace(/&/g, '&amp;').replace(/</g, '&lt;');
196
+ }