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,30 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require_relative '../../lib/stream_weaver'
|
|
5
|
+
|
|
6
|
+
# Agentic mode example - collect data and return to agent
|
|
7
|
+
App = app "User Survey" do
|
|
8
|
+
text "## User Information Survey"
|
|
9
|
+
text "Please fill out this form. When you click Submit, the data will be returned to the calling process."
|
|
10
|
+
|
|
11
|
+
text "Your Name:"
|
|
12
|
+
text_field :name, placeholder: "Enter your full name"
|
|
13
|
+
|
|
14
|
+
text "Your Email:"
|
|
15
|
+
text_field :email, placeholder: "Enter your email address"
|
|
16
|
+
|
|
17
|
+
text "Priority Level:"
|
|
18
|
+
select :priority, ["Low", "Medium", "High", "Critical"]
|
|
19
|
+
|
|
20
|
+
checkbox :agree, "I agree to terms and conditions"
|
|
21
|
+
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Run in agentic mode - blocks until form submitted, outputs JSON, then exits
|
|
25
|
+
# The form will automatically show a "Submit to Agent" button
|
|
26
|
+
result = App.run_once!
|
|
27
|
+
|
|
28
|
+
# This line will execute after form submission
|
|
29
|
+
puts "\n✅ Agent received data:"
|
|
30
|
+
puts JSON.pretty_generate(result)
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require_relative '../../lib/stream_weaver'
|
|
5
|
+
|
|
6
|
+
# Agentic mode example with auto-close window feature
|
|
7
|
+
App = app "Quick Survey" do
|
|
8
|
+
header "Quick User Survey"
|
|
9
|
+
text "Fill out this form. The window will close automatically after submission."
|
|
10
|
+
|
|
11
|
+
text "Your Name:"
|
|
12
|
+
text_field :name, placeholder: "Enter your full name"
|
|
13
|
+
|
|
14
|
+
text "Your Email:"
|
|
15
|
+
text_field :email, placeholder: "Enter your email address"
|
|
16
|
+
|
|
17
|
+
text "Priority Level:"
|
|
18
|
+
select :priority, ["Low", "Medium", "High", "Critical"]
|
|
19
|
+
|
|
20
|
+
checkbox :agree, "I agree to terms and conditions"
|
|
21
|
+
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Run in agentic mode with auto-close enabled
|
|
25
|
+
# The browser window will close automatically 1 second after clicking submit
|
|
26
|
+
result = App.run_once!(auto_close_window: true)
|
|
27
|
+
|
|
28
|
+
# This line will execute after form submission
|
|
29
|
+
puts "\n✅ Agent received data:"
|
|
30
|
+
puts JSON.pretty_generate(result)
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require_relative '../../lib/stream_weaver'
|
|
5
|
+
|
|
6
|
+
# Daily Cultivation Check-in Form (matches /daily-checkin format)
|
|
7
|
+
# Updated: December 2025
|
|
8
|
+
cultivation_app = app "Daily Cultivation Check-in" do
|
|
9
|
+
header "🌱 Daily Cultivation Check-in"
|
|
10
|
+
text "Reflect on today's cultivation journey"
|
|
11
|
+
|
|
12
|
+
# Determine checkin date
|
|
13
|
+
checkin_date = if Time.now.hour < 18
|
|
14
|
+
(Date.today - 1).strftime("%A, %B %d, %Y")
|
|
15
|
+
else
|
|
16
|
+
Date.today.strftime("%A, %B %d, %Y")
|
|
17
|
+
end
|
|
18
|
+
header3 "📅 #{checkin_date}"
|
|
19
|
+
|
|
20
|
+
# Question 1: Energy level today
|
|
21
|
+
header3 "1. How is your cultivation energy today? (1-10)"
|
|
22
|
+
select :energy_today, ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"], default: "8"
|
|
23
|
+
|
|
24
|
+
# Question 2: Daily Narrative (what happened)
|
|
25
|
+
header3 "2. What happened today?"
|
|
26
|
+
text "Activities, meetings, events, notable moments"
|
|
27
|
+
text_area :daily_narrative, placeholder: "Describe your day - this becomes your Daily Narrative section...", rows: 6, submit: false
|
|
28
|
+
|
|
29
|
+
# Question 3: Achievements (unlimited - 7 slots)
|
|
30
|
+
header3 "3. Cultivation Achievements"
|
|
31
|
+
text "List your wins - progress of any size counts! (leave extras blank)"
|
|
32
|
+
text_field :achievement_1, placeholder: "Achievement #1", submit: false
|
|
33
|
+
text_field :achievement_2, placeholder: "Achievement #2", submit: false
|
|
34
|
+
text_field :achievement_3, placeholder: "Achievement #3", submit: false
|
|
35
|
+
text_field :achievement_4, placeholder: "Achievement #4 (optional)", submit: false
|
|
36
|
+
text_field :achievement_5, placeholder: "Achievement #5 (optional)", submit: false
|
|
37
|
+
text_field :achievement_6, placeholder: "Achievement #6 (optional)", submit: false
|
|
38
|
+
text_field :achievement_7, placeholder: "Achievement #7 (optional)", submit: false
|
|
39
|
+
|
|
40
|
+
# Question 4: Tomorrow's priority
|
|
41
|
+
header3 "4. What's your #1 cultivation priority for tomorrow?"
|
|
42
|
+
text_area :priority_tomorrow, placeholder: "Your top priority for tomorrow...", rows: 2, submit: false
|
|
43
|
+
|
|
44
|
+
# Question 5: Tomorrow's energy forecast
|
|
45
|
+
header3 "5. Energy level for tomorrow's practice? (1-10)"
|
|
46
|
+
select :energy_tomorrow, ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"], default: "8"
|
|
47
|
+
|
|
48
|
+
# Question 6: Obstacles
|
|
49
|
+
header3 "6. Any obstacles or resistances you faced?"
|
|
50
|
+
text "(or leave blank if none)"
|
|
51
|
+
text_area :obstacles, placeholder: "Describe any challenges, blockers, or resistances...", rows: 3, submit: false
|
|
52
|
+
|
|
53
|
+
# Question 7: Learnings & Patterns
|
|
54
|
+
header3 "7. Any learnings or patterns you noticed?"
|
|
55
|
+
text "(or leave blank if none)"
|
|
56
|
+
text_area :learnings, placeholder: "Insights, patterns, things you learned today...", rows: 3, submit: false
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Run in agentic mode - agent collects the reflection data
|
|
60
|
+
puts "\n╔══════════════════════════════════════════════════════════╗"
|
|
61
|
+
puts "║ 🌱 Daily Cultivation Check-in (StreamWeaver) ║"
|
|
62
|
+
puts "╚══════════════════════════════════════════════════════════╝\n"
|
|
63
|
+
puts "Fill out your daily reflection form in the browser."
|
|
64
|
+
puts "Click '🤖 Submit to Agent' when complete.\n"
|
|
65
|
+
|
|
66
|
+
result = cultivation_app.run_once!(timeout: 1800)
|
|
67
|
+
|
|
68
|
+
# Output JSON for agent consumption
|
|
69
|
+
puts "\n#{result.to_json}"
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require_relative '../../lib/stream_weaver'
|
|
5
|
+
|
|
6
|
+
App = app "Hello World" do
|
|
7
|
+
header1 "Welcome to StreamWeaver!"
|
|
8
|
+
|
|
9
|
+
text_field :name, placeholder: "Enter your name"
|
|
10
|
+
|
|
11
|
+
if state[:name] && state[:name].strip != ""
|
|
12
|
+
text "Hello, #{state[:name]}! 👋"
|
|
13
|
+
|
|
14
|
+
checkbox :subscribe, "Subscribe to newsletter"
|
|
15
|
+
|
|
16
|
+
if state[:subscribe]
|
|
17
|
+
text "✅ You're subscribed!"
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
App.run! if __FILE__ == $0
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
# Opal Phase 2b UAT — tabs + sortable table
|
|
4
|
+
# Build: streamweaver opal-build examples/basic/opal_tabs_table.rb
|
|
5
|
+
# Open: open dist/index.html
|
|
6
|
+
|
|
7
|
+
require_relative '../../lib/stream_weaver'
|
|
8
|
+
|
|
9
|
+
App = app "Opal Phase 2b: Tabs + Table" do
|
|
10
|
+
header1 "Opal Phase 2b UAT"
|
|
11
|
+
|
|
12
|
+
tabs :section do
|
|
13
|
+
tab "People" do
|
|
14
|
+
header3 "Sortable Table — click column headers to sort"
|
|
15
|
+
table :people,
|
|
16
|
+
headers: ["Name", "Department", "Score"],
|
|
17
|
+
rows: [
|
|
18
|
+
["Alice", "Engineering", "92"],
|
|
19
|
+
["Bob", "Design", "78"],
|
|
20
|
+
["Carol", "Engineering", "85"],
|
|
21
|
+
["Dave", "Product", "90"],
|
|
22
|
+
["Eve", "Design", "88"]
|
|
23
|
+
],
|
|
24
|
+
sortable: true,
|
|
25
|
+
striped: true
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
tab "Settings" do
|
|
29
|
+
header3 "Settings Tab"
|
|
30
|
+
text_field :query, placeholder: "Search..."
|
|
31
|
+
text "You typed: #{state[:query]}" if state[:query] && !state[:query].empty?
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
tab "About" do
|
|
35
|
+
header3 "About"
|
|
36
|
+
md "**Opal Phase 2b** adds `render_tabs` and `render_table` to the Opal adapter using the `register_callbacks` protocol."
|
|
37
|
+
md "- Tabs switch without a server round-trip"
|
|
38
|
+
md "- Table sorts client-side (click a column header)"
|
|
39
|
+
md "- All using the same DSL as server-side StreamWeaver"
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
App.run! if __FILE__ == $0
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require_relative '../../lib/stream_weaver'
|
|
5
|
+
|
|
6
|
+
# Full CRUD Todo List App
|
|
7
|
+
App = app "Todo Manager" do
|
|
8
|
+
header "📝 Todo List"
|
|
9
|
+
|
|
10
|
+
text_field :new_todo, placeholder: "Enter a new todo"
|
|
11
|
+
|
|
12
|
+
button "Add Todo" do |state|
|
|
13
|
+
state[:todos] ||= []
|
|
14
|
+
if state[:new_todo] && state[:new_todo].strip != ""
|
|
15
|
+
state[:todos] << state[:new_todo]
|
|
16
|
+
state[:new_todo] = ""
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Display todos
|
|
21
|
+
state[:todos] ||= []
|
|
22
|
+
|
|
23
|
+
if state[:todos].empty?
|
|
24
|
+
text "No todos yet. Add one above!"
|
|
25
|
+
else
|
|
26
|
+
header3 "Your Todos (#{state[:todos].length})"
|
|
27
|
+
|
|
28
|
+
state[:todos].each_with_index do |todo, idx|
|
|
29
|
+
div class: "todo-item" do
|
|
30
|
+
text todo
|
|
31
|
+
button "✓", style: :secondary do |state|
|
|
32
|
+
state[:todos].delete_at(idx)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
App.run! if __FILE__ == $0
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
# Manual-verification harness for button loading state (FAC-P1.5).
|
|
5
|
+
# The spinner + dim/disabled treatment is automatic now -- no hand-built markup
|
|
6
|
+
# needed. Button action sleeps 2s so you can see it before the page updates:
|
|
7
|
+
# - the clicked button dims, disables, and spins (button.htmx-request::after)
|
|
8
|
+
# - #app-container dims subtly after a ~150ms delay (no flicker on fast responses)
|
|
9
|
+
# "Opted Out" demonstrates the per-component `loading: false` escape hatch.
|
|
10
|
+
|
|
11
|
+
$LOAD_PATH.unshift(File.expand_path("../lib", __dir__))
|
|
12
|
+
require "stream_weaver"
|
|
13
|
+
|
|
14
|
+
app "Button Loading Test" do
|
|
15
|
+
header "Button Loading State Test"
|
|
16
|
+
md "Click a button — it should dim and spin for ~2 seconds before the page updates."
|
|
17
|
+
|
|
18
|
+
button "Primary (2s delay)" do |s|
|
|
19
|
+
sleep 2
|
|
20
|
+
s[:last] = "primary clicked at #{Time.now.strftime('%H:%M:%S')}"
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
button "Secondary (2s delay)", style: :secondary do |s|
|
|
24
|
+
sleep 2
|
|
25
|
+
s[:last] = "secondary clicked at #{Time.now.strftime('%H:%M:%S')}"
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
button "Opted Out (2s delay, loading: false)", loading: false do |s|
|
|
29
|
+
sleep 2
|
|
30
|
+
s[:last] = "opted-out clicked at #{Time.now.strftime('%H:%M:%S')}"
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
if state[:last]
|
|
34
|
+
md "**Last action:** #{state[:last]}"
|
|
35
|
+
end
|
|
36
|
+
end.run!
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Demo: Mermaid diagrams pushed to a canvas session
|
|
3
|
+
#
|
|
4
|
+
# Shows how to use mermaid in canvas-push mode — useful when an AI agent
|
|
5
|
+
# or script needs to render a diagram without running a full StreamWeaver app.
|
|
6
|
+
#
|
|
7
|
+
# Usage: bash examples/canvas/mermaid_canvas_demo.sh
|
|
8
|
+
|
|
9
|
+
set -e
|
|
10
|
+
|
|
11
|
+
SESSION="mermaid-demo-$$"
|
|
12
|
+
STEPS=3
|
|
13
|
+
|
|
14
|
+
echo "=== StreamWeaver Mermaid Canvas Demo ==="
|
|
15
|
+
echo ""
|
|
16
|
+
echo "Starting canvas session: $SESSION"
|
|
17
|
+
|
|
18
|
+
# streamweaver panel handles browser opening automatically (iTerm2 split pane or
|
|
19
|
+
# external browser fallback) — no need to capture output or parse URLs here.
|
|
20
|
+
streamweaver panel "$SESSION" 2>/dev/null
|
|
21
|
+
|
|
22
|
+
sleep 1
|
|
23
|
+
|
|
24
|
+
# Prime the page with a spinner placeholder while the user reads the terminal output.
|
|
25
|
+
streamweaver canvas-push "$SESSION" <<'RUBY'
|
|
26
|
+
div style: "display:flex;align-items:center;justify-content:center;min-height:60vh;flex-direction:column;gap:1rem" do
|
|
27
|
+
spinner size: :lg
|
|
28
|
+
md "Loading demo — press **Enter** in the terminal to begin step 1…"
|
|
29
|
+
end
|
|
30
|
+
RUBY
|
|
31
|
+
|
|
32
|
+
echo ""
|
|
33
|
+
read -rp "Ready. Press Enter for step 1/$STEPS (architecture diagram)... " _
|
|
34
|
+
|
|
35
|
+
# -----------------------------------------------------------------------
|
|
36
|
+
# Push 1/3: Architecture diagram with zoom
|
|
37
|
+
# -----------------------------------------------------------------------
|
|
38
|
+
echo ""
|
|
39
|
+
echo "[1/$STEPS] Pushing architecture diagram..."
|
|
40
|
+
streamweaver canvas-push "$SESSION" <<'RUBY'
|
|
41
|
+
hstack spacing: :md, align: :center do
|
|
42
|
+
badge "1 / 3", variant: :info
|
|
43
|
+
header1 "System Architecture"
|
|
44
|
+
end
|
|
45
|
+
md "Use `zoom: true` for large diagrams — adds +/−/↺ controls and Ctrl+scroll zoom."
|
|
46
|
+
|
|
47
|
+
mermaid <<~MERMAID, zoom: true
|
|
48
|
+
graph TD
|
|
49
|
+
Browser["Browser"]
|
|
50
|
+
SW["StreamWeaver Server"]
|
|
51
|
+
Canvas["Canvas Bridge"]
|
|
52
|
+
Agent["AI Agent / Script"]
|
|
53
|
+
|
|
54
|
+
Agent -->|"canvas-push DSL"| Canvas
|
|
55
|
+
Canvas -->|"WebSocket"| SW
|
|
56
|
+
SW -->|"SSE update"| Browser
|
|
57
|
+
Browser -->|"canvas-wait result"| Canvas
|
|
58
|
+
Canvas -->|"JSON"| Agent
|
|
59
|
+
|
|
60
|
+
style Agent fill:#dbeafe,stroke:#3b82f6,color:#1e3a5f
|
|
61
|
+
style Canvas fill:#dcfce7,stroke:#22c55e,color:#166534
|
|
62
|
+
style SW fill:#fef3c7,stroke:#f59e0b,color:#92400e
|
|
63
|
+
MERMAID
|
|
64
|
+
RUBY
|
|
65
|
+
|
|
66
|
+
read -rp "Step 1/$STEPS pushed. Press Enter for step 2/$STEPS (compact diagrams in cards)... " _
|
|
67
|
+
|
|
68
|
+
# -----------------------------------------------------------------------
|
|
69
|
+
# Push 2/3: Two compact sequence diagrams side-by-side
|
|
70
|
+
# -----------------------------------------------------------------------
|
|
71
|
+
echo ""
|
|
72
|
+
echo "[2/$STEPS] Pushing compact side-by-side diagrams..."
|
|
73
|
+
streamweaver canvas-push "$SESSION" <<'RUBY'
|
|
74
|
+
hstack spacing: :md, align: :center do
|
|
75
|
+
badge "2 / 3", variant: :warning
|
|
76
|
+
header1 "Compact Diagrams in Cards"
|
|
77
|
+
end
|
|
78
|
+
md "Use `compact: true` when embedding inside a `card` — reduces diagram padding."
|
|
79
|
+
|
|
80
|
+
columns widths: ['50%', '50%'] do
|
|
81
|
+
column do
|
|
82
|
+
card do
|
|
83
|
+
header3 "Happy Path"
|
|
84
|
+
mermaid <<~MERMAID, compact: true
|
|
85
|
+
sequenceDiagram
|
|
86
|
+
Client->>API: Request
|
|
87
|
+
API->>DB: Query
|
|
88
|
+
DB-->>API: Data
|
|
89
|
+
API-->>Client: 200 OK
|
|
90
|
+
MERMAID
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
column do
|
|
94
|
+
card do
|
|
95
|
+
header3 "Error + Retry"
|
|
96
|
+
mermaid <<~MERMAID, compact: true
|
|
97
|
+
sequenceDiagram
|
|
98
|
+
Client->>API: Request
|
|
99
|
+
API->>DB: Query
|
|
100
|
+
DB-->>API: Error
|
|
101
|
+
API-->>Client: 500
|
|
102
|
+
Client->>API: Retry
|
|
103
|
+
API-->>Client: 200 OK
|
|
104
|
+
MERMAID
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
RUBY
|
|
109
|
+
|
|
110
|
+
read -rp "Step 2/$STEPS pushed. Press Enter for step 3/$STEPS (theme vars)... " _
|
|
111
|
+
|
|
112
|
+
# -----------------------------------------------------------------------
|
|
113
|
+
# Push 3/3: Theme vars (use a variable — heredoc + multi-line hash is invalid Ruby)
|
|
114
|
+
# -----------------------------------------------------------------------
|
|
115
|
+
echo ""
|
|
116
|
+
echo "[3/$STEPS] Pushing themed diagram..."
|
|
117
|
+
streamweaver canvas-push "$SESSION" <<'RUBY'
|
|
118
|
+
hstack spacing: :md, align: :center do
|
|
119
|
+
badge "3 / 3", variant: :success
|
|
120
|
+
header1 "Custom Theme Variables"
|
|
121
|
+
end
|
|
122
|
+
md "Pass `theme_vars:` to override Mermaid colors per-diagram. StreamWeaver auto-derives `mainBkg` from `primaryColor`."
|
|
123
|
+
|
|
124
|
+
indigo = { primaryColor: "#6366f1", primaryTextColor: "#ffffff", primaryBorderColor: "#4f46e5", lineColor: "#6366f1", secondaryColor: "#e0e7ff" }
|
|
125
|
+
mermaid <<~MERMAID, theme_vars: indigo
|
|
126
|
+
graph LR
|
|
127
|
+
Idea --> Spike
|
|
128
|
+
Spike --> Build
|
|
129
|
+
Build --> Ship
|
|
130
|
+
Ship --> Learn
|
|
131
|
+
Learn --> Idea
|
|
132
|
+
MERMAID
|
|
133
|
+
RUBY
|
|
134
|
+
|
|
135
|
+
read -rp "Step 3/$STEPS pushed. Press Enter to see the completion summary... " _
|
|
136
|
+
|
|
137
|
+
echo ""
|
|
138
|
+
echo "All $STEPS steps complete."
|
|
139
|
+
|
|
140
|
+
streamweaver canvas-push "$SESSION" <<'RUBY'
|
|
141
|
+
div style: "text-align:center;padding:4rem" do
|
|
142
|
+
badge "Complete", variant: :success
|
|
143
|
+
div(style: "margin-top:1rem") { header1 "All 3 steps complete!" }
|
|
144
|
+
md "Press **Enter** in the terminal to close this session."
|
|
145
|
+
end
|
|
146
|
+
RUBY
|
|
147
|
+
|
|
148
|
+
read -rp "Press Enter to close the session... " _
|
|
149
|
+
|
|
150
|
+
streamweaver canvas-close "$SESSION" 2>/dev/null || true
|
|
151
|
+
echo "Session closed."
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../../lib/stream_weaver'
|
|
4
|
+
|
|
5
|
+
# Simple bar chart demonstration
|
|
6
|
+
app "Bar Chart Demo" do
|
|
7
|
+
header2 "StreamWeaver Charts - Phase 1"
|
|
8
|
+
|
|
9
|
+
# Example 1: Inline hash data (simplest)
|
|
10
|
+
card do
|
|
11
|
+
header3 "Inline Data (Hash)"
|
|
12
|
+
bar_chart data: {
|
|
13
|
+
"Calendar" => 45,
|
|
14
|
+
"News" => 120,
|
|
15
|
+
"Tasks" => 30,
|
|
16
|
+
"Email" => 65
|
|
17
|
+
}, title: "Time by Activity (seconds)"
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
columns widths: ['50%', '50%'] do
|
|
21
|
+
column do
|
|
22
|
+
# Example 2: Horizontal bar chart
|
|
23
|
+
card do
|
|
24
|
+
header3 "Horizontal Bars"
|
|
25
|
+
hbar_chart data: {
|
|
26
|
+
"Phase A" => 25,
|
|
27
|
+
"Phase B" => 45,
|
|
28
|
+
"Phase C" => 15,
|
|
29
|
+
"Phase D" => 35
|
|
30
|
+
}, colors: ["#4a90d9"], height: "200px"
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
column do
|
|
35
|
+
# Example 3: Explicit labels/values
|
|
36
|
+
card do
|
|
37
|
+
header3 "Explicit Labels/Values"
|
|
38
|
+
bar_chart labels: %w[Mon Tue Wed Thu Fri],
|
|
39
|
+
values: [12, 19, 8, 15, 22],
|
|
40
|
+
colors: ["#10b981"],
|
|
41
|
+
height: "200px"
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Example 4: Custom colors
|
|
47
|
+
card do
|
|
48
|
+
header3 "Custom Styling"
|
|
49
|
+
bar_chart data: { "A" => 100, "B" => 80, "C" => 60, "D" => 40, "E" => 20 },
|
|
50
|
+
colors: ["#c45b28"],
|
|
51
|
+
title: "Performance Scores",
|
|
52
|
+
show_values: true,
|
|
53
|
+
height: "180px"
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
text "Charts rendered with Chart.js - loaded via CDN only when charts are present."
|
|
57
|
+
end.run!
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../../lib/stream_weaver'
|
|
4
|
+
|
|
5
|
+
# Line chart and sparkline demonstration
|
|
6
|
+
app "Line Chart Demo" do
|
|
7
|
+
header2 "StreamWeaver Charts - Phase 2"
|
|
8
|
+
|
|
9
|
+
# Example 1: Simple line chart from array
|
|
10
|
+
card do
|
|
11
|
+
header3 "Trend Data (Array)"
|
|
12
|
+
line_chart data: [12, 19, 8, 15, 22, 18, 25],
|
|
13
|
+
title: "Weekly Progress"
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
columns widths: ['50%', '50%'] do
|
|
17
|
+
column do
|
|
18
|
+
# Example 2: Line chart with options
|
|
19
|
+
card do
|
|
20
|
+
header3 "With Fill"
|
|
21
|
+
line_chart data: { Mon: 5, Tue: 12, Wed: 8, Thu: 15, Fri: 10 },
|
|
22
|
+
fill: true,
|
|
23
|
+
colors: ["#4a90d9"],
|
|
24
|
+
height: "180px"
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
column do
|
|
29
|
+
# Example 3: No smoothing
|
|
30
|
+
card do
|
|
31
|
+
header3 "Straight Lines"
|
|
32
|
+
line_chart data: [10, 25, 15, 30, 20],
|
|
33
|
+
smooth: false,
|
|
34
|
+
colors: ["#10b981"],
|
|
35
|
+
height: "180px"
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Example 4: Sparklines (minimal, inline charts)
|
|
41
|
+
card do
|
|
42
|
+
header3 "Sparklines"
|
|
43
|
+
text "Compact trend indicators without axes or labels:"
|
|
44
|
+
|
|
45
|
+
columns widths: ['33%', '33%', '33%'] do
|
|
46
|
+
column do
|
|
47
|
+
text "Revenue"
|
|
48
|
+
sparkline data: [45, 52, 48, 61, 55, 67, 72]
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
column do
|
|
52
|
+
text "Users"
|
|
53
|
+
sparkline data: [120, 135, 142, 138, 155, 162, 170], colors: ["#4a90d9"]
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
column do
|
|
57
|
+
text "Errors"
|
|
58
|
+
sparkline data: [8, 12, 6, 15, 4, 3, 2], colors: ["#dc2626"]
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Example 5: No points
|
|
64
|
+
card do
|
|
65
|
+
header3 "Clean Line (No Points)"
|
|
66
|
+
line_chart data: { Jan: 100, Feb: 120, Mar: 115, Apr: 135, May: 150, Jun: 145 },
|
|
67
|
+
points: false,
|
|
68
|
+
colors: ["#c45b28"],
|
|
69
|
+
height: "160px"
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
text "Charts rendered with Chart.js - line_chart for full charts, sparkline for compact trends."
|
|
73
|
+
end.run!
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../../lib/stream_weaver'
|
|
4
|
+
|
|
5
|
+
# Pie chart, doughnut chart, and area chart demonstration
|
|
6
|
+
app "Pie & Area Charts Demo" do
|
|
7
|
+
header2 "StreamWeaver Charts - Pie, Doughnut & Area"
|
|
8
|
+
|
|
9
|
+
columns widths: ['50%', '50%'] do
|
|
10
|
+
column do
|
|
11
|
+
# Example 1: Pie chart
|
|
12
|
+
card do
|
|
13
|
+
header3 "Pie Chart"
|
|
14
|
+
pie_chart data: {
|
|
15
|
+
"Calendar" => 45,
|
|
16
|
+
"News" => 120,
|
|
17
|
+
"Tasks" => 30,
|
|
18
|
+
"Email" => 65
|
|
19
|
+
}, title: "Time Distribution"
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
column do
|
|
24
|
+
# Example 2: Doughnut chart
|
|
25
|
+
card do
|
|
26
|
+
header3 "Doughnut Chart"
|
|
27
|
+
doughnut_chart data: {
|
|
28
|
+
"Frontend" => 40,
|
|
29
|
+
"Backend" => 35,
|
|
30
|
+
"DevOps" => 25
|
|
31
|
+
}, title: "Team Allocation"
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Example 3: Area chart (line with fill)
|
|
37
|
+
card do
|
|
38
|
+
header3 "Area Chart"
|
|
39
|
+
area_chart data: { Mon: 45, Tue: 52, Wed: 48, Thu: 61, Fri: 55, Sat: 67, Sun: 72 },
|
|
40
|
+
title: "Weekly Trend",
|
|
41
|
+
colors: ["#4a90d9"]
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
columns widths: ['50%', '50%'] do
|
|
45
|
+
column do
|
|
46
|
+
# Example 4: Custom cutout for doughnut
|
|
47
|
+
card do
|
|
48
|
+
header3 "Thin Doughnut (75% cutout)"
|
|
49
|
+
doughnut_chart data: { A: 30, B: 50, C: 20 },
|
|
50
|
+
cutout: '75%',
|
|
51
|
+
height: "180px"
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
column do
|
|
56
|
+
# Example 5: Legend position
|
|
57
|
+
card do
|
|
58
|
+
header3 "Legend Bottom"
|
|
59
|
+
pie_chart data: { Sales: 100, Marketing: 60, Engineering: 80 },
|
|
60
|
+
legend_position: 'bottom',
|
|
61
|
+
height: "180px"
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Example 6: Comparing area charts
|
|
67
|
+
card do
|
|
68
|
+
header3 "Smooth vs Straight Area"
|
|
69
|
+
columns widths: ['50%', '50%'] do
|
|
70
|
+
column do
|
|
71
|
+
text "Smooth (default)"
|
|
72
|
+
area_chart data: [10, 25, 15, 30, 20, 35],
|
|
73
|
+
colors: ["#10b981"],
|
|
74
|
+
height: "120px"
|
|
75
|
+
end
|
|
76
|
+
column do
|
|
77
|
+
text "Straight lines"
|
|
78
|
+
area_chart data: [10, 25, 15, 30, 20, 35],
|
|
79
|
+
smooth: false,
|
|
80
|
+
colors: ["#f59e0b"],
|
|
81
|
+
height: "120px"
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
text "Pie/doughnut show proportions. Area charts show cumulative trends."
|
|
87
|
+
end.run!
|