waygraph 0.15.53 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (556) hide show
  1. package/README.md +8 -3
  2. package/bin/waygraph +2 -2
  3. package/dist/analysis/check.d.ts +38 -0
  4. package/dist/analysis/check.js +87 -0
  5. package/dist/analysis/coverage-gap.d.ts +1 -1
  6. package/dist/analysis/coverage-gap.js +14 -37
  7. package/dist/analysis/flow-source.d.ts +9 -0
  8. package/dist/analysis/flow-source.js +25 -0
  9. package/dist/analysis/graph.d.ts +13 -14
  10. package/dist/analysis/graph.js +48 -371
  11. package/dist/analysis/map-check.js +4 -39
  12. package/dist/analysis/practices-check.d.ts +1 -1
  13. package/dist/analysis/practices-check.js +24 -45
  14. package/dist/cli/args.d.ts +23 -0
  15. package/dist/cli/args.js +20 -0
  16. package/dist/{cli.d.ts → cli/cli.d.ts} +0 -1
  17. package/dist/{cli.js → cli/cli.js} +10 -9
  18. package/dist/{commands → cli/commands}/agent-dive-scaffold.js +35 -64
  19. package/dist/cli/commands/agent-dive.js +42 -0
  20. package/dist/{commands → cli/commands}/check.d.ts +0 -1
  21. package/dist/cli/commands/check.js +104 -0
  22. package/dist/cli/commands/codemod-checkpoints.d.ts +18 -0
  23. package/dist/cli/commands/codemod-checkpoints.js +186 -0
  24. package/dist/cli/commands/codemod-flows.d.ts +18 -0
  25. package/dist/cli/commands/codemod-flows.js +284 -0
  26. package/dist/cli/commands/codemod-stubs.d.ts +10 -0
  27. package/dist/cli/commands/codemod-stubs.js +187 -0
  28. package/dist/{commands → cli/commands}/extensions.js +5 -4
  29. package/dist/{commands → cli/commands}/init.js +1 -2
  30. package/dist/{commands → cli/commands}/list.js +9 -7
  31. package/dist/cli/commands/manifest.d.ts +2 -0
  32. package/dist/cli/commands/manifest.js +20 -0
  33. package/dist/cli/commands/map.js +57 -0
  34. package/dist/{commands → cli/commands}/run.d.ts +0 -1
  35. package/dist/cli/commands/run.js +64 -0
  36. package/dist/{commands → cli/commands}/session.js +61 -88
  37. package/dist/{commands → cli/commands}/test.js +11 -14
  38. package/dist/cli/commands/traverse.js +105 -0
  39. package/dist/{commands → cli/commands}/try.js +29 -25
  40. package/dist/{commands → cli/commands}/upgrade.js +40 -4
  41. package/dist/cli/flags.d.ts +193 -16
  42. package/dist/cli/flags.js +179 -234
  43. package/dist/cli/run-chain.d.ts +1 -0
  44. package/dist/cli/run-chain.js +42 -7
  45. package/dist/cli/usage.d.ts +1 -1
  46. package/dist/cli/usage.js +21 -53
  47. package/dist/cli/util.d.ts +2 -2
  48. package/dist/cli/util.js +2 -3
  49. package/dist/{highlights → demo/narration}/css.d.ts +1 -1
  50. package/dist/{highlights → demo/narration}/css.js +2 -3
  51. package/dist/{highlights → demo/narration}/demo-pace.d.ts +7 -11
  52. package/dist/{highlights → demo/narration}/demo-pace.js +9 -11
  53. package/dist/{highlights → demo/narration}/device.d.ts +4 -2
  54. package/dist/{highlights → demo/narration}/device.js +3 -1
  55. package/dist/demo/narration/merge.d.ts +8 -0
  56. package/dist/demo/narration/merge.js +71 -0
  57. package/dist/{highlights/run-phase.d.ts → demo/narration/narration.d.ts} +10 -14
  58. package/dist/{highlights/run-phase.js → demo/narration/narration.js} +25 -94
  59. package/dist/{highlights → demo/narration}/shorthand.d.ts +1 -1
  60. package/dist/demo/narration/stub-ctx.d.ts +8 -0
  61. package/dist/demo/narration/stub-ctx.js +164 -0
  62. package/dist/{highlights → demo/narration}/style.d.ts +1 -7
  63. package/dist/{highlights → demo/narration}/style.js +1 -41
  64. package/dist/{highlights → demo/narration}/todo-dock.d.ts +3 -3
  65. package/dist/{highlights → demo/narration}/todo-dock.js +13 -30
  66. package/dist/demo/overlay/auto-chrome.d.ts +7 -0
  67. package/dist/demo/overlay/auto-chrome.js +97 -0
  68. package/dist/{session/overlay-beacon.d.ts → demo/overlay/beacon.d.ts} +7 -0
  69. package/dist/{session/overlay-beacon.js → demo/overlay/beacon.js} +5 -0
  70. package/dist/demo/overlay/cursor.d.ts +12 -0
  71. package/dist/demo/overlay/cursor.js +142 -0
  72. package/dist/demo/overlay/device-stage.d.ts +13 -0
  73. package/dist/demo/overlay/device-stage.js +396 -0
  74. package/dist/demo/overlay/inpage/banner.d.ts +1 -0
  75. package/dist/demo/overlay/inpage/banner.js +160 -0
  76. package/dist/demo/overlay/inpage/caption.d.ts +2 -0
  77. package/dist/demo/overlay/inpage/caption.js +24 -0
  78. package/dist/demo/overlay/inpage/core.d.ts +1 -0
  79. package/dist/demo/overlay/inpage/core.js +345 -0
  80. package/dist/demo/overlay/inpage/device-chip.d.ts +1 -0
  81. package/dist/demo/overlay/inpage/device-chip.js +191 -0
  82. package/dist/demo/overlay/inpage/network.d.ts +9 -0
  83. package/dist/demo/overlay/inpage/network.js +200 -0
  84. package/dist/demo/overlay/inpage/panel-chrome.d.ts +1 -0
  85. package/dist/demo/overlay/inpage/panel-chrome.js +203 -0
  86. package/dist/demo/overlay/inpage/stamp.d.ts +1 -0
  87. package/dist/demo/overlay/inpage/stamp.js +46 -0
  88. package/dist/demo/overlay/inpage/swipe-zoom.d.ts +1 -0
  89. package/dist/demo/overlay/inpage/swipe-zoom.js +220 -0
  90. package/dist/demo/overlay/inpage/todos.d.ts +1 -0
  91. package/dist/demo/overlay/inpage/todos.js +294 -0
  92. package/dist/demo/overlay/locator-theater.d.ts +25 -0
  93. package/dist/demo/overlay/locator-theater.js +76 -0
  94. package/dist/demo/overlay/network-capture.d.ts +22 -0
  95. package/dist/demo/overlay/network-capture.js +127 -0
  96. package/dist/demo/overlay/overlay-css.d.ts +3 -0
  97. package/dist/demo/overlay/overlay-css.js +369 -0
  98. package/dist/demo/overlay/overlay-stage.d.ts +23 -0
  99. package/dist/demo/overlay/overlay-stage.js +106 -0
  100. package/dist/demo/overlay/overlay.d.ts +10 -0
  101. package/dist/demo/overlay/overlay.js +89 -0
  102. package/dist/{pilot-overlay/overlay-fixtures.d.ts → demo/overlay/phase-fixtures.d.ts} +2 -2
  103. package/dist/{pilot-overlay/overlay-fixtures.js → demo/overlay/phase-fixtures.js} +2 -2
  104. package/dist/{pilot-overlay/action-ring.js → demo/overlay/pilot/actions.js} +2 -1
  105. package/dist/{pilot-overlay → demo/overlay/pilot}/fixtures.d.ts +6 -5
  106. package/dist/{pilot-overlay → demo/overlay/pilot}/fixtures.js +19 -18
  107. package/dist/{pilot-overlay → demo/overlay/pilot}/shell.d.ts +2 -2
  108. package/dist/{pilot-overlay → demo/overlay/pilot}/shell.js +13 -22
  109. package/dist/demo/overlay/reattach.d.ts +7 -0
  110. package/dist/demo/overlay/reattach.js +23 -0
  111. package/dist/demo/overlay/rings.d.ts +33 -0
  112. package/dist/demo/overlay/rings.js +448 -0
  113. package/dist/{ui → demo/overlay/ui}/components/ring.js +2 -2
  114. package/dist/{ui → demo/overlay/ui}/overlay.css +4 -4
  115. package/dist/{ui → demo/overlay/ui}/shadow.d.ts +1 -1
  116. package/dist/{ui → demo/overlay/ui}/shadow.js +39 -2
  117. package/dist/demo/stepper/after.d.ts +3 -0
  118. package/dist/demo/stepper/after.js +113 -0
  119. package/dist/demo/stepper/banner-log.d.ts +37 -0
  120. package/dist/demo/stepper/banner-log.js +63 -0
  121. package/dist/demo/stepper/before.d.ts +4 -0
  122. package/dist/demo/stepper/before.js +110 -0
  123. package/dist/demo/stepper/demo-log.d.ts +31 -0
  124. package/dist/demo/stepper/demo-log.js +309 -0
  125. package/dist/demo/stepper/gate.d.ts +11 -0
  126. package/dist/demo/stepper/gate.js +78 -0
  127. package/dist/demo/stepper/interaction-patch.d.ts +3 -0
  128. package/dist/demo/stepper/interaction-patch.js +323 -0
  129. package/dist/demo/stepper/pacing.d.ts +21 -0
  130. package/dist/demo/stepper/pacing.js +23 -0
  131. package/dist/demo/stepper/slides.d.ts +11 -0
  132. package/dist/demo/stepper/slides.js +233 -0
  133. package/dist/demo/stepper/step-panels.d.ts +21 -0
  134. package/dist/demo/stepper/step-panels.js +589 -0
  135. package/dist/demo/stepper/stepper.d.ts +24 -0
  136. package/dist/demo/stepper/stepper.js +122 -0
  137. package/dist/demo/stepper/teardown.d.ts +48 -0
  138. package/dist/demo/stepper/teardown.js +179 -0
  139. package/dist/demo/stepper/todo-advance.d.ts +14 -0
  140. package/dist/demo/stepper/todo-advance.js +110 -0
  141. package/dist/demo/stepper/view.d.ts +68 -0
  142. package/dist/demo/stepper/view.js +31 -0
  143. package/dist/demo/types.d.ts +17 -0
  144. package/dist/demo/verbose-log.js +15 -0
  145. package/dist/{types.d.ts → engine/block/block.d.ts} +106 -91
  146. package/dist/{core → engine/block}/block.js +10 -53
  147. package/dist/{core → engine/block}/compose.d.ts +10 -7
  148. package/dist/{core → engine/block}/compose.js +1 -1
  149. package/dist/{core/blocks → engine/block/kinds}/api.d.ts +17 -12
  150. package/dist/{core/blocks → engine/block/kinds}/api.js +26 -18
  151. package/dist/{core/blocks → engine/block/kinds}/effect.d.ts +13 -18
  152. package/dist/engine/block/kinds/effect.js +17 -0
  153. package/dist/{core/blocks → engine/block/kinds}/method.d.ts +19 -29
  154. package/dist/{core/blocks → engine/block/kinds}/method.js +7 -21
  155. package/dist/{core/blocks → engine/block/kinds}/nav.d.ts +22 -31
  156. package/dist/{core/blocks → engine/block/kinds}/nav.js +6 -12
  157. package/dist/{core/blocks → engine/block/kinds}/page.d.ts +15 -20
  158. package/dist/{core/blocks → engine/block/kinds}/page.js +5 -7
  159. package/dist/engine/checkpoint/checkpoint.d.ts +22 -0
  160. package/dist/engine/checkpoint/checkpoint.js +8 -0
  161. package/dist/engine/checkpoint/route.d.ts +28 -0
  162. package/dist/engine/checkpoint/route.js +28 -0
  163. package/dist/{core → engine}/config.d.ts +7 -2
  164. package/dist/engine/config.js +6 -0
  165. package/dist/engine/engine.d.ts +45 -0
  166. package/dist/{core → engine}/engine.js +6 -10
  167. package/dist/engine/env.d.ts +59 -0
  168. package/dist/engine/env.js +83 -0
  169. package/dist/{errors.d.ts → engine/errors.d.ts} +23 -22
  170. package/dist/{errors.js → engine/errors.js} +22 -22
  171. package/dist/{core → engine/flow}/branch-regression.d.ts +8 -7
  172. package/dist/{core → engine/flow}/branch-regression.js +4 -3
  173. package/dist/engine/flow/flow.d.ts +162 -0
  174. package/dist/engine/flow/flow.js +244 -0
  175. package/dist/{core → engine/flow}/map-builder.d.ts +42 -40
  176. package/dist/{core → engine/flow}/map-builder.js +46 -48
  177. package/dist/{core → engine}/locate.d.ts +1 -1
  178. package/dist/{core → engine}/locate.js +1 -2
  179. package/dist/{mem-stub.d.ts → engine/mem/mem-stub.d.ts} +9 -8
  180. package/dist/{mem-stub.js → engine/mem/mem-stub.js} +2 -2
  181. package/dist/{mem-page.d.ts → engine/mem/mem.d.ts} +1 -1
  182. package/dist/{mem-page.js → engine/mem/mem.js} +2 -1
  183. package/dist/engine/page-gone.d.ts +5 -0
  184. package/dist/engine/page-gone.js +20 -0
  185. package/dist/engine/run/connect.d.ts +28 -0
  186. package/dist/{types.js → engine/run/connect.js} +11 -10
  187. package/dist/engine/run/events.d.ts +67 -0
  188. package/dist/engine/run/events.js +90 -0
  189. package/dist/engine/run/hooks.d.ts +16 -0
  190. package/dist/engine/run/hooks.js +8 -0
  191. package/dist/engine/run/launch.d.ts +13 -0
  192. package/dist/engine/run/launch.js +27 -0
  193. package/dist/{core/run-graph.d.ts → engine/run/run.d.ts} +9 -11
  194. package/dist/{core/run-graph.js → engine/run/run.js} +22 -11
  195. package/dist/engine/stub/pace.d.ts +12 -0
  196. package/dist/engine/stub/pace.js +2 -0
  197. package/dist/engine/stub/ring.d.ts +130 -0
  198. package/dist/engine/stub/ring.js +41 -0
  199. package/dist/engine/stub/stub.d.ts +268 -0
  200. package/dist/engine/stub/stub.js +1 -0
  201. package/dist/engine/stub/todos.d.ts +104 -0
  202. package/dist/engine/stub/todos.js +2 -0
  203. package/dist/engine/stub/viewport.d.ts +26 -0
  204. package/dist/engine/stub/viewport.js +2 -0
  205. package/dist/{trait.d.ts → engine/trait/trait.d.ts} +1 -1
  206. package/dist/index.d.ts +84 -36
  207. package/dist/index.js +44 -19
  208. package/dist/{session/auto-explore-run.d.ts → live/auto/auto.d.ts} +10 -16
  209. package/dist/{session/auto-explore-run.js → live/auto/auto.js} +164 -248
  210. package/dist/{session/auto-explore.d.ts → live/auto/explore.d.ts} +4 -14
  211. package/dist/{session/auto-explore.js → live/auto/explore.js} +21 -127
  212. package/dist/{auto-session/session.d.ts → live/auto-session/auto-session.d.ts} +1 -1
  213. package/dist/{auto-session/session.js → live/auto-session/auto-session.js} +27 -24
  214. package/dist/{auto-session → live/auto-session}/helpers.d.ts +16 -5
  215. package/dist/{auto-session → live/auto-session}/helpers.js +1 -1
  216. package/dist/{session/auto-session-ipc.d.ts → live/auto-session/ipc.d.ts} +7 -5
  217. package/dist/{session/auto-session-ipc.js → live/auto-session/ipc.js} +31 -16
  218. package/dist/{session/browser.d.ts → live/auto-session/start.d.ts} +1 -2
  219. package/dist/{session/browser.js → live/auto-session/start.js} +2 -3
  220. package/dist/{pilot-overlay → live/pilot}/panel.d.ts +1 -1
  221. package/dist/{pilot-overlay → live/pilot}/panel.js +23 -31
  222. package/dist/{session → live/pilot}/pilot.d.ts +4 -3
  223. package/dist/{session → live/pilot}/pilot.js +4 -4
  224. package/dist/{traverse → live/traverse}/coverage.d.ts +4 -0
  225. package/dist/{traverse → live/traverse}/coverage.js +3 -0
  226. package/dist/{traverse → live/traverse}/lease.d.ts +1 -0
  227. package/dist/{traverse → live/traverse}/lease.js +1 -0
  228. package/dist/{traverse/run.d.ts → live/traverse/traverse.d.ts} +4 -1
  229. package/dist/{traverse/run.js → live/traverse/traverse.js} +26 -43
  230. package/dist/manifest/manifest.d.ts +52 -0
  231. package/dist/manifest/manifest.js +93 -0
  232. package/dist/manifest/map-imports.d.ts +7 -0
  233. package/dist/manifest/map-imports.js +22 -0
  234. package/dist/manifest/maps.d.ts +33 -0
  235. package/dist/manifest/maps.js +62 -0
  236. package/dist/manifest/pack.d.ts +21 -0
  237. package/dist/manifest/pack.js +109 -0
  238. package/dist/manifest/project.d.ts +60 -0
  239. package/dist/manifest/project.js +101 -0
  240. package/dist/{session/block-inject.js → manifest/roots.js} +1 -18
  241. package/dist/manifest/scan.d.ts +19 -0
  242. package/dist/manifest/scan.js +57 -0
  243. package/dist/{blocks-select.d.ts → manifest/select.d.ts} +3 -0
  244. package/dist/{blocks-select.js → manifest/select.js} +2 -0
  245. package/dist/manifest/source.d.ts +23 -0
  246. package/dist/manifest/source.js +86 -0
  247. package/dist/runner/mode.d.ts +71 -0
  248. package/dist/runner/mode.js +1 -0
  249. package/dist/runner/modes/branches.d.ts +5 -0
  250. package/dist/runner/modes/branches.js +37 -0
  251. package/dist/runner/modes/demo.d.ts +3 -0
  252. package/dist/runner/modes/demo.js +13 -0
  253. package/dist/runner/modes/report.d.ts +2 -0
  254. package/dist/runner/modes/report.js +54 -0
  255. package/dist/runner/modes/run.d.ts +2 -0
  256. package/dist/runner/modes/run.js +3 -0
  257. package/dist/runner/options.d.ts +31 -0
  258. package/dist/runner/options.js +42 -0
  259. package/dist/runner/plan/find.d.ts +18 -0
  260. package/dist/runner/plan/find.js +65 -0
  261. package/dist/runner/plan/plan.d.ts +11 -0
  262. package/dist/runner/plan/plan.js +97 -0
  263. package/dist/runner/plan/seed-mem.d.ts +12 -0
  264. package/dist/runner/plan/seed-mem.js +98 -0
  265. package/dist/runner/plan/spec.d.ts +5 -0
  266. package/dist/runner/plan/spec.js +17 -0
  267. package/dist/runner/play-steps.d.ts +2 -0
  268. package/dist/runner/play-steps.js +59 -0
  269. package/dist/runner/runner.d.ts +4 -0
  270. package/dist/runner/runner.js +64 -0
  271. package/dist/runner/session.d.ts +9 -0
  272. package/dist/runner/session.js +87 -0
  273. package/dist/{browser.js → runtime/browser.js} +4 -2
  274. package/dist/{env-file.js → runtime/env-file.js} +7 -12
  275. package/dist/{extensions.d.ts → runtime/extensions.d.ts} +2 -5
  276. package/dist/{extensions.js → runtime/extensions.js} +3 -1
  277. package/dist/runtime/full-launch.d.ts +1 -0
  278. package/dist/runtime/full-launch.js +34 -0
  279. package/dist/runtime/global-flag.d.ts +5 -0
  280. package/dist/runtime/global-flag.js +18 -0
  281. package/dist/{playwright-config.d.ts → runtime/playwright-config.d.ts} +1 -1
  282. package/dist/{playwright.config.js → runtime/playwright.config.js} +3 -2
  283. package/dist/runtime/run-log.d.ts +2 -0
  284. package/dist/runtime/run-log.js +17 -0
  285. package/dist/{video-dir.js → runtime/video-dir.js} +3 -2
  286. package/dist/{config.d.ts → runtime/waygraph-config.d.ts} +8 -9
  287. package/dist/{config.js → runtime/waygraph-config.js} +21 -51
  288. package/dist/{webserver.js → runtime/webserver.js} +5 -30
  289. package/examples/routed-demo/config/waygraph.config.ts +20 -0
  290. package/examples/routed-demo/package.json +1 -4
  291. package/examples/routed-demo/scripts/fixture-server.mjs +1 -1
  292. package/examples/routed-demo/src/flows/routed-demo-map.flow.ts +2 -4
  293. package/examples/routed-demo/src/flows/routed-demo.flow.ts +2 -3
  294. package/examples/routed-demo/src/map/(app_base)/dashboard/_methods/click-widget.block.ts +5 -4
  295. package/examples/routed-demo/src/map/(app_base)/dashboard/_nav.block.ts +3 -3
  296. package/examples/routed-demo/src/map/(app_base)/dashboard/_page.block.ts +3 -3
  297. package/examples/routed-demo/src/map/(external)/docs/_nav.block.ts +3 -3
  298. package/examples/routed-demo/src/map/(external)/docs/_page.block.ts +3 -3
  299. package/examples/routed-demo/src/states/routed-demo.states.ts +5 -3
  300. package/examples/routed-demo/tests/routed-demo.spec.ts +4 -4
  301. package/examples/routed-demo/tsconfig.json +1 -1
  302. package/examples/saucedemo/README.md +11 -12
  303. package/examples/saucedemo/config/waygraph.config.ts +17 -0
  304. package/examples/saucedemo/docs/CONVENTION.md +5 -7
  305. package/examples/saucedemo/docs/HELPERS.md +12 -12
  306. package/examples/saucedemo/package-lock.json +10 -3
  307. package/examples/saucedemo/package.json +12 -29
  308. package/examples/saucedemo/src/blocks/SITE-MAP.md +0 -1
  309. package/examples/saucedemo/src/blocks/saucedemo-web/NAV.md +1 -5
  310. package/examples/saucedemo/src/blocks/saucedemo-web/cart/nav-cart.block.ts +3 -52
  311. package/examples/saucedemo/src/blocks/saucedemo-web/cart/nav-checkout-info.block.ts +3 -3
  312. package/examples/saucedemo/src/blocks/saucedemo-web/checkout-step-one/methods/fill-first-name.method.block.ts +5 -4
  313. package/examples/saucedemo/src/blocks/saucedemo-web/checkout-step-one/methods/fill-last-name.method.block.ts +5 -4
  314. package/examples/saucedemo/src/blocks/saucedemo-web/checkout-step-one/methods/fill-postal-code.method.block.ts +5 -4
  315. package/examples/saucedemo/src/blocks/saucedemo-web/checkout-step-one/methods/submit-checkout-info.method.block.ts +5 -4
  316. package/examples/saucedemo/src/blocks/saucedemo-web/checkout-step-two/methods/finish-order.method.block.ts +21 -27
  317. package/examples/saucedemo/src/blocks/saucedemo-web/inventory/inventory.page.block.ts +3 -9
  318. package/examples/saucedemo/src/blocks/saucedemo-web/inventory/methods/add-all-to-cart.method.block.ts +4 -6
  319. package/examples/saucedemo/src/blocks/saucedemo-web/inventory/methods/add-to-cart.effect.block.ts +10 -76
  320. package/examples/saucedemo/src/blocks/saucedemo-web/inventory/methods/remove-all-from-cart.method.block.ts +4 -6
  321. package/examples/saucedemo/src/blocks/saucedemo-web/inventory/methods/remove-from-cart.effect.block.ts +4 -3
  322. package/examples/saucedemo/src/blocks/saucedemo-web/inventory/nav-item-detail.block.ts +3 -3
  323. package/examples/saucedemo/src/blocks/saucedemo-web/inventory-item/nav-back-to-inventory.block.ts +3 -3
  324. package/examples/saucedemo/src/blocks/saucedemo-web/inventory-item/nav-back-to-products.block.ts +3 -3
  325. package/examples/saucedemo/src/blocks/saucedemo-web/inventory-item/nav-continue-shopping.block.ts +3 -3
  326. package/examples/saucedemo/src/blocks/saucedemo-web/methods/fill-password.method.block.ts +5 -29
  327. package/examples/saucedemo/src/blocks/saucedemo-web/methods/fill-username.method.block.ts +5 -48
  328. package/examples/saucedemo/src/blocks/saucedemo-web/methods/submit-login.method.block.ts +13 -77
  329. package/examples/saucedemo/src/blocks/saucedemo-web/methods/submit-logout.method.block.ts +5 -4
  330. package/examples/saucedemo/src/blocks/saucedemo-web/nav-login.block.ts +3 -3
  331. package/examples/saucedemo/src/flows/api-demo.flow.ts +26 -18
  332. package/examples/saucedemo/src/flows/cart-bulk.flow.ts +19 -14
  333. package/examples/saucedemo/src/flows/cart-continue.flow.ts +10 -8
  334. package/examples/saucedemo/src/flows/cart-mem.flow.ts +7 -7
  335. package/examples/saucedemo/src/flows/catalog-logout.flow.ts +13 -8
  336. package/examples/saucedemo/src/flows/checkout-then-browse-again.flow.ts +26 -48
  337. package/examples/saucedemo/src/flows/checkout.flow.ts +70 -86
  338. package/examples/saucedemo/src/flows/device-showcase.flow.ts +24 -25
  339. package/examples/saucedemo/src/flows/login.flow.ts +11 -18
  340. package/examples/saucedemo/src/flows/mem-stub-demo.flow.ts +9 -20
  341. package/examples/saucedemo/src/flows/shop.flow.ts +15 -20
  342. package/examples/saucedemo/src/flows/smoke.flow.ts +12 -27
  343. package/examples/saucedemo/src/flows/stub-on-error.flow.ts +24 -43
  344. package/examples/saucedemo/src/flows/viewer-blocked.flow.ts +26 -34
  345. package/examples/saucedemo/src/states/checkout.mem-stubs.ts +11 -0
  346. package/examples/saucedemo/src/states/checkout.states.ts +21 -11
  347. package/examples/saucedemo/src/stubs/device-showcase.ts +191 -0
  348. package/examples/saucedemo/src/stubs/login.ts +37 -0
  349. package/examples/saucedemo/tests/auto-graph.spec.ts +4 -12
  350. package/examples/saucedemo/tests/chain-flow-episodes.spec.ts +7 -9
  351. package/examples/saucedemo/tests/submit-login-branch.spec.ts +18 -5
  352. package/package.json +12 -7
  353. package/templates/agents/waygraph-planner.agent.md +2 -2
  354. package/templates/quickstart/README.md +4 -7
  355. package/templates/quickstart/config/waygraph.config.ts +17 -0
  356. package/templates/quickstart/docs/CONVENTION.md +5 -6
  357. package/templates/quickstart/docs/HELPERS.md +11 -9
  358. package/templates/quickstart/package.json +14 -17
  359. package/templates/quickstart/src/blocks/SITE-MAP.md +13 -3
  360. package/templates/quickstart/src/blocks/saucedemo-web/NAV.md +1 -5
  361. package/templates/quickstart/src/blocks/saucedemo-web/cart/nav-cart.block.ts +3 -52
  362. package/templates/quickstart/src/blocks/saucedemo-web/cart/nav-checkout-info.block.ts +3 -3
  363. package/templates/quickstart/src/blocks/saucedemo-web/checkout-step-one/methods/fill-first-name.method.block.ts +5 -4
  364. package/templates/quickstart/src/blocks/saucedemo-web/checkout-step-one/methods/fill-last-name.method.block.ts +5 -4
  365. package/templates/quickstart/src/blocks/saucedemo-web/checkout-step-one/methods/fill-postal-code.method.block.ts +5 -4
  366. package/templates/quickstart/src/blocks/saucedemo-web/checkout-step-one/methods/submit-checkout-info.method.block.ts +5 -4
  367. package/templates/quickstart/src/blocks/saucedemo-web/checkout-step-two/methods/finish-order.method.block.ts +21 -27
  368. package/templates/quickstart/src/blocks/saucedemo-web/inventory/inventory.page.block.ts +3 -9
  369. package/templates/quickstart/src/blocks/saucedemo-web/inventory/methods/add-all-to-cart.method.block.ts +4 -6
  370. package/templates/quickstart/src/blocks/saucedemo-web/inventory/methods/add-to-cart.effect.block.ts +10 -76
  371. package/templates/quickstart/src/blocks/saucedemo-web/inventory/methods/remove-all-from-cart.method.block.ts +4 -6
  372. package/templates/quickstart/src/blocks/saucedemo-web/inventory/methods/remove-from-cart.effect.block.ts +4 -3
  373. package/templates/quickstart/src/blocks/saucedemo-web/inventory/nav-item-detail.block.ts +3 -3
  374. package/templates/quickstart/src/blocks/saucedemo-web/inventory-item/nav-back-to-inventory.block.ts +3 -3
  375. package/templates/quickstart/src/blocks/saucedemo-web/inventory-item/nav-back-to-products.block.ts +3 -3
  376. package/templates/quickstart/src/blocks/saucedemo-web/inventory-item/nav-continue-shopping.block.ts +3 -3
  377. package/templates/quickstart/src/blocks/saucedemo-web/methods/fill-password.method.block.ts +5 -29
  378. package/templates/quickstart/src/blocks/saucedemo-web/methods/fill-username.method.block.ts +5 -48
  379. package/templates/quickstart/src/blocks/saucedemo-web/methods/submit-login.method.block.ts +13 -77
  380. package/templates/quickstart/src/blocks/saucedemo-web/methods/submit-logout.method.block.ts +5 -4
  381. package/templates/quickstart/src/blocks/saucedemo-web/nav-login.block.ts +3 -3
  382. package/templates/quickstart/src/flows/api-demo.flow.ts +45 -0
  383. package/templates/quickstart/src/flows/cart-bulk.flow.ts +19 -14
  384. package/templates/quickstart/src/flows/cart-continue.flow.ts +10 -8
  385. package/templates/quickstart/src/flows/cart-mem.flow.ts +7 -7
  386. package/templates/quickstart/src/flows/catalog-logout.flow.ts +13 -8
  387. package/templates/quickstart/src/flows/checkout-then-browse-again.flow.ts +26 -48
  388. package/templates/quickstart/src/flows/checkout.flow.ts +70 -63
  389. package/templates/quickstart/src/flows/device-showcase.flow.ts +24 -25
  390. package/templates/quickstart/src/flows/login.flow.ts +11 -18
  391. package/templates/quickstart/src/flows/mem-stub-demo.flow.ts +12 -0
  392. package/templates/quickstart/src/flows/shop.flow.ts +15 -20
  393. package/templates/quickstart/src/flows/smoke.flow.ts +12 -27
  394. package/templates/quickstart/src/flows/stub-on-error.flow.ts +31 -0
  395. package/templates/quickstart/src/flows/viewer-blocked.flow.ts +26 -34
  396. package/templates/quickstart/src/states/checkout.mem-stubs.ts +11 -0
  397. package/templates/quickstart/src/states/checkout.states.ts +21 -11
  398. package/templates/quickstart/src/stubs/device-showcase.ts +191 -0
  399. package/templates/quickstart/src/stubs/login.ts +37 -0
  400. package/templates/quickstart/tests/chain-flow.spec.ts +7 -10
  401. package/templates/scaffold/README.md +2 -1
  402. package/templates/scaffold/STRUCTURE.md +5 -4
  403. package/templates/scaffold/config/waygraph.config.ts +1 -0
  404. package/templates/scaffold/gitignore +1 -0
  405. package/templates/scaffold/src/flows/README.md +2 -2
  406. package/templates/scaffold/src/map/(app_base)/docs/_nav.block.ts +3 -3
  407. package/templates/scaffold/src/map/(app_base)/docs/_page.block.ts +3 -3
  408. package/templates/scaffold/src/map/(app_base)/home/_methods/add-item.effect.block.ts +4 -4
  409. package/templates/scaffold/src/map/(app_base)/home/_methods/assert-hello.method.block.ts +3 -3
  410. package/templates/scaffold/src/map/(app_base)/home/_methods/assert-item-added.method.block.ts +3 -3
  411. package/templates/scaffold/src/map/(app_base)/home/_methods/clear-cart.method.block.ts +5 -4
  412. package/templates/scaffold/src/map/(app_base)/home/_methods/remove-item.effect.block.ts +4 -4
  413. package/templates/scaffold/src/map/(app_base)/home/_nav.block.ts +3 -3
  414. package/templates/scaffold/src/map/(app_base)/home/_page.block.ts +3 -3
  415. package/templates/scaffold/src/map/(app_base)/home/nav-verification-link.block.ts +4 -4
  416. package/templates/scaffold/src/map/(external)/hoppscotch/_keys.ts +21 -0
  417. package/templates/scaffold/src/map/(external)/hoppscotch/_methods/assert-response-body.method.block.ts +4 -4
  418. package/templates/scaffold/src/map/(external)/hoppscotch/_methods/assert-response-header.method.block.ts +4 -4
  419. package/templates/scaffold/src/map/(external)/hoppscotch/_methods/assert-status.method.block.ts +4 -4
  420. package/templates/scaffold/src/map/(external)/hoppscotch/_methods/pick-extension-interceptor.method.block.ts +5 -4
  421. package/templates/scaffold/src/map/(external)/hoppscotch/_methods/read-response-body.method.block.ts +6 -5
  422. package/templates/scaffold/src/map/(external)/hoppscotch/_methods/read-response-headers.method.block.ts +6 -5
  423. package/templates/scaffold/src/map/(external)/hoppscotch/_methods/send-request.method.block.ts +5 -4
  424. package/templates/scaffold/src/map/(external)/hoppscotch/_methods/set-bearer-token.method.block.ts +6 -5
  425. package/templates/scaffold/src/map/(external)/hoppscotch/_methods/set-headers.method.block.ts +6 -5
  426. package/templates/scaffold/src/map/(external)/hoppscotch/_methods/set-json-body.method.block.ts +6 -5
  427. package/templates/scaffold/src/map/(external)/hoppscotch/_methods/set-method.method.block.ts +6 -5
  428. package/templates/scaffold/src/map/(external)/hoppscotch/_methods/set-query-params.method.block.ts +6 -5
  429. package/templates/scaffold/src/map/(external)/hoppscotch/_methods/set-url.method.block.ts +6 -5
  430. package/templates/scaffold/src/map/(external)/hoppscotch/_nav.block.ts +3 -3
  431. package/templates/scaffold/src/map/(external)/hoppscotch/_page.block.ts +3 -3
  432. package/templates/scaffold/src/map/(external)/hoppscotch/_states.ts +6 -0
  433. package/templates/scaffold/src/map/(external)/hoppscotch/settings/_nav.block.ts +3 -3
  434. package/templates/scaffold/src/map/(external)/mailpit/_keys.ts +13 -0
  435. package/templates/scaffold/src/map/(external)/mailpit/_methods/assert-email-content.method.block.ts +4 -4
  436. package/templates/scaffold/src/map/(external)/mailpit/_methods/assert-email-received.method.block.ts +4 -4
  437. package/templates/scaffold/src/map/(external)/mailpit/_methods/extract-email-link.method.block.ts +6 -5
  438. package/templates/scaffold/src/map/(external)/mailpit/_methods/open-message.method.block.ts +6 -5
  439. package/templates/scaffold/src/map/(external)/mailpit/_nav.block.ts +3 -3
  440. package/templates/scaffold/src/map/(external)/mailpit/_page.block.ts +3 -3
  441. package/templates/scaffold/src/map/(external)/mailpit/_states.ts +9 -0
  442. package/templates/scaffold/src/map/README.md +7 -0
  443. package/templates/scaffold/src/states/README.md +4 -1
  444. package/templates/scaffold/src/states/demo.mem-keys.ts +1 -29
  445. package/templates/scaffold/src/states/demo.states.ts +14 -20
  446. package/templates/scaffold/tests/hoppscotch.spec.ts +1 -11
  447. package/templates/scaffold/tests/mail-verify.spec.ts +2 -2
  448. package/templates/skills/waygraph-blind-pilot.skill.md +2 -6
  449. package/templates/skills/waygraph-convention.skill.md +23 -14
  450. package/templates/skills/waygraph-pilot.skill.md +7 -4
  451. package/dist/auto-session/verbose-log.js +0 -16
  452. package/dist/auto-session.d.ts +0 -2
  453. package/dist/auto-session.js +0 -3
  454. package/dist/cli/discover.d.ts +0 -40
  455. package/dist/cli/discover.js +0 -148
  456. package/dist/commands/agent-dive.js +0 -52
  457. package/dist/commands/check.js +0 -192
  458. package/dist/commands/map.js +0 -29
  459. package/dist/commands/run.js +0 -104
  460. package/dist/commands/traverse.js +0 -177
  461. package/dist/core/block.d.ts +0 -109
  462. package/dist/core/blocks/effect.js +0 -23
  463. package/dist/core/config.js +0 -17
  464. package/dist/core/engine.d.ts +0 -198
  465. package/dist/core/flow.d.ts +0 -293
  466. package/dist/core/flow.js +0 -432
  467. package/dist/core.d.ts +0 -14
  468. package/dist/core.js +0 -15
  469. package/dist/highlights/merge.d.ts +0 -8
  470. package/dist/highlights/merge.js +0 -173
  471. package/dist/highlights/stub-ctx.d.ts +0 -10
  472. package/dist/highlights/stub-ctx.js +0 -331
  473. package/dist/highlights/types.d.ts +0 -607
  474. package/dist/highlights.d.ts +0 -9
  475. package/dist/highlights.js +0 -10
  476. package/dist/pilot-overlay.d.ts +0 -5
  477. package/dist/pilot-overlay.js +0 -6
  478. package/dist/runner/banner-log.js +0 -63
  479. package/dist/runner/chain-run.js +0 -102
  480. package/dist/runner/cursor.js +0 -140
  481. package/dist/runner/demo-log.js +0 -316
  482. package/dist/runner/device-stage.d.ts +0 -9
  483. package/dist/runner/device-stage.js +0 -420
  484. package/dist/runner/discovery.js +0 -105
  485. package/dist/runner/index.js +0 -2
  486. package/dist/runner/inpage/banner.d.ts +0 -21
  487. package/dist/runner/inpage/banner.js +0 -156
  488. package/dist/runner/inpage/caption.d.ts +0 -3
  489. package/dist/runner/inpage/caption.js +0 -23
  490. package/dist/runner/inpage/core.d.ts +0 -4
  491. package/dist/runner/inpage/core.js +0 -316
  492. package/dist/runner/inpage/device.d.ts +0 -3
  493. package/dist/runner/inpage/device.js +0 -211
  494. package/dist/runner/inpage/network.d.ts +0 -15
  495. package/dist/runner/inpage/network.js +0 -217
  496. package/dist/runner/inpage/panel-chrome.js +0 -192
  497. package/dist/runner/inpage/stamp.js +0 -46
  498. package/dist/runner/inpage/swipe-zoom.js +0 -220
  499. package/dist/runner/inpage/todos.js +0 -337
  500. package/dist/runner/interaction-patch.js +0 -384
  501. package/dist/runner/main.js +0 -469
  502. package/dist/runner/network-capture.d.ts +0 -9
  503. package/dist/runner/network-capture.js +0 -126
  504. package/dist/runner/overlay-css.d.ts +0 -3
  505. package/dist/runner/overlay-css.js +0 -377
  506. package/dist/runner/overlay-install.js +0 -90
  507. package/dist/runner/overlay-stage.js +0 -110
  508. package/dist/runner/rings.js +0 -514
  509. package/dist/runner/seed-mem.js +0 -110
  510. package/dist/runner/slides.js +0 -278
  511. package/dist/runner/step-mode.js +0 -703
  512. package/dist/runner/step-panels.js +0 -729
  513. package/dist/runner/teardown.js +0 -202
  514. package/dist/runner/todo-dock.js +0 -142
  515. package/dist/session/step-overlay.d.ts +0 -37
  516. package/dist/session/step-overlay.js +0 -244
  517. package/examples/routed-demo/playwright.config.ts +0 -21
  518. package/examples/saucedemo/playwright.config.ts +0 -19
  519. package/examples/saucedemo/scripts/drive-auto-cli.mjs +0 -93
  520. package/examples/saucedemo/scripts/prove-add-to-cart-menu.mjs +0 -126
  521. package/examples/saucedemo/scripts/prove-auto-graph.mjs +0 -92
  522. package/examples/saucedemo/scripts/prove-wrong-login-runtime.mjs +0 -63
  523. package/examples/saucedemo/src/blocks/saucedemo-web/ff-owner-auth.block.ts +0 -22
  524. package/templates/quickstart/playwright.config.ts +0 -14
  525. package/templates/quickstart/scripts/drive-auto-cli.mjs +0 -93
  526. package/templates/quickstart/src/blocks/saucedemo-web/ff-owner-auth.block.ts +0 -22
  527. /package/dist/{commands → cli/commands}/agent-dive-scaffold.d.ts +0 -0
  528. /package/dist/{commands → cli/commands}/agent-dive.d.ts +0 -0
  529. /package/dist/{commands → cli/commands}/extensions.d.ts +0 -0
  530. /package/dist/{commands → cli/commands}/init.d.ts +0 -0
  531. /package/dist/{commands → cli/commands}/list.d.ts +0 -0
  532. /package/dist/{commands → cli/commands}/map.d.ts +0 -0
  533. /package/dist/{commands → cli/commands}/session.d.ts +0 -0
  534. /package/dist/{commands → cli/commands}/test.d.ts +0 -0
  535. /package/dist/{commands → cli/commands}/traverse.d.ts +0 -0
  536. /package/dist/{commands → cli/commands}/try.d.ts +0 -0
  537. /package/dist/{commands → cli/commands}/upgrade.d.ts +0 -0
  538. /package/dist/{highlights → demo/narration}/shorthand.js +0 -0
  539. /package/dist/{pilot-overlay/action-ring.d.ts → demo/overlay/pilot/actions.d.ts} +0 -0
  540. /package/dist/{ui → demo/overlay/ui}/components/ring.d.ts +0 -0
  541. /package/dist/{ui → demo/overlay/ui}/stylesheet.d.ts +0 -0
  542. /package/dist/{ui → demo/overlay/ui}/stylesheet.js +0 -0
  543. /package/dist/{ui → demo/overlay/ui}/tokens.d.ts +0 -0
  544. /package/dist/{ui → demo/overlay/ui}/tokens.js +0 -0
  545. /package/dist/{highlights → demo}/types.js +0 -0
  546. /package/dist/{auto-session → demo}/verbose-log.d.ts +0 -0
  547. /package/dist/{selector.d.ts → engine/trait/selector.d.ts} +0 -0
  548. /package/dist/{selector.js → engine/trait/selector.js} +0 -0
  549. /package/dist/{trait.js → engine/trait/trait.js} +0 -0
  550. /package/dist/{session/block-inject.d.ts → manifest/roots.d.ts} +0 -0
  551. /package/dist/{browser.d.ts → runtime/browser.d.ts} +0 -0
  552. /package/dist/{env-file.d.ts → runtime/env-file.d.ts} +0 -0
  553. /package/dist/{playwright-config.js → runtime/playwright-config.js} +0 -0
  554. /package/dist/{playwright.config.d.ts → runtime/playwright.config.d.ts} +0 -0
  555. /package/dist/{video-dir.d.ts → runtime/video-dir.d.ts} +0 -0
  556. /package/dist/{webserver.d.ts → runtime/webserver.d.ts} +0 -0
@@ -0,0 +1,284 @@
1
+ // `waygraph upgrade --codemod flows`: rewrites `defineFlow([start, ...Blocks, end], options)`, `chainFlow(...)` and the
2
+ // flow wrappers (`withTitle`, `withMemStub`, `withSessionReset`, `withExpectedFailure`, `withDemoPace`,
3
+ // `withHighlightStyle`, `withBlockPace`, `withStub*`) into `map()` chains. Works on the TypeScript AST (ts-morph); each
4
+ // Block's kind (nav, method, assert, ...) comes from the project's own runtime scan, so it picks the right step method.
5
+ // The same pass moves ctx stubs onto their one form (codemod-stubs.ts).
6
+ import { existsSync } from "node:fs";
7
+ import { join, relative } from "node:path";
8
+ import { Node, Project, SyntaxKind } from "ts-morph";
9
+ import { scanProject } from "../../manifest/project.js";
10
+ import { walkDir } from "../../manifest/scan.js";
11
+ import { convertStubs } from "./codemod-stubs.js";
12
+ const SETTINGS = {
13
+ withMemStub: () => "memStub: true",
14
+ withSessionReset: () => "sessionReset: true",
15
+ withExpectedFailure: (a) => `expectedFailure: ${a}`,
16
+ withDemoPace: (a) => `demoPace: ${a}`,
17
+ withHighlightStyle: (a) => `highlightStyle: ${a}`,
18
+ };
19
+ const STUBS = { withStubBefore: "stubBefore", withStubAfter: "stubAfter", withStubOnError: "stubOnError" };
20
+ const REMOVED = new Set(["start", "end", "chainFlow", "withTitle", "withBlockPace", "withHighlightFixtures", ...Object.keys(SETTINGS), ...Object.keys(STUBS)]);
21
+ const STEP = { nav: "gotoPage", page: "gotoPage", method: "method", effect: "method", api: "method", assert: "assert" };
22
+ /** The Block identifier an element of a flow is built from: `X`, `X.stubBefore(...)`, `withVerify(X, ...)`. */
23
+ function rootIdentifier(expr) {
24
+ if (Node.isIdentifier(expr))
25
+ return expr;
26
+ if (Node.isCallExpression(expr)) {
27
+ const callee = expr.getExpression();
28
+ if (Node.isPropertyAccessExpression(callee))
29
+ return rootIdentifier(callee.getExpression());
30
+ if (Node.isIdentifier(callee) && callee.getText() === "withVerify")
31
+ return expr.getArguments()[0] && rootIdentifier(expr.getArguments()[0]);
32
+ }
33
+ return undefined;
34
+ }
35
+ /** Where an identifier is declared: its file and exported name, following imports. */
36
+ function declarationOf(id) {
37
+ let symbol = id.getSymbol();
38
+ if (!symbol)
39
+ return undefined;
40
+ if (symbol.isAlias())
41
+ symbol = symbol.getAliasedSymbol() ?? symbol;
42
+ const decl = symbol.getDeclarations()[0];
43
+ if (!decl)
44
+ return undefined;
45
+ return { file: decl.getSourceFile().getFilePath(), name: symbol.getName() };
46
+ }
47
+ /** `engine.map({...}).start()...end()`: the `.map(...)` call at the root of a chain, or undefined. */
48
+ function mapCallOf(expr) {
49
+ let cur = expr;
50
+ while (Node.isCallExpression(cur)) {
51
+ const callee = cur.getExpression();
52
+ if (!Node.isPropertyAccessExpression(callee))
53
+ return undefined;
54
+ if (callee.getName() === "map")
55
+ return cur;
56
+ cur = callee.getExpression();
57
+ }
58
+ return undefined;
59
+ }
60
+ /** The first step call after `.map(...)`/`.start()` in a chain. */
61
+ function firstStepOf(mapCall) {
62
+ let parent = mapCall.getParent();
63
+ while (parent && Node.isPropertyAccessExpression(parent)) {
64
+ const call = parent.getParent();
65
+ if (!call || !Node.isCallExpression(call))
66
+ return undefined;
67
+ if (parent.getName() !== "start")
68
+ return call;
69
+ parent = call.getParent();
70
+ }
71
+ return undefined;
72
+ }
73
+ function addSetting(mapCall, setting) {
74
+ const arg = mapCall.getArguments()[0];
75
+ if (arg && Node.isObjectLiteralExpression(arg)) {
76
+ const inner = arg.getText().slice(1, -1).trim().replace(/,$/, "");
77
+ arg.replaceWithText(`{ ${inner ? `${inner}, ` : ""}${setting} }`);
78
+ }
79
+ else if (!arg) {
80
+ mapCall.addArgument(`{ ${setting} }`);
81
+ }
82
+ else {
83
+ arg.replaceWithText(`{ ...${arg.getText()}, ${setting} }`);
84
+ }
85
+ }
86
+ function addTitle(step, title) {
87
+ const block = step.getArguments()[0];
88
+ if (block)
89
+ block.replaceWithText(titleStub(block.getText(), title, indentOf(step)));
90
+ }
91
+ /** `engine` when the file has one in scope, else the standalone `map` export (imported from waygraph). */
92
+ function mapRoot(sf, needsMap) {
93
+ const hasEngine = sf.getImportDeclarations().some((d) => d.getNamedImports().some((n) => (n.getAliasNode()?.getText() ?? n.getName()) === "engine"))
94
+ || sf.getVariableDeclaration("engine") !== undefined;
95
+ if (hasEngine)
96
+ return "engine.map";
97
+ needsMap.add(sf);
98
+ return "map";
99
+ }
100
+ /** The indentation of the statement a node sits in, so a rewritten chain lines up with the code around it. */
101
+ function indentOf(node) {
102
+ const statement = node.getFirstAncestor((a) => Node.isStatement(a) || Node.isSourceFile(a.getParentOrThrow())) ?? node;
103
+ return " ".repeat(statement.getIndentationLevel() * 2);
104
+ }
105
+ function titleStub(block, title, indent) {
106
+ return `${block}.stubBefore((ctx) => {\n${indent} ctx.title(${title});\n${indent} })`;
107
+ }
108
+ function chain(head, steps, indent) {
109
+ return [head, ...steps, ".end()"].join(`\n${indent} `);
110
+ }
111
+ /** Rewrites one call if it is one of the old forms; returns a problem message when it can't. */
112
+ function rewrite(call, kindOf, needsMap) {
113
+ const sf = call.getSourceFile();
114
+ const callee = call.getExpression();
115
+ const args = call.getArguments();
116
+ const name = Node.isIdentifier(callee) ? callee.getText() : undefined;
117
+ const indent = indentOf(call);
118
+ if (Node.isPropertyAccessExpression(callee) && callee.getName() === "defineFlow") {
119
+ const list = args[0];
120
+ if (!list || !Node.isArrayLiteralExpression(list))
121
+ return "defineFlow without an array literal";
122
+ const elements = list.getElements().filter((e) => e.getText() !== "start" && e.getText() !== "end");
123
+ const steps = [];
124
+ for (const el of elements) {
125
+ let block = el;
126
+ let opts = "";
127
+ if (Node.isCallExpression(el) && el.getExpression().getText() === "withBlockPace") {
128
+ block = el.getArguments()[0];
129
+ opts = `, { pace: ${el.getArguments()[1]?.getText()} }`;
130
+ }
131
+ const id = rootIdentifier(block);
132
+ const decl = id && declarationOf(id);
133
+ const kind = decl && kindOf(decl.file, decl.name);
134
+ const step = kind && STEP[kind];
135
+ if (!step)
136
+ return `${el.getText().split("\n")[0]} is not a Block from a define*Block factory (kind: ${kind ?? "unknown"}); map() can't take it - rebuild it with a factory or nest it with .flow()`;
137
+ const external = step === "gotoPage" && /[\\/]\(external\)[\\/]/.test(decl.file);
138
+ steps.push(`.${external ? "gotoExternal" : step}(${block.getText()}${opts})`);
139
+ }
140
+ const options = args[1];
141
+ let settings = "";
142
+ let title;
143
+ if (options) {
144
+ if (!Node.isObjectLiteralExpression(options))
145
+ return "defineFlow options that aren't an object literal";
146
+ const kept = [];
147
+ for (const p of options.getProperties()) {
148
+ if (Node.isPropertyAssignment(p) && p.getName() === "title")
149
+ title = p.getInitializer().getText();
150
+ else
151
+ kept.push(p.getText());
152
+ }
153
+ if (kept.length)
154
+ settings = `{ ${kept.join(", ")} }`;
155
+ }
156
+ if (title && steps[0])
157
+ steps[0] = steps[0].replace(/^(\.\w+\()(.*)\)$/s, (_all, head, block) => `${head}${titleStub(block, title, indent)})`);
158
+ call.replaceWithText(chain(`${callee.getExpression().getText()}.map(${settings})`, [".start()", ...steps], indent));
159
+ return "changed";
160
+ }
161
+ if (name === "chainFlow") {
162
+ call.replaceWithText(chain(`${mapRoot(sf, needsMap)}()`, [".start()", ...args.map((a) => `.flow(${a.getText()})`)], indent));
163
+ return "changed";
164
+ }
165
+ if (name && STUBS[name] && args.length === 2) {
166
+ call.replaceWithText(`${args[0].getText()}.${STUBS[name]}(${args[1].getText()})`);
167
+ return "changed";
168
+ }
169
+ if (name && (SETTINGS[name] || name === "withTitle") && args[0]) {
170
+ const flow = args[0];
171
+ const mapCall = mapCallOf(flow);
172
+ if (name === "withTitle") {
173
+ const first = mapCall && firstStepOf(mapCall);
174
+ if (!first)
175
+ return `withTitle(${flow.getText().split("\n")[0]}, …): name the flow with ctx.title(…) in a stub on its first step`;
176
+ addTitle(first, args[1].getText());
177
+ }
178
+ else if (mapCall) {
179
+ addSetting(mapCall, SETTINGS[name](args[1]?.getText()));
180
+ }
181
+ else {
182
+ call.replaceWithText(chain(`${mapRoot(sf, needsMap)}({ ${SETTINGS[name](args[1]?.getText())} })`, [".start()", `.flow(${flow.getText()})`], indent));
183
+ return "changed";
184
+ }
185
+ call.replaceWithText(flow.getText());
186
+ return "changed";
187
+ }
188
+ if (name === "withHighlightFixtures")
189
+ return "withHighlightFixtures: chain ctx stubs on each Block where the flow uses it (Block.stubAfter((ctx) => …))";
190
+ if (name === "withBlockPace")
191
+ return "withBlockPace outside a flow: use the step option .method(Block, { pace })";
192
+ if (Node.isPropertyAccessExpression(callee) && callee.getName() === "end" && args[0] && mapCallOf(call)) {
193
+ const options = args[0];
194
+ if (Node.isObjectLiteralExpression(options)) {
195
+ const mapCall = mapCallOf(call);
196
+ for (const p of options.getProperties())
197
+ addSetting(mapCall, p.getText());
198
+ options.replaceWithText("");
199
+ call.replaceWithText(call.getText().replace(/\.end\(\s*\)$/, ".end()"));
200
+ return "changed";
201
+ }
202
+ }
203
+ return undefined;
204
+ }
205
+ /** Rewrites the old flow forms in a project's source files; returns problems it left for a person. */
206
+ export function convertFlows(project, kindOf) {
207
+ const changed = new Set();
208
+ const problems = [];
209
+ const needsMap = new Set();
210
+ for (const sf of project.getSourceFiles()) {
211
+ // One rewrite per pass, innermost calls first, so a wrapper sees the map() chain its argument became. Calls left
212
+ // for a person never change, so the final pass (nothing left to rewrite) lists each of them once.
213
+ const rewritten = new Set();
214
+ for (;;) {
215
+ let progressed = false;
216
+ const left = [];
217
+ for (const call of sf.getDescendantsOfKind(SyntaxKind.CallExpression).reverse()) {
218
+ if (call.wasForgotten())
219
+ continue;
220
+ const top = sf.getStatements().indexOf(call.getFirstAncestor((a) => a.getParent() === sf));
221
+ const result = rewrite(call, kindOf, needsMap);
222
+ if (result === "changed") {
223
+ changed.add(sf);
224
+ rewritten.add(top);
225
+ progressed = true;
226
+ break;
227
+ }
228
+ if (result)
229
+ left.push({ file: sf.getFilePath(), line: call.getStartLineNumber(), reason: result });
230
+ }
231
+ if (!progressed) {
232
+ problems.push(...left.reverse());
233
+ break;
234
+ }
235
+ }
236
+ if (!changed.has(sf))
237
+ continue;
238
+ // Replacing nested calls leaves odd indentation behind; TypeScript's formatter tidies just the rewritten statements.
239
+ const statements = sf.getStatements();
240
+ for (const i of rewritten)
241
+ statements[i]?.formatText({ indentSize: 2, convertTabsToSpaces: true });
242
+ for (const imp of sf.getImportDeclarations()) {
243
+ if (imp.getModuleSpecifierValue() !== "waygraph")
244
+ continue;
245
+ for (const n of imp.getNamedImports()) {
246
+ const local = n.getAliasNode()?.getText() ?? n.getName();
247
+ const stillUsed = sf.getDescendantsOfKind(SyntaxKind.Identifier).some((i) => {
248
+ const parent = i.getParent();
249
+ if (i.getText() !== local || Node.isImportSpecifier(parent))
250
+ return false;
251
+ return !(Node.isPropertyAccessExpression(parent) && parent.getNameNode() === i);
252
+ });
253
+ if (REMOVED.has(n.getName()) && !stillUsed)
254
+ n.remove();
255
+ }
256
+ if (needsMap.has(sf) && !imp.getNamedImports().some((n) => n.getName() === "map"))
257
+ imp.addNamedImport("map");
258
+ if (imp.getNamedImports().length === 0 && !imp.getDefaultImport() && !imp.getNamespaceImport())
259
+ imp.remove();
260
+ }
261
+ }
262
+ return { changed: [...changed], problems };
263
+ }
264
+ /** Runs the codemod over a project's TypeScript files, using its runtime scan for each Block's kind. */
265
+ export async function codemodFlows(projectDir) {
266
+ const scan = await scanProject(projectDir, { flows: false, maps: false });
267
+ const kinds = new Map(scan.blocks.map((b) => [`${b.absFile}#${b.exportName}`, b.kind]));
268
+ // Compiler options from the project's tsconfig; files from walkDir, which skips node_modules, dist and .git.
269
+ const tsconfig = join(projectDir, "tsconfig.json");
270
+ const project = new Project({ ...(existsSync(tsconfig) ? { tsConfigFilePath: tsconfig } : {}), skipAddingFilesFromTsConfig: true });
271
+ for (const file of walkDir(projectDir, /\.ts$/))
272
+ if (!file.endsWith(".d.ts"))
273
+ project.addSourceFileAtPath(file);
274
+ const flows = convertFlows(project, (file, name) => kinds.get(`${file}#${name}`));
275
+ const stubs = convertStubs(project);
276
+ const changed = [...new Set([...flows.changed, ...stubs.changed])];
277
+ const problems = [...flows.problems, ...stubs.problems];
278
+ for (const sf of changed)
279
+ sf.saveSync();
280
+ return {
281
+ changed: changed.map((sf) => relative(projectDir, sf.getFilePath())),
282
+ problems: problems.map((p) => `${relative(projectDir, p.file)}:${p.line}: ${p.reason}`),
283
+ };
284
+ }
@@ -0,0 +1,10 @@
1
+ import type { Project, SourceFile } from "ts-morph";
2
+ /** Rewrites the old stub forms in every file; returns the files it changed and the calls left for a person. */
3
+ export declare function convertStubs(project: Project): {
4
+ changed: SourceFile[];
5
+ problems: {
6
+ file: string;
7
+ line: number;
8
+ reason: string;
9
+ }[];
10
+ };
@@ -0,0 +1,187 @@
1
+ // Part of `waygraph upgrade --codemod flows`: moves ctx stubs onto the one form each thing has in 0.16.0. The list-only
2
+ // `ctx.todos([...])` and its setters (`todoId`, `todoTitle`, `todoStyle`, `todoPos`, `todoIndex`) become
3
+ // `ctx.todos(id, items, { title, style, pos, index })`; `todoGroups(groups)` gets the same id and options; the method
4
+ // aliases (`banner`, `bannerPos`, `clearDevice`, `clearTodos`, `landscape`, `portrait`, `todoDockFull`) become the
5
+ // names they stood for. A stub written as a slot map (`{ email: { selector, label } }`) becomes a function of
6
+ // `ctx.ring` calls, and a stub set in a `define*Block({ ... })` (options or instruction) moves out to a chained
7
+ // `.stubBefore(...)` on the Block. Works on the TypeScript AST (ts-morph).
8
+ import { Node, SyntaxKind } from "ts-morph";
9
+ const RENAMED = {
10
+ banner: (a) => `title(${a.join(", ")})`,
11
+ bannerPos: (a) => `titlePos(${a.join(", ")})`,
12
+ clearDevice: () => "hideDevice()",
13
+ clearTodos: () => "hideTodos()",
14
+ landscape: () => 'orientation("landscape")',
15
+ portrait: () => 'orientation("portrait")',
16
+ todoDockFull: () => "todoDockUi({ compact: false, collision: false, behindRing: false })",
17
+ };
18
+ /** The setters that fold into `todos(id, items, opts)`, and the option each one becomes. */
19
+ const DOCK_SETTERS = { todoId: "id", todoTitle: "title", todoStyle: "style", todoPos: "pos", todoIndex: "index" };
20
+ const DEFAULT_DOCK_ID = '"todos"';
21
+ /** `ctx.method(...)` as a statement on its own: the receiver, the method and the call. */
22
+ function ctxCall(statement) {
23
+ if (!Node.isExpressionStatement(statement))
24
+ return undefined;
25
+ const call = statement.getExpression();
26
+ if (!Node.isCallExpression(call))
27
+ return undefined;
28
+ const callee = call.getExpression();
29
+ if (!Node.isPropertyAccessExpression(callee) || !Node.isIdentifier(callee.getExpression()))
30
+ return undefined;
31
+ return { receiver: callee.getExpression().getText(), method: callee.getName(), call };
32
+ }
33
+ /** Whether `receiver` is a stub's ctx: typed as StubCtx, or the first parameter of a function passed to a stub phase. */
34
+ function isStubCtx(call, receiver) {
35
+ const fn = call.getFirstAncestor((a) => Node.isArrowFunction(a) || Node.isFunctionExpression(a) || Node.isFunctionDeclaration(a) || Node.isMethodDeclaration(a));
36
+ if (!fn || !(Node.isArrowFunction(fn) || Node.isFunctionExpression(fn) || Node.isFunctionDeclaration(fn) || Node.isMethodDeclaration(fn)))
37
+ return false;
38
+ const param = fn.getParameters()[0];
39
+ if (!param || param.getName() !== receiver)
40
+ return false;
41
+ if (/StubCtx/.test(param.getType().getText(param)))
42
+ return true;
43
+ const parent = fn.getParent();
44
+ const callee = Node.isCallExpression(parent) ? parent.getExpression() : undefined;
45
+ if (Node.isPropertyAccessExpression(callee) && /^stub(Before|After|OnError)$/.test(callee.getName()))
46
+ return true;
47
+ return Node.isPropertyAssignment(parent) && /^stub(Before|After|OnError)$/.test(parent.getName());
48
+ }
49
+ /** Todo items written with the old `name` key get `id`. */
50
+ function renameItemNames(items) {
51
+ for (const obj of items.getDescendantsOfKind(SyntaxKind.ObjectLiteralExpression)) {
52
+ const name = obj.getProperty("name");
53
+ if (Node.isPropertyAssignment(name) && !obj.getProperty("id"))
54
+ name.getNameNode().replaceWithText("id");
55
+ }
56
+ }
57
+ /** Rewrites one statement list; returns whether anything changed and the calls it could not convert. */
58
+ function convertStatements(statements, problems) {
59
+ const calls = statements.map(ctxCall);
60
+ let changed = false;
61
+ const consumed = new Set();
62
+ calls.forEach((c, i) => {
63
+ if (!c || !isStubCtx(c.call, c.receiver))
64
+ return;
65
+ const args = c.call.getArguments().map((a) => a.getText());
66
+ if (RENAMED[c.method]) {
67
+ c.call.replaceWithText(`${c.receiver}.${RENAMED[c.method](args)}`);
68
+ changed = true;
69
+ return;
70
+ }
71
+ const isList = c.method === "todos" && c.call.getArguments().length === 1;
72
+ if (!isList && c.method !== "todoGroups")
73
+ return;
74
+ if (c.method === "todoGroups" && c.call.getArguments().length !== 1)
75
+ return;
76
+ // The dock's setters in the same stub, before or after the list, fold into its options.
77
+ const opts = {};
78
+ calls.forEach((s, j) => {
79
+ if (!s || s.receiver !== c.receiver || !DOCK_SETTERS[s.method])
80
+ return;
81
+ if (s.method === "todoIndex" && c.method === "todoGroups")
82
+ return;
83
+ opts[DOCK_SETTERS[s.method]] = s.call.getArguments()[0]?.getText() ?? "undefined";
84
+ consumed.add(j);
85
+ });
86
+ const items = c.call.getArguments()[0];
87
+ renameItemNames(items);
88
+ const id = opts.id ?? DEFAULT_DOCK_ID;
89
+ delete opts.id;
90
+ const entries = Object.entries(opts);
91
+ const tail = entries.length ? `, { ${entries.map(([k, v]) => `${k}: ${v}`).join(", ")} }` : "";
92
+ c.call.replaceWithText(`${c.receiver}.${c.method}(${id}, ${items.getText()}${tail})`);
93
+ changed = true;
94
+ });
95
+ for (const i of [...consumed].sort((a, b) => b - a))
96
+ statements[i].remove();
97
+ for (const [i, c] of calls.entries()) {
98
+ if (!c || consumed.has(i) || c.call.wasForgotten() || !isStubCtx(c.call, c.receiver))
99
+ continue;
100
+ if (DOCK_SETTERS[c.method] && c.method !== "todoIndex")
101
+ problems.push({ line: c.call.getStartLineNumber(), reason: `ctx.${c.method}() with no ctx.todos(...) beside it: pass it as an option of ctx.todos(id, items, { ... })` });
102
+ if (c.method === "set")
103
+ problems.push({ line: c.call.getStartLineNumber(), reason: "ctx.set({...}) was removed: call ctx.ring / ctx.todos / ctx.title ... instead" });
104
+ }
105
+ return changed;
106
+ }
107
+ const PHASES = new Set(["stubBefore", "stubAfter", "stubOnError"]);
108
+ /** A slot map as a stub function: `{ a: {...} }` -> `(ctx) => { ctx.ring("a", {...}); }`. */
109
+ function mapToStub(map) {
110
+ if (!Node.isObjectLiteralExpression(map))
111
+ return map.getText();
112
+ const rings = map.getProperties().flatMap((p) => (Node.isPropertyAssignment(p) ? [`ctx.ring(${JSON.stringify(p.getName().replace(/^["']|["']$/g, ""))}, ${p.getInitializerOrThrow().getText()});`] : []));
113
+ return `(ctx) => {\n${rings.map((r) => " " + r).join("\n")}\n}`;
114
+ }
115
+ /** `X.stubAfter({ ... })` -> `X.stubAfter((ctx) => { ctx.ring(...) })`. */
116
+ function convertSlotMaps(sf) {
117
+ let changed = false;
118
+ for (const call of sf.getDescendantsOfKind(SyntaxKind.CallExpression).reverse()) {
119
+ if (call.wasForgotten())
120
+ continue;
121
+ const callee = call.getExpression();
122
+ const arg = call.getArguments()[0];
123
+ if (Node.isPropertyAccessExpression(callee) && PHASES.has(callee.getName()) && Node.isObjectLiteralExpression(arg)) {
124
+ arg.replaceWithText(mapToStub(arg));
125
+ changed = true;
126
+ }
127
+ }
128
+ return changed;
129
+ }
130
+ /** `defineXBlock({ ..., stubBefore: fn })` (or in its instruction) -> `defineXBlock({ ... }).stubBefore(fn)`. */
131
+ function hoistDefinitionStubs(sf) {
132
+ let changed = false;
133
+ for (const call of sf.getDescendantsOfKind(SyntaxKind.CallExpression).reverse()) {
134
+ if (call.wasForgotten() || !/^define\w*Block$/.test(call.getExpression().getText()))
135
+ continue;
136
+ const options = call.getArguments()[0];
137
+ if (!Node.isObjectLiteralExpression(options))
138
+ continue;
139
+ const holders = [options];
140
+ const instruction = options.getProperty("instruction");
141
+ if (Node.isPropertyAssignment(instruction) && Node.isObjectLiteralExpression(instruction.getInitializer()))
142
+ holders.push(instruction.getInitializer());
143
+ const chained = [];
144
+ for (const holder of holders) {
145
+ for (const prop of holder.getProperties()) {
146
+ const name = Node.isPropertyAssignment(prop) || Node.isMethodDeclaration(prop) ? prop.getName() : "";
147
+ if (!PHASES.has(name))
148
+ continue;
149
+ let fn;
150
+ if (Node.isMethodDeclaration(prop))
151
+ fn = `(${prop.getParameters().map((p) => p.getText()).join(", ")}) => ${prop.getBodyOrThrow().getText()}`;
152
+ else {
153
+ const init = prop.getInitializerOrThrow();
154
+ fn = Node.isObjectLiteralExpression(init) ? mapToStub(init) : init.getText();
155
+ }
156
+ chained.push(`.${name}(${fn})`);
157
+ prop.remove();
158
+ }
159
+ }
160
+ if (chained.length) {
161
+ call.replaceWithText(call.getText() + chained.join(""));
162
+ changed = true;
163
+ }
164
+ }
165
+ return changed;
166
+ }
167
+ /** Rewrites the old stub forms in every file; returns the files it changed and the calls left for a person. */
168
+ export function convertStubs(project) {
169
+ const changed = [];
170
+ const problems = [];
171
+ for (const sf of project.getSourceFiles()) {
172
+ const left = [];
173
+ let touched = hoistDefinitionStubs(sf);
174
+ if (convertSlotMaps(sf))
175
+ touched = true;
176
+ for (const block of sf.getDescendantsOfKind(SyntaxKind.Block).reverse()) {
177
+ if (block.wasForgotten())
178
+ continue;
179
+ if (convertStatements(block.getStatements(), left))
180
+ touched = true;
181
+ }
182
+ if (touched)
183
+ changed.push(sf);
184
+ problems.push(...left.map((p) => ({ file: sf.getFilePath(), ...p })));
185
+ }
186
+ return { changed, problems };
187
+ }
@@ -1,9 +1,10 @@
1
1
  import { resolve } from "node:path";
2
- import { loadWaygraphConfig } from "../config.js";
3
- import { extensionInfo, resolveExtension } from "../extensions.js";
2
+ import { loadWaygraphConfig } from "../../runtime/waygraph-config.js";
3
+ import { extensionInfo, resolveExtension } from "../../runtime/extensions.js";
4
+ import { parseCommand } from "../args.js";
4
5
  export async function extensionsCase(args) {
5
- const update = args.includes("--update");
6
- const rest = args.slice(2).filter((a) => a !== "--update");
6
+ const { values, positionals: rest } = parseCommand("extensions", { update: { type: "boolean", help: "Download again" } }, args.slice(2));
7
+ const update = values.update === true;
7
8
  if (args[1] !== "install") {
8
9
  console.error("usage: waygraph extensions install [project] [--update]");
9
10
  process.exit(1);
@@ -1,5 +1,4 @@
1
- // Split out of the former 8,700-line cli.ts (see src/ARCHITECTURE.md). Behavior unchanged.
2
- import { packageRoot } from "../cli/util.js";
1
+ import { packageRoot } from "../util.js";
3
2
  import { agentSkillFiles } from "./agent-dive-scaffold.js";
4
3
  import { basename, dirname, join, relative, resolve, sep } from "node:path";
5
4
  import { spawnSync } from "node:child_process";
@@ -1,12 +1,13 @@
1
- // Split out of the former 8,700-line cli.ts (see src/ARCHITECTURE.md). Behavior unchanged.
2
- import { blockExportToLabel, discoverFlows, extractFlowNames, extractGotos, extractUrlTraits, parseBlockImports, walkDir } from "../cli/discover.js";
1
+ import { blockExportToLabel, extractFlowNames, extractGotos, extractUrlTraits, parseBlockImports } from "../../analysis/flow-source.js";
2
+ import { walkDir } from "../../manifest/scan.js";
3
+ import { exportedNames, parseSource } from "../../manifest/source.js";
3
4
  import { relative, resolve } from "node:path";
4
- import { existsSync, readFileSync } from "node:fs";
5
+ import { existsSync } from "node:fs";
5
6
  // ---------------------------------------------------------------------------
6
7
  // `list`
7
8
  // ---------------------------------------------------------------------------
8
9
  function listCommand(projectDir) {
9
- const files = discoverFlows(projectDir);
10
+ const files = walkDir(projectDir, /\.flow\.ts$/);
10
11
  if (files.length === 0) {
11
12
  console.log(`waygraph: no flows found under ${projectDir}`);
12
13
  return;
@@ -22,7 +23,7 @@ function listCommand(projectDir) {
22
23
  // `nav`
23
24
  // ---------------------------------------------------------------------------
24
25
  function navCommand(projectDir, flowName) {
25
- const files = discoverFlows(projectDir);
26
+ const files = walkDir(projectDir, /\.flow\.ts$/);
26
27
  const targets = flowName
27
28
  ? files.filter((f) => extractFlowNames(f).includes(flowName))
28
29
  : files;
@@ -33,13 +34,14 @@ function navCommand(projectDir, flowName) {
33
34
  process.exitCode = 1;
34
35
  return;
35
36
  }
37
+ let scanned;
38
+ const blockFiles = () => (scanned ??= walkDir(projectDir, /\.block\.ts$/).map((f) => ({ file: f, exports: exportedNames(parseSource(f)) })));
36
39
  for (const file of targets) {
37
40
  for (const name of extractFlowNames(file)) {
38
41
  console.log(`${name} (${relative(projectDir, file)})`);
39
- const blockDir = projectDir;
40
42
  for (const blockExport of parseBlockImports(file)) {
41
43
  console.log(` -> ${blockExportToLabel(blockExport)}`);
42
- const blockFile = walkDir(blockDir, /\.block\.ts$/).find((f) => readFileSync(f, "utf-8").includes(`export const ${blockExport}`));
44
+ const blockFile = blockFiles().find((f) => f.exports.includes(blockExport))?.file;
43
45
  if (!blockFile)
44
46
  continue;
45
47
  for (const url of extractGotos(blockFile))
@@ -0,0 +1,2 @@
1
+ /** `waygraph manifest [project] [--out <file>]`: every Block, Flow and Checkpoint of the project, as JSON. */
2
+ export declare function manifestCase(args: string[]): Promise<void>;
@@ -0,0 +1,20 @@
1
+ import { mkdirSync, writeFileSync } from "node:fs";
2
+ import { dirname, resolve } from "node:path";
3
+ import { buildManifest } from "../../manifest/manifest.js";
4
+ import { parseCommand } from "../args.js";
5
+ /** `waygraph manifest [project] [--out <file>]`: every Block, Flow and Checkpoint of the project, as JSON. */
6
+ export async function manifestCase(args) {
7
+ const { values, positionals: positional } = parseCommand("manifest", { out: { type: "string", help: "Write to this file" } }, args.slice(1));
8
+ const out = values.out;
9
+ const proj = resolve(positional[0] ?? process.cwd());
10
+ const manifest = await buildManifest(proj);
11
+ const json = JSON.stringify(manifest, null, 2) + "\n";
12
+ if (!out) {
13
+ process.stdout.write(json);
14
+ return;
15
+ }
16
+ const file = resolve(proj, out);
17
+ mkdirSync(dirname(file), { recursive: true });
18
+ writeFileSync(file, json);
19
+ console.error(`waygraph manifest: ${manifest.blocks.length} Block(s), ${manifest.flows.length} flow(s) -> ${file}`);
20
+ }
@@ -0,0 +1,57 @@
1
+ import { relative, resolve } from "node:path";
2
+ import { checkMap } from "../../analysis/map-check.js";
3
+ import { packMapGroup } from "../../manifest/pack.js";
4
+ import { parseCommand } from "../args.js";
5
+ const PACK_OPTIONS = {
6
+ out: { type: "string", value: "<dir>", help: "Output folder (default .waygraph/packages/<group>)" },
7
+ name: { type: "string", value: "<package>", help: "Package name (default waygraph-map-<group>)" },
8
+ version: { type: "string", value: "<x.y.z>", help: "Package version (default 0.1.0)" },
9
+ };
10
+ async function packCase(args) {
11
+ const { values, positionals } = parseCommand("map pack", PACK_OPTIONS, args);
12
+ const group = positionals[0];
13
+ if (!group) {
14
+ console.error("usage: waygraph map pack <group> [project] [--out <dir>] [--name <package>] [--version <x.y.z>]");
15
+ process.exitCode = 1;
16
+ return;
17
+ }
18
+ const proj = resolve(positionals[1] ?? process.cwd());
19
+ const result = await packMapGroup(proj, group, { out: values.out, name: values.name, version: values.version });
20
+ if (!result.ok) {
21
+ console.error(`waygraph map pack: ${result.reason}`);
22
+ for (const p of result.problems ?? [])
23
+ console.error(` ${relative(proj, p.file)} imports "${p.spec}"`);
24
+ process.exitCode = 1;
25
+ return;
26
+ }
27
+ console.log(`waygraph map pack: ${result.group} -> ${relative(proj, result.dir) || "."} (${result.name}, ${result.blocks} Blocks)`);
28
+ console.log(` publish: cd ${relative(process.cwd(), result.dir) || "."} && npm publish install elsewhere: npm i ${result.name}`);
29
+ }
30
+ export async function mapCase(args) {
31
+ if (args[1] === "pack")
32
+ return packCase(args.slice(2));
33
+ const proj = resolve(args[1] ?? process.cwd());
34
+ const result = await checkMap(proj);
35
+ if (!result.hasMapDir) {
36
+ console.log(`waygraph map: no src/map/ directory under ${proj} - nothing to check ` +
37
+ "(this project isn't on the Waygraph Map convention, or hasn't been migrated yet)");
38
+ return;
39
+ }
40
+ console.log(`waygraph map: ${result.nodes.length} node(s) found under ${relative(proj, result.mapRoot)}`);
41
+ if (result.violations.length === 0) {
42
+ console.log("waygraph map: 0 violations - every static Nav/Page url verbatim-matches its folder path");
43
+ }
44
+ else {
45
+ for (const v of result.violations) {
46
+ console.error(`waygraph map: ${v.file} (${v.block}) - ${v.reason}`);
47
+ }
48
+ console.error(`waygraph map: ${result.violations.length} violation${result.violations.length === 1 ? "" : "s"}`);
49
+ // Unlike `check`'s warnings-only stance, a Map violation is exactly
50
+ // the class of bug this command exists to catch (a fabricated
51
+ // folder grouping that never matched the real site, e.g. the real
52
+ // (auth)/signin/ mistake this command's own header comment cites) -
53
+ // fail loud, not just warn.
54
+ process.exitCode = 1;
55
+ }
56
+ return;
57
+ }
@@ -1,3 +1,2 @@
1
1
  export declare function runCase(args: string[]): Promise<void>;
2
- export declare function chainCase(args: string[]): Promise<void>;
3
2
  export declare function demoCase(args: string[]): Promise<void>;