stream_weaver 0.3.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 (381) hide show
  1. checksums.yaml +7 -0
  2. data/.beads/.gitignore +77 -0
  3. data/.beads/README.md +81 -0
  4. data/.beads/config.yaml +54 -0
  5. data/.beads/metadata.json +7 -0
  6. data/.rspec +3 -0
  7. data/AGENTS.md +91 -0
  8. data/CHANGELOG.md +294 -0
  9. data/CLAUDE.md +67 -0
  10. data/LICENSE.txt +21 -0
  11. data/README.md +565 -0
  12. data/Rakefile +13 -0
  13. data/assets/streamweaver-hero.jpg +0 -0
  14. data/bench/baselines/ledger.rb +58 -0
  15. data/bench/baselines/warroom.rb +51 -0
  16. data/bench/fixtures/ledger.rb +76 -0
  17. data/bench/fixtures/warroom.rb +60 -0
  18. data/bench/results/6daf8b8.md +102 -0
  19. data/bench/results/c8d749b.md +102 -0
  20. data/bench/results/eb06ab9.md +102 -0
  21. data/bench/run.rb +151 -0
  22. data/bench/support.rb +84 -0
  23. data/copy_this/dto_run_sample_run_7631.html +220 -0
  24. data/docs/SERVICE_MODE.md +302 -0
  25. data/docs/architecture/how_streamweaver_works.md +772 -0
  26. data/docs/blog/2026-01-16-streamweaver-introduction.md +515 -0
  27. data/docs/bug-2026-08-31-canvas-bridge-socket-collision.md +83 -0
  28. data/docs/canvas-ipc-session-summary.md +127 -0
  29. data/docs/canvas-panel-workflow.md +172 -0
  30. data/docs/canvas-read.md +147 -0
  31. data/docs/canvas-roadmap.md +275 -0
  32. data/docs/case-studies/2026-09-03-didx-canvas-read-shelf.md +147 -0
  33. data/docs/claude-code-companion-skill-spec.md +567 -0
  34. data/docs/components_reference.md +1223 -0
  35. data/docs/crud-patterns.md +265 -0
  36. data/docs/endpoints.md +122 -0
  37. data/docs/for_llms.md +1 -0
  38. data/docs/form-patterns.md +165 -0
  39. data/docs/frontend-only.md +169 -0
  40. data/docs/html-artifact-audit.md +238 -0
  41. data/docs/ideas/2025-01-01-as-a-service.md +203 -0
  42. data/docs/ideas/2026-01-16-charm-tui-exploration.md +542 -0
  43. data/docs/ideas/2026-08-27-static-doc-shelf-export.md +153 -0
  44. data/docs/ideas/dhh-review-future-refactors.md +142 -0
  45. data/docs/opal-jamstack.md +47 -0
  46. data/docs/opal-npm-direction.md +184 -0
  47. data/docs/opal-spike-findings.md +194 -0
  48. data/docs/plans/2025-12-16-form-blocks-design.md +124 -0
  49. data/docs/plans/2025-12-30-examples-browser-design.md +152 -0
  50. data/docs/plans/2026-01-02-charts-design.md +288 -0
  51. data/docs/plans/2026-01-10-canvas-ipc-design.md +247 -0
  52. data/docs/plans/2026-01-19-cabinet-control-components.md +176 -0
  53. data/docs/plans/2026-01-26-gem-release-and-panel.md +140 -0
  54. data/docs/plans/canvas-claude-project-design.md +238 -0
  55. data/docs/plans/canvas-doc-location-and-discovery.md +32 -0
  56. data/docs/plans/org-doc-preview-surfaces.md +293 -0
  57. data/docs/plans/shadcn-polish-plan.md +417 -0
  58. data/docs/porting-artifacts.md +252 -0
  59. data/docs/reference/agent-skills-comparison.md +369 -0
  60. data/docs/reference/travel-state-prd.artifact.html +780 -0
  61. data/docs/research/2026-08-17-hotwire-alike-landscape.md +268 -0
  62. data/docs/research/2026-08-17-hotwire-concept-map.md +404 -0
  63. data/docs/research/2026-08-22-lazy-fragments-trigger-decision.md +246 -0
  64. data/docs/research/2026-08-22-learnhotwire-syllabus-coverage.md +239 -0
  65. data/docs/research/frontend-only-matrix.md +278 -0
  66. data/docs/research/streamweaver-way-spike-findings.md +529 -0
  67. data/docs/resource-dsl.md +342 -0
  68. data/docs/routing.md +302 -0
  69. data/docs/ruby-ui-comparison.md +319 -0
  70. data/docs/shared-dsl-fragments.md +356 -0
  71. data/docs/streamweaver-for-ai-agents.md +401 -0
  72. data/docs/streamweaver-frontend-vision.md +123 -0
  73. data/docs/streamweaver_canvas/glimmer_initial_final_layer.rb +77 -0
  74. data/docs/streamweaver_canvas/save_example.rb +9 -0
  75. data/docs/templates.md +213 -0
  76. data/docs/testing.md +155 -0
  77. data/docs/theming-hooks.md +281 -0
  78. data/docs/tutorials/the-streamweaver-way.md +882 -0
  79. data/docs/university/capability-inventory.md +137 -0
  80. data/docs/university/dependency-survey.md +114 -0
  81. data/docs/university/design-spec.md +217 -0
  82. data/docs/university/mockups/code-block-doc-theme-dark.png +0 -0
  83. data/docs/university/mockups/code-block-doc-theme-light.png +0 -0
  84. data/docs/university/mockups/course-list-dark.png +0 -0
  85. data/docs/university/mockups/course-list-light.png +0 -0
  86. data/docs/university/mockups/course_canvas_mockup.rb +741 -0
  87. data/docs/university/mockups/step-screen-dark.png +0 -0
  88. data/docs/university/mockups/step-screen-light.png +0 -0
  89. data/docs/university/roadmap.md +72 -0
  90. data/docs/university/send-to-coworker.md +77 -0
  91. data/docs/university/worker-session-mining.md +109 -0
  92. data/docs/visual/browser-rendering-spike.md +173 -0
  93. data/docs/visual/builder-visual-plan-analysis.md +378 -0
  94. data/docs/visual/sw-plan-format-exploration.md +511 -0
  95. data/docs/visual/sw-plan-rendering-deep-dive.md +453 -0
  96. data/docs/visual-skills/PROGRESS.md +60 -0
  97. data/docs/visual-skills/SESSION-CONTEXT.md +207 -0
  98. data/docs/visual-skills/analysis/components.md +317 -0
  99. data/docs/visual-skills/analysis/overlap.md +360 -0
  100. data/docs/visual-skills/analysis/pi-design-deck.md +1102 -0
  101. data/docs/visual-skills/analysis/streamweaver-inventory.md +93 -0
  102. data/docs/visual-skills/analysis/unified-specs.feature +1003 -0
  103. data/docs/visual-skills/analysis/visual-explainer.md +964 -0
  104. data/docs/visual-skills/blog/blog-series-outline.md +39 -0
  105. data/docs/visual-skills/blog/token-efficiency.md +73 -0
  106. data/docs/visual-skills/design/architecture.md +1725 -0
  107. data/docs/visual-skills/design/codex-review.md +340 -0
  108. data/docs/visual-skills/design/dhh-review.md +209 -0
  109. data/docs/visual-skills/design/evolution.md +100 -0
  110. data/docs/visual-skills/design/gemini-review.md +55 -0
  111. data/docs/visual-skills/design/review-synthesis.md +149 -0
  112. data/docs/visual-skills/implementation/STATE.md +22 -0
  113. data/docs/visual-skills/implementation/plan.md +347 -0
  114. data/docs/visual-skills/implementation/spike-findings.md +237 -0
  115. data/docs/visual-skills/implementation/tasks.md +702 -0
  116. data/docs/visual-skills/lessons-learned/process.md +145 -0
  117. data/examples/README.md +96 -0
  118. data/examples/advanced/all_components.rb +177 -0
  119. data/examples/advanced/examples_browser.rb +394 -0
  120. data/examples/advanced/teachables_browser.rb +261 -0
  121. data/examples/advanced/theme_tweaker.rb +366 -0
  122. data/examples/advanced/tutorial.rb +1528 -0
  123. data/examples/agentic/agentic_form.rb +30 -0
  124. data/examples/agentic/agentic_form_autoclose.rb +30 -0
  125. data/examples/agentic/cultivation_tracker.rb +69 -0
  126. data/examples/basic/hello_world.rb +22 -0
  127. data/examples/basic/opal_tabs_table.rb +44 -0
  128. data/examples/basic/todo_list.rb +39 -0
  129. data/examples/button_loading_test.rb +36 -0
  130. data/examples/canvas/mermaid_canvas_demo.sh +151 -0
  131. data/examples/charts/bar_chart_demo.rb +57 -0
  132. data/examples/charts/line_chart_demo.rb +73 -0
  133. data/examples/charts/pie_area_demo.rb +87 -0
  134. data/examples/charts/stacked_bar_chart_demo.rb +69 -0
  135. data/examples/claude_code/README.md +85 -0
  136. data/examples/claude_code/codebreaker/.claude/commands/infiltrate.md +632 -0
  137. data/examples/claude_code/codebreaker/.claude/settings.json +11 -0
  138. data/examples/claude_code/codebreaker/.claude/settings.local.json +17 -0
  139. data/examples/claude_code/codebreaker/.claude/skills/infiltrate.md +0 -0
  140. data/examples/claude_code/codebreaker/README.md +213 -0
  141. data/examples/claude_code/tutorial/.claude/commands/learn.md +453 -0
  142. data/examples/claude_code/tutorial/README.md +102 -0
  143. data/examples/claude_code/verification_flow/.claude/commands/verify.md +171 -0
  144. data/examples/claude_code/verification_flow/README.md +126 -0
  145. data/examples/components/annotated_code_demo.rb +54 -0
  146. data/examples/components/callout_demo.rb +33 -0
  147. data/examples/components/checkbox_group_demo.rb +46 -0
  148. data/examples/components/design_review.css +468 -0
  149. data/examples/components/design_review_demo.rb +44 -0
  150. data/examples/components/design_review_dsl.rb +300 -0
  151. data/examples/components/diff_block_demo.rb +112 -0
  152. data/examples/components/events_demo.rb +184 -0
  153. data/examples/components/form_demo.rb +62 -0
  154. data/examples/components/lesson_demo.rb +53 -0
  155. data/examples/components/markdown_demo.rb +110 -0
  156. data/examples/components/mermaid_demo.rb +166 -0
  157. data/examples/components/pareto_set.rb +64 -0
  158. data/examples/components/prd_demo.rb +21 -0
  159. data/examples/components/prd_dsl.rb +385 -0
  160. data/examples/components/quiz_demo.rb +47 -0
  161. data/examples/components/run_viewer_demo.rb +100 -0
  162. data/examples/components/score_and_collapsible_demo.rb +82 -0
  163. data/examples/components/select_stale_value_smoke_test.rb +39 -0
  164. data/examples/components/table_demo.rb +247 -0
  165. data/examples/components/timer_with_state_demo.rb +58 -0
  166. data/examples/components/todo_due_dates.rb +63 -0
  167. data/examples/components/uat_gaps_demo.rb +112 -0
  168. data/examples/dashboard/feed_simulator.rb +60 -0
  169. data/examples/dashboard/live_dashboard.rb +80 -0
  170. data/examples/dashboard_components.rb +108 -0
  171. data/examples/deferred_fragments_demo.rb +62 -0
  172. data/examples/generate_more_spike/README.md +63 -0
  173. data/examples/generate_more_spike/app.rb +441 -0
  174. data/examples/git_health.sh +401 -0
  175. data/examples/layout/layout_components_demo.rb +174 -0
  176. data/examples/layout/modal_demo.rb +215 -0
  177. data/examples/layout/navigation_demo.rb +227 -0
  178. data/examples/layout/route_tabs_demo.rb +52 -0
  179. data/examples/layout/routing_demo.rb +52 -0
  180. data/examples/layout/scroll_box_demo.rb +154 -0
  181. data/examples/lazy_fragments_demo.rb +151 -0
  182. data/examples/my_todos/README.md +29 -0
  183. data/examples/my_todos/my_todos.rb +312 -0
  184. data/examples/my_todos/store.rb +86 -0
  185. data/examples/opal/reactive_demo.rb +62 -0
  186. data/examples/opal/scenarios/s1_counter.rb +15 -0
  187. data/examples/opal/scenarios/s2_search_filter.rb +17 -0
  188. data/examples/opal/scenarios/s3_sibling_tabs.rb +25 -0
  189. data/examples/opal/scenarios/s4_shopping_cart.rb +34 -0
  190. data/examples/opal/scenarios/s5_watch.rb +39 -0
  191. data/examples/opal/scenarios/s6_on_start.rb +20 -0
  192. data/examples/opal/scenarios/s7_wizard.rb +33 -0
  193. data/examples/opal/scenarios/s8_loan_calculator.rb +21 -0
  194. data/examples/opal/scenarios/s9_dashboard.rb +27 -0
  195. data/examples/operations_dashboard_demo.rb +167 -0
  196. data/examples/panel_demo.sh +447 -0
  197. data/examples/parity/assets/tyrion_slice.css +86 -0
  198. data/examples/parity/rivet_people_slice.rb +182 -0
  199. data/examples/parity/tyrion_components.css +777 -0
  200. data/examples/parity/tyrion_warroom_components.rb +414 -0
  201. data/examples/parity/tyrion_warroom_slice.rb +549 -0
  202. data/examples/puma_dev/README.md +124 -0
  203. data/examples/puma_dev/config.ru +34 -0
  204. data/examples/puma_dev/standalone_app.rb +34 -0
  205. data/examples/scaffolding/blog.rb +49 -0
  206. data/examples/scaffolding/utf_lite.rb +105 -0
  207. data/examples/styling/feedback_demo.rb +229 -0
  208. data/examples/styling/style_showcase.rb +172 -0
  209. data/examples/styling/theme_demo.rb +508 -0
  210. data/examples/timer_health_checker.rb +111 -0
  211. data/examples/timer_showcase.rb +131 -0
  212. data/examples/tutorials/render_markdown.rb +112 -0
  213. data/examples/tutorials/streamweaver_way_tutorial.rb +44 -0
  214. data/examples/tutorials/tutorial_content.rb +1082 -0
  215. data/examples/visual_skills/design_deck_demo.rb +314 -0
  216. data/examples/visual_skills/explainer_demo.rb +499 -0
  217. data/exe/streamweaver +9 -0
  218. data/gsd/ROADMAP-1.0.md +167 -0
  219. data/gsd/STATE.md +13 -0
  220. data/gsd/research/market-positioning-research.md +139 -0
  221. data/gsd/research/production-patterns-research.md +270 -0
  222. data/gsd/research/repo-audit-1.0.md +274 -0
  223. data/lib/stream_weaver/action_token.rb +58 -0
  224. data/lib/stream_weaver/adapter/alpinejs.rb +8249 -0
  225. data/lib/stream_weaver/adapter/base.rb +591 -0
  226. data/lib/stream_weaver/adapter/opal.rb +334 -0
  227. data/lib/stream_weaver/adapter/static.rb +1118 -0
  228. data/lib/stream_weaver/admin.rb +176 -0
  229. data/lib/stream_weaver/app.rb +1821 -0
  230. data/lib/stream_weaver/assets/js/sw-copy.js +50 -0
  231. data/lib/stream_weaver/assets/js/sw-heredoc-rewrite.js +68 -0
  232. data/lib/stream_weaver/assets/js/sw-keyboard.js +165 -0
  233. data/lib/stream_weaver/assets/js/sw-mermaid-zoom.js +621 -0
  234. data/lib/stream_weaver/assets/js/sw-route-tabs.js +53 -0
  235. data/lib/stream_weaver/assets/js/sw-sidebar-toc.js +116 -0
  236. data/lib/stream_weaver/assets/js/sw-slide-nav.js +103 -0
  237. data/lib/stream_weaver/canvas/bridge.rb +239 -0
  238. data/lib/stream_weaver/canvas/bridge_server.rb +646 -0
  239. data/lib/stream_weaver/canvas/client.rb +298 -0
  240. data/lib/stream_weaver/canvas/doc_roots.rb +233 -0
  241. data/lib/stream_weaver/canvas/doc_store.rb +252 -0
  242. data/lib/stream_weaver/canvas/gist_publisher.rb +264 -0
  243. data/lib/stream_weaver/canvas/gist_save_handler.rb +89 -0
  244. data/lib/stream_weaver/canvas/gist_store.rb +135 -0
  245. data/lib/stream_weaver/canvas/helpers.rb +109 -0
  246. data/lib/stream_weaver/canvas/history.rb +90 -0
  247. data/lib/stream_weaver/canvas/protocol.rb +86 -0
  248. data/lib/stream_weaver/canvas/reader.rb +853 -0
  249. data/lib/stream_weaver/canvas/save_doc_widget.rb +457 -0
  250. data/lib/stream_weaver/canvas/scroll_top_hint.rb +21 -0
  251. data/lib/stream_weaver/canvas/session.rb +132 -0
  252. data/lib/stream_weaver/cli.rb +3235 -0
  253. data/lib/stream_weaver/component_assets.rb +70 -0
  254. data/lib/stream_weaver/component_registry.rb +67 -0
  255. data/lib/stream_weaver/component_renderer.rb +48 -0
  256. data/lib/stream_weaver/components/annotated_code.rb +53 -0
  257. data/lib/stream_weaver/components/api_endpoint.rb +42 -0
  258. data/lib/stream_weaver/components/callout.rb +59 -0
  259. data/lib/stream_weaver/components/chart.rb +84 -0
  260. data/lib/stream_weaver/components/code_block.rb +77 -0
  261. data/lib/stream_weaver/components/comparison.rb +39 -0
  262. data/lib/stream_weaver/components/decision.rb +38 -0
  263. data/lib/stream_weaver/components/deck/close_overlay.rb +84 -0
  264. data/lib/stream_weaver/components/deck/confirmation_bar.rb +60 -0
  265. data/lib/stream_weaver/components/deck/deck_option.rb +61 -0
  266. data/lib/stream_weaver/components/deck/deck_slide.rb +77 -0
  267. data/lib/stream_weaver/components/deck/deck_state.rb +469 -0
  268. data/lib/stream_weaver/components/deck/deck_summary.rb +73 -0
  269. data/lib/stream_weaver/components/deck/design_deck.rb +60 -0
  270. data/lib/stream_weaver/components/deck/generate_more_controls.rb +84 -0
  271. data/lib/stream_weaver/components/deck/model_selector.rb +84 -0
  272. data/lib/stream_weaver/components/deck/skeleton_placeholder.rb +36 -0
  273. data/lib/stream_weaver/components/diff_block.rb +125 -0
  274. data/lib/stream_weaver/components/doc_header.rb +57 -0
  275. data/lib/stream_weaver/components/image_block.rb +70 -0
  276. data/lib/stream_weaver/components/implementation_map.rb +33 -0
  277. data/lib/stream_weaver/components/keyboard_shortcuts.rb +94 -0
  278. data/lib/stream_weaver/components/kpi_dashboard.rb +78 -0
  279. data/lib/stream_weaver/components/mermaid.rb +79 -0
  280. data/lib/stream_weaver/components/pipeline.rb +63 -0
  281. data/lib/stream_weaver/components/sidebar_toc.rb +46 -0
  282. data/lib/stream_weaver/components/slide_container.rb +141 -0
  283. data/lib/stream_weaver/components/timeline_event.rb +58 -0
  284. data/lib/stream_weaver/components/wireframe.rb +29 -0
  285. data/lib/stream_weaver/components/wireframe_block.rb +34 -0
  286. data/lib/stream_weaver/components.rb +2711 -0
  287. data/lib/stream_weaver/css.rb +230 -0
  288. data/lib/stream_weaver/dev_fallback_overlay.rb +61 -0
  289. data/lib/stream_weaver/display_dsl.rb +1004 -0
  290. data/lib/stream_weaver/export/html_exporter.rb +478 -0
  291. data/lib/stream_weaver/feed.rb +34 -0
  292. data/lib/stream_weaver/feed_builder.rb +31 -0
  293. data/lib/stream_weaver/fonts.rb +33 -0
  294. data/lib/stream_weaver/interaction_runner.rb +487 -0
  295. data/lib/stream_weaver/iterm.rb +460 -0
  296. data/lib/stream_weaver/layout_registry.rb +92 -0
  297. data/lib/stream_weaver/opal/bridge.rb +52 -0
  298. data/lib/stream_weaver/opal/builder.rb +193 -0
  299. data/lib/stream_weaver/opal/env.rb +29 -0
  300. data/lib/stream_weaver/opal/reactive_state.rb +75 -0
  301. data/lib/stream_weaver/opal/regexp_anchor_patch.rb +62 -0
  302. data/lib/stream_weaver/opal/renderer.rb +77 -0
  303. data/lib/stream_weaver/opal/runtime.rb +250 -0
  304. data/lib/stream_weaver/opal/shell.rb +145 -0
  305. data/lib/stream_weaver/opal/string_bridge.rb +50 -0
  306. data/lib/stream_weaver/opal/stubs/diff.min.js +1 -0
  307. data/lib/stream_weaver/opal/stubs/digest.rb +15 -0
  308. data/lib/stream_weaver/opal/stubs/marked.umd.js +79 -0
  309. data/lib/stream_weaver/opal/stubs/md5.rb +3 -0
  310. data/lib/stream_weaver/opal/stubs/morphdom.min.js +775 -0
  311. data/lib/stream_weaver/opal/stubs/prism-tomorrow.min.css +1 -0
  312. data/lib/stream_weaver/opal/stubs/prism.min.js +1967 -0
  313. data/lib/stream_weaver/opal_entry.rb +136 -0
  314. data/lib/stream_weaver/org/inline.rb +95 -0
  315. data/lib/stream_weaver/org/reader.rb +561 -0
  316. data/lib/stream_weaver/org/recording_context.rb +86 -0
  317. data/lib/stream_weaver/org/source_splitter.rb +63 -0
  318. data/lib/stream_weaver/org/writer.rb +300 -0
  319. data/lib/stream_weaver/page_shell.rb +530 -0
  320. data/lib/stream_weaver/portfile.rb +79 -0
  321. data/lib/stream_weaver/pushable.rb +42 -0
  322. data/lib/stream_weaver/resource/default_views.rb +111 -0
  323. data/lib/stream_weaver/resource/field_input.rb +25 -0
  324. data/lib/stream_weaver/resource/state_keys.rb +16 -0
  325. data/lib/stream_weaver/resource/store.rb +18 -0
  326. data/lib/stream_weaver/resource.rb +104 -0
  327. data/lib/stream_weaver/server.rb +1471 -0
  328. data/lib/stream_weaver/service.rb +1240 -0
  329. data/lib/stream_weaver/service_client.rb +104 -0
  330. data/lib/stream_weaver/session_store.rb +186 -0
  331. data/lib/stream_weaver/skills/streamweaver-canvas-safe/SKILL.md +66 -0
  332. data/lib/stream_weaver/skills/streamweaver-canvas-safe/examples/canvas-safe-showcase.rb +98 -0
  333. data/lib/stream_weaver/skills/streamweaver-canvas-safe/references/actions-and-buttons.md +47 -0
  334. data/lib/stream_weaver/skills/streamweaver-canvas-safe/references/charts-and-diagrams.md +38 -0
  335. data/lib/stream_weaver/skills/streamweaver-canvas-safe/references/deck.md +32 -0
  336. data/lib/stream_weaver/skills/streamweaver-canvas-safe/references/inputs-and-forms.md +65 -0
  337. data/lib/stream_weaver/skills/streamweaver-canvas-safe/references/tabs-and-navigation.md +53 -0
  338. data/lib/stream_weaver/skills/streamweaver-doc-builder/SKILL.md +298 -0
  339. data/lib/stream_weaver/skills/streamweaver-visual-companion/SKILL.md +130 -0
  340. data/lib/stream_weaver/skills/streamweaver-visual-companion/examples/design-review-example.css +468 -0
  341. data/lib/stream_weaver/skills/streamweaver-visual-companion/examples/design-review-example.rb +39 -0
  342. data/lib/stream_weaver/skills/streamweaver-visual-companion/examples/design-review-example_dsl.rb +300 -0
  343. data/lib/stream_weaver/skills/streamweaver-visual-companion/examples/doc-parity-example.rb +24 -0
  344. data/lib/stream_weaver/skills/streamweaver-visual-companion/examples/doc-parity-example_dsl.rb +385 -0
  345. data/lib/stream_weaver/skills/streamweaver-visual-companion/references/checkpoints-and-forms.md +28 -0
  346. data/lib/stream_weaver/skills/streamweaver-visual-companion/references/cleanup-and-panel.md +44 -0
  347. data/lib/stream_weaver/skills/streamweaver-visual-companion/references/example-gallery.md +8 -0
  348. data/lib/stream_weaver/skills/streamweaver-visual-companion/references/persistence.md +58 -0
  349. data/lib/stream_weaver/skills/streamweaver-way/SKILL.md +396 -0
  350. data/lib/stream_weaver/skills/visual-plan/SKILL.md +201 -0
  351. data/lib/stream_weaver/skills/visual-recap/SKILL.md +244 -0
  352. data/lib/stream_weaver/streamer.rb +63 -0
  353. data/lib/stream_weaver/templates/choices.rb +149 -0
  354. data/lib/stream_weaver/templates/code.rb +157 -0
  355. data/lib/stream_weaver/templates/confirm.rb +110 -0
  356. data/lib/stream_weaver/templates/diff.rb +195 -0
  357. data/lib/stream_weaver/templates/info.rb +142 -0
  358. data/lib/stream_weaver/templates/table.rb +169 -0
  359. data/lib/stream_weaver/templates/wizard.rb +271 -0
  360. data/lib/stream_weaver/theme/auto_mode.rb +116 -0
  361. data/lib/stream_weaver/theme/presets.rb +555 -0
  362. data/lib/stream_weaver/theme.rb +639 -0
  363. data/lib/stream_weaver/university/canvas.rb +924 -0
  364. data/lib/stream_weaver/university/course.rb +699 -0
  365. data/lib/stream_weaver/university/demos/counter.rb +33 -0
  366. data/lib/stream_weaver/university/demos/dashboard.rb +147 -0
  367. data/lib/stream_weaver/university/demos/decision_form.rb +143 -0
  368. data/lib/stream_weaver/university/demos.rb +50 -0
  369. data/lib/stream_weaver/university/listener.rb +467 -0
  370. data/lib/stream_weaver/university/progress.rb +201 -0
  371. data/lib/stream_weaver/university/runner.rb +138 -0
  372. data/lib/stream_weaver/university/scripts/growing_doc.rb +609 -0
  373. data/lib/stream_weaver/university/scripts/growing_doc_state.rb +91 -0
  374. data/lib/stream_weaver/utils.rb +31 -0
  375. data/lib/stream_weaver/version.rb +5 -0
  376. data/lib/stream_weaver/views/canvas/reader_layout.erb +800 -0
  377. data/lib/stream_weaver/views.rb +3940 -0
  378. data/lib/stream_weaver.rb +122 -0
  379. data/llms.txt +1269 -0
  380. data/sig/stream_weaver.rbs +4 -0
  381. metadata +598 -0
@@ -0,0 +1,401 @@
1
+ # StreamWeaver for AI Agents
2
+
3
+ A guide to building visual UI for AI agent workflows with minimal token overhead.
4
+
5
+ ## The Problem
6
+
7
+ AI agents need visual UI, but the options are frustrating:
8
+
9
+ **Terminal output** is hard to parse. Complex choices become walls of text. Multi-step workflows turn into scrolling nightmares. Users lose context.
10
+
11
+ **HTML/React** is verbose. A simple form is 50+ lines. AI generation is slow and expensive. Token costs matter—slower, more expensive, less context available for the actual problem.
12
+
13
+ **What agents actually need:**
14
+ - Quick visual feedback for complex choices
15
+ - Forms that don't require parsing natural language
16
+ - Progress indicators and status displays
17
+ - Charts and data visualization
18
+ - All without burning context on boilerplate
19
+
20
+ ## The Solution: Concise DSL
21
+
22
+ StreamWeaver is a Ruby DSL that renders to HTML. Many components, clear syntax, fast to build real apps.
23
+
24
+ ### Token Comparison
25
+
26
+ A form with 3 fields and a button:
27
+
28
+ **StreamWeaver DSL** (~45 tokens):
29
+ ```ruby
30
+ card do
31
+ header1 "Sign Up"
32
+ text_field :email, placeholder: "you@example.com", label: "Email"
33
+ text_field :name, placeholder: "Your Name", label: "Name"
34
+ text_field :company, label: "Company"
35
+ button "Submit", id: "btn_submit", style: :primary
36
+ end
37
+ ```
38
+
39
+ **HTML** (~200+ tokens):
40
+ ```html
41
+ <div class="card">
42
+ <h1>Sign Up</h1>
43
+ <div class="form-group">
44
+ <label for="email">Email</label>
45
+ <input type="text" id="email" name="email" placeholder="you@example.com" class="form-control">
46
+ </div>
47
+ <div class="form-group">
48
+ <label for="name">Name</label>
49
+ <input type="text" id="name" name="name" placeholder="Your Name" class="form-control">
50
+ </div>
51
+ <div class="form-group">
52
+ <label for="company">Company</label>
53
+ <input type="text" id="company" name="company" class="form-control">
54
+ </div>
55
+ <button type="submit" class="btn btn-primary">Submit</button>
56
+ </div>
57
+ ```
58
+
59
+ **React** (~300+ tokens):
60
+ ```jsx
61
+ function SignUpForm() {
62
+ const [email, setEmail] = useState('');
63
+ const [name, setName] = useState('');
64
+ const [company, setCompany] = useState('');
65
+
66
+ return (
67
+ <div className="card">
68
+ <h1>Sign Up</h1>
69
+ <div className="form-group">
70
+ <label htmlFor="email">Email</label>
71
+ <input
72
+ type="text"
73
+ id="email"
74
+ value={email}
75
+ onChange={(e) => setEmail(e.target.value)}
76
+ placeholder="you@example.com"
77
+ />
78
+ </div>
79
+ {/* ... more fields ... */}
80
+ <button type="submit" className="btn btn-primary">Submit</button>
81
+ </div>
82
+ );
83
+ }
84
+ ```
85
+
86
+ That's **5-7x fewer tokens** for the same UI. For AI generation, this means:
87
+ - Faster responses
88
+ - Lower cost
89
+ - More context available for actual work
90
+
91
+ ### Component Variety
92
+
93
+ StreamWeaver includes components for common agent needs:
94
+
95
+ | Category | Components |
96
+ |----------|------------|
97
+ | Layout | `card`, `columns`, `hstack`, `vstack`, `collapsible` |
98
+ | Text | `header1`-`header4`, `text`, `md` (markdown) |
99
+ | Forms | `text_field`, `radio_group`, `checkbox`, `select`, `button` |
100
+ | Data | `table`, `bar_chart`, `pie_chart`, `stat_display` |
101
+ | Status | `status_dot`, `progress_bar`, `spinner`, `badge`, `alert` |
102
+ | Media | `image`, `video`, `audio` |
103
+
104
+ ### CRITICAL: Never Put Markdown Inside `text`
105
+
106
+ `text` is a literal renderer — markdown syntax appears as raw characters on screen.
107
+
108
+ ```ruby
109
+ # WRONG — renders as: **Select the article PDF:** (asterisks visible to user)
110
+ text "**Select the article PDF:**"
111
+
112
+ # CORRECT — use md for markdown formatting
113
+ md "**Select the article PDF:**"
114
+
115
+ # BETTER — use semantic headers for labels and section titles
116
+ header3 "Select the article PDF:"
117
+ header4 "What do you want to know?"
118
+ ```
119
+
120
+ Use `text` only for plain prose. Use `md` when you need inline markdown (bold, italic, links, code). Use `header1`–`header6` for structural headings and form-section labels.
121
+
122
+ ## The Modes Gamut
123
+
124
+ StreamWeaver supports multiple modes, from full standalone apps to persistent canvas sessions with Claude Code.
125
+
126
+ | Mode | Use Case | Process Model | Example |
127
+ |------|----------|---------------|---------|
128
+ | **Standalone** | Full applications | `streamweaver app.rb` | Rivet, tutorial.rb, theme_tweaker |
129
+ | **Agentic** (`run_once!`) | Mid-task UI from scripts | Generate → wait → parse JSON | Quick prompts, confirmations |
130
+ | **Service** | Multi-app hosting | Long-running server, reuse apps | Dashboard with multiple widgets |
131
+ | **Canvas/Panel** | Claude Code companion | Persistent session, push/wait | codebreaker, verification_flow |
132
+
133
+ ### Standalone Mode
134
+
135
+ Full applications that run independently.
136
+
137
+ ```bash
138
+ streamweaver my_app.rb
139
+ ```
140
+
141
+ Good for:
142
+ - Reusable tools and utilities
143
+ - Self-documenting tutorials
144
+ - Applications that run outside agent workflows
145
+
146
+ Example: `examples/advanced/tutorial.rb` teaches StreamWeaver using StreamWeaver itself.
147
+
148
+ ### Agentic Mode (`run_once!`)
149
+
150
+ Quick UI mid-script. Generate DSL, render, wait for input, parse JSON response.
151
+
152
+ ```ruby
153
+ require 'stream_weaver'
154
+
155
+ result = StreamWeaver.run_once! do
156
+ card do
157
+ header1 "Quick Question"
158
+ radio_group :choice, ["Option A", "Option B", "Option C"]
159
+ button "Continue", id: "btn_continue", style: :primary
160
+ end
161
+ end
162
+
163
+ puts "User chose: #{result['choice']}"
164
+ ```
165
+
166
+ Good for:
167
+ - Confirmation dialogs
168
+ - Quick selections
169
+ - Mid-workflow decisions
170
+
171
+ ### Service Mode
172
+
173
+ Long-running server that hosts multiple apps. Avoids startup overhead when switching between apps.
174
+
175
+ ```bash
176
+ streamweaver service start
177
+ streamweaver service add my_app.rb
178
+ streamweaver service status
179
+ ```
180
+
181
+ Good for:
182
+ - Dashboard with multiple widgets
183
+ - Frequently-used utilities
184
+ - Development workflows
185
+
186
+ ### Canvas/Panel Mode
187
+
188
+ Persistent session with Claude Code. The agent opens a panel, pushes updates, waits for input, and continues the conversation.
189
+
190
+ ```bash
191
+ # Open a panel (browser in iTerm split pane)
192
+ streamweaver panel my_session
193
+
194
+ # Push DSL content (via stdin)
195
+ streamweaver canvas-push my_session <<'DSL'
196
+ card do
197
+ header1 "Working..."
198
+ spinner label: "Processing files..."
199
+ end
200
+ DSL
201
+
202
+ # Wait for user interaction (returns JSON)
203
+ streamweaver canvas-wait my_session
204
+
205
+ # Show toast notification
206
+ streamweaver canvas-toast my_session "Check terminal for input"
207
+
208
+ # Close when done
209
+ streamweaver canvas-close my_session
210
+ ```
211
+
212
+ Good for:
213
+ - Multi-phase Claude Code workflows
214
+ - Real-time status updates
215
+ - Interactive analysis tools
216
+
217
+ ## Remote & Mobile Access
218
+
219
+ StreamWeaver apps aren't limited to localhost. With Tailscale or LAN access, the same app you build for local use becomes a mobile dashboard:
220
+
221
+ ```bash
222
+ # Access from your phone via Tailscale
223
+ STREAMWEAVER_HOST=0.0.0.0 STREAMWEAVER_PORT=4580 ruby dashboard.rb
224
+ # → http://your-machine:4580 from any Tailscale device
225
+ ```
226
+
227
+ Or in code:
228
+ ```ruby
229
+ app "Ops Dashboard", theme: :dark do
230
+ # ... status displays, charts, priority items
231
+ end.run!(host: '0.0.0.0', port: 4580)
232
+ ```
233
+
234
+ This opens up use cases like:
235
+ - **Mobile monitoring** — check build status, deployment health from your phone
236
+ - **Team dashboards** — share a StreamWeaver app across Tailscale for team visibility
237
+ - **Remote agentic UI** — trigger agent workflows from a tablet while away from your desk
238
+
239
+ The fixed port ensures bookmarks and home screen shortcuts stay stable across restarts.
240
+
241
+ ## When to Use What
242
+
243
+ ```
244
+ ┌─────────────────────┐
245
+ │ What are you │
246
+ │ building? │
247
+ └──────────┬──────────┘
248
+
249
+ ┌──────────────────────────┼──────────────────────────┐
250
+ │ │ │
251
+ ▼ ▼ ▼
252
+ ┌────────────────┐ ┌────────────────┐ ┌────────────────┐
253
+ │ Reusable app │ │ Quick UI in │ │ Claude Code │
254
+ │ or tool? │ │ a script? │ │ integration? │
255
+ └───────┬────────┘ └───────┬────────┘ └───────┬────────┘
256
+ │ │ │
257
+ ▼ ▼ │
258
+ ┌────────────────┐ ┌────────────────┐ │
259
+ │ STANDALONE │ │ AGENTIC │ │
260
+ │ streamweaver │ │ run_once! │ │
261
+ │ app.rb │ │ │ │
262
+ └────────────────┘ └────────────────┘ │
263
+
264
+ ┌───────────────────────┴───────────────────────┐
265
+ │ │
266
+ ▼ ▼
267
+ ┌────────────────┐ ┌────────────────┐
268
+ │ Single │ │ Multi-app │
269
+ │ workflow? │ │ dashboard? │
270
+ └───────┬────────┘ └───────┬────────┘
271
+ │ │
272
+ ▼ ▼
273
+ ┌────────────────┐ ┌────────────────┐
274
+ │ CANVAS/PANEL │ │ SERVICE │
275
+ │ slash command │ │ multi-app │
276
+ │ + heredocs │ │ hosting │
277
+ └────────────────┘ └────────────────┘
278
+ ```
279
+
280
+ ## Canvas/Panel Patterns
281
+
282
+ The canvas/panel mode is the most common for Claude Code integration. Key patterns:
283
+
284
+ ### Pattern A: Progress While Working
285
+
286
+ Show a spinner while Claude does actual work:
287
+
288
+ ```bash
289
+ # Push spinner (with canvas_continue)
290
+ streamweaver canvas-push session <<'DSL'
291
+ canvas_continue message: "Analyzing..."
292
+ card do
293
+ header1 "Working"
294
+ spinner label: "Processing files..."
295
+ end
296
+ DSL
297
+
298
+ # DO THE ACTUAL WORK (Glob, Grep, Read, etc.)
299
+ # ...
300
+
301
+ # Push results (NO canvas_continue)
302
+ streamweaver canvas-push session <<'DSL'
303
+ card do
304
+ header1 "Results"
305
+ table headers: ["File", "Lines"], rows: [["main.rb", "150"]]
306
+ button "Continue", id: "btn_continue", style: :primary
307
+ end
308
+ DSL
309
+
310
+ # Wait for user
311
+ streamweaver canvas-wait session
312
+ ```
313
+
314
+ ### Pattern B: Form Interaction
315
+
316
+ Show a form and wait for user input:
317
+
318
+ ```bash
319
+ # Push form (NO canvas_continue)
320
+ streamweaver canvas-push session <<'DSL'
321
+ card do
322
+ header1 "Choose Options"
323
+ radio_group :choice, ["Option A", "Option B"]
324
+ button "Submit", id: "btn_submit", style: :primary
325
+ end
326
+ DSL
327
+
328
+ # Wait for user
329
+ streamweaver canvas-wait session
330
+ ```
331
+
332
+ **Critical:** Never combine `canvas_continue` with `canvas-wait`. That's contradictory:
333
+ - `canvas_continue` says "I'm working, here's a spinner"
334
+ - `canvas-wait` says "I'm done, waiting for you"
335
+
336
+ ### Toast for Terminal Prompts
337
+
338
+ When Claude needs permission for tools, toast alerts the user:
339
+
340
+ ```bash
341
+ streamweaver canvas-toast session "Check terminal for authorization" --variant warning
342
+ ```
343
+
344
+ ## Real Examples
345
+
346
+ ### codebreaker
347
+
348
+ Spy-themed code analysis tool. Demonstrates:
349
+ - Multi-phase workflow (briefing → reconnaissance → report → deep analysis)
350
+ - Component variety (charts, tables, status dots, progress bars)
351
+ - Dynamic DSL generation based on analysis results
352
+ - `canvas_continue` for progress, `canvas-wait` for interaction
353
+
354
+ ### verification_flow
355
+
356
+ Realistic 2FA-style account verification. Demonstrates:
357
+ - Form collection across multiple steps
358
+ - Status page updates during provisioning
359
+ - Toast usage for terminal prompts
360
+ - Clean phase transitions
361
+
362
+ ### tutorial (Claude Code)
363
+
364
+ Conversational canvas tutorial. Demonstrates:
365
+ - Freeform exploration (no fixed order)
366
+ - Dynamic DSL generation based on questions
367
+ - Code + rendered output in same view
368
+ - Iterative refinement ("make it blue")
369
+
370
+ ## Creating Your Own
371
+
372
+ 1. Create directory with `.claude/commands/yourcommand.md`
373
+ 2. Write instructions with canvas-push heredocs and canvas-wait
374
+ 3. Add `.claude/settings.local.json` for permissions:
375
+
376
+ ```json
377
+ {
378
+ "permissions": {
379
+ "allow": [
380
+ "Bash(streamweaver panel:*)",
381
+ "Bash(streamweaver canvas-push:*)",
382
+ "Bash(streamweaver canvas-wait:*)",
383
+ "Bash(streamweaver canvas-toast:*)",
384
+ "Bash(streamweaver canvas-close:*)"
385
+ ]
386
+ }
387
+ }
388
+ ```
389
+
390
+ 4. Run with `/yourcommand` in Claude Code
391
+
392
+ ## Summary
393
+
394
+ StreamWeaver makes AI agent UI practical:
395
+
396
+ - **Concise DSL**: 5-7x fewer tokens than HTML/React
397
+ - **Rich components**: Forms, charts, tables, status indicators
398
+ - **Multiple modes**: Standalone apps to Claude Code canvases
399
+ - **Simple patterns**: Push DSL, wait for JSON, repeat
400
+
401
+ Build what you need to show, not the infrastructure to show it.
@@ -0,0 +1,123 @@
1
+ # StreamWeaver Frontend Vision
2
+
3
+ ## The Thesis
4
+
5
+ A **Hotwire-equivalent frontend stack for Ruby/Rails developers**, built on lighter infrastructure than Hotwire and with no build step:
6
+
7
+ ```
8
+ Ruby DSL + htmx + Alpine.js + Idiomorph
9
+ ```
10
+
11
+ Same capabilities as Turbo + Stimulus, but cheaper to load, easier to read for Rails developers, and aligned with the way StreamWeaver already ships UI: a Ruby DSL renders complete server-side pages, the browser swaps regions intelligently, and nobody runs `npm install`.
12
+
13
+ The goal is to make StreamWeaver the obvious choice when a Ruby developer wants to build a browser UI without leaving Ruby — and to make those apps **look and feel like well-built Rails apps** so anyone with Rails muscle memory can read them.
14
+
15
+ ## Why Not Hotwire Directly
16
+
17
+ Hotwire is excellent. The reasons we're not adopting it wholesale:
18
+
19
+ - **Asset pipeline assumptions.** Turbo and Stimulus expect a Rails-flavored build pipeline (importmaps, esbuild, propshaft). StreamWeaver apps are a single Ruby file plus a CDN script tag — bringing in Hotwire's tooling violates that promise.
20
+ - **Bundle size.** Turbo (~30kb) + Stimulus (~10kb) is fine in absolute terms but heavier than htmx (~10kb) + Alpine (~15kb) + Idiomorph (~5kb).
21
+ - **Tied to a worldview.** Stimulus controllers are JavaScript classes registered to DOM elements. Alpine declarations live inline in the markup, closer to the data they affect. For Ruby developers used to ERB partials with embedded behavior, Alpine is a smaller mental jump.
22
+ - **Token efficiency.** Alpine inline declarations and htmx attributes are token-cheap when an LLM is generating views — relevant given how much of StreamWeaver gets written by Claude.
23
+
24
+ We are not anti-Hotwire. We are choosing the same shape with lighter materials.
25
+
26
+ ## What We Keep From Hotwire
27
+
28
+ - **Server renders complete pages.** No virtual DOM in the browser, no client-side router, no JSON-and-render-on-client pattern. The server is the source of truth for what the page looks like.
29
+ - **Diff-based morph for navigation.** Idiomorph is literally the same algorithm Turbo 8 uses; we adopt it directly. State preservation across navigation comes from the morph algorithm, not from explicit per-region swap configuration.
30
+ - **Bookmarkable resource URLs.** Every meaningful view has its own URL. Users can share links, back-button works, refresh works.
31
+ - **Forms POST to controllers, return updated views.** No client-side form state machines. The server says what the page should look like after a submission.
32
+
33
+ ## What We Use Instead
34
+
35
+ | Hotwire | StreamWeaver convention | Why |
36
+ |---|---|---|
37
+ | Turbo Drive | htmx `hx-boost` | Lighter, no build step, same UX |
38
+ | Turbo Frames | htmx `hx-target`/`hx-swap` | More explicit, less opinionated, fits htmx idioms |
39
+ | Turbo Streams | htmx out-of-band swaps + Alpine | OOB covers the partial-update case; Alpine covers the live-update case |
40
+ | Stimulus controllers | Alpine `x-data` declarations | Closer to the markup, no separate JS file per component |
41
+ | Idiomorph (extracted from Turbo) | Idiomorph (used directly) | Same library |
42
+
43
+ ## Rails-isms We Are Adopting
44
+
45
+ This is the part of the vision still being filled in. Confirmed directions:
46
+
47
+ ### Resource URLs
48
+ Every meaningful view gets a Rails-style resource URL. No positional indexes that depend on local server state.
49
+
50
+ ```
51
+ /docs/:name # show
52
+ /docs # index
53
+ /history/:session # session's history
54
+ /history/:session/:timestamp # specific snapshot
55
+ ```
56
+
57
+ Filed as bd `stream_weaver-9ei`.
58
+
59
+ ### Routes-as-conventions
60
+ Sidebar navigation, Prev/Next links, all link emission produces these resource URLs. No hand-rolled query-string indexes.
61
+
62
+ ### Layouts and Partials (in progress)
63
+ Templates compose from a layout + content + nav region structure. Partials would be a future addition once the layout convention stabilizes.
64
+
65
+ ### Forms (open question)
66
+ Rails form helpers (`form_with`, `form_for`, `f.text_field`) translate naturally to a StreamWeaver DSL. The user has signaled interest in stealing the patterns:
67
+
68
+ ```ruby
69
+ form_with(url: "/docs", method: :post) do |f|
70
+ f.text_field :name
71
+ f.submit "Save"
72
+ end
73
+ ```
74
+
75
+ This is **not yet implemented**. It is on the roadmap. The current DSL has `text_field :name, placeholder: "..."` which is closer to Rails' `text_field_tag`. Migrating to a `form_with`-style block is plausible.
76
+
77
+ ### Scaffolding (long-term)
78
+ A `streamweaver new <name>` generator that scaffolds a resource (model + canvas templates + URLs) following these conventions. This is well downstream — the conventions need to stabilize first.
79
+
80
+ ## Naming
81
+
82
+ The combined frontend stack ("htmx + Alpine + Idiomorph + StreamWeaver DSL with resource URL conventions") deserves a name so it can be referred to as a unit. Working title: **streamwire** (StreamWeaver + Hotwire-shape). Open to alternatives. The naming matters because once a thing is named, conventions can be enforced ("this should follow streamwire patterns") instead of restated each time.
83
+
84
+ ## State Conventions
85
+
86
+ Where each kind of state lives:
87
+
88
+ | State type | Lives in | Examples |
89
+ |---|---|---|
90
+ | What is being viewed | URL | which doc, which session, which tab |
91
+ | Persistent data | Server (file/DB) | saved docs, user preferences |
92
+ | Ephemeral UI state | Client (Alpine) | dialog open/closed, dropdown expanded |
93
+ | In-progress input | Client (Alpine) | text being typed before submit |
94
+ | Bookmarkable filters | URL query string | search query, sort order |
95
+
96
+ The principle: **state is in the URL when sharing/bookmarking the URL should restore it.** Otherwise it's client-only.
97
+
98
+ ## What Solves What
99
+
100
+ The recurring bug pattern Forrest has hit ("my apps reload the whole page and lose state") is solved structurally by Idiomorph. Once the bridge_server and reader templates use morph as the default swap strategy, future features inherit state preservation without thinking about it. No new feature can accidentally regress to "click → full reload → lose accordion state" because that path stops existing in the layouts.
101
+
102
+ ## Path Forward
103
+
104
+ 1. **Adopt Idiomorph in StreamWeaver layouts** (bd `stream_weaver-2ds`, P2). Replaces hand-rolled OOB swaps and JS active-class fixups with one extension.
105
+ 2. **Adopt resource URLs in canvas-read** (bd `stream_weaver-9ei`, P2). Establishes the URL convention.
106
+ 3. **Document everything in `llms.txt` (linked as `docs/for_llms.md`)** so LLMs build new apps correctly without rediscovering the patterns. This is the most important deliverable — Forrest reports significant churn from unclear conventions.
107
+ 4. **Migrate existing examples** to the conventions once the patterns are documented. Existing apps under `examples/` become reference material.
108
+ 5. **(Later)** Forms — translate Rails form helpers to the DSL.
109
+ 6. **(Later)** Scaffolding generator.
110
+
111
+ ## Open Questions
112
+
113
+ - Naming: streamwire? streamweave? something else?
114
+ - Forms: how much Rails form helper API to mirror exactly?
115
+ - Multi-page apps: routing conventions for apps with several resources
116
+ - Asset handling: how a single-file Ruby app declares its own CSS/JS without a build step
117
+ - Testing: convention for testing StreamWeaver views (currently spec-by-rendered-HTML — fine for now)
118
+
119
+ These get answered as the conventions get exercised by real apps.
120
+
121
+ ---
122
+
123
+ *This document captures the strategic direction. For the practical "how to build a StreamWeaver app correctly" guide, see `llms.txt` (linked as `docs/for_llms.md`).*
@@ -0,0 +1,77 @@
1
+ # streamweaver-doc: v1
2
+ header1 "Glimmer: Inspired By, Not Dependent On"
3
+
4
+ div(style: "height:8px")
5
+
6
+ columns widths: ["50%", "50%"] do
7
+ column do
8
+ card do
9
+ header3 "Why we skip the Glimmer gem"
10
+ badge "Too heavy for Opal", color: :red
11
+ div(style: "height:8px")
12
+ md "Glimmer depends on **facets** — a massive Ruby utility library. Compiled to Opal, facets alone balloons the JS bundle."
13
+ div(style: "height:8px")
14
+ md "Also: the `<=>` / `<=` binding syntax is confusing — it reuses comparison operators for a completely different meaning."
15
+ div(style: "height:8px")
16
+ md "We take the **ideas**, not the code."
17
+ end
18
+ end
19
+ column do
20
+ card do
21
+ header3 "What we take from Glimmer"
22
+ badge "Conceptual only", color: :green
23
+ div(style: "height:8px")
24
+ md "**Observer pattern** — the right model for reactive state"
25
+ md "**Direct DOM** (no virtual DOM) — proven to be sufficient"
26
+ md "**Observable model enhancement** — state auto-notifies observers when keys change"
27
+ div(style: "height:8px")
28
+ md "We implement this in ~70 lines of pure Ruby/Opal. No dependencies."
29
+ end
30
+ end
31
+ end
32
+
33
+ div(style: "height:24px")
34
+ header2 "ReactiveState: ~70 Lines, Zero Deps"
35
+ div(style: "height:8px")
36
+
37
+ card do
38
+ header3 "Design"
39
+ columns widths: ["50%", "50%"] do
40
+ column do
41
+ md "**ReactiveState** is a Ruby hash wrapper:"
42
+ md "- `[]` tracks which block regions read which keys during render"
43
+ md "- `[]=` notifies observers when a key changes"
44
+ md "- Observers are DOM updater lambdas registered at render time"
45
+ div(style: "height:8px")
46
+ md "Explicit watch for edge cases:"
47
+ md "- `watch(:search) { |val| ... }` — readable, obvious"
48
+ md "- No operator overloading confusion"
49
+ end
50
+ column do
51
+ md "**Invisible to the user — no API change:**"
52
+ md "Phase 1: plain hash, whole block re-runs"
53
+ md "Phase 2: ReactiveState proxy, only affected DOM nodes update"
54
+ div(style: "height:8px")
55
+ md "Same DSL code works in both phases. Upgrade is internal to the adapter."
56
+ div(style: "height:8px")
57
+ badge "Zero learning curve for app authors", color: :green
58
+ end
59
+ end
60
+ end
61
+
62
+ div(style: "height:24px")
63
+ header2 "Final Layer Map"
64
+ div(style: "height:8px")
65
+
66
+ table(
67
+ headers: ["Layer", "What it is", "Phase"],
68
+ rows: [
69
+ ["User DSL", "Unchanged StreamWeaver DSL — same app/card/text_field/button", "Now"],
70
+ ["Adapter::Opal", "Renders DSL to HTML string, wires event listeners, holds state", "1"],
71
+ ["OpalBuilder", "opal-build command → dist/index.html + dist/app.js", "1"],
72
+ ["morphdom.js", "Client-side DOM patching after block re-execution", "1"],
73
+ ["ReactiveState", "~70-line Observable hash: auto-tracks reads, notifies on write", "2"],
74
+ ["History API wrapper", "route DSL via pushState/popstate — same calls as Sinatra routes", "2"],
75
+ ["Supabase client", "Thin Ruby/Opal wrapper — sync state to Supabase on demand", "3 (MMA app)"]
76
+ ]
77
+ )
@@ -0,0 +1,9 @@
1
+ # streamweaver-doc: v1
2
+ header1 "🎯 Save as doc button — fresh bridge"
3
+ md "Hard-refresh this page (cmd-shift-R or ctrl-shift-R) — old bridge had stale code."
4
+ md ""
5
+ md "**Button is at the bottom-right corner.** If you don't see it:"
6
+ md "1. Try hard-refresh"
7
+ md "2. Check that this URL is `http://localhost:4700/canvas/canvas-arch`"
8
+ md "3. Open dev tools (cmd-opt-I) → Console — any JS errors?"
9
+ md "4. Inspect element on the page → look for `<button class=\"sw-save-doc-btn\">`"