@atolis-hq/wake 0.2.97 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (442) hide show
  1. package/dist/src/activities/agent/agent-activity-definition.js +26 -0
  2. package/dist/src/activities/agent/agent-activity.js +171 -0
  3. package/dist/src/activities/agent/agent-result.js +149 -0
  4. package/dist/src/activities/contracts/activity.js +10 -0
  5. package/dist/src/activities/contracts/config.js +2 -0
  6. package/dist/src/activities/contracts/event-schema.js +302 -0
  7. package/dist/src/activities/contracts/events.js +42 -0
  8. package/dist/src/activities/contracts/identifiers.js +29 -0
  9. package/dist/src/activities/contracts/registry.js +71 -0
  10. package/dist/src/activities/contracts/streams.js +17 -0
  11. package/dist/src/activities/contracts/vocabulary.js +58 -0
  12. package/dist/src/activities/index.js +21 -0
  13. package/dist/src/activities/pr/activity-support.js +111 -0
  14. package/dist/src/activities/pr/application.js +158 -0
  15. package/dist/src/activities/pr/approve.js +85 -0
  16. package/dist/src/activities/pr/capability.js +11 -0
  17. package/dist/src/activities/pr/decision-claim.js +76 -0
  18. package/dist/src/activities/pr/event-drafts.js +66 -0
  19. package/dist/src/activities/pr/intent.js +37 -0
  20. package/dist/src/activities/pr/merge-authority-gate.js +14 -0
  21. package/dist/src/activities/pr/merge.js +110 -0
  22. package/dist/src/activities/pr/policy.js +135 -0
  23. package/dist/src/activities/pr/projection.js +130 -0
  24. package/dist/src/activities/pr/vocabulary.js +30 -0
  25. package/dist/src/activities/review/authorization.js +22 -0
  26. package/dist/src/activities/review/contracts.js +22 -0
  27. package/dist/src/activities/review/signals.js +3 -0
  28. package/dist/src/bootstrap/analytics-projection.js +26 -0
  29. package/dist/src/bootstrap/board-projection.js +337 -0
  30. package/dist/src/bootstrap/composition-root.js +382 -0
  31. package/dist/src/bootstrap/config/load-config.js +51 -0
  32. package/dist/src/bootstrap/config/root-schema.js +134 -0
  33. package/dist/src/bootstrap/external-ref.js +12 -0
  34. package/dist/src/bootstrap/fake-provider-files.js +44 -0
  35. package/dist/src/bootstrap/fake-scenarios.js +22 -0
  36. package/dist/src/bootstrap/index.js +48 -0
  37. package/dist/src/bootstrap/initialise.js +434 -0
  38. package/dist/src/bootstrap/paths.js +15 -0
  39. package/dist/src/bootstrap/projection-runtime.js +27 -0
  40. package/dist/src/bootstrap/runner-quota-reporter.js +21 -0
  41. package/dist/src/bootstrap/runner-registry.js +30 -0
  42. package/dist/src/bootstrap/schedule-checkpoint-store.js +49 -0
  43. package/dist/src/bootstrap/self-update-application.js +195 -0
  44. package/dist/src/bootstrap/self-update-failure-log.js +33 -0
  45. package/dist/src/bootstrap/source-update-port.js +47 -0
  46. package/dist/src/bootstrap/status-publish-activity.js +42 -0
  47. package/dist/src/bootstrap/surface-api-applications.js +325 -0
  48. package/dist/src/bootstrap/surface-api-execution-applications.js +95 -0
  49. package/dist/src/bootstrap/surface-api-metadata.js +12 -0
  50. package/dist/src/bootstrap/surface-api-projection-pages.js +22 -0
  51. package/dist/src/bootstrap/surface-api-run-context.js +5 -0
  52. package/dist/src/bootstrap/surface-api-transcripts.js +57 -0
  53. package/dist/src/bootstrap/surface-api-work-applications.js +199 -0
  54. package/dist/src/bootstrap/surface-applications.js +7 -0
  55. package/dist/src/bootstrap/surface-cli-applications.js +701 -0
  56. package/dist/src/bootstrap/update-ledger.js +61 -0
  57. package/dist/src/bootstrap/update-maintenance-lease.js +176 -0
  58. package/dist/src/{version.js → bootstrap/version.js} +35 -51
  59. package/dist/src/control-plane/application/advance-once.js +184 -0
  60. package/dist/src/control-plane/application/control-plane-projection.js +42 -0
  61. package/dist/src/control-plane/application/control-plane-service.js +42 -0
  62. package/dist/src/control-plane/application/intake-pipeline.js +29 -0
  63. package/dist/src/control-plane/application/runner-control-service.js +66 -0
  64. package/dist/src/control-plane/application/runner-pipeline.js +57 -0
  65. package/dist/src/control-plane/application/schedule-service.js +47 -0
  66. package/dist/src/control-plane/application/work-cancellation-policy.js +31 -0
  67. package/dist/src/control-plane/contracts/commands.js +10 -0
  68. package/dist/src/control-plane/contracts/config.js +22 -0
  69. package/dist/src/control-plane/contracts/events.js +81 -0
  70. package/dist/src/control-plane/contracts/streams.js +5 -0
  71. package/dist/src/control-plane/domain/dispatch-policy.js +15 -0
  72. package/dist/src/control-plane/domain/quota-policy.js +26 -0
  73. package/dist/src/control-plane/domain/runner-quota.js +35 -0
  74. package/dist/src/control-plane/domain/schedule-policy.js +46 -0
  75. package/dist/src/control-plane/index.js +20 -0
  76. package/dist/src/control-plane/infrastructure/intake-host.js +24 -0
  77. package/dist/src/control-plane/infrastructure/resident-host.js +45 -0
  78. package/dist/src/control-plane/infrastructure/tick-host.js +35 -0
  79. package/dist/src/execution/application/activation-claim.js +50 -0
  80. package/dist/src/execution/application/active-run-cancellation.js +14 -0
  81. package/dist/src/execution/application/execution-activity.js +97 -0
  82. package/dist/src/execution/application/execution-projection.js +17 -0
  83. package/dist/src/execution/application/execution-service.js +372 -0
  84. package/dist/src/execution/application/execution-validation.js +26 -0
  85. package/dist/src/execution/application/recovery-service.js +212 -0
  86. package/dist/src/execution/application/run-lifecycle.js +115 -0
  87. package/dist/src/execution/application/run-liveness-service.js +80 -0
  88. package/dist/src/execution/application/run-repository.js +27 -0
  89. package/dist/src/execution/contracts/commands.js +1 -0
  90. package/dist/src/execution/contracts/config.js +35 -0
  91. package/dist/src/execution/contracts/control-plane.js +1 -0
  92. package/dist/src/execution/contracts/event-factory.js +53 -0
  93. package/dist/src/execution/contracts/events.js +274 -0
  94. package/dist/src/execution/contracts/identifiers.js +5 -0
  95. package/dist/src/execution/contracts/liveness.js +1 -0
  96. package/dist/src/execution/contracts/results.js +1 -0
  97. package/dist/src/execution/contracts/runner.js +15 -0
  98. package/dist/src/execution/contracts/streams.js +10 -0
  99. package/dist/src/execution/contracts/views.js +1 -0
  100. package/dist/src/execution/contracts/vocabulary.js +43 -0
  101. package/dist/src/execution/contracts/workspace.js +1 -0
  102. package/dist/src/execution/domain/run-result.js +34 -0
  103. package/dist/src/execution/domain/run.js +142 -0
  104. package/dist/src/execution/index.js +31 -0
  105. package/dist/src/execution/infrastructure/agent-runner-adapter.js +114 -0
  106. package/dist/src/execution/infrastructure/process-execution.js +29 -0
  107. package/dist/src/execution/infrastructure/prompt-templates.js +42 -0
  108. package/dist/src/execution/infrastructure/runners/claude.js +120 -0
  109. package/dist/src/execution/infrastructure/runners/codex.js +143 -0
  110. package/dist/src/execution/infrastructure/runners/command.js +4 -0
  111. package/dist/src/execution/infrastructure/runners/cursor.js +69 -0
  112. package/dist/src/execution/infrastructure/runners/fake-scenarios.js +99 -0
  113. package/dist/src/execution/infrastructure/runners/fake.js +65 -0
  114. package/dist/src/execution/infrastructure/runners/registry.js +26 -0
  115. package/dist/src/execution/infrastructure/transcript-store.js +223 -0
  116. package/dist/src/execution/infrastructure/transcripts.js +11 -0
  117. package/dist/src/execution/infrastructure/workspace/fake-workspace.js +19 -0
  118. package/dist/src/execution/infrastructure/workspace/git-workspace.js +241 -0
  119. package/dist/src/integrations/application/agent-run-publication-reactor.js +111 -0
  120. package/dist/src/integrations/application/artifact-registration-reactor.js +159 -0
  121. package/dist/src/integrations/application/poll-service.js +25 -0
  122. package/dist/src/integrations/application/terminal-agent-run-report.js +40 -0
  123. package/dist/src/integrations/application/work-admission.js +31 -0
  124. package/dist/src/integrations/application/work-conclusion.js +19 -0
  125. package/dist/src/integrations/contracts/artifact-events.js +60 -0
  126. package/dist/src/integrations/contracts/artifact-vocabulary.js +9 -0
  127. package/dist/src/integrations/contracts/config.js +14 -0
  128. package/dist/src/integrations/contracts/identifiers.js +5 -0
  129. package/dist/src/integrations/contracts/intake-rules.js +14 -0
  130. package/dist/src/integrations/contracts/intake.js +1 -0
  131. package/dist/src/integrations/contracts/outcome-vocabulary.js +7 -0
  132. package/dist/src/integrations/contracts/provider.js +37 -0
  133. package/dist/src/integrations/contracts/streams.js +10 -0
  134. package/dist/src/integrations/delivery/application/delivery-outcome-reactor.js +75 -0
  135. package/dist/src/integrations/delivery/application/delivery-projector.js +165 -0
  136. package/dist/src/integrations/delivery/application/delivery-service.js +173 -0
  137. package/dist/src/integrations/delivery/contracts/commands.js +1 -0
  138. package/dist/src/integrations/delivery/contracts/config.js +1 -0
  139. package/dist/src/integrations/delivery/contracts/event-factory.js +18 -0
  140. package/dist/src/integrations/delivery/contracts/events.js +86 -0
  141. package/dist/src/integrations/delivery/contracts/intents.js +89 -0
  142. package/dist/src/integrations/delivery/contracts/views.js +1 -0
  143. package/dist/src/integrations/delivery/contracts/vocabulary.js +22 -0
  144. package/dist/src/integrations/fake/durable-delivery-provider.js +48 -0
  145. package/dist/src/integrations/fake/external-sink.js +9 -0
  146. package/dist/src/integrations/fake/external-source.js +44 -0
  147. package/dist/src/integrations/fake/inbound-translator.js +130 -0
  148. package/dist/src/integrations/fake/provider.js +95 -0
  149. package/dist/src/integrations/github/application/agent-context-reader.js +54 -0
  150. package/dist/src/integrations/github/application/agent-run-comment.js +94 -0
  151. package/dist/src/integrations/github/application/comment-history-reader.js +43 -0
  152. package/dist/src/integrations/github/application/inbound-context.js +10 -0
  153. package/dist/src/integrations/github/application/inbound-review-signals.js +159 -0
  154. package/dist/src/integrations/github/application/inbound-translator.js +231 -0
  155. package/dist/src/integrations/github/application/inbound-watch-gate-signals.js +84 -0
  156. package/dist/src/integrations/github/application/intake-policy.js +23 -0
  157. package/dist/src/integrations/github/application/outbound-translator.js +47 -0
  158. package/dist/src/integrations/github/application/poll-service.js +29 -0
  159. package/dist/src/integrations/github/application/pull-request-translation.js +10 -0
  160. package/dist/src/integrations/github/application/resource-links.js +8 -0
  161. package/dist/src/integrations/github/application/review-command-translator.js +16 -0
  162. package/dist/src/integrations/github/application/wake-labels.js +95 -0
  163. package/dist/src/integrations/github/contracts/config.js +47 -0
  164. package/dist/src/integrations/github/contracts/events.js +127 -0
  165. package/dist/src/integrations/github/contracts/external-key.js +19 -0
  166. package/dist/src/integrations/github/contracts/payloads.js +9 -0
  167. package/dist/src/integrations/github/contracts/vocabulary.js +55 -0
  168. package/dist/src/integrations/github/index.js +31 -0
  169. package/dist/src/integrations/github/infrastructure/client-reads.js +214 -0
  170. package/dist/src/integrations/github/infrastructure/client.js +132 -0
  171. package/dist/src/integrations/github/infrastructure/content-fingerprint.js +10 -0
  172. package/dist/src/integrations/github/infrastructure/delivery.js +31 -0
  173. package/dist/src/integrations/github/infrastructure/etag-cache.js +56 -0
  174. package/dist/src/integrations/github/infrastructure/gh-auth.js +19 -0
  175. package/dist/src/integrations/github/infrastructure/issue-source.js +109 -0
  176. package/dist/src/integrations/github/infrastructure/pr-source.js +186 -0
  177. package/dist/src/integrations/github/infrastructure/review-source.js +70 -0
  178. package/dist/src/integrations/github/infrastructure/source.js +108 -0
  179. package/dist/src/integrations/github/provider.js +96 -0
  180. package/dist/src/integrations/index.js +30 -0
  181. package/dist/src/kernel/contracts/checkpoint-store.js +1 -0
  182. package/dist/src/kernel/contracts/clock.js +1 -0
  183. package/dist/src/kernel/contracts/commands.js +1 -0
  184. package/dist/src/kernel/contracts/event-journal.js +2 -0
  185. package/dist/src/kernel/contracts/event-schema.js +54 -0
  186. package/dist/src/kernel/contracts/events.js +11 -0
  187. package/dist/src/kernel/contracts/id-generator.js +1 -0
  188. package/dist/src/kernel/contracts/identifiers.js +8 -0
  189. package/dist/src/kernel/contracts/projection-store.js +1 -0
  190. package/dist/src/kernel/contracts/relations.js +1 -0
  191. package/dist/src/kernel/contracts/schema.js +17 -0
  192. package/dist/src/kernel/contracts/vocabulary.js +6 -0
  193. package/dist/src/kernel/domain/event-envelope.js +29 -0
  194. package/dist/src/kernel/domain/match-mode.js +11 -0
  195. package/dist/src/kernel/domain/relation.js +10 -0
  196. package/dist/src/kernel/index.js +17 -0
  197. package/dist/src/{lib/clock.js → kernel/infrastructure/system-clock.js} +3 -3
  198. package/dist/src/kernel/infrastructure/ulid-id-generator.js +9 -0
  199. package/dist/src/main.js +137 -1030
  200. package/dist/src/orchestration/application/accept-activity-outcome.js +25 -0
  201. package/dist/src/orchestration/application/accept-signal.js +35 -0
  202. package/dist/src/orchestration/application/advance-workflow.js +160 -0
  203. package/dist/src/orchestration/application/coordination-claims.js +107 -0
  204. package/dist/src/orchestration/application/group-budget-recorder.js +43 -0
  205. package/dist/src/orchestration/application/orchestration-projection.js +20 -0
  206. package/dist/src/orchestration/application/orchestration-repository.js +36 -0
  207. package/dist/src/orchestration/application/orchestration-service.js +82 -0
  208. package/dist/src/orchestration/application/request-child.js +118 -0
  209. package/dist/src/orchestration/application/signal-reactor.js +17 -0
  210. package/dist/src/orchestration/application/start-workflow.js +51 -0
  211. package/dist/src/orchestration/application/watch-reactor.js +82 -0
  212. package/dist/src/orchestration/contracts/activity-outcome.js +18 -0
  213. package/dist/src/orchestration/contracts/commands.js +1 -0
  214. package/dist/src/orchestration/contracts/config.js +128 -0
  215. package/dist/src/orchestration/contracts/event-decoder.js +263 -0
  216. package/dist/src/orchestration/contracts/events.js +41 -0
  217. package/dist/src/orchestration/contracts/identifiers.js +35 -0
  218. package/dist/src/orchestration/contracts/streams.js +38 -0
  219. package/dist/src/orchestration/contracts/views.js +1 -0
  220. package/dist/src/orchestration/contracts/vocabulary.js +30 -0
  221. package/dist/src/orchestration/domain/activation-policy.js +55 -0
  222. package/dist/src/orchestration/domain/approval-defaults.js +17 -0
  223. package/dist/src/orchestration/domain/child-policy.js +63 -0
  224. package/dist/src/orchestration/domain/compiler.js +162 -0
  225. package/dist/src/orchestration/domain/coordination-events.js +25 -0
  226. package/dist/src/orchestration/domain/decision-events.js +47 -0
  227. package/dist/src/orchestration/domain/interpreter.js +49 -0
  228. package/dist/src/orchestration/domain/operator-retry-policy.js +34 -0
  229. package/dist/src/orchestration/domain/retry-policy.js +26 -0
  230. package/dist/src/orchestration/domain/signal-policy.js +120 -0
  231. package/dist/src/orchestration/domain/supplemental-policy.js +61 -0
  232. package/dist/src/orchestration/domain/transition.js +55 -0
  233. package/dist/src/orchestration/domain/workflow-graph.js +41 -0
  234. package/dist/src/orchestration/domain/workflow-instance-events.js +236 -0
  235. package/dist/src/orchestration/domain/workflow-instance.js +41 -0
  236. package/dist/src/orchestration/domain/workflow-selector.js +21 -0
  237. package/dist/src/orchestration/index.js +19 -0
  238. package/dist/src/persistence/application/projection-runner.js +79 -0
  239. package/dist/src/persistence/filesystem/file-checkpoint-store.js +35 -0
  240. package/dist/src/persistence/filesystem/file-event-journal.js +143 -0
  241. package/dist/src/persistence/filesystem/file-lock.js +91 -0
  242. package/dist/src/persistence/filesystem/file-projection-store.js +64 -0
  243. package/dist/src/persistence/index.js +8 -0
  244. package/dist/src/persistence/memory/in-memory-checkpoint-store.js +14 -0
  245. package/dist/src/persistence/memory/in-memory-event-journal.js +88 -0
  246. package/dist/src/persistence/memory/in-memory-projection-store.js +17 -0
  247. package/dist/src/resources/application/lookup-projections.js +48 -0
  248. package/dist/src/resources/application/resource-lookup.js +16 -0
  249. package/dist/src/resources/application/resource-projections.js +81 -0
  250. package/dist/src/resources/application/resource-repository.js +18 -0
  251. package/dist/src/resources/application/resource-service.js +83 -0
  252. package/dist/src/resources/contracts/commands.js +1 -0
  253. package/dist/src/resources/contracts/config.js +2 -0
  254. package/dist/src/resources/contracts/events.js +83 -0
  255. package/dist/src/resources/contracts/identifiers.js +15 -0
  256. package/dist/src/resources/contracts/streams.js +6 -0
  257. package/dist/src/resources/contracts/views.js +1 -0
  258. package/dist/src/resources/contracts/vocabulary.js +67 -0
  259. package/dist/src/resources/domain/correlation.js +8 -0
  260. package/dist/src/resources/domain/resource.js +58 -0
  261. package/dist/src/resources/index.js +14 -0
  262. package/dist/src/surfaces/api/contracts/activities.js +1 -0
  263. package/dist/src/surfaces/api/contracts/board.js +2 -0
  264. package/dist/src/surfaces/api/contracts/common.js +46 -0
  265. package/dist/src/surfaces/api/contracts/control-plane.js +5 -0
  266. package/dist/src/surfaces/api/contracts/events.js +1 -0
  267. package/dist/src/surfaces/api/contracts/execution.js +1 -0
  268. package/dist/src/surfaces/api/contracts/index.js +13 -0
  269. package/dist/src/surfaces/api/contracts/observability.js +1 -0
  270. package/dist/src/surfaces/api/contracts/orchestration.js +1 -0
  271. package/dist/src/surfaces/api/contracts/resources.js +1 -0
  272. package/dist/src/surfaces/api/contracts/status.js +1 -0
  273. package/dist/src/surfaces/api/contracts/system.js +1 -0
  274. package/dist/src/surfaces/api/contracts/transport-values.js +39 -0
  275. package/dist/src/surfaces/api/contracts/work.js +17 -0
  276. package/dist/src/surfaces/api/http-server.js +121 -0
  277. package/dist/src/surfaces/api/presenters/activities.js +1 -0
  278. package/dist/src/surfaces/api/presenters/board.js +3 -0
  279. package/dist/src/surfaces/api/presenters/control-plane.js +1 -0
  280. package/dist/src/surfaces/api/presenters/events.js +1 -0
  281. package/dist/src/surfaces/api/presenters/execution.js +59 -0
  282. package/dist/src/surfaces/api/presenters/observability.js +1 -0
  283. package/dist/src/surfaces/api/presenters/orchestration.js +19 -0
  284. package/dist/src/surfaces/api/presenters/resources.js +15 -0
  285. package/dist/src/surfaces/api/presenters/status.js +3 -0
  286. package/dist/src/surfaces/api/presenters/system.js +14 -0
  287. package/dist/src/surfaces/api/presenters/work.js +16 -0
  288. package/dist/src/surfaces/api/problem-details.js +9 -0
  289. package/dist/src/surfaces/api/router.js +13 -0
  290. package/dist/src/surfaces/api/routes/activities.js +1 -0
  291. package/dist/src/surfaces/api/routes/applications.js +1 -0
  292. package/dist/src/surfaces/api/routes/commands.js +82 -0
  293. package/dist/src/surfaces/api/routes/control-plane.js +6 -0
  294. package/dist/src/surfaces/api/routes/events.js +1 -0
  295. package/dist/src/surfaces/api/routes/execution.js +8 -0
  296. package/dist/src/surfaces/api/routes/index.js +18 -0
  297. package/dist/src/surfaces/api/routes/observability.js +1 -0
  298. package/dist/src/surfaces/api/routes/orchestration.js +1 -0
  299. package/dist/src/surfaces/api/routes/pagination.js +78 -0
  300. package/dist/src/surfaces/api/routes/read.js +135 -0
  301. package/dist/src/surfaces/api/routes/resources.js +1 -0
  302. package/dist/src/surfaces/api/routes/responses.js +67 -0
  303. package/dist/src/surfaces/api/routes/system.js +1 -0
  304. package/dist/src/surfaces/api/routes/work.js +9 -0
  305. package/dist/src/surfaces/cli/commands/api.js +1 -0
  306. package/dist/src/surfaces/cli/commands/audit.js +10 -0
  307. package/dist/src/surfaces/cli/commands/correlate.js +2 -0
  308. package/dist/src/surfaces/cli/commands/doctor.js +6 -0
  309. package/dist/src/surfaces/cli/commands/init.js +39 -0
  310. package/dist/src/surfaces/cli/commands/sandbox-entrypoint.js +33 -0
  311. package/dist/src/surfaces/cli/commands/sandbox-setup.js +29 -0
  312. package/dist/src/surfaces/cli/commands/sandbox.js +105 -0
  313. package/dist/src/surfaces/cli/commands/self-update.js +38 -0
  314. package/dist/src/surfaces/cli/commands/smoke.js +16 -0
  315. package/dist/src/surfaces/cli/commands/start.js +1 -0
  316. package/dist/src/surfaces/cli/commands/stop.js +13 -0
  317. package/dist/src/surfaces/cli/commands/tick.js +1 -0
  318. package/dist/src/surfaces/cli/commands/ui.js +2 -0
  319. package/dist/src/surfaces/cli/commands/validate-state.js +5 -0
  320. package/dist/src/surfaces/cli/infrastructure/docker-cli.js +221 -0
  321. package/dist/src/surfaces/cli/infrastructure/process-log.js +86 -0
  322. package/dist/src/surfaces/cli/main.js +140 -0
  323. package/dist/src/surfaces/cli/usage.js +33 -0
  324. package/dist/src/surfaces/contracts/config.js +34 -0
  325. package/dist/src/surfaces/index.js +47 -0
  326. package/dist/src/surfaces/web-assets/assets/index-Bfn4FwZG.css +1 -0
  327. package/dist/src/surfaces/web-assets/assets/index-ipB6JPGU.js +1090 -0
  328. package/dist/src/surfaces/web-assets/index.html +13 -0
  329. package/dist/src/surfaces/web-host/asset-source.js +1 -0
  330. package/dist/src/surfaces/web-host/packaged-assets.js +44 -0
  331. package/dist/src/work/application/work-projection.js +59 -0
  332. package/dist/src/work/application/work-repository.js +18 -0
  333. package/dist/src/work/application/work-service.js +117 -0
  334. package/dist/src/work/contracts/commands.js +1 -0
  335. package/dist/src/work/contracts/config.js +2 -0
  336. package/dist/src/work/contracts/events.js +103 -0
  337. package/dist/src/work/contracts/identifiers.js +5 -0
  338. package/dist/src/work/contracts/streams.js +6 -0
  339. package/dist/src/work/contracts/views.js +1 -0
  340. package/dist/src/work/contracts/vocabulary.js +6 -0
  341. package/dist/src/work/domain/work-item.js +89 -0
  342. package/dist/src/work/index.js +11 -0
  343. package/docker/Dockerfile +10 -6
  344. package/docker/Dockerfile.packaged +3 -3
  345. package/package.json +29 -4
  346. package/prompts/implement.md +2 -2
  347. package/templates/SETUP.md +7 -7
  348. package/dist/src/adapters/claude/claude-runner.js +0 -529
  349. package/dist/src/adapters/codex/codex-runner.js +0 -503
  350. package/dist/src/adapters/cursor/cursor-runner.js +0 -418
  351. package/dist/src/adapters/docker/docker-cli.js +0 -150
  352. package/dist/src/adapters/fake/fake-artifact-verifier.js +0 -14
  353. package/dist/src/adapters/fake/fake-github-pull-request-activity-source.js +0 -77
  354. package/dist/src/adapters/fake/fake-resource-index.js +0 -21
  355. package/dist/src/adapters/fake/fake-runner.js +0 -77
  356. package/dist/src/adapters/fake/fake-ticketing-system.js +0 -185
  357. package/dist/src/adapters/fake/fake-workspace-manager.js +0 -81
  358. package/dist/src/adapters/fs/resource-index.js +0 -126
  359. package/dist/src/adapters/fs/self-update-ledger.js +0 -17
  360. package/dist/src/adapters/fs/state-store.js +0 -775
  361. package/dist/src/adapters/git/git-workspace-manager.js +0 -289
  362. package/dist/src/adapters/github/github-artifact-verifier.js +0 -38
  363. package/dist/src/adapters/github/github-auth.js +0 -16
  364. package/dist/src/adapters/github/github-client.js +0 -249
  365. package/dist/src/adapters/github/github-etag-cache.js +0 -57
  366. package/dist/src/adapters/github/github-issues-work-source.js +0 -692
  367. package/dist/src/adapters/github/github-pull-request-activity-source.js +0 -584
  368. package/dist/src/adapters/github/github-pull-request-merge-actor.js +0 -45
  369. package/dist/src/adapters/http/ui-assets.js +0 -1188
  370. package/dist/src/adapters/http/ui-data.js +0 -1107
  371. package/dist/src/adapters/http/ui-server.js +0 -458
  372. package/dist/src/adapters/runner/cli-command.js +0 -73
  373. package/dist/src/adapters/runner/prompt-templates.js +0 -76
  374. package/dist/src/adapters/runner/runner-cli-adapter.js +0 -112
  375. package/dist/src/adapters/runner/runner-registry.js +0 -139
  376. package/dist/src/adapters/runner/runtime-events.js +0 -32
  377. package/dist/src/adapters/runner/stage-prompt.js +0 -268
  378. package/dist/src/adapters/runner/transcripts.js +0 -25
  379. package/dist/src/cli/audit-command.js +0 -36
  380. package/dist/src/cli/correlate-command.js +0 -62
  381. package/dist/src/cli/doctor-command.js +0 -48
  382. package/dist/src/cli/init-command.js +0 -18
  383. package/dist/src/cli/sandbox-command.js +0 -258
  384. package/dist/src/cli/sandbox-entrypoint-command.js +0 -88
  385. package/dist/src/cli/sandbox-exec-logging.js +0 -7
  386. package/dist/src/cli/sandbox-resume.js +0 -79
  387. package/dist/src/cli/sandbox-setup-command.js +0 -31
  388. package/dist/src/cli/scaffold-assets.js +0 -100
  389. package/dist/src/cli/self-update-command.js +0 -198
  390. package/dist/src/cli/startup-preflight.js +0 -134
  391. package/dist/src/cli/stop-command.js +0 -46
  392. package/dist/src/cli/ui-command.js +0 -27
  393. package/dist/src/config/defaults.js +0 -10
  394. package/dist/src/config/discover-config-files.js +0 -11
  395. package/dist/src/config/load-config.js +0 -69
  396. package/dist/src/config/split-config.js +0 -14
  397. package/dist/src/core/active-run-recovery.js +0 -44
  398. package/dist/src/core/approval-intents.js +0 -16
  399. package/dist/src/core/audit-events.js +0 -82
  400. package/dist/src/core/control-plane.js +0 -192
  401. package/dist/src/core/event-builders.js +0 -153
  402. package/dist/src/core/event-resolver.js +0 -249
  403. package/dist/src/core/lifecycle-service.js +0 -8
  404. package/dist/src/core/live-execution.js +0 -81
  405. package/dist/src/core/outbox.js +0 -198
  406. package/dist/src/core/policy-engine.js +0 -389
  407. package/dist/src/core/projection-updater.js +0 -693
  408. package/dist/src/core/quota-backoff.js +0 -69
  409. package/dist/src/core/run-lease.js +0 -38
  410. package/dist/src/core/scheduled-workflow-source.js +0 -199
  411. package/dist/src/core/sink-router.js +0 -107
  412. package/dist/src/core/stale-run-reconciler.js +0 -352
  413. package/dist/src/core/tick-runner.js +0 -2442
  414. package/dist/src/core/workspace-cleanup.js +0 -117
  415. package/dist/src/domain/branch-naming.js +0 -14
  416. package/dist/src/domain/custom-commands.js +0 -58
  417. package/dist/src/domain/event-types.js +0 -158
  418. package/dist/src/domain/manual-labels.js +0 -1
  419. package/dist/src/domain/resource-uri.js +0 -38
  420. package/dist/src/domain/runner-routing.js +0 -127
  421. package/dist/src/domain/runtime-events.js +0 -36
  422. package/dist/src/domain/schema.js +0 -1233
  423. package/dist/src/domain/sources.js +0 -16
  424. package/dist/src/domain/stages.js +0 -36
  425. package/dist/src/domain/work-item-labels.js +0 -48
  426. package/dist/src/domain/work-item-lifecycle.js +0 -10
  427. package/dist/src/domain/work-item-status.js +0 -33
  428. package/dist/src/domain/workflows.js +0 -159
  429. package/dist/src/lib/deep-merge.js +0 -14
  430. package/dist/src/lib/detached-process-logging.js +0 -46
  431. package/dist/src/lib/event-log.js +0 -21
  432. package/dist/src/lib/format.js +0 -41
  433. package/dist/src/lib/json-file.js +0 -23
  434. package/dist/src/lib/lock.js +0 -181
  435. package/dist/src/lib/log-rotation.js +0 -42
  436. package/dist/src/lib/paths.js +0 -52
  437. package/dist/src/lib/process-identity.js +0 -54
  438. package/dist/src/lib/state-health.js +0 -30
  439. package/dist/src/lib/work-id.js +0 -19
  440. package/dist/src/lib/yaml-file.js +0 -20
  441. /package/dist/src/{core → activities/pr}/contracts.js +0 -0
  442. /package/dist/src/{domain/types.js → control-plane/contracts/views.js} +0 -0
@@ -1,584 +0,0 @@
1
- import { buildResourceUri } from '../../domain/resource-uri.js';
2
- import { createUnkeyedEventEnvelope, createEventEnvelope } from '../../lib/event-log.js';
3
- import { formatGitHubError, formatWakeComment, readControlPlaneUiUrl, wakeIdempotencyMarker, } from './github-issues-work-source.js';
4
- const githubPrSource = 'github-pr';
5
- const wakeCommentMarker = '<!-- wake:agent -->';
6
- function prResourceUri(repo, number) {
7
- return buildResourceUri('github', 'pr', `${repo}#${number}`);
8
- }
9
- function reviewThreadRootId(comment, byId) {
10
- let current = comment;
11
- const visited = new Set();
12
- while (current.in_reply_to_id !== undefined && !visited.has(current.id)) {
13
- visited.add(current.id);
14
- const parent = byId.get(current.in_reply_to_id);
15
- if (parent === undefined) {
16
- break;
17
- }
18
- current = parent;
19
- }
20
- return current.id;
21
- }
22
- function reviewThreadResourceUri(repo, prNumber, rootId) {
23
- return buildResourceUri('github', 'pr-review-thread', `${repo}#${prNumber}/rt_${rootId}`);
24
- }
25
- function safeEventToken(value) {
26
- return value.replace(/[^a-z0-9]+/gi, '-');
27
- }
28
- function isFailingCheckRun(run) {
29
- return (run.status === 'completed' &&
30
- (run.conclusion === 'failure' ||
31
- run.conclusion === 'timed_out' ||
32
- run.conclusion === 'cancelled' ||
33
- run.conclusion === 'action_required'));
34
- }
35
- function isFailingStatus(status) {
36
- return status.state === 'failure' || status.state === 'error';
37
- }
38
- // selfLogin is the only reliable signal for an agent-authored comment posted
39
- // by direct API/CLI call (e.g. a `revise` run replying via `gh api
40
- // .../replies`), which never carries the marker and whose account `type` is
41
- // `User`, not `Bot` — checking only those two would let the agent's own
42
- // replies look human and re-trigger another run against themselves (#258
43
- // follow-up incident: 99 duplicate replies from exactly this gap). Optional
44
- // because it's undefined when the GitHub client is a fake/test double.
45
- function isBotAuthored(comment, selfLogin) {
46
- return (comment.user?.type === 'Bot' ||
47
- (comment.body ?? '').includes(wakeCommentMarker) ||
48
- (selfLogin !== undefined && comment.user?.login === selfLogin));
49
- }
50
- export function createGitHubPullRequestActivitySource(deps) {
51
- function repoAndNumberFromPrUri(resourceUri) {
52
- // github:pr:<owner>/<repo>#<number>
53
- const locator = resourceUri.split(':').slice(2).join(':');
54
- const match = /^([^/]+)\/([^#]+)#(\d+)$/.exec(locator);
55
- if (match === null) {
56
- return null;
57
- }
58
- const [, owner, repo, numberStr] = match;
59
- if (owner === undefined || repo === undefined || numberStr === undefined) {
60
- return null;
61
- }
62
- return { owner, repo, repoRef: `${owner}/${repo}`, number: Number(numberStr) };
63
- }
64
- function reviewThreadRefFromUri(resourceUri) {
65
- const locator = resourceUri.split(':').slice(2).join(':');
66
- const match = /^([^/]+)\/([^#]+)#(\d+)\/rt_(\d+)$/.exec(locator);
67
- if (match === null) {
68
- return null;
69
- }
70
- const [, owner, repo, numberStr, rootIdStr] = match;
71
- if (owner === undefined ||
72
- repo === undefined ||
73
- numberStr === undefined ||
74
- rootIdStr === undefined) {
75
- return null;
76
- }
77
- return {
78
- owner,
79
- repo,
80
- repoRef: `${owner}/${repo}`,
81
- number: Number(numberStr),
82
- rootId: Number(rootIdStr),
83
- };
84
- }
85
- function prCommentPublishedEvent(input) {
86
- return createEventEnvelope({
87
- eventId: `${input.intent.eventId}-published`,
88
- workItemKey: input.intent.workItemKey,
89
- streamScope: 'work-item',
90
- direction: 'outbound',
91
- sourceSystem: githubPrSource,
92
- sourceEventType: 'pr.comment.reply.published',
93
- sourceRefs: { repo: input.repoRef, resourceUri: input.resourceUri },
94
- occurredAt: input.publishedAt,
95
- ingestedAt: input.publishedAt,
96
- trigger: 'context-only',
97
- payload: {
98
- intentEventId: input.intent.eventId,
99
- idempotencyKey: input.intent.payload.idempotencyKey,
100
- deliveryState: 'CONFIRMED',
101
- kind: input.intent.payload.kind,
102
- body: input.intent.payload.body,
103
- providerId: input.providerId,
104
- },
105
- });
106
- }
107
- function reviewCommentPublishedEvent(input) {
108
- return createEventEnvelope({
109
- eventId: `${input.intent.eventId}-published`,
110
- workItemKey: input.intent.workItemKey,
111
- streamScope: 'work-item',
112
- direction: 'outbound',
113
- sourceSystem: githubPrSource,
114
- sourceEventType: 'pr.review-comment.reply.published',
115
- sourceRefs: {
116
- resourceUri: input.resourceUri,
117
- sourceUrl: input.sourceUrl,
118
- },
119
- occurredAt: input.publishedAt,
120
- ingestedAt: input.publishedAt,
121
- trigger: 'context-only',
122
- payload: {
123
- intentEventId: input.intent.eventId,
124
- idempotencyKey: input.intent.payload.idempotencyKey,
125
- deliveryState: 'CONFIRMED',
126
- kind: input.intent.payload.kind,
127
- body: input.intent.payload.body,
128
- providerId: input.providerId,
129
- },
130
- });
131
- }
132
- async function discoverPullRequests(ingestedAt) {
133
- const seenPrData = new Map();
134
- const confirmedOpenRepos = new Set();
135
- if (!deps.config.sources.github.pullRequests.enabled) {
136
- return { events: [], seenPrData, confirmedOpenRepos };
137
- }
138
- const events = [];
139
- for (const repoRef of deps.config.sources.github.repos) {
140
- const [owner, repo] = repoRef.split('/');
141
- if (owner === undefined || repo === undefined) {
142
- continue;
143
- }
144
- try {
145
- const maxResults = deps.config.sources.github.pullRequests.maxPullRequestsPerRepo;
146
- const prs = await deps.client.listPullRequests(owner, repo, maxResults);
147
- // listPullRequests only ever returns open PRs (state: 'open'), so an
148
- // uncapped result set here is a complete picture of what's currently
149
- // open — used below to confirm a watched PR has actually closed
150
- // rather than merely being truncated by maxResults.
151
- if (prs.length < maxResults) {
152
- confirmedOpenRepos.add(repoRef);
153
- }
154
- for (const pr of prs) {
155
- const resourceUri = prResourceUri(repoRef, pr.number);
156
- seenPrData.set(resourceUri, {
157
- headSha: pr.head.sha,
158
- baseRef: pr.base?.ref,
159
- htmlUrl: pr.html_url,
160
- });
161
- const known = await deps.resourceIndex.resolve(resourceUri);
162
- if (known !== undefined) {
163
- continue;
164
- }
165
- events.push(createUnkeyedEventEnvelope({
166
- // Embeds updated_at (mirroring the issue path's ticket.upsert
167
- // eventId) so a PR that fails mint qualification is re-offered
168
- // for qualification whenever it actually changes — not
169
- // permanently quarantined under UNRESOLVED_WORK_ITEM_KEY the
170
- // first time it's seen, even after config or the PR itself
171
- // changes. appendEventEnvelope still dedups on eventId, so an
172
- // unchanged PR is only ever appended once per updated_at value.
173
- eventId: `pr-seen-${repoRef.replace(/[^a-z0-9]+/gi, '-')}-${pr.number}-${pr.updated_at}`,
174
- streamScope: 'global-intake',
175
- direction: 'inbound',
176
- sourceSystem: githubPrSource,
177
- sourceEventType: 'pr.seen',
178
- sourceRefs: { repo: repoRef, sourceUrl: pr.html_url, resourceUri },
179
- occurredAt: pr.updated_at,
180
- ingestedAt,
181
- trigger: 'context-only',
182
- payload: {
183
- pr: {
184
- number: pr.number,
185
- author: pr.user?.login ?? 'unknown',
186
- headRef: pr.head.ref,
187
- },
188
- },
189
- }));
190
- }
191
- }
192
- catch (error) {
193
- console.error(`[github-pr-activity-source] discovery failed for ${repoRef}, skipping this tick: ${formatGitHubError(error)}`);
194
- }
195
- }
196
- return { events, seenPrData, confirmedOpenRepos };
197
- }
198
- async function pollWatchedPr(resourceUri, ingestedAt) {
199
- if (!deps.config.sources.github.pullRequests.enabled) {
200
- return [];
201
- }
202
- const ref = repoAndNumberFromPrUri(resourceUri);
203
- if (ref === null) {
204
- return [];
205
- }
206
- const events = [];
207
- const perPage = deps.config.sources.github.pullRequests.commentPageSize;
208
- try {
209
- const comments = await deps.client.listComments(ref.owner, ref.repo, ref.number, perPage);
210
- for (const comment of comments) {
211
- events.push(createUnkeyedEventEnvelope({
212
- eventId: `pr-comment-${ref.repoRef}-${ref.number}-${comment.id}-${comment.updated_at}`,
213
- streamScope: 'work-item',
214
- direction: 'inbound',
215
- sourceSystem: githubPrSource,
216
- sourceEventType: 'pr.comment.created',
217
- sourceRefs: {
218
- repo: ref.repoRef,
219
- commentId: String(comment.id),
220
- sourceUrl: comment.html_url,
221
- resourceUri,
222
- },
223
- occurredAt: comment.updated_at,
224
- ingestedAt,
225
- trigger: 'context-only',
226
- payload: {
227
- comment: {
228
- id: `pr-${comment.id}`,
229
- body: comment.body ?? '',
230
- author: { login: comment.user?.login ?? 'unknown' },
231
- createdAt: comment.created_at,
232
- updatedAt: comment.updated_at,
233
- resourceUri,
234
- },
235
- },
236
- derivedHints: { botAuthoredComment: isBotAuthored(comment, deps.selfLogin) },
237
- }));
238
- }
239
- const reviews = await deps.client.listReviews(ref.owner, ref.repo, ref.number, perPage);
240
- for (const review of reviews) {
241
- // GitHub allows submitting a review (e.g. "Request changes" or
242
- // "Approve") with no comment text — skipping those entirely would
243
- // lose the state-change signal itself, not just a missing comment,
244
- // so a bare state marker is still emitted.
245
- const body = (review.body ?? '').trim();
246
- const submittedAt = review.submitted_at ?? ingestedAt;
247
- events.push(createUnkeyedEventEnvelope({
248
- eventId: `pr-review-${ref.repoRef}-${ref.number}-${review.id}`,
249
- streamScope: 'work-item',
250
- direction: 'inbound',
251
- sourceSystem: githubPrSource,
252
- sourceEventType: 'pr.review.created',
253
- sourceRefs: {
254
- repo: ref.repoRef,
255
- commentId: `review-${review.id}`,
256
- sourceUrl: review.html_url,
257
- resourceUri,
258
- },
259
- occurredAt: submittedAt,
260
- ingestedAt,
261
- trigger: 'context-only',
262
- payload: {
263
- comment: {
264
- id: `pr-review-${review.id}`,
265
- body: body.length === 0 ? `[${review.state}]` : `[${review.state}] ${body}`,
266
- author: { login: review.user?.login ?? 'unknown' },
267
- createdAt: submittedAt,
268
- updatedAt: submittedAt,
269
- resourceUri,
270
- },
271
- },
272
- derivedHints: { botAuthoredComment: isBotAuthored(review, deps.selfLogin) },
273
- }));
274
- }
275
- const reviewComments = await deps.client.listReviewComments(ref.owner, ref.repo, ref.number, perPage);
276
- const byId = new Map(reviewComments.map((c) => [c.id, c]));
277
- for (const comment of reviewComments) {
278
- const rootId = reviewThreadRootId(comment, byId);
279
- const threadUri = reviewThreadResourceUri(ref.repoRef, ref.number, rootId);
280
- events.push(createUnkeyedEventEnvelope({
281
- eventId: `pr-review-comment-${ref.repoRef}-${ref.number}-${comment.id}-${comment.updated_at}`,
282
- streamScope: 'work-item',
283
- direction: 'inbound',
284
- sourceSystem: githubPrSource,
285
- sourceEventType: 'pr.review-comment.created',
286
- sourceRefs: {
287
- repo: ref.repoRef,
288
- commentId: String(comment.id),
289
- sourceUrl: comment.html_url,
290
- resourceUri: threadUri,
291
- // The thread's own resourceUri is never registered on its own
292
- // (each thread is unique), so core falls back to resolving via
293
- // the owning PR when this misses the index on first sighting.
294
- parentResourceUri: resourceUri,
295
- },
296
- occurredAt: comment.updated_at,
297
- ingestedAt,
298
- trigger: 'context-only',
299
- payload: {
300
- comment: {
301
- id: `pr-review-comment-${comment.id}`,
302
- body: comment.body ?? '',
303
- author: { login: comment.user?.login ?? 'unknown' },
304
- createdAt: comment.created_at,
305
- updatedAt: comment.updated_at,
306
- resourceUri: threadUri,
307
- reviewThread: {
308
- path: comment.path,
309
- line: comment.line ?? comment.original_line ?? undefined,
310
- },
311
- },
312
- },
313
- derivedHints: { botAuthoredComment: isBotAuthored(comment, deps.selfLogin) },
314
- }));
315
- }
316
- }
317
- catch (error) {
318
- console.error(`[github-pr-activity-source] activity poll failed for ${resourceUri}, skipping this tick: ${formatGitHubError(error)}`);
319
- }
320
- return events;
321
- }
322
- async function pollRequiredCheckFailures(ref, resourceUri, ingestedAt, cachedPr) {
323
- if (!deps.config.sources.github.pullRequests.enabled ||
324
- !deps.config.sources.github.pullRequests.checks.enabled ||
325
- deps.client.getRequiredStatusChecks === undefined ||
326
- deps.client.listCheckRunsForRef === undefined ||
327
- deps.client.getCombinedStatusForRef === undefined) {
328
- return [];
329
- }
330
- // headSha/baseRef/htmlUrl are already returned by this tick's PR
331
- // discovery pass (listPullRequests) — reuse that instead of spending a
332
- // dedicated getPullRequest call per watched PR. Falls back only when the
333
- // watched PR wasn't present in discovery (e.g. truncated by
334
- // maxPullRequestsPerRepo, or pullRequests polling failed this tick).
335
- let headSha;
336
- let baseRef;
337
- let htmlUrl;
338
- if (cachedPr?.headSha !== undefined && cachedPr.baseRef !== undefined) {
339
- headSha = cachedPr.headSha;
340
- baseRef = cachedPr.baseRef;
341
- htmlUrl = cachedPr.htmlUrl;
342
- }
343
- else {
344
- const pr = await deps.client.getPullRequest(ref.owner, ref.repo, ref.number);
345
- headSha = pr.head.sha;
346
- baseRef = pr.base?.ref;
347
- htmlUrl = pr.html_url;
348
- }
349
- if (headSha === undefined || baseRef === undefined) {
350
- return [];
351
- }
352
- const required = await deps.client.getRequiredStatusChecks(ref.owner, ref.repo, baseRef);
353
- const requiredContexts = new Set([...required.contexts, ...required.checks]);
354
- if (requiredContexts.size === 0) {
355
- return [];
356
- }
357
- const [checkRuns, statuses] = await Promise.all([
358
- deps.client.listCheckRunsForRef(ref.owner, ref.repo, headSha),
359
- deps.client.getCombinedStatusForRef(ref.owner, ref.repo, headSha),
360
- ]);
361
- const events = [];
362
- for (const run of checkRuns) {
363
- if (!requiredContexts.has(run.name) || !isFailingCheckRun(run)) {
364
- continue;
365
- }
366
- const occurredAt = run.completed_at ?? run.started_at ?? ingestedAt;
367
- const sourceUrl = run.html_url ?? run.details_url ?? htmlUrl;
368
- events.push(createUnkeyedEventEnvelope({
369
- eventId: `pr-check-failed-${safeEventToken(ref.repoRef)}-${ref.number}-${safeEventToken(run.name)}-${headSha}-${safeEventToken(occurredAt)}-${run.conclusion}`,
370
- streamScope: 'work-item',
371
- direction: 'inbound',
372
- sourceSystem: githubPrSource,
373
- sourceEventType: 'pr.checks.failed',
374
- sourceRefs: { repo: ref.repoRef, sourceUrl, resourceUri },
375
- occurredAt,
376
- ingestedAt,
377
- trigger: 'context-only',
378
- payload: {
379
- comment: {
380
- id: `pr-check-failed-${headSha}-${run.id}-${run.conclusion}`,
381
- body: `Required check failed: ${run.name} (${run.conclusion}).`,
382
- author: { login: 'github-checks' },
383
- createdAt: occurredAt,
384
- updatedAt: occurredAt,
385
- resourceUri,
386
- },
387
- checkFailure: {
388
- kind: 'check_run',
389
- name: run.name,
390
- conclusion: run.conclusion,
391
- headSha,
392
- },
393
- },
394
- }));
395
- }
396
- for (const status of statuses) {
397
- if (!requiredContexts.has(status.context) || !isFailingStatus(status)) {
398
- continue;
399
- }
400
- events.push(createUnkeyedEventEnvelope({
401
- eventId: `pr-status-failed-${safeEventToken(ref.repoRef)}-${ref.number}-${safeEventToken(status.context)}-${headSha}-${safeEventToken(status.updated_at)}-${status.state}`,
402
- streamScope: 'work-item',
403
- direction: 'inbound',
404
- sourceSystem: githubPrSource,
405
- sourceEventType: 'pr.checks.failed',
406
- sourceRefs: {
407
- repo: ref.repoRef,
408
- sourceUrl: status.target_url ?? htmlUrl,
409
- resourceUri,
410
- },
411
- occurredAt: status.updated_at,
412
- ingestedAt,
413
- trigger: 'context-only',
414
- payload: {
415
- comment: {
416
- id: `pr-status-failed-${headSha}-${status.context}-${status.state}`,
417
- body: `Required status failed: ${status.context} (${status.state})${status.description === undefined || status.description === null ? '.' : `: ${status.description}`}`,
418
- author: { login: 'github-status' },
419
- createdAt: status.created_at,
420
- updatedAt: status.updated_at,
421
- resourceUri,
422
- },
423
- checkFailure: {
424
- kind: 'status',
425
- name: status.context,
426
- conclusion: status.state,
427
- headSha,
428
- },
429
- },
430
- }));
431
- }
432
- return events;
433
- }
434
- return {
435
- async pollEvents(input) {
436
- const ingestedAt = deps.now().toISOString();
437
- const watched = (input?.watch ?? []).filter((ref) => ref.resourceUri.startsWith('github:pr:'));
438
- const { events: discovered, seenPrData, confirmedOpenRepos, } = await discoverPullRequests(ingestedAt);
439
- // A watched PR absent from this tick's complete open-PR listing has
440
- // closed or merged — stop spending its 7 activity/checks calls every
441
- // tick. `confirmedOpenRepos` only covers repos where discovery
442
- // succeeded and wasn't truncated, so an untruncated miss or a failed
443
- // repo poll leaves the PR in the active set rather than risking a
444
- // false drop.
445
- const activeWatched = watched.filter((ref) => {
446
- const parsed = repoAndNumberFromPrUri(ref.resourceUri);
447
- if (parsed === null) {
448
- return true;
449
- }
450
- return !confirmedOpenRepos.has(parsed.repoRef) || seenPrData.has(ref.resourceUri);
451
- });
452
- const activityBatches = await Promise.all(activeWatched.map((ref) => pollWatchedPr(ref.resourceUri, ingestedAt)));
453
- const checkBatches = await Promise.all(activeWatched.map(async (watchRef) => {
454
- const ref = repoAndNumberFromPrUri(watchRef.resourceUri);
455
- if (ref === null) {
456
- return [];
457
- }
458
- try {
459
- return await pollRequiredCheckFailures(ref, watchRef.resourceUri, ingestedAt, seenPrData.get(watchRef.resourceUri));
460
- }
461
- catch (error) {
462
- console.error(`[github-pr-activity-source] check poll failed for ${watchRef.resourceUri}, skipping this tick: ${formatGitHubError(error)}`);
463
- return [];
464
- }
465
- }));
466
- return [...discovered, ...activityBatches.flat(), ...checkBatches.flat()];
467
- },
468
- async deliverIntent(input) {
469
- const resourceUri = input.event.sourceRefs.resourceUri;
470
- if (resourceUri === undefined) {
471
- throw new Error(`cannot deliver intent ${input.event.eventId}: missing sourceRefs.resourceUri`);
472
- }
473
- const publishedAt = deps.now().toISOString();
474
- if (resourceUri.startsWith('github:pr-review-thread:')) {
475
- const ref = reviewThreadRefFromUri(resourceUri);
476
- if (ref === null) {
477
- throw new Error(`cannot deliver intent ${input.event.eventId}: malformed review-thread uri ${resourceUri}`);
478
- }
479
- const marker = wakeIdempotencyMarker(input.event.payload.idempotencyKey);
480
- if (marker !== undefined) {
481
- const comments = await deps.client.listReviewComments(ref.owner, ref.repo, ref.number, deps.config.sources.github.pullRequests.commentPageSize);
482
- const existing = comments.find((comment) => (comment.body ?? '').includes(marker));
483
- if (existing !== undefined) {
484
- return [
485
- reviewCommentPublishedEvent({
486
- intent: input.event,
487
- resourceUri,
488
- sourceUrl: existing.html_url,
489
- publishedAt,
490
- providerId: existing.id,
491
- }),
492
- ];
493
- }
494
- }
495
- const response = await deps.client.replyToReviewComment(ref.owner, ref.repo, ref.number, ref.rootId, formatWakeComment(input.event.payload, await readControlPlaneUiUrl(deps.config.paths.wakeRoot)));
496
- return [
497
- reviewCommentPublishedEvent({
498
- intent: input.event,
499
- resourceUri,
500
- sourceUrl: response?.html_url,
501
- publishedAt,
502
- providerId: response?.id,
503
- }),
504
- ];
505
- }
506
- const ref = repoAndNumberFromPrUri(resourceUri);
507
- if (ref === null) {
508
- throw new Error(`cannot deliver intent ${input.event.eventId}: malformed pr uri ${resourceUri}`);
509
- }
510
- const marker = wakeIdempotencyMarker(input.event.payload.idempotencyKey);
511
- if (marker !== undefined) {
512
- const comments = await deps.client.listComments(ref.owner, ref.repo, ref.number, deps.config.sources.github.pullRequests.commentPageSize);
513
- const existing = comments.find((comment) => (comment.body ?? '').includes(marker));
514
- if (existing !== undefined) {
515
- return [
516
- prCommentPublishedEvent({
517
- intent: input.event,
518
- resourceUri,
519
- repoRef: ref.repoRef,
520
- publishedAt,
521
- providerId: existing.id,
522
- }),
523
- ];
524
- }
525
- }
526
- const response = await deps.client.createComment(ref.owner, ref.repo, ref.number, formatWakeComment(input.event.payload, await readControlPlaneUiUrl(deps.config.paths.wakeRoot)));
527
- return [
528
- prCommentPublishedEvent({
529
- intent: input.event,
530
- resourceUri,
531
- repoRef: ref.repoRef,
532
- publishedAt,
533
- providerId: response?.data?.id,
534
- }),
535
- ];
536
- },
537
- async reconcileIntent(input) {
538
- const resourceUri = input.event.sourceRefs.resourceUri;
539
- const marker = wakeIdempotencyMarker(input.event.payload.idempotencyKey);
540
- if (resourceUri === undefined || marker === undefined) {
541
- return [];
542
- }
543
- const publishedAt = deps.now().toISOString();
544
- if (resourceUri.startsWith('github:pr-review-thread:')) {
545
- const ref = reviewThreadRefFromUri(resourceUri);
546
- if (ref === null) {
547
- return [];
548
- }
549
- const comments = await deps.client.listReviewComments(ref.owner, ref.repo, ref.number, deps.config.sources.github.pullRequests.commentPageSize);
550
- const existing = comments.find((comment) => (comment.body ?? '').includes(marker));
551
- if (existing === undefined) {
552
- return [];
553
- }
554
- return [
555
- reviewCommentPublishedEvent({
556
- intent: input.event,
557
- resourceUri,
558
- sourceUrl: existing.html_url,
559
- publishedAt,
560
- providerId: existing.id,
561
- }),
562
- ];
563
- }
564
- const ref = repoAndNumberFromPrUri(resourceUri);
565
- if (ref === null) {
566
- return [];
567
- }
568
- const comments = await deps.client.listComments(ref.owner, ref.repo, ref.number, deps.config.sources.github.pullRequests.commentPageSize);
569
- const existing = comments.find((comment) => (comment.body ?? '').includes(marker));
570
- if (existing === undefined) {
571
- return [];
572
- }
573
- return [
574
- prCommentPublishedEvent({
575
- intent: input.event,
576
- resourceUri,
577
- repoRef: ref.repoRef,
578
- publishedAt,
579
- providerId: existing.id,
580
- }),
581
- ];
582
- },
583
- };
584
- }
@@ -1,45 +0,0 @@
1
- // GitHub's enablePullRequestAutoMerge mutation queues a merge pending
2
- // required checks; it refuses with an "already in clean status" error when
3
- // there's nothing left to wait for (checks already passed/skipped). That's
4
- // not a policy rejection — it just means the direct merge endpoint is the
5
- // right call instead of the auto-merge queue.
6
- function isAlreadyCleanError(error) {
7
- return error instanceof Error && /is in clean status/i.test(error.message);
8
- }
9
- function parseGithubPullRequestResourceUri(resourceUri) {
10
- const match = /^github:pr:([^/]+)\/([^#]+)#(\d+)$/.exec(resourceUri);
11
- if (match === null) {
12
- throw new Error(`Unsupported GitHub pull request resource URI: ${resourceUri}`);
13
- }
14
- return {
15
- owner: match[1],
16
- repo: match[2],
17
- pullNumber: Number(match[3]),
18
- };
19
- }
20
- export function createGitHubPullRequestMergeActor(input) {
21
- return {
22
- async listChangedFiles(resourceUri) {
23
- const ref = parseGithubPullRequestResourceUri(resourceUri);
24
- const files = await input.client.listPullRequestFiles(ref.owner, ref.repo, ref.pullNumber);
25
- return files.map((file) => file.filename);
26
- },
27
- async approve(resourceUri, body) {
28
- const ref = parseGithubPullRequestResourceUri(resourceUri);
29
- await input.client.createPullRequestApproval(ref.owner, ref.repo, ref.pullNumber, body);
30
- },
31
- async enableAutoMerge(resourceUri, mergeMethod) {
32
- const ref = parseGithubPullRequestResourceUri(resourceUri);
33
- const pr = await input.client.getPullRequest(ref.owner, ref.repo, ref.pullNumber);
34
- try {
35
- await input.client.enablePullRequestAutoMerge(pr.node_id, mergeMethod);
36
- }
37
- catch (error) {
38
- if (!isAlreadyCleanError(error)) {
39
- throw error;
40
- }
41
- await input.client.mergePullRequest(ref.owner, ref.repo, ref.pullNumber, mergeMethod);
42
- }
43
- },
44
- };
45
- }