dsh-pstack 0.2.0-beta.1 → 0.2.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 (275) hide show
  1. package/LICENSE +2 -3
  2. package/README.md +148 -84
  3. package/README.zh.md +198 -0
  4. package/assets/pstack-config-entry.png +0 -0
  5. package/cordis.patch.yml +105 -27
  6. package/dist/client.mjs +2341 -0
  7. package/dist/client.mjs.map +1 -0
  8. package/dist/host-contract-CUPSpeNk.d.mts +22 -0
  9. package/dist/index.d.mts +49 -238
  10. package/dist/index.mjs +250 -123
  11. package/dist/models.d.mts +44 -0
  12. package/dist/models.mjs +201 -0
  13. package/dist/paths-BT77khwm.mjs +48 -0
  14. package/dist/pstack/LICENSE +21 -0
  15. package/dist/pstack/README.md +291 -0
  16. package/dist/pstack/agents/poteto-agent.md +9 -0
  17. package/{assets → dist/pstack}/docs/guide/01-setup.md +13 -11
  18. package/{assets → dist/pstack}/docs/guide/02-poteto-mode.md +4 -4
  19. package/{assets → dist/pstack}/docs/guide/04-design.md +4 -4
  20. package/{assets → dist/pstack}/docs/guide/05-build-and-clean.md +2 -2
  21. package/{assets → dist/pstack}/docs/guide/06-verify-and-ship.md +13 -3
  22. package/{assets → dist/pstack}/docs/guide/07-overnight.md +15 -13
  23. package/{assets → dist/pstack}/docs/guide/09-make-it-yours.md +6 -2
  24. package/{assets → dist/pstack}/docs/guide/10-recipes-and-pitfalls.md +7 -5
  25. package/{assets → dist/pstack}/docs/guide/README.md +1 -1
  26. package/dist/pstack/docs/harness/dsh.md +98 -0
  27. package/{assets → dist/pstack}/skills/architect/SKILL.md +12 -12
  28. package/dist/pstack/skills/arena/SKILL.md +50 -0
  29. package/{assets → dist/pstack}/skills/automate-me/SKILL.md +14 -14
  30. package/{assets → dist/pstack}/skills/benchmark-checklist/SKILL.md +1 -1
  31. package/{assets → dist/pstack}/skills/blast-radius/SKILL.md +4 -6
  32. package/{assets → dist/pstack}/skills/correct/SKILL.md +1 -1
  33. package/{assets → dist/pstack}/skills/create-formal-verification-skill/SKILL.md +4 -2
  34. package/{assets → dist/pstack}/skills/create-verification-skill/SKILL.md +5 -5
  35. package/dist/pstack/skills/figure-it-out/SKILL.md +54 -0
  36. package/dist/pstack/skills/how/SKILL.md +38 -0
  37. package/{assets → dist/pstack}/skills/in-your-own-words/SKILL.md +1 -1
  38. package/dist/pstack/skills/interrogate/SKILL.md +33 -0
  39. package/{assets → dist/pstack}/skills/ketchup/SKILL.md +3 -5
  40. package/dist/pstack/skills/ketchup-video/SKILL.md +29 -0
  41. package/{assets → dist/pstack}/skills/maintain-formal-verification-skill/SKILL.md +1 -1
  42. package/{assets → dist/pstack}/skills/maintain-verification-skill/SKILL.md +3 -3
  43. package/dist/pstack/skills/make-bot-ui/SKILL.md +117 -0
  44. package/dist/pstack/skills/no-comments/SKILL.md +26 -0
  45. package/{assets → dist/pstack}/skills/poteto-help/SKILL.md +34 -31
  46. package/{assets → dist/pstack}/skills/poteto-help/references/prompting.md +1 -1
  47. package/{assets → dist/pstack}/skills/poteto-help/references/recipes.md +3 -3
  48. package/{assets → dist/pstack}/skills/poteto-mode/SKILL.md +20 -19
  49. package/dist/pstack/skills/poteto-mode/playbooks/authoring-a-skill.md +12 -0
  50. package/dist/pstack/skills/poteto-mode/playbooks/autonomous-run.md +13 -0
  51. package/dist/pstack/skills/poteto-mode/playbooks/autopilot-full.md +25 -0
  52. package/dist/pstack/skills/poteto-mode/playbooks/autopilot-stack.md +8 -0
  53. package/{assets → dist/pstack}/skills/poteto-mode/playbooks/babysit.md +4 -4
  54. package/dist/pstack/skills/poteto-mode/playbooks/bug-fix.md +15 -0
  55. package/{assets → dist/pstack}/skills/poteto-mode/playbooks/eval.md +3 -3
  56. package/dist/pstack/skills/poteto-mode/playbooks/feature.md +21 -0
  57. package/{assets → dist/pstack}/skills/poteto-mode/playbooks/hillclimb.md +3 -3
  58. package/{assets → dist/pstack}/skills/poteto-mode/playbooks/investigation.md +2 -2
  59. package/{assets → dist/pstack}/skills/poteto-mode/playbooks/multi-phase-plan.md +23 -23
  60. package/{assets → dist/pstack}/skills/poteto-mode/playbooks/opening-a-pr.md +6 -6
  61. package/dist/pstack/skills/poteto-mode/playbooks/orchestrate.md +25 -0
  62. package/{assets → dist/pstack}/skills/poteto-mode/playbooks/pause-safely.md +2 -2
  63. package/dist/pstack/skills/poteto-mode/playbooks/perf-issue.md +25 -0
  64. package/{assets → dist/pstack}/skills/poteto-mode/playbooks/prototype.md +4 -4
  65. package/dist/pstack/skills/poteto-mode/playbooks/refactoring.md +16 -0
  66. package/dist/pstack/skills/poteto-mode/playbooks/runtime-forensics.md +11 -0
  67. package/dist/pstack/skills/poteto-mode/playbooks/session-pickup.md +11 -0
  68. package/{assets → dist/pstack}/skills/poteto-mode/playbooks/shipping.md +2 -2
  69. package/{assets → dist/pstack}/skills/poteto-mode/playbooks/trace-forensics.md +2 -2
  70. package/dist/pstack/skills/poteto-mode/playbooks/visual-parity.md +11 -0
  71. package/dist/pstack/skills/poteto-mode/playbooks/worktree-cleanup.md +12 -0
  72. package/{assets → dist/pstack}/skills/poteto-mode/scripts/check-plan.mjs +6 -8
  73. package/dist/pstack/skills/poteto-mode/scripts/check-plan.test.mjs +128 -0
  74. package/{assets/skills/poteto-mode/scripts/check-plan.test.mjs → dist/pstack/skills/poteto-mode/scripts/expect.mjs} +12 -101
  75. package/dist/pstack/skills/poteto-mode/scripts/support.mjs +93 -0
  76. package/dist/pstack/skills/poteto-mode/scripts/watch-pr/cli.mjs +123 -0
  77. package/dist/pstack/skills/poteto-mode/scripts/watch-pr/cli.test.mjs +217 -0
  78. package/dist/pstack/skills/poteto-mode/scripts/watch-pr/fakes.test-helper.mjs +119 -0
  79. package/dist/pstack/skills/poteto-mode/scripts/watch-pr/github.mjs +626 -0
  80. package/dist/pstack/skills/poteto-mode/scripts/watch-pr/github.test.mjs +521 -0
  81. package/dist/pstack/skills/poteto-mode/scripts/watch-pr/policy.mjs +657 -0
  82. package/dist/pstack/skills/poteto-mode/scripts/watch-pr/policy.test.mjs +523 -0
  83. package/dist/pstack/skills/poteto-mode/scripts/watch-pr/render.mjs +106 -0
  84. package/dist/pstack/skills/poteto-mode/scripts/watch-pr/types.mjs +9 -0
  85. package/dist/pstack/skills/poteto-mode/scripts/watch-pr/watch-pr.mjs +5 -0
  86. package/{assets → dist/pstack}/skills/poteto-mode/scripts/worktree-audit.mjs +15 -22
  87. package/dist/pstack/skills/poteto-mode/scripts/worktree-audit.test.mjs +134 -0
  88. package/{assets → dist/pstack}/skills/principle-attack-the-premise/SKILL.md +1 -1
  89. package/{assets → dist/pstack}/skills/principle-boundary-discipline/SKILL.md +1 -1
  90. package/{assets → dist/pstack}/skills/principle-encode-lessons-in-structure/SKILL.md +1 -1
  91. package/{assets → dist/pstack}/skills/principle-exhaust-the-design-space/SKILL.md +1 -1
  92. package/{assets → dist/pstack}/skills/principle-experience-first/SKILL.md +1 -1
  93. package/{assets → dist/pstack}/skills/principle-explain-the-number/SKILL.md +3 -2
  94. package/{assets → dist/pstack}/skills/principle-fix-root-causes/SKILL.md +1 -1
  95. package/{assets → dist/pstack}/skills/principle-laziness-protocol/SKILL.md +1 -1
  96. package/{assets → dist/pstack}/skills/principle-make-operations-idempotent/SKILL.md +1 -1
  97. package/{assets → dist/pstack}/skills/principle-migrate-callers-then-delete-legacy-apis/SKILL.md +1 -1
  98. package/{assets → dist/pstack}/skills/principle-minimize-reader-load/SKILL.md +1 -1
  99. package/{assets → dist/pstack}/skills/principle-model-the-domain/SKILL.md +1 -1
  100. package/{assets → dist/pstack}/skills/principle-never-block-on-the-human/SKILL.md +1 -1
  101. package/{assets → dist/pstack}/skills/principle-outcome-oriented-execution/SKILL.md +1 -1
  102. package/{assets → dist/pstack}/skills/principle-prove-it-works/SKILL.md +2 -2
  103. package/{assets → dist/pstack}/skills/principle-redesign-from-first-principles/SKILL.md +1 -1
  104. package/{assets → dist/pstack}/skills/principle-separate-before-serializing-shared-state/SKILL.md +1 -1
  105. package/{assets → dist/pstack}/skills/principle-sequence-verifiable-units/SKILL.md +1 -1
  106. package/{assets → dist/pstack}/skills/principle-subtract-before-you-add/SKILL.md +1 -1
  107. package/{assets → dist/pstack}/skills/principle-test-behavior-not-implementation/SKILL.md +1 -1
  108. package/{assets → dist/pstack}/skills/principle-type-system-discipline/SKILL.md +1 -1
  109. package/dist/pstack/skills/recall/SKILL.md +37 -0
  110. package/dist/pstack/skills/reflect/SKILL.md +71 -0
  111. package/{assets → dist/pstack}/skills/reflect/references/divergent-reviewer.md +4 -4
  112. package/{assets → dist/pstack}/skills/reflect/references/judgment-reviewer.md +2 -2
  113. package/{assets → dist/pstack}/skills/reflect/references/synthesizer.md +5 -5
  114. package/{assets → dist/pstack}/skills/reflect/references/tooling-reviewer.md +2 -2
  115. package/dist/pstack/skills/setup-pstack/SKILL.md +80 -0
  116. package/{assets → dist/pstack}/skills/sharpen/SKILL.md +1 -1
  117. package/{assets → dist/pstack}/skills/show-me-your-work/SKILL.md +8 -8
  118. package/{assets → dist/pstack}/skills/show-me-your-work/scripts/log.mjs +1 -3
  119. package/dist/pstack/skills/show-me-your-work/scripts/log.test.mjs +56 -0
  120. package/dist/pstack/skills/statechart/SKILL.md +82 -0
  121. package/dist/pstack/skills/statechart/references/render.md +93 -0
  122. package/dist/pstack/skills/statechart/scripts/backends/cfg.mjs +31 -0
  123. package/dist/pstack/skills/statechart/scripts/backends/mermaid.mjs +186 -0
  124. package/dist/pstack/skills/statechart/scripts/backends/plain-text.mjs +62 -0
  125. package/dist/pstack/skills/statechart/scripts/backends/report.mjs +84 -0
  126. package/dist/pstack/skills/statechart/scripts/frontends/config.mjs +268 -0
  127. package/dist/pstack/skills/statechart/scripts/frontends/dot.mjs +67 -0
  128. package/dist/pstack/skills/statechart/scripts/frontends/marks.mjs +94 -0
  129. package/dist/pstack/skills/statechart/scripts/frontends/messages.mjs +48 -0
  130. package/dist/pstack/skills/statechart/scripts/frontends/spec.mjs +101 -0
  131. package/dist/pstack/skills/statechart/scripts/frontends/trace.mjs +39 -0
  132. package/dist/pstack/skills/statechart/scripts/frontends/value.mjs +180 -0
  133. package/dist/pstack/skills/statechart/scripts/frontends/verdict.mjs +40 -0
  134. package/dist/pstack/skills/statechart/scripts/frontends/view.mjs +99 -0
  135. package/dist/pstack/skills/statechart/scripts/ir.mjs +277 -0
  136. package/dist/pstack/skills/statechart/scripts/passes/annotate.mjs +92 -0
  137. package/dist/pstack/skills/statechart/scripts/passes/label.mjs +210 -0
  138. package/dist/pstack/skills/statechart/scripts/passes/lift.mjs +84 -0
  139. package/dist/pstack/skills/statechart/scripts/passes/loop-check.mjs +47 -0
  140. package/dist/pstack/skills/statechart/scripts/passes/paths.mjs +72 -0
  141. package/dist/pstack/skills/statechart/scripts/passes/reach.mjs +135 -0
  142. package/dist/pstack/skills/statechart/scripts/passes/region-check.mjs +82 -0
  143. package/dist/pstack/skills/statechart/scripts/passes/regions.mjs +268 -0
  144. package/dist/pstack/skills/statechart/scripts/pipeline.mjs +72 -0
  145. package/dist/pstack/skills/statechart/scripts/run.mjs +440 -0
  146. package/dist/pstack/skills/statechart/scripts/statechart.mjs +155 -0
  147. package/dist/pstack/skills/statechart/scripts/statechart.test.mjs +198 -0
  148. package/dist/pstack/skills/statechart/scripts/worker.mjs +31 -0
  149. package/dist/pstack/skills/swarm/SKILL.md +43 -0
  150. package/{assets → dist/pstack}/skills/tdd/SKILL.md +1 -1
  151. package/{assets → dist/pstack}/skills/teach/SKILL.md +2 -2
  152. package/{assets → dist/pstack}/skills/technical-writing/SKILL.md +1 -1
  153. package/{assets → dist/pstack}/skills/typescript-best-practices/SKILL.md +3 -6
  154. package/{assets → dist/pstack}/skills/why/SKILL.md +8 -8
  155. package/dist/remote.d.mts +27 -0
  156. package/dist/remote.mjs +234 -0
  157. package/dist/role-config-NNn5r1JX.mjs +415 -0
  158. package/dist/role-manifest-C3fUzjLI.d.mts +19 -0
  159. package/dist/role-wire-DZwTn2wF.d.mts +55 -0
  160. package/dist/roles.d.mts +18 -0
  161. package/dist/roles.mjs +323 -0
  162. package/dist/script.d.mts +9 -111
  163. package/dist/script.mjs +32 -329
  164. package/dist/skill.d.mts +38 -0
  165. package/dist/skill.mjs +183 -0
  166. package/dist/skills/authored/decision-audit/SKILL.md +103 -0
  167. package/dist/skills/authored/decision-audit/SKILL.zh.md +103 -0
  168. package/dist/skills/authored/decision-audit/references/recover-commit.md +17 -0
  169. package/dist/skills/authored/decision-audit/references/recover-commit.zh.md +17 -0
  170. package/dist/skills/authored/decision-write/SKILL.md +133 -0
  171. package/dist/skills/authored/decision-write/SKILL.zh.md +133 -0
  172. package/dist/skills/authored/decision-write/references/land.md +48 -0
  173. package/dist/skills/authored/decision-write/references/land.zh.md +48 -0
  174. package/dist/skills/authored/decision-write/references/scope.md +16 -0
  175. package/dist/skills/authored/decision-write/references/scope.zh.md +16 -0
  176. package/dist/skills/authored/docs-drift/SKILL.md +120 -0
  177. package/dist/skills/authored/docs-drift/SKILL.zh.md +120 -0
  178. package/dist/skills/authored/setup-project-docs/SKILL.md +63 -0
  179. package/dist/skills/authored/setup-project-docs/SKILL.zh.md +63 -0
  180. package/dist/skills/authored/setup-project-docs/references/decision-conventions.md +13 -0
  181. package/dist/skills/authored/setup-project-docs/references/decision-conventions.zh.md +13 -0
  182. package/dist/skills/vendored/retro/SKILL.md +44 -0
  183. package/dist/skills/vendored/retro/agents/openai.yaml +5 -0
  184. package/dist/skills/vendored/writing-for-agents/SKILL-MECHANICS.md +22 -0
  185. package/dist/skills/vendored/writing-for-agents/SKILL.md +81 -0
  186. package/dist/skills/vendored/writing-for-agents/agents/openai.yaml +3 -0
  187. package/dist/subagent.d.mts +54 -206
  188. package/dist/subagent.mjs +258 -963
  189. package/locale/en.json +3 -2
  190. package/locale/zh.json +3 -2
  191. package/package.json +93 -66
  192. package/assets/agents/poteto-agent.md +0 -8
  193. package/assets/docs/harness/dsh.md +0 -60
  194. package/assets/docs/pstack-models.example.md +0 -54
  195. package/assets/skills/arena/SKILL.md +0 -50
  196. package/assets/skills/figure-it-out/SKILL.md +0 -54
  197. package/assets/skills/how/SKILL.md +0 -38
  198. package/assets/skills/interrogate/SKILL.md +0 -71
  199. package/assets/skills/interrogate/references/code-quality-review.md +0 -47
  200. package/assets/skills/interrogate/references/lead-judgment.md +0 -39
  201. package/assets/skills/interrogate/references/reviewer-prompt.md +0 -62
  202. package/assets/skills/interrogate/references/rubric.md +0 -77
  203. package/assets/skills/no-comments/SKILL.md +0 -26
  204. package/assets/skills/poteto-mode/playbooks/authoring-a-skill.md +0 -12
  205. package/assets/skills/poteto-mode/playbooks/autonomous-run.md +0 -15
  206. package/assets/skills/poteto-mode/playbooks/autopilot-full.md +0 -25
  207. package/assets/skills/poteto-mode/playbooks/autopilot-stack.md +0 -12
  208. package/assets/skills/poteto-mode/playbooks/bug-fix.md +0 -15
  209. package/assets/skills/poteto-mode/playbooks/feature.md +0 -21
  210. package/assets/skills/poteto-mode/playbooks/orchestrate.md +0 -112
  211. package/assets/skills/poteto-mode/playbooks/perf-issue.md +0 -25
  212. package/assets/skills/poteto-mode/playbooks/refactoring.md +0 -16
  213. package/assets/skills/poteto-mode/playbooks/runtime-forensics.md +0 -11
  214. package/assets/skills/poteto-mode/playbooks/session-pickup.md +0 -11
  215. package/assets/skills/poteto-mode/playbooks/visual-parity.md +0 -11
  216. package/assets/skills/poteto-mode/playbooks/worktree-cleanup.md +0 -20
  217. package/assets/skills/poteto-mode/scripts/orch/orch.mjs +0 -4282
  218. package/assets/skills/poteto-mode/scripts/orch/orch.test.mjs +0 -2042
  219. package/assets/skills/poteto-mode/scripts/watch-pr/cli.test.mjs +0 -5101
  220. package/assets/skills/poteto-mode/scripts/watch-pr/github.test.mjs +0 -1177
  221. package/assets/skills/poteto-mode/scripts/watch-pr/policy.test.mjs +0 -1441
  222. package/assets/skills/poteto-mode/scripts/watch-pr/watch-pr.mjs +0 -4601
  223. package/assets/skills/recall/SKILL.md +0 -37
  224. package/assets/skills/reflect/SKILL.md +0 -69
  225. package/assets/skills/setup-pstack/SKILL.md +0 -67
  226. package/assets/skills/swarm/SKILL.md +0 -43
  227. package/dist/frontmatter-BQX3ekwP.mjs +0 -229
  228. package/dist/frontmatter-BQX3ekwP.mjs.map +0 -1
  229. package/dist/history.d.mts +0 -429
  230. package/dist/history.mjs +0 -1129
  231. package/dist/history.mjs.map +0 -1
  232. package/dist/host-contract-o47JH_r8.d.mts +0 -527
  233. package/dist/index.mjs.map +0 -1
  234. package/dist/paths-D_JlVmBk.mjs +0 -42
  235. package/dist/paths-D_JlVmBk.mjs.map +0 -1
  236. package/dist/script.mjs.map +0 -1
  237. package/dist/subagent.mjs.map +0 -1
  238. /package/{static/icon.png → assets/logo.png} +0 -0
  239. /package/{assets → dist/pstack}/agents/comment-sicko.md +0 -0
  240. /package/{assets → dist/pstack}/docs/guide/03-understand.md +0 -0
  241. /package/{assets → dist/pstack}/docs/guide/08-principles.md +0 -0
  242. /package/{assets → dist/pstack}/docs/guide/images/design.jpg +0 -0
  243. /package/{assets → dist/pstack}/docs/guide/images/overnight.jpg +0 -0
  244. /package/{assets → dist/pstack}/docs/guide/images/recipes.jpg +0 -0
  245. /package/{assets → dist/pstack}/docs/guide/images/router.jpg +0 -0
  246. /package/{assets → dist/pstack}/docs/guide/images/understanding.jpg +0 -0
  247. /package/{assets → dist/pstack}/docs/guide/images/verification.jpg +0 -0
  248. /package/{assets → dist/pstack}/skills/architect/references/design-red-flags.md +0 -0
  249. /package/{assets → dist/pstack}/skills/architect/references/rationale-template.md +0 -0
  250. /package/{assets → dist/pstack}/skills/architect/references/runner-prompt.md +0 -0
  251. /package/{assets → dist/pstack}/skills/bro/SKILL.md +0 -0
  252. /package/{assets → dist/pstack}/skills/create-verification-skill/references/feature-map-example/README.md +0 -0
  253. /package/{assets → dist/pstack}/skills/create-verification-skill/references/feature-map-example/create-note.md +0 -0
  254. /package/{assets → dist/pstack}/skills/create-verification-skill/references/feature-map-example/search.md +0 -0
  255. /package/{assets → dist/pstack}/skills/how/references/explainer-prompt.md +0 -0
  256. /package/{assets → dist/pstack}/skills/how/references/explorer-prompt.md +0 -0
  257. /package/{assets → dist/pstack}/skills/poteto-mode/references/bugbot-triage.md +0 -0
  258. /package/{assets → dist/pstack}/skills/principle-build-the-lever/SKILL.md +0 -0
  259. /package/{assets → dist/pstack}/skills/principle-foundational-thinking/SKILL.md +0 -0
  260. /package/{assets → dist/pstack}/skills/principle-guard-the-context-window/SKILL.md +0 -0
  261. /package/{assets → dist/pstack}/skills/show-me-your-work/references/decision-log-template.tsv +0 -0
  262. /package/{assets → dist/pstack}/skills/typescript-best-practices/references/patterns.md +0 -0
  263. /package/{assets → dist/pstack}/skills/unslop/SKILL.md +0 -0
  264. /package/{assets → dist/pstack}/skills/why/references/epistemics.md +0 -0
  265. /package/{assets → dist/pstack}/skills/why/references/investigator-prompt.md +0 -0
  266. /package/{assets → dist/pstack}/skills/why/references/source-playbook.md +0 -0
  267. /package/{assets → dist/pstack}/skills/why/references/sources/code-archaeology.md +0 -0
  268. /package/{assets → dist/pstack}/skills/why/references/sources/databricks.md +0 -0
  269. /package/{assets → dist/pstack}/skills/why/references/sources/datadog.md +0 -0
  270. /package/{assets → dist/pstack}/skills/why/references/sources/incident-postmortem.md +0 -0
  271. /package/{assets → dist/pstack}/skills/why/references/sources/linear.md +0 -0
  272. /package/{assets → dist/pstack}/skills/why/references/sources/notion.md +0 -0
  273. /package/{assets → dist/pstack}/skills/why/references/sources/sentry.md +0 -0
  274. /package/{assets → dist/pstack}/skills/why/references/sources/slack.md +0 -0
  275. /package/{assets → dist/pstack}/skills/why/references/synthesizer-prompt.md +0 -0
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import fs from "node:fs";
3
3
  import process from "node:process";
4
- //#region .runtime-sources/skills/poteto-mode/scripts/check-plan.mjs
4
+ // runtime/skills/poteto-mode/scripts/check-plan.mjs
5
5
  const RULE = "Tests alone are not sufficient verification. A PR is verified only when its unit, live, and perf boxes are all checked.";
6
6
  const LANES = /Ten lanes on `[^`<>]+` at the PR head/;
7
7
  const SUB_BLOCKS = [
@@ -22,11 +22,8 @@ const PROGRAM_H3 = [
22
22
  "Verdict and merge",
23
23
  "Boot recipe"
24
24
  ];
25
- const PROGRAM_MARKERS = [
26
- "create_goal",
27
- "schedule_create",
28
- "status message"
29
- ];
25
+ const PROGRAM_MARKERS = ["git show origin/main:", "status message"];
26
+ const TICK_MARKERS = ["create_goal", "schedule_create"];
30
27
  const HOW_TO_READ_MARKERS = [
31
28
  "One box is one unit of work",
32
29
  "names the evidence",
@@ -82,7 +79,7 @@ for (let i = start; i < raw.length; i++) {
82
79
  code
83
80
  });
84
81
  if (code) continue;
85
- const prose = text.replace(/`[^`]*`/g, "`").replace(/!\[[^\]]*\]\([^)]*\)/g, "").replace(/\]\([^)]*\)/g, "]");
82
+ const prose = text.replace(/(?<!`)(`+)(?!`)(.*?)(?<!`)\1(?!`)/g, "`").replace(/!\[[^\]]*\]\([^)]*\)/g, "").replace(/\]\([^)]*\)/g, "]");
86
83
  if (/[\u2013\u2014]/.test(prose)) fail(n, "long dash");
87
84
  if (/[\u2018\u2019\u201c\u201d]/.test(prose)) fail(n, "curly quote");
88
85
  if (/: \S/.test(prose)) fail(n, "mid-sentence colon");
@@ -124,6 +121,8 @@ else {
124
121
  else cursor = at + 1;
125
122
  }
126
123
  for (const marker of PROGRAM_MARKERS) if (!bodyText(program).includes(marker)) fail(program.n, `Program checklist lacks "${marker}"`);
124
+ const programText = bodyText(program);
125
+ if (!programText.includes("/loop 1h") && !TICK_MARKERS.every((marker) => programText.includes(marker))) fail(program.n, `Program checklist lacks "/loop 1h" or both "create_goal" and "schedule_create"`);
127
126
  }
128
127
  const close = find("Close the program");
129
128
  if (!close) fail(1, "no \"## Close the program\" section");
@@ -216,5 +215,4 @@ for (const line of report) console.log(line);
216
215
  console.log(`${prSections.length} PR sections, ${problems.length} problems`);
217
216
  for (const p of problems) console.error(p);
218
217
  process.exit(problems.length ? 1 : 0);
219
- //#endregion
220
218
  export {};
@@ -0,0 +1,128 @@
1
+ import { expect } from "./expect.mjs";
2
+ import "./support.mjs";
3
+ import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
4
+ import { tmpdir } from "node:os";
5
+ import { join } from "node:path";
6
+ import { spawnSync } from "node:child_process";
7
+ import { test } from "node:test";
8
+ // runtime/skills/poteto-mode/scripts/check-plan.test.ts
9
+ const checker = join(import.meta.dirname, "check-plan.mjs");
10
+ const rule = "Tests alone are not sufficient verification. A PR is verified only when its unit, live, and perf boxes are all checked.";
11
+ const validPlan = `# Demo
12
+
13
+ ## How to read this
14
+ One box is one unit of work and names the evidence. Check a box only when its evidence exists. See playbooks/.
15
+ ${rule}
16
+
17
+ ## Program checklist
18
+ ### Arm the program
19
+ ### Spawn owners
20
+ ### PR mechanics
21
+ ### Verdict and merge
22
+ ### Boot recipe
23
+ \`git show origin/main:\` \`create_goal\` \`schedule_create\` status message
24
+
25
+ ## PR 1
26
+ **Depends on.** None.
27
+ **Files.**
28
+ - [ ] Do the thing.
29
+ **Build.**
30
+ - [ ] Do the thing.
31
+ **You see.**
32
+ - [ ] Do the thing.
33
+ **Verify, unit.** ${rule}
34
+ - [ ] Check the thing.
35
+ **Verify, live.** ${rule} Ten lanes on \`example-model\` at the PR head
36
+ ${Array.from({ length: 10 }, (_, i) => `- [ ] Lane ${i + 1}. Save \`lane-${i + 1}.png\`. Pass when evidence exists.`).join("\n")}
37
+ **Verify, perf.** ${rule}
38
+ - [ ] Metric. Recorded.
39
+ - [ ] Probe. Recorded.
40
+ - [ ] Baseline. Recorded.
41
+ - [ ] Rule. Recorded.
42
+ **Review gate.** None.
43
+ **Merge.**
44
+ - [ ] Merge when approved.
45
+
46
+ ## Close the program
47
+ Close.
48
+
49
+ ## Appendix Prototype evidence
50
+ Recorded.
51
+ `;
52
+ const runPlan = (example, expectedExit) => {
53
+ const directory = mkdtempSync(join(tmpdir(), "check-plan-test-"));
54
+ const file = join(directory, "plan.md");
55
+ writeFileSync(file, validPlan + example);
56
+ try {
57
+ const result = spawnSync("node", [checker, file], { encoding: "utf8" });
58
+ expect(result.status).toBe(expectedExit);
59
+ return result;
60
+ } finally {
61
+ rmSync(directory, {
62
+ recursive: true,
63
+ force: true
64
+ });
65
+ }
66
+ };
67
+ test("accepts ordinary, indented, and longer closing fences", () => {
68
+ for (const indent of [
69
+ "",
70
+ " ",
71
+ " ",
72
+ " "
73
+ ]) runPlan(`${indent}\`\`\`markdown\n## Example only\n${indent}\`\`\`\n`, 0);
74
+ runPlan("```markdown\n## Example only\n````\n", 0);
75
+ });
76
+ test("accepts nested backticks and tilde info strings", () => {
77
+ runPlan("````markdown\n```markdown\n## Example only\n```\n````\n", 0);
78
+ runPlan("~~~markdown `info`\n## Example only\n ~~~\n", 0);
79
+ });
80
+ test("keeps mismatched, shorter, and suffixed closers inside the fence", () => {
81
+ runPlan("````markdown\n~~~\n## Example only\n````\n", 0);
82
+ runPlan("````markdown\n```\n## Example only\n````\n", 0);
83
+ runPlan("````markdown\n``` info\n## Example only\n````\n", 0);
84
+ });
85
+ test("rejects headings and prose outside a proper close", () => {
86
+ for (const suffix of [" ", " "]) {
87
+ const heading = runPlan(`\`\`\`markdown\n## Example only\n\`\`\`${suffix}\n## Example only\n`, 1);
88
+ expect(heading.stderr).toContain("\"## Example only\" after Close the program is not an appendix");
89
+ }
90
+ const prose = runPlan("```markdown\nThis prose has a mid-sentence colon: inside code\n```\nThis prose has a mid-sentence colon: bad.\n", 1);
91
+ expect(prose.stderr).toContain("mid-sentence colon");
92
+ });
93
+ test("rejects backtick info strings containing a backtick", () => {
94
+ const result = runPlan("```markdown `invalid`\n## Example only\n```\n", 1);
95
+ expect(result.stderr).toContain("\"## Example only\" after Close the program is not an appendix");
96
+ });
97
+ test("ignores prose punctuation inside matching multi-backtick code spans", () => {
98
+ for (const count of [
99
+ 2,
100
+ 3,
101
+ 4
102
+ ]) {
103
+ const delimiter = "`".repeat(count);
104
+ runPlan(`Use ${delimiter}echo \`x\`: “quoted” — example${delimiter}.\n`, 0);
105
+ }
106
+ });
107
+ test("checks prose following a multi-backtick span and unmatched delimiters", () => {
108
+ const outside = runPlan("Use ``echo `x`: y``. Bad: prose.\n", 1);
109
+ expect(outside.stderr).toContain("mid-sentence colon");
110
+ const unmatched = runPlan("Use ``unclosed: bad` here.\n", 1);
111
+ expect(unmatched.stderr).toContain("mid-sentence colon");
112
+ });
113
+ test("accepts the upstream /loop tick or the DSH goal plus schedule tick", () => {
114
+ const upstream = validPlan.replace("`git show origin/main:` `create_goal` `schedule_create` status message", "`git show origin/main:` /loop 1h status message");
115
+ const directory = mkdtempSync(join(tmpdir(), "check-plan-test-"));
116
+ const file = join(directory, "plan.md");
117
+ writeFileSync(file, upstream);
118
+ try {
119
+ const result = spawnSync("node", [checker, file], { encoding: "utf8" });
120
+ expect(result.status).toBe(0);
121
+ } finally {
122
+ rmSync(directory, {
123
+ recursive: true,
124
+ force: true
125
+ });
126
+ }
127
+ });
128
+ export {};
@@ -1,11 +1,5 @@
1
- #!/usr/bin/env node
2
- import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
3
- import { tmpdir } from "node:os";
4
- import { join } from "node:path";
5
- import { spawnSync } from "node:child_process";
6
- import { test } from "node:test";
7
1
  import { inspect } from "node:util";
8
- //#region .runtime-sources/skills/poteto-mode/scripts/expect.ts
2
+ // runtime/skills/poteto-mode/scripts/expect.ts
9
3
  /**
10
4
  * A small `expect` for `node:test`.
11
5
  *
@@ -16,8 +10,8 @@ import { inspect } from "node:util";
16
10
  * port auditable against the calls that actually exist.
17
11
  *
18
12
  * Covered: `toBe`, `toEqual`, `toContain`, `toMatch`, `toThrow`, `toBeNull`,
19
- * `toBeInstanceOf`, `toHaveLength`, `toEndWith`, `toMatchObject`, `.not` on each,
20
- * and `rejects` / `resolves` for promises.
13
+ * `toBeUndefined`, `toBeInstanceOf`, `toHaveLength`, `toEndWith`, `toMatchObject`,
14
+ * `.not` on each, and `rejects` / `resolves` for promises.
21
15
  *
22
16
  * Two differences from `bun:test`, stated so a failure is not misread:
23
17
  *
@@ -146,6 +140,9 @@ function buildMatchers(actual, negate) {
146
140
  toBeNull() {
147
141
  checkPlain(actual === null, "toBeNull");
148
142
  },
143
+ toBeUndefined() {
144
+ checkPlain(actual === void 0, "toBeUndefined");
145
+ },
149
146
  toBeInstanceOf(expected) {
150
147
  check(actual instanceof expected, "toBeInstanceOf", expected);
151
148
  },
@@ -221,6 +218,10 @@ function buildAsyncMatchers(actual, mode, negate) {
221
218
  buildMatchers(subject, false).toBeNull();
222
219
  return;
223
220
  }
221
+ if (name === "toBeUndefined") {
222
+ buildMatchers(subject, false).toBeUndefined();
223
+ return;
224
+ }
224
225
  const matchers = buildMatchers(subject, false);
225
226
  const matcher = matchers[name];
226
227
  if (typeof matcher !== "function") throw new AssertionError(`unknown matcher ${name}`);
@@ -233,6 +234,7 @@ function buildAsyncMatchers(actual, mode, negate) {
233
234
  toMatch: (expected) => wrap("toMatch", expected),
234
235
  toThrow: (expected) => wrap("toThrow", expected),
235
236
  toBeNull: () => wrap("toBeNull"),
237
+ toBeUndefined: () => wrap("toBeUndefined"),
236
238
  toBeInstanceOf: (expected) => wrap("toBeInstanceOf", expected),
237
239
  toHaveLength: (expected) => wrap("toHaveLength", expected),
238
240
  toEndWith: (expected) => wrap("toEndWith", expected),
@@ -249,95 +251,4 @@ const expect = Object.assign((actual) => buildMatchers(actual, false), {
249
251
  rejects: (actual) => buildAsyncMatchers(actual, "rejects", false),
250
252
  resolves: (actual) => buildAsyncMatchers(actual, "resolves", false)
251
253
  });
252
- //#endregion
253
- //#region .runtime-sources/skills/poteto-mode/scripts/check-plan.test.ts
254
- const checker = join(import.meta.dirname, "check-plan.mjs");
255
- const rule = "Tests alone are not sufficient verification. A PR is verified only when its unit, live, and perf boxes are all checked.";
256
- const validPlan = `# Demo
257
-
258
- ## How to read this
259
- One box is one unit of work and names the evidence. Check a box only when its evidence exists. See playbooks/.
260
- ${rule}
261
-
262
- ## Program checklist
263
- ### Arm the program
264
- ### Spawn owners
265
- ### PR mechanics
266
- ### Verdict and merge
267
- ### Boot recipe
268
- \`create_goal\` \`schedule_create\` status message
269
-
270
- ## PR 1
271
- **Depends on.** None.
272
- **Files.**
273
- - [ ] Do the thing.
274
- **Build.**
275
- - [ ] Do the thing.
276
- **You see.**
277
- - [ ] Do the thing.
278
- **Verify, unit.** ${rule}
279
- - [ ] Check the thing.
280
- **Verify, live.** ${rule} Ten lanes on \`example-model\` at the PR head
281
- ${Array.from({ length: 10 }, (_, i) => `- [ ] Lane ${i + 1}. Save \`lane-${i + 1}.png\`. Pass when evidence exists.`).join("\n")}
282
- **Verify, perf.** ${rule}
283
- - [ ] Metric. Recorded.
284
- - [ ] Probe. Recorded.
285
- - [ ] Baseline. Recorded.
286
- - [ ] Rule. Recorded.
287
- **Review gate.** None.
288
- **Merge.**
289
- - [ ] Merge when approved.
290
-
291
- ## Close the program
292
- Close.
293
-
294
- ## Appendix Prototype evidence
295
- Recorded.
296
- `;
297
- const runPlan = (example, expectedExit) => {
298
- const directory = mkdtempSync(join(tmpdir(), "check-plan-test-"));
299
- const file = join(directory, "plan.md");
300
- writeFileSync(file, validPlan + example);
301
- try {
302
- const result = spawnSync("node", [checker, file], { encoding: "utf8" });
303
- expect(result.status).toBe(expectedExit);
304
- return result;
305
- } finally {
306
- rmSync(directory, {
307
- recursive: true,
308
- force: true
309
- });
310
- }
311
- };
312
- test("accepts ordinary, indented, and longer closing fences", () => {
313
- for (const indent of [
314
- "",
315
- " ",
316
- " ",
317
- " "
318
- ]) runPlan(`${indent}\`\`\`markdown\n## Example only\n${indent}\`\`\`\n`, 0);
319
- runPlan("```markdown\n## Example only\n````\n", 0);
320
- });
321
- test("accepts nested backticks and tilde info strings", () => {
322
- runPlan("````markdown\n```markdown\n## Example only\n```\n````\n", 0);
323
- runPlan("~~~markdown `info`\n## Example only\n ~~~\n", 0);
324
- });
325
- test("keeps mismatched, shorter, and suffixed closers inside the fence", () => {
326
- runPlan("````markdown\n~~~\n## Example only\n````\n", 0);
327
- runPlan("````markdown\n```\n## Example only\n````\n", 0);
328
- runPlan("````markdown\n``` info\n## Example only\n````\n", 0);
329
- });
330
- test("rejects headings and prose outside a proper close", () => {
331
- for (const suffix of [" ", " "]) {
332
- const heading = runPlan(`\`\`\`markdown\n## Example only\n\`\`\`${suffix}\n## Example only\n`, 1);
333
- expect(heading.stderr).toContain("\"## Example only\" after Close the program is not an appendix");
334
- }
335
- const prose = runPlan("```markdown\nThis prose has a mid-sentence colon: inside code\n```\nThis prose has a mid-sentence colon: bad.\n", 1);
336
- expect(prose.stderr).toContain("mid-sentence colon");
337
- });
338
- test("rejects backtick info strings containing a backtick", () => {
339
- const result = runPlan("```markdown `invalid`\n## Example only\n```\n", 1);
340
- expect(result.stderr).toContain("\"## Example only\" after Close the program is not an appendix");
341
- });
342
- //#endregion
343
- export {};
254
+ export { AssertionError, deepEqual, expect };
@@ -0,0 +1,93 @@
1
+ import { expect } from "./expect.mjs";
2
+ import { spawn as spawn$1, spawnSync as spawnSync$1 } from "node:child_process";
3
+ // runtime/skills/poteto-mode/scripts/support.ts
4
+ /**
5
+ * The one support module the ported upstream tests import.
6
+ *
7
+ * The five upstream test files were written for `bun:test` and use exactly two
8
+ * Bun facilities: its `expect`, and `Bun.spawnSync` / `Bun.spawn` for running git
9
+ * and short-lived processes. Rather than rewrite every call site, this module
10
+ * supplies those two shapes and the test patch only replaces the import line. The
11
+ * bodies below stay byte-for-byte the upstream text, so a future upstream change
12
+ * is still readable against this tree.
13
+ *
14
+ * `Bun.spawnSync` returns `{ exitCode, stdout, stderr, success }` with Buffer
15
+ * output and never throws on a nonzero exit; `node:child_process.spawnSync`
16
+ * returns `{ status, stdout, stderr }`. The adapter is the mapping between them,
17
+ * not a second implementation.
18
+ *
19
+ * `Bun.spawn` returns `{ pid, exited: Promise<number> }`. The adapter runs the
20
+ * child to completion and resolves `exited` with the exit status, which is what
21
+ * the one call site awaits.
22
+ */
23
+ /**
24
+ * Run a command to completion, Bun-shaped.
25
+ *
26
+ * A signal-terminated child reports `exitCode: 1` rather than `null`, so a test
27
+ * that formats the code never prints `undefined` for a killed process.
28
+ */
29
+ function spawnSync(argv, options = {}) {
30
+ const [command, ...args] = argv;
31
+ if (command === void 0) throw new TypeError("spawnSync needs a command");
32
+ const result = spawnSync$1(command, args, {
33
+ cwd: options.cwd,
34
+ env: options.env,
35
+ stdio: [
36
+ options.stdin === "inherit" ? "inherit" : "pipe",
37
+ options.stdout === "inherit" ? "inherit" : "pipe",
38
+ options.stderr === "inherit" ? "inherit" : "pipe"
39
+ ],
40
+ encoding: "buffer"
41
+ });
42
+ const exitCode = result.status ?? 1;
43
+ return {
44
+ exitCode,
45
+ stdout: Buffer.isBuffer(result.stdout) ? result.stdout : Buffer.alloc(0),
46
+ stderr: Buffer.isBuffer(result.stderr) ? result.stderr : Buffer.alloc(0),
47
+ success: exitCode === 0
48
+ };
49
+ }
50
+ /**
51
+ * A child that exits immediately, as a real process.
52
+ *
53
+ * The current interpreter running an empty program is a process like any other: its
54
+ * `pid` is real and its exit status is 0.
55
+ */
56
+ function immediateExit() {
57
+ return spawn$1(process.execPath, ["-e", ""], { stdio: "ignore" });
58
+ }
59
+ /** Whether `command` starts at all, checked without a shell. */
60
+ function resolves(command) {
61
+ return spawnSync$1(command, ["--version"], { stdio: "ignore" }).error === void 0;
62
+ }
63
+ /**
64
+ * Start a command and expose Bun's `{ pid, exited }` shape.
65
+ *
66
+ * The one upstream call is `spawn(["true"])`, used to obtain a pid that has already
67
+ * exited so the test can plant a stale lock. It reads `pid` *before* awaiting
68
+ * `exited`, so the pid must be real and already dead when this returns.
69
+ *
70
+ * That rules out "spawn it and fall back on failure": the failure is asynchronous, so
71
+ * the caller would read `-1`. The probe is synchronous instead, which lets this
72
+ * function choose the right child before returning. `true` is used when it exists and
73
+ * the current interpreter otherwise — a `PATH` without the usual Unix utilities is
74
+ * exactly the environment this release has to work in.
75
+ */
76
+ function spawn(argv) {
77
+ const [command, ...args] = argv;
78
+ if (command === void 0) throw new TypeError("spawn needs a command");
79
+ const child = resolves(command) ? spawn$1(command, args, { stdio: "ignore" }) : immediateExit();
80
+ return {
81
+ pid: child.pid ?? -1,
82
+ exited: new Promise((resolve) => {
83
+ child.once("close", (code) => resolve(code ?? 1));
84
+ child.once("error", () => resolve(1));
85
+ })
86
+ };
87
+ }
88
+ /** The `Bun` global the upstream tests reference, limited to what they call. */
89
+ const Bun = {
90
+ spawnSync,
91
+ spawn
92
+ };
93
+ export { Bun, expect, spawn, spawnSync };
@@ -0,0 +1,123 @@
1
+ import { nonEmpty, parsePrNumber } from "./types.mjs";
2
+ import { GhGitHubReader, WatcherQueryError, discoverStack, resolveContext } from "./github.mjs";
3
+ import { runQueued, runSimple, statusQueryVerdict, verdictFactory } from "./policy.mjs";
4
+ import { renderJson, renderPretty } from "./render.mjs";
5
+ import { setTimeout } from "node:timers/promises";
6
+ import { Command, CommanderError, InvalidArgumentError, Option } from "commander";
7
+ // runtime/skills/poteto-mode/scripts/watch-pr/cli.ts
8
+ function positiveNumber(value) {
9
+ const parsed = Number(value);
10
+ if (!Number.isFinite(parsed) || parsed <= 0) throw new InvalidArgumentError("must be greater than zero");
11
+ return parsed;
12
+ }
13
+ function nonNegativeNumber(value) {
14
+ const parsed = Number(value);
15
+ if (!Number.isFinite(parsed) || parsed < 0) throw new InvalidArgumentError("must be zero or greater");
16
+ return parsed;
17
+ }
18
+ function positiveInteger(value) {
19
+ const parsed = Number(value);
20
+ if (!Number.isInteger(parsed) || parsed <= 0) throw new InvalidArgumentError("must be a positive integer");
21
+ return parsed;
22
+ }
23
+ function prNumber(value) {
24
+ try {
25
+ return parsePrNumber(Number(value.replace(/^#/, "")));
26
+ } catch {
27
+ throw new InvalidArgumentError("must be a positive integer");
28
+ }
29
+ }
30
+ function stackPrList(value) {
31
+ const numbers = value.split(",").map((part) => prNumber(part.trim()));
32
+ if (new Set(numbers).size !== numbers.length) throw new InvalidArgumentError("contains a duplicate PR");
33
+ const parsed = nonEmpty(numbers);
34
+ if (parsed === null) throw new InvalidArgumentError("cannot be empty");
35
+ return parsed;
36
+ }
37
+ function parseArgs(argv, io) {
38
+ const program = new Command("watch-pr").description("Watch one pull request, a connected stack, or an immutable queued stack.\nJSON (NDJSON while polling) is the default; --pretty renders human text.").configureOutput({
39
+ writeOut: io.stdout,
40
+ writeErr: io.stderr
41
+ }).exitOverride().option("--owner <owner>", "GitHub repository owner").option("--repo <repo>", "GitHub repository name").option("--pr <number>", "pull request number", prNumber).addOption(new Option("--stack", "watch the connected open stack").default(false).conflicts("queuedStack")).option("--queued-stack", "watch the captured stack until all PRs merge", false).option("--stack-prs <n,...>", "frozen bottom-to-top queue (queued mode only)", stackPrList).option("--interval <seconds>", "poll interval", positiveNumber, 60).option("--sweep-interval <seconds>", "whole-stack sweep interval", positiveNumber, 300).option("--timeout <seconds>", "deadline; 0 disables it", nonNegativeNumber, 0).option("--max-query-errors <count>", "consecutive query-error budget", positiveInteger, 5).option("--status-only", "print one status table and exit 0", false).option("--allow-draft", "do not treat a draft as a merge gate", false).option("--pretty", "render human text instead of JSON", false);
42
+ program.parse(argv, { from: "user" });
43
+ const raw = program.opts();
44
+ if (raw.stackPrs !== void 0 && !raw.queuedStack) program.error("error: --stack-prs requires --queued-stack");
45
+ return {
46
+ owner: raw.owner ?? null,
47
+ repo: raw.repo ?? null,
48
+ pr: raw.pr ?? null,
49
+ mode: raw.queuedStack ? "queued-stack" : raw.stack ? "stack" : "single",
50
+ stackPrs: raw.stackPrs ?? [],
51
+ statusOnly: raw.statusOnly,
52
+ pretty: raw.pretty,
53
+ polling: {
54
+ interval: raw.interval,
55
+ sweepInterval: raw.sweepInterval,
56
+ timeout: raw.timeout,
57
+ maxQueryErrors: raw.maxQueryErrors,
58
+ allowDraft: raw.allowDraft
59
+ }
60
+ };
61
+ }
62
+ function realRuntime() {
63
+ return {
64
+ reader: new GhGitHubReader(),
65
+ clock: {
66
+ now: () => performance.now() / 1e3,
67
+ observedAt: () => (/* @__PURE__ */ new Date()).toISOString(),
68
+ sleep: async (seconds) => {
69
+ await setTimeout(seconds * 1e3);
70
+ }
71
+ },
72
+ stdout: (value) => process.stdout.write(value),
73
+ stderr: (value) => process.stderr.write(value)
74
+ };
75
+ }
76
+ async function main(argv, runtime = realRuntime()) {
77
+ let options;
78
+ try {
79
+ options = parseArgs(argv, runtime);
80
+ } catch (error) {
81
+ if (!(error instanceof CommanderError)) throw error;
82
+ return error.exitCode === 0 ? 0 : 64;
83
+ }
84
+ const render = options.pretty ? renderPretty : renderJson;
85
+ const emit = (verdict) => runtime.stdout(render(verdict));
86
+ let contexts;
87
+ try {
88
+ const seed = await resolveContext({
89
+ reader: runtime.reader,
90
+ owner: options.owner,
91
+ repo: options.repo,
92
+ pr: options.pr ?? options.stackPrs[0] ?? null
93
+ });
94
+ contexts = nonEmpty(options.stackPrs.map((number) => ({
95
+ ...seed,
96
+ number
97
+ }))) ?? (options.mode === "single" ? [seed] : await discoverStack(runtime.reader, seed));
98
+ } catch (error) {
99
+ if (!(error instanceof WatcherQueryError)) throw error;
100
+ const verdict = statusQueryVerdict(verdictFactory(runtime.clock, options.mode), 1, error.failure);
101
+ runtime.stdout(render(verdict));
102
+ return verdict.exitCode;
103
+ }
104
+ const dependencies = {
105
+ reader: runtime.reader,
106
+ clock: runtime.clock,
107
+ emit
108
+ };
109
+ const verdict = options.mode === "queued-stack" && !options.statusOnly ? await runQueued({
110
+ dependencies,
111
+ contexts,
112
+ options: options.polling
113
+ }) : await runSimple({
114
+ dependencies,
115
+ contexts,
116
+ mode: options.mode,
117
+ statusOnly: options.statusOnly,
118
+ options: options.polling
119
+ });
120
+ runtime.stdout(render(verdict));
121
+ return verdict.exitCode;
122
+ }
123
+ export { main, parseArgs };