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,1003 @@
|
|
|
1
|
+
# Unified Gherkin Specification: StreamWeaver Visual Skills
|
|
2
|
+
#
|
|
3
|
+
# This specification covers ALL functionality from both pi-design-deck and
|
|
4
|
+
# visual-explainer, adapted for StreamWeaver's Ruby DSL architecture.
|
|
5
|
+
#
|
|
6
|
+
# Organization:
|
|
7
|
+
# Part 1: Shared Component Features (used by both projects)
|
|
8
|
+
# Part 2: Design Deck Features (deck-specific)
|
|
9
|
+
# Part 3: Visual Explainer Features (explainer-specific)
|
|
10
|
+
|
|
11
|
+
# =============================================================================
|
|
12
|
+
# PART 1: SHARED COMPONENT FEATURES
|
|
13
|
+
# =============================================================================
|
|
14
|
+
|
|
15
|
+
Feature: Mermaid Diagram Rendering
|
|
16
|
+
As a StreamWeaver app developer
|
|
17
|
+
I want to render Mermaid diagrams in my pages
|
|
18
|
+
So that I can visualize system architecture, flows, and relationships
|
|
19
|
+
|
|
20
|
+
Background:
|
|
21
|
+
Given a StreamWeaver app is running
|
|
22
|
+
|
|
23
|
+
Scenario: Render a basic Mermaid diagram
|
|
24
|
+
Given the app includes a mermaid component with code "graph TD\n A-->B\n B-->C"
|
|
25
|
+
When the page renders
|
|
26
|
+
Then Mermaid.js is loaded from CDN (mermaid@11 ESM)
|
|
27
|
+
And the diagram renders as an inline SVG
|
|
28
|
+
And the SVG uses theme: 'base' with custom themeVariables
|
|
29
|
+
|
|
30
|
+
Scenario: Mermaid diagram respects dark/light theme
|
|
31
|
+
Given the app includes a mermaid component
|
|
32
|
+
When the page loads in dark mode
|
|
33
|
+
Then the Mermaid themeVariables use dark palette colors
|
|
34
|
+
When the page loads in light mode
|
|
35
|
+
Then the Mermaid themeVariables use light palette colors
|
|
36
|
+
And the theme is determined once at load time via matchMedia
|
|
37
|
+
|
|
38
|
+
Scenario: Mermaid diagram with zoom controls
|
|
39
|
+
Given the app includes a mermaid component with zoom: true
|
|
40
|
+
When the page renders
|
|
41
|
+
Then the diagram is wrapped in a zoom-enabled container
|
|
42
|
+
And zoom controls appear: +, -, reset, 1:1, expand
|
|
43
|
+
And Ctrl/Cmd+scroll zooms the diagram
|
|
44
|
+
And click-and-drag pans the diagram
|
|
45
|
+
And clicking without dragging opens full-size in a new tab
|
|
46
|
+
And double-click fits the diagram to the container
|
|
47
|
+
|
|
48
|
+
Scenario: Mermaid diagram in compact mode
|
|
49
|
+
Given the app includes a mermaid component with compact: true
|
|
50
|
+
When the page renders
|
|
51
|
+
Then the diagram renders without zoom controls
|
|
52
|
+
And the container height adapts to the SVG dimensions
|
|
53
|
+
And the diagram is suitable for embedding within a card
|
|
54
|
+
|
|
55
|
+
Scenario: Mermaid diagram with per-block theme overrides
|
|
56
|
+
Given the app includes a mermaid component with theme variables { primaryColor: "#ff0000" }
|
|
57
|
+
When the page renders
|
|
58
|
+
Then the diagram uses the overridden primaryColor
|
|
59
|
+
And other theme variables fall back to defaults
|
|
60
|
+
|
|
61
|
+
Scenario: Mermaid diagram with ELK layout
|
|
62
|
+
Given the app includes a mermaid component with layout: :elk
|
|
63
|
+
When the page renders
|
|
64
|
+
Then the @mermaid-js/layout-elk CDN module is loaded
|
|
65
|
+
And the diagram uses ELK layout algorithm
|
|
66
|
+
|
|
67
|
+
# -----------------------------------------------------------------------------
|
|
68
|
+
|
|
69
|
+
Feature: Code Syntax Highlighting
|
|
70
|
+
As a StreamWeaver app developer
|
|
71
|
+
I want to display syntax-highlighted code blocks
|
|
72
|
+
So that code is readable and visually appealing
|
|
73
|
+
|
|
74
|
+
Background:
|
|
75
|
+
Given a StreamWeaver app is running
|
|
76
|
+
|
|
77
|
+
Scenario: Render a code block with language
|
|
78
|
+
Given the app includes a code_block component with code "const x = 1;" and lang: "javascript"
|
|
79
|
+
When the page renders
|
|
80
|
+
Then Prism.js is loaded from CDN with autoloader
|
|
81
|
+
And the code is syntax-highlighted for JavaScript
|
|
82
|
+
And the block has a monospace font from the theme
|
|
83
|
+
|
|
84
|
+
Scenario: Render a code block with file header
|
|
85
|
+
Given the app includes a code_block component with file: "src/server.ts"
|
|
86
|
+
When the page renders
|
|
87
|
+
Then a file header appears above the code showing "src/server.ts"
|
|
88
|
+
And the header has a distinct background from the code body
|
|
89
|
+
|
|
90
|
+
Scenario: Code block with scroll container
|
|
91
|
+
Given the app includes a code_block with 50 lines of code
|
|
92
|
+
When the page renders
|
|
93
|
+
Then the code block has a scrollable container
|
|
94
|
+
And the maximum height is constrained
|
|
95
|
+
|
|
96
|
+
Scenario: Code block truncation for thumbnails
|
|
97
|
+
Given the app includes a code_block with truncate: 3
|
|
98
|
+
When the page renders
|
|
99
|
+
Then only the first 3 lines of code are shown
|
|
100
|
+
And no scrollbar appears
|
|
101
|
+
|
|
102
|
+
Scenario: Code block within a card
|
|
103
|
+
Given the app includes a code_block inside a card component
|
|
104
|
+
When the page renders
|
|
105
|
+
Then the code block uses recessed depth styling
|
|
106
|
+
And padding and margins integrate with the card layout
|
|
107
|
+
|
|
108
|
+
# -----------------------------------------------------------------------------
|
|
109
|
+
|
|
110
|
+
Feature: Theme Management
|
|
111
|
+
As a StreamWeaver app user
|
|
112
|
+
I want the page to respect my color scheme preference
|
|
113
|
+
So that the visual output matches my environment
|
|
114
|
+
|
|
115
|
+
Background:
|
|
116
|
+
Given a StreamWeaver app is running
|
|
117
|
+
|
|
118
|
+
Scenario: Auto theme follows OS preference
|
|
119
|
+
Given the app uses theme mode: :auto
|
|
120
|
+
When the OS is in light mode
|
|
121
|
+
Then the page renders with light palette CSS custom properties
|
|
122
|
+
When the OS switches to dark mode
|
|
123
|
+
Then the page renders with dark palette via prefers-color-scheme
|
|
124
|
+
And no page reload is required for CSS-only elements
|
|
125
|
+
|
|
126
|
+
Scenario: Dark theme is default
|
|
127
|
+
Given the app uses theme mode: :dark
|
|
128
|
+
When the page loads
|
|
129
|
+
Then the page renders with dark theme variables
|
|
130
|
+
And the meta theme-color is set to the dark background color
|
|
131
|
+
|
|
132
|
+
Scenario: Manual theme toggle via keyboard
|
|
133
|
+
Given the app has a theme toggle shortcut configured as "mod+shift+l"
|
|
134
|
+
When the user presses Cmd+Shift+L on Mac (or Ctrl+Shift+L elsewhere)
|
|
135
|
+
Then the theme switches between light and dark
|
|
136
|
+
And the override is saved to localStorage
|
|
137
|
+
And meta theme-color is updated
|
|
138
|
+
|
|
139
|
+
Scenario: Manual theme toggle via button
|
|
140
|
+
Given the app includes a theme_toggle component
|
|
141
|
+
When the page renders
|
|
142
|
+
Then a toggle button appears with sun/moon icons
|
|
143
|
+
When the user clicks the toggle
|
|
144
|
+
Then the theme switches
|
|
145
|
+
|
|
146
|
+
Scenario: Theme override persists across sessions
|
|
147
|
+
Given the user previously toggled to light theme
|
|
148
|
+
When the page reloads
|
|
149
|
+
Then the light theme is applied from localStorage
|
|
150
|
+
And the auto/default mode is overridden
|
|
151
|
+
|
|
152
|
+
Scenario: CSS custom properties define theme tokens
|
|
153
|
+
Given the app is using the theme system
|
|
154
|
+
Then the following CSS custom properties are defined:
|
|
155
|
+
| Property | Purpose |
|
|
156
|
+
| --bg | Page background |
|
|
157
|
+
| --surface | Card/container background |
|
|
158
|
+
| --border | Low-opacity border |
|
|
159
|
+
| --text | Primary text color |
|
|
160
|
+
| --text-dim | Secondary text color |
|
|
161
|
+
| --accent | Primary accent color |
|
|
162
|
+
| --accent-dim| Accent at low alpha |
|
|
163
|
+
|
|
164
|
+
# -----------------------------------------------------------------------------
|
|
165
|
+
|
|
166
|
+
Feature: Keyboard Shortcuts
|
|
167
|
+
As a StreamWeaver app user
|
|
168
|
+
I want keyboard shortcuts for common actions
|
|
169
|
+
So that I can interact efficiently without a mouse
|
|
170
|
+
|
|
171
|
+
Background:
|
|
172
|
+
Given a StreamWeaver app is running
|
|
173
|
+
And the keyboard shortcut system is initialized
|
|
174
|
+
|
|
175
|
+
Scenario: Register a keyboard shortcut
|
|
176
|
+
Given the app registers a shortcut for "mod+s" with action :save
|
|
177
|
+
When the user presses Cmd+S on Mac
|
|
178
|
+
Then the :save action fires
|
|
179
|
+
And the default browser save dialog is prevented
|
|
180
|
+
|
|
181
|
+
Scenario: Context-aware shortcut suppression
|
|
182
|
+
Given the app registers arrow keys for slide navigation
|
|
183
|
+
And focus is inside a scrollable mermaid diagram container
|
|
184
|
+
When the user presses ArrowRight
|
|
185
|
+
Then the slide does NOT advance
|
|
186
|
+
And the mermaid container handles the event instead
|
|
187
|
+
|
|
188
|
+
Scenario: Context-aware shortcut suppression for text inputs
|
|
189
|
+
Given the app registers number keys 1-9 for quick selection
|
|
190
|
+
And focus is inside a textarea or text input
|
|
191
|
+
When the user presses "3"
|
|
192
|
+
Then the character "3" is typed into the input
|
|
193
|
+
And no selection action occurs
|
|
194
|
+
|
|
195
|
+
Scenario: Reduced motion respects system preference
|
|
196
|
+
Given the OS has prefers-reduced-motion: reduce enabled
|
|
197
|
+
When any keyboard-triggered transition occurs
|
|
198
|
+
Then the transition completes instantly without animation
|
|
199
|
+
|
|
200
|
+
# -----------------------------------------------------------------------------
|
|
201
|
+
|
|
202
|
+
Feature: HTML Export
|
|
203
|
+
As a StreamWeaver app developer
|
|
204
|
+
I want to export my page as a self-contained HTML file
|
|
205
|
+
So that it can be viewed offline or shared without a server
|
|
206
|
+
|
|
207
|
+
Background:
|
|
208
|
+
Given a StreamWeaver app is running
|
|
209
|
+
|
|
210
|
+
Scenario: Export current page as HTML
|
|
211
|
+
Given the app has rendered a page with mermaid diagrams and styled cards
|
|
212
|
+
When the export action is triggered
|
|
213
|
+
Then a single HTML file is generated
|
|
214
|
+
And all CSS is inlined in a <style> tag
|
|
215
|
+
And CDN links for Mermaid.js and fonts are preserved
|
|
216
|
+
And the file works when opened directly from the filesystem
|
|
217
|
+
|
|
218
|
+
Scenario: Export with inlined images
|
|
219
|
+
Given the page contains images served from the StreamWeaver server
|
|
220
|
+
When the export action is triggered with inline_images: true
|
|
221
|
+
Then images are base64-encoded as data URIs in the HTML
|
|
222
|
+
And no external image references remain
|
|
223
|
+
|
|
224
|
+
Scenario: Export preserves both themes
|
|
225
|
+
Given the page has light and dark theme support
|
|
226
|
+
When the exported HTML is opened
|
|
227
|
+
Then it responds to prefers-color-scheme media queries
|
|
228
|
+
And both themes render correctly
|
|
229
|
+
|
|
230
|
+
Scenario: Export writes to specified path
|
|
231
|
+
Given the export action specifies output: "~/.agent/diagrams/my-review.html"
|
|
232
|
+
When the export completes
|
|
233
|
+
Then the file exists at the specified path
|
|
234
|
+
And the file is a valid HTML5 document
|
|
235
|
+
|
|
236
|
+
# -----------------------------------------------------------------------------
|
|
237
|
+
|
|
238
|
+
Feature: Slide Navigation
|
|
239
|
+
As a StreamWeaver app user
|
|
240
|
+
I want to navigate between slides
|
|
241
|
+
So that I can view content sequentially
|
|
242
|
+
|
|
243
|
+
Background:
|
|
244
|
+
Given a StreamWeaver app is running with a slide-based layout
|
|
245
|
+
|
|
246
|
+
Scenario: Navigate with arrow keys
|
|
247
|
+
Given the app is showing slide 1 of 5
|
|
248
|
+
When the user presses ArrowRight
|
|
249
|
+
Then slide 2 becomes visible
|
|
250
|
+
And a transition animation plays (unless reduced motion is on)
|
|
251
|
+
|
|
252
|
+
Scenario: Navigate with buttons
|
|
253
|
+
Given the app has Back and Next navigation buttons
|
|
254
|
+
And the app is showing slide 2 of 5
|
|
255
|
+
When the user clicks "Next"
|
|
256
|
+
Then slide 3 becomes visible
|
|
257
|
+
When the user clicks "Back"
|
|
258
|
+
Then slide 2 becomes visible again
|
|
259
|
+
|
|
260
|
+
Scenario: Progress bar updates on navigation
|
|
261
|
+
Given the app has a progress bar
|
|
262
|
+
And the app is showing slide 2 of 5
|
|
263
|
+
Then the progress bar shows 40% completion
|
|
264
|
+
When the user navigates to slide 4
|
|
265
|
+
Then the progress bar shows 80% completion
|
|
266
|
+
|
|
267
|
+
Scenario: Back button disabled on first slide
|
|
268
|
+
Given the app is showing slide 1
|
|
269
|
+
Then the Back button is disabled
|
|
270
|
+
And the Next button is enabled
|
|
271
|
+
|
|
272
|
+
Scenario: Keyboard navigation respects interactive element focus
|
|
273
|
+
Given an interactive element (mermaid diagram, table, code block) has focus
|
|
274
|
+
When the user presses an arrow key
|
|
275
|
+
Then the slide does NOT change
|
|
276
|
+
And the interactive element handles the key event
|
|
277
|
+
|
|
278
|
+
# -----------------------------------------------------------------------------
|
|
279
|
+
|
|
280
|
+
Feature: Responsive Layout
|
|
281
|
+
As a StreamWeaver app user on various devices
|
|
282
|
+
I want pages to adapt to my screen size
|
|
283
|
+
So that content is readable on any device
|
|
284
|
+
|
|
285
|
+
Background:
|
|
286
|
+
Given a StreamWeaver app is running
|
|
287
|
+
|
|
288
|
+
Scenario: Grid collapses on narrow screens
|
|
289
|
+
Given the app uses a grid component with columns: 3
|
|
290
|
+
When the viewport width is below 900px
|
|
291
|
+
Then the grid collapses to a single column
|
|
292
|
+
And content remains readable
|
|
293
|
+
|
|
294
|
+
Scenario: Auto-detect grid columns from content count
|
|
295
|
+
Given the app uses a grid component with auto_columns: true
|
|
296
|
+
And the grid contains 4 child elements
|
|
297
|
+
When the page renders at desktop width
|
|
298
|
+
Then the grid displays in 2 columns
|
|
299
|
+
When the grid contains 3 child elements
|
|
300
|
+
Then the grid displays in 3 columns
|
|
301
|
+
|
|
302
|
+
Scenario: Page respects max-width constraint
|
|
303
|
+
Given the app sets max_width: 1200
|
|
304
|
+
When the viewport is 1920px wide
|
|
305
|
+
Then the content area is centered at 1200px
|
|
306
|
+
And side margins are equal
|
|
307
|
+
|
|
308
|
+
# =============================================================================
|
|
309
|
+
# PART 2: DESIGN DECK FEATURES
|
|
310
|
+
# =============================================================================
|
|
311
|
+
|
|
312
|
+
Feature: Design Deck Creation
|
|
313
|
+
As an AI agent
|
|
314
|
+
I want to create interactive design decks via StreamWeaver DSL
|
|
315
|
+
So that users can view and select from visual design options
|
|
316
|
+
|
|
317
|
+
Background:
|
|
318
|
+
Given a StreamWeaver app is configured for design deck mode
|
|
319
|
+
|
|
320
|
+
Scenario: Create a deck with slides and options
|
|
321
|
+
Given the agent defines a deck with the DSL:
|
|
322
|
+
"""ruby
|
|
323
|
+
design_deck "Architecture Direction" do
|
|
324
|
+
slide "arch", "System Architecture", context: "Choose the backend architecture" do
|
|
325
|
+
option "Monolith", aside: "Simpler to deploy" do
|
|
326
|
+
mermaid "graph TD\n Client-->API\n API-->DB"
|
|
327
|
+
code_block "app.listen(3000)", lang: "ts"
|
|
328
|
+
end
|
|
329
|
+
option "Microservices", recommended: true do
|
|
330
|
+
mermaid "graph LR\n Gateway-->Auth\n Gateway-->Orders"
|
|
331
|
+
end
|
|
332
|
+
end
|
|
333
|
+
end
|
|
334
|
+
"""
|
|
335
|
+
When the StreamWeaver app starts
|
|
336
|
+
Then a local server starts on an available port
|
|
337
|
+
And the browser opens to the deck URL
|
|
338
|
+
And the first slide displays with options in a grid
|
|
339
|
+
And a progress bar shows 1/2 (plus summary)
|
|
340
|
+
|
|
341
|
+
Scenario: Deck with preview blocks renders correctly
|
|
342
|
+
Given a slide has options with mermaid, code, and image blocks
|
|
343
|
+
When the deck renders
|
|
344
|
+
Then mermaid blocks render as inline SVG diagrams (compact mode)
|
|
345
|
+
And code blocks render with Prism.js syntax highlighting
|
|
346
|
+
And image blocks display from the asset serving endpoint
|
|
347
|
+
And blocks stack vertically within each option card
|
|
348
|
+
|
|
349
|
+
Scenario: Deck with per-slide column override
|
|
350
|
+
Given a slide specifies columns: 1
|
|
351
|
+
When the deck renders that slide
|
|
352
|
+
Then options display in a single-column layout
|
|
353
|
+
And other slides use auto-detected column counts
|
|
354
|
+
|
|
355
|
+
Scenario: Deck with context text
|
|
356
|
+
Given a slide has a context property
|
|
357
|
+
When the deck renders that slide
|
|
358
|
+
Then the context text appears below the slide title
|
|
359
|
+
And it is styled as secondary text with constrained width
|
|
360
|
+
|
|
361
|
+
Scenario: Deck rejects invalid configuration
|
|
362
|
+
Given a deck config has a slide with id "summary"
|
|
363
|
+
When the deck tries to render
|
|
364
|
+
Then it raises an error: "summary is a reserved slide id"
|
|
365
|
+
|
|
366
|
+
Scenario: Only one deck active at a time
|
|
367
|
+
Given a design deck is already active
|
|
368
|
+
When the agent tries to create another deck
|
|
369
|
+
Then it receives an error: "A design deck is already active"
|
|
370
|
+
|
|
371
|
+
# -----------------------------------------------------------------------------
|
|
372
|
+
|
|
373
|
+
Feature: Deck Slide Navigation
|
|
374
|
+
As a user viewing a design deck
|
|
375
|
+
I want to navigate between decision slides
|
|
376
|
+
So that I can review all design dimensions
|
|
377
|
+
|
|
378
|
+
Scenario: Navigate forward with button
|
|
379
|
+
Given the deck is showing slide 1 of 3
|
|
380
|
+
When I click the "Next" button
|
|
381
|
+
Then slide 2 becomes active with a fade transition
|
|
382
|
+
And the progress bar updates to 2/4
|
|
383
|
+
And the heading of slide 2 receives focus
|
|
384
|
+
|
|
385
|
+
Scenario: Navigate backward
|
|
386
|
+
Given the deck is showing slide 2 of 3
|
|
387
|
+
When I click the "Back" button
|
|
388
|
+
Then slide 1 becomes active
|
|
389
|
+
And the Back button becomes disabled
|
|
390
|
+
|
|
391
|
+
Scenario: Navigate to auto-generated summary
|
|
392
|
+
Given the deck is showing the last regular slide
|
|
393
|
+
When I click "Next"
|
|
394
|
+
Then the summary slide appears
|
|
395
|
+
And the Next button shows "Done" and is disabled
|
|
396
|
+
|
|
397
|
+
Scenario: Arrow keys navigate slides
|
|
398
|
+
Given the deck is showing slide 1
|
|
399
|
+
And no option card is focused
|
|
400
|
+
When I press the Right arrow key
|
|
401
|
+
Then slide 2 becomes active
|
|
402
|
+
|
|
403
|
+
Scenario: Arrow keys navigate options when focused
|
|
404
|
+
Given an option card has focus
|
|
405
|
+
When I press the Down arrow key
|
|
406
|
+
Then focus moves to the next option card
|
|
407
|
+
And the slide does not change
|
|
408
|
+
|
|
409
|
+
# -----------------------------------------------------------------------------
|
|
410
|
+
|
|
411
|
+
Feature: Option Selection
|
|
412
|
+
As a user viewing a design deck
|
|
413
|
+
I want to select one option per slide
|
|
414
|
+
So that my design choices are communicated to the agent
|
|
415
|
+
|
|
416
|
+
Scenario: Select option by clicking
|
|
417
|
+
Given slide 1 has 3 options
|
|
418
|
+
When I click option "Microservices"
|
|
419
|
+
Then option "Microservices" shows as selected
|
|
420
|
+
And a checkmark badge appears with a pop animation
|
|
421
|
+
And the radio indicator fills with accent color
|
|
422
|
+
And the selection is saved to state
|
|
423
|
+
|
|
424
|
+
Scenario: Select option by number key
|
|
425
|
+
Given slide 1 has 3 options
|
|
426
|
+
When I press the "2" key
|
|
427
|
+
Then the second option becomes selected
|
|
428
|
+
|
|
429
|
+
Scenario: Select option by Space key
|
|
430
|
+
Given an option card has focus
|
|
431
|
+
When I press Space
|
|
432
|
+
Then that option becomes selected
|
|
433
|
+
|
|
434
|
+
Scenario: Change selection deselects previous
|
|
435
|
+
Given option "Monolith" is selected on slide 1
|
|
436
|
+
When I click option "Microservices"
|
|
437
|
+
Then "Microservices" becomes selected
|
|
438
|
+
And "Monolith" is deselected
|
|
439
|
+
And dirty state is marked
|
|
440
|
+
|
|
441
|
+
Scenario: Selection persists across page reload
|
|
442
|
+
Given I have selected options on slides 1 and 2
|
|
443
|
+
When I reload the page
|
|
444
|
+
Then my previous selections are restored from persisted state
|
|
445
|
+
|
|
446
|
+
Scenario: Add notes to an option
|
|
447
|
+
Given option "Microservices" is selected
|
|
448
|
+
When I type "Use event sourcing" in the notes textarea
|
|
449
|
+
Then the notes are saved to state
|
|
450
|
+
And notes appear in the summary slide
|
|
451
|
+
|
|
452
|
+
Scenario: Recommended badge displays on unselected option
|
|
453
|
+
Given an option has recommended: true
|
|
454
|
+
And it is not currently selected
|
|
455
|
+
Then a "Recommended" badge appears in the header
|
|
456
|
+
|
|
457
|
+
Scenario: Aside text displays below preview
|
|
458
|
+
Given an option has aside text with newlines
|
|
459
|
+
Then the aside text renders below the preview
|
|
460
|
+
And newline characters render as line breaks
|
|
461
|
+
|
|
462
|
+
# -----------------------------------------------------------------------------
|
|
463
|
+
|
|
464
|
+
Feature: Generate More Options
|
|
465
|
+
As a user who wants additional design options
|
|
466
|
+
I want to request AI-generated alternatives
|
|
467
|
+
So that I have more choices to consider
|
|
468
|
+
|
|
469
|
+
Background:
|
|
470
|
+
Given a design deck is active in StreamWeaver
|
|
471
|
+
|
|
472
|
+
Scenario: Generate one additional option
|
|
473
|
+
Given the deck is showing a slide with 2 options
|
|
474
|
+
When I click "Generate" with count set to 1
|
|
475
|
+
Then a skeleton placeholder with shimmer animation appears in the grid
|
|
476
|
+
And the button shows "Generating..." with a spinner
|
|
477
|
+
And the agent receives a generate-more callback with the slide id and count
|
|
478
|
+
When the agent pushes a new option via the StreamWeaver API
|
|
479
|
+
Then the skeleton is replaced with the new option card
|
|
480
|
+
And the card has an entry animation
|
|
481
|
+
And a "Generated" badge appears on the option
|
|
482
|
+
And the grid rebalances for the new option count
|
|
483
|
+
|
|
484
|
+
Scenario: Generate multiple options at once
|
|
485
|
+
When I select count "3" and click "Generate"
|
|
486
|
+
Then 3 skeleton placeholders appear
|
|
487
|
+
When the agent pushes 3 options
|
|
488
|
+
Then skeletons are replaced one by one as options arrive via SSE
|
|
489
|
+
|
|
490
|
+
Scenario: Generate with custom prompt
|
|
491
|
+
Given I type "make it more minimal" in the prompt input
|
|
492
|
+
When I click "Generate"
|
|
493
|
+
Then the prompt text is included in the agent callback
|
|
494
|
+
And the prompt input is cleared
|
|
495
|
+
|
|
496
|
+
Scenario: Generation timeout
|
|
497
|
+
Given I clicked "Generate"
|
|
498
|
+
And 30 seconds pass without receiving an option
|
|
499
|
+
Then a toast notification shows "Generation timed out"
|
|
500
|
+
And the generate button is restored to its default state
|
|
501
|
+
|
|
502
|
+
Scenario: Regenerate all options on a slide
|
|
503
|
+
Given the slide has 3 options
|
|
504
|
+
When I click "Regenerate all"
|
|
505
|
+
Then a skeleton overlay covers the existing options grid
|
|
506
|
+
And the agent receives a regenerate callback
|
|
507
|
+
When the agent pushes 3 replacement options
|
|
508
|
+
Then the overlay is removed
|
|
509
|
+
And new options appear with staggered entry animations
|
|
510
|
+
And the previous selection for this slide is cleared
|
|
511
|
+
|
|
512
|
+
Scenario: Concurrent generation prevented
|
|
513
|
+
Given a generation is already in progress
|
|
514
|
+
Then the Generate and Regenerate buttons are disabled
|
|
515
|
+
|
|
516
|
+
# -----------------------------------------------------------------------------
|
|
517
|
+
|
|
518
|
+
Feature: Save and Load Decks
|
|
519
|
+
As a user who wants to preserve design decisions
|
|
520
|
+
I want to save, load, and export deck snapshots
|
|
521
|
+
So that I can resume work or share decisions
|
|
522
|
+
|
|
523
|
+
Background:
|
|
524
|
+
Given a design deck is active in StreamWeaver
|
|
525
|
+
|
|
526
|
+
Scenario: Manual save with keyboard shortcut
|
|
527
|
+
Given I have selections on 2 slides
|
|
528
|
+
When I press Cmd+S
|
|
529
|
+
Then the deck state is saved to a snapshot file
|
|
530
|
+
And a toast notification shows the save path
|
|
531
|
+
And the save status shows "Saved at HH:MM"
|
|
532
|
+
|
|
533
|
+
Scenario: Auto-save on submit
|
|
534
|
+
Given auto-save is enabled (default)
|
|
535
|
+
When I submit the deck
|
|
536
|
+
Then a snapshot is saved with "-submitted" suffix
|
|
537
|
+
And image assets are copied to the snapshot directory
|
|
538
|
+
|
|
539
|
+
Scenario: Auto-save on cancel with selections
|
|
540
|
+
Given I have selected options on at least one slide
|
|
541
|
+
When I cancel the deck
|
|
542
|
+
Then a snapshot is saved with "-cancelled" suffix
|
|
543
|
+
|
|
544
|
+
Scenario: List saved decks
|
|
545
|
+
Given there are 3 saved deck snapshots
|
|
546
|
+
When the agent queries for saved decks
|
|
547
|
+
Then it receives an array of deck metadata
|
|
548
|
+
And each entry includes id, title, savedAt, status, slideCount
|
|
549
|
+
|
|
550
|
+
Scenario: Open a saved deck
|
|
551
|
+
Given a deck snapshot exists with id "api-design-main-submitted"
|
|
552
|
+
When the agent opens that deck
|
|
553
|
+
Then the deck loads with selections pre-populated
|
|
554
|
+
And notes are restored
|
|
555
|
+
And the user can modify and re-submit
|
|
556
|
+
|
|
557
|
+
Scenario: Export deck as standalone HTML
|
|
558
|
+
Given a submitted deck exists
|
|
559
|
+
When the agent exports it as HTML
|
|
560
|
+
Then a self-contained HTML file is generated
|
|
561
|
+
And it contains embedded CSS and inlined images
|
|
562
|
+
And all slides are visible simultaneously (no navigation)
|
|
563
|
+
And selected options are highlighted with a badge
|
|
564
|
+
|
|
565
|
+
Scenario: Dirty state tracking
|
|
566
|
+
Given I make a selection
|
|
567
|
+
Then the save status shows "Unsaved changes"
|
|
568
|
+
When I save
|
|
569
|
+
Then the status shows "Saved at HH:MM"
|
|
570
|
+
|
|
571
|
+
# -----------------------------------------------------------------------------
|
|
572
|
+
|
|
573
|
+
Feature: Deck Keyboard Navigation
|
|
574
|
+
As a user who prefers keyboard interaction
|
|
575
|
+
I want full keyboard support for the deck
|
|
576
|
+
So that I can navigate, select, and submit efficiently
|
|
577
|
+
|
|
578
|
+
Scenario: Quick select by number
|
|
579
|
+
Given slide 1 has 4 options
|
|
580
|
+
When I press "3"
|
|
581
|
+
Then the third option is selected
|
|
582
|
+
|
|
583
|
+
Scenario: Enter advances to next slide
|
|
584
|
+
Given I am on slide 1
|
|
585
|
+
And no interactive element has focus
|
|
586
|
+
When I press Enter
|
|
587
|
+
Then slide 2 becomes active
|
|
588
|
+
|
|
589
|
+
Scenario: Enter on summary submits
|
|
590
|
+
Given I am on the summary slide
|
|
591
|
+
And all selections are made
|
|
592
|
+
When I press Enter
|
|
593
|
+
Then the deck is submitted
|
|
594
|
+
|
|
595
|
+
Scenario: Escape shows confirmation then cancels
|
|
596
|
+
Given I have selections
|
|
597
|
+
When I press Escape
|
|
598
|
+
Then a confirmation bar appears at the top
|
|
599
|
+
When I press Escape again
|
|
600
|
+
Then the deck is cancelled
|
|
601
|
+
And selections are auto-saved
|
|
602
|
+
|
|
603
|
+
Scenario: Escape with no selections cancels immediately
|
|
604
|
+
Given I have no selections
|
|
605
|
+
When I press Escape
|
|
606
|
+
Then the deck is cancelled immediately without confirmation
|
|
607
|
+
|
|
608
|
+
Scenario: Arrow keys navigate between options
|
|
609
|
+
Given an option card has focus
|
|
610
|
+
When I press ArrowDown
|
|
611
|
+
Then focus moves to the next option
|
|
612
|
+
When I press ArrowUp
|
|
613
|
+
Then focus moves to the previous option
|
|
614
|
+
|
|
615
|
+
# -----------------------------------------------------------------------------
|
|
616
|
+
|
|
617
|
+
Feature: Model Selection
|
|
618
|
+
As a user who wants control over option generation
|
|
619
|
+
I want to choose which AI model generates new options
|
|
620
|
+
So that I can get options from different model capabilities
|
|
621
|
+
|
|
622
|
+
Background:
|
|
623
|
+
Given a design deck is active in StreamWeaver
|
|
624
|
+
|
|
625
|
+
Scenario: Model bar appears with multiple models
|
|
626
|
+
Given the agent has 3 or more models available
|
|
627
|
+
When the deck loads
|
|
628
|
+
Then a model bar appears below the header
|
|
629
|
+
And "Current" is the active selection by default
|
|
630
|
+
|
|
631
|
+
Scenario: Select a different model
|
|
632
|
+
Given the model bar is visible
|
|
633
|
+
When I select "gemini-3.1-pro" from the model list
|
|
634
|
+
Then subsequent generate-more requests use this model
|
|
635
|
+
|
|
636
|
+
Scenario: Save model as default
|
|
637
|
+
Given a model is selected
|
|
638
|
+
When I check the "Default" checkbox
|
|
639
|
+
Then the model preference is saved to settings
|
|
640
|
+
And future decks pre-select this model
|
|
641
|
+
|
|
642
|
+
Scenario: Model bar hidden with fewer than 2 models
|
|
643
|
+
Given the agent has only 1 model available
|
|
644
|
+
When the deck loads
|
|
645
|
+
Then no model bar appears
|
|
646
|
+
|
|
647
|
+
# =============================================================================
|
|
648
|
+
# PART 3: VISUAL EXPLAINER FEATURES
|
|
649
|
+
# =============================================================================
|
|
650
|
+
|
|
651
|
+
Feature: Web Diagram Generation
|
|
652
|
+
As a developer using an AI agent
|
|
653
|
+
I want to generate visual HTML diagrams via StreamWeaver
|
|
654
|
+
So that I can understand complex systems better than ASCII art
|
|
655
|
+
|
|
656
|
+
Background:
|
|
657
|
+
Given the StreamWeaver visual-explainer skill is loaded
|
|
658
|
+
|
|
659
|
+
Scenario: Generate a basic diagram
|
|
660
|
+
Given the user invokes the web-diagram command with topic "WebSocket message flow"
|
|
661
|
+
When the agent generates a StreamWeaver page with the DSL
|
|
662
|
+
Then the page uses a distinctive aesthetic direction (not default/generic)
|
|
663
|
+
And the page is served via StreamWeaver or exported as self-contained HTML
|
|
664
|
+
And the browser opens to display it
|
|
665
|
+
And the agent reports the URL or file path
|
|
666
|
+
|
|
667
|
+
Scenario: Diagram uses distinctive typography
|
|
668
|
+
Given a diagram page is being generated
|
|
669
|
+
Then the body font is NOT Inter, Roboto, Arial, Helvetica, or system-ui alone
|
|
670
|
+
And the font pairing is loaded from Google Fonts CDN
|
|
671
|
+
And the pairing is chosen from the curated list of 13 recommended pairings
|
|
672
|
+
|
|
673
|
+
Scenario: Diagram avoids AI slop patterns
|
|
674
|
+
Given a diagram page is being generated
|
|
675
|
+
Then accent colors do NOT include the forbidden indigo/violet hex values
|
|
676
|
+
And headings do NOT use gradient text with background-clip
|
|
677
|
+
And section headers do NOT use emoji icons
|
|
678
|
+
And cards do NOT have animated glowing box-shadows
|
|
679
|
+
|
|
680
|
+
Scenario: Diagram renders with Mermaid zoom controls
|
|
681
|
+
Given the page includes a Mermaid diagram
|
|
682
|
+
Then it is wrapped in a zoom-enabled container with controls
|
|
683
|
+
And supports mouse wheel zoom, pan, and click-to-expand
|
|
684
|
+
|
|
685
|
+
Scenario: Diagram works in both themes
|
|
686
|
+
Given a diagram has been generated
|
|
687
|
+
When the OS is in light mode
|
|
688
|
+
Then the page renders with light palette
|
|
689
|
+
When the OS switches to dark mode
|
|
690
|
+
Then the page renders with dark palette
|
|
691
|
+
And both themes look intentional, not broken
|
|
692
|
+
|
|
693
|
+
Scenario: Optional AI image generation
|
|
694
|
+
Given surf-cli is available on the system
|
|
695
|
+
When the agent generates a diagram that would benefit from an image
|
|
696
|
+
Then it generates an image via surf-cli
|
|
697
|
+
And embeds it as a base64 data URI
|
|
698
|
+
|
|
699
|
+
Scenario: Graceful degradation without surf-cli
|
|
700
|
+
Given surf-cli is NOT available
|
|
701
|
+
When the agent generates a diagram
|
|
702
|
+
Then image generation is skipped without error
|
|
703
|
+
And the page uses CSS and typography alone
|
|
704
|
+
|
|
705
|
+
# -----------------------------------------------------------------------------
|
|
706
|
+
|
|
707
|
+
Feature: Visual Plan Generation
|
|
708
|
+
As a developer
|
|
709
|
+
I want a visual implementation plan for a feature
|
|
710
|
+
So that I can understand the design before coding
|
|
711
|
+
|
|
712
|
+
Background:
|
|
713
|
+
Given the StreamWeaver visual-explainer skill is loaded
|
|
714
|
+
|
|
715
|
+
Scenario: Generate a visual plan
|
|
716
|
+
Given the user invokes the visual-plan command for "user authentication"
|
|
717
|
+
When the agent gathers data
|
|
718
|
+
Then it parses the feature request
|
|
719
|
+
And reads relevant codebase files
|
|
720
|
+
And understands extension points and prior art
|
|
721
|
+
And generates a 10-section StreamWeaver page
|
|
722
|
+
|
|
723
|
+
Scenario: Plan includes state machine diagram
|
|
724
|
+
Given a visual plan has been generated
|
|
725
|
+
Then section 3 contains a Mermaid state diagram or flowchart
|
|
726
|
+
And it shows the lifecycle of the feature's core entity
|
|
727
|
+
|
|
728
|
+
Scenario: Plan includes code snippets
|
|
729
|
+
Given a visual plan has been generated
|
|
730
|
+
Then section 5 shows modified functions with syntax-highlighted code
|
|
731
|
+
And each snippet has an explanation of the change
|
|
732
|
+
|
|
733
|
+
Scenario: Verification checkpoint before rendering
|
|
734
|
+
Given the agent has gathered all data for the plan
|
|
735
|
+
Then it creates a verification fact sheet
|
|
736
|
+
And cross-references claims against actual code
|
|
737
|
+
Before generating the final StreamWeaver page
|
|
738
|
+
|
|
739
|
+
# -----------------------------------------------------------------------------
|
|
740
|
+
|
|
741
|
+
Feature: Slide Deck Generation
|
|
742
|
+
As a presenter
|
|
743
|
+
I want to convert technical content into a presentation
|
|
744
|
+
So that I can present findings to a team
|
|
745
|
+
|
|
746
|
+
Background:
|
|
747
|
+
Given the StreamWeaver visual-explainer skill is loaded
|
|
748
|
+
|
|
749
|
+
Scenario: Slide deck is opt-in only
|
|
750
|
+
Given the agent encounters complex content
|
|
751
|
+
Then it NEVER auto-selects slide format
|
|
752
|
+
And slides are only generated via explicit command or flag
|
|
753
|
+
|
|
754
|
+
Scenario: Generate a slide deck
|
|
755
|
+
Given the user invokes the slides command for "API Gateway Redesign"
|
|
756
|
+
When the agent generates the deck
|
|
757
|
+
Then it uses scroll-snap with 100dvh per slide
|
|
758
|
+
And it picks from 4 slide presets (Midnight Editorial, Warm Signal, Terminal Mono, Swiss Clean)
|
|
759
|
+
And the deck has multiple slide types (title, content, split, diagram, dashboard, etc.)
|
|
760
|
+
|
|
761
|
+
Scenario: Slide deck keyboard navigation
|
|
762
|
+
Given a slide deck is displayed
|
|
763
|
+
When the user presses ArrowRight or ArrowDown
|
|
764
|
+
Then the next slide scrolls into view smoothly
|
|
765
|
+
And Space, PageDown, PageUp, Home, End keys also work
|
|
766
|
+
And touch swipe (>50px) navigates between slides
|
|
767
|
+
And a progress bar, nav dots, and slide counter are visible
|
|
768
|
+
|
|
769
|
+
Scenario: Content completeness over polish
|
|
770
|
+
Given a source document has 7 sections and 6 decisions
|
|
771
|
+
Then the slide deck covers all 7 sections and all 6 decisions
|
|
772
|
+
And a 22-slide complete deck beats a 13-slide polished but incomplete deck
|
|
773
|
+
|
|
774
|
+
Scenario: Cinematic slide transitions
|
|
775
|
+
Given a slide scrolls into view
|
|
776
|
+
Then it fades in with translateY(40px) and scale(0.98)
|
|
777
|
+
And child elements with reveal class stagger in at 0.1s intervals
|
|
778
|
+
And @media (prefers-reduced-motion: reduce) disables all transitions
|
|
779
|
+
|
|
780
|
+
Scenario: Compositional variety
|
|
781
|
+
Given a slide deck is being generated
|
|
782
|
+
Then consecutive slides vary their spatial approach
|
|
783
|
+
And the deck alternates between centered, left-heavy, right-heavy, split compositions
|
|
784
|
+
|
|
785
|
+
Scenario: Slides flag on other commands
|
|
786
|
+
Given the user invokes "/diff-review main --slides"
|
|
787
|
+
Then data is gathered using the diff-review workflow
|
|
788
|
+
But presented as a slide deck instead of a scrollable page
|
|
789
|
+
|
|
790
|
+
# -----------------------------------------------------------------------------
|
|
791
|
+
|
|
792
|
+
Feature: Diff Review
|
|
793
|
+
As a developer
|
|
794
|
+
I want a visual diff review via StreamWeaver
|
|
795
|
+
So that I can understand code changes with architecture context
|
|
796
|
+
|
|
797
|
+
Background:
|
|
798
|
+
Given the StreamWeaver visual-explainer skill is loaded
|
|
799
|
+
|
|
800
|
+
Scenario: Diff review against main branch
|
|
801
|
+
Given the user invokes the diff-review command with no argument
|
|
802
|
+
When the agent gathers data
|
|
803
|
+
Then it runs git diff --stat and --name-status against main
|
|
804
|
+
And reads all changed files in full
|
|
805
|
+
And checks CHANGELOG.md and README.md for needed updates
|
|
806
|
+
And generates a verification fact sheet
|
|
807
|
+
And renders a 10-section StreamWeaver page
|
|
808
|
+
|
|
809
|
+
Scenario: Diff review of a specific PR
|
|
810
|
+
Given the user invokes diff-review for PR #42
|
|
811
|
+
Then the agent runs "gh pr diff 42" for the diff data
|
|
812
|
+
|
|
813
|
+
Scenario: Diff review of a commit hash
|
|
814
|
+
Given the user invokes diff-review for "abc123"
|
|
815
|
+
Then the agent runs "git show abc123" for the diff data
|
|
816
|
+
|
|
817
|
+
Scenario: Executive summary provides aha moment
|
|
818
|
+
Given a diff review has been generated
|
|
819
|
+
Then section 1 uses hero depth styling
|
|
820
|
+
And leads with WHY the changes exist
|
|
821
|
+
And a reader of only this section understands the essence
|
|
822
|
+
|
|
823
|
+
Scenario: Code review has Good/Bad/Ugly structure
|
|
824
|
+
Given a diff review has been generated
|
|
825
|
+
Then the code review section has 4 categories: Good, Bad, Ugly, Questions
|
|
826
|
+
And each uses colored left-border cards (green, red, amber, blue)
|
|
827
|
+
And each item references specific files and line ranges
|
|
828
|
+
|
|
829
|
+
Scenario: Module architecture has Mermaid diagram
|
|
830
|
+
Given a diff review has been generated
|
|
831
|
+
Then section 3 contains a Mermaid dependency graph
|
|
832
|
+
And the diagram has zoom controls
|
|
833
|
+
|
|
834
|
+
Scenario: Decision log captures rationale
|
|
835
|
+
Given a diff review has been generated
|
|
836
|
+
Then each decision card shows: decision, rationale, alternatives, confidence
|
|
837
|
+
And confidence levels have visual treatment (green/blue/amber)
|
|
838
|
+
|
|
839
|
+
# -----------------------------------------------------------------------------
|
|
840
|
+
|
|
841
|
+
Feature: Plan Review
|
|
842
|
+
As a developer
|
|
843
|
+
I want to compare a plan against the actual codebase
|
|
844
|
+
So that I can identify gaps and risks before implementation
|
|
845
|
+
|
|
846
|
+
Background:
|
|
847
|
+
Given the StreamWeaver visual-explainer skill is loaded
|
|
848
|
+
|
|
849
|
+
Scenario: Plan review with plan file
|
|
850
|
+
Given the user invokes plan-review for "docs/plan.md"
|
|
851
|
+
When the agent gathers data
|
|
852
|
+
Then it reads the plan file in full
|
|
853
|
+
And reads every file the plan references
|
|
854
|
+
And reads files that import/depend on referenced files
|
|
855
|
+
And maps the blast radius
|
|
856
|
+
And generates a 9-section StreamWeaver page
|
|
857
|
+
|
|
858
|
+
Scenario: Current vs planned architecture diagrams
|
|
859
|
+
Given a plan review has been generated
|
|
860
|
+
Then it shows current and planned Mermaid diagrams
|
|
861
|
+
And both use the same node names for visual comparison
|
|
862
|
+
And new nodes are highlighted with accent borders
|
|
863
|
+
And removed nodes have reduced opacity
|
|
864
|
+
|
|
865
|
+
Scenario: Risk assessment includes cognitive complexity
|
|
866
|
+
Given a plan review has been generated
|
|
867
|
+
Then the risk section includes cognitive complexity flags
|
|
868
|
+
And each has severity and mitigation suggestion
|
|
869
|
+
|
|
870
|
+
Scenario: Understanding gaps dashboard
|
|
871
|
+
Given a plan review has been generated
|
|
872
|
+
Then the closing section shows a rationale gaps dashboard
|
|
873
|
+
And provides explicit pre-implementation documentation recommendations
|
|
874
|
+
|
|
875
|
+
# -----------------------------------------------------------------------------
|
|
876
|
+
|
|
877
|
+
Feature: Project Recap
|
|
878
|
+
As a developer returning to a project after time away
|
|
879
|
+
I want a visual mental model snapshot
|
|
880
|
+
So that I can quickly re-orient and resume productive work
|
|
881
|
+
|
|
882
|
+
Background:
|
|
883
|
+
Given the StreamWeaver visual-explainer skill is loaded
|
|
884
|
+
|
|
885
|
+
Scenario: Default 2-week recap
|
|
886
|
+
Given the user invokes project-recap with no argument
|
|
887
|
+
When the agent gathers data
|
|
888
|
+
Then it uses a 2-week time window
|
|
889
|
+
And reads README.md, CHANGELOG.md, and project config
|
|
890
|
+
And runs git log --since="2 weeks ago"
|
|
891
|
+
And checks for uncommitted changes and stale branches
|
|
892
|
+
And generates an 8-section StreamWeaver page
|
|
893
|
+
|
|
894
|
+
Scenario: Custom time window
|
|
895
|
+
Given the user invokes project-recap with "3m"
|
|
896
|
+
Then the agent uses a 3-month time window
|
|
897
|
+
|
|
898
|
+
Scenario: Architecture snapshot as visual anchor
|
|
899
|
+
Given a project recap has been generated
|
|
900
|
+
Then the architecture Mermaid diagram uses hero depth styling
|
|
901
|
+
And labels nodes with what they DO, not just file names
|
|
902
|
+
|
|
903
|
+
Scenario: Cognitive debt hotspots surfaced
|
|
904
|
+
Given a project recap has been generated
|
|
905
|
+
Then the cognitive debt section uses amber-tinted cards
|
|
906
|
+
And each hotspot has severity indicator and remediation suggestion
|
|
907
|
+
|
|
908
|
+
# -----------------------------------------------------------------------------
|
|
909
|
+
|
|
910
|
+
Feature: Fact Check
|
|
911
|
+
As a developer
|
|
912
|
+
I want to verify generated documents match actual code
|
|
913
|
+
So that I can trust the information in reviews and plans
|
|
914
|
+
|
|
915
|
+
Background:
|
|
916
|
+
Given the StreamWeaver visual-explainer skill is loaded
|
|
917
|
+
|
|
918
|
+
Scenario: Fact check the most recent output
|
|
919
|
+
Given the user invokes fact-check with no argument
|
|
920
|
+
Then the agent finds the most recently generated page
|
|
921
|
+
And extracts every verifiable claim
|
|
922
|
+
And verifies each against the actual codebase
|
|
923
|
+
And corrects inaccuracies in place
|
|
924
|
+
And adds a verification summary section
|
|
925
|
+
And reports results
|
|
926
|
+
|
|
927
|
+
Scenario: Fact check a specific file
|
|
928
|
+
Given the user invokes fact-check for a specific HTML file path
|
|
929
|
+
Then the agent reads that specific file
|
|
930
|
+
And proceeds with the standard verification process
|
|
931
|
+
|
|
932
|
+
Scenario: Claims are classified
|
|
933
|
+
Given a fact check is in progress
|
|
934
|
+
Then each claim is classified as Confirmed, Corrected, or Unverifiable
|
|
935
|
+
And the verification summary includes counts for each category
|
|
936
|
+
|
|
937
|
+
Scenario: Corrections preserve page structure
|
|
938
|
+
Given corrections are being applied
|
|
939
|
+
Then layout, CSS, and diagrams are preserved
|
|
940
|
+
And only factual content is changed
|
|
941
|
+
And subjective analysis is never modified
|
|
942
|
+
|
|
943
|
+
# -----------------------------------------------------------------------------
|
|
944
|
+
|
|
945
|
+
Feature: Share and Deploy
|
|
946
|
+
As a developer
|
|
947
|
+
I want to share generated pages with a live URL
|
|
948
|
+
So that teammates can view them without local access
|
|
949
|
+
|
|
950
|
+
Background:
|
|
951
|
+
Given the StreamWeaver visual-explainer skill is loaded
|
|
952
|
+
|
|
953
|
+
Scenario: Share a page via Vercel
|
|
954
|
+
Given the user invokes share for a generated HTML file
|
|
955
|
+
And vercel-deploy is available
|
|
956
|
+
Then the HTML is deployed to Vercel
|
|
957
|
+
And a live URL is returned
|
|
958
|
+
And a claim URL for account transfer is returned
|
|
959
|
+
And the deployment is public with 30-day retention
|
|
960
|
+
|
|
961
|
+
Scenario: Share a live StreamWeaver page
|
|
962
|
+
Given the user invokes share for a currently running StreamWeaver page
|
|
963
|
+
Then the page is exported as self-contained HTML first
|
|
964
|
+
And then deployed to Vercel
|
|
965
|
+
|
|
966
|
+
Scenario: Share without vercel-deploy
|
|
967
|
+
Given vercel-deploy is NOT available
|
|
968
|
+
When the user invokes share
|
|
969
|
+
Then an error message explains the missing dependency
|
|
970
|
+
|
|
971
|
+
# -----------------------------------------------------------------------------
|
|
972
|
+
|
|
973
|
+
Feature: Auto-Trigger on Complex Output
|
|
974
|
+
As a developer
|
|
975
|
+
I want complex tabular data automatically rendered visually
|
|
976
|
+
So that I do not have to explicitly request visual treatment
|
|
977
|
+
|
|
978
|
+
Background:
|
|
979
|
+
Given the StreamWeaver visual-explainer skill is loaded
|
|
980
|
+
|
|
981
|
+
Scenario: Table with 4+ rows triggers visual rendering
|
|
982
|
+
Given the agent is about to present tabular data
|
|
983
|
+
And the table has 4 or more rows
|
|
984
|
+
Then the agent generates a StreamWeaver page instead of ASCII art
|
|
985
|
+
And opens it in the browser
|
|
986
|
+
And may include a brief text summary in the terminal
|
|
987
|
+
|
|
988
|
+
Scenario: Table with 3+ columns triggers visual rendering
|
|
989
|
+
Given the agent is about to present tabular data
|
|
990
|
+
And the table has 3 or more columns
|
|
991
|
+
Then the agent generates a StreamWeaver page
|
|
992
|
+
|
|
993
|
+
Scenario: Small table does not trigger
|
|
994
|
+
Given the table has fewer than 4 rows AND fewer than 3 columns
|
|
995
|
+
Then the agent renders it as normal text in the terminal
|
|
996
|
+
|
|
997
|
+
Scenario: Auto-generated table has proper styling
|
|
998
|
+
Given an HTML table is auto-generated via StreamWeaver
|
|
999
|
+
Then the table has a sticky header
|
|
1000
|
+
And alternating row backgrounds
|
|
1001
|
+
And row hover highlighting
|
|
1002
|
+
And status indicators use styled spans, never emoji
|
|
1003
|
+
And wide tables have a scrollable container
|