@tuongaz/seeflow 0.1.64 → 0.1.68

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 (314) hide show
  1. package/README.md +4 -0
  2. package/dist/web/assets/abap-DsBKuouk.js +1 -0
  3. package/dist/web/assets/actionscript-3-D_z4Izcz.js +1 -0
  4. package/dist/web/assets/ada-727ZlQH0.js +1 -0
  5. package/dist/web/assets/andromeeda-C3khCPGq.js +1 -0
  6. package/dist/web/assets/angular-html-4alyEGLm.js +1 -0
  7. package/dist/web/assets/angular-ts-BixEUTMq.js +1 -0
  8. package/dist/web/assets/apache-Dn00JSTd.js +1 -0
  9. package/dist/web/assets/apex-COJ4H7py.js +1 -0
  10. package/dist/web/assets/apl-BBq3IX1j.js +1 -0
  11. package/dist/web/assets/applescript-Bu5BbsvL.js +1 -0
  12. package/dist/web/assets/ara-7O62HKoU.js +1 -0
  13. package/dist/web/assets/asciidoc-BPT9niGB.js +1 -0
  14. package/dist/web/assets/asm-Dhn9LcZ4.js +1 -0
  15. package/dist/web/assets/astro-CqkE3fuf.js +1 -0
  16. package/dist/web/assets/aurora-x-D-2ljcwZ.js +1 -0
  17. package/dist/web/assets/awk-eg146-Ew.js +1 -0
  18. package/dist/web/assets/ayu-dark-Cv9koXgw.js +1 -0
  19. package/dist/web/assets/ballerina-Du268qiB.js +1 -0
  20. package/dist/web/assets/bat-fje9CFhw.js +1 -0
  21. package/dist/web/assets/beancount-BwXTMy5W.js +1 -0
  22. package/dist/web/assets/berry-3xVqZejG.js +1 -0
  23. package/dist/web/assets/bibtex-xW4inM5L.js +1 -0
  24. package/dist/web/assets/bicep-DHo0CJ0O.js +1 -0
  25. package/dist/web/assets/blade-a8OxSdnT.js +1 -0
  26. package/dist/web/assets/bsl-Dgyn0ogV.js +1 -0
  27. package/dist/web/assets/c-C3t2pwGQ.js +1 -0
  28. package/dist/web/assets/cadence-DNquZEk8.js +1 -0
  29. package/dist/web/assets/cairo--RitsXJZ.js +1 -0
  30. package/dist/web/assets/catppuccin-frappe-CD_QflpE.js +1 -0
  31. package/dist/web/assets/catppuccin-latte-DRW-0cLl.js +1 -0
  32. package/dist/web/assets/catppuccin-macchiato-C-_shW-Y.js +1 -0
  33. package/dist/web/assets/catppuccin-mocha-LGGdnPYs.js +1 -0
  34. package/dist/web/assets/chart-8DxAnLoD.js +73 -0
  35. package/dist/web/assets/clarity-BHOwM8T6.js +1 -0
  36. package/dist/web/assets/clojure-DxSadP1t.js +1 -0
  37. package/dist/web/assets/cmake-DbXoA79R.js +1 -0
  38. package/dist/web/assets/cobol-PTqiYgYu.js +1 -0
  39. package/dist/web/assets/code-block-cx7LPXvE.js +13 -0
  40. package/dist/web/assets/codeowners-Bp6g37R7.js +1 -0
  41. package/dist/web/assets/codeql-sacFqUAJ.js +1 -0
  42. package/dist/web/assets/coffee-dyiR41kL.js +1 -0
  43. package/dist/web/assets/common-lisp-C7gG9l05.js +1 -0
  44. package/dist/web/assets/coq-Dsg_Bt_b.js +1 -0
  45. package/dist/web/assets/cpp-BksuvNSY.js +1 -0
  46. package/dist/web/assets/crystal-DtDmRg-F.js +1 -0
  47. package/dist/web/assets/csharp-D9R-vmeu.js +1 -0
  48. package/dist/web/assets/css-BPhBrDlE.js +1 -0
  49. package/dist/web/assets/csv-B0qRVHPH.js +1 -0
  50. package/dist/web/assets/cue-DtFQj3wx.js +1 -0
  51. package/dist/web/assets/cypher-m2LEI-9-.js +1 -0
  52. package/dist/web/assets/d-BoXegm-a.js +1 -0
  53. package/dist/web/assets/dark-plus-C3mMm8J8.js +1 -0
  54. package/dist/web/assets/dart-B9wLZaAG.js +1 -0
  55. package/dist/web/assets/dax-ClGRhx96.js +1 -0
  56. package/dist/web/assets/desktop-DEIpsLCJ.js +1 -0
  57. package/dist/web/assets/diff-BgYniUM_.js +1 -0
  58. package/dist/web/assets/docker-COcR7UxN.js +1 -0
  59. package/dist/web/assets/dotenv-BjQB5zDj.js +1 -0
  60. package/dist/web/assets/dracula-BzJJZx-M.js +1 -0
  61. package/dist/web/assets/dracula-soft-BXkSAIEj.js +1 -0
  62. package/dist/web/assets/dream-maker-C-nORZOA.js +1 -0
  63. package/dist/web/assets/edge-D5gP-w-T.js +1 -0
  64. package/dist/web/assets/elixir-CLiX3zqd.js +1 -0
  65. package/dist/web/assets/elm-CmHSxxaM.js +1 -0
  66. package/dist/web/assets/emacs-lisp-BX77sIaO.js +1 -0
  67. package/dist/web/assets/erb-BYTLMnw6.js +1 -0
  68. package/dist/web/assets/erlang-B-DoSBHF.js +1 -0
  69. package/dist/web/assets/everforest-dark-BgDCqdQA.js +1 -0
  70. package/dist/web/assets/everforest-light-C8M2exoo.js +1 -0
  71. package/dist/web/assets/fennel-bCA53EVm.js +1 -0
  72. package/dist/web/assets/fish-w-ucz2PV.js +1 -0
  73. package/dist/web/assets/fluent-Dayu4EKP.js +1 -0
  74. package/dist/web/assets/fortran-fixed-form-TqA4NnZg.js +1 -0
  75. package/dist/web/assets/fortran-free-form-DKXYxT9g.js +1 -0
  76. package/dist/web/assets/fsharp-XplgxFYe.js +1 -0
  77. package/dist/web/assets/gdresource-BHYsBjWJ.js +1 -0
  78. package/dist/web/assets/gdscript-DfxzS6Rs.js +1 -0
  79. package/dist/web/assets/gdshader-SKMF96pI.js +1 -0
  80. package/dist/web/assets/genie-ajMbGru0.js +1 -0
  81. package/dist/web/assets/gherkin--30QC5Em.js +1 -0
  82. package/dist/web/assets/git-commit-i4q6IMui.js +1 -0
  83. package/dist/web/assets/git-rebase-B-v9cOL2.js +1 -0
  84. package/dist/web/assets/github-dark-DHJKELXO.js +1 -0
  85. package/dist/web/assets/github-dark-default-Cuk6v7N8.js +1 -0
  86. package/dist/web/assets/github-dark-dimmed-DH5Ifo-i.js +1 -0
  87. package/dist/web/assets/github-dark-high-contrast-E3gJ1_iC.js +1 -0
  88. package/dist/web/assets/github-light-DAi9KRSo.js +1 -0
  89. package/dist/web/assets/github-light-default-D7oLnXFd.js +1 -0
  90. package/dist/web/assets/github-light-high-contrast-BfjtVDDH.js +1 -0
  91. package/dist/web/assets/gleam-B430Bg39.js +1 -0
  92. package/dist/web/assets/glimmer-js-D-cwc0-E.js +1 -0
  93. package/dist/web/assets/glimmer-ts-pgjy16dm.js +1 -0
  94. package/dist/web/assets/glsl-DBO2IWDn.js +1 -0
  95. package/dist/web/assets/gnuplot-CM8KxXT1.js +1 -0
  96. package/dist/web/assets/go-B1SYOhNW.js +1 -0
  97. package/dist/web/assets/graphql-cDcHW_If.js +1 -0
  98. package/dist/web/assets/groovy-DkBy-JyN.js +1 -0
  99. package/dist/web/assets/hack-D1yCygmZ.js +1 -0
  100. package/dist/web/assets/haml-B2EZWmdv.js +1 -0
  101. package/dist/web/assets/handlebars-BQGss363.js +1 -0
  102. package/dist/web/assets/haskell-BILxekzW.js +1 -0
  103. package/dist/web/assets/haxe-C5wWYbrZ.js +1 -0
  104. package/dist/web/assets/hcl-HzYwdGDm.js +1 -0
  105. package/dist/web/assets/hjson-T-Tgc4AT.js +1 -0
  106. package/dist/web/assets/hlsl-ifBTmRxC.js +1 -0
  107. package/dist/web/assets/houston-DnULxvSX.js +1 -0
  108. package/dist/web/assets/html-C2L_23MC.js +1 -0
  109. package/dist/web/assets/html-derivative-CSfWNPLT.js +1 -0
  110. package/dist/web/assets/http-FRrOvY1W.js +1 -0
  111. package/dist/web/assets/hxml-TIA70rKU.js +1 -0
  112. package/dist/web/assets/hy-BMj5Y0dO.js +1 -0
  113. package/dist/web/assets/imba-bv_oIlVt.js +1 -0
  114. package/dist/web/assets/index-CeLShda7.css +1 -0
  115. package/dist/web/assets/index-Dp4QwEl0.js +8608 -0
  116. package/dist/web/assets/{index.es-DZEdTXNJ.js → index.es-C-uXEdZB.js} +1 -1
  117. package/dist/web/assets/ini-BjABl1g7.js +1 -0
  118. package/dist/web/assets/java-xI-RfyKK.js +1 -0
  119. package/dist/web/assets/javascript-ySlJ1b_l.js +1 -0
  120. package/dist/web/assets/jinja-DGy0s7-h.js +1 -0
  121. package/dist/web/assets/jison-BqZprYcd.js +1 -0
  122. package/dist/web/assets/json-BQoSv7ci.js +1 -0
  123. package/dist/web/assets/json5-w8dY5SsB.js +1 -0
  124. package/dist/web/assets/jsonc-TU54ms6u.js +1 -0
  125. package/dist/web/assets/jsonl-DREVFZK8.js +1 -0
  126. package/dist/web/assets/jsonnet-BfivnA6A.js +1 -0
  127. package/dist/web/assets/{jspdf.es.min-DT1Li8zz.js → jspdf.es.min-BFQufOcQ.js} +3 -3
  128. package/dist/web/assets/jssm-P4WzXJd0.js +1 -0
  129. package/dist/web/assets/jsx-BAng5TT0.js +1 -0
  130. package/dist/web/assets/julia-BBuGR-5E.js +1 -0
  131. package/dist/web/assets/kanagawa-dragon-CkXjmgJE.js +1 -0
  132. package/dist/web/assets/kanagawa-lotus-CfQXZHmo.js +1 -0
  133. package/dist/web/assets/kanagawa-wave-DWedfzmr.js +1 -0
  134. package/dist/web/assets/kotlin-B5lbUyaz.js +1 -0
  135. package/dist/web/assets/kusto-mebxcVVE.js +1 -0
  136. package/dist/web/assets/laserwave-DUszq2jm.js +1 -0
  137. package/dist/web/assets/latex-C-cWTeAZ.js +1 -0
  138. package/dist/web/assets/lean-XBlWyCtg.js +1 -0
  139. package/dist/web/assets/less-BfCpw3nA.js +1 -0
  140. package/dist/web/assets/light-plus-B7mTdjB0.js +1 -0
  141. package/dist/web/assets/liquid-D3W5UaiH.js +1 -0
  142. package/dist/web/assets/log-Cc5clBb7.js +1 -0
  143. package/dist/web/assets/logo-IuBKFhSY.js +1 -0
  144. package/dist/web/assets/lua-CvWAzNxB.js +1 -0
  145. package/dist/web/assets/luau-Du5NY7AG.js +1 -0
  146. package/dist/web/assets/make-Bvotw-X0.js +1 -0
  147. package/dist/web/assets/markdown-DK_1WFMa.js +1 -0
  148. package/dist/web/assets/markdown-UIAJJxZW.js +1 -0
  149. package/dist/web/assets/marko-z0MBrx5-.js +1 -0
  150. package/dist/web/assets/material-theme-D5KoaKCx.js +1 -0
  151. package/dist/web/assets/material-theme-darker-BfHTSMKl.js +1 -0
  152. package/dist/web/assets/material-theme-lighter-B0m2ddpp.js +1 -0
  153. package/dist/web/assets/material-theme-ocean-CyktbL80.js +1 -0
  154. package/dist/web/assets/material-theme-palenight-Csfq5Kiy.js +1 -0
  155. package/dist/web/assets/matlab-D9-PGadD.js +1 -0
  156. package/dist/web/assets/mdc-DB_EDNY_.js +1 -0
  157. package/dist/web/assets/mdx-sdHcTMYB.js +1 -0
  158. package/dist/web/assets/mermaid-Ci6OQyBP.js +1 -0
  159. package/dist/web/assets/min-dark-CafNBF8u.js +1 -0
  160. package/dist/web/assets/min-light-CTRr51gU.js +1 -0
  161. package/dist/web/assets/mipsasm-BC5c_5Pe.js +1 -0
  162. package/dist/web/assets/mojo-Tz6hzZYG.js +1 -0
  163. package/dist/web/assets/monokai-D4h5O-jR.js +1 -0
  164. package/dist/web/assets/move-DB_GagMm.js +1 -0
  165. package/dist/web/assets/narrat-DLbgOhZU.js +1 -0
  166. package/dist/web/assets/nextflow-B0XVJmRM.js +1 -0
  167. package/dist/web/assets/nginx-D_VnBJ67.js +1 -0
  168. package/dist/web/assets/night-owl-C39BiMTA.js +1 -0
  169. package/dist/web/assets/nim-ZlGxZxc3.js +1 -0
  170. package/dist/web/assets/nix-shcSOmrb.js +1 -0
  171. package/dist/web/assets/nord-Ddv68eIx.js +1 -0
  172. package/dist/web/assets/nushell-D4Tzg5kh.js +1 -0
  173. package/dist/web/assets/objective-c-Deuh7S70.js +1 -0
  174. package/dist/web/assets/objective-cpp-BUEGK8hf.js +1 -0
  175. package/dist/web/assets/ocaml-BNioltXt.js +1 -0
  176. package/dist/web/assets/one-dark-pro-GBQ2dnAY.js +1 -0
  177. package/dist/web/assets/one-light-PoHY5YXO.js +1 -0
  178. package/dist/web/assets/pascal-JqZropPD.js +1 -0
  179. package/dist/web/assets/perl-CHQXSrWU.js +1 -0
  180. package/dist/web/assets/php-B5ebYQev.js +1 -0
  181. package/dist/web/assets/plastic-3e1v2bzS.js +1 -0
  182. package/dist/web/assets/plsql-LKU2TuZ1.js +1 -0
  183. package/dist/web/assets/po-BFLt1xDp.js +1 -0
  184. package/dist/web/assets/poimandres-CS3Unz2-.js +1 -0
  185. package/dist/web/assets/polar-DKykz6zU.js +1 -0
  186. package/dist/web/assets/postcss-B3ZDOciz.js +1 -0
  187. package/dist/web/assets/powerquery-CSHBycmS.js +1 -0
  188. package/dist/web/assets/powershell-BIEUsx6d.js +1 -0
  189. package/dist/web/assets/prisma-B48N-Iqd.js +1 -0
  190. package/dist/web/assets/prolog-BY-TUvya.js +1 -0
  191. package/dist/web/assets/proto-zocC4JxJ.js +1 -0
  192. package/dist/web/assets/pug-CM9l7STV.js +1 -0
  193. package/dist/web/assets/puppet-Cza_XSSt.js +1 -0
  194. package/dist/web/assets/purescript-Bg-kzb6g.js +1 -0
  195. package/dist/web/assets/python-DhUJRlN_.js +1 -0
  196. package/dist/web/assets/qml-D8XfuvdV.js +1 -0
  197. package/dist/web/assets/qmldir-C8lEn-DE.js +1 -0
  198. package/dist/web/assets/qss-DhMKtDLN.js +1 -0
  199. package/dist/web/assets/r-CwjWoCRV.js +1 -0
  200. package/dist/web/assets/racket-CzouJOBO.js +1 -0
  201. package/dist/web/assets/raku-B1bQXN8T.js +1 -0
  202. package/dist/web/assets/razor-CNLDkMZG.js +1 -0
  203. package/dist/web/assets/red-bN70gL4F.js +1 -0
  204. package/dist/web/assets/reg-5LuOXUq_.js +1 -0
  205. package/dist/web/assets/regexp-DWJ3fJO_.js +1 -0
  206. package/dist/web/assets/rel-DJlmqQ1C.js +1 -0
  207. package/dist/web/assets/riscv-QhoSD0DR.js +1 -0
  208. package/dist/web/assets/rose-pine-CmCqftbK.js +1 -0
  209. package/dist/web/assets/rose-pine-dawn-Ds-gbosJ.js +1 -0
  210. package/dist/web/assets/rose-pine-moon-CjDtw9vr.js +1 -0
  211. package/dist/web/assets/rst-4NLicBqY.js +1 -0
  212. package/dist/web/assets/ruby-DeZ3UC14.js +1 -0
  213. package/dist/web/assets/rust-Be6lgOlo.js +1 -0
  214. package/dist/web/assets/sas-BmTFh92c.js +1 -0
  215. package/dist/web/assets/sass-BJ4Li9vH.js +1 -0
  216. package/dist/web/assets/scala-DQVVAn-B.js +1 -0
  217. package/dist/web/assets/scheme-BJGe-b2p.js +1 -0
  218. package/dist/web/assets/scss-C31hgJw-.js +1 -0
  219. package/dist/web/assets/sdbl-BLhTXw86.js +1 -0
  220. package/dist/web/assets/shaderlab-B7qAK45m.js +1 -0
  221. package/dist/web/assets/shellscript-atvbtKCR.js +1 -0
  222. package/dist/web/assets/shellsession-C_rIy8kc.js +1 -0
  223. package/dist/web/assets/slack-dark-BthQWCQV.js +1 -0
  224. package/dist/web/assets/slack-ochin-DqwNpetd.js +1 -0
  225. package/dist/web/assets/smalltalk-DkLiglaE.js +1 -0
  226. package/dist/web/assets/snazzy-light-Bw305WKR.js +1 -0
  227. package/dist/web/assets/solarized-dark-DXbdFlpD.js +1 -0
  228. package/dist/web/assets/solarized-light-L9t79GZl.js +1 -0
  229. package/dist/web/assets/solidity-C1w2a3ep.js +1 -0
  230. package/dist/web/assets/soy-C-lX7w71.js +1 -0
  231. package/dist/web/assets/sparql-bYkjHRlG.js +1 -0
  232. package/dist/web/assets/splunk-Cf8iN4DR.js +1 -0
  233. package/dist/web/assets/sql-COK4E0Yg.js +1 -0
  234. package/dist/web/assets/ssh-config-BknIz3MU.js +1 -0
  235. package/dist/web/assets/stata-DorPZHa4.js +1 -0
  236. package/dist/web/assets/stylus-BeQkCIfX.js +1 -0
  237. package/dist/web/assets/svelte-MSaWC3Je.js +1 -0
  238. package/dist/web/assets/swift-BSxZ-RaX.js +1 -0
  239. package/dist/web/assets/synthwave-84-CbfX1IO0.js +1 -0
  240. package/dist/web/assets/system-verilog-C7L56vO4.js +1 -0
  241. package/dist/web/assets/systemd-CUnW07Te.js +1 -0
  242. package/dist/web/assets/talonscript-C1XDQQGZ.js +1 -0
  243. package/dist/web/assets/tasl-CQjiPCtT.js +1 -0
  244. package/dist/web/assets/tcl-DQ1-QYvQ.js +1 -0
  245. package/dist/web/assets/templ-dwX3ZSMB.js +1 -0
  246. package/dist/web/assets/terraform-BbSNqyBO.js +1 -0
  247. package/dist/web/assets/tex-rYs2v40G.js +1 -0
  248. package/dist/web/assets/tokyo-night-DBQeEorK.js +1 -0
  249. package/dist/web/assets/toml-CB2ApiWb.js +1 -0
  250. package/dist/web/assets/ts-tags-CipyTH0X.js +1 -0
  251. package/dist/web/assets/tsv-B_m7g4N7.js +1 -0
  252. package/dist/web/assets/tsx-B6W0miNI.js +1 -0
  253. package/dist/web/assets/turtle-BMR_PYu6.js +1 -0
  254. package/dist/web/assets/twig-NC5TFiHP.js +1 -0
  255. package/dist/web/assets/typescript-Dj6nwHGl.js +1 -0
  256. package/dist/web/assets/typespec-BpWG_bgh.js +1 -0
  257. package/dist/web/assets/typst-BVUVsWT6.js +1 -0
  258. package/dist/web/assets/v-CAQ2eGtk.js +1 -0
  259. package/dist/web/assets/vala-BFOHcciG.js +1 -0
  260. package/dist/web/assets/vb-CdO5JTpU.js +1 -0
  261. package/dist/web/assets/verilog-CJaU5se_.js +1 -0
  262. package/dist/web/assets/vesper-BEBZ7ncR.js +1 -0
  263. package/dist/web/assets/vhdl-DYoNaHQp.js +1 -0
  264. package/dist/web/assets/viml-m4uW47V2.js +1 -0
  265. package/dist/web/assets/vitesse-black-Bkuqu6BP.js +1 -0
  266. package/dist/web/assets/vitesse-dark-D0r3Knsf.js +1 -0
  267. package/dist/web/assets/vitesse-light-CVO1_9PV.js +1 -0
  268. package/dist/web/assets/vue-BuYVFjOK.js +1 -0
  269. package/dist/web/assets/vue-html-xdeiXROB.js +1 -0
  270. package/dist/web/assets/vyper-nyqBNV6O.js +1 -0
  271. package/dist/web/assets/wasm-C6j12Q_x.js +1 -0
  272. package/dist/web/assets/wasm-CG6Dc4jp.js +1 -0
  273. package/dist/web/assets/wenyan-7A4Fjokl.js +1 -0
  274. package/dist/web/assets/wgsl-CB0Krxn9.js +1 -0
  275. package/dist/web/assets/wikitext-DCE3LsBG.js +1 -0
  276. package/dist/web/assets/wolfram-C3FkfJm5.js +1 -0
  277. package/dist/web/assets/xml-e3z08dGr.js +1 -0
  278. package/dist/web/assets/xsl-Dd0NUgwM.js +1 -0
  279. package/dist/web/assets/yaml-CVw76BM1.js +1 -0
  280. package/dist/web/assets/zenscript-HnGAYVZD.js +1 -0
  281. package/dist/web/assets/zig-BVz_zdnA.js +1 -0
  282. package/dist/web/index.html +2 -2
  283. package/examples/component-showcase/README.md +29 -0
  284. package/examples/component-showcase/flow.json +40 -0
  285. package/examples/component-showcase/nodes/chart/spec.json +66 -0
  286. package/examples/component-showcase/nodes/counter/spec.json +57 -0
  287. package/examples/component-showcase/nodes/fetcher/actions/refresh.ts +35 -0
  288. package/examples/component-showcase/nodes/fetcher/spec.json +68 -0
  289. package/examples/component-showcase/nodes/form/spec.json +87 -0
  290. package/examples/component-showcase/package.json +6 -0
  291. package/examples/component-showcase/style.json +28 -0
  292. package/examples/ecommerce-platform/flow.json +28 -30
  293. package/examples/order-pipeline/flow.json +16 -16
  294. package/package.json +2 -1
  295. package/src/api.ts +73 -23
  296. package/src/cli-e2e.ts +6 -7
  297. package/src/cli-manifest.ts +3 -5
  298. package/src/cli.ts +27 -0
  299. package/src/component-action-runner.ts +188 -0
  300. package/src/component-spec-resolver.ts +60 -0
  301. package/src/diagram.ts +8 -5
  302. package/src/layout.ts +23 -26
  303. package/src/mcp.ts +2 -2
  304. package/src/merge.ts +8 -3
  305. package/src/node-files.ts +1 -1
  306. package/src/operations.ts +109 -52
  307. package/src/runtime.ts +37 -0
  308. package/src/schema-catalog.ts +23 -11
  309. package/src/schema.ts +256 -262
  310. package/src/server.ts +1 -1
  311. package/src/status-runner.ts +2 -1
  312. package/src/watcher.ts +46 -10
  313. package/dist/web/assets/index-BAEA18IR.js +0 -7838
  314. package/dist/web/assets/index-CwfFCUzZ.css +0 -1
@@ -4,23 +4,22 @@
4
4
  "nodes": [
5
5
  {
6
6
  "id": "node-cQOUPXanaX",
7
- "type": "shapeNode",
7
+ "type": "user",
8
8
  "data": {
9
- "shape": "user",
10
9
  "name": "Customer",
11
10
  "description": "Web / Mobile / Partner"
12
11
  }
13
12
  },
14
13
  {
15
14
  "id": "node-CbwYqb7NfB",
16
- "type": "playNode",
15
+ "type": "rectangle",
17
16
  "data": {
18
17
  "name": "API Gateway",
18
+ "description": "Auth, rate-limiting, routing.",
19
+ "detail": "file://detail.md",
19
20
  "stateSource": {
20
21
  "kind": "request"
21
22
  },
22
- "description": "Auth, rate-limiting, routing.",
23
- "detail": "file://detail.md",
24
23
  "playAction": {
25
24
  "kind": "script",
26
25
  "interpreter": "bun",
@@ -31,38 +30,38 @@
31
30
  },
32
31
  {
33
32
  "id": "node-3zFtHg6ENc",
34
- "type": "stateNode",
33
+ "type": "rectangle",
35
34
  "data": {
36
35
  "name": "Auth Service",
36
+ "description": "JWT issuance + OAuth2 / OIDC.",
37
+ "detail": "file://detail.md",
37
38
  "stateSource": {
38
39
  "kind": "request"
39
- },
40
- "description": "JWT issuance + OAuth2 / OIDC.",
41
- "detail": "file://detail.md"
40
+ }
42
41
  }
43
42
  },
44
43
  {
45
44
  "id": "node-kwBY8YPmYM",
46
- "type": "stateNode",
45
+ "type": "rectangle",
47
46
  "data": {
48
47
  "name": "Product Catalog",
48
+ "description": "SKUs, variants, pricing, full-text search.",
49
+ "detail": "file://detail.md",
49
50
  "stateSource": {
50
51
  "kind": "request"
51
- },
52
- "description": "SKUs, variants, pricing, full-text search.",
53
- "detail": "file://detail.md"
52
+ }
54
53
  }
55
54
  },
56
55
  {
57
56
  "id": "node-5F424NWbEu",
58
- "type": "playNode",
57
+ "type": "rectangle",
59
58
  "data": {
60
59
  "name": "Cart Service",
60
+ "description": "Add/remove items, apply coupons, checkout.",
61
+ "detail": "file://detail.md",
61
62
  "stateSource": {
62
63
  "kind": "request"
63
64
  },
64
- "description": "Add/remove items, apply coupons, checkout.",
65
- "detail": "file://detail.md",
66
65
  "playAction": {
67
66
  "kind": "script",
68
67
  "interpreter": "bun",
@@ -73,14 +72,14 @@
73
72
  },
74
73
  {
75
74
  "id": "node-yKrg9DV5fJ",
76
- "type": "playNode",
75
+ "type": "rectangle",
77
76
  "data": {
78
77
  "name": "Order Service",
78
+ "description": "pending → confirmed → shipped → delivered.",
79
+ "detail": "file://detail.md",
79
80
  "stateSource": {
80
81
  "kind": "event"
81
82
  },
82
- "description": "pending → confirmed → shipped → delivered.",
83
- "detail": "file://detail.md",
84
83
  "playAction": {
85
84
  "kind": "script",
86
85
  "interpreter": "bun",
@@ -91,40 +90,39 @@
91
90
  },
92
91
  {
93
92
  "id": "node-mPqan8rFYN",
94
- "type": "stateNode",
93
+ "type": "rectangle",
95
94
  "data": {
96
95
  "name": "Payment Service",
96
+ "description": "Stripe + PayPal gateway integration.",
97
+ "detail": "file://detail.md",
97
98
  "stateSource": {
98
99
  "kind": "event"
99
- },
100
- "description": "Stripe + PayPal gateway integration.",
101
- "detail": "file://detail.md"
100
+ }
102
101
  }
103
102
  },
104
103
  {
105
104
  "id": "node-fkptXw7uvs",
106
- "type": "stateNode",
105
+ "type": "rectangle",
107
106
  "data": {
108
107
  "name": "Notification Service",
108
+ "description": "Email + SMS + push via AWS SES / SNS.",
109
+ "detail": "file://detail.md",
109
110
  "stateSource": {
110
111
  "kind": "event"
111
- },
112
- "description": "Email + SMS + push via AWS SES / SNS.",
113
- "detail": "file://detail.md"
112
+ }
114
113
  }
115
114
  },
116
115
  {
117
116
  "id": "node-5SDiw3Wz6s",
118
- "type": "shapeNode",
117
+ "type": "database",
119
118
  "data": {
120
- "shape": "database",
121
119
  "name": "PostgreSQL",
122
120
  "description": "Orders, users, products — primary OLTP store"
123
121
  }
124
122
  },
125
123
  {
126
124
  "id": "node-XwygzfKPZ5",
127
- "type": "htmlNode",
125
+ "type": "html",
128
126
  "data": {
129
127
  "name": "Platform Health",
130
128
  "html": "file://view.html"
@@ -4,14 +4,14 @@
4
4
  "nodes": [
5
5
  {
6
6
  "id": "node-XKIyds0TDg",
7
- "type": "playNode",
7
+ "type": "rectangle",
8
8
  "data": {
9
9
  "name": "POST /orders",
10
+ "description": "Creates order, kicks off the pipeline.",
11
+ "detail": "file://detail.md",
10
12
  "stateSource": {
11
13
  "kind": "request"
12
14
  },
13
- "description": "Creates order, kicks off the pipeline.",
14
- "detail": "file://detail.md",
15
15
  "playAction": {
16
16
  "kind": "script",
17
17
  "interpreter": "bun",
@@ -22,39 +22,39 @@
22
22
  },
23
23
  {
24
24
  "id": "node-GXTKUcE3ye",
25
- "type": "stateNode",
25
+ "type": "rectangle",
26
26
  "data": {
27
27
  "name": "Inventory Service",
28
- "stateSource": {
29
- "kind": "event"
30
- },
31
28
  "description": "Reserves stock.",
32
29
  "detail": "file://detail.md",
33
- "icon": "a-arrow-down-icon"
30
+ "icon": "a-arrow-down-icon",
31
+ "stateSource": {
32
+ "kind": "event"
33
+ }
34
34
  }
35
35
  },
36
36
  {
37
37
  "id": "node-YOYiHJpY0i",
38
- "type": "stateNode",
38
+ "type": "rectangle",
39
39
  "data": {
40
40
  "name": "Payment Service",
41
+ "description": "Charges card.",
42
+ "detail": "file://detail.md",
41
43
  "stateSource": {
42
44
  "kind": "event"
43
- },
44
- "description": "Charges card.",
45
- "detail": "file://detail.md"
45
+ }
46
46
  }
47
47
  },
48
48
  {
49
49
  "id": "node-zUIH7WFnhK",
50
- "type": "stateNode",
50
+ "type": "rectangle",
51
51
  "data": {
52
52
  "name": "Fulfillment Service",
53
+ "description": "Enqueues shipment.",
54
+ "detail": "file://detail.md",
53
55
  "stateSource": {
54
56
  "kind": "event"
55
- },
56
- "description": "Enqueues shipment.",
57
- "detail": "file://detail.md"
57
+ }
58
58
  }
59
59
  }
60
60
  ],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tuongaz/seeflow",
3
- "version": "0.1.64",
3
+ "version": "0.1.68",
4
4
  "description": "Local studio that hosts file-defined demos as React Flow canvases wired to a running app via REST + SSE + Zod schema.",
5
5
  "keywords": [
6
6
  "seeflow",
@@ -43,6 +43,7 @@
43
43
  },
44
44
  "dependencies": {
45
45
  "@modelcontextprotocol/sdk": "^1.29.0",
46
+ "@seeflow/canvas": "workspace:*",
46
47
  "elkjs": "^0.11.1",
47
48
  "hono": "^4.6.14",
48
49
  "zod": "^3.23.8",
package/src/api.ts CHANGED
@@ -3,6 +3,7 @@ import { dirname, isAbsolute, join, resolve, sep } from 'node:path';
3
3
  import { Hono } from 'hono';
4
4
  import { streamSSE } from 'hono/streaming';
5
5
  import { z } from 'zod';
6
+ import { runComponentAction } from './component-action-runner.ts';
6
7
  import {
7
8
  AssembleRequestSchema,
8
9
  ProposeScopeRequestSchema,
@@ -38,6 +39,7 @@ import {
38
39
  } from './proxy.ts';
39
40
  import type { Registry } from './registry.ts';
40
41
  import { getSchemaCategory, listSchemaCategories, schemaCategoryNames } from './schema-catalog.ts';
42
+ import type { ComponentAction } from './schema.ts';
41
43
  import { FlowSchema, ResolvedFlowSchema } from './schema.ts';
42
44
  import { type Spawner, defaultSpawner } from './shellout.ts';
43
45
  import { ID_TYPES, MAX_ID_COUNT, generateIds, isIdType } from './short-id.ts';
@@ -345,14 +347,7 @@ export function createApi(options: ApiOptions): Hono {
345
347
  }
346
348
  const flow = flowParse.data;
347
349
  const result = await computeLayout(
348
- flow.nodes.map((n) => ({
349
- id: n.id,
350
- type: n.type,
351
- // Only `shape` matters for layout (floating-annotation detection +
352
- // shape-specific sizing). Other Flow data fields are irrelevant.
353
- data:
354
- n.type === 'shapeNode' ? { shape: (n.data as { shape?: string }).shape } : undefined,
355
- })),
350
+ flow.nodes.map((n) => ({ id: n.id, type: n.type })),
356
351
  flow.connectors.map((c) => ({ id: c.id, source: c.source, target: c.target })),
357
352
  options,
358
353
  );
@@ -375,12 +370,18 @@ export function createApi(options: ApiOptions): Hono {
375
370
  .map((n) => ({
376
371
  id: n.id,
377
372
  type: n.type as
378
- | 'playNode'
379
- | 'stateNode'
380
- | 'shapeNode'
381
- | 'imageNode'
382
- | 'iconNode'
383
- | 'htmlNode',
373
+ | 'rectangle'
374
+ | 'ellipse'
375
+ | 'sticky'
376
+ | 'text'
377
+ | 'database'
378
+ | 'server'
379
+ | 'user'
380
+ | 'queue'
381
+ | 'cloud'
382
+ | 'image'
383
+ | 'html'
384
+ | 'icon',
384
385
  data:
385
386
  typeof n.width === 'number' && typeof n.height === 'number'
386
387
  ? { width: n.width, height: n.height }
@@ -582,7 +583,7 @@ export function createApi(options: ApiOptions): Hono {
582
583
  });
583
584
 
584
585
  // POST /api/projects/:id/files/open — shell out to `$EDITOR <abs>` so the
585
- // user can edit a project-scoped file (htmlNode block, image asset) in
586
+ // user can edit a project-scoped file (type:'html' block, image asset) in
586
587
  // their IDE. The endpoint always returns the resolved absolute path in
587
588
  // the response body so the frontend can copy-to-clipboard when $EDITOR
588
589
  // isn't set or the spawn fails. Path safety mirrors the GET route.
@@ -815,13 +816,10 @@ export function createApi(options: ApiOptions): Hono {
815
816
 
816
817
  const node = merged.flow.nodes.find((n) => n.id === nodeId);
817
818
  if (!node) return c.json({ error: `Unknown nodeId: ${nodeId}` }, 404);
818
- if (
819
- node.type === 'shapeNode' ||
820
- node.type === 'imageNode' ||
821
- node.type === 'iconNode' ||
822
- node.type === 'htmlNode' ||
823
- !node.data.playAction
824
- ) {
819
+ // playAction is optional on every node type post-flat-types. The runtime
820
+ // gate is purely "is the field set?" — visual kind doesn't constrain
821
+ // playability.
822
+ if (!node.data.playAction) {
825
823
  return c.json({ error: `Node ${nodeId} has no playAction` }, 400);
826
824
  }
827
825
 
@@ -854,6 +852,58 @@ export function createApi(options: ApiOptions): Hono {
854
852
  return c.json(result);
855
853
  });
856
854
 
855
+ // POST /api/flows/:id/nodes/:nodeId/actions/:name — dispatch a component
856
+ // node's named action over HTTP. Only `script`-kind actions cross this seam;
857
+ // `set`-kind actions mutate canvas state locally and never round-trip
858
+ // through the API (the runner rejects them with statusHint 400).
859
+ // Payload is the JSON request body (defaults to {} on parse failure) and is
860
+ // piped to the script's stdin by `runComponentAction`. Response is the
861
+ // script's parsed JSON stdout on success.
862
+ api.post('/flows/:id/nodes/:nodeId/actions/:name', async (c) => {
863
+ const id = c.req.param('id');
864
+ const nodeId = c.req.param('nodeId');
865
+ const actionName = c.req.param('name');
866
+
867
+ const entry = registry.getById(id);
868
+ if (!entry) return c.json({ error: 'unknown demo' }, 404);
869
+ if (!events) return c.json({ error: 'events not enabled' }, 500);
870
+
871
+ const fullPath = resolveFilePath(entry.repoPath, entry.flowPath);
872
+ if (!existsSync(fullPath)) {
873
+ return c.json({ error: `Flow file not found: ${fullPath}` }, 404);
874
+ }
875
+ const merged = readMergedFlow(fullPath);
876
+ if (!merged.flow) {
877
+ return c.json({ error: merged.error ?? 'Flow read failed' }, 400);
878
+ }
879
+
880
+ const node = merged.flow.nodes.find((n) => n.id === nodeId);
881
+ if (!node) return c.json({ error: `Unknown nodeId: ${nodeId}` }, 404);
882
+ if (node.type !== 'component') {
883
+ return c.json({ error: `Node ${nodeId} is not a component node` }, 400);
884
+ }
885
+
886
+ const action = (node.data as { spec: { actions?: Record<string, ComponentAction> } }).spec
887
+ .actions?.[actionName];
888
+ if (!action) return c.json({ error: `Unknown action: ${actionName}` }, 404);
889
+
890
+ const payload = await c.req.json().catch(() => ({}));
891
+ const result = await runComponentAction({
892
+ events,
893
+ flowId: id,
894
+ nodeId,
895
+ cwd: entry.repoPath,
896
+ actionName,
897
+ action,
898
+ payload,
899
+ spawner: processSpawner,
900
+ });
901
+ if (!result.ok) {
902
+ return c.json({ error: result.error }, result.statusHint as 400 | 404 | 500 | 504);
903
+ }
904
+ return c.json(result.body);
905
+ });
906
+
857
907
  // POST /api/flows/:id/reset — the "Restart demo" workflow (US-008). Order:
858
908
  // 1. Stop every live play-script + every long-running status-script for
859
909
  // this demo in parallel — both must complete before any reset script
@@ -1007,7 +1057,7 @@ export function createApi(options: ApiOptions): Hono {
1007
1057
  });
1008
1058
 
1009
1059
  // PATCH a single node — partial update of position, label, detail, visual
1010
- // fields, or shapeNode-only fields. Every UI-driven node edit (other than
1060
+ // fields, or geometric-only fields. Every UI-driven node edit (other than
1011
1061
  // the high-frequency drag fast-path above) flows through here. The mutation
1012
1062
  // is performed against the raw parsed JSON (so unknown v2 fields the schema
1013
1063
  // doesn't yet recognize survive round-trips) and the WHOLE resulting demo
package/src/cli-e2e.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  // End-to-end validator used by `seeflow e2e <flowId>`. Opens an SSE channel to
2
- // the studio, triggers every playNode's playAction (sequentially), then drains
2
+ // the studio, triggers every node carrying a playAction (sequentially), then drains
3
3
  // the channel for node:done/error + node:status reports. Mirrors the algorithm
4
4
  // in skills/seeflow/scripts/validate-end-to-end.ts — kept here so the CLI does
5
5
  // not depend on the skill folder.
@@ -167,15 +167,14 @@ function openSseChannel(body: ReadableStream<Uint8Array>): SseChannel {
167
167
  }
168
168
 
169
169
  function hasPlayAction(node: NodeShape): boolean {
170
- return (
171
- (node.type === 'playNode' || node.type === 'stateNode') && node.data?.playAction !== undefined
172
- );
170
+ // Flat-types refactor: capabilities are top-level data fields on every
171
+ // type, not gated by the type tag. The e2e runner iterates every node
172
+ // carrying a playAction regardless of variant.
173
+ return node.data?.playAction !== undefined;
173
174
  }
174
175
 
175
176
  function hasStatusAction(node: NodeShape): boolean {
176
- return (
177
- (node.type === 'playNode' || node.type === 'stateNode') && node.data?.statusAction !== undefined
178
- );
177
+ return node.data?.statusAction !== undefined;
179
178
  }
180
179
 
181
180
  export async function validateEndToEnd(options: ValidateOptions): Promise<ValidationReport> {
@@ -281,7 +281,7 @@ export const COMMAND_MANIFEST: CommandManifestEntry[] = [
281
281
  },
282
282
  requiresStudio: false,
283
283
  examples: [
284
- 'seeflow flow:add-bulk abc12345 --json \'{"nodes":[{"id":"a","type":"shapeNode","data":{"shape":"rectangle"}}],"connectors":[]}\'',
284
+ 'seeflow flow:add-bulk abc12345 --json \'{"nodes":[{"id":"a","type":"rectangle","data":{}}],"connectors":[]}\'',
285
285
  'seeflow flow:add-bulk abc12345 --file batch.json',
286
286
  ],
287
287
  },
@@ -344,7 +344,7 @@ export const COMMAND_MANIFEST: CommandManifestEntry[] = [
344
344
  flags: BODY_FLAGS,
345
345
  body: {
346
346
  example: {
347
- type: 'stateNode',
347
+ type: 'rectangle',
348
348
  data: { name: 'hello', stateSource: { kind: 'request' } },
349
349
  },
350
350
  },
@@ -360,9 +360,7 @@ export const COMMAND_MANIFEST: CommandManifestEntry[] = [
360
360
  ],
361
361
  },
362
362
  requiresStudio: false,
363
- examples: [
364
- 'seeflow nodes:add abc12345 --json \'{"type":"shapeNode","data":{"shape":"rectangle"}}\'',
365
- ],
363
+ examples: ['seeflow nodes:add abc12345 --json \'{"type":"rectangle","data":{}}\''],
366
364
  },
367
365
  {
368
366
  name: 'nodes:get',
package/src/cli.ts CHANGED
@@ -20,6 +20,7 @@ import {
20
20
  clearPid,
21
21
  defaultPidPath,
22
22
  isPidAlive,
23
+ portInUse,
23
24
  readConfig,
24
25
  readPid,
25
26
  studioUrl,
@@ -266,6 +267,20 @@ async function runHelp() {
266
267
  console.log(renderCommandList());
267
268
  }
268
269
 
270
+ // Pre-flight: refuse to start if the studio port already has a TCP listener.
271
+ // We deliberately do NOT probe Vite's port (5173) here — `bun run dev` spawns
272
+ // Vite alongside the studio, so Vite legitimately owns 5173 in dev mode and a
273
+ // probe can't distinguish "our Vite" from a stranger. If Vite's port is taken
274
+ // by something else, Vite itself surfaces the conflict.
275
+ async function assertPortFree(studioPort: number, host: string): Promise<void> {
276
+ if (!(await portInUse(host, studioPort))) return;
277
+ console.error(
278
+ `Cannot start SeeFlow: port ${studioPort} already in use.\n` +
279
+ `Stop the running server on ${studioPort} first, then retry.`,
280
+ );
281
+ process.exit(1);
282
+ }
283
+
269
284
  async function runStart() {
270
285
  mkdirSync(seeflowHome(), { recursive: true });
271
286
  const config = readConfig();
@@ -294,6 +309,12 @@ async function runStart() {
294
309
  return;
295
310
  }
296
311
 
312
+ // Defense-in-depth: parent already checked in spawnDaemon, but a race
313
+ // between parent-check and child-bind can still let another process grab
314
+ // the port. Re-check here so the child fails fast with a clear error
315
+ // instead of EADDRINUSE at bind time.
316
+ await assertPortFree(port, config.host);
317
+
297
318
  // persist the chosen address so other subcommands can find us
298
319
  writeConfig({ port, host: config.host });
299
320
 
@@ -329,6 +350,7 @@ async function runStart() {
329
350
  async function seedExamples(registry: Registry) {
330
351
  await seedExample(registry, 'order-pipeline');
331
352
  await seedExample(registry, 'ecommerce-platform');
353
+ await seedExample(registry, 'component-showcase');
332
354
  }
333
355
 
334
356
  async function seedExample(registry: Registry, exampleName: string) {
@@ -368,6 +390,11 @@ async function spawnDaemon(port: number, host: string) {
368
390
  return;
369
391
  }
370
392
 
393
+ // Studio port must be free before we fork a detached child — otherwise the
394
+ // user waits HEALTH_TIMEOUT_MS for a doomed health probe before seeing a
395
+ // generic timeout error.
396
+ await assertPortFree(port, host);
397
+
371
398
  const proc = spawnDetachedStudio(port);
372
399
  writePid(proc.pid);
373
400
  writeConfig({ port, host });