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,453 @@
|
|
|
1
|
+
# SW Plan Format: MDX Pipeline, GitHub Rendering, and the Design Strategy
|
|
2
|
+
|
|
3
|
+
**Date:** 2026-06-17
|
|
4
|
+
**Status:** Research complete — design conclusions
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## How MDX Actually Compiles
|
|
9
|
+
|
|
10
|
+
MDX is not "Markdown with components." It's a full compiler that transforms
|
|
11
|
+
`.mdx` source through five distinct AST stages before you get renderable output.
|
|
12
|
+
Source-verified from `@mdx-js/mdx/lib/core.js`:
|
|
13
|
+
|
|
14
|
+
```
|
|
15
|
+
.mdx source
|
|
16
|
+
↓ remark-parse + remark-mdx (micromark + acorn for JS)
|
|
17
|
+
mdast (Markdown AST — nodes like paragraph, heading, JSX)
|
|
18
|
+
↓ remarkMarkAndUnravel + user remark plugins (e.g. remark-gfm)
|
|
19
|
+
mdast (transformed)
|
|
20
|
+
↓ remark-rehype (mdast-util-to-hast)
|
|
21
|
+
hast (HTML AST — div, span, pre nodes)
|
|
22
|
+
↓ user rehype plugins (syntax highlight, math, etc.)
|
|
23
|
+
hast (transformed)
|
|
24
|
+
↓ rehype-recma → recma-document → recma-jsx-rewrite → recma-build-jsx
|
|
25
|
+
esast (ES AST — JavaScript module tree)
|
|
26
|
+
↓ recma-stringify (astring codegen)
|
|
27
|
+
JS module string (React component code)
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
**The output is not HTML.** It's a JavaScript module:
|
|
31
|
+
|
|
32
|
+
```js
|
|
33
|
+
import { jsx as _jsx, jsxs as _jsxs } from 'react/jsx-runtime'
|
|
34
|
+
|
|
35
|
+
function _createMdxContent(props) {
|
|
36
|
+
const _components = { h1: 'h1', ...props.components }
|
|
37
|
+
return _jsxs(_Fragment, { children: [
|
|
38
|
+
_jsx(_components.h1, { children: 'Overview' }),
|
|
39
|
+
_jsx(_components.ImplementationMap, { files: [...] })
|
|
40
|
+
]})
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export default function MDXContent(props = {}) { ... }
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
React renders that JS component to DOM at runtime.
|
|
47
|
+
|
|
48
|
+
### What This Costs in Setup
|
|
49
|
+
|
|
50
|
+
To use MDX you need:
|
|
51
|
+
|
|
52
|
+
- A bundler with MDX loader configured (webpack `@mdx-js/loader`, Rollup
|
|
53
|
+
`@mdx-js/rollup`, or esbuild `@mdx-js/esbuild`)
|
|
54
|
+
- React and `react/jsx-runtime` as dependencies
|
|
55
|
+
- In Next.js App Router: a mandatory `mdx-components.tsx` file at project root
|
|
56
|
+
- For custom components: a provider or explicit `components=` prop passed to
|
|
57
|
+
every `<MDXContent>` render call
|
|
58
|
+
- Plugin knowledge: remark/rehype ecosystem for anything beyond basic markdown
|
|
59
|
+
|
|
60
|
+
For **runtime rendering** (serving dynamic MDX from a DB like Builder does):
|
|
61
|
+
- `compile(mdxString, { outputFormat: 'function-body' })` → JS string
|
|
62
|
+
- `run(compiledCode, { ...runtime })` → React component
|
|
63
|
+
- This is essentially `new AsyncFunction(compiledCode)` — blocked by CSP in
|
|
64
|
+
many production environments, and a security concern if content is
|
|
65
|
+
user-controlled
|
|
66
|
+
|
|
67
|
+
**Summary of MDX friction:** You can't just point a server at a `.mdx` file and
|
|
68
|
+
have it render. You need a full JS build pipeline, React, and careful component
|
|
69
|
+
registry management. Builder gets away with this because they own a hosted SaaS
|
|
70
|
+
app that runs all of this. If you're not running that hosted app, `.mdx` files
|
|
71
|
+
are expensive text you can't easily render.
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## How GitHub Renders `.org` Files — Source-Backed Facts
|
|
76
|
+
|
|
77
|
+
GitHub uses the `github/markup` gem, which for `.org` files calls:
|
|
78
|
+
|
|
79
|
+
```ruby
|
|
80
|
+
# From github/markup/lib/github/markups.rb (actual source)
|
|
81
|
+
GitHub::Markup.markup(:MARKUP_ORG, 'org-ruby', /org/, ["Org"]) do |filename, content, options: {}|
|
|
82
|
+
Orgmode::Parser.new(content, {
|
|
83
|
+
:allow_include_files => false, # #+INCLUDE: is hardcoded OFF
|
|
84
|
+
:skip_syntax_highlight => true # no Pygments, raw <pre> only
|
|
85
|
+
}).to_html
|
|
86
|
+
end
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
The HTML then passes through **html-pipeline's `SanitizationFilter`** (Selma),
|
|
90
|
+
which has a strict allowlist. This is the layer that kills most attempts at
|
|
91
|
+
custom rendering.
|
|
92
|
+
|
|
93
|
+
### What GitHub's Sanitizer Strips
|
|
94
|
+
|
|
95
|
+
After org-ruby generates HTML, Selma removes:
|
|
96
|
+
- `style="..."` attribute — stripped from ALL elements
|
|
97
|
+
- `class="..."` attribute — stripped from most elements
|
|
98
|
+
- `<script>`, `<style>`, `<link>` — blocked entirely
|
|
99
|
+
- `<iframe>` — blocked
|
|
100
|
+
- `#+BEGIN_HTML` blocks pass through org-ruby verbatim, then Selma sanitizes
|
|
101
|
+
|
|
102
|
+
**No mechanism exists to inject custom CSS or JS** into GitHub's rendered view
|
|
103
|
+
of a `.org` file. Not via in-buffer settings, not via `.gitattributes`, not at
|
|
104
|
+
all. GitHub Pages is different — but that's a separate deployment, not the
|
|
105
|
+
in-repo file view.
|
|
106
|
+
|
|
107
|
+
### The Critical Finding: What Happens to Custom Content
|
|
108
|
+
|
|
109
|
+
| Construct | org-ruby output | After GitHub sanitizer |
|
|
110
|
+
|---|---|---|
|
|
111
|
+
| `* Heading` | `<h1>` | ✅ Passes |
|
|
112
|
+
| `\| table \|` | `<table><tr><td>` | ✅ Passes |
|
|
113
|
+
| `- list` | `<ul><li>` | ✅ Passes |
|
|
114
|
+
| `#+BEGIN_SRC ruby` | `<pre class="src">` | ✅ Passes (class stripped) |
|
|
115
|
+
| `#+BEGIN_QUOTE` | `<blockquote>` | ✅ Passes |
|
|
116
|
+
| `#+BEGIN_EXAMPLE` | `<pre class="example">` | ✅ Passes |
|
|
117
|
+
| `:PROPERTIES:` drawer | **Nothing** | ✅ Nothing (invisible) |
|
|
118
|
+
| `#+BEGIN_MYBLOCK` | **Dropped** (treated as `:comment`) | Nothing |
|
|
119
|
+
| `style="..."` | Emitted | ❌ Stripped |
|
|
120
|
+
| `class="..."` | Emitted | ❌ Stripped |
|
|
121
|
+
|
|
122
|
+
The `:PROPERTIES:` drawer outcome is perfect for us: **completely invisible on
|
|
123
|
+
GitHub, but parsed by org-ruby into a clean Ruby hash** that our renderer reads.
|
|
124
|
+
The headline is still visible; the metadata is hidden.
|
|
125
|
+
|
|
126
|
+
The custom block outcome is a constraint we must design around: **any
|
|
127
|
+
`#+BEGIN_SW_WHATEVER` block gets silently dropped by org-ruby** before GitHub
|
|
128
|
+
ever sees it.
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## The Design Constraint and the Insight It Unlocks
|
|
133
|
+
|
|
134
|
+
Here's the real question: do we need GitHub to render our custom components
|
|
135
|
+
beautifully? Or do we need the *content* of those components to be readable?
|
|
136
|
+
|
|
137
|
+
Those are different requirements.
|
|
138
|
+
|
|
139
|
+
**MDX on GitHub:** Custom component syntax is completely unreadable as raw text.
|
|
140
|
+
```
|
|
141
|
+
<ImplementationMap
|
|
142
|
+
id="b2"
|
|
143
|
+
files={[
|
|
144
|
+
{ path: "lib/auth/session.rb", note: "Add guest token issuer" },
|
|
145
|
+
{ path: "db/schema.rb", note: "Add guest_sessions table" },
|
|
146
|
+
]}
|
|
147
|
+
/>
|
|
148
|
+
```
|
|
149
|
+
A reviewer reading this in a PR sees JSX noise. No information is conveyed
|
|
150
|
+
without the renderer.
|
|
151
|
+
|
|
152
|
+
**SW-Org on GitHub (if we design it right):** The *content* of every component
|
|
153
|
+
is encoded in native org structures that GitHub already renders:
|
|
154
|
+
|
|
155
|
+
```org
|
|
156
|
+
* Implementation Map
|
|
157
|
+
:PROPERTIES:
|
|
158
|
+
:SW_COMPONENT: implementation_map
|
|
159
|
+
:END:
|
|
160
|
+
|
|
161
|
+
| File | Note |
|
|
162
|
+
|-------------------------|---------------------------|
|
|
163
|
+
| lib/auth/session.rb | Add guest token issuer |
|
|
164
|
+
| db/schema.rb | Add guest_sessions table |
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
GitHub renders this as a real heading + real table. A reviewer sees exactly what
|
|
168
|
+
they need. The `:PROPERTIES:` drawer is invisible. The StreamWeaver renderer
|
|
169
|
+
sees `SW_COMPONENT: implementation_map` and makes it beautiful.
|
|
170
|
+
|
|
171
|
+
**This is strictly better than MDX for raw readability** — and we can achieve it
|
|
172
|
+
without GitHub doing anything special.
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## Format Design: Every Component Maps to Native Org
|
|
177
|
+
|
|
178
|
+
The design principle: **encode all component data in org constructs that already
|
|
179
|
+
render well on GitHub**. Use `:PROPERTIES:` only for machine metadata that
|
|
180
|
+
humans don't need to read.
|
|
181
|
+
|
|
182
|
+
### Implementation Map
|
|
183
|
+
|
|
184
|
+
```org
|
|
185
|
+
* Implementation Map
|
|
186
|
+
:PROPERTIES:
|
|
187
|
+
:SW_COMPONENT: implementation_map
|
|
188
|
+
:END:
|
|
189
|
+
|
|
190
|
+
| File | Role |
|
|
191
|
+
|----------------------------|------------------------------|
|
|
192
|
+
| lib/auth/session.rb | Add guest token issuer |
|
|
193
|
+
| app/routes/checkout.rb | Branch on guest vs auth user |
|
|
194
|
+
| db/schema.rb | Add guest_sessions table |
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
**GitHub renders:** Heading + proper HTML table. ✅
|
|
198
|
+
**SW renders:** Styled file-map component with path icons and rationale.
|
|
199
|
+
|
|
200
|
+
### Decision Block
|
|
201
|
+
|
|
202
|
+
```org
|
|
203
|
+
* Decision: Token Storage Strategy
|
|
204
|
+
:PROPERTIES:
|
|
205
|
+
:SW_COMPONENT: decision
|
|
206
|
+
:SW_RECOMMENDED: opaque
|
|
207
|
+
:END:
|
|
208
|
+
|
|
209
|
+
| Option | Detail |
|
|
210
|
+
|---------------|---------------------------------------------|
|
|
211
|
+
| jwt | Stateless, no DB lookup |
|
|
212
|
+
| *opaque* | Revocable, supports account merge later ✓ |
|
|
213
|
+
|
|
214
|
+
The opaque token approach is recommended because it allows guest sessions to be
|
|
215
|
+
revoked immediately and merged into real accounts post-purchase.
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
**GitHub renders:** Heading + table (the `*opaque*` shows as bold, the ✓ is
|
|
219
|
+
a unicode character). The recommended option is visually distinguished even
|
|
220
|
+
without the renderer. ✅
|
|
221
|
+
**SW renders:** Styled decision block with highlighted recommended option and
|
|
222
|
+
rationale callout.
|
|
223
|
+
|
|
224
|
+
### Callout
|
|
225
|
+
|
|
226
|
+
```org
|
|
227
|
+
* Risk: Session Expiry
|
|
228
|
+
:PROPERTIES:
|
|
229
|
+
:SW_COMPONENT: callout
|
|
230
|
+
:SW_TONE: risk
|
|
231
|
+
:END:
|
|
232
|
+
|
|
233
|
+
#+BEGIN_QUOTE
|
|
234
|
+
Guest sessions must expire to prevent unbounded DB growth.
|
|
235
|
+
Proposed TTL: 24h — needs confirmation from data team.
|
|
236
|
+
#+END_QUOTE
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
**GitHub renders:** Heading + `<blockquote>`. Visually indented. ✅
|
|
240
|
+
**SW renders:** Styled risk callout with red/orange border and icon.
|
|
241
|
+
|
|
242
|
+
Note: `#+BEGIN_QUOTE` is one of org-ruby's supported block types — it renders
|
|
243
|
+
as `<blockquote>`. This is the right native fallback for callouts.
|
|
244
|
+
|
|
245
|
+
### Annotated Code
|
|
246
|
+
|
|
247
|
+
```org
|
|
248
|
+
* Auth Token Implementation
|
|
249
|
+
:PROPERTIES:
|
|
250
|
+
:SW_COMPONENT: annotated_code
|
|
251
|
+
:SW_LANG: ruby
|
|
252
|
+
:END:
|
|
253
|
+
|
|
254
|
+
#+BEGIN_SRC ruby
|
|
255
|
+
def issue_guest_token(email)
|
|
256
|
+
JWT.encode({ sub: email, role: 'guest' }, SECRET, exp: 24.hours.from_now)
|
|
257
|
+
end
|
|
258
|
+
#+END_SRC
|
|
259
|
+
|
|
260
|
+
Annotations:
|
|
261
|
+
1. ~role: 'guest'~ restricts token scope — guest tokens cannot call admin APIs
|
|
262
|
+
2. ~exp: 24.hours~ matches the cleanup job cadence defined in ~db/jobs/session_cleanup.rb~
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
**GitHub renders:** Heading + syntax-highlighted code block + numbered list with
|
|
266
|
+
inline code. ✅ Every annotation is readable.
|
|
267
|
+
**SW renders:** Code with line-pinned annotation bubbles.
|
|
268
|
+
|
|
269
|
+
### Wireframe
|
|
270
|
+
|
|
271
|
+
This is the hard case — a wireframe is inherently visual. Fallback options:
|
|
272
|
+
|
|
273
|
+
```org
|
|
274
|
+
* Checkout Screen: Guest Path
|
|
275
|
+
:PROPERTIES:
|
|
276
|
+
:SW_COMPONENT: wireframe
|
|
277
|
+
:SW_SURFACE: browser
|
|
278
|
+
:END:
|
|
279
|
+
|
|
280
|
+
#+BEGIN_SRC html
|
|
281
|
+
<div class="page">
|
|
282
|
+
<header>MyApp</header>
|
|
283
|
+
<main>
|
|
284
|
+
<h2>Continue as guest?</h2>
|
|
285
|
+
<button data-goto="b">Continue as Guest</button>
|
|
286
|
+
<a href="#">Sign in instead</a>
|
|
287
|
+
</main>
|
|
288
|
+
</div>
|
|
289
|
+
#+END_SRC
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
**GitHub renders:** Heading + HTML source in a code block. Not a visual mockup,
|
|
293
|
+
but the HTML is readable and documents the intended structure. ✅
|
|
294
|
+
**SW renders:** Full device-framed browser mockup with prototype navigation.
|
|
295
|
+
|
|
296
|
+
This is the honest tradeoff: wireframes can't degrade to "beautiful on GitHub"
|
|
297
|
+
because they're fundamentally visual. But the HTML source is still more readable
|
|
298
|
+
than MDX's JSX prop syntax, and it renders perfectly in SW.
|
|
299
|
+
|
|
300
|
+
### Mermaid Diagram
|
|
301
|
+
|
|
302
|
+
```org
|
|
303
|
+
* Auth Flow Architecture
|
|
304
|
+
:PROPERTIES:
|
|
305
|
+
:SW_COMPONENT: diagram
|
|
306
|
+
:SW_DIAGRAM: mermaid
|
|
307
|
+
:END:
|
|
308
|
+
|
|
309
|
+
#+BEGIN_SRC mermaid
|
|
310
|
+
sequenceDiagram
|
|
311
|
+
User->>App: Request checkout
|
|
312
|
+
App->>Auth: Issue guest token
|
|
313
|
+
Auth-->>App: JWT (role: guest, TTL: 24h)
|
|
314
|
+
App-->>User: Checkout continues
|
|
315
|
+
#+END_SRC
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
**GitHub renders:** Code block labeled `mermaid`. GitHub *does* natively render
|
|
319
|
+
Mermaid in Markdown (`.md`) files — but **not** in `.org` files (org-ruby
|
|
320
|
+
predates that feature). Renders as source. ✅ (Readable source; not rendered.)
|
|
321
|
+
**SW renders:** Live Mermaid diagram via Mermaid.js.
|
|
322
|
+
|
|
323
|
+
---
|
|
324
|
+
|
|
325
|
+
## Friction Comparison: MDX vs SW-Org
|
|
326
|
+
|
|
327
|
+
### To render an MDX file from scratch
|
|
328
|
+
|
|
329
|
+
1. `npm install @mdx-js/mdx @mdx-js/rollup react react-dom @types/mdx`
|
|
330
|
+
2. Configure bundler plugin
|
|
331
|
+
3. Create `mdx-components.tsx` with component registry
|
|
332
|
+
4. Build (`next build` or Vite build)
|
|
333
|
+
5. Start server
|
|
334
|
+
6. Open browser
|
|
335
|
+
|
|
336
|
+
Or for runtime rendering:
|
|
337
|
+
1. `compile(mdxString, { outputFormat: 'function-body' })`
|
|
338
|
+
2. `run(code, { ...runtime })`
|
|
339
|
+
3. Pass `components` prop with full registry
|
|
340
|
+
4. Render to DOM via React
|
|
341
|
+
|
|
342
|
+
**Friction level:** High. Requires JS build toolchain, React, bundler
|
|
343
|
+
integration, and component registry management.
|
|
344
|
+
|
|
345
|
+
### To render an SW-Org file from scratch
|
|
346
|
+
|
|
347
|
+
```bash
|
|
348
|
+
streamweaver serve plan.org
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
That's it. The org-ruby gem is already installed (`gem list` confirms 0.9.12
|
|
352
|
+
is present). The parser is ~150 lines of Ruby reading from an already-installed
|
|
353
|
+
gem. No bundler, no React, no build step.
|
|
354
|
+
|
|
355
|
+
**Friction level:** Single command. Already lower than MDX by any measure.
|
|
356
|
+
|
|
357
|
+
---
|
|
358
|
+
|
|
359
|
+
## Can We Get GitHub to Natively Render Our Components?
|
|
360
|
+
|
|
361
|
+
**Short answer: No. And it doesn't matter.**
|
|
362
|
+
|
|
363
|
+
GitHub's org-ruby integration:
|
|
364
|
+
1. Uses `org-ruby` hardcoded with `allow_include_files: false`
|
|
365
|
+
2. Passes output through `html-pipeline` Selma sanitizer (strips `class=`,
|
|
366
|
+
`style=`, all JS/CSS)
|
|
367
|
+
3. Custom `#+BEGIN_SW_*` blocks → **silently dropped** (org-ruby classifies
|
|
368
|
+
unknown block types as `:comment`)
|
|
369
|
+
4. No `.gitattributes` hook for custom rendering
|
|
370
|
+
5. No way to inject CSS or JS into file rendering
|
|
371
|
+
|
|
372
|
+
**The format-design insight makes this a non-issue.** If we encode component
|
|
373
|
+
data in native org structures (tables, code blocks, blockquotes, headings), then
|
|
374
|
+
GitHub's natural org rendering IS the good degraded view. We're not asking
|
|
375
|
+
GitHub to render a custom component — we're asking it to render a table, which
|
|
376
|
+
it already does beautifully.
|
|
377
|
+
|
|
378
|
+
The `:PROPERTIES:` drawer being invisible is a feature: the machine metadata
|
|
379
|
+
stays out of the human's way on GitHub, while remaining fully accessible to
|
|
380
|
+
the StreamWeaver parser.
|
|
381
|
+
|
|
382
|
+
---
|
|
383
|
+
|
|
384
|
+
## The Rendering Architecture
|
|
385
|
+
|
|
386
|
+
```
|
|
387
|
+
plan.org (checked in, human-readable on GitHub)
|
|
388
|
+
│
|
|
389
|
+
├─ GitHub view: headings + tables + code blocks
|
|
390
|
+
│ (degraded but fully readable, no renderer needed)
|
|
391
|
+
│
|
|
392
|
+
└─ StreamWeaver serve plan.org
|
|
393
|
+
│
|
|
394
|
+
├─ OrgParser: read in-buffer settings + headlines
|
|
395
|
+
├─ Per-headline: dispatch on SW_COMPONENT property
|
|
396
|
+
├─ Render each block via StreamWeaver component DSL
|
|
397
|
+
└─ Live canvas: full component styling + interactivity
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
**Bidirectionality:**
|
|
401
|
+
```
|
|
402
|
+
canvas-push (live Ruby DSL) ←→ canvas-export --format org ←→ git commit
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
You never write org by hand in normal flow. Claude Code writes the live DSL;
|
|
406
|
+
`canvas-export` serializes it to org; you commit. Future sessions restore from
|
|
407
|
+
the org file.
|
|
408
|
+
|
|
409
|
+
---
|
|
410
|
+
|
|
411
|
+
## The One Thing to Watch: Custom Blocks
|
|
412
|
+
|
|
413
|
+
Because `#+BEGIN_SW_CUSTOM` blocks are dropped by org-ruby → GitHub, we have a
|
|
414
|
+
design rule:
|
|
415
|
+
|
|
416
|
+
**Rule: No custom `#+BEGIN_` blocks for content that must be readable on GitHub.**
|
|
417
|
+
|
|
418
|
+
Use:
|
|
419
|
+
- `#+BEGIN_QUOTE` → callouts
|
|
420
|
+
- `#+BEGIN_SRC lang` → code and diagrams (as source)
|
|
421
|
+
- `| table |` → structured data
|
|
422
|
+
- `- list` / `1. numbered` → annotations and options
|
|
423
|
+
|
|
424
|
+
The `#+BEGIN_SRC html` fallback for wireframes is acceptable: the HTML source
|
|
425
|
+
is more informative than JSX prop syntax and clearly marks "this is a UI
|
|
426
|
+
component."
|
|
427
|
+
|
|
428
|
+
---
|
|
429
|
+
|
|
430
|
+
## Verdict
|
|
431
|
+
|
|
432
|
+
| Dimension | MDX | SW-Org |
|
|
433
|
+
|---|---|---|
|
|
434
|
+
| Raw readability on GitHub | ❌ JSX is noise | ✅ Tables, headings, code blocks |
|
|
435
|
+
| Renderer friction | ❌ React + bundler required | ✅ `streamweaver serve plan.org` |
|
|
436
|
+
| Custom component registry | ❌ Must configure + maintain | ✅ Property drawer dispatch |
|
|
437
|
+
| Checked-in artifact | ⚠️ Useless without hosted app | ✅ Readable anywhere |
|
|
438
|
+
| Bidirectional (canvas ↔ file) | ❌ Hard (JSX serialization is painful) | ✅ Natural text format |
|
|
439
|
+
| Already installed | ❌ Needs npm install | ✅ org-ruby 0.9.12 present |
|
|
440
|
+
| GitHub native rendering | ❌ JSX not rendered | ✅ Natural org elements render |
|
|
441
|
+
| LLM writability | ✅ Easy (learned from training) | ✅ Easy (tables + drawers) |
|
|
442
|
+
| Emacs integration | ❌ | ✅ Full org-mode native |
|
|
443
|
+
|
|
444
|
+
SW-Org is strictly better than MDX for StreamWeaver's use case. The only thing
|
|
445
|
+
MDX has going for it is ecosystem momentum — it's what JavaScript developers
|
|
446
|
+
already know. Since StreamWeaver is Ruby-first and the target audience writes
|
|
447
|
+
Ruby, that advantage doesn't apply.
|
|
448
|
+
|
|
449
|
+
---
|
|
450
|
+
|
|
451
|
+
*Research and design by Selene — June 2026*
|
|
452
|
+
*Sources: @mdx-js/mdx source (core.js), github/markup source (markups.rb),
|
|
453
|
+
org-ruby source (html_output_buffer.rb, parser.rb, line.rb)*
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# StreamWeaver Visual Skills — Progress Log
|
|
2
|
+
|
|
3
|
+
## Vision
|
|
4
|
+
Port the value of pi-design-deck and visual-explainer into StreamWeaver as
|
|
5
|
+
first-class skills/components. The StreamWeaver DSL approach should be dramatically
|
|
6
|
+
more token-efficient than raw HTML generation while delivering equal or better UX.
|
|
7
|
+
|
|
8
|
+
## Phase 1: Deep Analysis
|
|
9
|
+
- [x] pi-design-deck deep analysis → `analysis/pi-design-deck.md` (138K tokens, 28 tool uses, 5m10s)
|
|
10
|
+
- [x] visual-explainer deep analysis → `analysis/visual-explainer.md` (151K tokens, 35 tool uses, 6m23s)
|
|
11
|
+
- [x] StreamWeaver component inventory → `analysis/streamweaver-inventory.md`
|
|
12
|
+
- [x] Overlap/unification analysis → `analysis/overlap.md` (360 lines, 37% shared confirmed)
|
|
13
|
+
- [x] Unified Gherkin spec → `analysis/unified-specs.feature` (1003 lines, 23 features)
|
|
14
|
+
- [x] Component inventory → `analysis/components.md` (317 lines, 50 components across 5 phases)
|
|
15
|
+
|
|
16
|
+
## Phase 2: Unified Specification
|
|
17
|
+
- [x] Combined cucumber/Gherkin specs → `analysis/unified-specs.feature`
|
|
18
|
+
- [x] Component inventory → `analysis/components.md`
|
|
19
|
+
|
|
20
|
+
## Phase 3: Design
|
|
21
|
+
- [x] OO design document → `design/architecture.md` (1618 lines, 12 sections, 9 open questions)
|
|
22
|
+
- [x] DHH review → `design/dhh-review.md` ("fundamentally sound, needs ruthless editing")
|
|
23
|
+
- [x] Codex second opinion → `design/codex-review.md` ("solid, spike generate-more, file-backed state")
|
|
24
|
+
- [x] Gemini adversarial review → `design/gemini-review.md` ("push-to-state not push-to-DOM")
|
|
25
|
+
- [x] Review synthesis → `design/review-synthesis.md` (3 reviewers reconciled)
|
|
26
|
+
- [x] Design iteration log → `design/evolution.md` (5 entries)
|
|
27
|
+
- [x] Architecture updated with all post-review changes (push-to-state, cancellation, accessibility, scalability)
|
|
28
|
+
|
|
29
|
+
## Phase 4: Implementation Planning
|
|
30
|
+
- [x] GSD-style task breakdown → `implementation/tasks.md` (15 tasks, 5 waves)
|
|
31
|
+
- [x] Subagent implementation plan → `implementation/plan.md` (ralph-loop orchestration)
|
|
32
|
+
- [x] STATE.md initialized → `implementation/STATE.md`
|
|
33
|
+
|
|
34
|
+
## Phase 5: Implementation (COMPLETE)
|
|
35
|
+
- [x] Wave 1: T1 (generate-more spike) + T2 (theme + CSS foundation)
|
|
36
|
+
- [x] Wave 2: T3-T6 (shared components — mermaid, codeblock, keyboard, card/table)
|
|
37
|
+
- [x] Wave 3: T7-T9 (deck core — shell, selection, summary)
|
|
38
|
+
- [x] Wave 4: T10-T12 (generate-more full + explainer components)
|
|
39
|
+
- [x] Wave 5: T13-T15 (polish — helpers, deck polish, theme presets)
|
|
40
|
+
- [x] Full integration: 1427 tests, 0 failures
|
|
41
|
+
|
|
42
|
+
## Phase 6: Documentation & Blog
|
|
43
|
+
- [ ] Blog post draft → `blog/token-efficiency.md`
|
|
44
|
+
- [ ] Lessons learned → `lessons-learned/process.md`
|
|
45
|
+
|
|
46
|
+
## Lessons Learned (running log)
|
|
47
|
+
_Extracted during the process for eventual skill creation_
|
|
48
|
+
|
|
49
|
+
1. **Clone reference projects locally** — enables subagent deep-dives without web fetch rate limits
|
|
50
|
+
2. **Parallel analysis with shared template** — consistent output format enables mechanical overlap detection
|
|
51
|
+
3. **Cucumber/Gherkin as intent capture** — bridges "what they do" to "what we need to build", model-friendly
|
|
52
|
+
4. **GSD ralph-loop pattern** — break implementation into file-tracked tasks, subagents get fresh context per task
|
|
53
|
+
5. **Track evolution, not just final state** — LLMs advancing the work need to see decision rationale
|
|
54
|
+
6. **Parallel analysis subagents with shared template** — consistent output enables mechanical overlap detection
|
|
55
|
+
7. **Token cost asymmetry reveals value** — explainer saves 80-85% because design system moves from prompt to framework
|
|
56
|
+
8. **Blog material emerges from process** — capture it live, don't reconstruct later
|
|
57
|
+
9. **Multi-model review catches different things** — DHH (simplicity), Codex (edge cases), Gemini (architecture)
|
|
58
|
+
10. **Adversarial prompt on third review** — yielded best insight (push-to-state)
|
|
59
|
+
11. **Pre-compaction SESSION-CONTEXT.md** — insurance policy for context loss
|
|
60
|
+
12. **GSD ralph-loop for implementation** — context sharding, atomic tasks, file-tracked state
|