dsh-pstack 0.2.0-beta.1 → 0.2.0-beta.3

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 (261) hide show
  1. package/LICENSE +2 -3
  2. package/README.md +135 -84
  3. package/README.zh.md +185 -0
  4. package/cordis.patch.yml +97 -27
  5. package/dist/host-contract-CUPSpeNk.d.mts +22 -0
  6. package/dist/index.d.mts +49 -238
  7. package/dist/index.mjs +250 -123
  8. package/dist/models.d.mts +44 -0
  9. package/dist/models.mjs +201 -0
  10. package/dist/paths-BT77khwm.mjs +48 -0
  11. package/dist/pstack/LICENSE +21 -0
  12. package/dist/pstack/README.md +291 -0
  13. package/dist/pstack/agents/poteto-agent.md +9 -0
  14. package/{assets → dist/pstack}/docs/guide/01-setup.md +13 -11
  15. package/{assets → dist/pstack}/docs/guide/02-poteto-mode.md +4 -4
  16. package/{assets → dist/pstack}/docs/guide/04-design.md +4 -4
  17. package/{assets → dist/pstack}/docs/guide/05-build-and-clean.md +2 -2
  18. package/{assets → dist/pstack}/docs/guide/06-verify-and-ship.md +13 -3
  19. package/{assets → dist/pstack}/docs/guide/07-overnight.md +15 -13
  20. package/{assets → dist/pstack}/docs/guide/09-make-it-yours.md +6 -2
  21. package/{assets → dist/pstack}/docs/guide/10-recipes-and-pitfalls.md +7 -5
  22. package/{assets → dist/pstack}/docs/guide/README.md +1 -1
  23. package/dist/pstack/docs/harness/dsh.md +98 -0
  24. package/{assets → dist/pstack}/skills/architect/SKILL.md +12 -12
  25. package/dist/pstack/skills/arena/SKILL.md +50 -0
  26. package/{assets → dist/pstack}/skills/automate-me/SKILL.md +14 -14
  27. package/{assets → dist/pstack}/skills/benchmark-checklist/SKILL.md +1 -1
  28. package/{assets → dist/pstack}/skills/blast-radius/SKILL.md +4 -6
  29. package/{assets → dist/pstack}/skills/correct/SKILL.md +1 -1
  30. package/{assets → dist/pstack}/skills/create-formal-verification-skill/SKILL.md +4 -2
  31. package/{assets → dist/pstack}/skills/create-verification-skill/SKILL.md +5 -5
  32. package/dist/pstack/skills/figure-it-out/SKILL.md +54 -0
  33. package/dist/pstack/skills/how/SKILL.md +38 -0
  34. package/{assets → dist/pstack}/skills/in-your-own-words/SKILL.md +1 -1
  35. package/dist/pstack/skills/interrogate/SKILL.md +33 -0
  36. package/{assets → dist/pstack}/skills/ketchup/SKILL.md +3 -5
  37. package/dist/pstack/skills/ketchup-video/SKILL.md +29 -0
  38. package/{assets → dist/pstack}/skills/maintain-formal-verification-skill/SKILL.md +1 -1
  39. package/{assets → dist/pstack}/skills/maintain-verification-skill/SKILL.md +3 -3
  40. package/dist/pstack/skills/make-bot-ui/SKILL.md +117 -0
  41. package/dist/pstack/skills/no-comments/SKILL.md +26 -0
  42. package/{assets → dist/pstack}/skills/poteto-help/SKILL.md +34 -31
  43. package/{assets → dist/pstack}/skills/poteto-help/references/prompting.md +1 -1
  44. package/{assets → dist/pstack}/skills/poteto-help/references/recipes.md +3 -3
  45. package/{assets → dist/pstack}/skills/poteto-mode/SKILL.md +20 -19
  46. package/dist/pstack/skills/poteto-mode/playbooks/authoring-a-skill.md +12 -0
  47. package/dist/pstack/skills/poteto-mode/playbooks/autonomous-run.md +13 -0
  48. package/dist/pstack/skills/poteto-mode/playbooks/autopilot-full.md +25 -0
  49. package/dist/pstack/skills/poteto-mode/playbooks/autopilot-stack.md +8 -0
  50. package/{assets → dist/pstack}/skills/poteto-mode/playbooks/babysit.md +4 -4
  51. package/dist/pstack/skills/poteto-mode/playbooks/bug-fix.md +15 -0
  52. package/{assets → dist/pstack}/skills/poteto-mode/playbooks/eval.md +3 -3
  53. package/dist/pstack/skills/poteto-mode/playbooks/feature.md +21 -0
  54. package/{assets → dist/pstack}/skills/poteto-mode/playbooks/hillclimb.md +3 -3
  55. package/{assets → dist/pstack}/skills/poteto-mode/playbooks/investigation.md +2 -2
  56. package/{assets → dist/pstack}/skills/poteto-mode/playbooks/multi-phase-plan.md +23 -23
  57. package/{assets → dist/pstack}/skills/poteto-mode/playbooks/opening-a-pr.md +6 -6
  58. package/dist/pstack/skills/poteto-mode/playbooks/orchestrate.md +25 -0
  59. package/{assets → dist/pstack}/skills/poteto-mode/playbooks/pause-safely.md +2 -2
  60. package/dist/pstack/skills/poteto-mode/playbooks/perf-issue.md +25 -0
  61. package/{assets → dist/pstack}/skills/poteto-mode/playbooks/prototype.md +4 -4
  62. package/dist/pstack/skills/poteto-mode/playbooks/refactoring.md +16 -0
  63. package/dist/pstack/skills/poteto-mode/playbooks/runtime-forensics.md +11 -0
  64. package/dist/pstack/skills/poteto-mode/playbooks/session-pickup.md +11 -0
  65. package/{assets → dist/pstack}/skills/poteto-mode/playbooks/shipping.md +2 -2
  66. package/{assets → dist/pstack}/skills/poteto-mode/playbooks/trace-forensics.md +2 -2
  67. package/dist/pstack/skills/poteto-mode/playbooks/visual-parity.md +11 -0
  68. package/dist/pstack/skills/poteto-mode/playbooks/worktree-cleanup.md +12 -0
  69. package/{assets → dist/pstack}/skills/poteto-mode/scripts/check-plan.mjs +6 -8
  70. package/dist/pstack/skills/poteto-mode/scripts/check-plan.test.mjs +128 -0
  71. package/{assets/skills/poteto-mode/scripts/check-plan.test.mjs → dist/pstack/skills/poteto-mode/scripts/expect.mjs} +12 -101
  72. package/dist/pstack/skills/poteto-mode/scripts/support.mjs +93 -0
  73. package/dist/pstack/skills/poteto-mode/scripts/watch-pr/cli.mjs +123 -0
  74. package/dist/pstack/skills/poteto-mode/scripts/watch-pr/cli.test.mjs +217 -0
  75. package/dist/pstack/skills/poteto-mode/scripts/watch-pr/fakes.test-helper.mjs +119 -0
  76. package/dist/pstack/skills/poteto-mode/scripts/watch-pr/github.mjs +626 -0
  77. package/dist/pstack/skills/poteto-mode/scripts/watch-pr/github.test.mjs +521 -0
  78. package/dist/pstack/skills/poteto-mode/scripts/watch-pr/policy.mjs +657 -0
  79. package/dist/pstack/skills/poteto-mode/scripts/watch-pr/policy.test.mjs +523 -0
  80. package/dist/pstack/skills/poteto-mode/scripts/watch-pr/render.mjs +106 -0
  81. package/dist/pstack/skills/poteto-mode/scripts/watch-pr/types.mjs +9 -0
  82. package/dist/pstack/skills/poteto-mode/scripts/watch-pr/watch-pr.mjs +5 -0
  83. package/{assets → dist/pstack}/skills/poteto-mode/scripts/worktree-audit.mjs +15 -22
  84. package/dist/pstack/skills/poteto-mode/scripts/worktree-audit.test.mjs +134 -0
  85. package/{assets → dist/pstack}/skills/principle-attack-the-premise/SKILL.md +1 -1
  86. package/{assets → dist/pstack}/skills/principle-boundary-discipline/SKILL.md +1 -1
  87. package/{assets → dist/pstack}/skills/principle-encode-lessons-in-structure/SKILL.md +1 -1
  88. package/{assets → dist/pstack}/skills/principle-exhaust-the-design-space/SKILL.md +1 -1
  89. package/{assets → dist/pstack}/skills/principle-experience-first/SKILL.md +1 -1
  90. package/{assets → dist/pstack}/skills/principle-explain-the-number/SKILL.md +3 -2
  91. package/{assets → dist/pstack}/skills/principle-fix-root-causes/SKILL.md +1 -1
  92. package/{assets → dist/pstack}/skills/principle-laziness-protocol/SKILL.md +1 -1
  93. package/{assets → dist/pstack}/skills/principle-make-operations-idempotent/SKILL.md +1 -1
  94. package/{assets → dist/pstack}/skills/principle-migrate-callers-then-delete-legacy-apis/SKILL.md +1 -1
  95. package/{assets → dist/pstack}/skills/principle-minimize-reader-load/SKILL.md +1 -1
  96. package/{assets → dist/pstack}/skills/principle-model-the-domain/SKILL.md +1 -1
  97. package/{assets → dist/pstack}/skills/principle-never-block-on-the-human/SKILL.md +1 -1
  98. package/{assets → dist/pstack}/skills/principle-outcome-oriented-execution/SKILL.md +1 -1
  99. package/{assets → dist/pstack}/skills/principle-prove-it-works/SKILL.md +2 -2
  100. package/{assets → dist/pstack}/skills/principle-redesign-from-first-principles/SKILL.md +1 -1
  101. package/{assets → dist/pstack}/skills/principle-separate-before-serializing-shared-state/SKILL.md +1 -1
  102. package/{assets → dist/pstack}/skills/principle-sequence-verifiable-units/SKILL.md +1 -1
  103. package/{assets → dist/pstack}/skills/principle-subtract-before-you-add/SKILL.md +1 -1
  104. package/{assets → dist/pstack}/skills/principle-test-behavior-not-implementation/SKILL.md +1 -1
  105. package/{assets → dist/pstack}/skills/principle-type-system-discipline/SKILL.md +1 -1
  106. package/dist/pstack/skills/recall/SKILL.md +37 -0
  107. package/dist/pstack/skills/reflect/SKILL.md +71 -0
  108. package/{assets → dist/pstack}/skills/reflect/references/divergent-reviewer.md +4 -4
  109. package/{assets → dist/pstack}/skills/reflect/references/judgment-reviewer.md +2 -2
  110. package/{assets → dist/pstack}/skills/reflect/references/synthesizer.md +5 -5
  111. package/{assets → dist/pstack}/skills/reflect/references/tooling-reviewer.md +2 -2
  112. package/dist/pstack/skills/setup-pstack/SKILL.md +80 -0
  113. package/{assets → dist/pstack}/skills/sharpen/SKILL.md +1 -1
  114. package/{assets → dist/pstack}/skills/show-me-your-work/SKILL.md +8 -8
  115. package/{assets → dist/pstack}/skills/show-me-your-work/scripts/log.mjs +1 -3
  116. package/dist/pstack/skills/show-me-your-work/scripts/log.test.mjs +56 -0
  117. package/dist/pstack/skills/statechart/SKILL.md +82 -0
  118. package/dist/pstack/skills/statechart/references/render.md +93 -0
  119. package/dist/pstack/skills/statechart/scripts/backends/cfg.mjs +31 -0
  120. package/dist/pstack/skills/statechart/scripts/backends/mermaid.mjs +186 -0
  121. package/dist/pstack/skills/statechart/scripts/backends/plain-text.mjs +62 -0
  122. package/dist/pstack/skills/statechart/scripts/backends/report.mjs +84 -0
  123. package/dist/pstack/skills/statechart/scripts/frontends/config.mjs +268 -0
  124. package/dist/pstack/skills/statechart/scripts/frontends/dot.mjs +67 -0
  125. package/dist/pstack/skills/statechart/scripts/frontends/marks.mjs +94 -0
  126. package/dist/pstack/skills/statechart/scripts/frontends/messages.mjs +48 -0
  127. package/dist/pstack/skills/statechart/scripts/frontends/spec.mjs +101 -0
  128. package/dist/pstack/skills/statechart/scripts/frontends/trace.mjs +39 -0
  129. package/dist/pstack/skills/statechart/scripts/frontends/value.mjs +180 -0
  130. package/dist/pstack/skills/statechart/scripts/frontends/verdict.mjs +40 -0
  131. package/dist/pstack/skills/statechart/scripts/frontends/view.mjs +99 -0
  132. package/dist/pstack/skills/statechart/scripts/ir.mjs +277 -0
  133. package/dist/pstack/skills/statechart/scripts/passes/annotate.mjs +92 -0
  134. package/dist/pstack/skills/statechart/scripts/passes/label.mjs +210 -0
  135. package/dist/pstack/skills/statechart/scripts/passes/lift.mjs +84 -0
  136. package/dist/pstack/skills/statechart/scripts/passes/loop-check.mjs +47 -0
  137. package/dist/pstack/skills/statechart/scripts/passes/paths.mjs +72 -0
  138. package/dist/pstack/skills/statechart/scripts/passes/reach.mjs +135 -0
  139. package/dist/pstack/skills/statechart/scripts/passes/region-check.mjs +82 -0
  140. package/dist/pstack/skills/statechart/scripts/passes/regions.mjs +268 -0
  141. package/dist/pstack/skills/statechart/scripts/pipeline.mjs +72 -0
  142. package/dist/pstack/skills/statechart/scripts/run.mjs +440 -0
  143. package/dist/pstack/skills/statechart/scripts/statechart.mjs +155 -0
  144. package/dist/pstack/skills/statechart/scripts/statechart.test.mjs +198 -0
  145. package/dist/pstack/skills/statechart/scripts/worker.mjs +31 -0
  146. package/dist/pstack/skills/swarm/SKILL.md +43 -0
  147. package/{assets → dist/pstack}/skills/tdd/SKILL.md +1 -1
  148. package/{assets → dist/pstack}/skills/teach/SKILL.md +2 -2
  149. package/{assets → dist/pstack}/skills/technical-writing/SKILL.md +1 -1
  150. package/{assets → dist/pstack}/skills/typescript-best-practices/SKILL.md +3 -6
  151. package/{assets → dist/pstack}/skills/why/SKILL.md +8 -8
  152. package/dist/script.d.mts +9 -111
  153. package/dist/script.mjs +32 -329
  154. package/dist/skill.d.mts +38 -0
  155. package/dist/skill.mjs +183 -0
  156. package/dist/skills/authored/decision-audit/SKILL.md +99 -0
  157. package/dist/skills/authored/decision-audit/SKILL.zh.md +99 -0
  158. package/dist/skills/authored/decision-audit/references/recover-commit.md +17 -0
  159. package/dist/skills/authored/decision-audit/references/recover-commit.zh.md +17 -0
  160. package/dist/skills/authored/decision-write/SKILL.md +131 -0
  161. package/dist/skills/authored/decision-write/SKILL.zh.md +131 -0
  162. package/dist/skills/authored/decision-write/references/land.md +48 -0
  163. package/dist/skills/authored/decision-write/references/land.zh.md +48 -0
  164. package/dist/skills/authored/setup-project-docs/SKILL.md +58 -0
  165. package/dist/skills/authored/setup-project-docs/SKILL.zh.md +58 -0
  166. package/dist/skills/authored/setup-project-docs/references/decision-conventions.md +11 -0
  167. package/dist/skills/authored/setup-project-docs/references/decision-conventions.zh.md +11 -0
  168. package/dist/skills/vendored/retro/SKILL.md +44 -0
  169. package/dist/skills/vendored/retro/agents/openai.yaml +5 -0
  170. package/dist/skills/vendored/writing-for-agents/SKILL-MECHANICS.md +22 -0
  171. package/dist/skills/vendored/writing-for-agents/SKILL.md +81 -0
  172. package/dist/skills/vendored/writing-for-agents/agents/openai.yaml +3 -0
  173. package/dist/subagent.d.mts +56 -193
  174. package/dist/subagent.mjs +443 -741
  175. package/locale/en.json +3 -2
  176. package/locale/zh.json +3 -2
  177. package/package.json +63 -66
  178. package/assets/agents/poteto-agent.md +0 -8
  179. package/assets/docs/harness/dsh.md +0 -60
  180. package/assets/docs/pstack-models.example.md +0 -54
  181. package/assets/skills/arena/SKILL.md +0 -50
  182. package/assets/skills/figure-it-out/SKILL.md +0 -54
  183. package/assets/skills/how/SKILL.md +0 -38
  184. package/assets/skills/interrogate/SKILL.md +0 -71
  185. package/assets/skills/interrogate/references/code-quality-review.md +0 -47
  186. package/assets/skills/interrogate/references/lead-judgment.md +0 -39
  187. package/assets/skills/interrogate/references/reviewer-prompt.md +0 -62
  188. package/assets/skills/interrogate/references/rubric.md +0 -77
  189. package/assets/skills/no-comments/SKILL.md +0 -26
  190. package/assets/skills/poteto-mode/playbooks/authoring-a-skill.md +0 -12
  191. package/assets/skills/poteto-mode/playbooks/autonomous-run.md +0 -15
  192. package/assets/skills/poteto-mode/playbooks/autopilot-full.md +0 -25
  193. package/assets/skills/poteto-mode/playbooks/autopilot-stack.md +0 -12
  194. package/assets/skills/poteto-mode/playbooks/bug-fix.md +0 -15
  195. package/assets/skills/poteto-mode/playbooks/feature.md +0 -21
  196. package/assets/skills/poteto-mode/playbooks/orchestrate.md +0 -112
  197. package/assets/skills/poteto-mode/playbooks/perf-issue.md +0 -25
  198. package/assets/skills/poteto-mode/playbooks/refactoring.md +0 -16
  199. package/assets/skills/poteto-mode/playbooks/runtime-forensics.md +0 -11
  200. package/assets/skills/poteto-mode/playbooks/session-pickup.md +0 -11
  201. package/assets/skills/poteto-mode/playbooks/visual-parity.md +0 -11
  202. package/assets/skills/poteto-mode/playbooks/worktree-cleanup.md +0 -20
  203. package/assets/skills/poteto-mode/scripts/orch/orch.mjs +0 -4282
  204. package/assets/skills/poteto-mode/scripts/orch/orch.test.mjs +0 -2042
  205. package/assets/skills/poteto-mode/scripts/watch-pr/cli.test.mjs +0 -5101
  206. package/assets/skills/poteto-mode/scripts/watch-pr/github.test.mjs +0 -1177
  207. package/assets/skills/poteto-mode/scripts/watch-pr/policy.test.mjs +0 -1441
  208. package/assets/skills/poteto-mode/scripts/watch-pr/watch-pr.mjs +0 -4601
  209. package/assets/skills/recall/SKILL.md +0 -37
  210. package/assets/skills/reflect/SKILL.md +0 -69
  211. package/assets/skills/setup-pstack/SKILL.md +0 -67
  212. package/assets/skills/swarm/SKILL.md +0 -43
  213. package/dist/frontmatter-BQX3ekwP.mjs +0 -229
  214. package/dist/frontmatter-BQX3ekwP.mjs.map +0 -1
  215. package/dist/history.d.mts +0 -429
  216. package/dist/history.mjs +0 -1129
  217. package/dist/history.mjs.map +0 -1
  218. package/dist/host-contract-o47JH_r8.d.mts +0 -527
  219. package/dist/index.mjs.map +0 -1
  220. package/dist/paths-D_JlVmBk.mjs +0 -42
  221. package/dist/paths-D_JlVmBk.mjs.map +0 -1
  222. package/dist/script.mjs.map +0 -1
  223. package/dist/subagent.mjs.map +0 -1
  224. /package/{static/icon.png → assets/logo.png} +0 -0
  225. /package/{assets → dist/pstack}/agents/comment-sicko.md +0 -0
  226. /package/{assets → dist/pstack}/docs/guide/03-understand.md +0 -0
  227. /package/{assets → dist/pstack}/docs/guide/08-principles.md +0 -0
  228. /package/{assets → dist/pstack}/docs/guide/images/design.jpg +0 -0
  229. /package/{assets → dist/pstack}/docs/guide/images/overnight.jpg +0 -0
  230. /package/{assets → dist/pstack}/docs/guide/images/recipes.jpg +0 -0
  231. /package/{assets → dist/pstack}/docs/guide/images/router.jpg +0 -0
  232. /package/{assets → dist/pstack}/docs/guide/images/understanding.jpg +0 -0
  233. /package/{assets → dist/pstack}/docs/guide/images/verification.jpg +0 -0
  234. /package/{assets → dist/pstack}/skills/architect/references/design-red-flags.md +0 -0
  235. /package/{assets → dist/pstack}/skills/architect/references/rationale-template.md +0 -0
  236. /package/{assets → dist/pstack}/skills/architect/references/runner-prompt.md +0 -0
  237. /package/{assets → dist/pstack}/skills/bro/SKILL.md +0 -0
  238. /package/{assets → dist/pstack}/skills/create-verification-skill/references/feature-map-example/README.md +0 -0
  239. /package/{assets → dist/pstack}/skills/create-verification-skill/references/feature-map-example/create-note.md +0 -0
  240. /package/{assets → dist/pstack}/skills/create-verification-skill/references/feature-map-example/search.md +0 -0
  241. /package/{assets → dist/pstack}/skills/how/references/explainer-prompt.md +0 -0
  242. /package/{assets → dist/pstack}/skills/how/references/explorer-prompt.md +0 -0
  243. /package/{assets → dist/pstack}/skills/poteto-mode/references/bugbot-triage.md +0 -0
  244. /package/{assets → dist/pstack}/skills/principle-build-the-lever/SKILL.md +0 -0
  245. /package/{assets → dist/pstack}/skills/principle-foundational-thinking/SKILL.md +0 -0
  246. /package/{assets → dist/pstack}/skills/principle-guard-the-context-window/SKILL.md +0 -0
  247. /package/{assets → dist/pstack}/skills/show-me-your-work/references/decision-log-template.tsv +0 -0
  248. /package/{assets → dist/pstack}/skills/typescript-best-practices/references/patterns.md +0 -0
  249. /package/{assets → dist/pstack}/skills/unslop/SKILL.md +0 -0
  250. /package/{assets → dist/pstack}/skills/why/references/epistemics.md +0 -0
  251. /package/{assets → dist/pstack}/skills/why/references/investigator-prompt.md +0 -0
  252. /package/{assets → dist/pstack}/skills/why/references/source-playbook.md +0 -0
  253. /package/{assets → dist/pstack}/skills/why/references/sources/code-archaeology.md +0 -0
  254. /package/{assets → dist/pstack}/skills/why/references/sources/databricks.md +0 -0
  255. /package/{assets → dist/pstack}/skills/why/references/sources/datadog.md +0 -0
  256. /package/{assets → dist/pstack}/skills/why/references/sources/incident-postmortem.md +0 -0
  257. /package/{assets → dist/pstack}/skills/why/references/sources/linear.md +0 -0
  258. /package/{assets → dist/pstack}/skills/why/references/sources/notion.md +0 -0
  259. /package/{assets → dist/pstack}/skills/why/references/sources/sentry.md +0 -0
  260. /package/{assets → dist/pstack}/skills/why/references/sources/slack.md +0 -0
  261. /package/{assets → dist/pstack}/skills/why/references/synthesizer-prompt.md +0 -0
@@ -0,0 +1,47 @@
1
+ import { append, holds, loopOf, must, tupleKey, unkey } from "../ir.mjs";
2
+ // runtime/skills/statechart/scripts/passes/loop-check.ts
3
+ function loopCheck({ regions, loops }, { names, keys, drawnLabels, sorted }, { index, from, to }, found) {
4
+ const R = names.length;
5
+ const combo = (i) => {
6
+ const parts = [];
7
+ for (let r = 0; r < R; r++) parts.push(keys[r][i]);
8
+ return tupleKey(parts);
9
+ };
10
+ const stepsFrom = /* @__PURE__ */ new Map();
11
+ const arrowsFrom = [];
12
+ if (loops.length) {
13
+ for (const j of sorted) append(stepsFrom, from[j], j);
14
+ for (const { arrows } of regions) {
15
+ const out = /* @__PURE__ */ new Map();
16
+ for (const a of arrows) append(out, a.from, a);
17
+ arrowsFrom.push(out);
18
+ }
19
+ }
20
+ for (const b of found) {
21
+ if (b.loop === void 0) continue;
22
+ const inLoop = /* @__PURE__ */ new Set();
23
+ const twinsOf = /* @__PURE__ */ new Map();
24
+ for (const i of loopOf(b, index)) {
25
+ inLoop.add(combo(i));
26
+ append(twinsOf, combo(i), i);
27
+ }
28
+ for (const i of loopOf(b, index)) {
29
+ const twins = must(twinsOf, combo(i));
30
+ for (const [r, name] of names.entries()) {
31
+ const takes = (a) => {
32
+ for (const s of twins) for (const j of stepsFrom.get(s) ?? []) if (drawnLabels[j] === a.label && keys[r][to[j]] === a.to) return true;
33
+ return false;
34
+ };
35
+ const rest = [];
36
+ for (let o = 0; o < R; o++) if (o !== r) rest.push(keys[o][i]);
37
+ for (const a of arrowsFrom[r].get(keys[r][i]) ?? []) {
38
+ if (!holds(a.condition, rest)) continue;
39
+ const next = [];
40
+ for (let o = 0; o < R; o++) next.push(o === r ? a.to : keys[o][i]);
41
+ if (!inLoop.has(tupleKey(next)) && !takes(a)) throw new Error(`The chart draws the step ${a.label} out of ${name ? `${name} ` : ""}${unkey(a.from).join(" / ")}, but the ${b.rule.name} loop cannot take it there. Show in a label what stops it.`);
42
+ }
43
+ }
44
+ }
45
+ }
46
+ }
47
+ export { loopCheck };
@@ -0,0 +1,72 @@
1
+ import { hasRule, must, stateKey } from "../ir.mjs";
2
+ // runtime/skills/statechart/scripts/passes/paths.ts
3
+ function pathGraph(names) {
4
+ const graph = {
5
+ states: /* @__PURE__ */ new Map(),
6
+ steps: []
7
+ };
8
+ const ids = /* @__PURE__ */ new Map();
9
+ const taken = /* @__PURE__ */ new Map();
10
+ const idOf = (vars, start) => {
11
+ if (!vars) throw new Error("TLC's trace has a state with no values.");
12
+ const k = stateKey(names.map((name) => vars[name]));
13
+ let id = ids.get(k);
14
+ if (id === void 0) {
15
+ ids.set(k, id = String(ids.size));
16
+ graph.states.set(id, {
17
+ vars,
18
+ start,
19
+ breaks: []
20
+ });
21
+ } else if (start) must(graph.states, id).start = true;
22
+ return id;
23
+ };
24
+ const route = (seq) => {
25
+ const start = idOf(seq[0].vars, true);
26
+ const path = [];
27
+ let from = start;
28
+ for (let i = 1; i < seq.length; i++) {
29
+ const { action } = seq[i];
30
+ const to = idOf(seq[i].vars, false);
31
+ const k = `${from} ${to} ${action}`;
32
+ let step = taken.get(k);
33
+ if (!step) {
34
+ taken.set(k, step = {
35
+ from,
36
+ to,
37
+ action
38
+ });
39
+ graph.steps.push(step);
40
+ }
41
+ path.push({
42
+ action,
43
+ state: to,
44
+ step
45
+ });
46
+ from = to;
47
+ }
48
+ return {
49
+ start,
50
+ path
51
+ };
52
+ };
53
+ return {
54
+ graph,
55
+ bug: (rule, trace) => {
56
+ if (!trace.length) throw new Error(`TLC's trace for ${rule.name} has no states.`);
57
+ const bug = {
58
+ rule,
59
+ ...route(trace)
60
+ };
61
+ const end = must(graph.states, bug.path.at(-1)?.state ?? bug.start);
62
+ if (!hasRule(end.breaks, rule)) end.breaks.push(rule);
63
+ return bug;
64
+ },
65
+ lasso: ({ seq, loop }) => seq.length ? {
66
+ ...route(seq),
67
+ loop,
68
+ stutters: loop === seq.length - 1
69
+ } : void 0
70
+ };
71
+ }
72
+ export { pathGraph };
@@ -0,0 +1,135 @@
1
+ import { byText, count, defaultState, must, ruleKey, sortBy } from "../ir.mjs";
2
+ // runtime/skills/statechart/scripts/passes/reach.ts
3
+ function walk(graph) {
4
+ const ids = [];
5
+ const states = [];
6
+ const nameOf = [];
7
+ const starts = [];
8
+ const unique = /* @__PURE__ */ new Set();
9
+ for (const [id, s] of graph.states) {
10
+ const name = defaultState(s.vars);
11
+ if (s.start) starts.push(ids.length);
12
+ ids.push(id);
13
+ states.push(s);
14
+ nameOf.push(name);
15
+ unique.add(name);
16
+ }
17
+ const names = Array.from(unique).sort(byText);
18
+ const rankOf = /* @__PURE__ */ new Map();
19
+ for (let i = 0; i < names.length; i++) rankOf.set(names[i], i);
20
+ const n = ids.length;
21
+ const index = /* @__PURE__ */ new Map();
22
+ const nameRank = new Int32Array(n);
23
+ for (let i = 0; i < n; i++) {
24
+ index.set(ids[i], i);
25
+ nameRank[i] = must(rankOf, nameOf[i]);
26
+ }
27
+ const m = graph.steps.length;
28
+ const from = new Int32Array(m);
29
+ const to = new Int32Array(m);
30
+ const action = new Int32Array(m);
31
+ const actions = /* @__PURE__ */ new Map();
32
+ for (let j = 0; j < m; j++) {
33
+ const t = graph.steps[j];
34
+ from[j] = must(index, t.from);
35
+ to[j] = must(index, t.to);
36
+ let a = actions.get(t.action);
37
+ if (a === void 0) actions.set(t.action, a = actions.size);
38
+ action[j] = a;
39
+ }
40
+ const actionRank = new Int32Array(actions.size);
41
+ for (const [i, a] of [...actions.keys()].sort(byText).entries()) actionRank[must(actions, a)] = i;
42
+ const toName = new Int32Array(m);
43
+ for (let j = 0; j < m; j++) {
44
+ action[j] = actionRank[action[j]];
45
+ toName[j] = nameRank[to[j]];
46
+ }
47
+ const first = new Int32Array(n + 1);
48
+ for (let j = 0; j < m; j++) first[from[j] + 1]++;
49
+ for (let i = 0; i < n; i++) first[i + 1] += first[i];
50
+ const fill = first.slice(0, n);
51
+ const next = new Int32Array(m);
52
+ for (const j of sortBy(count(m), [action, toName])) next[fill[from[j]]++] = j;
53
+ starts.sort((a, b) => nameRank[a] - nameRank[b]);
54
+ const depth = new Int32Array(n).fill(-1);
55
+ const via = new Int32Array(n).fill(-1);
56
+ const reached = new Int32Array(n);
57
+ let size = 0;
58
+ for (const s of starts) {
59
+ depth[s] = 0;
60
+ reached[size++] = s;
61
+ }
62
+ for (let q = 0; q < size; q++) {
63
+ const s = reached[q];
64
+ for (let e = first[s]; e < first[s + 1]; e++) {
65
+ const t = to[next[e]];
66
+ if (depth[t] >= 0) continue;
67
+ depth[t] = depth[s] + 1;
68
+ via[t] = next[e];
69
+ reached[size++] = t;
70
+ }
71
+ }
72
+ return {
73
+ ids,
74
+ states,
75
+ index,
76
+ nameOf,
77
+ nameRank,
78
+ from,
79
+ to,
80
+ action,
81
+ depth,
82
+ via,
83
+ reached: reached.subarray(0, size),
84
+ starts
85
+ };
86
+ }
87
+ function drawOrder({ depth, nameRank }) {
88
+ const n = depth.length;
89
+ let deepest = 0;
90
+ for (let i = 0; i < n; i++) if (depth[i] > deepest) deepest = depth[i];
91
+ const level = new Int32Array(n);
92
+ for (let i = 0; i < n; i++) level[i] = depth[i] < 0 ? deepest + 1 : depth[i];
93
+ const order = sortBy(count(n), [level, nameRank]);
94
+ const rank = new Int32Array(n);
95
+ for (let p = 0; p < n; p++) rank[order[p]] = p;
96
+ return {
97
+ order,
98
+ rank
99
+ };
100
+ }
101
+ function bugs(graph, { ids, from, via, reached } = walk(graph)) {
102
+ const ends = /* @__PURE__ */ new Map();
103
+ for (const [id, s] of graph.states) for (const rule of s.ends ?? []) ends.set(ruleKey(rule), id);
104
+ const first = /* @__PURE__ */ new Map();
105
+ for (const i of reached) {
106
+ const s = must(graph.states, ids[i]);
107
+ for (const rule of s.past ? s.ends : s.breaks) {
108
+ const k = ruleKey(rule);
109
+ if (!first.has(k) && (ends.get(k) ?? ids[i]) === ids[i]) first.set(k, {
110
+ rule,
111
+ i
112
+ });
113
+ }
114
+ }
115
+ const found = [];
116
+ for (const { rule, i } of first.values()) {
117
+ const path = [];
118
+ let start = i;
119
+ for (let j; (j = via[start]) >= 0; start = from[j]) {
120
+ const step = graph.steps[j];
121
+ path.unshift({
122
+ action: step.action,
123
+ state: step.to,
124
+ step
125
+ });
126
+ }
127
+ found.push({
128
+ rule,
129
+ start: ids[start],
130
+ path
131
+ });
132
+ }
133
+ return found;
134
+ }
135
+ export { bugs, drawOrder, walk };
@@ -0,0 +1,82 @@
1
+ import { append, holds, tupleKey, unkey } from "../ir.mjs";
2
+ // runtime/skills/statechart/scripts/passes/region-check.ts
3
+ function regionsLie(regions, { names, keys, sorted, drawnLabels, together }, { from, to, starts }, order) {
4
+ if (names.length < 2) return void 0;
5
+ const combo = (i) => {
6
+ const c = [];
7
+ for (let r = 0; r < names.length; r++) c.push(keys[r][i]);
8
+ return c;
9
+ };
10
+ const words = (c) => {
11
+ const parts = [];
12
+ for (let i = 0; i < names.length; i++) parts.push(`${names[i]} ${unkey(c[i]).join(" / ")}`);
13
+ return parts.join(", ");
14
+ };
15
+ const addMove = (moves, m) => moves.set(tupleKey([
16
+ m.from,
17
+ m.text,
18
+ m.to
19
+ ]), m);
20
+ let product = [[]];
21
+ for (const r of regions) {
22
+ const next = [];
23
+ for (const c of product) for (const s of r.states) if (s.start) next.push([...c, tupleKey(s.path)]);
24
+ product = next;
25
+ }
26
+ const realStarts = /* @__PURE__ */ new Set();
27
+ for (const i of starts) realStarts.add(tupleKey(combo(i)));
28
+ for (const c of product) if (!realStarts.has(tupleKey(c))) return `The regions chart starts at ${words(c)}, where the model never starts.`;
29
+ for (const [i, r] of regions.entries()) for (const a of r.arrows) if (a.condition.kind === "tuples") return `In ${names[i]}, ${a.label} from ${unkey(a.from).join(" / ")} depends on the other regions in a way that one "and" or "or" condition cannot say.`;
30
+ const real = /* @__PURE__ */ new Map();
31
+ for (const j of sorted) {
32
+ const before = combo(from[j]);
33
+ const after = combo(to[j]);
34
+ if (tupleKey(before) !== tupleKey(after)) addMove(real, {
35
+ from: before,
36
+ text: drawnLabels[j],
37
+ to: after
38
+ });
39
+ }
40
+ const combos = /* @__PURE__ */ new Map();
41
+ for (const i of order) {
42
+ const c = combo(i);
43
+ combos.set(tupleKey(c), c);
44
+ }
45
+ const drawn = /* @__PURE__ */ new Map();
46
+ for (const c of combos.values()) {
47
+ const enabled = /* @__PURE__ */ new Map();
48
+ for (const [i, r] of regions.entries()) {
49
+ const rest = [];
50
+ for (let k = 0; k < c.length; k++) if (k !== i) rest.push(c[k]);
51
+ for (const a of r.arrows) if (a.from === c[i] && holds(a.condition, rest)) append(enabled, a.label, {
52
+ i,
53
+ a
54
+ });
55
+ }
56
+ for (const [text, list] of enabled) {
57
+ let groups = [];
58
+ if (together.has(text)) {
59
+ const byRegion = /* @__PURE__ */ new Map();
60
+ for (const m of list) append(byRegion, m.i, m);
61
+ groups = [[]];
62
+ for (const opts of byRegion.values()) {
63
+ const next = [];
64
+ for (const g of groups) for (const m of opts) next.push([...g, m]);
65
+ groups = next;
66
+ }
67
+ } else for (const m of list) groups.push([m]);
68
+ for (const group of groups) {
69
+ const to = [...c];
70
+ for (const { i, a } of group) to[i] = a.to;
71
+ addMove(drawn, {
72
+ from: c,
73
+ text,
74
+ to
75
+ });
76
+ }
77
+ }
78
+ }
79
+ for (const [k, extra] of drawn) if (!real.has(k)) return `The regions chart lets ${words(extra.from)} go to ${words(extra.to)} by ${extra.text}, which the model never does.`;
80
+ for (const [k, missing] of real) if (!drawn.has(k)) return `The model goes from ${words(missing.from)} to ${words(missing.to)} by ${missing.text}, which the regions chart cannot show.`;
81
+ }
82
+ export { regionsLie };
@@ -0,0 +1,268 @@
1
+ import { append, byText, hasRule, holds, loopOf, must, ruleKey, seqOf, tupleKey, unkey } from "../ir.mjs";
2
+ // runtime/skills/statechart/scripts/passes/regions.ts
3
+ const anyRest = {
4
+ kind: "and",
5
+ otherKeys: []
6
+ };
7
+ function drawRegions({ states: tla, index, from, to }, { names, shapes, drawnLabels, group, keys, kinds, sizes, sorted, pathSteps, notes }, order, found, view) {
8
+ const n = shapes.length;
9
+ const m = drawnLabels.length;
10
+ const R = names.length;
11
+ const lead = new Uint8Array(n);
12
+ const looped = new Uint8Array(n);
13
+ for (const b of found) {
14
+ for (const i of seqOf(b, index).slice(0, b.loop)) lead[i] = 1;
15
+ for (const i of loopOf(b, index)) looped[i] = 1;
16
+ }
17
+ const loop = (j) => R === 1 && pathSteps[j] === 1;
18
+ const stays = (j) => {
19
+ for (let r = 0; r < R; r++) if (kinds[r][from[j]] !== kinds[r][to[j]]) return false;
20
+ return true;
21
+ };
22
+ let inside = 0;
23
+ for (const j of sorted) if (stays(j) && !loop(j)) inside++;
24
+ const comboOf = R === 1 ? (i) => kinds[0][i] : (i) => {
25
+ let c = "";
26
+ for (let r = 0; r < R; r++) c += (r ? "," : "") + kinds[r][i];
27
+ return c;
28
+ };
29
+ const dirty = /* @__PURE__ */ new Map();
30
+ for (const i of order) if (tla[i].breaks.length) {
31
+ const c = comboOf(i);
32
+ if (!dirty.has(c)) dirty.set(c, i);
33
+ }
34
+ const clean = new Uint8Array(n);
35
+ if (dirty.size) for (let i = 0; i < n; i++) clean[i] = dirty.has(comboOf(i)) ? 0 : 1;
36
+ else clean.fill(1);
37
+ const regions = [];
38
+ const objects = [];
39
+ for (const [r, name] of names.entries()) {
40
+ const key = keys[r];
41
+ const kind = kinds[r];
42
+ const states = /* @__PURE__ */ new Map();
43
+ const objectOf = new Array(sizes[r]);
44
+ const keyOf = new Array(sizes[r]);
45
+ const position = new Int32Array(sizes[r]);
46
+ for (const i of order) {
47
+ const s = tla[i];
48
+ let o = objectOf[kind[i]];
49
+ if (!o) {
50
+ o = {
51
+ path: shapes[i][name],
52
+ start: false,
53
+ members: [],
54
+ works: false,
55
+ lead: false,
56
+ repeats: false,
57
+ breaks: [],
58
+ group: void 0
59
+ };
60
+ objectOf[kind[i]] = o;
61
+ keyOf[kind[i]] = key[i];
62
+ position[kind[i]] = states.size;
63
+ states.set(key[i], o);
64
+ }
65
+ o.start ||= s.start;
66
+ o.works ||= clean[i] === 1;
67
+ o.lead ||= lead[i] === 1;
68
+ o.repeats ||= looped[i] === 1;
69
+ o.members.push(i);
70
+ }
71
+ const parents = /* @__PURE__ */ new Set();
72
+ for (const s of states.values()) for (let i = 1; i < s.path.length; i++) parents.add(tupleKey(s.path.slice(0, i)));
73
+ for (const s of states.values()) {
74
+ if (parents.size && parents.has(tupleKey(s.path))) throw new Error(`The view's state() returned ${s.path.join(" / ")} both as a state and as a parent state${name ? ` in ${name}` : ""}. Give that state a child name of its own.`);
75
+ const rules = /* @__PURE__ */ new Map();
76
+ for (const i of s.members) for (const rule of tla[i].breaks) rules.set(ruleKey(rule), rule);
77
+ s.breaks = [];
78
+ for (const rule of [...rules.values()].sort((a, b) => byText(a.name, b.name) || byText(a.kind, b.kind))) {
79
+ let always = true;
80
+ for (const i of s.members) always &&= hasRule(tla[i].breaks, rule);
81
+ s.breaks.push({
82
+ rule,
83
+ always
84
+ });
85
+ }
86
+ const groups = /* @__PURE__ */ new Set();
87
+ for (const i of s.members) groups.add(group(i));
88
+ s.group = groups.size === 1 ? [...groups][0] : void 0;
89
+ }
90
+ const others = [];
91
+ for (let o = 0; o < R; o++) if (o !== r) others.push(o);
92
+ const tuple = (i) => {
93
+ const t = [];
94
+ for (const o of others) t.push(keys[o][i]);
95
+ return t;
96
+ };
97
+ const two = others.length === 1;
98
+ const words = (vs) => {
99
+ const texts = [];
100
+ for (const v of vs) texts.push(unkey(v).join(" / "));
101
+ return texts.sort(byText).join(two ? " or " : ", ");
102
+ };
103
+ const is = (o, vs) => two ? `when ${words(vs)}` : `${names[o]} is ${vs.size > 1 ? "one of " : ""}${words(vs)}`;
104
+ const isNot = (o, vs) => two ? `unless ${words(vs)}` : `${names[o]} is ${vs.length > 1 ? "none of" : "not"} ${words(vs)}`;
105
+ const moves = [];
106
+ const pairs = /* @__PURE__ */ new Map();
107
+ const size = sizes[r];
108
+ for (const j of sorted) {
109
+ const f = kind[from[j]];
110
+ const t = kind[to[j]];
111
+ if (f === t && !loop(j)) continue;
112
+ const text = drawnLabels[j];
113
+ const pair = position[f] * size + position[t];
114
+ let move = pairs.get(pair);
115
+ while (move && move.text !== text) move = move.other;
116
+ if (!move) {
117
+ move = {
118
+ f,
119
+ t,
120
+ text,
121
+ group: [],
122
+ other: pairs.get(pair)
123
+ };
124
+ pairs.set(pair, move);
125
+ moves.push(move);
126
+ }
127
+ if (R > 1) move.group.push(j);
128
+ }
129
+ const tuplesAt = /* @__PURE__ */ new Map();
130
+ const seenAt = /* @__PURE__ */ new Map();
131
+ if (R > 1) for (const i of order) append(tuplesAt, kind[i], i);
132
+ const arrows = [];
133
+ for (const move of moves) {
134
+ const fromKey = keyOf[move.f];
135
+ const toKey = keyOf[move.t];
136
+ if (R === 1) {
137
+ arrows.push({
138
+ from: fromKey,
139
+ to: toKey,
140
+ label: move.text,
141
+ condition: anyRest,
142
+ when: void 0
143
+ });
144
+ continue;
145
+ }
146
+ const ok = /* @__PURE__ */ new Set();
147
+ for (const j of move.group) ok.add(tupleKey(tuple(from[j])));
148
+ const takes = (t) => ok.has(tupleKey(t));
149
+ let seen = seenAt.get(move.f);
150
+ if (!seen) {
151
+ seen = [];
152
+ const seenKeys = /* @__PURE__ */ new Set();
153
+ for (const i of must(tuplesAt, move.f)) {
154
+ const t = tuple(i);
155
+ const k = tupleKey(t);
156
+ if (seenKeys.has(k)) continue;
157
+ seenKeys.add(k);
158
+ seen.push(t);
159
+ }
160
+ seenAt.set(move.f, seen);
161
+ }
162
+ const all = [];
163
+ const and = [];
164
+ const or = [];
165
+ for (let j = 0; j < others.length; j++) {
166
+ const values = /* @__PURE__ */ new Set();
167
+ const taken = /* @__PURE__ */ new Set();
168
+ const untaken = /* @__PURE__ */ new Set();
169
+ for (const t of seen) {
170
+ values.add(t[j]);
171
+ if (takes(t)) taken.add(t[j]);
172
+ else untaken.add(t[j]);
173
+ }
174
+ const only = /* @__PURE__ */ new Set();
175
+ for (const v of values) if (!untaken.has(v)) only.add(v);
176
+ all.push(values);
177
+ and.push(taken);
178
+ or.push(only);
179
+ }
180
+ const fits = (condition) => {
181
+ for (const t of seen) if (holds(condition, t) !== takes(t)) return false;
182
+ return true;
183
+ };
184
+ const andHolds = {
185
+ kind: "and",
186
+ otherKeys: and
187
+ };
188
+ const orHolds = {
189
+ kind: "or",
190
+ otherKeys: or
191
+ };
192
+ const text = move.text;
193
+ if (fits(andHolds)) {
194
+ const parts = [];
195
+ for (let j = 0; j < others.length; j++) {
196
+ const no = [];
197
+ for (const v of all[j]) if (!and[j].has(v)) no.push(v);
198
+ if (no.length) parts.push(and[j].size <= no.length ? is(others[j], and[j]) : isNot(others[j], no));
199
+ }
200
+ arrows.push({
201
+ from: fromKey,
202
+ to: toKey,
203
+ label: text,
204
+ condition: andHolds,
205
+ when: parts.length ? two ? parts[0] : `when ${parts.join(" and ")}` : void 0
206
+ });
207
+ } else if (fits(orHolds)) {
208
+ const parts = [];
209
+ for (let j = 0; j < others.length; j++) if (or[j].size) parts.push(is(others[j], or[j]));
210
+ arrows.push({
211
+ from: fromKey,
212
+ to: toKey,
213
+ label: text,
214
+ condition: orHolds,
215
+ when: `when ${parts.join(" or ")}`
216
+ });
217
+ } else arrows.push({
218
+ from: fromKey,
219
+ to: toKey,
220
+ label: text,
221
+ condition: {
222
+ kind: "tuples",
223
+ otherTuples: ok
224
+ }
225
+ });
226
+ }
227
+ const steps = [];
228
+ for (const [k, a] of arrows.entries()) steps.push({
229
+ from: objectOf[moves[k].f].path,
230
+ to: objectOf[moves[k].t].path,
231
+ label: a.label,
232
+ when: a.label.endsWith("]") ? void 0 : a.when
233
+ });
234
+ regions.push({
235
+ name,
236
+ states: [...states.values()],
237
+ steps,
238
+ arrows
239
+ });
240
+ objects.push(objectOf);
241
+ }
242
+ const hidden = [];
243
+ for (const i of dirty.values()) {
244
+ const ps = [];
245
+ for (let r = 0; r < R; r++) ps.push(objects[r][kinds[r][i]]);
246
+ let works = true;
247
+ for (const s of ps) works &&= s.works;
248
+ if (works) hidden.push(ps);
249
+ }
250
+ for (const ps of hidden) for (const s of ps) s.works = false;
251
+ const paths = [];
252
+ const loops = [];
253
+ for (const b of found) {
254
+ if (b.loop !== 0) paths.push(b.rule.name);
255
+ if (b.loop !== void 0) loops.push(b.rule.name);
256
+ }
257
+ return {
258
+ title: view.title,
259
+ regions,
260
+ notes,
261
+ inside,
262
+ quiet: m - sorted.length,
263
+ colors: view.colors ?? {},
264
+ paths,
265
+ loops
266
+ };
267
+ }
268
+ export { drawRegions };
@@ -0,0 +1,72 @@
1
+ import { ruleKey } from "./ir.mjs";
2
+ import { mermaidLines } from "./backends/mermaid.mjs";
3
+ import { plainText } from "./backends/plain-text.mjs";
4
+ import { report } from "./backends/report.mjs";
5
+ import { asParents, ask, labelGraph, storiesOf } from "./passes/label.mjs";
6
+ import { lift } from "./passes/lift.mjs";
7
+ import { loopCheck } from "./passes/loop-check.mjs";
8
+ import { bugs, drawOrder, walk } from "./passes/reach.mjs";
9
+ import { regionsLie } from "./passes/region-check.mjs";
10
+ import { drawRegions } from "./passes/regions.mjs";
11
+ // runtime/skills/statechart/scripts/pipeline.ts
12
+ function* inParts(lines) {
13
+ let start = 0;
14
+ let size = 0;
15
+ for (let i = 0; i < lines.length; i++) {
16
+ size += lines[i].length + 1;
17
+ if (size > 16777216 || i === lines.length - 1) {
18
+ yield (start ? "\n" : "") + lines.slice(start, i + 1).join("\n");
19
+ start = i + 1;
20
+ size = 0;
21
+ }
22
+ }
23
+ }
24
+ const shortestFirst = (a, b) => a.path.length - b.path.length;
25
+ function project(graph, walked, view, found) {
26
+ const { order, rank } = drawOrder(walked);
27
+ const draw = (answers) => {
28
+ const labels = labelGraph(graph, walked, answers, rank, found);
29
+ return {
30
+ labels,
31
+ chart: drawRegions(walked, labels, order, found, view)
32
+ };
33
+ };
34
+ const answers = ask(graph, walked, view);
35
+ const first = draw(answers);
36
+ const lie = regionsLie(first.chart.regions, first.labels, walked, order);
37
+ const { labels, chart } = lie ? draw(asParents(walked, answers)) : first;
38
+ loopCheck(chart, labels, walked, found);
39
+ return {
40
+ chart: lift(lie ? {
41
+ ...chart,
42
+ lie
43
+ } : chart),
44
+ stories: storiesOf(graph, found, walked, first.labels)
45
+ };
46
+ }
47
+ function compile(result, view) {
48
+ const walked = walk(result.graph);
49
+ const found = [...result.paths ?? bugs(result.graph, walked)].sort(shortestFirst);
50
+ for (const p of result.properties) if (p.bug) found.push({
51
+ rule: p.rule,
52
+ ...p.bug
53
+ });
54
+ const { chart, stories } = found.length || !result.paths ? project(result.graph, walked, view, found) : {
55
+ chart: void 0,
56
+ stories: /* @__PURE__ */ new Map()
57
+ };
58
+ const text = report(result, found, chart, stories);
59
+ const files = /* @__PURE__ */ new Map();
60
+ if (chart) files.set("chart.mmd", inParts(mermaidLines(chart)));
61
+ files.set("report.md", [text]);
62
+ files.set("tlc.out", plainText(result.messages));
63
+ const drawn = /* @__PURE__ */ new Set();
64
+ for (const b of found) if (b.rule.kind !== "property") drawn.add(ruleKey(b.rule));
65
+ for (const { rule, outcome, messages } of [...result.rules, ...result.properties]) if (outcome === "broken" && messages && !drawn.has(ruleKey(rule))) files.set(`tlc-${rule.name}.out`, plainText(messages));
66
+ return {
67
+ report: text,
68
+ files,
69
+ exit: result.exit
70
+ };
71
+ }
72
+ export { compile, project };