@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
@@ -1,29 +1,7 @@
1
- import { a as repositoryIdsSchema, s as taskIdSchema, t as changeIdSchema, u as replyToSchema } from "../id-DwCihQr4.mjs";
2
- import { z } from "zod";
1
+ import { communicationEventSchema, communicationOutcomeSchema, communicationOutcomes } from "../schema/communication.mjs";
2
+ import { createOutboxCommunicationRouter, sweepCommunicationOutbox } from "./outbox.mjs";
3
3
  //#region src/connectors/index.ts
4
- const communicationOutcomes = [
5
- "accepted",
6
- "started",
7
- "succeeded",
8
- "failed",
9
- "needs_human",
10
- "question",
11
- "digest",
12
- "rolled_back",
13
- "budget_warning",
14
- "budget_exhausted",
15
- "message"
16
- ];
17
- const communicationOutcomeSchema = z.enum(communicationOutcomes).describe("Lifecycle outcome a connector should render and deliver.");
18
- const communicationEventSchema = z.strictObject({
19
- eventId: z.string().min(1).describe("Stable idempotency key for this delivery."),
20
- repositoryIds: repositoryIdsSchema,
21
- taskId: taskIdSchema.optional(),
22
- changeId: changeIdSchema.optional(),
23
- replyTo: replyToSchema,
24
- outcome: communicationOutcomeSchema,
25
- data: z.record(z.string(), z.unknown()).describe("Outcome-specific data rendered by the selected connector.")
26
- });
4
+ /** Create a channel router that rejects duplicate registrations and unsupported destinations. */
27
5
  function createCommunicationRouter(adapters) {
28
6
  const byChannel = /* @__PURE__ */ new Map();
29
7
  for (const adapter of adapters) {
@@ -44,6 +22,6 @@ function createCommunicationRouter(adapters) {
44
22
  });
45
23
  }
46
24
  //#endregion
47
- export { communicationEventSchema, communicationOutcomeSchema, communicationOutcomes, createCommunicationRouter };
25
+ export { communicationEventSchema, communicationOutcomeSchema, communicationOutcomes, createCommunicationRouter, createOutboxCommunicationRouter, sweepCommunicationOutbox };
48
26
 
49
27
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../src/connectors/index.ts"],"sourcesContent":["import { z } from \"zod\";\nimport { changeIdSchema, repositoryIdsSchema, taskIdSchema } from \"../schema/id\";\nimport { replyToSchema } from \"../schema/common\";\nimport type { ReplyTo } from \"../schema/common\";\nimport type { SignalSource } from \"../schema/signal\";\n\nexport interface WebhookEvent {\n deliveryId: string;\n event: string;\n payload: unknown;\n}\n\nexport interface NormalizedSignal<TSource extends SignalSource = SignalSource> {\n source: TSource;\n deliveryId: string;\n replyTo: ReplyTo;\n payload: unknown;\n}\n\nexport type SignalNormalizer<TSignal extends NormalizedSignal = NormalizedSignal> = (\n event: WebhookEvent,\n) => TSignal | null;\n\nexport const communicationOutcomes = [\n \"accepted\",\n \"started\",\n \"succeeded\",\n \"failed\",\n \"needs_human\",\n \"question\",\n \"digest\",\n \"rolled_back\",\n \"budget_warning\",\n \"budget_exhausted\",\n \"message\",\n] as const;\n\nexport const communicationOutcomeSchema = z\n .enum(communicationOutcomes)\n .describe(\"Lifecycle outcome a connector should render and deliver.\");\n\nexport const communicationEventSchema = z.strictObject({\n eventId: z.string().min(1).describe(\"Stable idempotency key for this delivery.\"),\n repositoryIds: repositoryIdsSchema,\n taskId: taskIdSchema.optional(),\n changeId: changeIdSchema.optional(),\n replyTo: replyToSchema,\n outcome: communicationOutcomeSchema,\n data: z\n .record(z.string(), z.unknown())\n .describe(\"Outcome-specific data rendered by the selected connector.\"),\n});\n\nexport type CommunicationOutcome = z.infer<typeof communicationOutcomeSchema>;\nexport type CommunicationEvent = z.infer<typeof communicationEventSchema>;\n\nexport interface CommunicationAdapter {\n readonly channel: string;\n deliver(event: CommunicationEvent): Promise<void>;\n}\n\nexport interface CommunicationRouter {\n readonly channels: readonly string[];\n deliver(event: CommunicationEvent): Promise<void>;\n}\n\nexport function createCommunicationRouter(\n adapters: readonly CommunicationAdapter[],\n): CommunicationRouter {\n const byChannel = new Map<string, CommunicationAdapter>();\n for (const adapter of adapters) {\n const channel = adapter.channel.trim();\n if (channel.length === 0) {\n throw new Error(\"Communication adapter channel is required.\");\n }\n if (byChannel.has(channel)) {\n throw new Error(`Communication adapter ${channel} is registered more than once.`);\n }\n byChannel.set(channel, adapter);\n }\n const channels = Object.freeze([...byChannel.keys()]);\n\n return Object.freeze({\n channels,\n async deliver(input: CommunicationEvent): Promise<void> {\n const event = communicationEventSchema.parse(input);\n const adapter = byChannel.get(event.replyTo.channel);\n if (adapter === undefined) {\n throw new Error(`No communication adapter is registered for ${event.replyTo.channel}.`);\n }\n await adapter.deliver(event);\n },\n });\n}\n"],"mappings":";;;AAuBA,MAAa,wBAAwB;CACnC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAEA,MAAa,6BAA6B,EACvC,KAAK,qBAAqB,CAAC,CAC3B,SAAS,0DAA0D;AAEtE,MAAa,2BAA2B,EAAE,aAAa;CACrD,SAAS,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,2CAA2C;CAC/E,eAAe;CACf,QAAQ,aAAa,SAAS;CAC9B,UAAU,eAAe,SAAS;CAClC,SAAS;CACT,SAAS;CACT,MAAM,EACH,OAAO,EAAE,OAAO,GAAG,EAAE,QAAQ,CAAC,CAAC,CAC/B,SAAS,2DAA2D;AACzE,CAAC;AAeD,SAAgB,0BACd,UACqB;CACrB,MAAM,4BAAY,IAAI,IAAkC;CACxD,KAAK,MAAM,WAAW,UAAU;EAC9B,MAAM,UAAU,QAAQ,QAAQ,KAAK;EACrC,IAAI,QAAQ,WAAW,GACrB,MAAM,IAAI,MAAM,4CAA4C;EAE9D,IAAI,UAAU,IAAI,OAAO,GACvB,MAAM,IAAI,MAAM,yBAAyB,QAAQ,+BAA+B;EAElF,UAAU,IAAI,SAAS,OAAO;CAChC;CACA,MAAM,WAAW,OAAO,OAAO,CAAC,GAAG,UAAU,KAAK,CAAC,CAAC;CAEpD,OAAO,OAAO,OAAO;EACnB;EACA,MAAM,QAAQ,OAA0C;GACtD,MAAM,QAAQ,yBAAyB,MAAM,KAAK;GAClD,MAAM,UAAU,UAAU,IAAI,MAAM,QAAQ,OAAO;GACnD,IAAI,YAAY,KAAA,GACd,MAAM,IAAI,MAAM,8CAA8C,MAAM,QAAQ,QAAQ,EAAE;GAExF,MAAM,QAAQ,QAAQ,KAAK;EAC7B;CACF,CAAC;AACH"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../src/connectors/index.ts"],"sourcesContent":["import { communicationEventSchema, type CommunicationEvent } from \"../schema/communication\";\nimport type { ReplyTo } from \"../schema/common\";\nimport type { SignalSource } from \"../schema/signal\";\n\nexport {\n communicationEventSchema,\n communicationOutcomeSchema,\n communicationOutcomes,\n type CommunicationEvent,\n type CommunicationOutcome,\n} from \"../schema/communication\";\n\n/** An authenticated provider webhook envelope before connector-specific normalization. */\nexport interface WebhookEvent {\n deliveryId: string;\n event: string;\n payload: unknown;\n}\n\n/** Connector-neutral signal data ready for admission into Factory. */\nexport interface NormalizedSignal<TSource extends SignalSource = SignalSource> {\n source: TSource;\n deliveryId: string;\n replyTo: ReplyTo;\n payload: unknown;\n}\n\n/** Converts a verified webhook into a Factory signal or deliberately ignores it. */\nexport type SignalNormalizer<TSignal extends NormalizedSignal = NormalizedSignal> = (\n event: WebhookEvent,\n) => TSignal | null;\n\n/** Delivers communication events for one provider channel. */\nexport interface CommunicationAdapter {\n readonly channel: string;\n deliver(event: CommunicationEvent): Promise<void>;\n}\n\n/** Routes validated communication events to adapters by reply channel. */\nexport interface CommunicationRouter {\n readonly channels: readonly string[];\n deliver(event: CommunicationEvent): Promise<void>;\n}\n\n/** Create a channel router that rejects duplicate registrations and unsupported destinations. */\nexport function createCommunicationRouter(\n adapters: readonly CommunicationAdapter[],\n): CommunicationRouter {\n const byChannel = new Map<string, CommunicationAdapter>();\n for (const adapter of adapters) {\n const channel = adapter.channel.trim();\n if (channel.length === 0) {\n throw new Error(\"Communication adapter channel is required.\");\n }\n if (byChannel.has(channel)) {\n throw new Error(`Communication adapter ${channel} is registered more than once.`);\n }\n byChannel.set(channel, adapter);\n }\n const channels = Object.freeze([...byChannel.keys()]);\n\n return Object.freeze({\n channels,\n async deliver(input: CommunicationEvent): Promise<void> {\n const event = communicationEventSchema.parse(input);\n const adapter = byChannel.get(event.replyTo.channel);\n if (adapter === undefined) {\n throw new Error(`No communication adapter is registered for ${event.replyTo.channel}.`);\n }\n await adapter.deliver(event);\n },\n });\n}\n\nexport {\n createOutboxCommunicationRouter,\n sweepCommunicationOutbox,\n type CommunicationOutboxStores,\n type CreateOutboxCommunicationRouterOptions,\n type OutboxDeliveryOptions,\n type OutboxSweepResult,\n type SweepCommunicationOutboxOptions,\n} from \"./outbox\";\n"],"mappings":";;;;AA6CA,SAAgB,0BACd,UACqB;CACrB,MAAM,4BAAY,IAAI,IAAkC;CACxD,KAAK,MAAM,WAAW,UAAU;EAC9B,MAAM,UAAU,QAAQ,QAAQ,KAAK;EACrC,IAAI,QAAQ,WAAW,GACrB,MAAM,IAAI,MAAM,4CAA4C;EAE9D,IAAI,UAAU,IAAI,OAAO,GACvB,MAAM,IAAI,MAAM,yBAAyB,QAAQ,+BAA+B;EAElF,UAAU,IAAI,SAAS,OAAO;CAChC;CACA,MAAM,WAAW,OAAO,OAAO,CAAC,GAAG,UAAU,KAAK,CAAC,CAAC;CAEpD,OAAO,OAAO,OAAO;EACnB;EACA,MAAM,QAAQ,OAA0C;GACtD,MAAM,QAAQ,yBAAyB,MAAM,KAAK;GAClD,MAAM,UAAU,UAAU,IAAI,MAAM,QAAQ,OAAO;GACnD,IAAI,YAAY,KAAA,GACd,MAAM,IAAI,MAAM,8CAA8C,MAAM,QAAQ,QAAQ,EAAE;GAExF,MAAM,QAAQ,QAAQ,KAAK;EAC7B;CACF,CAAC;AACH"}
@@ -0,0 +1,34 @@
1
+ import { FactoryStores } from "../store/engine.mjs";
2
+ import { CommunicationRouter } from "./index.mjs";
3
+ //#region src/connectors/outbox.d.ts
4
+ /** Store capability required for durable communication delivery. */
5
+ type CommunicationOutboxStores = Pick<FactoryStores, "outbox">;
6
+ /** Counts delivered, rescheduled, and no-longer-claimable messages from an outbox sweep. */
7
+ interface OutboxSweepResult {
8
+ delivered: number;
9
+ retried: number;
10
+ skipped: number;
11
+ }
12
+ /** Configures outbox claim duration, batch size, and retry scheduling. */
13
+ interface OutboxDeliveryOptions {
14
+ readonly leaseMs?: number;
15
+ readonly limit?: number;
16
+ readonly retryDelayMs?: (attempt: number) => number;
17
+ }
18
+ /** Stores, router, and delivery bounds supplied to one outbox sweep. */
19
+ interface SweepCommunicationOutboxOptions extends OutboxDeliveryOptions {
20
+ readonly stores: CommunicationOutboxStores;
21
+ readonly router: CommunicationRouter;
22
+ }
23
+ /** Stores, router, and delivery bounds used to construct a durable router. */
24
+ interface CreateOutboxCommunicationRouterOptions extends OutboxDeliveryOptions {
25
+ readonly stores: CommunicationOutboxStores;
26
+ readonly router: CommunicationRouter;
27
+ }
28
+ /** Deliver one bounded batch of pending communication events with durable retry state. */
29
+ declare function sweepCommunicationOutbox(options: SweepCommunicationOutboxOptions): Promise<OutboxSweepResult>;
30
+ /** Wrap a communication router so every delivery is durably enqueued before it is attempted. */
31
+ declare function createOutboxCommunicationRouter(options: CreateOutboxCommunicationRouterOptions): CommunicationRouter;
32
+ //#endregion
33
+ export { CommunicationOutboxStores, CreateOutboxCommunicationRouterOptions, OutboxDeliveryOptions, OutboxSweepResult, SweepCommunicationOutboxOptions, createOutboxCommunicationRouter, sweepCommunicationOutbox };
34
+ //# sourceMappingURL=outbox.d.mts.map
@@ -0,0 +1,50 @@
1
+ import { redactedErrorMessage } from "../errors.mjs";
2
+ //#region src/connectors/outbox.ts
3
+ const defaultRetryDelayMs = (attempt) => Math.min(6e4 * 2 ** Math.max(0, attempt - 1), 36e5);
4
+ async function deliverOne(stores, router, id, options) {
5
+ const claimed = await stores.outbox.claim(id, options.leaseMs);
6
+ if (claimed === null) return "skipped";
7
+ try {
8
+ await router.deliver(claimed.event);
9
+ return await stores.outbox.complete(claimed.id, claimed.attempt) === null ? "skipped" : "delivered";
10
+ } catch (error) {
11
+ const delay = (options.retryDelayMs ?? defaultRetryDelayMs)(claimed.attempt);
12
+ return await stores.outbox.retry(claimed.id, {
13
+ attempt: claimed.attempt,
14
+ reason: redactedErrorMessage(error, [], "Unknown communication delivery error"),
15
+ delayMs: delay
16
+ }) === null ? "skipped" : "retried";
17
+ }
18
+ }
19
+ /** Deliver one bounded batch of pending communication events with durable retry state. */
20
+ async function sweepCommunicationOutbox(options) {
21
+ const { stores, router } = options;
22
+ const limit = options.limit ?? 100;
23
+ const messages = await stores.outbox.pending(limit);
24
+ const result = {
25
+ delivered: 0,
26
+ retried: 0,
27
+ skipped: 0
28
+ };
29
+ for (const message of messages) {
30
+ const outcome = await deliverOne(stores, router, message.id, options);
31
+ result[outcome] += 1;
32
+ }
33
+ return result;
34
+ }
35
+ /** Wrap a communication router so every delivery is durably enqueued before it is attempted. */
36
+ function createOutboxCommunicationRouter(options) {
37
+ const { stores, router } = options;
38
+ return Object.freeze({
39
+ channels: router.channels,
40
+ async deliver(event) {
41
+ const message = await stores.outbox.enqueue(event);
42
+ if (message.state === "delivered") return;
43
+ await deliverOne(stores, router, message.id, options);
44
+ }
45
+ });
46
+ }
47
+ //#endregion
48
+ export { createOutboxCommunicationRouter, sweepCommunicationOutbox };
49
+
50
+ //# sourceMappingURL=outbox.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outbox.mjs","names":[],"sources":["../../src/connectors/outbox.ts"],"sourcesContent":["import type { OutboxId } from \"../schema/id\";\nimport type { FactoryStores } from \"../store/engine\";\nimport { redactedErrorMessage } from \"../errors\";\nimport type { CommunicationEvent, CommunicationRouter } from \"./index\";\n\n/** Store capability required for durable communication delivery. */\nexport type CommunicationOutboxStores = Pick<FactoryStores, \"outbox\">;\n\n/** Counts delivered, rescheduled, and no-longer-claimable messages from an outbox sweep. */\nexport interface OutboxSweepResult {\n delivered: number;\n retried: number;\n skipped: number;\n}\n\n/** Configures outbox claim duration, batch size, and retry scheduling. */\nexport interface OutboxDeliveryOptions {\n readonly leaseMs?: number;\n readonly limit?: number;\n readonly retryDelayMs?: (attempt: number) => number;\n}\n\n/** Stores, router, and delivery bounds supplied to one outbox sweep. */\nexport interface SweepCommunicationOutboxOptions extends OutboxDeliveryOptions {\n readonly stores: CommunicationOutboxStores;\n readonly router: CommunicationRouter;\n}\n\n/** Stores, router, and delivery bounds used to construct a durable router. */\nexport interface CreateOutboxCommunicationRouterOptions extends OutboxDeliveryOptions {\n readonly stores: CommunicationOutboxStores;\n readonly router: CommunicationRouter;\n}\n\nconst defaultRetryDelayMs = (attempt: number) =>\n Math.min(60_000 * 2 ** Math.max(0, attempt - 1), 60 * 60_000);\n\nasync function deliverOne(\n stores: CommunicationOutboxStores,\n router: CommunicationRouter,\n id: OutboxId,\n options: OutboxDeliveryOptions,\n): Promise<\"delivered\" | \"retried\" | \"skipped\"> {\n const claimed = await stores.outbox.claim(id, options.leaseMs);\n if (claimed === null) return \"skipped\";\n try {\n await router.deliver(claimed.event);\n const completed = await stores.outbox.complete(claimed.id, claimed.attempt);\n return completed === null ? \"skipped\" : \"delivered\";\n } catch (error) {\n const delay = (options.retryDelayMs ?? defaultRetryDelayMs)(claimed.attempt);\n const retried = await stores.outbox.retry(claimed.id, {\n attempt: claimed.attempt,\n reason: redactedErrorMessage(error, [], \"Unknown communication delivery error\"),\n delayMs: delay,\n });\n return retried === null ? \"skipped\" : \"retried\";\n }\n}\n\n/** Deliver one bounded batch of pending communication events with durable retry state. */\nexport async function sweepCommunicationOutbox(\n options: SweepCommunicationOutboxOptions,\n): Promise<OutboxSweepResult> {\n const { stores, router } = options;\n const limit = options.limit ?? 100;\n const messages = await stores.outbox.pending(limit);\n const result: OutboxSweepResult = { delivered: 0, retried: 0, skipped: 0 };\n for (const message of messages) {\n const outcome = await deliverOne(stores, router, message.id, options);\n result[outcome] += 1;\n }\n return result;\n}\n\n/** Wrap a communication router so every delivery is durably enqueued before it is attempted. */\nexport function createOutboxCommunicationRouter(\n options: CreateOutboxCommunicationRouterOptions,\n): CommunicationRouter {\n const { stores, router } = options;\n return Object.freeze({\n channels: router.channels,\n async deliver(event: CommunicationEvent): Promise<void> {\n const message = await stores.outbox.enqueue(event);\n if (message.state === \"delivered\") return;\n await deliverOne(stores, router, message.id, options);\n },\n });\n}\n"],"mappings":";;AAkCA,MAAM,uBAAuB,YAC3B,KAAK,IAAI,MAAS,KAAK,KAAK,IAAI,GAAG,UAAU,CAAC,GAAG,IAAW;AAE9D,eAAe,WACb,QACA,QACA,IACA,SAC8C;CAC9C,MAAM,UAAU,MAAM,OAAO,OAAO,MAAM,IAAI,QAAQ,OAAO;CAC7D,IAAI,YAAY,MAAM,OAAO;CAC7B,IAAI;EACF,MAAM,OAAO,QAAQ,QAAQ,KAAK;EAElC,OAAO,MADiB,OAAO,OAAO,SAAS,QAAQ,IAAI,QAAQ,OAAO,MACrD,OAAO,YAAY;CAC1C,SAAS,OAAO;EACd,MAAM,SAAS,QAAQ,gBAAgB,oBAAA,CAAqB,QAAQ,OAAO;EAM3E,OAAO,MALe,OAAO,OAAO,MAAM,QAAQ,IAAI;GACpD,SAAS,QAAQ;GACjB,QAAQ,qBAAqB,OAAO,CAAC,GAAG,sCAAsC;GAC9E,SAAS;EACX,CAAC,MACkB,OAAO,YAAY;CACxC;AACF;;AAGA,eAAsB,yBACpB,SAC4B;CAC5B,MAAM,EAAE,QAAQ,WAAW;CAC3B,MAAM,QAAQ,QAAQ,SAAS;CAC/B,MAAM,WAAW,MAAM,OAAO,OAAO,QAAQ,KAAK;CAClD,MAAM,SAA4B;EAAE,WAAW;EAAG,SAAS;EAAG,SAAS;CAAE;CACzE,KAAK,MAAM,WAAW,UAAU;EAC9B,MAAM,UAAU,MAAM,WAAW,QAAQ,QAAQ,QAAQ,IAAI,OAAO;EACpE,OAAO,YAAY;CACrB;CACA,OAAO;AACT;;AAGA,SAAgB,gCACd,SACqB;CACrB,MAAM,EAAE,QAAQ,WAAW;CAC3B,OAAO,OAAO,OAAO;EACnB,UAAU,OAAO;EACjB,MAAM,QAAQ,OAA0C;GACtD,MAAM,UAAU,MAAM,OAAO,OAAO,QAAQ,KAAK;GACjD,IAAI,QAAQ,UAAU,aAAa;GACnC,MAAM,WAAW,QAAQ,QAAQ,QAAQ,IAAI,OAAO;EACtD;CACF,CAAC;AACH"}
@@ -0,0 +1,136 @@
1
+ //#region src/connectors/slack-approval-blocks.ts
2
+ const slackApprovalPrefix = "factory_approval:";
3
+ const slackRejectionCallback = "factory_approval_reject";
4
+ const slackReasonBlock = "reason";
5
+ const slackReasonAction = "reason_text";
6
+ function escape(text) {
7
+ return text.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
8
+ }
9
+ function plain(text) {
10
+ return {
11
+ type: "plain_text",
12
+ text: text.slice(0, 2900)
13
+ };
14
+ }
15
+ function section(text) {
16
+ return {
17
+ type: "section",
18
+ text: {
19
+ type: "mrkdwn",
20
+ text: text.slice(0, 2900)
21
+ }
22
+ };
23
+ }
24
+ function context(text) {
25
+ return {
26
+ type: "context",
27
+ elements: [{
28
+ type: "mrkdwn",
29
+ text: text.slice(0, 2900)
30
+ }]
31
+ };
32
+ }
33
+ function button(action, text, id, style) {
34
+ return {
35
+ type: "button",
36
+ action_id: `${slackApprovalPrefix}${action}`,
37
+ text: plain(text),
38
+ value: id,
39
+ ...style ? { style } : {}
40
+ };
41
+ }
42
+ function actor(value) {
43
+ const user = /^slack:T[A-Z0-9]+:([UW][A-Z0-9]+)$/u.exec(value ?? "")?.[1];
44
+ return user ? `<@${user}>` : escape(value ?? "an operator");
45
+ }
46
+ function title(view) {
47
+ return view.finding?.title ?? `${view.task.kind.replaceAll("_", " ")} proposal`;
48
+ }
49
+ function slackApprovalMessage(view) {
50
+ const { task, finding, decision } = view;
51
+ const pending = task.approval === "required" && task.state === "queued";
52
+ const blocks = [
53
+ context([finding?.priority, ...view.repositories].filter(Boolean).map((text) => escape(text)).join(" · ")),
54
+ section(`*${escape(title(view))}*`),
55
+ section(escape(finding?.body ?? "Inspect the task and its origin before deciding."))
56
+ ];
57
+ if (finding) blocks.push(section(`*Evidence · ${escape(finding.verification.level)}*\n${escape(finding.verification.summary)}`));
58
+ if (pending && !decision) {
59
+ blocks.push(context("This task requires operator approval before work can start."));
60
+ blocks.push({
61
+ type: "actions",
62
+ elements: [
63
+ button("approve", "Approve work", task.id, "primary"),
64
+ button("reject", "Reject…", task.id),
65
+ button("evidence", "View evidence", task.id)
66
+ ]
67
+ });
68
+ blocks.push(context("Grants permission to start. Budget and dependency checks still apply."));
69
+ } else if (pending && decision) {
70
+ blocks.push(context(`Decision saved by ${actor(decision.decidedBy)}. Its task update still needs to finish.`));
71
+ blocks.push({
72
+ type: "actions",
73
+ elements: [button("retry", "Finish recorded decision", task.id, "primary"), button("evidence", "View evidence", task.id)]
74
+ });
75
+ } else {
76
+ const state = decision?.state === "approved" ? `Approved by ${actor(decision.decidedBy)} · ${task.state === "queued" ? "queued for execution" : escape(task.state.replaceAll("_", " "))}` : decision?.state === "rejected" ? `Rejected by ${actor(decision.decidedBy)} · task cancelled` : `Task ${escape(task.state.replaceAll("_", " "))}`;
77
+ blocks.push(context(state));
78
+ if (decision?.reason) blocks.push(section(escape(decision.reason)));
79
+ blocks.push({
80
+ type: "actions",
81
+ elements: [button("evidence", "View evidence", task.id), ...decision ? [button("decision", "View decision", task.id)] : []]
82
+ });
83
+ }
84
+ return {
85
+ text: escape(`${title(view)} · ${decision?.state ?? (pending ? "Awaiting approval" : task.state)}`),
86
+ blocks
87
+ };
88
+ }
89
+ function slackApprovalModal(view, kind, metadata) {
90
+ const { finding, decision } = view;
91
+ const blocks = [section(`*${escape(title(view))}*`)];
92
+ if (kind === "reject") {
93
+ blocks.push(section("Factory will cancel this task. Your reason will be visible with the decision."));
94
+ blocks.push({
95
+ type: "input",
96
+ block_id: slackReasonBlock,
97
+ label: plain("Reason"),
98
+ element: {
99
+ type: "plain_text_input",
100
+ action_id: slackReasonAction,
101
+ multiline: true,
102
+ min_length: 1,
103
+ max_length: 2e3,
104
+ ...decision?.state === "rejected" && decision.reason ? { initial_value: decision.reason } : {},
105
+ placeholder: plain("Why should this work not proceed?")
106
+ }
107
+ });
108
+ } else if (kind === "decision" && decision) {
109
+ blocks.push(section(`${decision.state === "approved" ? "Approved" : "Rejected"} by ${actor(decision.decidedBy)}`));
110
+ if (decision.reason) blocks.push(section(escape(decision.reason)));
111
+ blocks.push(context(`${escape(decision.recordedAt)} · ${escape(decision.receiptId)}`));
112
+ } else {
113
+ blocks.push(section(escape(finding?.body ?? "No finding is attached to this task.")));
114
+ if (finding) {
115
+ blocks.push(section(`*Evidence · ${escape(finding.verification.level)}*\n${escape(finding.verification.summary)}`));
116
+ if (finding.path) blocks.push(context(`Location: ${escape(finding.path)}${finding.line ? `:${finding.line}` : ""}`));
117
+ if (finding.verification.limitations) blocks.push(section(`*Limitations*\n${escape(finding.verification.limitations)}`));
118
+ }
119
+ blocks.push(context(`Task: ${escape(view.task.id)}`));
120
+ }
121
+ return {
122
+ type: "modal",
123
+ title: plain(kind === "reject" ? "Reject proposed work" : kind === "decision" ? "Recorded decision" : "Proposal evidence"),
124
+ close: plain(kind === "reject" ? "Cancel" : "Done"),
125
+ blocks,
126
+ ...kind === "reject" ? {
127
+ callback_id: slackRejectionCallback,
128
+ private_metadata: metadata,
129
+ submit: plain("Reject work")
130
+ } : {}
131
+ };
132
+ }
133
+ //#endregion
134
+ export { slackApprovalMessage, slackApprovalModal, slackApprovalPrefix, slackReasonAction, slackReasonBlock, slackRejectionCallback };
135
+
136
+ //# sourceMappingURL=slack-approval-blocks.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slack-approval-blocks.mjs","names":[],"sources":["../../src/connectors/slack-approval-blocks.ts"],"sourcesContent":["import type { ApprovalView } from \"../approval-contracts\";\n\nexport const slackApprovalPrefix = \"factory_approval:\";\nexport const slackRejectionCallback = \"factory_approval_reject\";\nexport const slackReasonBlock = \"reason\";\nexport const slackReasonAction = \"reason_text\";\n\nfunction escape(text: string) {\n return text.replaceAll(\"&\", \"&amp;\").replaceAll(\"<\", \"&lt;\").replaceAll(\">\", \"&gt;\");\n}\nfunction plain(text: string) {\n return { type: \"plain_text\", text: text.slice(0, 2900) };\n}\nfunction section(text: string) {\n return { type: \"section\", text: { type: \"mrkdwn\", text: text.slice(0, 2900) } };\n}\nfunction context(text: string) {\n return { type: \"context\", elements: [{ type: \"mrkdwn\", text: text.slice(0, 2900) }] };\n}\nfunction button(action: string, text: string, id: string, style?: \"primary\" | \"danger\") {\n return {\n type: \"button\",\n action_id: `${slackApprovalPrefix}${action}`,\n text: plain(text),\n value: id,\n ...(style ? { style } : {}),\n };\n}\nfunction actor(value: string | undefined) {\n const user = /^slack:T[A-Z0-9]+:([UW][A-Z0-9]+)$/u.exec(value ?? \"\")?.[1];\n return user ? `<@${user}>` : escape(value ?? \"an operator\");\n}\nfunction title(view: ApprovalView) {\n return view.finding?.title ?? `${view.task.kind.replaceAll(\"_\", \" \")} proposal`;\n}\n\nexport function slackApprovalMessage(view: ApprovalView) {\n const { task, finding, decision } = view;\n const pending = task.approval === \"required\" && task.state === \"queued\";\n const blocks: Record<string, unknown>[] = [\n context(\n [finding?.priority, ...view.repositories]\n .filter(Boolean)\n .map((text) => escape(text!))\n .join(\" · \"),\n ),\n section(`*${escape(title(view))}*`),\n section(escape(finding?.body ?? \"Inspect the task and its origin before deciding.\")),\n ];\n if (finding)\n blocks.push(\n section(\n `*Evidence · ${escape(finding.verification.level)}*\\n${escape(finding.verification.summary)}`,\n ),\n );\n if (pending && !decision) {\n blocks.push(context(\"This task requires operator approval before work can start.\"));\n blocks.push({\n type: \"actions\",\n elements: [\n button(\"approve\", \"Approve work\", task.id, \"primary\"),\n button(\"reject\", \"Reject…\", task.id),\n button(\"evidence\", \"View evidence\", task.id),\n ],\n });\n blocks.push(context(\"Grants permission to start. Budget and dependency checks still apply.\"));\n } else if (pending && decision) {\n blocks.push(\n context(\n `Decision saved by ${actor(decision.decidedBy)}. Its task update still needs to finish.`,\n ),\n );\n blocks.push({\n type: \"actions\",\n elements: [\n button(\"retry\", \"Finish recorded decision\", task.id, \"primary\"),\n button(\"evidence\", \"View evidence\", task.id),\n ],\n });\n } else {\n const state =\n decision?.state === \"approved\"\n ? `Approved by ${actor(decision.decidedBy)} · ${task.state === \"queued\" ? \"queued for execution\" : escape(task.state.replaceAll(\"_\", \" \"))}`\n : decision?.state === \"rejected\"\n ? `Rejected by ${actor(decision.decidedBy)} · task cancelled`\n : `Task ${escape(task.state.replaceAll(\"_\", \" \"))}`;\n blocks.push(context(state));\n if (decision?.reason) blocks.push(section(escape(decision.reason)));\n blocks.push({\n type: \"actions\",\n elements: [\n button(\"evidence\", \"View evidence\", task.id),\n ...(decision ? [button(\"decision\", \"View decision\", task.id)] : []),\n ],\n });\n }\n return {\n text: escape(\n `${title(view)} · ${decision?.state ?? (pending ? \"Awaiting approval\" : task.state)}`,\n ),\n blocks,\n };\n}\n\nexport function slackApprovalModal(\n view: ApprovalView,\n kind: \"reject\" | \"evidence\" | \"decision\",\n metadata: string,\n) {\n const { finding, decision } = view;\n const blocks: Record<string, unknown>[] = [section(`*${escape(title(view))}*`)];\n if (kind === \"reject\") {\n blocks.push(\n section(\"Factory will cancel this task. Your reason will be visible with the decision.\"),\n );\n blocks.push({\n type: \"input\",\n block_id: slackReasonBlock,\n label: plain(\"Reason\"),\n element: {\n type: \"plain_text_input\",\n action_id: slackReasonAction,\n multiline: true,\n min_length: 1,\n max_length: 2000,\n ...(decision?.state === \"rejected\" && decision.reason\n ? { initial_value: decision.reason }\n : {}),\n placeholder: plain(\"Why should this work not proceed?\"),\n },\n });\n } else if (kind === \"decision\" && decision) {\n blocks.push(\n section(\n `${decision.state === \"approved\" ? \"Approved\" : \"Rejected\"} by ${actor(decision.decidedBy)}`,\n ),\n );\n if (decision.reason) blocks.push(section(escape(decision.reason)));\n blocks.push(context(`${escape(decision.recordedAt)} · ${escape(decision.receiptId)}`));\n } else {\n blocks.push(section(escape(finding?.body ?? \"No finding is attached to this task.\")));\n if (finding) {\n blocks.push(\n section(\n `*Evidence · ${escape(finding.verification.level)}*\\n${escape(finding.verification.summary)}`,\n ),\n );\n if (finding.path)\n blocks.push(\n context(`Location: ${escape(finding.path)}${finding.line ? `:${finding.line}` : \"\"}`),\n );\n if (finding.verification.limitations)\n blocks.push(section(`*Limitations*\\n${escape(finding.verification.limitations)}`));\n }\n blocks.push(context(`Task: ${escape(view.task.id)}`));\n }\n return {\n type: \"modal\",\n title: plain(\n kind === \"reject\"\n ? \"Reject proposed work\"\n : kind === \"decision\"\n ? \"Recorded decision\"\n : \"Proposal evidence\",\n ),\n close: plain(kind === \"reject\" ? \"Cancel\" : \"Done\"),\n blocks,\n ...(kind === \"reject\"\n ? {\n callback_id: slackRejectionCallback,\n private_metadata: metadata,\n submit: plain(\"Reject work\"),\n }\n : {}),\n };\n}\n"],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ import { Task } from "../schema/task.mjs";
2
+ import { CommunicationEvent } from "../schema/communication.mjs";
3
+ import { FactoryStores } from "../store/engine.mjs";
4
+ import { ApprovalAccessOptions, ApprovalAccessStores } from "../approval-access.mjs";
5
+ //#region src/connectors/slack-approvals.d.ts
6
+ /** Store capabilities required to present and decide Slack approvals. */
7
+ type SlackApprovalsStores = ApprovalAccessStores & Pick<FactoryStores, "outbox" | "receipts">;
8
+ /** Configures authenticated Slack presentation and handling for durable Task approvals. */
9
+ interface SlackApprovalsOptions extends Omit<ApprovalAccessOptions, "stores"> {
10
+ readonly stores: SlackApprovalsStores;
11
+ /** Explicit fallback destination for work with no Slack reply thread. */
12
+ approvalChannel?: string;
13
+ request(operation: string, body: unknown): Promise<unknown>;
14
+ /** Authenticate the original request and body before accepting any interaction. */
15
+ verify(request: Request, body: string): Promise<void>;
16
+ reportError?(error: unknown): void;
17
+ }
18
+ /** Slack approval projection, interaction handler, and reconciliation operations. */
19
+ interface SlackApprovals {
20
+ handle(request: Request, waitUntil: (task: Promise<unknown>) => void): Promise<Response | null>;
21
+ reconcile(tasks: readonly Task[]): Promise<number>;
22
+ deliver(event: CommunicationEvent): Promise<void>;
23
+ updatePresented(taskId: Task["id"]): Promise<boolean>;
24
+ }
25
+ /** Slack is a projection of the same Task decision used by HTTP clients. */
26
+ declare function createSlackApprovals(options: SlackApprovalsOptions): SlackApprovals;
27
+ //#endregion
28
+ export { SlackApprovals, SlackApprovalsOptions, SlackApprovalsStores, createSlackApprovals };
29
+ //# sourceMappingURL=slack-approvals.d.mts.map