@vercel/factory 0.0.13 → 0.0.15

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 (458) hide show
  1. package/README.md +307 -1
  2. package/dist/agent-routes.d.mts +69 -0
  3. package/dist/agent-routes.mjs +64 -0
  4. package/dist/agent-routes.mjs.map +1 -0
  5. package/dist/api-contracts.d.mts +1749 -0
  6. package/dist/api-contracts.mjs +118 -0
  7. package/dist/api-contracts.mjs.map +1 -0
  8. package/dist/api-images.d.mts +30 -0
  9. package/dist/api-images.mjs +28 -0
  10. package/dist/api-images.mjs.map +1 -0
  11. package/dist/api-task-graph.mjs +57 -0
  12. package/dist/api-task-graph.mjs.map +1 -0
  13. package/dist/api.d.mts +77 -0
  14. package/dist/api.mjs +1087 -0
  15. package/dist/api.mjs.map +1 -0
  16. package/dist/approval-access.d.mts +39 -0
  17. package/dist/approval-access.mjs +62 -0
  18. package/dist/approval-access.mjs.map +1 -0
  19. package/dist/approval-contracts.d.mts +692 -0
  20. package/dist/approval-contracts.mjs +27 -0
  21. package/dist/approval-contracts.mjs.map +1 -0
  22. package/dist/approval.d.mts +49 -0
  23. package/dist/approval.mjs +39 -0
  24. package/dist/approval.mjs.map +1 -0
  25. package/dist/blob/artifacts.d.mts +37 -0
  26. package/dist/blob/artifacts.mjs +45 -0
  27. package/dist/blob/artifacts.mjs.map +1 -0
  28. package/dist/blob/index.d.mts +44 -8
  29. package/dist/blob/index.mjs +159 -35
  30. package/dist/blob/index.mjs.map +1 -1
  31. package/dist/budget.d.mts +108 -0
  32. package/dist/budget.mjs +141 -0
  33. package/dist/budget.mjs.map +1 -0
  34. package/dist/budgets.d.mts +4 -0
  35. package/dist/budgets.mjs +4 -0
  36. package/dist/build-factory.d.mts +6 -4
  37. package/dist/build-factory.mjs +2 -1
  38. package/dist/build-factory.mjs.map +1 -1
  39. package/dist/change-verification/brief.d.mts +9 -0
  40. package/dist/change-verification/brief.mjs +13 -0
  41. package/dist/change-verification/brief.mjs.map +1 -0
  42. package/dist/change-verification/dispatch.d.mts +24 -0
  43. package/dist/change-verification/dispatch.mjs +45 -0
  44. package/dist/change-verification/dispatch.mjs.map +1 -0
  45. package/dist/change-verification/eve-tool.d.mts +60 -0
  46. package/dist/change-verification/eve-tool.mjs +101 -0
  47. package/dist/change-verification/eve-tool.mjs.map +1 -0
  48. package/dist/changes/eve-record-change.d.mts +56 -0
  49. package/dist/changes/eve-record-change.mjs +97 -0
  50. package/dist/changes/eve-record-change.mjs.map +1 -0
  51. package/dist/changes/presentation.d.mts +14 -0
  52. package/dist/changes.d.mts +23 -0
  53. package/dist/changes.mjs +29 -0
  54. package/dist/changes.mjs.map +1 -0
  55. package/dist/client-events.d.mts +18 -0
  56. package/dist/client-events.mjs +41 -0
  57. package/dist/client-events.mjs.map +1 -0
  58. package/dist/client-stream.d.mts +28 -0
  59. package/dist/client-stream.mjs +204 -0
  60. package/dist/client-stream.mjs.map +1 -0
  61. package/dist/client-transcript.d.mts +41 -0
  62. package/dist/client-transcript.mjs +229 -0
  63. package/dist/client-transcript.mjs.map +1 -0
  64. package/dist/client.d.mts +234 -0
  65. package/dist/client.mjs +258 -0
  66. package/dist/client.mjs.map +1 -0
  67. package/dist/code-review/contracts.d.mts +26 -0
  68. package/dist/code-review/eve-post-review.d.mts +70 -0
  69. package/dist/code-review/eve-post-review.mjs +183 -0
  70. package/dist/code-review/eve-post-review.mjs.map +1 -0
  71. package/dist/code-review/eve-review-comments.d.mts +64 -0
  72. package/dist/code-review/eve-review-comments.mjs +159 -0
  73. package/dist/code-review/eve-review-comments.mjs.map +1 -0
  74. package/dist/code-review/github-contracts.d.mts +10 -0
  75. package/dist/code-review/github-reporter.d.mts +44 -0
  76. package/dist/code-review/github-reporter.mjs +260 -0
  77. package/dist/code-review/github-reporter.mjs.map +1 -0
  78. package/dist/code-review/preparation.d.mts +34 -0
  79. package/dist/code-review/preparation.mjs +23 -0
  80. package/dist/code-review/preparation.mjs.map +1 -0
  81. package/dist/code-review/stall.d.mts +17 -0
  82. package/dist/code-review/stall.mjs +30 -0
  83. package/dist/code-review/stall.mjs.map +1 -0
  84. package/dist/code-review.d.mts +6 -0
  85. package/dist/code-review.mjs +5 -0
  86. package/dist/communication.d.mts +9 -0
  87. package/dist/communication.mjs +9 -0
  88. package/dist/connectors/github.d.mts +26 -0
  89. package/dist/connectors/github.mjs +55 -0
  90. package/dist/connectors/github.mjs.map +1 -0
  91. package/dist/connectors/index.d.mts +35 -2
  92. package/dist/connectors/index.mjs +4 -26
  93. package/dist/connectors/index.mjs.map +1 -1
  94. package/dist/connectors/outbox.d.mts +34 -0
  95. package/dist/connectors/outbox.mjs +50 -0
  96. package/dist/connectors/outbox.mjs.map +1 -0
  97. package/dist/connectors/slack-approval-blocks.mjs +136 -0
  98. package/dist/connectors/slack-approval-blocks.mjs.map +1 -0
  99. package/dist/connectors/slack-approvals.d.mts +29 -0
  100. package/dist/connectors/slack-approvals.mjs +346 -0
  101. package/dist/connectors/slack-approvals.mjs.map +1 -0
  102. package/dist/connectors/slack.d.mts +35 -41
  103. package/dist/connectors/slack.mjs +13 -69
  104. package/dist/connectors/slack.mjs.map +1 -1
  105. package/dist/deepsec/eve-tool.d.mts +110 -0
  106. package/dist/deepsec/eve-tool.mjs +164 -0
  107. package/dist/deepsec/eve-tool.mjs.map +1 -0
  108. package/dist/deepsec/finding.d.mts +84 -0
  109. package/dist/deepsec/finding.mjs +56 -0
  110. package/dist/deepsec/finding.mjs.map +1 -0
  111. package/dist/deepsec.d.mts +3 -0
  112. package/dist/delivery-metrics/metrics.d.mts +93 -0
  113. package/dist/delivery-metrics/metrics.mjs +200 -0
  114. package/dist/delivery-metrics/metrics.mjs.map +1 -0
  115. package/dist/delivery-metrics.d.mts +2 -0
  116. package/dist/delivery-metrics.mjs +2 -0
  117. package/dist/dispatch.d.mts +81 -0
  118. package/dist/dispatch.mjs +140 -0
  119. package/dist/dispatch.mjs.map +1 -0
  120. package/dist/errors.d.mts +15 -0
  121. package/dist/errors.mjs +38 -0
  122. package/dist/errors.mjs.map +1 -0
  123. package/dist/eve/index.d.mts +143 -1561
  124. package/dist/eve/index.mjs +244 -1063
  125. package/dist/eve/index.mjs.map +1 -1
  126. package/dist/eve/invoke.d.mts +144 -0
  127. package/dist/eve/invoke.mjs +241 -0
  128. package/dist/eve/invoke.mjs.map +1 -0
  129. package/dist/eve/session-client.d.mts +68 -0
  130. package/dist/eve/session-client.mjs +131 -0
  131. package/dist/eve/session-client.mjs.map +1 -0
  132. package/dist/eve/task-execution.mjs +18 -0
  133. package/dist/eve/task-execution.mjs.map +1 -0
  134. package/dist/eve/task-session.d.mts +87 -0
  135. package/dist/eve/task-session.mjs +203 -0
  136. package/dist/eve/task-session.mjs.map +1 -0
  137. package/dist/eve/transcript.d.mts +37 -0
  138. package/dist/eve/transcript.mjs +65 -0
  139. package/dist/eve/transcript.mjs.map +1 -0
  140. package/dist/execution-public.d.mts +8 -0
  141. package/dist/execution-public.mjs +7 -0
  142. package/dist/execution.d.mts +75 -0
  143. package/dist/execution.mjs +153 -0
  144. package/dist/execution.mjs.map +1 -0
  145. package/dist/finding-remediation/admission.d.mts +51 -0
  146. package/dist/finding-remediation/admission.mjs +87 -0
  147. package/dist/finding-remediation/admission.mjs.map +1 -0
  148. package/dist/finding-remediation/brief.d.mts +14 -0
  149. package/dist/finding-remediation/brief.mjs +25 -0
  150. package/dist/finding-remediation/brief.mjs.map +1 -0
  151. package/dist/finding-remediation/eve-tool.d.mts +29 -0
  152. package/dist/finding-remediation/eve-tool.mjs +34 -0
  153. package/dist/finding-remediation/eve-tool.mjs.map +1 -0
  154. package/dist/findings/fingerprint.d.mts +14 -0
  155. package/dist/findings/fingerprint.mjs +28 -0
  156. package/dist/findings/fingerprint.mjs.map +1 -0
  157. package/dist/findings.d.mts +6 -0
  158. package/dist/findings.mjs +6 -0
  159. package/dist/github-app.d.mts +54 -0
  160. package/dist/github-app.mjs +121 -0
  161. package/dist/github-app.mjs.map +1 -0
  162. package/dist/github-publication.d.mts +198 -0
  163. package/dist/github-publication.mjs +429 -0
  164. package/dist/github-publication.mjs.map +1 -0
  165. package/dist/github-transfer.d.mts +72 -0
  166. package/dist/github-transfer.mjs +125 -0
  167. package/dist/github-transfer.mjs.map +1 -0
  168. package/dist/github.d.mts +406 -2
  169. package/dist/github.mjs +250 -37
  170. package/dist/github.mjs.map +1 -1
  171. package/dist/image-input.d.mts +51 -0
  172. package/dist/image-input.mjs +63 -0
  173. package/dist/image-input.mjs.map +1 -0
  174. package/dist/index.d.mts +14 -314
  175. package/dist/index.mjs +14 -1124
  176. package/dist/intake-contracts.d.mts +56 -0
  177. package/dist/intake-contracts.mjs +33 -0
  178. package/dist/intake-contracts.mjs.map +1 -0
  179. package/dist/integrations/deepsec.d.mts +4 -0
  180. package/dist/integrations/deepsec.mjs +3 -0
  181. package/dist/integrations/github.d.mts +11 -0
  182. package/dist/integrations/github.mjs +9 -0
  183. package/dist/integrations/slack.d.mts +3 -0
  184. package/dist/integrations/slack.mjs +3 -0
  185. package/dist/integrations/vercel.d.mts +3 -0
  186. package/dist/integrations/vercel.mjs +3 -0
  187. package/dist/merge-resolution/contracts.d.mts +17 -0
  188. package/dist/merge-resolution/contracts.mjs +19 -0
  189. package/dist/merge-resolution/contracts.mjs.map +1 -0
  190. package/dist/merge-resolution/eve-tools.d.mts +46 -0
  191. package/dist/merge-resolution/eve-tools.mjs +117 -0
  192. package/dist/merge-resolution/eve-tools.mjs.map +1 -0
  193. package/dist/multi-repository-changes/coordination.d.mts +49 -0
  194. package/dist/multi-repository-changes/coordination.mjs +115 -0
  195. package/dist/multi-repository-changes/coordination.mjs.map +1 -0
  196. package/dist/planning/cancellation.mjs +82 -0
  197. package/dist/planning/cancellation.mjs.map +1 -0
  198. package/dist/planning/configuration.d.mts +23 -0
  199. package/dist/planning/configuration.mjs +56 -0
  200. package/dist/planning/configuration.mjs.map +1 -0
  201. package/dist/planning/contracts.d.mts +136 -0
  202. package/dist/planning/contracts.mjs +42 -0
  203. package/dist/planning/contracts.mjs.map +1 -0
  204. package/dist/planning/dependencies.mjs +44 -0
  205. package/dist/planning/dependencies.mjs.map +1 -0
  206. package/dist/planning/effects.mjs +122 -0
  207. package/dist/planning/effects.mjs.map +1 -0
  208. package/dist/planning/reconcile.mjs +273 -0
  209. package/dist/planning/reconcile.mjs.map +1 -0
  210. package/dist/planning/runtime.d.mts +27 -0
  211. package/dist/planning/runtime.mjs +25 -0
  212. package/dist/planning/runtime.mjs.map +1 -0
  213. package/dist/planning/state.mjs +92 -0
  214. package/dist/planning/state.mjs.map +1 -0
  215. package/dist/planning/turns.mjs +262 -0
  216. package/dist/planning/turns.mjs.map +1 -0
  217. package/dist/planning/validation.mjs +106 -0
  218. package/dist/planning/validation.mjs.map +1 -0
  219. package/dist/postgres/index.d.mts +7 -1
  220. package/dist/postgres/index.mjs +7 -3
  221. package/dist/postgres/index.mjs.map +1 -1
  222. package/dist/presets/software-development/approval.d.mts +14 -0
  223. package/dist/presets/software-development/approval.mjs +21 -0
  224. package/dist/presets/software-development/approval.mjs.map +1 -0
  225. package/dist/presets/software-development/deepsec-brief.d.mts +8 -0
  226. package/dist/presets/software-development/deepsec-brief.mjs +14 -0
  227. package/dist/presets/software-development/deepsec-brief.mjs.map +1 -0
  228. package/dist/presets/software-development/dispatch.d.mts +53 -0
  229. package/dist/presets/software-development/dispatch.mjs +66 -0
  230. package/dist/presets/software-development/dispatch.mjs.map +1 -0
  231. package/dist/presets/software-development/eve-delegation-policy.d.mts +7 -0
  232. package/dist/presets/software-development/eve-delegation-policy.mjs +34 -0
  233. package/dist/presets/software-development/eve-delegation-policy.mjs.map +1 -0
  234. package/dist/presets/software-development/eve.d.mts +18 -0
  235. package/dist/presets/software-development/eve.mjs +19 -0
  236. package/dist/presets/software-development/eve.mjs.map +1 -0
  237. package/dist/presets/software-development/finish-task-policy.d.mts +7 -0
  238. package/dist/presets/software-development/finish-task-policy.mjs +9 -0
  239. package/dist/presets/software-development/finish-task-policy.mjs.map +1 -0
  240. package/dist/presets/software-development/recovery.d.mts +32 -0
  241. package/dist/presets/software-development/recovery.mjs +120 -0
  242. package/dist/presets/software-development/recovery.mjs.map +1 -0
  243. package/dist/presets/software-development/task-communication.d.mts +23 -0
  244. package/dist/presets/software-development/task-communication.mjs +120 -0
  245. package/dist/presets/software-development/task-communication.mjs.map +1 -0
  246. package/dist/presets/software-development.d.mts +9 -0
  247. package/dist/presets/software-development.mjs +9 -0
  248. package/dist/pull-requests/contracts.d.mts +72 -0
  249. package/dist/pull-requests/eve-fetch.d.mts +57 -0
  250. package/dist/pull-requests/eve-fetch.mjs +151 -0
  251. package/dist/pull-requests/eve-fetch.mjs.map +1 -0
  252. package/dist/pull-requests/github-label-manager.d.mts +27 -0
  253. package/dist/pull-requests/github-label-manager.mjs +40 -0
  254. package/dist/pull-requests/github-label-manager.mjs.map +1 -0
  255. package/dist/pull-requests/github-publisher.d.mts +53 -0
  256. package/dist/pull-requests/github-publisher.mjs +345 -0
  257. package/dist/pull-requests/github-publisher.mjs.map +1 -0
  258. package/dist/pull-requests.d.mts +5 -0
  259. package/dist/pull-requests.mjs +4 -0
  260. package/dist/receipts.d.mts +4 -0
  261. package/dist/receipts.mjs +3 -0
  262. package/dist/repositories.d.mts +18 -0
  263. package/dist/repositories.mjs +33 -0
  264. package/dist/repositories.mjs.map +1 -0
  265. package/dist/sandbox/command.d.mts +18 -0
  266. package/dist/sandbox/execution-abort.d.mts +16 -0
  267. package/dist/sandbox/execution-abort.mjs +49 -0
  268. package/dist/sandbox/execution-abort.mjs.map +1 -0
  269. package/dist/sandbox/execution-environment.d.mts +25 -0
  270. package/dist/sandbox/execution-run-ledger.d.mts +115 -0
  271. package/dist/sandbox/execution-run-ledger.mjs +209 -0
  272. package/dist/sandbox/execution-run-ledger.mjs.map +1 -0
  273. package/dist/sandbox/execution.d.mts +54 -0
  274. package/dist/sandbox/execution.mjs +228 -0
  275. package/dist/sandbox/execution.mjs.map +1 -0
  276. package/dist/sandbox/harness-runner.d.mts +79 -0
  277. package/dist/sandbox/harness-runner.mjs +162 -0
  278. package/dist/sandbox/harness-runner.mjs.map +1 -0
  279. package/dist/sandbox/index.d.mts +9 -0
  280. package/dist/sandbox/index.mjs +7 -0
  281. package/dist/sandbox/task-environment.d.mts +50 -0
  282. package/dist/sandbox/task-environment.mjs +140 -0
  283. package/dist/sandbox/task-environment.mjs.map +1 -0
  284. package/dist/sandbox/workspace.d.mts +29 -0
  285. package/dist/sandbox/workspace.mjs +28 -0
  286. package/dist/sandbox/workspace.mjs.map +1 -0
  287. package/dist/schema/agent-route.d.mts +22 -0
  288. package/dist/schema/agent-route.mjs +15 -0
  289. package/dist/schema/agent-route.mjs.map +1 -0
  290. package/dist/schema/answer.d.mts +23 -0
  291. package/dist/schema/answer.mjs +21 -0
  292. package/dist/schema/answer.mjs.map +1 -0
  293. package/dist/schema/budget.d.mts +38 -0
  294. package/dist/schema/budget.mjs +30 -0
  295. package/dist/schema/budget.mjs.map +1 -0
  296. package/dist/schema/catalog.mjs +72 -0
  297. package/dist/schema/catalog.mjs.map +1 -0
  298. package/dist/schema/change.d.mts +117 -0
  299. package/dist/schema/change.mjs +68 -0
  300. package/dist/schema/change.mjs.map +1 -0
  301. package/dist/schema/common.d.mts +33 -0
  302. package/dist/{id-DwCihQr4.mjs → schema/common.mjs} +7 -14
  303. package/dist/schema/common.mjs.map +1 -0
  304. package/dist/schema/communication.d.mts +52 -0
  305. package/dist/schema/communication.mjs +35 -0
  306. package/dist/schema/communication.mjs.map +1 -0
  307. package/dist/schema/execution.d.mts +101 -0
  308. package/dist/schema/execution.mjs +86 -0
  309. package/dist/schema/execution.mjs.map +1 -0
  310. package/dist/schema/factory-config.d.mts +95 -0
  311. package/dist/schema/factory-config.mjs +60 -0
  312. package/dist/schema/factory-config.mjs.map +1 -0
  313. package/dist/schema/finding.d.mts +125 -0
  314. package/dist/schema/finding.mjs +67 -0
  315. package/dist/schema/finding.mjs.map +1 -0
  316. package/dist/schema/id.d.mts +43 -0
  317. package/dist/schema/id.mjs +32 -0
  318. package/dist/schema/id.mjs.map +1 -0
  319. package/dist/schema/outbox.d.mts +240 -0
  320. package/dist/schema/outbox.mjs +53 -0
  321. package/dist/schema/outbox.mjs.map +1 -0
  322. package/dist/schema/question-route.mjs +16 -0
  323. package/dist/schema/question-route.mjs.map +1 -0
  324. package/dist/schema/receipt.d.mts +81 -0
  325. package/dist/schema/receipt.mjs +94 -0
  326. package/dist/schema/receipt.mjs.map +1 -0
  327. package/dist/schema/repository.d.mts +26 -0
  328. package/dist/schema/repository.mjs +25 -0
  329. package/dist/schema/repository.mjs.map +1 -0
  330. package/dist/schema/session.d.mts +135 -0
  331. package/dist/schema/session.mjs +53 -0
  332. package/dist/schema/session.mjs.map +1 -0
  333. package/dist/schema/signal.d.mts +105 -0
  334. package/dist/schema/signal.mjs +81 -0
  335. package/dist/schema/signal.mjs.map +1 -0
  336. package/dist/schema/stored-session.mjs +10 -0
  337. package/dist/schema/stored-session.mjs.map +1 -0
  338. package/dist/schema/stored-task.mjs +20 -0
  339. package/dist/schema/stored-task.mjs.map +1 -0
  340. package/dist/schema/task-effect.d.mts +39 -0
  341. package/dist/schema/task-effect.mjs +29 -0
  342. package/dist/schema/task-effect.mjs.map +1 -0
  343. package/dist/schema/task-graph.d.mts +3134 -0
  344. package/dist/schema/task-graph.mjs +97 -0
  345. package/dist/schema/task-graph.mjs.map +1 -0
  346. package/dist/schema/task-message.d.mts +254 -0
  347. package/dist/schema/task-message.mjs +189 -0
  348. package/dist/schema/task-message.mjs.map +1 -0
  349. package/dist/schema/task.d.mts +272 -0
  350. package/dist/schema/task.mjs +199 -0
  351. package/dist/schema/task.mjs.map +1 -0
  352. package/dist/schema/transcript.d.mts +170 -0
  353. package/dist/schema/transcript.mjs +86 -0
  354. package/dist/schema/transcript.mjs.map +1 -0
  355. package/dist/schema/transitions.d.mts +50 -0
  356. package/dist/schema/transitions.mjs +303 -0
  357. package/dist/schema/transitions.mjs.map +1 -0
  358. package/dist/schema/work.d.mts +101 -0
  359. package/dist/schema/work.mjs +102 -0
  360. package/dist/schema/work.mjs.map +1 -0
  361. package/dist/signal-triage.d.mts +20 -0
  362. package/dist/signal-triage.mjs +85 -0
  363. package/dist/signal-triage.mjs.map +1 -0
  364. package/dist/signals.d.mts +19 -0
  365. package/dist/signals.mjs +19 -0
  366. package/dist/signals.mjs.map +1 -0
  367. package/dist/stall.d.mts +38 -0
  368. package/dist/stall.mjs +79 -0
  369. package/dist/stall.mjs.map +1 -0
  370. package/dist/storage.d.mts +4 -0
  371. package/dist/storage.mjs +4 -0
  372. package/dist/store/driver.d.mts +65 -0
  373. package/dist/store/driver.mjs +42 -0
  374. package/dist/store/driver.mjs.map +1 -0
  375. package/dist/store/engine.d.mts +485 -0
  376. package/dist/store/engine.mjs +2175 -0
  377. package/dist/store/engine.mjs.map +1 -0
  378. package/dist/store/memory.d.mts +7 -0
  379. package/dist/store/memory.mjs +52 -0
  380. package/dist/store/memory.mjs.map +1 -0
  381. package/dist/store/task-effects.d.mts +38 -0
  382. package/dist/store/task-effects.mjs +118 -0
  383. package/dist/store/task-effects.mjs.map +1 -0
  384. package/dist/store/task-graphs.d.mts +60 -0
  385. package/dist/store/task-graphs.mjs +212 -0
  386. package/dist/store/task-graphs.mjs.map +1 -0
  387. package/dist/store/task-messages.d.mts +136 -0
  388. package/dist/store/task-messages.mjs +475 -0
  389. package/dist/store/task-messages.mjs.map +1 -0
  390. package/dist/store/task-work.d.mts +65 -0
  391. package/dist/store/task-work.mjs +134 -0
  392. package/dist/store/task-work.mjs.map +1 -0
  393. package/dist/store/work-notifications.d.mts +19 -0
  394. package/dist/store/work-notifications.mjs +48 -0
  395. package/dist/store/work-notifications.mjs.map +1 -0
  396. package/dist/sweep.d.mts +57 -0
  397. package/dist/sweep.mjs +143 -0
  398. package/dist/sweep.mjs.map +1 -0
  399. package/dist/task-communication.d.mts +35 -0
  400. package/dist/task-communication.mjs +47 -0
  401. package/dist/task-communication.mjs.map +1 -0
  402. package/dist/task-graph-view.d.mts +264 -0
  403. package/dist/task-graph-view.mjs +17 -0
  404. package/dist/task-graph-view.mjs.map +1 -0
  405. package/dist/task-message-processing.d.mts +60 -0
  406. package/dist/task-message-processing.mjs +200 -0
  407. package/dist/task-message-processing.mjs.map +1 -0
  408. package/dist/task-protocols.d.mts +80 -0
  409. package/dist/task-protocols.mjs +47 -0
  410. package/dist/task-protocols.mjs.map +1 -0
  411. package/dist/tasks.d.mts +17 -0
  412. package/dist/tasks.mjs +17 -0
  413. package/dist/vercel-git.d.mts +21 -0
  414. package/dist/vercel-git.mjs +112 -0
  415. package/dist/vercel-git.mjs.map +1 -0
  416. package/dist/vercel.d.mts +33 -2
  417. package/dist/vercel.mjs +48 -3
  418. package/dist/vercel.mjs.map +1 -1
  419. package/dist/work-triage/eve-tool.d.mts +29 -0
  420. package/dist/work-triage/eve-tool.mjs +32 -0
  421. package/dist/work-triage/eve-tool.mjs.map +1 -0
  422. package/dist/work-triage/find-existing-work.d.mts +32 -0
  423. package/dist/work-triage/find-existing-work.mjs +31 -0
  424. package/dist/work-triage/find-existing-work.mjs.map +1 -0
  425. package/dist/work-triage/github.d.mts +15 -0
  426. package/dist/work-triage/github.mjs +14 -0
  427. package/dist/work-triage/github.mjs.map +1 -0
  428. package/dist/work-triage.d.mts +3 -0
  429. package/dist/work-triage.mjs +3 -0
  430. package/dist/workflows.d.mts +48 -0
  431. package/dist/workflows.mjs +86 -0
  432. package/dist/workflows.mjs.map +1 -0
  433. package/dist/workspace-diff-assembly.d.mts +33 -0
  434. package/dist/workspace-diff-assembly.mjs +95 -0
  435. package/dist/workspace-diff-assembly.mjs.map +1 -0
  436. package/dist/workspace-diff.d.mts +90 -0
  437. package/dist/workspace-diff.mjs +61 -0
  438. package/dist/workspace-diff.mjs.map +1 -0
  439. package/dist/workspace-snapshot.d.mts +26 -0
  440. package/dist/workspace-snapshot.mjs +80 -0
  441. package/dist/workspace-snapshot.mjs.map +1 -0
  442. package/package.json +129 -40
  443. package/dist/approval-CwhTP1XB.mjs +0 -269
  444. package/dist/approval-CwhTP1XB.mjs.map +0 -1
  445. package/dist/change-CzEAoFVE.mjs +0 -620
  446. package/dist/change-CzEAoFVE.mjs.map +0 -1
  447. package/dist/dispatch-B77cuPxh.d.mts +0 -713
  448. package/dist/driver-BJutB0PE.d.mts +0 -34
  449. package/dist/driver-Bbd25rNM.mjs +0 -23
  450. package/dist/driver-Bbd25rNM.mjs.map +0 -1
  451. package/dist/factory-config-BJcjsPKl.mjs +0 -86
  452. package/dist/factory-config-BJcjsPKl.mjs.map +0 -1
  453. package/dist/factory-config-D2yU3G0c.d.mts +0 -58
  454. package/dist/github-DXsxboUL.d.mts +0 -271
  455. package/dist/id-DwCihQr4.mjs.map +0 -1
  456. package/dist/index-Cy4jfXh5.d.mts +0 -67
  457. package/dist/index.mjs.map +0 -1
  458. package/dist/signal-CHVEmzvI.d.mts +0 -59
@@ -0,0 +1,27 @@
1
+ import { taskIdSchema } from "./schema/id.mjs";
2
+ import { repositorySlugSchema } from "./schema/repository.mjs";
3
+ import { taskSchema } from "./schema/task.mjs";
4
+ import { receiptSchema } from "./schema/receipt.mjs";
5
+ import { findingSchema } from "./schema/finding.mjs";
6
+ import { z } from "zod";
7
+ //#region src/approval-contracts.ts
8
+ /** Validates the stable human reason attached to an approval decision. */
9
+ const approvalRequestSchema = z.strictObject({ reason: z.string().trim().min(1).max(2e3).optional().describe("Reason for the decision; required for rejection. Retain unchanged for retries.") });
10
+ /** Validates one authorized approval proposal and its immutable decision state. */
11
+ const approvalViewSchema = z.object({
12
+ task: taskSchema.describe("Task requiring or carrying a human decision."),
13
+ repositories: z.array(repositorySlugSchema).readonly().describe("Configured repository names for this Task."),
14
+ finding: findingSchema.nullable().describe("Finding that prompted the Task, when available."),
15
+ decision: receiptSchema.nullable().describe("Immutable decision receipt, or null before a decision.")
16
+ });
17
+ /** Validates a filtered, cursor-paginated page of approval proposals. */
18
+ const approvalPageSchema = z.object({
19
+ actor: z.string().describe("Authenticated actor used for decision attribution."),
20
+ items: z.array(approvalViewSchema).readonly().describe("Authorized approvals in the requested order."),
21
+ totalCount: z.number().int().nonnegative().optional().describe("Number of authorized approvals matching all filters, before pagination."),
22
+ nextCursor: taskIdSchema.nullable().describe("Continue this filtered listing after this Task ID.")
23
+ });
24
+ //#endregion
25
+ export { approvalPageSchema, approvalRequestSchema, approvalViewSchema };
26
+
27
+ //# sourceMappingURL=approval-contracts.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"approval-contracts.mjs","names":[],"sources":["../src/approval-contracts.ts"],"sourcesContent":["import { z } from \"zod\";\nimport { taskIdSchema, type TaskId } from \"./schema/id\";\nimport { taskSchema } from \"./schema/task\";\nimport { receiptSchema } from \"./schema/receipt\";\nimport { findingSchema } from \"./schema/finding\";\nimport { repositorySlugSchema, type RepositorySlug } from \"./schema/repository\";\n\n/** Workspace owner and optional individually authenticated actor at the approval boundary. */\nexport interface ApiPrincipal {\n /** Workspace identity used for existing conversation ownership. */\n readonly id: string;\n /** Individually authenticated, provider-qualified actor; absent for anonymous/workload access. */\n readonly actor?: string;\n}\n\n/** Validates the stable human reason attached to an approval decision. */\nexport const approvalRequestSchema = z.strictObject({\n reason: z\n .string()\n .trim()\n .min(1)\n .max(2000)\n .optional()\n .describe(\"Reason for the decision; required for rejection. Retain unchanged for retries.\"),\n});\n/** Validates one authorized approval proposal and its immutable decision state. */\nexport const approvalViewSchema = z.object({\n task: taskSchema.describe(\"Task requiring or carrying a human decision.\"),\n repositories: z\n .array(repositorySlugSchema)\n .readonly()\n .describe(\"Configured repository names for this Task.\"),\n finding: findingSchema.nullable().describe(\"Finding that prompted the Task, when available.\"),\n decision: receiptSchema\n .nullable()\n .describe(\"Immutable decision receipt, or null before a decision.\"),\n});\n/** Validates a filtered, cursor-paginated page of approval proposals. */\nexport const approvalPageSchema = z.object({\n actor: z.string().describe(\"Authenticated actor used for decision attribution.\"),\n items: z\n .array(approvalViewSchema)\n .readonly()\n .describe(\"Authorized approvals in the requested order.\"),\n totalCount: z\n .number()\n .int()\n .nonnegative()\n .optional()\n .describe(\"Number of authorized approvals matching all filters, before pagination.\"),\n nextCursor: taskIdSchema\n .nullable()\n .describe(\"Continue this filtered listing after this Task ID.\"),\n});\n/** Authorized Task proposal with repository, finding, and decision context. */\nexport type ApprovalView = z.infer<typeof approvalViewSchema>;\n/** Filtered, cursor-paginated approval proposals for one authorized actor. */\nexport type ApprovalPage = z.infer<typeof approvalPageSchema>;\n/** Filters, ordering, and cursor controls for approval discovery. */\nexport interface ApprovalListOptions {\n readonly repository?: RepositorySlug;\n readonly status?: \"pending\" | \"decided\" | \"all\";\n readonly query?: string;\n readonly sort?: \"created\" | \"priority\" | \"decided\";\n readonly limit?: number;\n readonly cursor?: TaskId;\n}\n"],"mappings":";;;;;;;;AAgBA,MAAa,wBAAwB,EAAE,aAAa,EAClD,QAAQ,EACL,OAAO,CAAC,CACR,KAAK,CAAC,CACN,IAAI,CAAC,CAAC,CACN,IAAI,GAAI,CAAC,CACT,SAAS,CAAC,CACV,SAAS,gFAAgF,EAC9F,CAAC;;AAED,MAAa,qBAAqB,EAAE,OAAO;CACzC,MAAM,WAAW,SAAS,8CAA8C;CACxE,cAAc,EACX,MAAM,oBAAoB,CAAC,CAC3B,SAAS,CAAC,CACV,SAAS,4CAA4C;CACxD,SAAS,cAAc,SAAS,CAAC,CAAC,SAAS,iDAAiD;CAC5F,UAAU,cACP,SAAS,CAAC,CACV,SAAS,wDAAwD;AACtE,CAAC;;AAED,MAAa,qBAAqB,EAAE,OAAO;CACzC,OAAO,EAAE,OAAO,CAAC,CAAC,SAAS,oDAAoD;CAC/E,OAAO,EACJ,MAAM,kBAAkB,CAAC,CACzB,SAAS,CAAC,CACV,SAAS,8CAA8C;CAC1D,YAAY,EACT,OAAO,CAAC,CACR,IAAI,CAAC,CACL,YAAY,CAAC,CACb,SAAS,CAAC,CACV,SAAS,yEAAyE;CACrF,YAAY,aACT,SAAS,CAAC,CACV,SAAS,oDAAoD;AAClE,CAAC"}
@@ -0,0 +1,49 @@
1
+ import { z } from "zod";
2
+ //#region src/approval.d.ts
3
+ /** Validates an open priority label used to match admission policy subjects. */
4
+ declare const approvalPrioritySchema: z.ZodString;
5
+ /**
6
+ * One approval rule. Every listed field must match for the rule to apply;
7
+ * absent fields match anything. Rules are evaluated first-match.
8
+ */
9
+ declare const approvalRuleSchema: z.ZodReadonly<z.ZodObject<{
10
+ source: z.ZodOptional<z.ZodString>;
11
+ kind: z.ZodOptional<z.ZodString>;
12
+ priority: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodString>>>;
13
+ require: z.ZodBoolean;
14
+ }, z.core.$strict>>;
15
+ /** Validates an ordered, first-match set of Task approval rules. */
16
+ declare const approvalPolicySchema: z.ZodReadonly<z.ZodArray<z.ZodReadonly<z.ZodObject<{
17
+ source: z.ZodOptional<z.ZodString>;
18
+ kind: z.ZodOptional<z.ZodString>;
19
+ priority: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodString>>>;
20
+ require: z.ZodBoolean;
21
+ }, z.core.$strict>>>>;
22
+ /** One first-match condition that decides whether admitted work requires approval. */
23
+ type ApprovalRule = z.infer<typeof approvalRuleSchema>;
24
+ /** Ordered admission policy that stamps a Task's approval requirement once. */
25
+ type ApprovalPolicy = z.infer<typeof approvalPolicySchema>;
26
+ /** Open priority label compared exactly by approval policy. */
27
+ type ApprovalPriority = z.infer<typeof approvalPrioritySchema>;
28
+ /** Neutral framework default when an application does not select an approval policy. */
29
+ declare const allowByDefaultApprovalPolicy: readonly Readonly<{
30
+ require: boolean;
31
+ source?: string | undefined;
32
+ kind?: string | undefined;
33
+ priority?: readonly string[] | undefined;
34
+ }>[];
35
+ /** Immutable intake attributes evaluated against an approval policy. */
36
+ interface ApprovalSubject {
37
+ source?: string;
38
+ kind: string;
39
+ priority?: string;
40
+ }
41
+ /**
42
+ * Decide at task-creation time whether a task needs approval. Pure: the answer
43
+ * is stamped on the task and never re-evaluated, so a later policy change
44
+ * cannot silently release work a human was expecting to see.
45
+ */
46
+ declare function requiresApproval(policy: ApprovalPolicy, subject: ApprovalSubject): boolean;
47
+ //#endregion
48
+ export { ApprovalPolicy, ApprovalPriority, ApprovalRule, ApprovalSubject, allowByDefaultApprovalPolicy, approvalPolicySchema, approvalPrioritySchema, approvalRuleSchema, requiresApproval };
49
+ //# sourceMappingURL=approval.d.mts.map
@@ -0,0 +1,39 @@
1
+ import { vocabularySchema } from "./schema/common.mjs";
2
+ import { z } from "zod";
3
+ //#region src/approval.ts
4
+ /** Validates an open priority label used to match admission policy subjects. */
5
+ const approvalPrioritySchema = z.string().min(1).max(64).describe("Priority label compared exactly, e.g. P0, P1, urgent, or a custom domain value.");
6
+ /**
7
+ * One approval rule. Every listed field must match for the rule to apply;
8
+ * absent fields match anything. Rules are evaluated first-match.
9
+ */
10
+ const approvalRuleSchema = z.strictObject({
11
+ source: vocabularySchema.optional().describe("Signal source, e.g. security_scan or github_issue."),
12
+ kind: vocabularySchema.optional().describe("Task kind, e.g. code_change."),
13
+ priority: z.array(approvalPrioritySchema).min(1).readonly().optional().describe("Finding priorities the rule applies to."),
14
+ require: z.boolean().describe("Whether matching tasks wait for a human before dispatch.")
15
+ }).readonly();
16
+ /** Validates an ordered, first-match set of Task approval rules. */
17
+ const approvalPolicySchema = z.array(approvalRuleSchema).readonly().describe("First-match rules deciding which tasks need a human before they run.");
18
+ /** Neutral framework default when an application does not select an approval policy. */
19
+ const allowByDefaultApprovalPolicy = approvalPolicySchema.parse([{ require: false }]);
20
+ /**
21
+ * Decide at task-creation time whether a task needs approval. Pure: the answer
22
+ * is stamped on the task and never re-evaluated, so a later policy change
23
+ * cannot silently release work a human was expecting to see.
24
+ */
25
+ function requiresApproval(policy, subject) {
26
+ for (const rule of policy) {
27
+ if (rule.source !== void 0 && rule.source !== subject.source) continue;
28
+ if (rule.kind !== void 0 && rule.kind !== subject.kind) continue;
29
+ if (rule.priority !== void 0) {
30
+ if (subject.priority === void 0 || !rule.priority.includes(subject.priority)) continue;
31
+ }
32
+ return rule.require;
33
+ }
34
+ return false;
35
+ }
36
+ //#endregion
37
+ export { allowByDefaultApprovalPolicy, approvalPolicySchema, approvalPrioritySchema, approvalRuleSchema, requiresApproval };
38
+
39
+ //# sourceMappingURL=approval.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"approval.mjs","names":[],"sources":["../src/approval.ts"],"sourcesContent":["import { z } from \"zod\";\nimport { vocabularySchema } from \"./schema/common\";\n\n/** Validates an open priority label used to match admission policy subjects. */\nexport const approvalPrioritySchema = z\n .string()\n .min(1)\n .max(64)\n .describe(\"Priority label compared exactly, e.g. P0, P1, urgent, or a custom domain value.\");\n\n/**\n * One approval rule. Every listed field must match for the rule to apply;\n * absent fields match anything. Rules are evaluated first-match.\n */\nexport const approvalRuleSchema = z\n .strictObject({\n source: vocabularySchema\n .optional()\n .describe(\"Signal source, e.g. security_scan or github_issue.\"),\n kind: vocabularySchema.optional().describe(\"Task kind, e.g. code_change.\"),\n priority: z\n .array(approvalPrioritySchema)\n .min(1)\n .readonly()\n .optional()\n .describe(\"Finding priorities the rule applies to.\"),\n require: z.boolean().describe(\"Whether matching tasks wait for a human before dispatch.\"),\n })\n .readonly();\n\n/** Validates an ordered, first-match set of Task approval rules. */\nexport const approvalPolicySchema = z\n .array(approvalRuleSchema)\n .readonly()\n .describe(\"First-match rules deciding which tasks need a human before they run.\");\n\n/** One first-match condition that decides whether admitted work requires approval. */\nexport type ApprovalRule = z.infer<typeof approvalRuleSchema>;\n/** Ordered admission policy that stamps a Task's approval requirement once. */\nexport type ApprovalPolicy = z.infer<typeof approvalPolicySchema>;\n/** Open priority label compared exactly by approval policy. */\nexport type ApprovalPriority = z.infer<typeof approvalPrioritySchema>;\n\n/** Neutral framework default when an application does not select an approval policy. */\nexport const allowByDefaultApprovalPolicy = approvalPolicySchema.parse([{ require: false }]);\n\n/** Immutable intake attributes evaluated against an approval policy. */\nexport interface ApprovalSubject {\n source?: string;\n kind: string;\n priority?: string;\n}\n\n/**\n * Decide at task-creation time whether a task needs approval. Pure: the answer\n * is stamped on the task and never re-evaluated, so a later policy change\n * cannot silently release work a human was expecting to see.\n */\nexport function requiresApproval(policy: ApprovalPolicy, subject: ApprovalSubject): boolean {\n for (const rule of policy) {\n if (rule.source !== undefined && rule.source !== subject.source) continue;\n if (rule.kind !== undefined && rule.kind !== subject.kind) continue;\n if (rule.priority !== undefined) {\n if (subject.priority === undefined || !rule.priority.includes(subject.priority)) continue;\n }\n return rule.require;\n }\n return false;\n}\n"],"mappings":";;;;AAIA,MAAa,yBAAyB,EACnC,OAAO,CAAC,CACR,IAAI,CAAC,CAAC,CACN,IAAI,EAAE,CAAC,CACP,SAAS,iFAAiF;;;;;AAM7F,MAAa,qBAAqB,EAC/B,aAAa;CACZ,QAAQ,iBACL,SAAS,CAAC,CACV,SAAS,oDAAoD;CAChE,MAAM,iBAAiB,SAAS,CAAC,CAAC,SAAS,8BAA8B;CACzE,UAAU,EACP,MAAM,sBAAsB,CAAC,CAC7B,IAAI,CAAC,CAAC,CACN,SAAS,CAAC,CACV,SAAS,CAAC,CACV,SAAS,yCAAyC;CACrD,SAAS,EAAE,QAAQ,CAAC,CAAC,SAAS,0DAA0D;AAC1F,CAAC,CAAC,CACD,SAAS;;AAGZ,MAAa,uBAAuB,EACjC,MAAM,kBAAkB,CAAC,CACzB,SAAS,CAAC,CACV,SAAS,sEAAsE;;AAUlF,MAAa,+BAA+B,qBAAqB,MAAM,CAAC,EAAE,SAAS,MAAM,CAAC,CAAC;;;;;;AAc3F,SAAgB,iBAAiB,QAAwB,SAAmC;CAC1F,KAAK,MAAM,QAAQ,QAAQ;EACzB,IAAI,KAAK,WAAW,KAAA,KAAa,KAAK,WAAW,QAAQ,QAAQ;EACjE,IAAI,KAAK,SAAS,KAAA,KAAa,KAAK,SAAS,QAAQ,MAAM;EAC3D,IAAI,KAAK,aAAa,KAAA,GAChB;OAAA,QAAQ,aAAa,KAAA,KAAa,CAAC,KAAK,SAAS,SAAS,QAAQ,QAAQ,GAAG;EAAA;EAEnF,OAAO,KAAK;CACd;CACA,OAAO;AACT"}
@@ -0,0 +1,37 @@
1
+ import { TaskId } from "../schema/id.mjs";
2
+ import { TaskAttemptRef } from "../schema/execution.mjs";
3
+ import { BlobClient } from "./index.mjs";
4
+ import { z } from "zod";
5
+ //#region src/blob/artifacts.d.ts
6
+ declare const artifactRefSchema: z.core.$ZodBranded<z.ZodString, "ArtifactRef", "out">;
7
+ /** A content-addressed reference that binds an artifact to its owning Task attempt and kind. */
8
+ type ArtifactRef = z.infer<typeof artifactRefSchema>;
9
+ /** Valid syntax grants neither read authority nor proof that an artifact exists. */
10
+ declare function parseArtifactRef(value: unknown): ArtifactRef;
11
+ /** Artifact kinds accepted by the Task-bound content-addressed store. */
12
+ type ArtifactKind = "patch" | "report" | "log";
13
+ /** Task attempt, kind, and encoded body used to derive or persist an artifact. */
14
+ interface ArtifactInput extends TaskAttemptRef {
15
+ kind: ArtifactKind;
16
+ /** Binary artifacts use base64. */
17
+ body: string;
18
+ }
19
+ /** Artifact reference and authorized owning Task used for one verified read. */
20
+ interface ReadArtifactInput {
21
+ ref: ArtifactRef;
22
+ taskId: TaskId;
23
+ }
24
+ /** Persists and retrieves content-addressed artifacts within a Task authorization boundary. */
25
+ interface ArtifactStore {
26
+ /** Content-addressed and therefore idempotent; returns the durable reference. */
27
+ put(artifact: ArtifactInput): Promise<ArtifactRef>;
28
+ /** Reads require the owning Task and re-verify the content digest. */
29
+ read(input: ReadArtifactInput): Promise<string>;
30
+ }
31
+ /** Derive a validated, content-addressed reference for an artifact without writing it. */
32
+ declare function artifactReference(artifact: ArtifactInput): ArtifactRef;
33
+ /** Create a Task-bound artifact store that verifies ownership and content digests on reads. */
34
+ declare function createArtifactStore(client: BlobClient): ArtifactStore;
35
+ //#endregion
36
+ export { ArtifactInput, ArtifactKind, ArtifactRef, ArtifactStore, ReadArtifactInput, artifactReference, createArtifactStore, parseArtifactRef };
37
+ //# sourceMappingURL=artifacts.d.mts.map
@@ -0,0 +1,45 @@
1
+ import { createHash } from "node:crypto";
2
+ import { z } from "zod";
3
+ //#region src/blob/artifacts.ts
4
+ const artifactRefPattern = /^factory-artifacts\/(task_[a-z0-9]{6,64})\/([1-9]\d{0,8})\/(patch|report|log)\/([0-9a-f]{64})$/u;
5
+ const artifactRefSchema = z.string().regex(artifactRefPattern, "Unrecognized artifact reference").brand();
6
+ /** Valid syntax grants neither read authority nor proof that an artifact exists. */
7
+ function parseArtifactRef(value) {
8
+ return artifactRefSchema.parse(value);
9
+ }
10
+ const sha256 = (body) => createHash("sha256").update(body).digest("hex");
11
+ /** Derive a validated, content-addressed reference for an artifact without writing it. */
12
+ function artifactReference(artifact) {
13
+ const ref = `factory-artifacts/${artifact.taskId}/${artifact.attempt}/${artifact.kind}/${sha256(artifact.body)}`;
14
+ if (!artifactRefPattern.test(ref)) throw new Error("Artifact reference requires a valid Task ID, attempt, and kind");
15
+ return parseArtifactRef(ref);
16
+ }
17
+ /** Create a Task-bound artifact store that verifies ownership and content digests on reads. */
18
+ function createArtifactStore(client) {
19
+ return {
20
+ async put(artifact) {
21
+ const ref = artifactReference(artifact);
22
+ await client.write({
23
+ pathname: ref,
24
+ body: artifact.body,
25
+ overwrite: true
26
+ });
27
+ return ref;
28
+ },
29
+ async read({ ref, taskId: authorizedTaskId }) {
30
+ const parsed = parseArtifactRef(ref);
31
+ const match = artifactRefPattern.exec(parsed);
32
+ if (!match) throw new Error("Unrecognized artifact reference");
33
+ const [, taskId, , , digest] = match;
34
+ if (taskId !== authorizedTaskId) throw new Error(`Artifact belongs to ${taskId}, not to the authorized Task ${authorizedTaskId}`);
35
+ const stored = await client.read({ pathname: parsed });
36
+ if (!stored) throw new Error(`Artifact ${ref} is unavailable`);
37
+ if (sha256(stored.body) !== digest) throw new Error(`Artifact ${ref} content does not match its digest`);
38
+ return stored.body;
39
+ }
40
+ };
41
+ }
42
+ //#endregion
43
+ export { artifactReference, createArtifactStore, parseArtifactRef };
44
+
45
+ //# sourceMappingURL=artifacts.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"artifacts.mjs","names":[],"sources":["../../src/blob/artifacts.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport type { BlobClient } from \"./index\";\nimport type { TaskAttemptRef } from \"../schema/execution\";\nimport type { TaskId } from \"../schema/id\";\nimport { z } from \"zod\";\n\nconst artifactRefPattern =\n /^factory-artifacts\\/(task_[a-z0-9]{6,64})\\/([1-9]\\d{0,8})\\/(patch|report|log)\\/([0-9a-f]{64})$/u;\nconst artifactRefSchema = z\n .string()\n .regex(artifactRefPattern, \"Unrecognized artifact reference\")\n .brand<\"ArtifactRef\">();\n\n/** A content-addressed reference that binds an artifact to its owning Task attempt and kind. */\nexport type ArtifactRef = z.infer<typeof artifactRefSchema>;\n\n/** Valid syntax grants neither read authority nor proof that an artifact exists. */\nexport function parseArtifactRef(value: unknown): ArtifactRef {\n return artifactRefSchema.parse(value);\n}\n\n/** Artifact kinds accepted by the Task-bound content-addressed store. */\nexport type ArtifactKind = \"patch\" | \"report\" | \"log\";\n\n/** Task attempt, kind, and encoded body used to derive or persist an artifact. */\nexport interface ArtifactInput extends TaskAttemptRef {\n kind: ArtifactKind;\n /** Binary artifacts use base64. */\n body: string;\n}\n\n/** Artifact reference and authorized owning Task used for one verified read. */\nexport interface ReadArtifactInput {\n ref: ArtifactRef;\n taskId: TaskId;\n}\n\n/** Persists and retrieves content-addressed artifacts within a Task authorization boundary. */\nexport interface ArtifactStore {\n /** Content-addressed and therefore idempotent; returns the durable reference. */\n put(artifact: ArtifactInput): Promise<ArtifactRef>;\n /** Reads require the owning Task and re-verify the content digest. */\n read(input: ReadArtifactInput): Promise<string>;\n}\n\nconst sha256 = (body: string) => createHash(\"sha256\").update(body).digest(\"hex\");\n\n/** Derive a validated, content-addressed reference for an artifact without writing it. */\nexport function artifactReference(artifact: ArtifactInput): ArtifactRef {\n const ref = `factory-artifacts/${artifact.taskId}/${artifact.attempt}/${artifact.kind}/${sha256(artifact.body)}`;\n if (!artifactRefPattern.test(ref)) {\n throw new Error(\"Artifact reference requires a valid Task ID, attempt, and kind\");\n }\n return parseArtifactRef(ref);\n}\n\n/** Create a Task-bound artifact store that verifies ownership and content digests on reads. */\nexport function createArtifactStore(client: BlobClient): ArtifactStore {\n return {\n async put(artifact) {\n const ref = artifactReference(artifact);\n // Same path implies same content, so overwriting is safe and retryable.\n await client.write({ pathname: ref, body: artifact.body, overwrite: true });\n return ref;\n },\n async read({ ref, taskId: authorizedTaskId }) {\n const parsed = parseArtifactRef(ref);\n const match = artifactRefPattern.exec(parsed);\n if (!match) throw new Error(\"Unrecognized artifact reference\");\n const [, taskId, , , digest] = match;\n if (taskId !== authorizedTaskId) {\n throw new Error(\n `Artifact belongs to ${taskId}, not to the authorized Task ${authorizedTaskId}`,\n );\n }\n const stored = await client.read({ pathname: parsed });\n if (!stored) throw new Error(`Artifact ${ref} is unavailable`);\n if (sha256(stored.body) !== digest) {\n throw new Error(`Artifact ${ref} content does not match its digest`);\n }\n return stored.body;\n },\n };\n}\n"],"mappings":";;;AAMA,MAAM,qBACJ;AACF,MAAM,oBAAoB,EACvB,OAAO,CAAC,CACR,MAAM,oBAAoB,iCAAiC,CAAC,CAC5D,MAAqB;;AAMxB,SAAgB,iBAAiB,OAA6B;CAC5D,OAAO,kBAAkB,MAAM,KAAK;AACtC;AA0BA,MAAM,UAAU,SAAiB,WAAW,QAAQ,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,OAAO,KAAK;;AAG/E,SAAgB,kBAAkB,UAAsC;CACtE,MAAM,MAAM,qBAAqB,SAAS,OAAO,GAAG,SAAS,QAAQ,GAAG,SAAS,KAAK,GAAG,OAAO,SAAS,IAAI;CAC7G,IAAI,CAAC,mBAAmB,KAAK,GAAG,GAC9B,MAAM,IAAI,MAAM,gEAAgE;CAElF,OAAO,iBAAiB,GAAG;AAC7B;;AAGA,SAAgB,oBAAoB,QAAmC;CACrE,OAAO;EACL,MAAM,IAAI,UAAU;GAClB,MAAM,MAAM,kBAAkB,QAAQ;GAEtC,MAAM,OAAO,MAAM;IAAE,UAAU;IAAK,MAAM,SAAS;IAAM,WAAW;GAAK,CAAC;GAC1E,OAAO;EACT;EACA,MAAM,KAAK,EAAE,KAAK,QAAQ,oBAAoB;GAC5C,MAAM,SAAS,iBAAiB,GAAG;GACnC,MAAM,QAAQ,mBAAmB,KAAK,MAAM;GAC5C,IAAI,CAAC,OAAO,MAAM,IAAI,MAAM,iCAAiC;GAC7D,MAAM,GAAG,YAAY,UAAU;GAC/B,IAAI,WAAW,kBACb,MAAM,IAAI,MACR,uBAAuB,OAAO,+BAA+B,kBAC/D;GAEF,MAAM,SAAS,MAAM,OAAO,KAAK,EAAE,UAAU,OAAO,CAAC;GACrD,IAAI,CAAC,QAAQ,MAAM,IAAI,MAAM,YAAY,IAAI,gBAAgB;GAC7D,IAAI,OAAO,OAAO,IAAI,MAAM,QAC1B,MAAM,IAAI,MAAM,YAAY,IAAI,mCAAmC;GAErE,OAAO,OAAO;EAChB;CACF;AACF"}
@@ -1,32 +1,68 @@
1
- import { i as StoreDriver } from "../driver-BJutB0PE.mjs";
1
+ import { MillisecondClock } from "../schema/common.mjs";
2
+ import { StoreDriver } from "../store/driver.mjs";
3
+ import { ArtifactInput, ArtifactKind, ArtifactRef, ArtifactStore, ReadArtifactInput, artifactReference, createArtifactStore, parseArtifactRef } from "./artifacts.mjs";
2
4
  //#region src/blob/index.d.ts
5
+ /** Blob content paired with the ETag required for compare-and-swap persistence. */
3
6
  interface BlobObject {
4
7
  body: string;
5
8
  etag: string;
6
9
  }
10
+ /** Exact blob pathname requested from storage. */
11
+ interface ReadBlobInput {
12
+ pathname: string;
13
+ }
14
+ /** Blob body and conditional-write policy used for one storage write. */
15
+ interface WriteBlobInput extends ReadBlobInput {
16
+ body: string;
17
+ overwrite: boolean;
18
+ ifMatch?: string;
19
+ }
20
+ /** Path prefix used to list matching blobs. */
21
+ interface ListBlobPathsInput {
22
+ prefix: string;
23
+ }
7
24
  /** The narrow blob operations the driver needs; injectable for tests. */
8
25
  interface BlobClient {
9
26
  /** Must return the latest content, never a cached copy. */
10
- read(pathname: string): Promise<BlobObject | null>;
27
+ read(input: ReadBlobInput): Promise<BlobObject | null>;
11
28
  /** Must reject if overwrite is false and the path exists, or if ifMatch is given and the ETag differs. */
12
- write(pathname: string, body: string, overwrite: boolean, ifMatch?: string): Promise<void>;
13
- listPaths(prefix: string): Promise<string[]>;
29
+ write(input: WriteBlobInput): Promise<void>;
30
+ listPaths(input: ListBlobPathsInput): Promise<readonly string[]>;
14
31
  }
32
+ /** Default private Vercel Blob client used by the durable Factory store driver. */
15
33
  declare const vercelBlobClient: BlobClient;
34
+ /** Bounds retries and exponential backoff for transient Blob operations. */
35
+ interface BlobRetryOptions {
36
+ /** Maximum attempts of a single read or write, including the first. Default 3. */
37
+ attempts?: number;
38
+ /** Backoff base in milliseconds; doubles each retry. Default 250. */
39
+ baseDelayMs?: number;
40
+ /** Ceiling on total elapsed retry time so a real outage still surfaces as a failure. Default 5000. */
41
+ maxTotalMs?: number;
42
+ }
43
+ /** Configures the Blob client, namespace, read concurrency, and transient retries. */
16
44
  interface BlobDriverOptions {
17
45
  client?: BlobClient;
18
46
  /** Path prefix inside the blob store; defaults to "factory". */
19
47
  prefix?: string;
48
+ /** Maximum Blob downloads in flight while listing a collection. Default 32. */
49
+ readConcurrency?: number;
50
+ /** Bounds retry of transient (5xx/429/network) Blob failures on reads and writes. */
51
+ retry?: BlobRetryOptions;
52
+ /** Millisecond clock used to bound total retry time. */
53
+ now?: MillisecondClock;
20
54
  }
21
55
  /**
22
56
  * Store driver on Vercel Blob: durable and dependency-free (one Blob store on
23
- * the project, no database). Inserts and receipts are exactly as safe as on
24
- * Postgres (create-if-absent is atomic). Updates read the latest content,
57
+ * the project, no database). Inserts are create-if-absent. Updates read the latest content,
25
58
  * bypassing Blob's CDN cache, and write with an ETag precondition, so a
26
59
  * writer that lost a race gets a VersionConflictError rather than
27
- * overwriting the winner.
60
+ * overwriting the winner. Reads and writes retry with backoff on transient
61
+ * (5xx/429/network) failures, bounded by attempts and total elapsed time;
62
+ * once exhausted, the failure surfaces as TransientStoreError so a real
63
+ * outage does not hang a caller retrying forever.
28
64
  */
29
65
  declare function createBlobDriver(options?: BlobDriverOptions): StoreDriver;
30
66
  //#endregion
31
- export { BlobClient, BlobDriverOptions, BlobObject, createBlobDriver, vercelBlobClient };
67
+ export { type ArtifactInput, type ArtifactKind, type ArtifactRef, type ArtifactStore, BlobClient, BlobDriverOptions, BlobObject, BlobRetryOptions, ListBlobPathsInput, type ReadArtifactInput, ReadBlobInput, WriteBlobInput, artifactReference, createArtifactStore, createBlobDriver, parseArtifactRef, vercelBlobClient };
32
68
  //# sourceMappingURL=index.d.mts.map
@@ -1,4 +1,5 @@
1
- import { n as RecordNotFoundError, r as VersionConflictError, t as RecordExistsError } from "../driver-Bbd25rNM.mjs";
1
+ import { RecordExistsError, RecordNotFoundError, TransientStoreError, VersionConflictError } from "../store/driver.mjs";
2
+ import { artifactReference, createArtifactStore, parseArtifactRef } from "./artifacts.mjs";
2
3
  import { get, list, put } from "@vercel/blob";
3
4
  //#region src/blob/index.ts
4
5
  function isNotFoundError(error) {
@@ -10,8 +11,44 @@ function isAlreadyExistsError(error) {
10
11
  function isPreconditionError(error) {
11
12
  return error instanceof Error && (error.name === "BlobPreconditionFailedError" || /precondition|etag|412/iu.test(error.message));
12
13
  }
14
+ const TRANSIENT_NETWORK_ERROR_CODES = /* @__PURE__ */ new Set([
15
+ "ECONNRESET",
16
+ "ECONNREFUSED",
17
+ "ETIMEDOUT",
18
+ "ENOTFOUND",
19
+ "EAI_AGAIN",
20
+ "EPIPE",
21
+ "EHOSTUNREACH",
22
+ "ENETUNREACH",
23
+ "UND_ERR_CONNECT_TIMEOUT",
24
+ "UND_ERR_SOCKET",
25
+ "UND_ERR_HEADERS_TIMEOUT"
26
+ ]);
27
+ function isTransientBlobError(error) {
28
+ if (!(error instanceof Error)) return false;
29
+ if (isAlreadyExistsError(error) || isPreconditionError(error) || isNotFoundError(error)) return false;
30
+ const code = error.code;
31
+ if (code !== void 0 && TRANSIENT_NETWORK_ERROR_CODES.has(code)) return true;
32
+ if (error.name === "AbortError") return true;
33
+ if (/fetch failed|network|socket hang up|timed? ?out|ECONNRESET|ECONNREFUSED|ETIMEDOUT|ENOTFOUND|EAI_AGAIN/iu.test(error.message)) return true;
34
+ return /(?:^|[^0-9])(?:429|5\d{2})(?:[^0-9]|$)/u.test(error.message);
35
+ }
36
+ function jsonValuesEqual(a, b) {
37
+ if (a === b) return true;
38
+ if (typeof a !== typeof b) return false;
39
+ if (a === null || b === null || typeof a !== "object" || typeof b !== "object") return false;
40
+ if (Array.isArray(a) || Array.isArray(b)) {
41
+ if (!Array.isArray(a) || !Array.isArray(b) || a.length !== b.length) return false;
42
+ return a.every((item, index) => jsonValuesEqual(item, b[index]));
43
+ }
44
+ const aKeys = Object.keys(a);
45
+ const bKeys = Object.keys(b);
46
+ if (aKeys.length !== bKeys.length) return false;
47
+ return aKeys.every((key) => Object.hasOwn(b, key) && jsonValuesEqual(a[key], b[key]));
48
+ }
49
+ /** Default private Vercel Blob client used by the durable Factory store driver. */
13
50
  const vercelBlobClient = {
14
- async read(pathname) {
51
+ async read({ pathname }) {
15
52
  let result;
16
53
  try {
17
54
  result = await get(pathname, {
@@ -28,15 +65,15 @@ const vercelBlobClient = {
28
65
  etag: result.blob.etag
29
66
  };
30
67
  },
31
- async write(pathname, body, overwrite, ifMatch) {
32
- await put(pathname, body, {
68
+ async write({ pathname, body, overwrite, ifMatch }) {
69
+ await put(pathname, body === "" ? Buffer.alloc(0) : body, {
33
70
  access: "private",
34
71
  allowOverwrite: overwrite,
35
72
  contentType: "application/json",
36
- ...ifMatch === void 0 ? {} : { ifMatch }
73
+ ...ifMatch === void 0 ? {} : { ifMatch: ifMatch.replace(/^W\//u, "") }
37
74
  });
38
75
  },
39
- async listPaths(prefix) {
76
+ async listPaths({ prefix }) {
40
77
  const paths = [];
41
78
  let cursor;
42
79
  do {
@@ -53,22 +90,57 @@ const vercelBlobClient = {
53
90
  };
54
91
  /**
55
92
  * Store driver on Vercel Blob: durable and dependency-free (one Blob store on
56
- * the project, no database). Inserts and receipts are exactly as safe as on
57
- * Postgres (create-if-absent is atomic). Updates read the latest content,
93
+ * the project, no database). Inserts are create-if-absent. Updates read the latest content,
58
94
  * bypassing Blob's CDN cache, and write with an ETag precondition, so a
59
95
  * writer that lost a race gets a VersionConflictError rather than
60
- * overwriting the winner.
96
+ * overwriting the winner. Reads and writes retry with backoff on transient
97
+ * (5xx/429/network) failures, bounded by attempts and total elapsed time;
98
+ * once exhausted, the failure surfaces as TransientStoreError so a real
99
+ * outage does not hang a caller retrying forever.
61
100
  */
62
101
  function createBlobDriver(options = {}) {
63
102
  const client = options.client ?? vercelBlobClient;
103
+ const now = options.now ?? Date.now;
64
104
  const prefix = options.prefix ?? "factory";
105
+ const readConcurrency = options.readConcurrency ?? 32;
106
+ if (!Number.isInteger(readConcurrency) || readConcurrency < 1) throw new Error("Blob read concurrency must be a positive integer");
107
+ const retry = {
108
+ attempts: options.retry?.attempts ?? 3,
109
+ baseDelayMs: options.retry?.baseDelayMs ?? 250,
110
+ maxTotalMs: options.retry?.maxTotalMs ?? 5e3
111
+ };
112
+ let activeReads = 0;
113
+ const readWaiters = [];
114
+ const activeLists = /* @__PURE__ */ new Map();
115
+ async function withTransientRetry(collection, id, operation) {
116
+ const start = now();
117
+ for (let attempt = 0;; attempt += 1) try {
118
+ return await operation();
119
+ } catch (error) {
120
+ if (!isTransientBlobError(error)) throw error;
121
+ const nextDelayMs = retry.baseDelayMs * 2 ** attempt;
122
+ if (attempt >= retry.attempts - 1 || now() - start + nextDelayMs > retry.maxTotalMs) throw new TransientStoreError(collection, id, error);
123
+ await new Promise((resolve) => setTimeout(resolve, nextDelayMs));
124
+ }
125
+ }
126
+ async function limitedRead(pathname) {
127
+ if (activeReads < readConcurrency) activeReads += 1;
128
+ else await new Promise((resolve) => readWaiters.push(resolve));
129
+ try {
130
+ return await client.read({ pathname });
131
+ } finally {
132
+ const waiter = readWaiters.shift();
133
+ if (waiter === void 0) activeReads -= 1;
134
+ else waiter();
135
+ }
136
+ }
65
137
  function pathFor(collection, id) {
66
138
  return `${prefix}/${collection}/${id}.json`;
67
139
  }
68
140
  async function readRecord(collection, id) {
69
141
  let object;
70
142
  try {
71
- object = await client.read(pathFor(collection, id));
143
+ object = await withTransientRetry(collection, id, () => limitedRead(pathFor(collection, id)));
72
144
  } catch (error) {
73
145
  if (isNotFoundError(error)) return null;
74
146
  throw error;
@@ -82,6 +154,14 @@ function createBlobDriver(options = {}) {
82
154
  etag: object.etag
83
155
  };
84
156
  }
157
+ async function wroteThisInsert(collection, id, value) {
158
+ const after = await readRecord(collection, id);
159
+ return after !== null && after.version === 1 && jsonValuesEqual(after.value, value);
160
+ }
161
+ async function wroteThisUpdate(collection, id, value, expectedNewVersion) {
162
+ const after = await readRecord(collection, id);
163
+ return after !== null && after.version === expectedNewVersion && jsonValuesEqual(after.value, value);
164
+ }
85
165
  return {
86
166
  name: "blob",
87
167
  async get(collection, id) {
@@ -91,51 +171,95 @@ function createBlobDriver(options = {}) {
91
171
  version: record.version
92
172
  };
93
173
  },
94
- async insert(collection, id, value) {
174
+ async insert({ collection, id, value }) {
175
+ let attempts = 0;
95
176
  try {
96
- await client.write(pathFor(collection, id), JSON.stringify({
97
- value,
98
- version: 1
99
- }), false);
177
+ await withTransientRetry(collection, id, () => {
178
+ attempts += 1;
179
+ return client.write({
180
+ pathname: pathFor(collection, id),
181
+ body: JSON.stringify({
182
+ value,
183
+ version: 1
184
+ }),
185
+ overwrite: false
186
+ });
187
+ });
100
188
  } catch (error) {
101
- if (isAlreadyExistsError(error)) throw new RecordExistsError(collection, id);
189
+ if (isAlreadyExistsError(error)) {
190
+ if (attempts > 1 && await wroteThisInsert(collection, id, value)) return;
191
+ throw new RecordExistsError(collection, id);
192
+ }
102
193
  throw error;
103
194
  }
104
195
  },
105
- async update(collection, id, value, expectedVersion) {
196
+ async update({ collection, id, value, expectedVersion }) {
106
197
  const existing = await readRecord(collection, id);
107
198
  if (existing === null) throw new RecordNotFoundError(collection, id);
108
199
  if (existing.version !== expectedVersion) throw new VersionConflictError(collection, id, expectedVersion);
200
+ let attempts = 0;
109
201
  try {
110
- await client.write(pathFor(collection, id), JSON.stringify({
111
- value,
112
- version: expectedVersion + 1
113
- }), true, existing.etag.replace(/^W\//u, ""));
202
+ await withTransientRetry(collection, id, () => {
203
+ attempts += 1;
204
+ return client.write({
205
+ pathname: pathFor(collection, id),
206
+ body: JSON.stringify({
207
+ value,
208
+ version: expectedVersion + 1
209
+ }),
210
+ overwrite: true,
211
+ ifMatch: existing.etag.replace(/^W\//u, "")
212
+ });
213
+ });
114
214
  } catch (error) {
115
- if (isPreconditionError(error)) throw new VersionConflictError(collection, id, expectedVersion);
215
+ if (isPreconditionError(error)) {
216
+ if (attempts > 1 && await wroteThisUpdate(collection, id, value, expectedVersion + 1)) return;
217
+ throw new VersionConflictError(collection, id, expectedVersion);
218
+ }
116
219
  throw error;
117
220
  }
118
221
  },
119
222
  async list(collection) {
120
- const dir = `${prefix}/${collection}/`;
121
- const paths = await client.listPaths(dir);
122
- const entries = [];
123
- for (const pathname of paths) {
124
- const id = pathname.slice(dir.length).replace(/\.json$/u, "");
125
- const record = await readRecord(collection, id);
126
- if (record !== null) entries.push({
127
- id,
128
- record: {
129
- value: record.value,
130
- version: record.version
223
+ const active = activeLists.get(collection);
224
+ if (active !== void 0) return active;
225
+ const listing = (async () => {
226
+ const dir = `${prefix}/${collection}/`;
227
+ const paths = await client.listPaths({ prefix: dir });
228
+ const entries = new Array(paths.length);
229
+ let next = 0;
230
+ let failure;
231
+ const workers = Array.from({ length: Math.min(readConcurrency, paths.length) }, async () => {
232
+ while (next < paths.length && failure === void 0) {
233
+ const index = next++;
234
+ const id = paths[index].slice(dir.length).replace(/\.json$/u, "");
235
+ try {
236
+ const record = await readRecord(collection, id);
237
+ entries[index] = record === null ? null : {
238
+ id,
239
+ record: {
240
+ value: record.value,
241
+ version: record.version
242
+ }
243
+ };
244
+ } catch (error) {
245
+ failure ??= error;
246
+ }
131
247
  }
132
248
  });
249
+ await Promise.all(workers);
250
+ if (failure !== void 0) throw failure;
251
+ return entries.filter((entry) => entry !== null);
252
+ })();
253
+ activeLists.set(collection, listing);
254
+ try {
255
+ return await listing;
256
+ } finally {
257
+ if (activeLists.get(collection) === listing) activeLists.delete(collection);
133
258
  }
134
- return entries;
135
259
  }
136
260
  };
137
261
  }
138
262
  //#endregion
139
- export { createBlobDriver, vercelBlobClient };
263
+ export { artifactReference, createArtifactStore, createBlobDriver, parseArtifactRef, vercelBlobClient };
140
264
 
141
265
  //# sourceMappingURL=index.mjs.map