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,468 @@
1
+ /* Design Review — component-parity port of a claude.ai-hosted Artifact
2
+ * (an editorial "design review" document: numbered sections, option cards
3
+ * with chips, a comparison matrix, and a verified/unverified checklist
4
+ * split). See docs/porting-artifacts.md for the general porting process
5
+ * this file is an example of.
6
+ *
7
+ * ONE stylesheet, targeting ONLY stable sw- hooks (the structural set is
8
+ * documented in docs/theming-hooks.md; the doc-component hooks used here
9
+ * are stable but not yet documented there -- stream_weaver-d11) plus this file's own ad- prefixed classes for
10
+ * the handful of elements with no dedicated component (chips, checklist
11
+ * tiles, meta-row, legend, footer, sources). No specificity workaround
12
+ * anywhere -- every framework rule lives in @layer stream-weaver, so this
13
+ * plain unlayered stylesheet always wins regardless of document order.
14
+ *
15
+ * Palette/type values transcribed directly from the source artifact's own
16
+ * <style> block (both light and dark custom-property sets). Renamed to an
17
+ * ad- prefix so these custom properties can never collide with
18
+ * StreamWeaver's own --sw-* tokens.
19
+ */
20
+
21
+ :root {
22
+ --ad-bg: #eef2f2;
23
+ --ad-surface: #ffffff;
24
+ --ad-surface-2: #e4eaea;
25
+ --ad-border: #d3dcdb;
26
+ --ad-ink: #14191b;
27
+ --ad-body: #333b3d;
28
+ --ad-muted: #677375;
29
+ --ad-accent: #2b6c7a;
30
+ --ad-accent-ink: #ffffff;
31
+ --ad-accent-soft: #dcedee;
32
+ --ad-accent-soft-border: #b7d6d9;
33
+ --ad-good: #3f7d4f;
34
+ --ad-good-soft: #e4f1e6;
35
+ --ad-mid: #9a6c17;
36
+ --ad-mid-soft: #f5ecd8;
37
+ --ad-weak: #b0503e;
38
+ --ad-weak-soft: #f6e4e0;
39
+ --ad-code-bg: #e7edec;
40
+ --ad-shadow: 0 1px 2px rgba(20, 25, 27, .06), 0 6px 16px -8px rgba(20, 25, 27, .12);
41
+ --ad-serif: ui-serif, "Iowan Old Style", "Palatino Linotype", Charter, Georgia, serif;
42
+ --ad-mono: ui-monospace, "SF Mono", "Cascadia Code", "Roboto Mono", Menlo, Consolas, monospace;
43
+ }
44
+
45
+ /* OS-level dark preference -- fallback when no explicit toggle has run. */
46
+ @media (prefers-color-scheme: dark) {
47
+ :root {
48
+ --ad-bg: #14181a;
49
+ --ad-surface: #1b2123;
50
+ --ad-surface-2: #20282a;
51
+ --ad-border: #2c3639;
52
+ --ad-ink: #eef2f1;
53
+ --ad-body: #c6cdcc;
54
+ --ad-muted: #8b9a9a;
55
+ --ad-accent: #6fb8c4;
56
+ --ad-accent-ink: #0d2226;
57
+ --ad-accent-soft: #1c3437;
58
+ --ad-accent-soft-border: #2d5459;
59
+ --ad-good: #7fc190;
60
+ --ad-good-soft: #1c2f22;
61
+ --ad-mid: #d9ab5c;
62
+ --ad-mid-soft: #332a18;
63
+ --ad-weak: #e08670;
64
+ --ad-weak-soft: #33221e;
65
+ --ad-code-bg: #20282a;
66
+ --ad-shadow: 0 1px 2px rgba(0, 0, 0, .3), 0 10px 24px -10px rgba(0, 0, 0, .5);
67
+ }
68
+ }
69
+
70
+ /* StreamWeaver's own manual toggle (theme_toggle) sets html.dark, not
71
+ the artifact's original data-theme attribute -- higher specificity
72
+ than :root, so it always wins over the media-query fallback above. */
73
+ html.dark {
74
+ --ad-bg: #14181a;
75
+ --ad-surface: #1b2123;
76
+ --ad-surface-2: #20282a;
77
+ --ad-border: #2c3639;
78
+ --ad-ink: #eef2f1;
79
+ --ad-body: #c6cdcc;
80
+ --ad-muted: #8b9a9a;
81
+ --ad-accent: #6fb8c4;
82
+ --ad-accent-ink: #0d2226;
83
+ --ad-accent-soft: #1c3437;
84
+ --ad-accent-soft-border: #2d5459;
85
+ --ad-good: #7fc190;
86
+ --ad-good-soft: #1c2f22;
87
+ --ad-mid: #d9ab5c;
88
+ --ad-mid-soft: #332a18;
89
+ --ad-weak: #e08670;
90
+ --ad-weak-soft: #33221e;
91
+ --ad-code-bg: #20282a;
92
+ --ad-shadow: 0 1px 2px rgba(0, 0, 0, .3), 0 10px 24px -10px rgba(0, 0, 0, .5);
93
+ }
94
+
95
+ body {
96
+ background: var(--ad-bg);
97
+ color: var(--ad-body);
98
+ font-family: var(--ad-serif);
99
+ font-size: 16.5px;
100
+ line-height: 1.65;
101
+ }
102
+
103
+ /* Neutralize the app chrome StreamWeaver normally wraps content in --
104
+ * `body.sw-layout-default` caps width/adds padding, and its `#app-container`
105
+ * child gets its OWN background/border/shadow (from --sw-color-bg-card,
106
+ * still keyed to the :doc theme's beige-light/warm-charcoal-dark palette,
107
+ * not this app's cool teal one) -- both would otherwise show through as a
108
+ * visible "card within a card" boundary around .ad-doc. .ad-doc becomes the
109
+ * sole layout/background authority so the page reads as one continuous
110
+ * edge-to-edge surface, matching the artifact. */
111
+ body[class*="sw-layout-"] {
112
+ max-width: none;
113
+ padding: 0;
114
+ background: var(--ad-bg);
115
+ }
116
+ #app-container {
117
+ background: transparent;
118
+ padding: 0;
119
+ margin: 0;
120
+ border: none;
121
+ box-shadow: none;
122
+ border-radius: 0;
123
+ max-width: none;
124
+ }
125
+
126
+ .ad-doc {
127
+ max-width: 860px;
128
+ margin: 0 auto;
129
+ padding: 2rem 1.5rem 6rem;
130
+ }
131
+
132
+ .ad-doc ::selection { background: var(--ad-accent-soft); color: var(--ad-ink); }
133
+
134
+ .ad-doc code {
135
+ font-family: var(--ad-mono);
136
+ background: var(--ad-code-bg);
137
+ border: 1px solid var(--ad-border);
138
+ border-radius: 3px;
139
+ padding: .08em .38em;
140
+ font-size: .87em;
141
+ color: var(--ad-ink);
142
+ }
143
+
144
+ .ad-doc a { color: var(--ad-accent); text-underline-offset: 3px; }
145
+ .ad-doc a:focus-visible { outline: 2px solid var(--ad-accent); outline-offset: 2px; border-radius: 2px; }
146
+
147
+ .ad-doc p,
148
+ .ad-doc .sw-markdown p { margin: .85rem 0; max-width: 65ch; color: var(--ad-body); }
149
+
150
+ /* ---------- Header (doc_header + hand-rolled dek/meta-row) ---------- */
151
+ .ad-doc .sw-doc-header {
152
+ padding: 0;
153
+ border: none;
154
+ box-shadow: none;
155
+ background: transparent;
156
+ }
157
+ .ad-doc .sw-doc-header__eyebrow {
158
+ font-family: var(--ad-mono);
159
+ font-size: .72rem;
160
+ letter-spacing: .14em;
161
+ text-transform: uppercase;
162
+ color: var(--ad-accent);
163
+ display: flex;
164
+ align-items: center;
165
+ gap: .6em;
166
+ }
167
+ .ad-doc .sw-doc-header__eyebrow::before {
168
+ content: "";
169
+ width: 1.4em;
170
+ height: 1px;
171
+ background: var(--ad-accent);
172
+ display: inline-block;
173
+ opacity: .55;
174
+ }
175
+ .ad-doc .sw-doc-header__title {
176
+ font-family: var(--ad-serif);
177
+ font-weight: 600;
178
+ font-size: clamp(1.8rem, 1.35rem + 1.9vw, 2.7rem);
179
+ line-height: 1.12;
180
+ letter-spacing: -.01em;
181
+ color: var(--ad-ink);
182
+ margin: .5rem 0 .6rem;
183
+ text-wrap: balance;
184
+ }
185
+ .ad-dek { font-size: 1.1rem; color: var(--ad-body); max-width: 62ch; margin: 0 0 1.6rem; }
186
+ .ad-meta-row {
187
+ display: flex;
188
+ flex-wrap: wrap;
189
+ gap: .5rem 1.4rem;
190
+ font-family: var(--ad-mono);
191
+ font-size: .78rem;
192
+ color: var(--ad-muted);
193
+ border-top: 1px solid var(--ad-border);
194
+ border-bottom: 1px solid var(--ad-border);
195
+ padding: .75rem 0;
196
+ margin-bottom: 1rem;
197
+ }
198
+ .ad-meta-label { color: var(--ad-body); font-weight: 600; margin-right: .3em; }
199
+
200
+ /* ---------- Section numbering ---------- */
201
+ .ad-doc .sw-doc-section-header { margin-top: 3.4rem; margin-bottom: 0; }
202
+ .ad-doc .sw-doc-section-header__eyebrow {
203
+ font-family: var(--ad-mono);
204
+ font-size: .72rem;
205
+ letter-spacing: .1em;
206
+ color: var(--ad-muted);
207
+ text-transform: uppercase;
208
+ }
209
+ /* The framework's own DocSectionHeader draws an extending horizontal rule
210
+ after the eyebrow label (a deliberate feature of that component) -- the
211
+ artifact's own section-num label is bare text with no rule. */
212
+ .ad-doc .sw-doc-section-header__eyebrow::after { display: none; content: none; }
213
+ .ad-doc .sw-doc-section-header__title {
214
+ font-family: var(--ad-serif);
215
+ font-size: 1.5rem;
216
+ font-weight: 600;
217
+ color: var(--ad-ink);
218
+ letter-spacing: -.005em;
219
+ text-wrap: balance;
220
+ margin: .3rem 0 0;
221
+ }
222
+ /* Sections 01/05 have only an eyebrow line, no second headline. */
223
+ .ad-doc .sw-doc-section-header__title:empty { display: none; }
224
+
225
+ /* ---------- Callout (section 01 framing box) ---------- */
226
+ .ad-doc .sw-callout {
227
+ background: var(--ad-surface);
228
+ border: 1px solid var(--ad-border);
229
+ border-left: 3px solid var(--ad-accent);
230
+ border-radius: 4px;
231
+ padding: 1.1rem 1.3rem;
232
+ box-shadow: var(--ad-shadow);
233
+ }
234
+ .ad-doc .sw-callout__icon { display: none; }
235
+ .ad-doc .sw-callout__title {
236
+ color: var(--ad-accent);
237
+ font-size: .75rem;
238
+ letter-spacing: .12em;
239
+ text-transform: uppercase;
240
+ font-family: var(--ad-mono);
241
+ margin-bottom: .5rem;
242
+ }
243
+ .ad-doc .sw-callout__content p { margin: .4rem 0; }
244
+
245
+ /* Recommendation panel -- stronger accent-soft version of the same idiom. */
246
+ .ad-reco .sw-callout {
247
+ background: var(--ad-accent-soft);
248
+ border: 1px solid var(--ad-accent-soft-border);
249
+ border-left: 4px solid var(--ad-accent);
250
+ border-radius: 5px;
251
+ padding: 1.4rem 1.6rem;
252
+ }
253
+ .ad-reco .sw-callout__title { color: var(--ad-accent); }
254
+ .ad-reco h3 {
255
+ font-family: var(--ad-serif);
256
+ color: var(--ad-ink);
257
+ font-size: 1.15rem;
258
+ font-weight: 600;
259
+ margin: .9rem 0 .3rem;
260
+ }
261
+
262
+ /* Dashed secondary aside -- deliberately quieter than .ad-reco. */
263
+ .ad-aside .sw-callout {
264
+ border: 1px dashed var(--ad-border);
265
+ border-radius: 5px;
266
+ padding: 1rem 1.2rem;
267
+ background: var(--ad-surface);
268
+ font-size: .95rem;
269
+ box-shadow: none;
270
+ }
271
+ .ad-aside .sw-callout__title { color: var(--ad-mid); }
272
+
273
+ /* ---------- Tables ---------- */
274
+ .ad-tbl-scroll { overflow-x: auto; border: 1px solid var(--ad-border); border-radius: 5px; box-shadow: var(--ad-shadow); }
275
+ .ad-doc .sw-table {
276
+ width: 100%;
277
+ border-collapse: collapse;
278
+ background: var(--ad-surface);
279
+ min-width: 640px;
280
+ font-family: var(--ad-serif);
281
+ }
282
+ .ad-doc .sw-table.mono { font-family: var(--ad-mono); }
283
+ .ad-doc .sw-table thead th {
284
+ text-align: left;
285
+ font-family: var(--ad-mono);
286
+ font-size: .72rem;
287
+ letter-spacing: .08em;
288
+ text-transform: uppercase;
289
+ color: var(--ad-muted);
290
+ background: var(--ad-surface-2);
291
+ padding: .7rem .9rem;
292
+ border-bottom: 1px solid var(--ad-border);
293
+ white-space: nowrap;
294
+ }
295
+ .ad-doc .sw-table tbody td {
296
+ padding: .75rem .9rem;
297
+ border-bottom: 1px solid var(--ad-border);
298
+ font-size: .92rem;
299
+ vertical-align: top;
300
+ color: var(--ad-body);
301
+ }
302
+ .ad-doc .sw-table tbody tr:last-child td { border-bottom: none; }
303
+ .ad-doc .sw-table tbody td:first-child { font-weight: 600; color: var(--ad-ink); white-space: nowrap; }
304
+
305
+ /* Comparison-matrix "pick" row (Option F is always the last row). */
306
+ .ad-matrix-table tbody tr:last-child { background: var(--ad-accent-soft); }
307
+ .ad-matrix-table tbody tr:last-child td:first-child { color: var(--ad-accent); }
308
+
309
+ .ad-cell-rating { display: flex; align-items: baseline; gap: .5em; }
310
+
311
+ /* ---------- Option cards ---------- */
312
+ .ad-option.sw-card {
313
+ background: var(--ad-surface);
314
+ border: 1px solid var(--ad-border);
315
+ border-radius: 6px;
316
+ box-shadow: var(--ad-shadow);
317
+ padding: 1.5rem 1.6rem 1.7rem;
318
+ margin-top: 1.4rem;
319
+ }
320
+ .ad-option--pick.sw-card {
321
+ border-color: var(--ad-accent-soft-border);
322
+ background: linear-gradient(var(--ad-accent-soft), var(--ad-accent-soft)), var(--ad-surface);
323
+ }
324
+ .ad-option .sw-card-header,
325
+ .ad-option .card-header {
326
+ display: grid;
327
+ grid-template-columns: 2.1rem 1fr auto;
328
+ column-gap: .9rem;
329
+ align-items: start;
330
+ /* Framework's .card-header--badged paints a shaded band (--sw-surface-elevated,
331
+ falls back to a hardcoded beige) behind badge/title/subtitle -- the artifact's
332
+ option-card header sits directly on the plain white card surface. */
333
+ background: transparent;
334
+ border-bottom: none;
335
+ }
336
+ .ad-option .card-header__badge {
337
+ grid-column: 1;
338
+ grid-row: 1 / 3;
339
+ width: 2.1rem;
340
+ height: 2.1rem;
341
+ border: 1.5px solid var(--ad-border);
342
+ border-radius: 4px;
343
+ display: flex;
344
+ align-items: center;
345
+ justify-content: center;
346
+ font-family: var(--ad-mono);
347
+ font-weight: 700;
348
+ font-size: 1rem;
349
+ color: var(--ad-muted);
350
+ /* Framework default tints this with --sw-accent at 12% -- the artifact's
351
+ .opt-badge has no fill of its own, just a border on the plain card surface. */
352
+ background: transparent;
353
+ margin-top: .1rem;
354
+ }
355
+ .ad-option--pick .card-header__badge { border-color: var(--ad-accent); color: var(--ad-accent); }
356
+ .ad-option .card-header__title {
357
+ grid-column: 2;
358
+ grid-row: 1;
359
+ font-family: var(--ad-serif);
360
+ font-size: 1.22rem;
361
+ font-weight: 600;
362
+ color: var(--ad-ink);
363
+ margin: 0;
364
+ text-wrap: balance;
365
+ }
366
+ .ad-option .card-header__meta,
367
+ .ad-option .ad-option-mech {
368
+ grid-column: 2;
369
+ grid-row: 2;
370
+ margin: .15rem 0 0;
371
+ color: var(--ad-muted);
372
+ font-size: .94rem;
373
+ font-family: var(--ad-serif);
374
+ }
375
+ .ad-option .ad-option-mech p { margin: 0; }
376
+ .ad-option .ad-option-mech code { font-size: .87em; }
377
+ .ad-option .sw-badge {
378
+ grid-column: 3;
379
+ grid-row: 1 / 3;
380
+ align-self: start;
381
+ justify-self: end;
382
+ font-family: var(--ad-mono);
383
+ font-size: .68rem;
384
+ letter-spacing: .1em;
385
+ text-transform: uppercase;
386
+ color: var(--ad-accent-ink);
387
+ background: var(--ad-accent);
388
+ padding: .22em .55em;
389
+ border-radius: 3px;
390
+ white-space: nowrap;
391
+ }
392
+
393
+ .ad-chips { display: flex; flex-wrap: wrap; gap: .45rem .5rem; margin: 1.05rem 0 .2rem; }
394
+ .ad-chip {
395
+ display: inline-flex;
396
+ align-items: center;
397
+ gap: .4em;
398
+ font-family: var(--ad-mono);
399
+ font-size: .74rem;
400
+ padding: .28em .6em .28em .5em;
401
+ border-radius: 3px;
402
+ border: 1px solid var(--ad-border);
403
+ background: var(--ad-surface-2);
404
+ color: var(--ad-body);
405
+ line-height: 1.3;
406
+ }
407
+ .ad-chip-dim { color: var(--ad-muted); text-transform: uppercase; letter-spacing: .05em; font-size: .9em; }
408
+ .ad-chip .sw-status-dot { width: .5em; height: .5em; }
409
+
410
+ .ad-option .sw-card-body p { margin: .9rem 0 0; font-size: .98rem; }
411
+
412
+ /* Semantic status-dot color mapping (good/mid/weak), reused in chips,
413
+ the legend, and the matrix table's rating cells. */
414
+ .ad-doc .sw-status-dot-green { background: var(--ad-good); }
415
+ .ad-doc .sw-status-dot-yellow { background: var(--ad-mid); }
416
+ .ad-doc .sw-status-dot-red { background: var(--ad-weak); }
417
+
418
+ /* ---------- Legend (section 04) ---------- */
419
+ .ad-legend { display: flex; flex-wrap: wrap; gap: 1.2rem; margin: .6rem 0 1rem; font-family: var(--ad-mono); font-size: .76rem; color: var(--ad-muted); }
420
+ .ad-legend-item { display: inline-flex; align-items: center; gap: .4em; }
421
+ .ad-legend-item .sw-status-dot { width: .55em; height: .55em; }
422
+
423
+ /* ---------- Split grid + checklist tiles (section 06) ---------- */
424
+ .ad-split.sw-columns { gap: 1.2rem; margin-top: 1rem; }
425
+ @media (max-width: 700px) {
426
+ .ad-split.sw-columns { flex-direction: column; }
427
+ }
428
+ .ad-col-h { font-family: var(--ad-mono); font-size: .72rem; letter-spacing: .09em; text-transform: uppercase; margin-bottom: .6rem; display: block; }
429
+ .ad-col-h--v { color: var(--ad-good); }
430
+ .ad-col-h--u { color: var(--ad-mid); }
431
+
432
+ .ad-checklist { display: flex; flex-direction: column; gap: .6rem; }
433
+ .ad-check-item {
434
+ background: var(--ad-surface);
435
+ border: 1px solid var(--ad-border);
436
+ border-radius: 5px;
437
+ padding: .7rem .85rem;
438
+ font-size: .89rem;
439
+ display: flex;
440
+ gap: .6rem;
441
+ box-shadow: var(--ad-shadow);
442
+ color: var(--ad-body);
443
+ }
444
+ .ad-check-item p { margin: 0; }
445
+ .ad-check-mark { flex: none; width: 1.1rem; text-align: center; font-family: var(--ad-mono); font-weight: 700; }
446
+ .ad-checklist--verified .ad-check-mark { color: var(--ad-good); }
447
+ .ad-checklist--unverified .ad-check-mark { color: var(--ad-mid); }
448
+
449
+ /* ---------- Sources / footer ---------- */
450
+ .ad-sources { margin-top: 1rem; font-family: var(--ad-mono); font-size: .78rem; line-height: 1.9; color: var(--ad-muted); word-break: break-word; }
451
+ /* The shared `.ad-doc p { max-width: 65ch }` prose rule was truncating this
452
+ block to a narrow column, wrapping every URL -- the artifact's own
453
+ .sources div has no <p> inside it at all (bare text), so it never hit
454
+ that rule; ours goes through `md`, which always wraps in <p>. */
455
+ .ad-sources p { margin: 0; max-width: none; }
456
+
457
+ .ad-footer {
458
+ margin-top: 4rem;
459
+ padding-top: 1.4rem;
460
+ border-top: 1px solid var(--ad-border);
461
+ font-family: var(--ad-mono);
462
+ font-size: .76rem;
463
+ color: var(--ad-muted);
464
+ display: flex;
465
+ justify-content: space-between;
466
+ flex-wrap: wrap;
467
+ gap: .5rem;
468
+ }
@@ -0,0 +1,44 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ # Component-parity port of a claude.ai-hosted Artifact: a fictional
5
+ # editorial design-review document ("Getting Wayfinder and Beacon in front
6
+ # of every agent"). Loads design_review_dsl.rb as its body so standalone
7
+ # and canvas-push stay in content sync, following the doc-parity-example.rb
8
+ # / prd_demo.rb precedent. See docs/porting-artifacts.md for the general
9
+ # process this example proves out.
10
+ #
11
+ # Demonstrates: doc_header, doc_section_header, callout (framing box,
12
+ # recommendation panel, dashed aside), card/card_header/card_body (option
13
+ # cards A-F with a "picked" state), table with markdown: true (landscape +
14
+ # comparison-matrix tables, one with a highlighted pick row), status_dot
15
+ # (chips, legend, matrix rating cells), columns/column (verified/unverified
16
+ # split), badge (recommended tag) -- re-skinned end to end via ONE
17
+ # unlayered stylesheet (design_review.css) targeting only stable sw- hooks
18
+ # (structural hooks per docs/theming-hooks.md; doc-component hooks pending
19
+ # documentation there, stream_weaver-d11).
20
+ #
21
+ # Run: ruby examples/components/design_review_demo.rb
22
+
23
+ require_relative "../../lib/stream_weaver"
24
+
25
+ DSL_PATH = File.join(__dir__, "design_review_dsl.rb")
26
+ CSS_PATH = File.join(__dir__, "design_review.css")
27
+
28
+ # Uses StreamWeaver::App.new directly (not the top-level `app` helper) --
29
+ # the helper's fixed kwarg list has no assets_dirs:, and App#script_dir is
30
+ # derived from its *direct* caller's file (caller_locations(1,1) inside
31
+ # #initialize), which resolves to lib/stream_weaver.rb itself when routed
32
+ # through the helper. Same workaround examples/parity/tyrion_warroom_components.rb
33
+ # uses for its own stylesheets:.
34
+ DesignReviewDemo = StreamWeaver::App.new(
35
+ "Design Review — Wayfinder & Beacon",
36
+ theme: :doc,
37
+ stylesheets: [CSS_PATH],
38
+ assets_dirs: [__dir__]
39
+ ) do
40
+ theme_toggle mode: :auto
41
+ instance_eval(File.read(DSL_PATH), DSL_PATH)
42
+ end.generate
43
+
44
+ DesignReviewDemo.run! if __FILE__ == $0