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,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Example config.ru for running StreamWeaver apps with Puma-dev
4
+ #
5
+ # Usage:
6
+ # 1. Create this file in your app directory
7
+ # 2. Symlink to Puma-dev: `puma-dev link`
8
+ # 3. Access at http://[directory-name].test
9
+ #
10
+ # The app will use the PORT environment variable set by Puma-dev
11
+ # and will not auto-open the browser.
12
+
13
+ require 'bundler/setup'
14
+ require 'stream_weaver'
15
+
16
+ # Define your StreamWeaver app
17
+ App = app "Hello from Puma-dev" do
18
+ header1 "Welcome to StreamWeaver on Puma-dev!"
19
+
20
+ text "This app is running on Puma-dev with a memorable URL."
21
+
22
+ text_field :name, placeholder: "Enter your name"
23
+
24
+ if state[:name] && state[:name].strip != ""
25
+ text "Hello, #{state[:name]}!"
26
+ end
27
+
28
+ button "Clear" do |state|
29
+ state[:name] = ""
30
+ end
31
+ end
32
+
33
+ # Run the app (browser won't auto-open when PORT env var is set by Puma-dev)
34
+ run App
@@ -0,0 +1,34 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ # Standalone mode example - auto-detects port and opens browser
5
+ #
6
+ # Usage:
7
+ # ruby standalone_app.rb
8
+ #
9
+ # The app will auto-detect an available port and open the browser.
10
+
11
+ require 'bundler/setup'
12
+ require 'stream_weaver'
13
+
14
+ App = app "Standalone Mode Example" do
15
+ header1 "Running in Standalone Mode"
16
+
17
+ text "This app auto-detected a port and opened the browser."
18
+ text "Perfect for quick one-off scripts!"
19
+
20
+ text_field :message, placeholder: "Type something..."
21
+
22
+ if state[:message] && !state[:message].empty?
23
+ div do
24
+ text "You typed: #{state[:message]}"
25
+ end
26
+ end
27
+
28
+ button "Clear" do |state|
29
+ state[:message] = ""
30
+ end
31
+ end
32
+
33
+ # Start the app - browser will open automatically
34
+ App.run! if __FILE__ == $0
@@ -0,0 +1,49 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require_relative '../../lib/stream_weaver'
5
+
6
+ module PostStore
7
+ @posts = [
8
+ { id: '1', title: 'Hello World', body: 'First post', status: 'published' },
9
+ { id: '2', title: 'Second Post', body: 'Another post', status: 'draft' }
10
+ ]
11
+
12
+ def self.all; @posts; end
13
+ def self.find(id); @posts.find { |p| p[:id] == id }; end
14
+
15
+ def self.create(attrs)
16
+ id = ((@posts.map { |p| p[:id].to_i }.max || 0) + 1).to_s
17
+ @posts << { id: id, **attrs }
18
+ id
19
+ end
20
+
21
+ def self.update(id, attrs)
22
+ post = find(id) or return false
23
+ post.merge!(attrs)
24
+ true
25
+ end
26
+
27
+ def self.destroy(id)
28
+ @posts.reject! { |p| p[:id] == id }
29
+ true
30
+ end
31
+ end
32
+
33
+ app 'Blog' do
34
+ resource :post, store: PostStore do
35
+ field :title, :string
36
+ field :body, :text
37
+ field :status, :enum, values: %w[draft published]
38
+ end
39
+
40
+ navbar do
41
+ nav_item 'Home', href: '/', active: state[:_sw_action] == :home
42
+ nav_item 'Posts', href: '/posts', active: state[:_sw_resource] == :post
43
+ end
44
+
45
+ page :home, '/' do
46
+ header1 'My Blog'
47
+ text 'Welcome! Check out the posts.'
48
+ end
49
+ end.run!
@@ -0,0 +1,105 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require_relative '../../lib/stream_weaver'
5
+ require 'cgi'
6
+
7
+ # Inline GoalStore — hardcoded fixtures, no YAML file dependencies
8
+ module GoalStore
9
+ @goals = [
10
+ { id: '1', title: 'Ship Resource DSL', horizon: 'month' },
11
+ { id: '2', title: 'Launch UTF Dashboard', horizon: 'quarter' },
12
+ { id: '3', title: 'Automate SDRD cycle', horizon: 'year' }
13
+ ]
14
+
15
+ def self.all; @goals; end
16
+ def self.find(id); @goals.find { |g| g[:id] == id }; end
17
+
18
+ def self.create(attrs)
19
+ id = ((@goals.map { |g| g[:id].to_i }.max || 0) + 1).to_s
20
+ @goals << { id: id, **attrs }
21
+ id
22
+ end
23
+
24
+ def self.update(id, attrs)
25
+ goal = find(id) or return false
26
+ goal.merge!(attrs)
27
+ true
28
+ end
29
+
30
+ def self.destroy(id)
31
+ @goals.reject! { |g| g[:id] == id }
32
+ true
33
+ end
34
+ end
35
+
36
+ # Inline InitiativeStore — hardcoded fixtures, no YAML file dependencies
37
+ module InitiativeStore
38
+ @initiatives = [
39
+ { id: '1', title: 'Write resource DSL specs', status: 'active', horizon: 'month' },
40
+ { id: '2', title: 'Build UTF Lite example', status: 'active', horizon: 'month' },
41
+ { id: '3', title: 'Playwright smoke tests', status: 'paused', horizon: 'quarter' }
42
+ ]
43
+
44
+ def self.all; @initiatives; end
45
+ def self.find(id); @initiatives.find { |i| i[:id] == id }; end
46
+
47
+ def self.create(attrs)
48
+ id = ((@initiatives.map { |i| i[:id].to_i }.max || 0) + 1).to_s
49
+ @initiatives << { id: id, **attrs }
50
+ id
51
+ end
52
+
53
+ def self.update(id, attrs)
54
+ initiative = find(id) or return false
55
+ initiative.merge!(attrs)
56
+ true
57
+ end
58
+
59
+ def self.destroy(id)
60
+ @initiatives.reject! { |i| i[:id] == id }
61
+ true
62
+ end
63
+ end
64
+
65
+ app 'UTF Lite', layout: :wide, theme: :dashboard do
66
+ resource :goal, store: GoalStore do
67
+ field :title, :string
68
+ field :horizon, :enum, values: %w[month quarter year]
69
+
70
+ index do |goals|
71
+ header1 'Goals'
72
+ goals.group_by { |g| g[:horizon] }.each do |horizon, gs|
73
+ header3 horizon.to_s.capitalize
74
+ table gs, markdown: true do
75
+ column :title do |g| CGI.escape_html(g[:title].to_s) end
76
+ column(:actions, header: '') do |g|
77
+ eid = CGI.escape(g[:id].to_s)
78
+ "[View](/goal/#{eid}) [Edit](/goal/#{eid}/edit) [Delete](/goal/#{eid}/delete)"
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
84
+
85
+ resource :initiative, store: InitiativeStore do
86
+ field :title, :string
87
+ field :status, :enum, values: %w[active paused completed]
88
+ field :horizon, :string
89
+ edit_view :page
90
+ end
91
+
92
+ navbar do
93
+ nav_item 'Home', href: '/', active: state[:_sw_action] == :home
94
+ nav_item 'Goals', href: '/goals', active: state[:_sw_resource] == :goal
95
+ nav_item 'Initiatives', href: '/initiatives', active: state[:_sw_resource] == :initiative
96
+ end
97
+
98
+ page :home, '/' do
99
+ header1 'UTF Dashboard Lite'
100
+ columns widths: ['50%', '50%'] do
101
+ column { card { header3 'Goals'; text "#{GoalStore.all.size} tracked" } }
102
+ column { card { header3 'Initiatives'; text "#{InitiativeStore.all.size} active" } }
103
+ end
104
+ end
105
+ end.run!
@@ -0,0 +1,229 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../lib/stream_weaver'
4
+
5
+ app = StreamWeaver::App.new("Feedback Components Demo") do
6
+ header1 "Feedback Components"
7
+ text "Demonstrating alerts, toasts, progress bars, and spinners."
8
+
9
+ # =========================================
10
+ # Alerts Section
11
+ # =========================================
12
+ header2 "Alerts"
13
+ text "Static feedback messages with different variants."
14
+
15
+ alert(variant: :info) do
16
+ text "This is an informational alert. Use it for general messages."
17
+ end
18
+
19
+ alert(variant: :success, title: "Success!") do
20
+ text "Your changes have been saved successfully."
21
+ end
22
+
23
+ alert(variant: :warning, title: "Warning") do
24
+ text "Your session will expire in 5 minutes."
25
+ end
26
+
27
+ alert(variant: :error, title: "Error") do
28
+ text "Unable to connect to the server. Please try again."
29
+ end
30
+
31
+ header3 "Dismissible Alerts"
32
+
33
+ alert(variant: :info, title: "Tip", dismissible: true) do
34
+ text "Click the X to dismiss this alert. It's only removed client-side."
35
+ end
36
+
37
+ alert(variant: :success, dismissible: true) do
38
+ text "You can dismiss me too!"
39
+ end
40
+
41
+ # =========================================
42
+ # Toast Notifications Section
43
+ # =========================================
44
+ header2 "Toast Notifications"
45
+ text "Temporary notifications that stack and auto-dismiss. Click buttons to add multiple toasts!"
46
+
47
+ # Add a toast container - this is where toasts will appear
48
+ toast_container position: :top_right, duration: 4000
49
+
50
+ state[:toast_count] ||= 0
51
+
52
+ hstack(spacing: :sm) do
53
+ button "Info Toast" do |s|
54
+ s[:toast_count] += 1
55
+ show_toast("Info message ##{s[:toast_count]}", variant: :info)
56
+ end
57
+
58
+ button "Success Toast" do |s|
59
+ s[:toast_count] += 1
60
+ show_toast("Success! Operation ##{s[:toast_count]} completed.", variant: :success)
61
+ end
62
+
63
+ button "Warning Toast" do |s|
64
+ s[:toast_count] += 1
65
+ show_toast("Warning: Check item ##{s[:toast_count]}", variant: :warning)
66
+ end
67
+
68
+ button "Error Toast" do |s|
69
+ s[:toast_count] += 1
70
+ show_toast("Error ##{s[:toast_count]}: Something went wrong!", variant: :error)
71
+ end
72
+ end
73
+
74
+ hstack(spacing: :sm) do
75
+ button "Add 3 Toasts", style: :secondary do |s|
76
+ show_toast("First notification", variant: :info)
77
+ show_toast("Second notification", variant: :success)
78
+ show_toast("Third notification", variant: :warning)
79
+ end
80
+
81
+ button "Clear All", style: :secondary do |s|
82
+ clear_toasts
83
+ s[:toast_count] = 0
84
+ end
85
+ end
86
+
87
+ text -> (s) { "Total toasts shown: #{s[:toast_count]}" }
88
+
89
+ # =========================================
90
+ # Progress Bars Section
91
+ # =========================================
92
+ header2 "Progress Bars"
93
+ text "Visual indicators for progress and completion."
94
+
95
+ header3 "Static Progress"
96
+
97
+ text "Default (25%):"
98
+ progress_bar value: 25
99
+
100
+ text "Success variant (50%):"
101
+ progress_bar value: 50, variant: :success
102
+
103
+ text "Warning variant (75%):"
104
+ progress_bar value: 75, variant: :warning
105
+
106
+ text "Error variant (90%):"
107
+ progress_bar value: 90, variant: :error
108
+
109
+ header3 "With Labels"
110
+
111
+ text "Progress with label:"
112
+ progress_bar value: 65, show_label: true
113
+
114
+ header3 "Animated"
115
+
116
+ text "Animated striped progress:"
117
+ progress_bar value: 80, animated: true, variant: :success
118
+
119
+ header3 "Dynamic Progress"
120
+ text "Click buttons to change progress:"
121
+
122
+ # Initialize progress state
123
+ state[:progress] ||= 30
124
+
125
+ progress_bar value: :progress, show_label: true, variant: :success
126
+
127
+ hstack(spacing: :sm) do
128
+ button "- 10", style: :secondary do |s|
129
+ s[:progress] = [0, s[:progress] - 10].max
130
+ end
131
+
132
+ button "+ 10" do |s|
133
+ s[:progress] = [100, s[:progress] + 10].min
134
+ end
135
+
136
+ button "Reset", style: :secondary do |s|
137
+ s[:progress] = 0
138
+ end
139
+
140
+ button "Complete" do |s|
141
+ s[:progress] = 100
142
+ end
143
+ end
144
+
145
+ # =========================================
146
+ # Spinners Section
147
+ # =========================================
148
+ header2 "Spinners"
149
+ text "Loading indicators for async operations."
150
+
151
+ header3 "Sizes"
152
+
153
+ hstack(spacing: :lg, align: :center) do
154
+ vstack(align: :center) do
155
+ spinner size: :sm
156
+ text "Small"
157
+ end
158
+
159
+ vstack(align: :center) do
160
+ spinner size: :md
161
+ text "Medium"
162
+ end
163
+
164
+ vstack(align: :center) do
165
+ spinner size: :lg
166
+ text "Large"
167
+ end
168
+ end
169
+
170
+ header3 "With Labels"
171
+
172
+ spinner size: :md, label: "Loading data..."
173
+ spinner size: :sm, label: "Processing..."
174
+
175
+ # =========================================
176
+ # Combined Example
177
+ # =========================================
178
+ header2 "Combined Example: File Upload Simulation"
179
+
180
+ state[:upload_status] ||= :idle
181
+ state[:upload_progress] ||= 0
182
+
183
+ card do
184
+ card_header "Upload Status"
185
+ card_body do
186
+ case state[:upload_status]
187
+ when :idle
188
+ text "Select a file to upload."
189
+ button "Start Upload" do |s|
190
+ s[:upload_status] = :uploading
191
+ s[:upload_progress] = 0
192
+ end
193
+
194
+ when :uploading
195
+ hstack(align: :center, spacing: :sm) do
196
+ spinner size: :sm, label: "Uploading..."
197
+ end
198
+ progress_bar value: :upload_progress, show_label: true, animated: true
199
+
200
+ hstack(spacing: :sm) do
201
+ button "+ Progress" do |s|
202
+ s[:upload_progress] += 20
203
+ if s[:upload_progress] >= 100
204
+ s[:upload_status] = :complete
205
+ s[:upload_progress] = 100
206
+ end
207
+ end
208
+
209
+ button "Cancel", style: :secondary do |s|
210
+ s[:upload_status] = :idle
211
+ s[:upload_progress] = 0
212
+ end
213
+ end
214
+
215
+ when :complete
216
+ alert(variant: :success, title: "Upload Complete!") do
217
+ text "Your file has been uploaded successfully."
218
+ end
219
+
220
+ button "Upload Another", style: :secondary do |s|
221
+ s[:upload_status] = :idle
222
+ s[:upload_progress] = 0
223
+ end
224
+ end
225
+ end
226
+ end
227
+ end
228
+
229
+ app.generate.run!
@@ -0,0 +1,172 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Style Showcase - Comprehensive test of StreamWeaver styling
4
+ #
5
+ # Tests:
6
+ # - All header levels h1-h6
7
+ # - Typography (bold, italic, code, links)
8
+ # - Long content overflow handling
9
+ # - Form elements
10
+ # - Cards and layouts
11
+ # - Layout modes (default/wide/full)
12
+ #
13
+ # Usage: ruby examples/style_showcase.rb
14
+
15
+ require_relative '../../lib/stream_weaver'
16
+
17
+ LAYOUT = (ARGV[0] || 'wide').to_sym # Pass layout as argument: ruby style_showcase.rb fluid
18
+
19
+ StreamWeaver.app "Style Showcase", layout: LAYOUT do
20
+ theme_switcher position: :inline
21
+ header1 "StreamWeaver Style Showcase"
22
+ md "**Current layout: `#{LAYOUT}`**"
23
+ md "Options: `default` (900px) | `wide` (1100px) | `full` (1400px) | `fluid` (100%)"
24
+ md "Test: `ruby style_showcase.rb fluid`"
25
+
26
+ # Typography Section
27
+ header2 "Typography Hierarchy"
28
+
29
+ card do
30
+ header1 "Header 1 - Page Title (2.25rem)"
31
+ header2 "Header 2 - Section (1.625rem)"
32
+ header3 "Header 3 - Subsection (1.25rem)"
33
+ header4 "Header 4 - Group (1.1rem)"
34
+ header5 "Header 5 - Minor (1rem)"
35
+ header6 "Header 6 - Label (0.9rem uppercase)"
36
+ end
37
+
38
+ header2 "Text Formatting"
39
+
40
+ card do
41
+ md "**Bold text** for emphasis."
42
+ md "*Italic text* for subtle emphasis."
43
+ md "`Inline code` for technical terms."
44
+ md "[Links](https://example.com) for navigation."
45
+ md "Regular paragraph text with good line height for readability. This should be easy to read even in longer blocks of content. The font is Source Sans 3 at 17px."
46
+ end
47
+
48
+ # Overflow Handling Section
49
+ header2 "Overflow & Long Content"
50
+
51
+ card do
52
+ header3 "Long URL"
53
+ text "https://example.com/this/is/a/very/long/url/path/that/should/wrap/properly/instead/of/breaking/the/layout/or/causing/horizontal/scroll"
54
+ end
55
+
56
+ card do
57
+ header3 "Long Word"
58
+ text "Supercalifragilisticexpialidocious and Pneumonoultramicroscopicsilicovolcanoconiosis should wrap properly."
59
+ end
60
+
61
+ card do
62
+ header3 "Wide Content"
63
+ text "Column 1 | Column 2 | Column 3 | Column 4 | Column 5 | Column 6 | Column 7 | Column 8"
64
+ text "Data that might be wider than expected in some cases with lots of information packed in."
65
+ end
66
+
67
+ # Form Elements Section
68
+ header2 "Form Elements"
69
+
70
+ header3 "Text Inputs"
71
+ text_field :name, placeholder: "Enter your name"
72
+ text_area :bio, placeholder: "Enter a longer description..."
73
+
74
+ header3 "Selection Controls"
75
+ checkbox :enabled, "Enable feature"
76
+ select :color, ["Red", "Green", "Blue"], default: "Green"
77
+
78
+ header3 "Radio Group"
79
+ radio_group :size, ["Small", "Medium", "Large"]
80
+
81
+ header3 "Buttons"
82
+ columns do
83
+ column do
84
+ button "Primary Action" do |s|
85
+ s[:clicked] = "primary"
86
+ end
87
+ end
88
+ column do
89
+ button "Secondary Action", style: :secondary do |s|
90
+ s[:clicked] = "secondary"
91
+ end
92
+ end
93
+ end
94
+
95
+ # Cards Section
96
+ header2 "Cards"
97
+
98
+ card do
99
+ header3 "Simple Card"
100
+ text "Cards provide visual grouping with a subtle terracotta accent bar."
101
+ end
102
+
103
+ card do
104
+ header3 "Card with Form"
105
+ form :card_form do
106
+ text_field :card_input, placeholder: "Input inside a card"
107
+ submit "Submit"
108
+ end
109
+ end
110
+
111
+ # Columns Layout Section
112
+ header2 "Column Layouts"
113
+
114
+ header3 "Equal Width Columns"
115
+ columns do
116
+ column do
117
+ card do
118
+ header4 "Column 1"
119
+ text "Equal width via flexbox."
120
+ end
121
+ end
122
+ column do
123
+ card do
124
+ header4 "Column 2"
125
+ text "Also equal width."
126
+ end
127
+ end
128
+ column do
129
+ card do
130
+ header4 "Column 3"
131
+ text "Three columns total."
132
+ end
133
+ end
134
+ end
135
+
136
+ header3 "Custom Width Columns"
137
+ columns widths: ['30%', '70%'] do
138
+ column do
139
+ card do
140
+ header4 "Sidebar (30%)"
141
+ text "Narrower column for navigation or metadata."
142
+ end
143
+ end
144
+ column do
145
+ card do
146
+ header4 "Main Content (70%)"
147
+ text "Wider column for primary content. This layout is useful for detail pages with a sidebar."
148
+ end
149
+ end
150
+ end
151
+
152
+ # Collapsible Section
153
+ header2 "Collapsible Sections"
154
+
155
+ collapsible "Click to expand details" do
156
+ text "This content is hidden by default and revealed on click."
157
+ text "Useful for progressive disclosure of complex information."
158
+ end
159
+
160
+ collapsible "Already expanded section", expanded: true do
161
+ text "This section starts open."
162
+ end
163
+
164
+ # Current State Display
165
+ header2 "Current State"
166
+ text "Name: #{state[:name]}"
167
+ text "Bio: #{state[:bio]}"
168
+ text "Enabled: #{state[:enabled]}"
169
+ text "Color: #{state[:color]}"
170
+ text "Size: #{state[:size]}"
171
+ text "Last clicked: #{state[:clicked] || '(none)'}"
172
+ end.run!