dsh-pstack 0.1.0 → 0.2.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (312) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +92 -117
  3. package/assets/agents/comment-sicko.md +1 -1
  4. package/assets/agents/poteto-agent.md +2 -2
  5. package/assets/docs/guide/01-setup.md +9 -9
  6. package/assets/docs/guide/02-poteto-mode.md +4 -4
  7. package/assets/docs/guide/05-build-and-clean.md +3 -3
  8. package/assets/docs/guide/06-verify-and-ship.md +2 -2
  9. package/assets/docs/guide/07-overnight.md +10 -12
  10. package/assets/docs/guide/09-make-it-yours.md +2 -6
  11. package/assets/docs/guide/10-recipes-and-pitfalls.md +3 -3
  12. package/assets/docs/guide/README.md +1 -1
  13. package/assets/docs/guide/images/design.jpg +0 -0
  14. package/assets/docs/guide/images/overnight.jpg +0 -0
  15. package/assets/docs/guide/images/recipes.jpg +0 -0
  16. package/assets/docs/guide/images/router.jpg +0 -0
  17. package/assets/docs/guide/images/understanding.jpg +0 -0
  18. package/assets/docs/guide/images/verification.jpg +0 -0
  19. package/assets/docs/harness/dsh.md +60 -65
  20. package/assets/docs/pstack-models.example.md +40 -9
  21. package/assets/skills/architect/SKILL.md +12 -12
  22. package/assets/skills/arena/SKILL.md +11 -11
  23. package/assets/skills/automate-me/SKILL.md +15 -14
  24. package/assets/skills/benchmark-checklist/SKILL.md +0 -2
  25. package/assets/skills/blast-radius/SKILL.md +5 -5
  26. package/assets/skills/bro/SKILL.md +0 -2
  27. package/assets/skills/correct/SKILL.md +0 -2
  28. package/assets/skills/create-formal-verification-skill/SKILL.md +2 -2
  29. package/assets/skills/create-verification-skill/SKILL.md +2 -2
  30. package/assets/skills/figure-it-out/SKILL.md +13 -13
  31. package/assets/skills/how/SKILL.md +6 -6
  32. package/assets/skills/how/references/explainer-prompt.md +1 -1
  33. package/assets/skills/in-your-own-words/SKILL.md +0 -2
  34. package/assets/skills/interrogate/SKILL.md +9 -7
  35. package/assets/skills/interrogate/references/rubric.md +1 -1
  36. package/assets/skills/ketchup/SKILL.md +4 -4
  37. package/assets/skills/maintain-formal-verification-skill/SKILL.md +2 -2
  38. package/assets/skills/maintain-verification-skill/SKILL.md +3 -3
  39. package/assets/skills/no-comments/SKILL.md +7 -7
  40. package/assets/skills/poteto-help/SKILL.md +32 -31
  41. package/assets/skills/poteto-help/references/prompting.md +1 -1
  42. package/assets/skills/poteto-help/references/recipes.md +1 -1
  43. package/assets/skills/poteto-mode/SKILL.md +17 -19
  44. package/assets/skills/poteto-mode/playbooks/authoring-a-skill.md +3 -3
  45. package/assets/skills/poteto-mode/playbooks/autonomous-run.md +6 -4
  46. package/assets/skills/poteto-mode/playbooks/autopilot-full.md +6 -6
  47. package/assets/skills/poteto-mode/playbooks/autopilot-stack.md +2 -2
  48. package/assets/skills/poteto-mode/playbooks/babysit.md +3 -3
  49. package/assets/skills/poteto-mode/playbooks/bug-fix.md +7 -7
  50. package/assets/skills/poteto-mode/playbooks/eval.md +3 -3
  51. package/assets/skills/poteto-mode/playbooks/feature.md +8 -8
  52. package/assets/skills/poteto-mode/playbooks/hillclimb.md +3 -3
  53. package/assets/skills/poteto-mode/playbooks/investigation.md +2 -2
  54. package/assets/skills/poteto-mode/playbooks/multi-phase-plan.md +21 -21
  55. package/assets/skills/poteto-mode/playbooks/opening-a-pr.md +6 -6
  56. package/assets/skills/poteto-mode/playbooks/orchestrate.md +13 -13
  57. package/assets/skills/poteto-mode/playbooks/pause-safely.md +2 -2
  58. package/assets/skills/poteto-mode/playbooks/perf-issue.md +6 -6
  59. package/assets/skills/poteto-mode/playbooks/prototype.md +4 -4
  60. package/assets/skills/poteto-mode/playbooks/refactoring.md +9 -9
  61. package/assets/skills/poteto-mode/playbooks/runtime-forensics.md +3 -3
  62. package/assets/skills/poteto-mode/playbooks/session-pickup.md +2 -2
  63. package/assets/skills/poteto-mode/playbooks/shipping.md +2 -2
  64. package/assets/skills/poteto-mode/playbooks/trace-forensics.md +2 -2
  65. package/assets/skills/poteto-mode/playbooks/visual-parity.md +5 -5
  66. package/assets/skills/poteto-mode/playbooks/worktree-cleanup.md +14 -6
  67. package/assets/skills/poteto-mode/scripts/check-plan.mjs +85 -70
  68. package/assets/skills/poteto-mode/scripts/check-plan.test.mjs +343 -0
  69. package/assets/skills/poteto-mode/scripts/orch/orch.mjs +4282 -0
  70. package/assets/skills/poteto-mode/scripts/orch/orch.test.mjs +2042 -0
  71. package/assets/skills/poteto-mode/scripts/watch-pr/cli.test.mjs +5101 -0
  72. package/assets/skills/poteto-mode/scripts/watch-pr/github.test.mjs +1177 -0
  73. package/assets/skills/poteto-mode/scripts/watch-pr/policy.test.mjs +1441 -0
  74. package/assets/skills/poteto-mode/scripts/watch-pr/watch-pr.mjs +4601 -0
  75. package/assets/skills/poteto-mode/scripts/worktree-audit.mjs +675 -0
  76. package/assets/skills/principle-attack-the-premise/SKILL.md +0 -2
  77. package/assets/skills/principle-boundary-discipline/SKILL.md +0 -2
  78. package/assets/skills/principle-build-the-lever/SKILL.md +0 -3
  79. package/assets/skills/principle-encode-lessons-in-structure/SKILL.md +0 -2
  80. package/assets/skills/principle-exhaust-the-design-space/SKILL.md +0 -2
  81. package/assets/skills/principle-experience-first/SKILL.md +0 -2
  82. package/assets/skills/principle-explain-the-number/SKILL.md +0 -2
  83. package/assets/skills/principle-fix-root-causes/SKILL.md +0 -2
  84. package/assets/skills/principle-foundational-thinking/SKILL.md +0 -2
  85. package/assets/skills/principle-guard-the-context-window/SKILL.md +0 -2
  86. package/assets/skills/principle-laziness-protocol/SKILL.md +0 -2
  87. package/assets/skills/principle-make-operations-idempotent/SKILL.md +0 -2
  88. package/assets/skills/principle-migrate-callers-then-delete-legacy-apis/SKILL.md +0 -2
  89. package/assets/skills/principle-minimize-reader-load/SKILL.md +0 -2
  90. package/assets/skills/principle-model-the-domain/SKILL.md +0 -2
  91. package/assets/skills/principle-never-block-on-the-human/SKILL.md +0 -2
  92. package/assets/skills/principle-outcome-oriented-execution/SKILL.md +0 -2
  93. package/assets/skills/principle-prove-it-works/SKILL.md +2 -2
  94. package/assets/skills/principle-redesign-from-first-principles/SKILL.md +0 -2
  95. package/assets/skills/principle-separate-before-serializing-shared-state/SKILL.md +0 -2
  96. package/assets/skills/principle-sequence-verifiable-units/SKILL.md +0 -2
  97. package/assets/skills/principle-subtract-before-you-add/SKILL.md +0 -2
  98. package/assets/skills/principle-test-behavior-not-implementation/SKILL.md +0 -2
  99. package/assets/skills/principle-type-system-discipline/SKILL.md +0 -2
  100. package/assets/skills/recall/SKILL.md +9 -9
  101. package/assets/skills/reflect/SKILL.md +20 -21
  102. package/assets/skills/reflect/references/divergent-reviewer.md +4 -4
  103. package/assets/skills/reflect/references/judgment-reviewer.md +2 -2
  104. package/assets/skills/reflect/references/synthesizer.md +6 -6
  105. package/assets/skills/reflect/references/tooling-reviewer.md +2 -2
  106. package/assets/skills/setup-pstack/SKILL.md +28 -37
  107. package/assets/skills/sharpen/SKILL.md +0 -2
  108. package/assets/skills/show-me-your-work/SKILL.md +9 -9
  109. package/assets/skills/show-me-your-work/scripts/log.mjs +108 -0
  110. package/assets/skills/swarm/SKILL.md +8 -6
  111. package/assets/skills/tdd/SKILL.md +0 -2
  112. package/assets/skills/teach/SKILL.md +2 -2
  113. package/assets/skills/technical-writing/SKILL.md +2 -2
  114. package/assets/skills/typescript-best-practices/SKILL.md +6 -4
  115. package/assets/skills/unslop/SKILL.md +0 -2
  116. package/assets/skills/why/SKILL.md +9 -9
  117. package/cordis.patch.yml +33 -14
  118. package/dist/frontmatter-BQX3ekwP.mjs +229 -0
  119. package/dist/frontmatter-BQX3ekwP.mjs.map +1 -0
  120. package/dist/history.d.mts +429 -0
  121. package/dist/history.mjs +1129 -0
  122. package/dist/history.mjs.map +1 -0
  123. package/dist/host-contract-o47JH_r8.d.mts +527 -0
  124. package/dist/index.d.mts +273 -11
  125. package/dist/index.mjs +248 -148
  126. package/dist/index.mjs.map +1 -1
  127. package/dist/paths-D_JlVmBk.mjs +42 -0
  128. package/dist/paths-D_JlVmBk.mjs.map +1 -0
  129. package/dist/script.d.mts +193 -0
  130. package/dist/script.mjs +782 -0
  131. package/dist/script.mjs.map +1 -0
  132. package/dist/subagent.d.mts +306 -100
  133. package/dist/subagent.mjs +1309 -343
  134. package/dist/subagent.mjs.map +1 -1
  135. package/locale/en.json +6 -0
  136. package/locale/zh.json +6 -0
  137. package/package.json +55 -41
  138. package/static/icon.png +0 -0
  139. package/assets/skills/poteto-mode/scripts/bootstrap.ts +0 -62
  140. package/assets/skills/poteto-mode/scripts/bun.lock +0 -67
  141. package/assets/skills/poteto-mode/scripts/check-plan.test.ts +0 -96
  142. package/assets/skills/poteto-mode/scripts/orch/orch.test.ts +0 -761
  143. package/assets/skills/poteto-mode/scripts/orch/orch.ts +0 -590
  144. package/assets/skills/poteto-mode/scripts/orch/store.ts +0 -1677
  145. package/assets/skills/poteto-mode/scripts/package.json +0 -16
  146. package/assets/skills/poteto-mode/scripts/watch-pr/cli.test.ts +0 -224
  147. package/assets/skills/poteto-mode/scripts/watch-pr/cli.ts +0 -223
  148. package/assets/skills/poteto-mode/scripts/watch-pr/fakes.test-helper.ts +0 -129
  149. package/assets/skills/poteto-mode/scripts/watch-pr/github.test.ts +0 -436
  150. package/assets/skills/poteto-mode/scripts/watch-pr/github.ts +0 -718
  151. package/assets/skills/poteto-mode/scripts/watch-pr/policy.test.ts +0 -420
  152. package/assets/skills/poteto-mode/scripts/watch-pr/policy.ts +0 -836
  153. package/assets/skills/poteto-mode/scripts/watch-pr/render.ts +0 -169
  154. package/assets/skills/poteto-mode/scripts/watch-pr/tsconfig.json +0 -13
  155. package/assets/skills/poteto-mode/scripts/watch-pr/types.compile.ts +0 -93
  156. package/assets/skills/poteto-mode/scripts/watch-pr/types.ts +0 -413
  157. package/assets/skills/poteto-mode/scripts/watch-pr/watch-pr +0 -6
  158. package/assets/skills/poteto-mode/scripts/worktree-audit.sh +0 -127
  159. package/assets/skills/show-me-your-work/scripts/log.sh +0 -42
  160. package/dist/LICENSE +0 -22
  161. package/dist/README.md +0 -159
  162. package/dist/assets/agents/comment-sicko.md +0 -32
  163. package/dist/assets/agents/poteto-agent.md +0 -8
  164. package/dist/assets/docs/guide/01-setup.md +0 -64
  165. package/dist/assets/docs/guide/02-poteto-mode.md +0 -139
  166. package/dist/assets/docs/guide/03-understand.md +0 -79
  167. package/dist/assets/docs/guide/04-design.md +0 -133
  168. package/dist/assets/docs/guide/05-build-and-clean.md +0 -83
  169. package/dist/assets/docs/guide/06-verify-and-ship.md +0 -152
  170. package/dist/assets/docs/guide/07-overnight.md +0 -122
  171. package/dist/assets/docs/guide/08-principles.md +0 -72
  172. package/dist/assets/docs/guide/09-make-it-yours.md +0 -100
  173. package/dist/assets/docs/guide/10-recipes-and-pitfalls.md +0 -180
  174. package/dist/assets/docs/guide/README.md +0 -38
  175. package/dist/assets/docs/harness/dsh.md +0 -65
  176. package/dist/assets/docs/pstack-models.example.md +0 -23
  177. package/dist/assets/skills/architect/SKILL.md +0 -81
  178. package/dist/assets/skills/architect/references/design-red-flags.md +0 -57
  179. package/dist/assets/skills/architect/references/rationale-template.md +0 -35
  180. package/dist/assets/skills/architect/references/runner-prompt.md +0 -20
  181. package/dist/assets/skills/arena/SKILL.md +0 -50
  182. package/dist/assets/skills/automate-me/SKILL.md +0 -105
  183. package/dist/assets/skills/benchmark-checklist/SKILL.md +0 -41
  184. package/dist/assets/skills/blast-radius/SKILL.md +0 -52
  185. package/dist/assets/skills/bro/SKILL.md +0 -9
  186. package/dist/assets/skills/correct/SKILL.md +0 -34
  187. package/dist/assets/skills/create-formal-verification-skill/SKILL.md +0 -43
  188. package/dist/assets/skills/create-verification-skill/SKILL.md +0 -46
  189. package/dist/assets/skills/create-verification-skill/references/feature-map-example/README.md +0 -47
  190. package/dist/assets/skills/create-verification-skill/references/feature-map-example/create-note.md +0 -39
  191. package/dist/assets/skills/create-verification-skill/references/feature-map-example/search.md +0 -45
  192. package/dist/assets/skills/figure-it-out/SKILL.md +0 -54
  193. package/dist/assets/skills/how/SKILL.md +0 -38
  194. package/dist/assets/skills/how/references/explainer-prompt.md +0 -55
  195. package/dist/assets/skills/how/references/explorer-prompt.md +0 -35
  196. package/dist/assets/skills/in-your-own-words/SKILL.md +0 -9
  197. package/dist/assets/skills/interrogate/SKILL.md +0 -69
  198. package/dist/assets/skills/interrogate/references/code-quality-review.md +0 -47
  199. package/dist/assets/skills/interrogate/references/lead-judgment.md +0 -39
  200. package/dist/assets/skills/interrogate/references/reviewer-prompt.md +0 -62
  201. package/dist/assets/skills/interrogate/references/rubric.md +0 -77
  202. package/dist/assets/skills/ketchup/SKILL.md +0 -45
  203. package/dist/assets/skills/maintain-formal-verification-skill/SKILL.md +0 -60
  204. package/dist/assets/skills/maintain-verification-skill/SKILL.md +0 -41
  205. package/dist/assets/skills/no-comments/SKILL.md +0 -26
  206. package/dist/assets/skills/poteto-help/SKILL.md +0 -161
  207. package/dist/assets/skills/poteto-help/references/prompting.md +0 -51
  208. package/dist/assets/skills/poteto-help/references/recipes.md +0 -51
  209. package/dist/assets/skills/poteto-mode/SKILL.md +0 -153
  210. package/dist/assets/skills/poteto-mode/playbooks/authoring-a-skill.md +0 -12
  211. package/dist/assets/skills/poteto-mode/playbooks/autonomous-run.md +0 -13
  212. package/dist/assets/skills/poteto-mode/playbooks/autopilot-full.md +0 -25
  213. package/dist/assets/skills/poteto-mode/playbooks/autopilot-stack.md +0 -12
  214. package/dist/assets/skills/poteto-mode/playbooks/babysit.md +0 -23
  215. package/dist/assets/skills/poteto-mode/playbooks/bug-fix.md +0 -15
  216. package/dist/assets/skills/poteto-mode/playbooks/eval.md +0 -25
  217. package/dist/assets/skills/poteto-mode/playbooks/feature.md +0 -21
  218. package/dist/assets/skills/poteto-mode/playbooks/hillclimb.md +0 -21
  219. package/dist/assets/skills/poteto-mode/playbooks/investigation.md +0 -14
  220. package/dist/assets/skills/poteto-mode/playbooks/multi-phase-plan.md +0 -155
  221. package/dist/assets/skills/poteto-mode/playbooks/opening-a-pr.md +0 -34
  222. package/dist/assets/skills/poteto-mode/playbooks/orchestrate.md +0 -112
  223. package/dist/assets/skills/poteto-mode/playbooks/pause-safely.md +0 -10
  224. package/dist/assets/skills/poteto-mode/playbooks/perf-issue.md +0 -25
  225. package/dist/assets/skills/poteto-mode/playbooks/prototype.md +0 -14
  226. package/dist/assets/skills/poteto-mode/playbooks/refactoring.md +0 -16
  227. package/dist/assets/skills/poteto-mode/playbooks/runtime-forensics.md +0 -11
  228. package/dist/assets/skills/poteto-mode/playbooks/session-pickup.md +0 -11
  229. package/dist/assets/skills/poteto-mode/playbooks/shipping.md +0 -12
  230. package/dist/assets/skills/poteto-mode/playbooks/trace-forensics.md +0 -14
  231. package/dist/assets/skills/poteto-mode/playbooks/visual-parity.md +0 -11
  232. package/dist/assets/skills/poteto-mode/playbooks/worktree-cleanup.md +0 -12
  233. package/dist/assets/skills/poteto-mode/references/bugbot-triage.md +0 -142
  234. package/dist/assets/skills/poteto-mode/scripts/bootstrap.ts +0 -62
  235. package/dist/assets/skills/poteto-mode/scripts/bun.lock +0 -67
  236. package/dist/assets/skills/poteto-mode/scripts/check-plan.mjs +0 -205
  237. package/dist/assets/skills/poteto-mode/scripts/check-plan.test.ts +0 -96
  238. package/dist/assets/skills/poteto-mode/scripts/orch/orch.test.ts +0 -761
  239. package/dist/assets/skills/poteto-mode/scripts/orch/orch.ts +0 -590
  240. package/dist/assets/skills/poteto-mode/scripts/orch/store.ts +0 -1677
  241. package/dist/assets/skills/poteto-mode/scripts/package.json +0 -16
  242. package/dist/assets/skills/poteto-mode/scripts/watch-pr/cli.test.ts +0 -224
  243. package/dist/assets/skills/poteto-mode/scripts/watch-pr/cli.ts +0 -223
  244. package/dist/assets/skills/poteto-mode/scripts/watch-pr/fakes.test-helper.ts +0 -129
  245. package/dist/assets/skills/poteto-mode/scripts/watch-pr/github.test.ts +0 -436
  246. package/dist/assets/skills/poteto-mode/scripts/watch-pr/github.ts +0 -718
  247. package/dist/assets/skills/poteto-mode/scripts/watch-pr/policy.test.ts +0 -420
  248. package/dist/assets/skills/poteto-mode/scripts/watch-pr/policy.ts +0 -836
  249. package/dist/assets/skills/poteto-mode/scripts/watch-pr/render.ts +0 -169
  250. package/dist/assets/skills/poteto-mode/scripts/watch-pr/tsconfig.json +0 -13
  251. package/dist/assets/skills/poteto-mode/scripts/watch-pr/types.compile.ts +0 -93
  252. package/dist/assets/skills/poteto-mode/scripts/watch-pr/types.ts +0 -413
  253. package/dist/assets/skills/poteto-mode/scripts/watch-pr/watch-pr +0 -6
  254. package/dist/assets/skills/poteto-mode/scripts/worktree-audit.sh +0 -127
  255. package/dist/assets/skills/principle-attack-the-premise/SKILL.md +0 -23
  256. package/dist/assets/skills/principle-boundary-discipline/SKILL.md +0 -36
  257. package/dist/assets/skills/principle-build-the-lever/SKILL.md +0 -26
  258. package/dist/assets/skills/principle-encode-lessons-in-structure/SKILL.md +0 -13
  259. package/dist/assets/skills/principle-exhaust-the-design-space/SKILL.md +0 -11
  260. package/dist/assets/skills/principle-experience-first/SKILL.md +0 -21
  261. package/dist/assets/skills/principle-explain-the-number/SKILL.md +0 -19
  262. package/dist/assets/skills/principle-fix-root-causes/SKILL.md +0 -23
  263. package/dist/assets/skills/principle-foundational-thinking/SKILL.md +0 -23
  264. package/dist/assets/skills/principle-guard-the-context-window/SKILL.md +0 -14
  265. package/dist/assets/skills/principle-laziness-protocol/SKILL.md +0 -12
  266. package/dist/assets/skills/principle-make-operations-idempotent/SKILL.md +0 -24
  267. package/dist/assets/skills/principle-migrate-callers-then-delete-legacy-apis/SKILL.md +0 -16
  268. package/dist/assets/skills/principle-minimize-reader-load/SKILL.md +0 -20
  269. package/dist/assets/skills/principle-model-the-domain/SKILL.md +0 -26
  270. package/dist/assets/skills/principle-never-block-on-the-human/SKILL.md +0 -17
  271. package/dist/assets/skills/principle-outcome-oriented-execution/SKILL.md +0 -23
  272. package/dist/assets/skills/principle-prove-it-works/SKILL.md +0 -24
  273. package/dist/assets/skills/principle-redesign-from-first-principles/SKILL.md +0 -18
  274. package/dist/assets/skills/principle-separate-before-serializing-shared-state/SKILL.md +0 -18
  275. package/dist/assets/skills/principle-sequence-verifiable-units/SKILL.md +0 -19
  276. package/dist/assets/skills/principle-subtract-before-you-add/SKILL.md +0 -20
  277. package/dist/assets/skills/principle-test-behavior-not-implementation/SKILL.md +0 -22
  278. package/dist/assets/skills/principle-type-system-discipline/SKILL.md +0 -15
  279. package/dist/assets/skills/recall/SKILL.md +0 -37
  280. package/dist/assets/skills/reflect/SKILL.md +0 -70
  281. package/dist/assets/skills/reflect/references/divergent-reviewer.md +0 -38
  282. package/dist/assets/skills/reflect/references/judgment-reviewer.md +0 -37
  283. package/dist/assets/skills/reflect/references/synthesizer.md +0 -56
  284. package/dist/assets/skills/reflect/references/tooling-reviewer.md +0 -48
  285. package/dist/assets/skills/setup-pstack/SKILL.md +0 -76
  286. package/dist/assets/skills/sharpen/SKILL.md +0 -18
  287. package/dist/assets/skills/show-me-your-work/SKILL.md +0 -84
  288. package/dist/assets/skills/show-me-your-work/references/decision-log-template.tsv +0 -1
  289. package/dist/assets/skills/show-me-your-work/scripts/log.sh +0 -42
  290. package/dist/assets/skills/swarm/SKILL.md +0 -41
  291. package/dist/assets/skills/tdd/SKILL.md +0 -44
  292. package/dist/assets/skills/teach/SKILL.md +0 -23
  293. package/dist/assets/skills/technical-writing/SKILL.md +0 -108
  294. package/dist/assets/skills/typescript-best-practices/SKILL.md +0 -32
  295. package/dist/assets/skills/typescript-best-practices/references/patterns.md +0 -328
  296. package/dist/assets/skills/unslop/SKILL.md +0 -64
  297. package/dist/assets/skills/why/SKILL.md +0 -100
  298. package/dist/assets/skills/why/references/epistemics.md +0 -71
  299. package/dist/assets/skills/why/references/investigator-prompt.md +0 -84
  300. package/dist/assets/skills/why/references/source-playbook.md +0 -17
  301. package/dist/assets/skills/why/references/sources/code-archaeology.md +0 -51
  302. package/dist/assets/skills/why/references/sources/databricks.md +0 -70
  303. package/dist/assets/skills/why/references/sources/datadog.md +0 -97
  304. package/dist/assets/skills/why/references/sources/incident-postmortem.md +0 -5
  305. package/dist/assets/skills/why/references/sources/linear.md +0 -48
  306. package/dist/assets/skills/why/references/sources/notion.md +0 -55
  307. package/dist/assets/skills/why/references/sources/sentry.md +0 -66
  308. package/dist/assets/skills/why/references/sources/slack.md +0 -17
  309. package/dist/assets/skills/why/references/synthesizer-prompt.md +0 -129
  310. package/dist/cordis.patch.yml +0 -20
  311. package/dist/paths-Bbai4CaT.mjs +0 -16
  312. package/dist/paths-Bbai4CaT.mjs.map +0 -1
@@ -1,836 +0,0 @@
1
- import {
2
- WatcherQueryError,
3
- resolveChecks,
4
- resolveReviewThreads,
5
- } from "./github.ts";
6
- import type * as T from "./types.ts";
7
- import { nonEmpty } from "./types.ts";
8
- export function assessGitHubMerge(args: {
9
- readonly mergeStateStatus: T.MergeStateStatus;
10
- readonly headRollupState: T.RollupState;
11
- }): T.GitHubMergeAssessment {
12
- if (args.mergeStateStatus === "BLOCKED") {
13
- if (args.headRollupState === "ERROR" || args.headRollupState === "FAILURE")
14
- return {
15
- kind: "refused",
16
- mergeStateStatus: args.mergeStateStatus,
17
- headRollupState: args.headRollupState,
18
- };
19
- return {
20
- kind: "allowed",
21
- basis: "rollup",
22
- mergeStateStatus: args.mergeStateStatus,
23
- headRollupState: args.headRollupState,
24
- };
25
- }
26
- return {
27
- kind: "allowed",
28
- basis: "merge-state",
29
- mergeStateStatus: args.mergeStateStatus,
30
- headRollupState: args.headRollupState,
31
- };
32
- }
33
- async function mergeAssessment(
34
- reader: T.GitHubReader,
35
- facts: T.PullRequestFacts
36
- ) {
37
- const commits = await reader.commitRollups(facts.context);
38
- const headRollupState =
39
- facts.headRefOid === null
40
- ? null
41
- : (commits.find((commit) => commit.oid === facts.headRefOid)?.state ??
42
- null);
43
- return {
44
- hadPreviousPassingCi: commits.some(
45
- (commit) => commit.oid !== facts.headRefOid && commit.state === "SUCCESS"
46
- ),
47
- github: assessGitHubMerge({
48
- mergeStateStatus: facts.mergeStateStatus,
49
- headRollupState,
50
- }),
51
- };
52
- }
53
- const AUTOMATION_TOKENS = [
54
- "bugbot",
55
- "security review",
56
- "pr review automation",
57
- "review automation",
58
- ] as const;
59
- export async function readSnapshot(args: {
60
- readonly reader: T.GitHubReader;
61
- readonly context: T.PrContext;
62
- readonly pendingHistory: "include" | "omit";
63
- readonly allowDraft: boolean;
64
- }): Promise<T.PrSnapshot> {
65
- const facts = await args.reader.pullRequest(args.context);
66
- if (facts.state === "MERGED" || facts.mergedAt !== null)
67
- return { kind: "merged", context: args.context, facts };
68
- if (facts.state === "CLOSED")
69
- return { kind: "closed", context: args.context, facts };
70
- const threads = await resolveReviewThreads(args.reader, args.context);
71
- const checks = await resolveChecks(args.reader, args.context);
72
- const failed = nonEmpty(
73
- checks.checks.filter(
74
- (check): check is T.FailedCheck => check.kind === "failed"
75
- )
76
- );
77
- const pending = nonEmpty(
78
- checks.checks.filter(
79
- (check): check is T.PendingCheck => check.kind === "pending"
80
- )
81
- );
82
- let ci: T.CiState;
83
- if (failed === null && pending !== null && args.pendingHistory === "omit")
84
- ci = {
85
- kind: "ci-pending",
86
- source: checks.source,
87
- all: checks.checks,
88
- failed: [],
89
- pending,
90
- hadPreviousPassingCi: false,
91
- };
92
- else {
93
- const merge = await mergeAssessment(args.reader, facts);
94
- const base = {
95
- source: checks.source,
96
- all: checks.checks,
97
- hadPreviousPassingCi: merge.hadPreviousPassingCi,
98
- };
99
- if (failed !== null)
100
- ci = {
101
- ...base,
102
- kind: "ci-failing",
103
- failed,
104
- pending: pending ?? [],
105
- github: merge.github,
106
- };
107
- else if (merge.github.kind === "refused")
108
- ci = {
109
- ...base,
110
- kind: "ci-github-rejected",
111
- failed: [],
112
- pending: pending ?? [],
113
- github: merge.github,
114
- };
115
- else if (pending !== null)
116
- ci = { ...base, kind: "ci-pending", failed: [], pending };
117
- else
118
- ci = {
119
- ...base,
120
- kind: "ci-clean",
121
- failed: [],
122
- pending: [],
123
- github: merge.github,
124
- };
125
- }
126
- return {
127
- kind: "open",
128
- context: args.context,
129
- facts,
130
- threads,
131
- ci,
132
- reviewAutomationRunning: checks.checks.some(
133
- (check) =>
134
- check.kind === "pending" &&
135
- AUTOMATION_TOKENS.some((token) =>
136
- check.name.toLowerCase().includes(token)
137
- )
138
- ),
139
- };
140
- }
141
- const conflictBlocker = (row: T.PrSnapshot): T.MergeBlocker | null =>
142
- row.kind === "open" &&
143
- (row.facts.mergeable === "CONFLICTING" ||
144
- row.facts.mergeStateStatus === "DIRTY" ||
145
- row.facts.mergeStateStatus === "CONFLICTING")
146
- ? { kind: "merge-conflicts", pr: row.context, facts: row.facts }
147
- : null;
148
- function threadBlocker(row: T.PrSnapshot): T.MergeBlocker | null {
149
- if (row.kind !== "open") return null;
150
- const threads = nonEmpty(row.threads);
151
- return threads === null
152
- ? null
153
- : { kind: "review-threads", pr: row.context, threads };
154
- }
155
- const ciBlocker = (row: T.PrSnapshot): T.MergeBlocker | null =>
156
- row.kind === "open" &&
157
- (row.ci.kind === "ci-failing" || row.ci.kind === "ci-github-rejected")
158
- ? { kind: "failing-checks", pr: row.context, ci: row.ci }
159
- : null;
160
- function gateReason(
161
- row: T.PrSnapshot,
162
- allowDraft: boolean
163
- ): T.MergeGateReason | null {
164
- if (row.kind === "merged") return null;
165
- if (row.kind === "closed") return "closed-without-merge";
166
- if (row.facts.isDraft && !allowDraft) return "draft-pr";
167
- return row.facts.reviewDecision === "CHANGES_REQUESTED"
168
- ? "changes-requested"
169
- : null;
170
- }
171
- function gateBlocker(
172
- row: T.PrSnapshot,
173
- allowDraft: boolean
174
- ): T.MergeBlocker | null {
175
- const reason = gateReason(row, allowDraft);
176
- return reason === null ||
177
- (reason === "draft-pr" &&
178
- row.kind === "open" &&
179
- row.ci.kind === "ci-pending")
180
- ? null
181
- : { kind: "merge-gate", pr: row.context, reason };
182
- }
183
- function readyContribution(
184
- row: T.PrSnapshot,
185
- allowDraft: boolean
186
- ): T.ReadyPr | T.MergedPr | null {
187
- if (row.kind === "merged")
188
- return {
189
- kind: "merged-pr",
190
- context: row.context,
191
- mergedAt: row.facts.mergedAt,
192
- };
193
- if (
194
- row.kind !== "open" ||
195
- row.ci.kind !== "ci-clean" ||
196
- row.threads.length !== 0 ||
197
- conflictBlocker(row) !== null ||
198
- gateReason(row, allowDraft) !== null
199
- )
200
- return null;
201
- const reviewDecision = row.facts.reviewDecision;
202
- if (reviewDecision === "CHANGES_REQUESTED") return null;
203
- return {
204
- kind: "ready-pr",
205
- context: row.context,
206
- proof: {
207
- mergeability: "clear",
208
- threads: [],
209
- ci: row.ci,
210
- gate: {
211
- state: "OPEN",
212
- reviewDecision,
213
- draft: row.facts.isDraft ? "draft-allowed" : "not-draft",
214
- },
215
- },
216
- };
217
- }
218
- export function classifyPr(
219
- row: T.PrSnapshot,
220
- allowDraft = false
221
- ): T.PrDecision {
222
- for (const blocker of [
223
- conflictBlocker(row),
224
- threadBlocker(row),
225
- ciBlocker(row),
226
- gateBlocker(row, allowDraft),
227
- ])
228
- if (blocker !== null) return { kind: "blocker", blocker };
229
- if (row.kind === "open" && row.ci.kind === "ci-pending")
230
- return { kind: "waiting", frontier: row.context, pending: row.ci.pending };
231
- const ready = readyContribution(row, allowDraft);
232
- if (ready === null) throw new Error("snapshot has no classified decision");
233
- return ready.kind === "merged-pr"
234
- ? { kind: "merged", pr: ready }
235
- : { kind: "ready", pr: ready };
236
- }
237
- export function selectTierMajorStackDecision(
238
- rows: T.NonEmpty<T.PrSnapshot>,
239
- allowDraft = false
240
- ): T.StackDecision {
241
- for (const tier of [conflictBlocker, threadBlocker, ciBlocker])
242
- for (const row of rows) {
243
- const blocker = tier(row);
244
- if (blocker !== null) return { kind: "blocker", blocker };
245
- }
246
- for (const row of rows) {
247
- const blocker = gateBlocker(row, allowDraft);
248
- if (blocker !== null) return { kind: "blocker", blocker };
249
- }
250
- for (const row of rows)
251
- if (row.kind === "open" && row.ci.kind === "ci-pending")
252
- return {
253
- kind: "waiting",
254
- frontier: row.context,
255
- pending: row.ci.pending,
256
- };
257
- const prs = nonEmpty(
258
- rows
259
- .map((row) => readyContribution(row, allowDraft))
260
- .filter((row): row is T.ReadyPr | T.MergedPr => row !== null)
261
- );
262
- if (prs === null || prs.length !== rows.length)
263
- throw new Error("stack has no classified decision");
264
- return { kind: "clear", prs };
265
- }
266
- export const queryBackoffSeconds = (
267
- interval: number,
268
- failures: number
269
- ): number => Math.min(Math.max(interval, 60) * 2 ** (failures - 1), 300);
270
- interface Envelope<M extends T.WatchMode> {
271
- readonly schemaVersion: 1;
272
- readonly sequence: number;
273
- readonly observedAt: string;
274
- readonly mode: M;
275
- }
276
- type Payload<V> = V extends unknown
277
- ? Omit<V, keyof Envelope<T.WatchMode>>
278
- : never;
279
- type VerdictPayload = Payload<T.WatcherVerdict>;
280
- export interface VerdictStamp<M extends T.WatchMode = T.WatchMode> {
281
- <const P extends VerdictPayload>(payload: P): Envelope<M> & P;
282
- <const P extends VerdictPayload, M2 extends T.WatchMode>(
283
- payload: P,
284
- mode: M2
285
- ): Envelope<M2> & P;
286
- }
287
- export function verdictFactory<M extends T.WatchMode>(
288
- clock: WatchClock,
289
- mode: M
290
- ): VerdictStamp<M> {
291
- let sequence = 0;
292
- function stamp<const P extends VerdictPayload>(payload: P): Envelope<M> & P;
293
- function stamp<const P extends VerdictPayload, M2 extends T.WatchMode>(
294
- payload: P,
295
- mode: M2
296
- ): Envelope<M2> & P;
297
- function stamp<const P extends VerdictPayload>(
298
- payload: P,
299
- override?: T.WatchMode
300
- ): Envelope<T.WatchMode> & P {
301
- return {
302
- schemaVersion: 1,
303
- sequence: (sequence += 1),
304
- observedAt: clock.observedAt(),
305
- mode: override ?? mode,
306
- ...payload,
307
- };
308
- }
309
- return stamp;
310
- }
311
- function blockerVerdict(
312
- stamp: VerdictStamp,
313
- blocker: T.MergeBlocker
314
- ): T.BlockerVerdict {
315
- switch (blocker.kind) {
316
- case "merge-conflicts":
317
- return stamp({ kind: "BLOCKER", terminal: true, exitCode: 2, blocker });
318
- case "review-threads":
319
- return stamp({ kind: "BLOCKER", terminal: true, exitCode: 3, blocker });
320
- case "failing-checks":
321
- return stamp({ kind: "BLOCKER", terminal: true, exitCode: 4, blocker });
322
- case "merge-gate":
323
- return stamp({ kind: "BLOCKER", terminal: true, exitCode: 6, blocker });
324
- default: {
325
- const exhaustive: never = blocker;
326
- return exhaustive;
327
- }
328
- }
329
- }
330
- export function statusQueryVerdict(
331
- stamp: VerdictStamp,
332
- failures: number,
333
- failure: T.QueryFailure
334
- ): T.BlockerVerdict {
335
- return stamp({
336
- kind: "BLOCKER",
337
- terminal: true,
338
- exitCode: 7,
339
- blocker: { kind: "status-query", failures, failure },
340
- });
341
- }
342
- export interface WatchClock {
343
- now(): number;
344
- observedAt(): string;
345
- sleep(seconds: number): Promise<void>;
346
- }
347
- export interface RunDependencies {
348
- readonly reader: T.GitHubReader;
349
- readonly clock: WatchClock;
350
- readonly emit: (verdict: T.ProgressVerdict) => void;
351
- }
352
- const deadlinePassed = (
353
- started: number,
354
- options: T.PollingOptions,
355
- now: number
356
- ): boolean => options.timeout > 0 && now - started >= options.timeout;
357
- type StepResult<V> =
358
- | { readonly kind: "terminal"; readonly verdict: V }
359
- | {
360
- readonly kind: "sleep";
361
- readonly seconds: number;
362
- readonly onDeadline?: () => V;
363
- }
364
- | { readonly kind: "continue" };
365
- async function pollUntilTerminal<V>(args: {
366
- readonly dependencies: RunDependencies;
367
- readonly options: T.PollingOptions;
368
- readonly stamp: VerdictStamp;
369
- readonly step: () => Promise<StepResult<V>>;
370
- }): Promise<V | T.BlockerVerdict | T.TimeoutVerdict> {
371
- let failures = 0;
372
- const started = args.dependencies.clock.now();
373
- while (true) {
374
- let result: StepResult<V>;
375
- try {
376
- result = await args.step();
377
- failures = 0;
378
- } catch (error) {
379
- if (!(error instanceof WatcherQueryError)) throw error;
380
- failures += 1;
381
- if (!error.failure.retryable || failures >= args.options.maxQueryErrors)
382
- return statusQueryVerdict(args.stamp, failures, error.failure);
383
- const retryInSeconds = queryBackoffSeconds(
384
- args.options.interval,
385
- failures
386
- );
387
- args.dependencies.emit(
388
- args.stamp({
389
- kind: "RETRY",
390
- terminal: false,
391
- failure: error.failure,
392
- consecutiveFailures: failures,
393
- retryInSeconds,
394
- })
395
- );
396
- if (deadlinePassed(started, args.options, args.dependencies.clock.now()))
397
- return args.stamp({
398
- kind: "TIMEOUT",
399
- terminal: true,
400
- exitCode: 5,
401
- reason: { kind: "status-unavailable", failure: error.failure },
402
- });
403
- await args.dependencies.clock.sleep(retryInSeconds);
404
- continue;
405
- }
406
- if (result.kind === "terminal") return result.verdict;
407
- if (result.kind === "sleep") {
408
- if (
409
- result.onDeadline !== undefined &&
410
- deadlinePassed(started, args.options, args.dependencies.clock.now())
411
- )
412
- return result.onDeadline();
413
- await args.dependencies.clock.sleep(result.seconds);
414
- }
415
- }
416
- }
417
- export async function runSimple(args: {
418
- readonly dependencies: RunDependencies;
419
- readonly contexts: T.NonEmpty<T.PrContext>;
420
- readonly mode: T.WatchMode;
421
- readonly statusOnly: boolean;
422
- readonly options: T.PollingOptions;
423
- }): Promise<T.TerminalVerdict> {
424
- const stamp = verdictFactory(args.dependencies.clock, args.mode);
425
- const step = async (): Promise<StepResult<T.TerminalVerdict>> => {
426
- const rows: T.PrSnapshot[] = [];
427
- for (const context of args.contexts)
428
- rows.push(
429
- await readSnapshot({
430
- reader: args.dependencies.reader,
431
- context,
432
- pendingHistory: "include",
433
- allowDraft: args.options.allowDraft,
434
- })
435
- );
436
- const complete = nonEmpty(rows);
437
- if (complete === null) throw new Error("watch context cannot be empty");
438
- if (args.statusOnly)
439
- return {
440
- kind: "terminal",
441
- verdict: stamp({
442
- kind: "STATUS",
443
- terminal: true,
444
- exitCode: 0,
445
- reason: "status-only",
446
- rows: complete,
447
- }),
448
- };
449
- if (args.mode === "queued-stack")
450
- throw new Error("queued-stack requires status-only in the simple runner");
451
- if (args.mode === "stack")
452
- args.dependencies.emit(
453
- stamp(
454
- { kind: "STATUS", terminal: false, reason: "poll", rows: complete },
455
- args.mode
456
- )
457
- );
458
- const decision =
459
- args.mode === "single"
460
- ? classifyPr(complete[0], args.options.allowDraft)
461
- : selectTierMajorStackDecision(complete, args.options.allowDraft);
462
- if (decision.kind === "blocker")
463
- return {
464
- kind: "terminal",
465
- verdict: blockerVerdict(stamp, decision.blocker),
466
- };
467
- if (decision.kind === "ready" || decision.kind === "merged")
468
- return {
469
- kind: "terminal",
470
- verdict: stamp(
471
- {
472
- kind: "READY",
473
- terminal: true,
474
- exitCode: 0,
475
- scope: { kind: "single", pr: decision.pr },
476
- },
477
- args.mode
478
- ),
479
- };
480
- if (decision.kind === "clear")
481
- return {
482
- kind: "terminal",
483
- verdict: stamp(
484
- {
485
- kind: "READY",
486
- terminal: true,
487
- exitCode: 0,
488
- scope: { kind: "stack", prs: decision.prs },
489
- },
490
- args.mode
491
- ),
492
- };
493
- args.dependencies.emit(
494
- stamp({
495
- kind: "WAITING",
496
- terminal: false,
497
- frontier: decision.frontier,
498
- reason: { kind: "pending-checks", pending: decision.pending },
499
- })
500
- );
501
- return {
502
- kind: "sleep",
503
- seconds: args.options.interval,
504
- onDeadline: () =>
505
- stamp({
506
- kind: "TIMEOUT",
507
- terminal: true,
508
- exitCode: 5,
509
- reason: { kind: "pending-checks", pending: decision.pending },
510
- }),
511
- };
512
- };
513
- return pollUntilTerminal({
514
- dependencies: args.dependencies,
515
- options: args.options,
516
- stamp,
517
- step,
518
- });
519
- }
520
- export type QueueWork =
521
- | {
522
- readonly kind: "whole-stack-sweep";
523
- readonly remaining: T.NonEmpty<T.PrContext>;
524
- }
525
- | { readonly kind: "frontier-poll"; readonly frontier: T.PrContext };
526
- export interface QueueState {
527
- readonly queue: T.NonEmpty<T.PrContext>;
528
- readonly snapshots: ReadonlyMap<T.PrNumber, T.PrSnapshot>;
529
- readonly work: QueueWork | null;
530
- readonly nextSweepAt: number;
531
- readonly frontier: T.PrContext | null;
532
- readonly lastWaitKey: string | null;
533
- readonly startedAt: number;
534
- }
535
- export const createQueueState = (
536
- queue: T.NonEmpty<T.PrContext>,
537
- now: number
538
- ): QueueState => ({
539
- queue,
540
- snapshots: new Map(),
541
- work: { kind: "whole-stack-sweep", remaining: queue },
542
- nextSweepAt: now,
543
- frontier: null,
544
- lastWaitKey: null,
545
- startedAt: now,
546
- });
547
- const orderedRows = (state: QueueState): T.PrSnapshot[] =>
548
- state.queue.flatMap((context) => {
549
- const row = state.snapshots.get(context.number);
550
- return row === undefined ? [] : [row];
551
- });
552
- const activeRows = (state: QueueState): T.PrSnapshot[] =>
553
- orderedRows(state).filter((row) => row.kind !== "merged");
554
- export function planQueue(state: QueueState, now: number): QueueState {
555
- if (state.work !== null) return state;
556
- if (state.snapshots.size === 0 || now >= state.nextSweepAt) {
557
- const remaining = nonEmpty(
558
- state.queue.filter(
559
- (context) => state.snapshots.get(context.number)?.kind !== "merged"
560
- )
561
- );
562
- if (remaining !== null)
563
- return { ...state, work: { kind: "whole-stack-sweep", remaining } };
564
- }
565
- const frontier = activeRows(state)[0]?.context;
566
- return frontier === undefined
567
- ? state
568
- : { ...state, work: { kind: "frontier-poll", frontier } };
569
- }
570
- export interface QueueSnapshotResult {
571
- readonly state: QueueState;
572
- readonly completedSweepRows: T.NonEmpty<T.PrSnapshot> | null;
573
- }
574
- export function applyQueueSnapshot(
575
- state: QueueState,
576
- snapshot: T.PrSnapshot,
577
- now: number,
578
- options: T.PollingOptions
579
- ): QueueSnapshotResult {
580
- if (state.work === null) throw new Error("queue has no read in flight");
581
- const snapshots = new Map(state.snapshots);
582
- snapshots.set(snapshot.context.number, snapshot);
583
- const base = { ...state, snapshots };
584
- if (state.work.kind === "frontier-poll")
585
- return { state: { ...base, work: null }, completedSweepRows: null };
586
- const [head, ...tail] = state.work.remaining;
587
- if (head.number !== snapshot.context.number)
588
- throw new Error("snapshot does not match sweep head");
589
- const remaining = nonEmpty(tail);
590
- if (remaining !== null)
591
- return {
592
- state: { ...base, work: { kind: "whole-stack-sweep", remaining } },
593
- completedSweepRows: null,
594
- };
595
- const rows = nonEmpty(
596
- state.queue.flatMap((context) => {
597
- const row = snapshots.get(context.number);
598
- return row === undefined ? [] : [row];
599
- })
600
- );
601
- if (rows === null || rows.length !== state.queue.length)
602
- throw new Error("sweep completed without every snapshot");
603
- return {
604
- state: { ...base, work: null, nextSweepAt: now + options.sweepInterval },
605
- completedSweepRows: rows,
606
- };
607
- }
608
- export type QueueEvaluation =
609
- | {
610
- readonly kind: "complete";
611
- readonly state: QueueState;
612
- readonly merged: T.NonEmpty<T.MergedPr>;
613
- }
614
- | {
615
- readonly kind: "blocker";
616
- readonly state: QueueState;
617
- readonly blocker: T.MergeBlocker;
618
- }
619
- | {
620
- readonly kind: "advance";
621
- readonly state: QueueState;
622
- readonly merged: T.PrContext;
623
- readonly frontier: T.PrContext;
624
- readonly remaining: number;
625
- }
626
- | {
627
- readonly kind: "timeout";
628
- readonly state: QueueState;
629
- readonly frontier: T.PrContext;
630
- readonly unmergedCount: number;
631
- }
632
- | {
633
- readonly kind: "waiting";
634
- readonly state: QueueState;
635
- readonly frontier: T.PrContext;
636
- readonly reason:
637
- | {
638
- readonly kind: "pending-checks";
639
- readonly pending: T.NonEmpty<T.PendingCheck>;
640
- }
641
- | { readonly kind: "merge-queue"; readonly unmergedCount: number };
642
- readonly emit: boolean;
643
- };
644
- export function evaluateQueue(
645
- state: QueueState,
646
- now: number,
647
- options: T.PollingOptions
648
- ): QueueEvaluation {
649
- const active = activeRows(state);
650
- if (active.length === 0) {
651
- const merged = nonEmpty(
652
- orderedRows(state).flatMap((row) =>
653
- row.kind === "merged"
654
- ? [
655
- {
656
- kind: "merged-pr" as const,
657
- context: row.context,
658
- mergedAt: row.facts.mergedAt,
659
- },
660
- ]
661
- : []
662
- )
663
- );
664
- if (merged === null) throw new Error("empty queue cannot complete");
665
- return { kind: "complete", state, merged };
666
- }
667
- const rows = nonEmpty(active);
668
- if (rows === null) throw new Error("active queue cannot be empty");
669
- const decision = selectTierMajorStackDecision(rows, options.allowDraft);
670
- if (decision.kind === "blocker")
671
- return { kind: "blocker", state, blocker: decision.blocker };
672
- const frontier = rows[0].context;
673
- if (state.frontier !== null && state.frontier.number !== frontier.number)
674
- return {
675
- kind: "advance",
676
- state: { ...state, frontier, lastWaitKey: null },
677
- merged: state.frontier,
678
- frontier,
679
- remaining: active.length,
680
- };
681
- if (deadlinePassed(state.startedAt, options, now))
682
- return {
683
- kind: "timeout",
684
- state: { ...state, frontier },
685
- frontier,
686
- unmergedCount: active.length,
687
- };
688
- const row = rows[0];
689
- const pending =
690
- row.kind === "open" && row.ci.kind === "ci-pending" ? row.ci.pending : null;
691
- const reason =
692
- pending === null
693
- ? ({ kind: "merge-queue", unmergedCount: active.length } as const)
694
- : ({ kind: "pending-checks", pending } as const);
695
- const key =
696
- reason.kind === "pending-checks"
697
- ? `pending:${frontier.number}:${reason.pending.length}`
698
- : `queue:${frontier.number}:${reason.unmergedCount}`;
699
- return {
700
- kind: "waiting",
701
- state: { ...state, frontier, lastWaitKey: key },
702
- frontier,
703
- reason,
704
- emit: state.lastWaitKey !== key,
705
- };
706
- }
707
- export async function runQueued(args: {
708
- readonly dependencies: RunDependencies;
709
- readonly contexts: T.NonEmpty<T.PrContext>;
710
- readonly options: T.PollingOptions;
711
- }): Promise<T.QueueTerminalVerdict> {
712
- let state = createQueueState(args.contexts, args.dependencies.clock.now());
713
- const stamp = verdictFactory(args.dependencies.clock, "queued-stack");
714
- args.dependencies.emit(
715
- stamp({ kind: "QUEUE", terminal: false, queue: args.contexts })
716
- );
717
- const step = async (): Promise<StepResult<T.QueueTerminalVerdict>> => {
718
- state = planQueue(state, args.dependencies.clock.now());
719
- if (state.work === null) {
720
- const complete = evaluateQueue(
721
- state,
722
- args.dependencies.clock.now(),
723
- args.options
724
- );
725
- if (complete.kind !== "complete")
726
- throw new Error("queue has no work while active");
727
- return {
728
- kind: "terminal",
729
- verdict: stamp({
730
- kind: "COMPLETE",
731
- terminal: true,
732
- exitCode: 0,
733
- queue: state.queue,
734
- merged: complete.merged,
735
- }),
736
- };
737
- }
738
- const context =
739
- state.work.kind === "whole-stack-sweep"
740
- ? state.work.remaining[0]
741
- : state.work.frontier;
742
- const snapshot = await readSnapshot({
743
- reader: args.dependencies.reader,
744
- context,
745
- pendingHistory: "omit",
746
- allowDraft: args.options.allowDraft,
747
- });
748
- const applied = applyQueueSnapshot(
749
- state,
750
- snapshot,
751
- args.dependencies.clock.now(),
752
- args.options
753
- );
754
- state = applied.state;
755
- if (applied.completedSweepRows !== null)
756
- args.dependencies.emit(
757
- stamp({
758
- kind: "STATUS",
759
- terminal: false,
760
- reason: "whole-stack-sweep",
761
- rows: applied.completedSweepRows,
762
- })
763
- );
764
- if (state.work !== null) return { kind: "continue" };
765
- const evaluation = evaluateQueue(
766
- state,
767
- args.dependencies.clock.now(),
768
- args.options
769
- );
770
- state = evaluation.state;
771
- switch (evaluation.kind) {
772
- case "complete":
773
- return {
774
- kind: "terminal",
775
- verdict: stamp({
776
- kind: "COMPLETE",
777
- terminal: true,
778
- exitCode: 0,
779
- queue: state.queue,
780
- merged: evaluation.merged,
781
- }),
782
- };
783
- case "blocker":
784
- return {
785
- kind: "terminal",
786
- verdict: blockerVerdict(stamp, evaluation.blocker),
787
- };
788
- case "advance":
789
- args.dependencies.emit(
790
- stamp({
791
- kind: "ADVANCE",
792
- terminal: false,
793
- merged: evaluation.merged,
794
- frontier: evaluation.frontier,
795
- remaining: evaluation.remaining,
796
- })
797
- );
798
- return { kind: "continue" };
799
- case "timeout":
800
- return {
801
- kind: "terminal",
802
- verdict: stamp({
803
- kind: "TIMEOUT",
804
- terminal: true,
805
- exitCode: 5,
806
- reason: {
807
- kind: "queued-stack",
808
- frontier: evaluation.frontier,
809
- unmergedCount: evaluation.unmergedCount,
810
- },
811
- }),
812
- };
813
- case "waiting":
814
- if (evaluation.emit)
815
- args.dependencies.emit(
816
- stamp({
817
- kind: "WAITING",
818
- terminal: false,
819
- frontier: evaluation.frontier,
820
- reason: evaluation.reason,
821
- })
822
- );
823
- return { kind: "sleep", seconds: args.options.interval };
824
- default: {
825
- const exhaustive: never = evaluation;
826
- return exhaustive;
827
- }
828
- }
829
- };
830
- return pollUntilTerminal({
831
- dependencies: args.dependencies,
832
- options: args.options,
833
- stamp,
834
- step,
835
- });
836
- }