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.
- checksums.yaml +7 -0
- data/.beads/.gitignore +77 -0
- data/.beads/README.md +81 -0
- data/.beads/config.yaml +54 -0
- data/.beads/metadata.json +7 -0
- data/.rspec +3 -0
- data/AGENTS.md +91 -0
- data/CHANGELOG.md +294 -0
- data/CLAUDE.md +67 -0
- data/LICENSE.txt +21 -0
- data/README.md +565 -0
- data/Rakefile +13 -0
- data/assets/streamweaver-hero.jpg +0 -0
- data/bench/baselines/ledger.rb +58 -0
- data/bench/baselines/warroom.rb +51 -0
- data/bench/fixtures/ledger.rb +76 -0
- data/bench/fixtures/warroom.rb +60 -0
- data/bench/results/6daf8b8.md +102 -0
- data/bench/results/c8d749b.md +102 -0
- data/bench/results/eb06ab9.md +102 -0
- data/bench/run.rb +151 -0
- data/bench/support.rb +84 -0
- data/copy_this/dto_run_sample_run_7631.html +220 -0
- data/docs/SERVICE_MODE.md +302 -0
- data/docs/architecture/how_streamweaver_works.md +772 -0
- data/docs/blog/2026-01-16-streamweaver-introduction.md +515 -0
- data/docs/bug-2026-08-31-canvas-bridge-socket-collision.md +83 -0
- data/docs/canvas-ipc-session-summary.md +127 -0
- data/docs/canvas-panel-workflow.md +172 -0
- data/docs/canvas-read.md +147 -0
- data/docs/canvas-roadmap.md +275 -0
- data/docs/case-studies/2026-09-03-didx-canvas-read-shelf.md +147 -0
- data/docs/claude-code-companion-skill-spec.md +567 -0
- data/docs/components_reference.md +1223 -0
- data/docs/crud-patterns.md +265 -0
- data/docs/endpoints.md +122 -0
- data/docs/for_llms.md +1 -0
- data/docs/form-patterns.md +165 -0
- data/docs/frontend-only.md +169 -0
- data/docs/html-artifact-audit.md +238 -0
- data/docs/ideas/2025-01-01-as-a-service.md +203 -0
- data/docs/ideas/2026-01-16-charm-tui-exploration.md +542 -0
- data/docs/ideas/2026-08-27-static-doc-shelf-export.md +153 -0
- data/docs/ideas/dhh-review-future-refactors.md +142 -0
- data/docs/opal-jamstack.md +47 -0
- data/docs/opal-npm-direction.md +184 -0
- data/docs/opal-spike-findings.md +194 -0
- data/docs/plans/2025-12-16-form-blocks-design.md +124 -0
- data/docs/plans/2025-12-30-examples-browser-design.md +152 -0
- data/docs/plans/2026-01-02-charts-design.md +288 -0
- data/docs/plans/2026-01-10-canvas-ipc-design.md +247 -0
- data/docs/plans/2026-01-19-cabinet-control-components.md +176 -0
- data/docs/plans/2026-01-26-gem-release-and-panel.md +140 -0
- data/docs/plans/canvas-claude-project-design.md +238 -0
- data/docs/plans/canvas-doc-location-and-discovery.md +32 -0
- data/docs/plans/org-doc-preview-surfaces.md +293 -0
- data/docs/plans/shadcn-polish-plan.md +417 -0
- data/docs/porting-artifacts.md +252 -0
- data/docs/reference/agent-skills-comparison.md +369 -0
- data/docs/reference/travel-state-prd.artifact.html +780 -0
- data/docs/research/2026-08-17-hotwire-alike-landscape.md +268 -0
- data/docs/research/2026-08-17-hotwire-concept-map.md +404 -0
- data/docs/research/2026-08-22-lazy-fragments-trigger-decision.md +246 -0
- data/docs/research/2026-08-22-learnhotwire-syllabus-coverage.md +239 -0
- data/docs/research/frontend-only-matrix.md +278 -0
- data/docs/research/streamweaver-way-spike-findings.md +529 -0
- data/docs/resource-dsl.md +342 -0
- data/docs/routing.md +302 -0
- data/docs/ruby-ui-comparison.md +319 -0
- data/docs/shared-dsl-fragments.md +356 -0
- data/docs/streamweaver-for-ai-agents.md +401 -0
- data/docs/streamweaver-frontend-vision.md +123 -0
- data/docs/streamweaver_canvas/glimmer_initial_final_layer.rb +77 -0
- data/docs/streamweaver_canvas/save_example.rb +9 -0
- data/docs/templates.md +213 -0
- data/docs/testing.md +155 -0
- data/docs/theming-hooks.md +281 -0
- data/docs/tutorials/the-streamweaver-way.md +882 -0
- data/docs/university/capability-inventory.md +137 -0
- data/docs/university/dependency-survey.md +114 -0
- data/docs/university/design-spec.md +217 -0
- data/docs/university/mockups/code-block-doc-theme-dark.png +0 -0
- data/docs/university/mockups/code-block-doc-theme-light.png +0 -0
- data/docs/university/mockups/course-list-dark.png +0 -0
- data/docs/university/mockups/course-list-light.png +0 -0
- data/docs/university/mockups/course_canvas_mockup.rb +741 -0
- data/docs/university/mockups/step-screen-dark.png +0 -0
- data/docs/university/mockups/step-screen-light.png +0 -0
- data/docs/university/roadmap.md +72 -0
- data/docs/university/send-to-coworker.md +77 -0
- data/docs/university/worker-session-mining.md +109 -0
- data/docs/visual/browser-rendering-spike.md +173 -0
- data/docs/visual/builder-visual-plan-analysis.md +378 -0
- data/docs/visual/sw-plan-format-exploration.md +511 -0
- data/docs/visual/sw-plan-rendering-deep-dive.md +453 -0
- data/docs/visual-skills/PROGRESS.md +60 -0
- data/docs/visual-skills/SESSION-CONTEXT.md +207 -0
- data/docs/visual-skills/analysis/components.md +317 -0
- data/docs/visual-skills/analysis/overlap.md +360 -0
- data/docs/visual-skills/analysis/pi-design-deck.md +1102 -0
- data/docs/visual-skills/analysis/streamweaver-inventory.md +93 -0
- data/docs/visual-skills/analysis/unified-specs.feature +1003 -0
- data/docs/visual-skills/analysis/visual-explainer.md +964 -0
- data/docs/visual-skills/blog/blog-series-outline.md +39 -0
- data/docs/visual-skills/blog/token-efficiency.md +73 -0
- data/docs/visual-skills/design/architecture.md +1725 -0
- data/docs/visual-skills/design/codex-review.md +340 -0
- data/docs/visual-skills/design/dhh-review.md +209 -0
- data/docs/visual-skills/design/evolution.md +100 -0
- data/docs/visual-skills/design/gemini-review.md +55 -0
- data/docs/visual-skills/design/review-synthesis.md +149 -0
- data/docs/visual-skills/implementation/STATE.md +22 -0
- data/docs/visual-skills/implementation/plan.md +347 -0
- data/docs/visual-skills/implementation/spike-findings.md +237 -0
- data/docs/visual-skills/implementation/tasks.md +702 -0
- data/docs/visual-skills/lessons-learned/process.md +145 -0
- data/examples/README.md +96 -0
- data/examples/advanced/all_components.rb +177 -0
- data/examples/advanced/examples_browser.rb +394 -0
- data/examples/advanced/teachables_browser.rb +261 -0
- data/examples/advanced/theme_tweaker.rb +366 -0
- data/examples/advanced/tutorial.rb +1528 -0
- data/examples/agentic/agentic_form.rb +30 -0
- data/examples/agentic/agentic_form_autoclose.rb +30 -0
- data/examples/agentic/cultivation_tracker.rb +69 -0
- data/examples/basic/hello_world.rb +22 -0
- data/examples/basic/opal_tabs_table.rb +44 -0
- data/examples/basic/todo_list.rb +39 -0
- data/examples/button_loading_test.rb +36 -0
- data/examples/canvas/mermaid_canvas_demo.sh +151 -0
- data/examples/charts/bar_chart_demo.rb +57 -0
- data/examples/charts/line_chart_demo.rb +73 -0
- data/examples/charts/pie_area_demo.rb +87 -0
- data/examples/charts/stacked_bar_chart_demo.rb +69 -0
- data/examples/claude_code/README.md +85 -0
- data/examples/claude_code/codebreaker/.claude/commands/infiltrate.md +632 -0
- data/examples/claude_code/codebreaker/.claude/settings.json +11 -0
- data/examples/claude_code/codebreaker/.claude/settings.local.json +17 -0
- data/examples/claude_code/codebreaker/.claude/skills/infiltrate.md +0 -0
- data/examples/claude_code/codebreaker/README.md +213 -0
- data/examples/claude_code/tutorial/.claude/commands/learn.md +453 -0
- data/examples/claude_code/tutorial/README.md +102 -0
- data/examples/claude_code/verification_flow/.claude/commands/verify.md +171 -0
- data/examples/claude_code/verification_flow/README.md +126 -0
- data/examples/components/annotated_code_demo.rb +54 -0
- data/examples/components/callout_demo.rb +33 -0
- data/examples/components/checkbox_group_demo.rb +46 -0
- data/examples/components/design_review.css +468 -0
- data/examples/components/design_review_demo.rb +44 -0
- data/examples/components/design_review_dsl.rb +300 -0
- data/examples/components/diff_block_demo.rb +112 -0
- data/examples/components/events_demo.rb +184 -0
- data/examples/components/form_demo.rb +62 -0
- data/examples/components/lesson_demo.rb +53 -0
- data/examples/components/markdown_demo.rb +110 -0
- data/examples/components/mermaid_demo.rb +166 -0
- data/examples/components/pareto_set.rb +64 -0
- data/examples/components/prd_demo.rb +21 -0
- data/examples/components/prd_dsl.rb +385 -0
- data/examples/components/quiz_demo.rb +47 -0
- data/examples/components/run_viewer_demo.rb +100 -0
- data/examples/components/score_and_collapsible_demo.rb +82 -0
- data/examples/components/select_stale_value_smoke_test.rb +39 -0
- data/examples/components/table_demo.rb +247 -0
- data/examples/components/timer_with_state_demo.rb +58 -0
- data/examples/components/todo_due_dates.rb +63 -0
- data/examples/components/uat_gaps_demo.rb +112 -0
- data/examples/dashboard/feed_simulator.rb +60 -0
- data/examples/dashboard/live_dashboard.rb +80 -0
- data/examples/dashboard_components.rb +108 -0
- data/examples/deferred_fragments_demo.rb +62 -0
- data/examples/generate_more_spike/README.md +63 -0
- data/examples/generate_more_spike/app.rb +441 -0
- data/examples/git_health.sh +401 -0
- data/examples/layout/layout_components_demo.rb +174 -0
- data/examples/layout/modal_demo.rb +215 -0
- data/examples/layout/navigation_demo.rb +227 -0
- data/examples/layout/route_tabs_demo.rb +52 -0
- data/examples/layout/routing_demo.rb +52 -0
- data/examples/layout/scroll_box_demo.rb +154 -0
- data/examples/lazy_fragments_demo.rb +151 -0
- data/examples/my_todos/README.md +29 -0
- data/examples/my_todos/my_todos.rb +312 -0
- data/examples/my_todos/store.rb +86 -0
- data/examples/opal/reactive_demo.rb +62 -0
- data/examples/opal/scenarios/s1_counter.rb +15 -0
- data/examples/opal/scenarios/s2_search_filter.rb +17 -0
- data/examples/opal/scenarios/s3_sibling_tabs.rb +25 -0
- data/examples/opal/scenarios/s4_shopping_cart.rb +34 -0
- data/examples/opal/scenarios/s5_watch.rb +39 -0
- data/examples/opal/scenarios/s6_on_start.rb +20 -0
- data/examples/opal/scenarios/s7_wizard.rb +33 -0
- data/examples/opal/scenarios/s8_loan_calculator.rb +21 -0
- data/examples/opal/scenarios/s9_dashboard.rb +27 -0
- data/examples/operations_dashboard_demo.rb +167 -0
- data/examples/panel_demo.sh +447 -0
- data/examples/parity/assets/tyrion_slice.css +86 -0
- data/examples/parity/rivet_people_slice.rb +182 -0
- data/examples/parity/tyrion_components.css +777 -0
- data/examples/parity/tyrion_warroom_components.rb +414 -0
- data/examples/parity/tyrion_warroom_slice.rb +549 -0
- data/examples/puma_dev/README.md +124 -0
- data/examples/puma_dev/config.ru +34 -0
- data/examples/puma_dev/standalone_app.rb +34 -0
- data/examples/scaffolding/blog.rb +49 -0
- data/examples/scaffolding/utf_lite.rb +105 -0
- data/examples/styling/feedback_demo.rb +229 -0
- data/examples/styling/style_showcase.rb +172 -0
- data/examples/styling/theme_demo.rb +508 -0
- data/examples/timer_health_checker.rb +111 -0
- data/examples/timer_showcase.rb +131 -0
- data/examples/tutorials/render_markdown.rb +112 -0
- data/examples/tutorials/streamweaver_way_tutorial.rb +44 -0
- data/examples/tutorials/tutorial_content.rb +1082 -0
- data/examples/visual_skills/design_deck_demo.rb +314 -0
- data/examples/visual_skills/explainer_demo.rb +499 -0
- data/exe/streamweaver +9 -0
- data/gsd/ROADMAP-1.0.md +167 -0
- data/gsd/STATE.md +13 -0
- data/gsd/research/market-positioning-research.md +139 -0
- data/gsd/research/production-patterns-research.md +270 -0
- data/gsd/research/repo-audit-1.0.md +274 -0
- data/lib/stream_weaver/action_token.rb +58 -0
- data/lib/stream_weaver/adapter/alpinejs.rb +8249 -0
- data/lib/stream_weaver/adapter/base.rb +591 -0
- data/lib/stream_weaver/adapter/opal.rb +334 -0
- data/lib/stream_weaver/adapter/static.rb +1118 -0
- data/lib/stream_weaver/admin.rb +176 -0
- data/lib/stream_weaver/app.rb +1821 -0
- data/lib/stream_weaver/assets/js/sw-copy.js +50 -0
- data/lib/stream_weaver/assets/js/sw-heredoc-rewrite.js +68 -0
- data/lib/stream_weaver/assets/js/sw-keyboard.js +165 -0
- data/lib/stream_weaver/assets/js/sw-mermaid-zoom.js +621 -0
- data/lib/stream_weaver/assets/js/sw-route-tabs.js +53 -0
- data/lib/stream_weaver/assets/js/sw-sidebar-toc.js +116 -0
- data/lib/stream_weaver/assets/js/sw-slide-nav.js +103 -0
- data/lib/stream_weaver/canvas/bridge.rb +239 -0
- data/lib/stream_weaver/canvas/bridge_server.rb +646 -0
- data/lib/stream_weaver/canvas/client.rb +298 -0
- data/lib/stream_weaver/canvas/doc_roots.rb +233 -0
- data/lib/stream_weaver/canvas/doc_store.rb +252 -0
- data/lib/stream_weaver/canvas/gist_publisher.rb +264 -0
- data/lib/stream_weaver/canvas/gist_save_handler.rb +89 -0
- data/lib/stream_weaver/canvas/gist_store.rb +135 -0
- data/lib/stream_weaver/canvas/helpers.rb +109 -0
- data/lib/stream_weaver/canvas/history.rb +90 -0
- data/lib/stream_weaver/canvas/protocol.rb +86 -0
- data/lib/stream_weaver/canvas/reader.rb +853 -0
- data/lib/stream_weaver/canvas/save_doc_widget.rb +457 -0
- data/lib/stream_weaver/canvas/scroll_top_hint.rb +21 -0
- data/lib/stream_weaver/canvas/session.rb +132 -0
- data/lib/stream_weaver/cli.rb +3235 -0
- data/lib/stream_weaver/component_assets.rb +70 -0
- data/lib/stream_weaver/component_registry.rb +67 -0
- data/lib/stream_weaver/component_renderer.rb +48 -0
- data/lib/stream_weaver/components/annotated_code.rb +53 -0
- data/lib/stream_weaver/components/api_endpoint.rb +42 -0
- data/lib/stream_weaver/components/callout.rb +59 -0
- data/lib/stream_weaver/components/chart.rb +84 -0
- data/lib/stream_weaver/components/code_block.rb +77 -0
- data/lib/stream_weaver/components/comparison.rb +39 -0
- data/lib/stream_weaver/components/decision.rb +38 -0
- data/lib/stream_weaver/components/deck/close_overlay.rb +84 -0
- data/lib/stream_weaver/components/deck/confirmation_bar.rb +60 -0
- data/lib/stream_weaver/components/deck/deck_option.rb +61 -0
- data/lib/stream_weaver/components/deck/deck_slide.rb +77 -0
- data/lib/stream_weaver/components/deck/deck_state.rb +469 -0
- data/lib/stream_weaver/components/deck/deck_summary.rb +73 -0
- data/lib/stream_weaver/components/deck/design_deck.rb +60 -0
- data/lib/stream_weaver/components/deck/generate_more_controls.rb +84 -0
- data/lib/stream_weaver/components/deck/model_selector.rb +84 -0
- data/lib/stream_weaver/components/deck/skeleton_placeholder.rb +36 -0
- data/lib/stream_weaver/components/diff_block.rb +125 -0
- data/lib/stream_weaver/components/doc_header.rb +57 -0
- data/lib/stream_weaver/components/image_block.rb +70 -0
- data/lib/stream_weaver/components/implementation_map.rb +33 -0
- data/lib/stream_weaver/components/keyboard_shortcuts.rb +94 -0
- data/lib/stream_weaver/components/kpi_dashboard.rb +78 -0
- data/lib/stream_weaver/components/mermaid.rb +79 -0
- data/lib/stream_weaver/components/pipeline.rb +63 -0
- data/lib/stream_weaver/components/sidebar_toc.rb +46 -0
- data/lib/stream_weaver/components/slide_container.rb +141 -0
- data/lib/stream_weaver/components/timeline_event.rb +58 -0
- data/lib/stream_weaver/components/wireframe.rb +29 -0
- data/lib/stream_weaver/components/wireframe_block.rb +34 -0
- data/lib/stream_weaver/components.rb +2711 -0
- data/lib/stream_weaver/css.rb +230 -0
- data/lib/stream_weaver/dev_fallback_overlay.rb +61 -0
- data/lib/stream_weaver/display_dsl.rb +1004 -0
- data/lib/stream_weaver/export/html_exporter.rb +478 -0
- data/lib/stream_weaver/feed.rb +34 -0
- data/lib/stream_weaver/feed_builder.rb +31 -0
- data/lib/stream_weaver/fonts.rb +33 -0
- data/lib/stream_weaver/interaction_runner.rb +487 -0
- data/lib/stream_weaver/iterm.rb +460 -0
- data/lib/stream_weaver/layout_registry.rb +92 -0
- data/lib/stream_weaver/opal/bridge.rb +52 -0
- data/lib/stream_weaver/opal/builder.rb +193 -0
- data/lib/stream_weaver/opal/env.rb +29 -0
- data/lib/stream_weaver/opal/reactive_state.rb +75 -0
- data/lib/stream_weaver/opal/regexp_anchor_patch.rb +62 -0
- data/lib/stream_weaver/opal/renderer.rb +77 -0
- data/lib/stream_weaver/opal/runtime.rb +250 -0
- data/lib/stream_weaver/opal/shell.rb +145 -0
- data/lib/stream_weaver/opal/string_bridge.rb +50 -0
- data/lib/stream_weaver/opal/stubs/diff.min.js +1 -0
- data/lib/stream_weaver/opal/stubs/digest.rb +15 -0
- data/lib/stream_weaver/opal/stubs/marked.umd.js +79 -0
- data/lib/stream_weaver/opal/stubs/md5.rb +3 -0
- data/lib/stream_weaver/opal/stubs/morphdom.min.js +775 -0
- data/lib/stream_weaver/opal/stubs/prism-tomorrow.min.css +1 -0
- data/lib/stream_weaver/opal/stubs/prism.min.js +1967 -0
- data/lib/stream_weaver/opal_entry.rb +136 -0
- data/lib/stream_weaver/org/inline.rb +95 -0
- data/lib/stream_weaver/org/reader.rb +561 -0
- data/lib/stream_weaver/org/recording_context.rb +86 -0
- data/lib/stream_weaver/org/source_splitter.rb +63 -0
- data/lib/stream_weaver/org/writer.rb +300 -0
- data/lib/stream_weaver/page_shell.rb +530 -0
- data/lib/stream_weaver/portfile.rb +79 -0
- data/lib/stream_weaver/pushable.rb +42 -0
- data/lib/stream_weaver/resource/default_views.rb +111 -0
- data/lib/stream_weaver/resource/field_input.rb +25 -0
- data/lib/stream_weaver/resource/state_keys.rb +16 -0
- data/lib/stream_weaver/resource/store.rb +18 -0
- data/lib/stream_weaver/resource.rb +104 -0
- data/lib/stream_weaver/server.rb +1471 -0
- data/lib/stream_weaver/service.rb +1240 -0
- data/lib/stream_weaver/service_client.rb +104 -0
- data/lib/stream_weaver/session_store.rb +186 -0
- data/lib/stream_weaver/skills/streamweaver-canvas-safe/SKILL.md +66 -0
- data/lib/stream_weaver/skills/streamweaver-canvas-safe/examples/canvas-safe-showcase.rb +98 -0
- data/lib/stream_weaver/skills/streamweaver-canvas-safe/references/actions-and-buttons.md +47 -0
- data/lib/stream_weaver/skills/streamweaver-canvas-safe/references/charts-and-diagrams.md +38 -0
- data/lib/stream_weaver/skills/streamweaver-canvas-safe/references/deck.md +32 -0
- data/lib/stream_weaver/skills/streamweaver-canvas-safe/references/inputs-and-forms.md +65 -0
- data/lib/stream_weaver/skills/streamweaver-canvas-safe/references/tabs-and-navigation.md +53 -0
- data/lib/stream_weaver/skills/streamweaver-doc-builder/SKILL.md +298 -0
- data/lib/stream_weaver/skills/streamweaver-visual-companion/SKILL.md +130 -0
- data/lib/stream_weaver/skills/streamweaver-visual-companion/examples/design-review-example.css +468 -0
- data/lib/stream_weaver/skills/streamweaver-visual-companion/examples/design-review-example.rb +39 -0
- data/lib/stream_weaver/skills/streamweaver-visual-companion/examples/design-review-example_dsl.rb +300 -0
- data/lib/stream_weaver/skills/streamweaver-visual-companion/examples/doc-parity-example.rb +24 -0
- data/lib/stream_weaver/skills/streamweaver-visual-companion/examples/doc-parity-example_dsl.rb +385 -0
- data/lib/stream_weaver/skills/streamweaver-visual-companion/references/checkpoints-and-forms.md +28 -0
- data/lib/stream_weaver/skills/streamweaver-visual-companion/references/cleanup-and-panel.md +44 -0
- data/lib/stream_weaver/skills/streamweaver-visual-companion/references/example-gallery.md +8 -0
- data/lib/stream_weaver/skills/streamweaver-visual-companion/references/persistence.md +58 -0
- data/lib/stream_weaver/skills/streamweaver-way/SKILL.md +396 -0
- data/lib/stream_weaver/skills/visual-plan/SKILL.md +201 -0
- data/lib/stream_weaver/skills/visual-recap/SKILL.md +244 -0
- data/lib/stream_weaver/streamer.rb +63 -0
- data/lib/stream_weaver/templates/choices.rb +149 -0
- data/lib/stream_weaver/templates/code.rb +157 -0
- data/lib/stream_weaver/templates/confirm.rb +110 -0
- data/lib/stream_weaver/templates/diff.rb +195 -0
- data/lib/stream_weaver/templates/info.rb +142 -0
- data/lib/stream_weaver/templates/table.rb +169 -0
- data/lib/stream_weaver/templates/wizard.rb +271 -0
- data/lib/stream_weaver/theme/auto_mode.rb +116 -0
- data/lib/stream_weaver/theme/presets.rb +555 -0
- data/lib/stream_weaver/theme.rb +639 -0
- data/lib/stream_weaver/university/canvas.rb +924 -0
- data/lib/stream_weaver/university/course.rb +699 -0
- data/lib/stream_weaver/university/demos/counter.rb +33 -0
- data/lib/stream_weaver/university/demos/dashboard.rb +147 -0
- data/lib/stream_weaver/university/demos/decision_form.rb +143 -0
- data/lib/stream_weaver/university/demos.rb +50 -0
- data/lib/stream_weaver/university/listener.rb +467 -0
- data/lib/stream_weaver/university/progress.rb +201 -0
- data/lib/stream_weaver/university/runner.rb +138 -0
- data/lib/stream_weaver/university/scripts/growing_doc.rb +609 -0
- data/lib/stream_weaver/university/scripts/growing_doc_state.rb +91 -0
- data/lib/stream_weaver/utils.rb +31 -0
- data/lib/stream_weaver/version.rb +5 -0
- data/lib/stream_weaver/views/canvas/reader_layout.erb +800 -0
- data/lib/stream_weaver/views.rb +3940 -0
- data/lib/stream_weaver.rb +122 -0
- data/llms.txt +1269 -0
- data/sig/stream_weaver.rbs +4 -0
- metadata +598 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# S3: Sibling Coordination via Shared State
|
|
3
|
+
# React equivalent: lift state to parent, thread props down to both siblings
|
|
4
|
+
# StreamWeaver: state[:key] is already global — no lifting needed
|
|
5
|
+
|
|
6
|
+
app "S3 — Sibling Coordination" do
|
|
7
|
+
tabs :active_tab do
|
|
8
|
+
tab "Config" do
|
|
9
|
+
text_field :theme_name, label: "Theme Name"
|
|
10
|
+
text_field :app_name, label: "App Name"
|
|
11
|
+
button("Light theme") { state[:dark] = false }
|
|
12
|
+
button("Dark theme") { state[:dark] = true }
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
tab "Preview" do
|
|
16
|
+
bg = state[:dark] ? "#1a1a2e" : "#ffffff"
|
|
17
|
+
fg = state[:dark] ? "#e0e0e0" : "#1a1a1a"
|
|
18
|
+
div(style: "background:#{bg};color:#{fg};padding:24px;border-radius:8px") do
|
|
19
|
+
header2 state[:app_name] || "My App"
|
|
20
|
+
text "Theme: #{state[:theme_name] || "(none set)"}"
|
|
21
|
+
text "Mode: #{state[:dark] ? "Dark" : "Light"}"
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# S4: Shopping Cart with Derived Total
|
|
3
|
+
# React equivalent: Context API (or Redux/Zustand) to share cart across component trees
|
|
4
|
+
# StreamWeaver: state[:cart] is already visible everywhere — no Context needed
|
|
5
|
+
|
|
6
|
+
app "S4 — Shopping Cart" do
|
|
7
|
+
products = [
|
|
8
|
+
{ name: "Widget", price: 9.99 },
|
|
9
|
+
{ name: "Gadget", price: 24.99 },
|
|
10
|
+
{ name: "Doohickey", price: 4.99 },
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
products.each do |p|
|
|
14
|
+
card do
|
|
15
|
+
header3 p[:name]
|
|
16
|
+
text "$#{p[:price]}"
|
|
17
|
+
button("Add to cart") { state[:cart] = (state[:cart] || []) + [p] }
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
div(style: "height:16px")
|
|
22
|
+
|
|
23
|
+
cart = state[:cart] || []
|
|
24
|
+
card do
|
|
25
|
+
header3 "Cart (#{cart.size} items)"
|
|
26
|
+
if cart.empty?
|
|
27
|
+
text "Nothing added yet"
|
|
28
|
+
else
|
|
29
|
+
cart.each { |item| text "• #{item[:name]} — $#{item[:price]}" }
|
|
30
|
+
text "Total: $#{"%.2f" % cart.sum { |i| i[:price] }}"
|
|
31
|
+
button("Clear") { state[:cart] = [] }
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# S5: Watch — Side Effect on State Change
|
|
3
|
+
# React equivalent: useEffect with [username] dependency array
|
|
4
|
+
# StreamWeaver: watch(:key) { |val| } — fires exactly when that key changes
|
|
5
|
+
|
|
6
|
+
TAKEN = %w[alice bob admin root test ruby opal streamweaver].freeze
|
|
7
|
+
|
|
8
|
+
app "S5 — Watch: Username Availability" do
|
|
9
|
+
watch(:username) do |name|
|
|
10
|
+
n = name.to_s.strip.downcase
|
|
11
|
+
state[:status] = if n.empty?
|
|
12
|
+
nil
|
|
13
|
+
elsif n.length < 3
|
|
14
|
+
:too_short
|
|
15
|
+
elsif TAKEN.include?(n)
|
|
16
|
+
:taken
|
|
17
|
+
else
|
|
18
|
+
:available
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
card do
|
|
23
|
+
header3 "Choose a username"
|
|
24
|
+
text_field :username, placeholder: "e.g. forrest42"
|
|
25
|
+
|
|
26
|
+
case state[:status]
|
|
27
|
+
when :too_short then badge "Too short (min 3 chars)", color: :yellow
|
|
28
|
+
when :taken then badge "Already taken", color: :red
|
|
29
|
+
when :available then badge "Available!", color: :green
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
div(style: "height:12px")
|
|
34
|
+
|
|
35
|
+
card do
|
|
36
|
+
header3 "How it works"
|
|
37
|
+
md "**watch(:username)** fires every time `:username` changes — like `useEffect(() => { check(username) }, [username])` in React. No polling, no diffing. The watch block runs once per distinct value, sets `:status`, and the render reflects it immediately."
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# S6: on_start — Async Fetch on Mount
|
|
3
|
+
# React equivalent: useEffect(() => { fetch('/api/items').then(...) }, [])
|
|
4
|
+
# StreamWeaver: on_start { } — fires exactly once after first render
|
|
5
|
+
|
|
6
|
+
app "S6 — on_start: Async Fetch on Mount" do
|
|
7
|
+
on_start do
|
|
8
|
+
after(0.8) do
|
|
9
|
+
state[:items] = ["Dashboard Report", "Weekly Summary", "Q2 Forecast", "Team Updates", "Release Notes"]
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
if state[:items]
|
|
14
|
+
badge "Loaded via on_start", color: :green
|
|
15
|
+
div(style: "height:8px")
|
|
16
|
+
state[:items].each { |item| text "• #{item}" }
|
|
17
|
+
else
|
|
18
|
+
text "Loading..."
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# S7: Multi-Step Wizard / State Machine
|
|
3
|
+
# React equivalent: useReducer — dispatch events to a pure transition function
|
|
4
|
+
# StreamWeaver: case/when is the reducer — Ruby already has this
|
|
5
|
+
|
|
6
|
+
app "S7 — Multi-Step Wizard" do
|
|
7
|
+
case (state[:step] || :info)
|
|
8
|
+
when :info
|
|
9
|
+
header3 "Step 1 of 3 — Your Info"
|
|
10
|
+
text_field :name, label: "Full Name"
|
|
11
|
+
text_field :email, label: "Email"
|
|
12
|
+
button("Next →") { state[:step] = :payment }
|
|
13
|
+
|
|
14
|
+
when :payment
|
|
15
|
+
header3 "Step 2 of 3 — Payment"
|
|
16
|
+
text_field :card, label: "Card Number"
|
|
17
|
+
button("← Back") { state[:step] = :info }
|
|
18
|
+
button("Next →") { state[:step] = :confirm }
|
|
19
|
+
|
|
20
|
+
when :confirm
|
|
21
|
+
header3 "Step 3 of 3 — Review"
|
|
22
|
+
text "Name: #{state[:name]}"
|
|
23
|
+
text "Email: #{state[:email]}"
|
|
24
|
+
text "Card: #{state[:card]}"
|
|
25
|
+
button("← Back") { state[:step] = :payment }
|
|
26
|
+
button("Submit ✓") { state[:step] = :done }
|
|
27
|
+
|
|
28
|
+
when :done
|
|
29
|
+
badge "Submitted!", color: :green
|
|
30
|
+
text "Welcome, #{state[:name]}."
|
|
31
|
+
button("Start over") { state[:step] = :info }
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# S8: Loan Calculator — Interdependent Derived Fields
|
|
3
|
+
# React equivalent: useMemo with [principal, rate, term] dependency array
|
|
4
|
+
# StreamWeaver: inline computation — no memoization annotation needed
|
|
5
|
+
|
|
6
|
+
app "S8 — Loan Calculator" do
|
|
7
|
+
text_field :principal, label: "Loan Amount ($)", type: :number
|
|
8
|
+
text_field :rate, label: "Annual Rate (%)", type: :number
|
|
9
|
+
text_field :term, label: "Term (months)", type: :number
|
|
10
|
+
|
|
11
|
+
p = state[:principal].to_f
|
|
12
|
+
r = state[:rate].to_f / 100.0 / 12.0
|
|
13
|
+
n = state[:term].to_f
|
|
14
|
+
payment = (r > 0 && n > 0) ? (p * r * (1 + r)**n) / ((1 + r)**n - 1) : 0.0
|
|
15
|
+
|
|
16
|
+
div(style: "height:16px")
|
|
17
|
+
card do
|
|
18
|
+
header3 "Monthly Payment"
|
|
19
|
+
text "$#{"%.2f" % payment}"
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# S9: Dashboard — Multiple Widgets Sharing One Symbol
|
|
3
|
+
# React equivalent: Context API + multiple connected components
|
|
4
|
+
# StreamWeaver: state[:symbol] is just there — every widget reads it directly
|
|
5
|
+
|
|
6
|
+
app "S9 — Dashboard: Multiple Widgets, Shared Symbol" do
|
|
7
|
+
prices = { "AAPL" => 189.30, "MSFT" => 378.85, "GOOG" => 140.53 }
|
|
8
|
+
volumes = { "AAPL" => "54.2M", "MSFT" => "22.1M", "GOOG" => "28.7M" }
|
|
9
|
+
pes = { "AAPL" => 29.4, "MSFT" => 35.2, "GOOG" => 26.1 }
|
|
10
|
+
|
|
11
|
+
sym = state[:symbol] || "AAPL"
|
|
12
|
+
|
|
13
|
+
# Symbol selector — buttons (safe across all Opal adapters)
|
|
14
|
+
text "Select symbol:"
|
|
15
|
+
%w[AAPL MSFT GOOG].each do |s|
|
|
16
|
+
button(s) { state[:symbol] = s }
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
div(style: "height:16px")
|
|
20
|
+
|
|
21
|
+
# Try columns layout
|
|
22
|
+
columns widths: ["33%", "33%", "34%"] do
|
|
23
|
+
column { card { header3 "Price"; text "$#{prices[sym]}" } }
|
|
24
|
+
column { card { header3 "Volume"; text volumes[sym] } }
|
|
25
|
+
column { card { header3 "P/E"; text pes[sym].to_s } }
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
# Example: Operations Dashboard
|
|
5
|
+
# Demonstrates app_shell layout with sidebar, expandable cards, and dashboard components
|
|
6
|
+
# Run with: ./exe/streamweaver examples/operations_dashboard_demo.rb
|
|
7
|
+
|
|
8
|
+
app "Operations Dashboard", theme: :dark, layout: :fluid do
|
|
9
|
+
app_shell sidebar_width: "340px" do
|
|
10
|
+
main do
|
|
11
|
+
# Header
|
|
12
|
+
app_header "Operations Dashboard", variant: :primary do
|
|
13
|
+
pulse_indicator color: :green, label: "All Systems Operational"
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Section header
|
|
17
|
+
hstack justify: :between, align: :center do
|
|
18
|
+
text "TEAMS"
|
|
19
|
+
hstack spacing: :sm do
|
|
20
|
+
button "Grid", variant: :secondary
|
|
21
|
+
button "List", variant: :secondary
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Team cards grid
|
|
26
|
+
grid cols: 2, gap: :lg do
|
|
27
|
+
# Engineering card
|
|
28
|
+
expandable_card key: :engineering_expanded,
|
|
29
|
+
title: "Engineering",
|
|
30
|
+
subtitle: "Product Development",
|
|
31
|
+
badge_text: "5 activities",
|
|
32
|
+
status: :red,
|
|
33
|
+
initially_expanded: true do
|
|
34
|
+
hstack spacing: :xl, justify: :start do
|
|
35
|
+
stat_display value: 1, label: "RESEARCH", color: :blue
|
|
36
|
+
stat_display value: 2, label: "TASKS", color: :purple
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
card variant: :outlined do
|
|
40
|
+
text "Sprint velocity below target - 3 blockers identified"
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
vstack spacing: :none do
|
|
44
|
+
activity_item time: "15:00", title: "Architecture review",
|
|
45
|
+
summary: "Evaluate microservices migration approach",
|
|
46
|
+
type: :research
|
|
47
|
+
|
|
48
|
+
activity_item time: "14:30", title: "CI pipeline fixed",
|
|
49
|
+
summary: "Flaky tests resolved, builds stable",
|
|
50
|
+
type: :task
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Design card
|
|
55
|
+
expandable_card key: :design_expanded,
|
|
56
|
+
title: "Design",
|
|
57
|
+
subtitle: "UX & Visual",
|
|
58
|
+
badge_text: "4 activities",
|
|
59
|
+
status: :green do
|
|
60
|
+
hstack spacing: :xl, justify: :start do
|
|
61
|
+
stat_display value: 1, label: "RESEARCH", color: :blue
|
|
62
|
+
stat_display value: 1, label: "TASKS", color: :purple
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
card variant: :outlined do
|
|
66
|
+
text "Design system v2 on track - components finalized"
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
vstack spacing: :none do
|
|
70
|
+
activity_item time: "15:00", title: "User research synthesis",
|
|
71
|
+
summary: "Interview findings compiled, patterns identified",
|
|
72
|
+
type: :research
|
|
73
|
+
|
|
74
|
+
activity_item time: "15:05", title: "Accessibility review needed",
|
|
75
|
+
summary: "WCAG compliance check for new components",
|
|
76
|
+
type: :escalation
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# Operations card
|
|
81
|
+
expandable_card key: :ops_expanded,
|
|
82
|
+
title: "Operations",
|
|
83
|
+
subtitle: "Infrastructure & SRE",
|
|
84
|
+
badge_text: "4 activities",
|
|
85
|
+
status: :yellow do
|
|
86
|
+
hstack spacing: :xl, justify: :start do
|
|
87
|
+
stat_display value: 1, label: "RESEARCH", color: :blue
|
|
88
|
+
stat_display value: 1, label: "TASKS", color: :purple
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
card variant: :outlined do
|
|
92
|
+
text "Monitoring upgrade in progress - 70% complete"
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# Product card
|
|
97
|
+
expandable_card key: :product_expanded,
|
|
98
|
+
title: "Product",
|
|
99
|
+
subtitle: "Strategy & Roadmap",
|
|
100
|
+
badge_text: "4 activities",
|
|
101
|
+
status: :green do
|
|
102
|
+
hstack spacing: :xl, justify: :start do
|
|
103
|
+
stat_display value: 1, label: "RESEARCH", color: :blue
|
|
104
|
+
stat_display value: 1, label: "TASKS", color: :purple
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
card variant: :outlined do
|
|
108
|
+
text "Q2 roadmap finalized - stakeholder alignment complete"
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
# Summary stats
|
|
114
|
+
header2 "THIS WEEK"
|
|
115
|
+
hstack spacing: :xl do
|
|
116
|
+
card do
|
|
117
|
+
stat_display value: 24, label: "ACTIVITIES", color: :blue, size: :lg
|
|
118
|
+
end
|
|
119
|
+
card do
|
|
120
|
+
stat_display value: 7, label: "RESEARCH", color: :blue, size: :lg
|
|
121
|
+
end
|
|
122
|
+
card do
|
|
123
|
+
stat_display value: 12, label: "TASKS", color: :purple, size: :lg
|
|
124
|
+
end
|
|
125
|
+
card do
|
|
126
|
+
stat_display value: 5, label: "ESCALATIONS", color: :red, size: :lg
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
sidebar header: "Blockers" do
|
|
132
|
+
badge "5", variant: :danger
|
|
133
|
+
|
|
134
|
+
vstack spacing: :md do
|
|
135
|
+
priority_item priority: :critical,
|
|
136
|
+
title: "Database capacity limit",
|
|
137
|
+
description: "Primary DB at 92% storage. Need immediate expansion or archival.",
|
|
138
|
+
meta_left: "ops",
|
|
139
|
+
meta_right: "Expand storage"
|
|
140
|
+
|
|
141
|
+
priority_item priority: :urgent,
|
|
142
|
+
title: "Third-party API outage",
|
|
143
|
+
description: "Payment provider experiencing degraded performance.",
|
|
144
|
+
meta_left: "backend",
|
|
145
|
+
meta_right: "Monitor status"
|
|
146
|
+
|
|
147
|
+
priority_item priority: :high,
|
|
148
|
+
title: "Security patch required",
|
|
149
|
+
description: "CVE-2024-1234 affects auth library. Update needed.",
|
|
150
|
+
meta_left: "security",
|
|
151
|
+
meta_right: "Apply patch"
|
|
152
|
+
|
|
153
|
+
priority_item priority: :high,
|
|
154
|
+
title: "Mobile app store review",
|
|
155
|
+
description: "iOS submission rejected - privacy manifest missing.",
|
|
156
|
+
meta_left: "mobile",
|
|
157
|
+
meta_right: "Update manifest"
|
|
158
|
+
|
|
159
|
+
priority_item priority: :high,
|
|
160
|
+
title: "Customer escalation",
|
|
161
|
+
description: "Enterprise client reporting data sync delays.",
|
|
162
|
+
meta_left: "support",
|
|
163
|
+
meta_right: "Investigate"
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
end
|