waygraph 0.15.46 → 0.15.49

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 (353) hide show
  1. package/dist/analysis/graph.js +2 -2
  2. package/dist/auto-session/session.js +2 -2
  3. package/dist/cli/discover.d.ts +1 -1
  4. package/dist/cli/discover.js +1 -1
  5. package/dist/cli.js +1 -1
  6. package/dist/{agent-dive.js → commands/agent-dive-scaffold.js} +2 -2
  7. package/dist/commands/agent-dive.js +1 -1
  8. package/dist/{engine/core.js → core/block.js} +6 -6
  9. package/dist/core/blocks/api.d.ts +54 -0
  10. package/dist/core/blocks/api.js +75 -0
  11. package/dist/{engine → core}/blocks/effect.d.ts +1 -1
  12. package/dist/{engine → core}/blocks/effect.js +1 -1
  13. package/dist/{engine → core}/blocks/method.d.ts +1 -1
  14. package/dist/{engine → core}/blocks/method.js +1 -1
  15. package/dist/{engine → core}/blocks/nav.js +1 -1
  16. package/dist/{engine → core}/blocks/page.js +1 -1
  17. package/dist/{engine → core}/branch-regression.js +2 -3
  18. package/dist/{engine → core}/compose.js +4 -4
  19. package/dist/{engine/engine-class.d.ts → core/engine.d.ts} +2 -133
  20. package/dist/core/engine.js +50 -0
  21. package/dist/{engine → core}/flow.js +5 -5
  22. package/dist/core/map-builder.d.ts +171 -0
  23. package/dist/{engine/engine-class.js → core/map-builder.js} +82 -98
  24. package/dist/{engine → core}/run-graph.js +4 -6
  25. package/dist/core.d.ts +14 -0
  26. package/dist/core.js +15 -0
  27. package/dist/errors.d.ts +54 -20
  28. package/dist/errors.js +67 -20
  29. package/dist/highlights/run-phase.js +15 -2
  30. package/dist/highlights/stub-ctx.js +16 -0
  31. package/dist/highlights/types.d.ts +38 -0
  32. package/dist/index.d.ts +5 -3
  33. package/dist/index.js +1 -1
  34. package/dist/mem-page.js +2 -2
  35. package/dist/mem-stub.d.ts +1 -1
  36. package/dist/pilot-overlay/fixtures.js +55 -43
  37. package/dist/pilot-overlay/shell.js +23 -10
  38. package/dist/runner/banner-log.js +1 -0
  39. package/dist/runner/device-stage.js +35 -15
  40. package/dist/runner/inpage/banner.d.ts +21 -0
  41. package/dist/runner/inpage/banner.js +29 -4
  42. package/dist/runner/inpage/caption.d.ts +3 -0
  43. package/dist/runner/inpage/caption.js +23 -0
  44. package/dist/runner/inpage/core.js +32 -9
  45. package/dist/runner/inpage/network.d.ts +15 -0
  46. package/dist/runner/inpage/network.js +217 -0
  47. package/dist/runner/inpage/panel-chrome.js +41 -1
  48. package/dist/runner/inpage/swipe-zoom.js +1 -1
  49. package/dist/runner/inpage/todos.js +6 -1
  50. package/dist/runner/main.js +9 -2
  51. package/dist/runner/network-capture.d.ts +9 -0
  52. package/dist/runner/network-capture.js +126 -0
  53. package/dist/runner/overlay-css.js +71 -7
  54. package/dist/runner/overlay-install.js +39 -2
  55. package/dist/runner/overlay-stage.js +5 -0
  56. package/dist/runner/rings.js +69 -45
  57. package/dist/runner/slides.js +14 -8
  58. package/dist/runner/step-mode.js +12 -0
  59. package/dist/runner/step-panels.js +9 -3
  60. package/dist/runner/teardown.js +16 -9
  61. package/dist/session/auto-explore-run.d.ts +1 -1
  62. package/dist/session/auto-explore-run.js +47 -10
  63. package/dist/{step-overlay.d.ts → session/step-overlay.d.ts} +1 -1
  64. package/dist/{step-overlay.js → session/step-overlay.js} +1 -1
  65. package/dist/trait.d.ts +1 -0
  66. package/dist/trait.js +15 -0
  67. package/dist/traverse/run.js +1 -1
  68. package/dist/ui/components/ring.js +4 -2
  69. package/dist/ui/overlay.css +36 -3
  70. package/examples/saucedemo/.waygraph-auto/00d147d1.log +21 -0
  71. package/examples/saucedemo/.waygraph-auto/02f7dd22.log +20 -0
  72. package/examples/saucedemo/.waygraph-auto/0402cfcf.log +6 -0
  73. package/examples/saucedemo/.waygraph-auto/062b581f.log +20 -0
  74. package/examples/saucedemo/.waygraph-auto/0681582b.log +6 -0
  75. package/examples/saucedemo/.waygraph-auto/07f3e964.log +6 -0
  76. package/examples/saucedemo/.waygraph-auto/0868ae4d.log +0 -0
  77. package/examples/saucedemo/.waygraph-auto/0924ddaa.log +22 -0
  78. package/examples/saucedemo/.waygraph-auto/092d6173.log +5 -0
  79. package/examples/saucedemo/.waygraph-auto/09924510.log +0 -0
  80. package/examples/saucedemo/.waygraph-auto/0998c941.log +21 -0
  81. package/examples/saucedemo/.waygraph-auto/0bf74300.log +21 -0
  82. package/examples/saucedemo/.waygraph-auto/0c01fd29.log +4 -0
  83. package/examples/saucedemo/.waygraph-auto/0c302590.log +0 -0
  84. package/examples/saucedemo/.waygraph-auto/0dee62d6.log +5 -0
  85. package/examples/saucedemo/.waygraph-auto/0eb4c081.log +5 -0
  86. package/examples/saucedemo/.waygraph-auto/10fd431c.log +0 -0
  87. package/examples/saucedemo/.waygraph-auto/13c6fe3c.log +0 -0
  88. package/examples/saucedemo/.waygraph-auto/1581b677.log +0 -0
  89. package/examples/saucedemo/.waygraph-auto/164761a5.log +6 -0
  90. package/examples/saucedemo/.waygraph-auto/1905ceb2.log +0 -0
  91. package/examples/saucedemo/.waygraph-auto/1b1d55c6.log +0 -0
  92. package/examples/saucedemo/.waygraph-auto/1b80fd24.log +6 -0
  93. package/examples/saucedemo/.waygraph-auto/1c30a3c2.log +0 -0
  94. package/examples/saucedemo/.waygraph-auto/1c58a174.log +0 -0
  95. package/examples/saucedemo/.waygraph-auto/1d90aa9a.log +0 -0
  96. package/examples/saucedemo/.waygraph-auto/1de7d889.log +0 -0
  97. package/examples/saucedemo/.waygraph-auto/1f233a4c.log +6 -0
  98. package/examples/saucedemo/.waygraph-auto/20e66801.log +0 -0
  99. package/examples/saucedemo/.waygraph-auto/20ffdb77.log +0 -0
  100. package/examples/saucedemo/.waygraph-auto/22f1a704.log +5 -0
  101. package/examples/saucedemo/.waygraph-auto/239cced3.log +20 -0
  102. package/examples/saucedemo/.waygraph-auto/25204b46.log +4 -0
  103. package/examples/saucedemo/.waygraph-auto/25e2e90f.log +0 -0
  104. package/examples/saucedemo/.waygraph-auto/2708455e.log +22 -0
  105. package/examples/saucedemo/.waygraph-auto/272a96fd.log +20 -0
  106. package/examples/saucedemo/.waygraph-auto/28d7be5d.log +0 -0
  107. package/examples/saucedemo/.waygraph-auto/2a6a8266.log +6 -0
  108. package/examples/saucedemo/.waygraph-auto/2b3401cf.log +20 -0
  109. package/examples/saucedemo/.waygraph-auto/2ceccd6d.log +0 -0
  110. package/examples/saucedemo/.waygraph-auto/2f1b0c13.log +6 -0
  111. package/examples/saucedemo/.waygraph-auto/2f8d4073.log +6 -0
  112. package/examples/saucedemo/.waygraph-auto/30739278.log +6 -0
  113. package/examples/saucedemo/.waygraph-auto/31cb2e80.log +0 -0
  114. package/examples/saucedemo/.waygraph-auto/322d63cd.log +0 -0
  115. package/examples/saucedemo/.waygraph-auto/3239aa8a.log +6 -0
  116. package/examples/saucedemo/.waygraph-auto/326d87b7.log +6 -0
  117. package/examples/saucedemo/.waygraph-auto/3351c0b6.log +0 -0
  118. package/examples/saucedemo/.waygraph-auto/33df0770.log +0 -0
  119. package/examples/saucedemo/.waygraph-auto/340d624d.log +0 -0
  120. package/examples/saucedemo/.waygraph-auto/36367ccf.log +0 -0
  121. package/examples/saucedemo/.waygraph-auto/372536a5.log +6 -0
  122. package/examples/saucedemo/.waygraph-auto/3a412f3c.log +0 -0
  123. package/examples/saucedemo/.waygraph-auto/3a859bd7.log +0 -0
  124. package/examples/saucedemo/.waygraph-auto/3cb0add7.log +0 -0
  125. package/examples/saucedemo/.waygraph-auto/3e42f0d8.log +0 -0
  126. package/examples/saucedemo/.waygraph-auto/4144071d.log +0 -0
  127. package/examples/saucedemo/.waygraph-auto/4176a3c6.log +0 -0
  128. package/examples/saucedemo/.waygraph-auto/41d0793d.log +4 -0
  129. package/examples/saucedemo/.waygraph-auto/41e6feae.log +0 -0
  130. package/examples/saucedemo/.waygraph-auto/424b4d5d.log +0 -0
  131. package/examples/saucedemo/.waygraph-auto/43253aba.log +0 -0
  132. package/examples/saucedemo/.waygraph-auto/438c6c53.log +22 -0
  133. package/examples/saucedemo/.waygraph-auto/4477db12.log +0 -0
  134. package/examples/saucedemo/.waygraph-auto/4a1258b7.log +0 -0
  135. package/examples/saucedemo/.waygraph-auto/4adcd179.log +20 -0
  136. package/examples/saucedemo/.waygraph-auto/4c9d9b16.log +21 -0
  137. package/examples/saucedemo/.waygraph-auto/4da39c36.log +6 -0
  138. package/examples/saucedemo/.waygraph-auto/4dbefa7e.log +5 -0
  139. package/examples/saucedemo/.waygraph-auto/4efa7035.log +6 -0
  140. package/examples/saucedemo/.waygraph-auto/505affdc.log +4 -0
  141. package/examples/saucedemo/.waygraph-auto/51bcb60a.log +0 -0
  142. package/examples/saucedemo/.waygraph-auto/5291bc78.log +22 -0
  143. package/examples/saucedemo/.waygraph-auto/54274c39.log +5 -0
  144. package/examples/saucedemo/.waygraph-auto/5440ce7e.log +0 -0
  145. package/examples/saucedemo/.waygraph-auto/5738175f.log +22 -0
  146. package/examples/saucedemo/.waygraph-auto/57ce5643.log +22 -0
  147. package/examples/saucedemo/.waygraph-auto/5984426b.log +6 -0
  148. package/examples/saucedemo/.waygraph-auto/5a682e7c.log +22 -0
  149. package/examples/saucedemo/.waygraph-auto/5b79320c.log +21 -0
  150. package/examples/saucedemo/.waygraph-auto/5c55aaac.log +21 -0
  151. package/examples/saucedemo/.waygraph-auto/5ed00b16.log +4 -0
  152. package/examples/saucedemo/.waygraph-auto/60b9c066.log +6 -0
  153. package/examples/saucedemo/.waygraph-auto/610dd127.log +0 -0
  154. package/examples/saucedemo/.waygraph-auto/61105500.log +5 -0
  155. package/examples/saucedemo/.waygraph-auto/61333142.log +5 -0
  156. package/examples/saucedemo/.waygraph-auto/6134afe8.log +20 -0
  157. package/examples/saucedemo/.waygraph-auto/61937e83.log +22 -0
  158. package/examples/saucedemo/.waygraph-auto/62a0bdc9.log +22 -0
  159. package/examples/saucedemo/.waygraph-auto/6376fc15.log +0 -0
  160. package/examples/saucedemo/.waygraph-auto/6599cbca.log +22 -0
  161. package/examples/saucedemo/.waygraph-auto/67aaca30.log +0 -0
  162. package/examples/saucedemo/.waygraph-auto/68b10298.log +0 -0
  163. package/examples/saucedemo/.waygraph-auto/68be5e12.log +0 -0
  164. package/examples/saucedemo/.waygraph-auto/68df05a6.log +22 -0
  165. package/examples/saucedemo/.waygraph-auto/693f67c4.log +20 -0
  166. package/examples/saucedemo/.waygraph-auto/69ae030a.log +6 -0
  167. package/examples/saucedemo/.waygraph-auto/69e73f35.log +6 -0
  168. package/examples/saucedemo/.waygraph-auto/6b2333b0.log +5 -0
  169. package/examples/saucedemo/.waygraph-auto/6c4c3817.log +0 -0
  170. package/examples/saucedemo/.waygraph-auto/6c954911.log +0 -0
  171. package/examples/saucedemo/.waygraph-auto/6d65a439.log +5 -0
  172. package/examples/saucedemo/.waygraph-auto/6d700055.log +0 -0
  173. package/examples/saucedemo/.waygraph-auto/6ead848f.log +0 -0
  174. package/examples/saucedemo/.waygraph-auto/72675b2d.log +6 -0
  175. package/examples/saucedemo/.waygraph-auto/733dd260.log +5 -0
  176. package/examples/saucedemo/.waygraph-auto/75016486.log +0 -0
  177. package/examples/saucedemo/.waygraph-auto/752b01c6.log +22 -0
  178. package/examples/saucedemo/.waygraph-auto/75675227.log +6 -0
  179. package/examples/saucedemo/.waygraph-auto/75e2e658.log +0 -0
  180. package/examples/saucedemo/.waygraph-auto/76ac1a86.log +0 -0
  181. package/examples/saucedemo/.waygraph-auto/77605295.log +0 -0
  182. package/examples/saucedemo/.waygraph-auto/792671f4.log +22 -0
  183. package/examples/saucedemo/.waygraph-auto/79915adb.log +20 -0
  184. package/examples/saucedemo/.waygraph-auto/7a398774.log +6 -0
  185. package/examples/saucedemo/.waygraph-auto/7a72f66e.log +6 -0
  186. package/examples/saucedemo/.waygraph-auto/7a984334.log +4 -0
  187. package/examples/saucedemo/.waygraph-auto/7c6ee793.log +20 -0
  188. package/examples/saucedemo/.waygraph-auto/7c726dc4.log +22 -0
  189. package/examples/saucedemo/.waygraph-auto/7c72e8a5.log +4 -0
  190. package/examples/saucedemo/.waygraph-auto/7dbee625.log +22 -0
  191. package/examples/saucedemo/.waygraph-auto/7df66956.log +0 -0
  192. package/examples/saucedemo/.waygraph-auto/7e053160.log +0 -0
  193. package/examples/saucedemo/.waygraph-auto/802a0b5b.log +0 -0
  194. package/examples/saucedemo/.waygraph-auto/80322e0b.log +0 -0
  195. package/examples/saucedemo/.waygraph-auto/80a4978e.log +6 -0
  196. package/examples/saucedemo/.waygraph-auto/81cfe480.log +22 -0
  197. package/examples/saucedemo/.waygraph-auto/832f5add.log +0 -0
  198. package/examples/saucedemo/.waygraph-auto/8337b6ad.log +0 -0
  199. package/examples/saucedemo/.waygraph-auto/8493928e.log +0 -0
  200. package/examples/saucedemo/.waygraph-auto/853bde43.log +0 -0
  201. package/examples/saucedemo/.waygraph-auto/86350ea6.log +22 -0
  202. package/examples/saucedemo/.waygraph-auto/86bb598a.log +0 -0
  203. package/examples/saucedemo/.waygraph-auto/86d09876.log +22 -0
  204. package/examples/saucedemo/.waygraph-auto/878ad01b.log +4 -0
  205. package/examples/saucedemo/.waygraph-auto/87c88ba5.log +0 -0
  206. package/examples/saucedemo/.waygraph-auto/87cb80ff.log +0 -0
  207. package/examples/saucedemo/.waygraph-auto/880b2e78.log +6 -0
  208. package/examples/saucedemo/.waygraph-auto/88527936.log +5 -0
  209. package/examples/saucedemo/.waygraph-auto/893023ea.log +5 -0
  210. package/examples/saucedemo/.waygraph-auto/89416718.log +0 -0
  211. package/examples/saucedemo/.waygraph-auto/8996a857.log +6 -0
  212. package/examples/saucedemo/.waygraph-auto/8a64ba0f.log +6 -0
  213. package/examples/saucedemo/.waygraph-auto/8b1cc2aa.log +6 -0
  214. package/examples/saucedemo/.waygraph-auto/8b73d13e.log +6 -0
  215. package/examples/saucedemo/.waygraph-auto/8d960d31.log +1 -0
  216. package/examples/saucedemo/.waygraph-auto/8d9e5cd2.log +21 -0
  217. package/examples/saucedemo/.waygraph-auto/8ec7d260.log +0 -0
  218. package/examples/saucedemo/.waygraph-auto/8ed43279.log +0 -0
  219. package/examples/saucedemo/.waygraph-auto/93acae32.log +5 -0
  220. package/examples/saucedemo/.waygraph-auto/96321a08.log +0 -0
  221. package/examples/saucedemo/.waygraph-auto/9742b6c2.log +6 -0
  222. package/examples/saucedemo/.waygraph-auto/99cc93eb.log +6 -0
  223. package/examples/saucedemo/.waygraph-auto/9cbfbedc.log +0 -0
  224. package/examples/saucedemo/.waygraph-auto/9dc147d2.log +22 -0
  225. package/examples/saucedemo/.waygraph-auto/a215a395.log +22 -0
  226. package/examples/saucedemo/.waygraph-auto/a23b7086.log +4 -0
  227. package/examples/saucedemo/.waygraph-auto/a35bd5ec.log +0 -0
  228. package/examples/saucedemo/.waygraph-auto/a68995e9.log +22 -0
  229. package/examples/saucedemo/.waygraph-auto/a6e4f936.log +22 -0
  230. package/examples/saucedemo/.waygraph-auto/a7da862b.log +0 -0
  231. package/examples/saucedemo/.waygraph-auto/a82e2a48.log +0 -0
  232. package/examples/saucedemo/.waygraph-auto/a952eb91.log +0 -0
  233. package/examples/saucedemo/.waygraph-auto/a9559653.log +5 -0
  234. package/examples/saucedemo/.waygraph-auto/aa478de2.log +0 -0
  235. package/examples/saucedemo/.waygraph-auto/ac350fc7.log +20 -0
  236. package/examples/saucedemo/.waygraph-auto/acc1b63a.log +0 -0
  237. package/examples/saucedemo/.waygraph-auto/ad12d191.log +0 -0
  238. package/examples/saucedemo/.waygraph-auto/ae3a9b06.log +0 -0
  239. package/examples/saucedemo/.waygraph-auto/b04638f4.log +6 -0
  240. package/examples/saucedemo/.waygraph-auto/b48863e5.log +22 -0
  241. package/examples/saucedemo/.waygraph-auto/b56968e1.log +6 -0
  242. package/examples/saucedemo/.waygraph-auto/b64e0620.log +20 -0
  243. package/examples/saucedemo/.waygraph-auto/b86a6218.log +6 -0
  244. package/examples/saucedemo/.waygraph-auto/b8e9e956.log +22 -0
  245. package/examples/saucedemo/.waygraph-auto/b9b310ff.log +21 -0
  246. package/examples/saucedemo/.waygraph-auto/bc111745.log +22 -0
  247. package/examples/saucedemo/.waygraph-auto/bf7a77a2.log +0 -0
  248. package/examples/saucedemo/.waygraph-auto/c0d6f353.log +21 -0
  249. package/examples/saucedemo/.waygraph-auto/c0febcf2.log +20 -0
  250. package/examples/saucedemo/.waygraph-auto/c4c52998.log +6 -0
  251. package/examples/saucedemo/.waygraph-auto/c809ceb4.log +22 -0
  252. package/examples/saucedemo/.waygraph-auto/ca6de7e7.log +0 -0
  253. package/examples/saucedemo/.waygraph-auto/ca8561bc.log +0 -0
  254. package/examples/saucedemo/.waygraph-auto/cb86d45b.log +0 -0
  255. package/examples/saucedemo/.waygraph-auto/cb9a1978.log +6 -0
  256. package/examples/saucedemo/.waygraph-auto/cbbc689c.log +6 -0
  257. package/examples/saucedemo/.waygraph-auto/cd88364b.log +0 -0
  258. package/examples/saucedemo/.waygraph-auto/cd919e1d.log +0 -0
  259. package/examples/saucedemo/.waygraph-auto/cfff9eef.log +20 -0
  260. package/examples/saucedemo/.waygraph-auto/d0f59b21.log +4 -0
  261. package/examples/saucedemo/.waygraph-auto/d1195079.log +20 -0
  262. package/examples/saucedemo/.waygraph-auto/d2ef067a.log +5 -0
  263. package/examples/saucedemo/.waygraph-auto/d425471f.log +6 -0
  264. package/examples/saucedemo/.waygraph-auto/d5293921.log +0 -0
  265. package/examples/saucedemo/.waygraph-auto/d62a22c2.log +21 -0
  266. package/examples/saucedemo/.waygraph-auto/d6d1761f.log +22 -0
  267. package/examples/saucedemo/.waygraph-auto/d6d5f411.log +22 -0
  268. package/examples/saucedemo/.waygraph-auto/d6df2771.log +6 -0
  269. package/examples/saucedemo/.waygraph-auto/d7075012.log +21 -0
  270. package/examples/saucedemo/.waygraph-auto/d9ddc297.log +0 -0
  271. package/examples/saucedemo/.waygraph-auto/db4ac845.log +0 -0
  272. package/examples/saucedemo/.waygraph-auto/db6d7774.log +0 -0
  273. package/examples/saucedemo/.waygraph-auto/db839827.log +5 -0
  274. package/examples/saucedemo/.waygraph-auto/dde5e859.log +22 -0
  275. package/examples/saucedemo/.waygraph-auto/de8cac58.log +0 -0
  276. package/examples/saucedemo/.waygraph-auto/ded5511a.log +6 -0
  277. package/examples/saucedemo/.waygraph-auto/dedfcb18.log +0 -0
  278. package/examples/saucedemo/.waygraph-auto/def4d9b1.log +0 -0
  279. package/examples/saucedemo/.waygraph-auto/e1549e40.log +0 -0
  280. package/examples/saucedemo/.waygraph-auto/e1b0676d.log +21 -0
  281. package/examples/saucedemo/.waygraph-auto/e5111463.log +0 -0
  282. package/examples/saucedemo/.waygraph-auto/e5fc1d7c.log +5 -0
  283. package/examples/saucedemo/.waygraph-auto/e6fd2202.log +0 -0
  284. package/examples/saucedemo/.waygraph-auto/edaa806d.log +0 -0
  285. package/examples/saucedemo/.waygraph-auto/edaf33de.log +0 -0
  286. package/examples/saucedemo/.waygraph-auto/edd40cbb.log +20 -0
  287. package/examples/saucedemo/.waygraph-auto/eddfbffc.log +6 -0
  288. package/examples/saucedemo/.waygraph-auto/ee9fa1ad.log +5 -0
  289. package/examples/saucedemo/.waygraph-auto/ef319474.log +22 -0
  290. package/examples/saucedemo/.waygraph-auto/f28eee8d.log +0 -0
  291. package/examples/saucedemo/.waygraph-auto/f33bde90.log +0 -0
  292. package/examples/saucedemo/.waygraph-auto/f6ba7cb4.log +6 -0
  293. package/examples/saucedemo/.waygraph-auto/f7ac4d62.log +20 -0
  294. package/examples/saucedemo/.waygraph-auto/f929bb79.log +0 -0
  295. package/examples/saucedemo/.waygraph-auto/f92d4c6c.log +22 -0
  296. package/examples/saucedemo/.waygraph-auto/f92faf40.log +5 -0
  297. package/examples/saucedemo/.waygraph-auto/fa784369.log +21 -0
  298. package/examples/saucedemo/.waygraph-auto/fb55f723.log +20 -0
  299. package/examples/saucedemo/.waygraph-auto/fba3b738.log +0 -0
  300. package/examples/saucedemo/.waygraph-auto/ffdf2854.log +6 -0
  301. package/examples/saucedemo/README.md +13 -2
  302. package/examples/saucedemo/package.json +4 -0
  303. package/examples/saucedemo/src/flows/api-demo.flow.ts +37 -0
  304. package/examples/saucedemo/src/flows/checkout.flow.ts +34 -11
  305. package/package.json +5 -3
  306. package/dist/auto-explore-run.d.ts +0 -37
  307. package/dist/auto-explore-run.js +0 -670
  308. package/dist/auto-explore.d.ts +0 -57
  309. package/dist/auto-explore.js +0 -376
  310. package/dist/auto-session-ipc.d.ts +0 -150
  311. package/dist/auto-session-ipc.js +0 -497
  312. package/dist/block-inject.d.ts +0 -15
  313. package/dist/block-inject.js +0 -91
  314. package/dist/browser.d.ts +0 -15
  315. package/dist/browser.js +0 -29
  316. package/dist/coverage-gap.d.ts +0 -11
  317. package/dist/coverage-gap.js +0 -119
  318. package/dist/engine.d.ts +0 -12
  319. package/dist/engine.js +0 -13
  320. package/dist/graph.d.ts +0 -92
  321. package/dist/graph.js +0 -467
  322. package/dist/highlight-shorthand.d.ts +0 -24
  323. package/dist/highlight-shorthand.js +0 -30
  324. package/dist/map-check.d.ts +0 -18
  325. package/dist/map-check.js +0 -140
  326. package/dist/overlay-beacon.d.ts +0 -44
  327. package/dist/overlay-beacon.js +0 -85
  328. package/dist/pilot.d.ts +0 -54
  329. package/dist/pilot.js +0 -80
  330. package/dist/practices-check.d.ts +0 -14
  331. package/dist/practices-check.js +0 -195
  332. package/dist/traverse-coverage.d.ts +0 -59
  333. package/dist/traverse-coverage.js +0 -127
  334. package/dist/traverse-lease.d.ts +0 -18
  335. package/dist/traverse-lease.js +0 -62
  336. package/dist/traverse-run.d.ts +0 -47
  337. package/dist/traverse-run.js +0 -439
  338. package/dist/ui/compose.d.ts +0 -4
  339. package/dist/ui/compose.js +0 -7
  340. /package/dist/{verbose-log.d.ts → auto-session/verbose-log.d.ts} +0 -0
  341. /package/dist/{verbose-log.js → auto-session/verbose-log.js} +0 -0
  342. /package/dist/{agent-dive.d.ts → commands/agent-dive-scaffold.d.ts} +0 -0
  343. /package/dist/{engine/core.d.ts → core/block.d.ts} +0 -0
  344. /package/dist/{engine → core}/blocks/nav.d.ts +0 -0
  345. /package/dist/{engine → core}/blocks/page.d.ts +0 -0
  346. /package/dist/{engine → core}/branch-regression.d.ts +0 -0
  347. /package/dist/{engine → core}/compose.d.ts +0 -0
  348. /package/dist/{engine → core}/config.d.ts +0 -0
  349. /package/dist/{engine → core}/config.js +0 -0
  350. /package/dist/{engine → core}/flow.d.ts +0 -0
  351. /package/dist/{engine → core}/locate.d.ts +0 -0
  352. /package/dist/{engine → core}/locate.js +0 -0
  353. /package/dist/{engine → core}/run-graph.d.ts +0 -0
@@ -1,44 +0,0 @@
1
- /**
2
- * Blind-agent / Playwright checks for waygraph overlay modals.
3
- *
4
- * Every live modal root must carry:
5
- * data-wg-ui="1"
6
- * data-wg-modal="panel|banner|auto-panel"
7
- * data-wg-ready="1" when painted and readable
8
- *
9
- * Agents: do not claim the stepper works unless
10
- * `assertWgOverlayReady(page)` (or WAYGRAPH_PROVE_EXIT=1) passes.
11
- */
12
- import type { Page } from "@playwright/test";
13
- export declare const WG_UI_SEL = "[data-wg-ui=\"1\"]";
14
- export declare const WG_READY_PANEL_SEL = "[data-wg-modal=\"panel\"][data-wg-ready=\"1\"]";
15
- export declare const WG_READY_AUTO_SEL = "[data-wg-modal=\"auto-panel\"][data-wg-ready=\"1\"]";
16
- export declare const WG_READY_BANNER_SEL = "[data-wg-modal=\"banner\"][data-wg-ready=\"1\"]";
17
- export type WgModalKind = "panel" | "banner" | "auto-panel";
18
- export type WgBeaconRow = {
19
- id: string | null;
20
- modal: string | null;
21
- ready: boolean;
22
- phase: string | null;
23
- step: string | null;
24
- block: string | null;
25
- collapsed: boolean;
26
- opacity: string;
27
- textLen: number;
28
- w: number;
29
- h: number;
30
- visible: boolean;
31
- };
32
- /** Browser-side beacon reader (also installed as window.__wgOverlayBeacon). */
33
- export declare function readWgOverlayBeaconInPage(): WgBeaconRow[];
34
- export declare function readWgOverlayBeacon(page: Page): Promise<WgBeaconRow[]>;
35
- /**
36
- * Hard gate: a blank / missing / opacity-0 modal fails.
37
- * Use after demo/auto paints its first overlay.
38
- */
39
- export declare function assertWgOverlayReady(page: Page, opts?: {
40
- modal?: WgModalKind;
41
- minTextLen?: number;
42
- /** When true, collapsed mini chrome is allowed (still needs visible box + text). */
43
- allowCollapsed?: boolean;
44
- }): Promise<WgBeaconRow>;
@@ -1,85 +0,0 @@
1
- /**
2
- * Blind-agent / Playwright checks for waygraph overlay modals.
3
- *
4
- * Every live modal root must carry:
5
- * data-wg-ui="1"
6
- * data-wg-modal="panel|banner|auto-panel"
7
- * data-wg-ready="1" when painted and readable
8
- *
9
- * Agents: do not claim the stepper works unless
10
- * `assertWgOverlayReady(page)` (or WAYGRAPH_PROVE_EXIT=1) passes.
11
- */
12
- export const WG_UI_SEL = '[data-wg-ui="1"]';
13
- export const WG_READY_PANEL_SEL = '[data-wg-modal="panel"][data-wg-ready="1"]';
14
- export const WG_READY_AUTO_SEL = '[data-wg-modal="auto-panel"][data-wg-ready="1"]';
15
- export const WG_READY_BANNER_SEL = '[data-wg-modal="banner"][data-wg-ready="1"]';
16
- /** Browser-side beacon reader (also installed as window.__wgOverlayBeacon). */
17
- export function readWgOverlayBeaconInPage() {
18
- const w = globalThis;
19
- if (typeof w.__wgOverlayBeacon === "function")
20
- return w.__wgOverlayBeacon();
21
- return Array.from(document.querySelectorAll(WG_UI_SEL)).map((el) => {
22
- const r = el.getBoundingClientRect();
23
- const st = getComputedStyle(el);
24
- return {
25
- id: el.id || null,
26
- modal: el.getAttribute("data-wg-modal"),
27
- ready: el.getAttribute("data-wg-ready") === "1",
28
- phase: el.getAttribute("data-wg-phase"),
29
- step: el.getAttribute("data-wg-step"),
30
- block: el.getAttribute("data-wg-block"),
31
- collapsed: el.getAttribute("data-wg-collapsed") === "1" || el.classList.contains("wg-collapsed"),
32
- opacity: st.opacity,
33
- textLen: (el.textContent || "").trim().length,
34
- w: Math.round(r.width),
35
- h: Math.round(r.height),
36
- visible: r.width > 0 && r.height > 0 && Number(st.opacity) > 0.05,
37
- };
38
- });
39
- }
40
- export async function readWgOverlayBeacon(page) {
41
- return page.evaluate(() => {
42
- const w = window;
43
- if (typeof w.__wgOverlayBeacon === "function") {
44
- return w.__wgOverlayBeacon();
45
- }
46
- return Array.from(document.querySelectorAll('[data-wg-ui="1"]')).map((el) => {
47
- const r = el.getBoundingClientRect();
48
- const st = getComputedStyle(el);
49
- return {
50
- id: el.id || null,
51
- modal: el.getAttribute("data-wg-modal"),
52
- ready: el.getAttribute("data-wg-ready") === "1",
53
- phase: el.getAttribute("data-wg-phase"),
54
- step: el.getAttribute("data-wg-step"),
55
- block: el.getAttribute("data-wg-block"),
56
- collapsed: el.getAttribute("data-wg-collapsed") === "1" || el.classList.contains("wg-collapsed"),
57
- opacity: st.opacity,
58
- textLen: (el.textContent || "").trim().length,
59
- w: Math.round(r.width),
60
- h: Math.round(r.height),
61
- visible: r.width > 0 && r.height > 0 && Number(st.opacity) > 0.05,
62
- };
63
- });
64
- });
65
- }
66
- /**
67
- * Hard gate: a blank / missing / opacity-0 modal fails.
68
- * Use after demo/auto paints its first overlay.
69
- */
70
- export async function assertWgOverlayReady(page, opts) {
71
- const modal = opts?.modal ?? "panel";
72
- const minText = opts?.minTextLen ?? 12;
73
- const rows = await readWgOverlayBeacon(page);
74
- const hit = rows.find((r) => r.modal === modal &&
75
- r.ready &&
76
- r.visible &&
77
- r.textLen >= minText &&
78
- (opts?.allowCollapsed || !r.collapsed || r.textLen >= minText));
79
- if (!hit) {
80
- throw new Error(`waygraph overlay NOT ready (modal=${modal}, minTextLen=${minText}). ` +
81
- `beacons=${JSON.stringify(rows)}. ` +
82
- `Do not claim stepper/modal works.`);
83
- }
84
- return hit;
85
- }
package/dist/pilot.d.ts DELETED
@@ -1,54 +0,0 @@
1
- /**
2
- * Waygraph Pilot: the one bootstrap call an agent needs to start driving a
3
- * real, persistent, inspectable browser session toward a natural-language
4
- * goal it plans and executes itself.
5
- *
6
- * Deliberately NOT a resolver that maps one ask to one Block
7
- * (`resolveAsk`/`pilotNarrate`/`pilotAct`, the v1 shape this replaced - see
8
- * git tag `waygraph-pilot-v1-logs-prettified` for that history). Real
9
- * requests are multi-step ("log in and buy the backpack for me", "make a
10
- * signature draft request") and need an agent that plans a whole sequence
11
- * against the graph, not a single best-matching edge. `pilotStart` does not
12
- * plan, resolve, narrate, or act on anything - it only combines two
13
- * already-proven, separately-existing primitives into one payload:
14
- *
15
- * - `spawnDetachedSession` (same mechanism as `auto --cli --detach`) - a
16
- * real, persistent, visible-if-headful Playwright session an agent can
17
- * keep driving across many calls, not a fresh session per request.
18
- * - `discoverGraph` (same mechanism as `waygraph graph`) - the WHOLE
19
- * project's Checkpoint/edge/description graph, not just what's reachable
20
- * from the session's current position, because planning a multi-step
21
- * route needs to see steps ahead, not just the next one.
22
- *
23
- * Driving the session afterward - `auto send <id> "<pick>"`, `auto status
24
- * <id>`, `auto dom <id>`, `auto trace <id>` - is left entirely to whatever
25
- * agent is holding it. All four already existed before this file did; see
26
- * openspec/changes/waygraph-pilot/design.md for the worked example (a real
27
- * login + add-to-cart + checkout run against examples/saucedemo, driven by
28
- * hand-picking indices from each status response) that proved this needs no
29
- * new execution primitive.
30
- */
31
- import { type WaygraphGraph } from "./analysis/graph.js";
32
- import { listBrowserSessions, type SessionMeta } from "./auto-session-ipc.js";
33
- import { type BrowserStartInit } from "./browser.js";
34
- import type { SessionSnapshot } from "./auto-session.js";
35
- export interface PilotStartResult {
36
- sessionId: string;
37
- socketPath: string;
38
- headless: boolean;
39
- /** The whole project's Block graph - every Checkpoint/edge/description, not just what's reachable right now. */
40
- graph: WaygraphGraph;
41
- /** The session's starting position, or `null` if the very first `status` read failed. */
42
- snapshot: SessionSnapshot | null;
43
- }
44
- /**
45
- * Starts a detached session and reads back its own graph + starting
46
- * snapshot in one call, so an agent bootstraps with everything it needs
47
- * (a live session it can keep driving, and the full map of what exists) in
48
- * one round trip instead of separately knowing to chain `auto --cli
49
- * --detach` and `waygraph graph` itself.
50
- */
51
- export declare function pilotStart(init: BrowserStartInit): Promise<PilotStartResult>;
52
- /** Reattach to an existing browser session — does not spawn a new browser. */
53
- export declare function pilotAttach(projectDir: string, sessionId: string, inject?: string[]): Promise<PilotStartResult>;
54
- export { listBrowserSessions, type SessionMeta };
package/dist/pilot.js DELETED
@@ -1,80 +0,0 @@
1
- /**
2
- * Waygraph Pilot: the one bootstrap call an agent needs to start driving a
3
- * real, persistent, inspectable browser session toward a natural-language
4
- * goal it plans and executes itself.
5
- *
6
- * Deliberately NOT a resolver that maps one ask to one Block
7
- * (`resolveAsk`/`pilotNarrate`/`pilotAct`, the v1 shape this replaced - see
8
- * git tag `waygraph-pilot-v1-logs-prettified` for that history). Real
9
- * requests are multi-step ("log in and buy the backpack for me", "make a
10
- * signature draft request") and need an agent that plans a whole sequence
11
- * against the graph, not a single best-matching edge. `pilotStart` does not
12
- * plan, resolve, narrate, or act on anything - it only combines two
13
- * already-proven, separately-existing primitives into one payload:
14
- *
15
- * - `spawnDetachedSession` (same mechanism as `auto --cli --detach`) - a
16
- * real, persistent, visible-if-headful Playwright session an agent can
17
- * keep driving across many calls, not a fresh session per request.
18
- * - `discoverGraph` (same mechanism as `waygraph graph`) - the WHOLE
19
- * project's Checkpoint/edge/description graph, not just what's reachable
20
- * from the session's current position, because planning a multi-step
21
- * route needs to see steps ahead, not just the next one.
22
- *
23
- * Driving the session afterward - `auto send <id> "<pick>"`, `auto status
24
- * <id>`, `auto dom <id>`, `auto trace <id>` - is left entirely to whatever
25
- * agent is holding it. All four already existed before this file did; see
26
- * openspec/changes/waygraph-pilot/design.md for the worked example (a real
27
- * login + add-to-cart + checkout run against examples/saucedemo, driven by
28
- * hand-picking indices from each status response) that proved this needs no
29
- * new execution primitive.
30
- */
31
- import { discoverGraph } from "./analysis/graph.js";
32
- import { requestSession, listBrowserSessions, resolveSessionMeta, } from "./auto-session-ipc.js";
33
- import { browserStart } from "./browser.js";
34
- /**
35
- * Starts a detached session and reads back its own graph + starting
36
- * snapshot in one call, so an agent bootstraps with everything it needs
37
- * (a live session it can keep driving, and the full map of what exists) in
38
- * one round trip instead of separately knowing to chain `auto --cli
39
- * --detach` and `waygraph graph` itself.
40
- */
41
- export async function pilotStart(init) {
42
- const { resolveInjectRoots } = await import("./block-inject.js");
43
- const exploreInject = init.inject ??
44
- (init.injectTokens?.length ? resolveInjectRoots(init.injectTokens, init.projectDir) : undefined);
45
- const started = await browserStart({
46
- ...init,
47
- ...(exploreInject?.length ? { inject: exploreInject } : {}),
48
- // Pilot navigates to baseURL on start (unlike `browser`, which defaults to about:blank).
49
- skipInitialNavigation: init.skipInitialNavigation ?? false,
50
- });
51
- const graph = await discoverGraph(init.projectDir, exploreInject?.length ? { inject: exploreInject } : undefined);
52
- const status = await requestSession(init.projectDir, started.sessionId, { op: "status" });
53
- return {
54
- sessionId: started.sessionId,
55
- socketPath: started.socketPath,
56
- headless: started.headless,
57
- graph,
58
- snapshot: status.ok ? status.snapshot : null,
59
- };
60
- }
61
- /** Reattach to an existing browser session — does not spawn a new browser. */
62
- export async function pilotAttach(projectDir, sessionId, inject) {
63
- const meta = resolveSessionMeta(sessionId, projectDir);
64
- if (!meta) {
65
- throw new Error(`waygraph pilot attach: no such session "${sessionId}" — run \`waygraph pilot sessions\` from the project dir`);
66
- }
67
- const graph = await discoverGraph(meta.projectDir, inject?.length ? { inject } : undefined);
68
- const status = await requestSession(meta.projectDir, sessionId, { op: "status" });
69
- if (!status.ok) {
70
- throw new Error(`waygraph pilot attach: session "${sessionId}" not reachable (${status.error})`);
71
- }
72
- return {
73
- sessionId: meta.sessionId,
74
- socketPath: meta.socketPath,
75
- headless: meta.headless,
76
- graph,
77
- snapshot: status.snapshot,
78
- };
79
- }
80
- export { listBrowserSessions };
@@ -1,14 +0,0 @@
1
- export type PracticeKind = "wildcard-checkpoint" | "assert-no-type-arg" | "multi-input" | "combined-action" | "empty-verify" | "overcomplex-selector" | "inline-selector-should-use-sel-file";
2
- export interface PracticeWarning {
3
- kind: PracticeKind;
4
- file: string;
5
- /** Short hint for humans/agents. */
6
- detail: string;
7
- }
8
- export interface PracticeCheckOptions {
9
- /** Skip all practice scanning (CLI `--no-practices`). */
10
- disabled?: boolean;
11
- }
12
- export declare function collectPracticeWarnings(projectDir: string, walkDir: (dir: string, re: RegExp) => string[], opts?: PracticeCheckOptions): PracticeWarning[];
13
- export declare function practiceKindLabel(kind: PracticeKind): string;
14
- export declare function formatPracticeWarnings(projectDir: string, warnings: PracticeWarning[]): string[];
@@ -1,195 +0,0 @@
1
- /**
2
- * `waygraph check` / `waygraph typecheck` practice warnings — style/typing issues
3
- * that compile but erode the typed graph. Warnings only (never fail exit code)
4
- * unless paired with `tsc` errors in `waygraph typecheck`.
5
- */
6
- import { readFileSync, readdirSync } from "node:fs";
7
- import { dirname, relative } from "node:path";
8
- /** define*Block<…Checkpoint<string>…> — prefer project Checkpoint types. */
9
- const WILDCARD_CHECKPOINT = /\bdefine(?:Method|Effect|Page|Nav|MemNav|NavClick|Action)Block\s*<[^>]*\bCheckpoint\s*<\s*string\s*>/;
10
- /** defineAssertBlock({ … }) with no explicit Out type — defaults to wildcard. */
11
- const ASSERT_NO_TYPE_ARG = /\bdefineAssertBlock\s*\(\s*\{/;
12
- /** defineAssertBlock, any form - used to scope the empty-verify check below. */
13
- const IS_ASSERT_BLOCK = /\bdefineAssertBlock\s*[<(]/;
14
- /**
15
- * define(Method|Effect)Block<In, Out> with two BARE identifier type args
16
- * (never a nested generic like Checkpoint<string> - that's WILDCARD_CHECKPOINT's
17
- * own warning) - lets a real transition (In !== Out) be told apart from a
18
- * self-loop (In === Out, e.g. fill-username) using only source text.
19
- */
20
- const METHOD_EFFECT_GENERIC = /\bdefine(?:Method|Effect)Block\s*<\s*([A-Za-z_$][\w$]*)\s*,\s*([A-Za-z_$][\w$]*)\s*>/;
21
- /** `verify: []` - a literal empty array, the codegen-stub shape this check exists for. */
22
- const EMPTY_VERIFY_ARRAY = /\bverify\s*:\s*\[\s*\]/;
23
- /** Any `verify:` key at all, empty or not. */
24
- const HAS_VERIFY_KEY = /\bverify\s*:/;
25
- const SCAN_GLOB = /\.(block|flow)\.ts$/;
26
- /**
27
- * A selector string reaching for a regex-based Playwright text pseudo-class (`:has-text(/…/)`,
28
- * `:text-matches(…)`) or a plain XPath - real, recurring pattern: an LLM asked to target a simple
29
- * element (one class, one id, one data-attribute) instead writes a regex/XPath from scratch. Not a
30
- * type error (Playwright's own selector syntax accepts all of this), so nothing else catches it.
31
- */
32
- const TEXT_MATCHES_PSEUDO = /:text-matches\(/;
33
- const HAS_TEXT_REGEX_PSEUDO = /:has-text\(\s*\//;
34
- const XPATH_LOCATOR = /\.locator\(\s*["'`](?:xpath=)?\/\//;
35
- /** A selector string literal inline in a Block file (`.locator("…")`, `click: "…"`, `url: "…"`) -
36
- * scoped to simple, single-token selectors (id/class/attr/tag) so this doesn't fire on the
37
- * legitimate multi-part selectors `.sel.ts` files themselves are made of. */
38
- const INLINE_SIMPLE_SELECTOR = /(?:\.locator|\bclick|\burl)\s*[:(]\s*["'`](#|\.)[\w-]+["'`]/;
39
- const METHOD_OR_EFFECT_FILE = /\.(method|effect)\.block\.ts$/;
40
- const METHOD_OR_EFFECT_DEFINE = /\bdefine(?:Method|Effect)Block\b/;
41
- /** Whole-file opt-out: `// waygraph-ignore-practices` */
42
- const IGNORE_ALL = /waygraph-ignore-practices/;
43
- /** Per-kind opt-out: `// waygraph-ignore: multi-input, combined-action` */
44
- const IGNORE_KINDS = /waygraph-ignore:\s*([^\n*]+)/;
45
- function walkBlockAndFlowFiles(projectDir, walkDir) {
46
- return walkDir(projectDir, SCAN_GLOB);
47
- }
48
- function ignoredKindsForFile(src) {
49
- if (IGNORE_ALL.test(src))
50
- return "all";
51
- const m = IGNORE_KINDS.exec(src);
52
- if (!m)
53
- return new Set();
54
- const kinds = new Set();
55
- for (const token of m[1].split(/[,;\s]+/)) {
56
- const t = token.trim();
57
- if (t)
58
- kinds.add(t);
59
- }
60
- return kinds;
61
- }
62
- function isIgnored(kind, ignore) {
63
- return ignore === "all" || ignore.has(kind);
64
- }
65
- function countMatches(src, re) {
66
- re.lastIndex = 0;
67
- return (src.match(re) ?? []).length;
68
- }
69
- export function collectPracticeWarnings(projectDir, walkDir, opts) {
70
- if (opts?.disabled)
71
- return [];
72
- const warnings = [];
73
- for (const file of walkBlockAndFlowFiles(projectDir, walkDir)) {
74
- const rel = relative(projectDir, file).replace(/\\/g, "/");
75
- const src = readFileSync(file, "utf-8");
76
- const ignore = ignoredKindsForFile(src);
77
- if (!isIgnored("wildcard-checkpoint", ignore) && WILDCARD_CHECKPOINT.test(src)) {
78
- warnings.push({
79
- kind: "wildcard-checkpoint",
80
- file: rel,
81
- detail: 'uses Checkpoint<string> in a Block helper generic — prefer a typed Checkpoint from src/states/ (e.g. defineMethodBlock<LoginPage, LoginPage>)',
82
- });
83
- }
84
- if (!isIgnored("assert-no-type-arg", ignore) && ASSERT_NO_TYPE_ARG.test(src)) {
85
- warnings.push({
86
- kind: "assert-no-type-arg",
87
- file: rel,
88
- detail: "defineAssertBlock({…}) without an explicit type argument — add defineAssertBlock<YourCheckpoint>({…}) so defineFlow typing stays honest",
89
- });
90
- }
91
- const isMethodOrEffect = METHOD_OR_EFFECT_FILE.test(rel) || METHOD_OR_EFFECT_DEFINE.test(src);
92
- if (isMethodOrEffect) {
93
- const fills = countMatches(src, /\.fill\s*\(/g);
94
- const clicks = countMatches(src, /\.click\s*\(/g);
95
- if (!isIgnored("multi-input", ignore) && fills >= 2) {
96
- warnings.push({
97
- kind: "multi-input",
98
- file: rel,
99
- detail: `Method/Effect act() has ${fills} .fill() calls — one distinct input per Block (split into separate defineMethodBlock files, e.g. fill-username + fill-password + submit-login)`,
100
- });
101
- }
102
- if (!isIgnored("combined-action", ignore) && fills >= 1 && clicks >= 1) {
103
- warnings.push({
104
- kind: "combined-action",
105
- file: rel,
106
- detail: "Method/Effect act() mixes .fill() and .click() — fill and submit must be separate Blocks (see examples/saucedemo login split)",
107
- });
108
- }
109
- const genericMatch = METHOD_EFFECT_GENERIC.exec(src);
110
- const isTransition = !!genericMatch && genericMatch[1] !== genericMatch[2];
111
- if (isTransition &&
112
- !isIgnored("empty-verify", ignore) &&
113
- (!HAS_VERIFY_KEY.test(src) || EMPTY_VERIFY_ARRAY.test(src))) {
114
- warnings.push({
115
- kind: "empty-verify",
116
- file: rel,
117
- detail: `transition Block (${genericMatch[1]} → ${genericMatch[2]}) has no verify checks — resolve() moving ` +
118
- "to a new Checkpoint is never confirmed by anything; add a Trait (or defineAssertBlock right after it), " +
119
- "or opt out explicitly with // waygraph-ignore: empty-verify if that's intentional",
120
- });
121
- }
122
- }
123
- if (!isIgnored("overcomplex-selector", ignore) &&
124
- (TEXT_MATCHES_PSEUDO.test(src) || HAS_TEXT_REGEX_PSEUDO.test(src) || XPATH_LOCATOR.test(src))) {
125
- const via = TEXT_MATCHES_PSEUDO.test(src)
126
- ? ":text-matches(...)"
127
- : HAS_TEXT_REGEX_PSEUDO.test(src)
128
- ? ":has-text(/regex/)"
129
- : "an XPath locator";
130
- warnings.push({
131
- kind: "overcomplex-selector",
132
- file: rel,
133
- detail: `uses ${via} — reach for a plain CSS selector (id/class/data-attribute, via a _sel.ts/` +
134
- "*.sel.ts export) instead of a regex/XPath match unless the DOM genuinely has no stable selector",
135
- });
136
- }
137
- if (!isIgnored("inline-selector-should-use-sel-file", ignore) && INLINE_SIMPLE_SELECTOR.test(src)) {
138
- // Two real, coexisting conventions: the Map layout's own `_sel.ts` (one per page folder, next
139
- // to `_nav`/`_page`/`_methods`) and the freeform layout's per-concern `<name>.sel.ts`.
140
- const siblingSelFile = readdirSync(dirname(file)).some((f) => f === "_sel.ts" || f.endsWith(".sel.ts"));
141
- if (siblingSelFile) {
142
- warnings.push({
143
- kind: "inline-selector-should-use-sel-file",
144
- file: rel,
145
- detail: "a selector string is inlined here, but this directory already has a _sel.ts / *.sel.ts file — " +
146
- "add/reuse the selector there instead of a new one-off literal",
147
- });
148
- }
149
- }
150
- if (!isIgnored("empty-verify", ignore) && IS_ASSERT_BLOCK.test(src) && EMPTY_VERIFY_ARRAY.test(src)) {
151
- warnings.push({
152
- kind: "empty-verify",
153
- file: rel,
154
- detail: "defineAssertBlock's verify array is empty — an assert Block whose only job is checking will pass " +
155
- "trivially forever; fill in real Traits or remove the stub",
156
- });
157
- }
158
- }
159
- return warnings;
160
- }
161
- export function practiceKindLabel(kind) {
162
- switch (kind) {
163
- case "wildcard-checkpoint":
164
- return "wildcard Checkpoint<string>";
165
- case "assert-no-type-arg":
166
- return "assert block missing type arg";
167
- case "multi-input":
168
- return "multiple inputs in one Block";
169
- case "combined-action":
170
- return "fill and click in one Block";
171
- case "empty-verify":
172
- return "empty verify — transition unconfirmed";
173
- case "overcomplex-selector":
174
- return "regex/XPath selector where a plain one would do";
175
- case "inline-selector-should-use-sel-file":
176
- return "inline selector — a _sel.ts/*.sel.ts file already exists here";
177
- default: {
178
- const _exhaustive = kind;
179
- return _exhaustive;
180
- }
181
- }
182
- }
183
- export function formatPracticeWarnings(projectDir, warnings) {
184
- const lines = [];
185
- for (const w of warnings) {
186
- lines.push(`waygraph practices: ${w.file} (${practiceKindLabel(w.kind)}) — ${w.detail}`);
187
- }
188
- if (warnings.length === 0) {
189
- lines.push(`waygraph practices: no bad-practice patterns under ${projectDir}`);
190
- }
191
- else {
192
- lines.push(`waygraph practices: ${warnings.length} bad-practice warning${warnings.length === 1 ? "" : "s"}`);
193
- }
194
- return lines;
195
- }
@@ -1,59 +0,0 @@
1
- export interface TraverseCoverageReport {
2
- version: 1;
3
- generatedAt: string;
4
- projectDir: string;
5
- parallel: number;
6
- /** Unique edge keys in the discovered graph (block names). */
7
- edgesTotal: number;
8
- /** Graph edges successfully walked this suite (after instance normalize). */
9
- edgesHit: number;
10
- /** edgesHit / edgesTotal (0 when total is 0). */
11
- ratio: number;
12
- /** Optional suite gate that was applied (0-1). */
13
- minEdgeCoverage?: number;
14
- /** true when minEdgeCoverage was set and ratio met it. */
15
- coveragePass?: boolean;
16
- /** Sorted graph edge keys that were hit. */
17
- hit: string[];
18
- /** Sorted graph edge keys never walked. */
19
- missed: string[];
20
- /** Raw worker hit keys (may include block::instanceId). */
21
- rawHit?: string[];
22
- workers?: Array<{
23
- traverseId: string;
24
- exitCode: number;
25
- steps: number;
26
- edgesHit: number;
27
- leaf?: string;
28
- }>;
29
- }
30
- /** Static graph edge key = Block runtime name. */
31
- export declare function edgeKeyFromGraphEdge(edge: {
32
- block: string;
33
- }): string;
34
- /** Collect unique edge keys from a WaygraphGraph-like edges list. */
35
- export declare function collectGraphEdgeKeys(edges: ReadonlyArray<{
36
- block: string;
37
- }>): string[];
38
- /**
39
- * Map a worker hit key onto the static graph key it covers.
40
- * `add-to-cart::sku-1` -> `add-to-cart` when that block is in the graph.
41
- */
42
- export declare function normalizeHitKey(hitKey: string, graphKeys: ReadonlySet<string>): string | null;
43
- /**
44
- * Parse --min-edge-coverage: `0.8`, `80%`, `80` (as percent when > 1).
45
- * Returns 0-1 fraction, or null when unset/invalid.
46
- */
47
- export declare function parseMinEdgeCoverage(raw: unknown): number | null;
48
- export declare function buildCoverageReport(opts: {
49
- projectDir: string;
50
- parallel: number;
51
- allEdgeKeys: readonly string[];
52
- hitKeys: ReadonlySet<string> | readonly string[];
53
- minEdgeCoverage?: number | null;
54
- workers?: TraverseCoverageReport["workers"];
55
- }): TraverseCoverageReport;
56
- /** Greppable one-liner for agents/CI. */
57
- export declare function formatCoverageLine(report: TraverseCoverageReport): string;
58
- export declare function defaultCoverageOutPath(projectDir: string): string;
59
- export declare function writeCoverageReport(path: string, report: TraverseCoverageReport): void;
@@ -1,127 +0,0 @@
1
- /**
2
- * Phase E: traverse edge coverage report + suite gate.
3
- * Coverage is independent of leaf PASS - a green leaf can still fail CI
4
- * when --min-edge-coverage is set and ratio is too low.
5
- *
6
- * Denominator = unique static graph edge block names (FF inners stay as their
7
- * own graph edges when discovered; RFC open Q deferred - no covered-via-prefix yet).
8
- * A hit of `block::instanceId` counts as covering `block`.
9
- */
10
- import { mkdirSync, writeFileSync } from "node:fs";
11
- import { dirname, join } from "node:path";
12
- /** Static graph edge key = Block runtime name. */
13
- export function edgeKeyFromGraphEdge(edge) {
14
- return edge.block;
15
- }
16
- /** Collect unique edge keys from a WaygraphGraph-like edges list. */
17
- export function collectGraphEdgeKeys(edges) {
18
- const set = new Set();
19
- for (const e of edges)
20
- set.add(edgeKeyFromGraphEdge(e));
21
- return [...set].sort();
22
- }
23
- /**
24
- * Map a worker hit key onto the static graph key it covers.
25
- * `add-to-cart::sku-1` -> `add-to-cart` when that block is in the graph.
26
- */
27
- export function normalizeHitKey(hitKey, graphKeys) {
28
- if (graphKeys.has(hitKey))
29
- return hitKey;
30
- const base = hitKey.includes("::") ? hitKey.slice(0, hitKey.indexOf("::")) : hitKey;
31
- if (graphKeys.has(base))
32
- return base;
33
- return null;
34
- }
35
- /**
36
- * Parse --min-edge-coverage: `0.8`, `80%`, `80` (as percent when > 1).
37
- * Returns 0-1 fraction, or null when unset/invalid.
38
- */
39
- export function parseMinEdgeCoverage(raw) {
40
- if (raw === undefined || raw === null || raw === "")
41
- return null;
42
- if (typeof raw === "number" && Number.isFinite(raw)) {
43
- if (raw < 0)
44
- return null;
45
- if (raw <= 1)
46
- return raw;
47
- if (raw <= 100)
48
- return raw / 100;
49
- return null;
50
- }
51
- if (typeof raw !== "string")
52
- return null;
53
- const t = raw.trim().toLowerCase();
54
- if (!t)
55
- return null;
56
- if (t.endsWith("%")) {
57
- const n = Number(t.slice(0, -1));
58
- if (!Number.isFinite(n) || n < 0 || n > 100)
59
- return null;
60
- return n / 100;
61
- }
62
- const n = Number(t);
63
- if (!Number.isFinite(n) || n < 0)
64
- return null;
65
- if (n <= 1)
66
- return n;
67
- if (n <= 100)
68
- return n / 100;
69
- return null;
70
- }
71
- export function buildCoverageReport(opts) {
72
- const all = [...new Set(opts.allEdgeKeys)].sort();
73
- const graphSet = new Set(all);
74
- const rawList = Array.isArray(opts.hitKeys) ? [...opts.hitKeys] : [...opts.hitKeys];
75
- const covered = new Set();
76
- for (const raw of rawList) {
77
- const n = normalizeHitKey(raw, graphSet);
78
- if (n)
79
- covered.add(n);
80
- }
81
- const hit = all.filter((k) => covered.has(k));
82
- const missed = all.filter((k) => !covered.has(k));
83
- const edgesTotal = all.length;
84
- const edgesHit = hit.length;
85
- const ratio = edgesTotal === 0 ? 0 : edgesHit / edgesTotal;
86
- const min = opts.minEdgeCoverage != null && Number.isFinite(opts.minEdgeCoverage)
87
- ? Math.min(1, Math.max(0, opts.minEdgeCoverage))
88
- : undefined;
89
- const coveragePass = min === undefined ? undefined : ratio + 1e-12 >= min;
90
- const coverageExtra = min !== undefined && coveragePass !== undefined
91
- ? { minEdgeCoverage: min, coveragePass }
92
- : {};
93
- return {
94
- version: 1,
95
- generatedAt: new Date().toISOString(),
96
- projectDir: opts.projectDir,
97
- parallel: opts.parallel,
98
- edgesTotal,
99
- edgesHit,
100
- ratio: Math.round(ratio * 10000) / 10000,
101
- ...coverageExtra,
102
- hit,
103
- missed,
104
- rawHit: [...new Set(rawList)].sort(),
105
- ...(opts.workers ? { workers: opts.workers } : {}),
106
- };
107
- }
108
- /** Greppable one-liner for agents/CI. */
109
- export function formatCoverageLine(report) {
110
- const pct = (report.ratio * 100).toFixed(1);
111
- const minPart = report.minEdgeCoverage !== undefined
112
- ? ` min=${(report.minEdgeCoverage * 100).toFixed(1)}%` +
113
- (report.coveragePass === false
114
- ? " FAIL"
115
- : report.coveragePass === true
116
- ? " PASS"
117
- : "")
118
- : "";
119
- return `[Coverage edges=${report.edgesHit}/${report.edgesTotal} ratio=${pct}%${minPart}]`;
120
- }
121
- export function defaultCoverageOutPath(projectDir) {
122
- return join(projectDir, ".waygraph-traverse", "coverage.json");
123
- }
124
- export function writeCoverageReport(path, report) {
125
- mkdirSync(dirname(path), { recursive: true });
126
- writeFileSync(path, JSON.stringify(report, null, 2) + "\n", "utf-8");
127
- }