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,238 @@
|
|
|
1
|
+
# Claude Project Design: Dynamic Canvas Workflows
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
A Claude Project that enables rich, interactive workflows via StreamWeaver canvas. The project combines:
|
|
6
|
+
1. A slash command to launch the canvas panel
|
|
7
|
+
2. Knowledge of StreamWeaver DSL for dynamic UI generation
|
|
8
|
+
3. Agentic script execution for data analysis
|
|
9
|
+
4. Multi-step flows that produce unique results each time
|
|
10
|
+
|
|
11
|
+
## Architecture
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
15
|
+
│ Claude Project │
|
|
16
|
+
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────┐ │
|
|
17
|
+
│ │ /canvas command │ │ StreamWeaver │ │ Domain │ │
|
|
18
|
+
│ │ (launches panel)│ │ DSL Knowledge │ │ Scripts │ │
|
|
19
|
+
│ └────────┬────────┘ └────────┬────────┘ └──────┬──────┘ │
|
|
20
|
+
│ │ │ │ │
|
|
21
|
+
│ ▼ ▼ ▼ │
|
|
22
|
+
│ ┌─────────────────────────────────────────────────────────┐│
|
|
23
|
+
│ │ Agentic Workflow Engine ││
|
|
24
|
+
│ │ 1. Analyze context (repo, data, user input) ││
|
|
25
|
+
│ │ 2. Generate custom UI via canvas DSL ││
|
|
26
|
+
│ │ 3. Collect user choices ││
|
|
27
|
+
│ │ 4. Execute domain-specific actions ││
|
|
28
|
+
│ │ 5. Display results with charts/tables ││
|
|
29
|
+
│ └─────────────────────────────────────────────────────────┘│
|
|
30
|
+
└─────────────────────────────────────────────────────────────┘
|
|
31
|
+
│
|
|
32
|
+
▼
|
|
33
|
+
┌───────────────────────────────┐
|
|
34
|
+
│ Browser Canvas Panel │
|
|
35
|
+
│ ┌─────────────────────────┐ │
|
|
36
|
+
│ │ Dynamic UI Components │ │
|
|
37
|
+
│ │ - Charts (bar, line) │ │
|
|
38
|
+
│ │ - Tables (sortable) │ │
|
|
39
|
+
│ │ - Progress indicators │ │
|
|
40
|
+
│ │ - Code with highlighting│ │
|
|
41
|
+
│ │ - Forms & selections │ │
|
|
42
|
+
│ └─────────────────────────┘ │
|
|
43
|
+
└───────────────────────────────┘
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Slash Command: `/canvas`
|
|
47
|
+
|
|
48
|
+
```
|
|
49
|
+
/canvas [workflow-name]
|
|
50
|
+
|
|
51
|
+
Examples:
|
|
52
|
+
/canvas # Interactive menu of available workflows
|
|
53
|
+
/canvas analyze # Launch project analyzer
|
|
54
|
+
/canvas review # Launch code review assistant
|
|
55
|
+
/canvas explore # Launch data explorer
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Core Workflows
|
|
59
|
+
|
|
60
|
+
### 1. Project Health Analyzer
|
|
61
|
+
|
|
62
|
+
**Purpose:** Analyze a codebase and generate custom health dashboard
|
|
63
|
+
|
|
64
|
+
**Flow:**
|
|
65
|
+
1. **Discovery** - Scan project structure, detect languages/frameworks
|
|
66
|
+
2. **Selection** - User picks what to analyze (tests, complexity, deps, etc.)
|
|
67
|
+
3. **Analysis** - Run analysis with progress indicators
|
|
68
|
+
4. **Dashboard** - Generate custom charts and recommendations
|
|
69
|
+
|
|
70
|
+
**Dynamic Elements:**
|
|
71
|
+
- Charts based on what metrics are relevant to the project
|
|
72
|
+
- Recommendations tailored to detected issues
|
|
73
|
+
- Drill-down tables for specific problem areas
|
|
74
|
+
|
|
75
|
+
### 2. Interactive Code Review
|
|
76
|
+
|
|
77
|
+
**Purpose:** Review code changes with visual diff and actionable fixes
|
|
78
|
+
|
|
79
|
+
**Flow:**
|
|
80
|
+
1. **Input** - User provides PR link, commit, or staged changes
|
|
81
|
+
2. **Analysis** - Categorize issues by severity and type
|
|
82
|
+
3. **Selection** - User picks which issues to address
|
|
83
|
+
4. **Preview** - Show proposed fixes with syntax highlighting
|
|
84
|
+
5. **Apply** - Make changes with progress tracking
|
|
85
|
+
6. **Summary** - Results with before/after comparison
|
|
86
|
+
|
|
87
|
+
### 3. Data Explorer Wizard
|
|
88
|
+
|
|
89
|
+
**Purpose:** Explore and visualize data from various sources
|
|
90
|
+
|
|
91
|
+
**Flow:**
|
|
92
|
+
1. **Source** - User specifies data (CSV, JSON, API, database)
|
|
93
|
+
2. **Profile** - Auto-detect schema, show sample data
|
|
94
|
+
3. **Questions** - User selects what to explore
|
|
95
|
+
4. **Visualization** - Generate appropriate charts
|
|
96
|
+
5. **Insights** - Surface patterns and anomalies
|
|
97
|
+
6. **Export** - Save findings or generate report
|
|
98
|
+
|
|
99
|
+
### 4. Decision Tree Builder
|
|
100
|
+
|
|
101
|
+
**Purpose:** Guide complex decisions with branching logic
|
|
102
|
+
|
|
103
|
+
**Flow:**
|
|
104
|
+
1. **Domain** - User describes the decision space
|
|
105
|
+
2. **Generation** - Claude creates branching questions
|
|
106
|
+
3. **Journey** - User navigates tree, sees path taken
|
|
107
|
+
4. **Result** - Final recommendation with reasoning
|
|
108
|
+
5. **Sensitivity** - "What if" analysis on key choices
|
|
109
|
+
|
|
110
|
+
## StreamWeaver DSL Knowledge Base
|
|
111
|
+
|
|
112
|
+
The project includes comprehensive knowledge of StreamWeaver components:
|
|
113
|
+
|
|
114
|
+
```ruby
|
|
115
|
+
# Layout
|
|
116
|
+
columns, hstack, vstack, card, collapsible
|
|
117
|
+
|
|
118
|
+
# Input
|
|
119
|
+
checkbox, radio_group, text_field, select, button
|
|
120
|
+
|
|
121
|
+
# Display
|
|
122
|
+
header1-6, md, text, alert, badge, status_dot
|
|
123
|
+
|
|
124
|
+
# Data Visualization
|
|
125
|
+
bar_chart, line_chart, table (sortable), progress_bar
|
|
126
|
+
|
|
127
|
+
# Feedback
|
|
128
|
+
spinner, status_dot (with pulse), activity_item
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## Example: Project Health Analyzer Script
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
#!/bin/bash
|
|
135
|
+
# project_health.sh - Launched by /canvas analyze
|
|
136
|
+
|
|
137
|
+
SESSION="project-health-$$"
|
|
138
|
+
streamweaver panel "$SESSION"
|
|
139
|
+
|
|
140
|
+
# Step 1: Discovery
|
|
141
|
+
streamweaver canvas-push "$SESSION" <<'RUBY'
|
|
142
|
+
header1 "Project Health Analyzer"
|
|
143
|
+
hstack spacing: :md, align: :center do
|
|
144
|
+
spinner size: :md
|
|
145
|
+
md "**Scanning project structure...**"
|
|
146
|
+
end
|
|
147
|
+
RUBY
|
|
148
|
+
|
|
149
|
+
# Analyze project (pseudo-code)
|
|
150
|
+
LANGUAGES=$(detect_languages)
|
|
151
|
+
TEST_COVERAGE=$(calculate_coverage)
|
|
152
|
+
COMPLEXITY=$(analyze_complexity)
|
|
153
|
+
|
|
154
|
+
# Step 2: Selection - dynamically built based on findings
|
|
155
|
+
streamweaver canvas-push "$SESSION" <<RUBY
|
|
156
|
+
header1 "Project Health Analyzer"
|
|
157
|
+
md "Found: **${LANGUAGES}** project with ${FILE_COUNT} files"
|
|
158
|
+
|
|
159
|
+
card do
|
|
160
|
+
header3 "Select Analysis Areas"
|
|
161
|
+
checkbox :tests, "Test Coverage (${TEST_COVERAGE}% current)"
|
|
162
|
+
checkbox :complexity, "Code Complexity"
|
|
163
|
+
checkbox :dependencies, "Dependency Health"
|
|
164
|
+
checkbox :security, "Security Scan"
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
button "Analyze Selected", id: "btn_analyze"
|
|
168
|
+
RUBY
|
|
169
|
+
|
|
170
|
+
CHOICES=$(streamweaver canvas-wait "$SESSION")
|
|
171
|
+
# ... continue based on user choices
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
## Project Files Structure
|
|
175
|
+
|
|
176
|
+
```
|
|
177
|
+
canvas-workflows/
|
|
178
|
+
├── CLAUDE.md # Project instructions
|
|
179
|
+
├── commands/
|
|
180
|
+
│ └── canvas.md # /canvas slash command
|
|
181
|
+
├── knowledge/
|
|
182
|
+
│ ├── streamweaver-dsl.md # Component reference
|
|
183
|
+
│ └── workflow-patterns.md # Common patterns
|
|
184
|
+
└── scripts/
|
|
185
|
+
├── project_health.sh # Project analyzer
|
|
186
|
+
├── code_review.sh # Code review assistant
|
|
187
|
+
├── data_explorer.sh # Data exploration
|
|
188
|
+
└── decision_tree.sh # Decision guidance
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
## CLAUDE.md Content
|
|
192
|
+
|
|
193
|
+
```markdown
|
|
194
|
+
# Canvas Workflows Project
|
|
195
|
+
|
|
196
|
+
You have access to StreamWeaver canvas for rich interactive workflows.
|
|
197
|
+
|
|
198
|
+
## Launching Canvas
|
|
199
|
+
|
|
200
|
+
Use `/canvas` to start interactive workflows, or run scripts directly:
|
|
201
|
+
- `./scripts/project_health.sh` - Analyze project health
|
|
202
|
+
- `./scripts/code_review.sh` - Interactive code review
|
|
203
|
+
|
|
204
|
+
## Creating Dynamic UIs
|
|
205
|
+
|
|
206
|
+
Generate StreamWeaver DSL based on context. The UI should adapt to:
|
|
207
|
+
- What data is available
|
|
208
|
+
- What the user has selected
|
|
209
|
+
- What findings are discovered
|
|
210
|
+
|
|
211
|
+
## Key Patterns
|
|
212
|
+
|
|
213
|
+
1. **Progressive Disclosure** - Show complexity gradually
|
|
214
|
+
2. **Contextual Charts** - Only show relevant visualizations
|
|
215
|
+
3. **Actionable Results** - Every screen should have clear next steps
|
|
216
|
+
4. **Error Gracefully** - Show friendly messages, offer alternatives
|
|
217
|
+
|
|
218
|
+
## Available Components
|
|
219
|
+
|
|
220
|
+
[Include condensed DSL reference]
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
## Unique Results Each Time
|
|
224
|
+
|
|
225
|
+
The workflows produce different results because they:
|
|
226
|
+
|
|
227
|
+
1. **Analyze Real Data** - Project structure, code metrics, git history
|
|
228
|
+
2. **Adapt to Context** - Different charts for different findings
|
|
229
|
+
3. **User-Driven Branching** - Choices affect subsequent screens
|
|
230
|
+
4. **Time-Sensitive** - Recent commits, current test status, etc.
|
|
231
|
+
|
|
232
|
+
## Next Steps
|
|
233
|
+
|
|
234
|
+
1. Create the `/canvas` slash command skill
|
|
235
|
+
2. Build knowledge base documents for StreamWeaver DSL
|
|
236
|
+
3. Implement `project_health.sh` as first complete workflow
|
|
237
|
+
4. Test end-to-end with Claude Code
|
|
238
|
+
5. Document patterns for creating new workflows
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Canvas doc location & discovery
|
|
2
|
+
|
|
3
|
+
**Status:** shipped (`stream_weaver-j3b3`).
|
|
4
|
+
**Related:** epic `stream_weaver-mdc`.
|
|
5
|
+
**History:** this file carried a lot of exploration that isn't needed anymore — a rejected `DocIndex` registry, a canvas-server-attach mechanism, an automatic silent-resolution design that a Codex review correctly rejected as over-scoped for a problem the user hadn't actually hit. See `git log -p -- docs/plans/canvas-doc-location-and-discovery.md` if any of that ever matters again. Not repeated below.
|
|
6
|
+
|
|
7
|
+
## Shipped
|
|
8
|
+
|
|
9
|
+
- File browser in `canvas-read` (navigate to any doc without restarting) — `stream_weaver-rdh`.
|
|
10
|
+
- Multi-repo discovery: scan + a lightweight append-only registry, so a doc saved anywhere shows up without manual registration — `stream_weaver-iugu`.
|
|
11
|
+
- Delete a saved doc from the sidebar — `stream_weaver-uvaj`.
|
|
12
|
+
- Atomic doc writes — `stream_weaver-5nvz`.
|
|
13
|
+
|
|
14
|
+
## The one real problem left (now fixed)
|
|
15
|
+
|
|
16
|
+
Docs save to the global store (`~/.streamweaver/canvas`) even when working in a repo, because `DocStore.save`'s automatic resolution asks "is the *server's* cwd a repo?" — meaningless once one canvas server outlives any single repo. Today the workaround is manually copying the file out of global into the right repo after the fact.
|
|
17
|
+
|
|
18
|
+
## Spec
|
|
19
|
+
|
|
20
|
+
- Every canvas push carries the directory it was pushed from. `Session` gets a `source_dir` attribute, set from `DocStore.git_root(Dir.pwd)` computed on the *pushing* side, not the server's own cwd. Updated on each successful push — expected to change as work moves between repos over a session's life. Guard: only update it on a push that actually succeeds, so it can't end up pointing at a different repo than the DSL it's paired with.
|
|
21
|
+
- Save-as-doc's dialog (already exists, both save routes) gets a visible toggle: **This repo** (`session.source_dir`, showing the resolved path) vs. **Global** — same choice already designed for Part B, just fed by the session's remembered directory instead of the server's own cwd. "This repo" is hidden when `source_dir` is nil.
|
|
22
|
+
- This is a manual choice, not automatic — you see the destination before you click Save, so there's no silent-redirect risk to design around.
|
|
23
|
+
|
|
24
|
+
## Not in scope here
|
|
25
|
+
|
|
26
|
+
Two things surfaced while investigating this that are real but unrelated — parking them, not building them now:
|
|
27
|
+
- Duplicate canvas/canvas-read instances (multiple ports for the same work) — annoying but not something actually hit yet; revisit if it becomes a real problem.
|
|
28
|
+
- A pre-existing race in the bridge's own boot sequence where a losing duplicate boot can delete a healthy sibling's PID/socket files — real bug, independent of everything above, filed separately at low priority (`stream_weaver-5tqz`).
|
|
29
|
+
|
|
30
|
+
## Beads
|
|
31
|
+
|
|
32
|
+
`stream_weaver-e13` (extract shared Save-as-doc widget — precondition, shipped) and `stream_weaver-j3b3` (`source_dir` + toggle, shipped). `stream_weaver-16fx` (attach-or-boot) deferred — needs materially more design than scoped, not blocking this.
|
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
# Design: preview surfaces for StreamWeaver `.org` docs
|
|
2
|
+
|
|
3
|
+
Status: S1 shipped (stream_weaver-yf3a, commit 558b5b6). S2 shipped
|
|
4
|
+
(stream_weaver-m04v, commit 172409d -- built via an isolated-worktree
|
|
5
|
+
subagent, reviewed and independently re-verified live before merge). S3
|
|
6
|
+
shipped (stream_weaver-qrzw, commit f516989 -- same subagent pattern;
|
|
7
|
+
merge needed a 3-way conflict in extension/README.md resolved by hand
|
|
8
|
+
since S2 and S3's worktrees both branched before the other landed; the
|
|
9
|
+
agent's key CSP finding was independently reproduced with a fresh gist
|
|
10
|
+
before closing). S4/S5/S6 not started. Tracked via `bd` issues, not
|
|
11
|
+
OpenSpec -- see "On OpenSpec" below for why that tool is no longer part
|
|
12
|
+
of this project's
|
|
13
|
+
workflow.
|
|
14
|
+
|
|
15
|
+
## The gap that started this
|
|
16
|
+
|
|
17
|
+
Two renderers exist today. Neither is wired to "preview an `.org` file
|
|
18
|
+
directly":
|
|
19
|
+
|
|
20
|
+
- `streamweaver canvas-read` (`lib/stream_weaver/canvas/reader.rb`) is
|
|
21
|
+
already a mature local doc browser -- live filesystem `/browse` with
|
|
22
|
+
breadcrumbs, `/open?path=` for any file, `/export` to standalone HTML,
|
|
23
|
+
`/save-doc` promoting to `.rb`/`.org`. But it is `.rb`-only: `FileList.build`
|
|
24
|
+
(`reader.rb:27`), `GET /open` (`reader.rb:259`), and `render_doc` never
|
|
25
|
+
detect or read `.org` at all. Zero support, not partial.
|
|
26
|
+
- The browser extension's Opal sandbox (`extension/sandbox.js`) is the only
|
|
27
|
+
place `.org` gets rendered outside a Ruby process, but `content.js` is
|
|
28
|
+
wired to exactly one trigger: a content script matched to
|
|
29
|
+
`"https://github.com/*"` in `manifest.json`. No local-file entry point.
|
|
30
|
+
|
|
31
|
+
Reframe: this isn't "build a new renderer," it's "wire the two renderers
|
|
32
|
+
that already exist to more entry points." Every option below is evaluated
|
|
33
|
+
on that basis.
|
|
34
|
+
|
|
35
|
+
## Audience segmentation
|
|
36
|
+
|
|
37
|
+
1. **Solo dev w/ StreamWeaver + agents (Claude Code etc.) installed** --
|
|
38
|
+
fastest path should be native, no distribution concern.
|
|
39
|
+
2. **Ruby-literate teammates without a running canvas server** -- want to
|
|
40
|
+
read a doc without booting anything.
|
|
41
|
+
3. **Non-Rubyist colleagues** (e.g. SharePoint viewers at a corporate
|
|
42
|
+
employer) -- need
|
|
43
|
+
zero-Ruby-install rendering. The extension already solves the "no Ruby"
|
|
44
|
+
problem architecturally (Opal ships the compiler as JS); the gap is
|
|
45
|
+
which host pages it activates on.
|
|
46
|
+
4. **Windows users / broader popularization** -- Ruby install friction on
|
|
47
|
+
Windows is real (RubyInstaller, DevKit, native gem compiles) in a way it
|
|
48
|
+
isn't on mac/linux. A pure-JS distribution removes that entirely for
|
|
49
|
+
*viewing* (authoring can stay Ruby, or skip Ruby altogether if an agent
|
|
50
|
+
generates `.org` directly).
|
|
51
|
+
5. **Emacs/org-mode natives** -- org-mode already renders generic org
|
|
52
|
+
locally, but not StreamWeaver's DSL semantics (callouts, sidebar_toc,
|
|
53
|
+
doc_header pills, `.sw-mermaid`, cards) -- fidelity needs the actual
|
|
54
|
+
StreamWeaver pipeline, not org-mode's own renderer.
|
|
55
|
+
|
|
56
|
+
## Surface options
|
|
57
|
+
|
|
58
|
+
### S1 -- `canvas-read` `.org` support
|
|
59
|
+
Teach `Reader` the same content-based detection `content.js`/`sandbox.js`
|
|
60
|
+
already use (`#+STREAMWEAVER_DSL:` marker), and run detected `.org` through
|
|
61
|
+
`Org::Reader.to_dsl` before `instance_eval`. Four confirmed touch points
|
|
62
|
+
(per `canvas-docs-discovery-export-fidelity`'s review, see Coordination
|
|
63
|
+
outcome below): `FileList.build` (`reader.rb:27`), `browse_entries`
|
|
64
|
+
(`reader.rb:154`), `GET /open`'s guard (`reader.rb:259`), and `render_doc`
|
|
65
|
+
itself, which needs an actual `Org::Reader.to_dsl` call before
|
|
66
|
+
`instance_eval`, not just a filter change.
|
|
67
|
+
|
|
68
|
+
- Cost: small. Reuses all of `/browse`'s directory-walking, breadcrumbs,
|
|
69
|
+
and export machinery for free -- the moment `.org` is recognized, folder
|
|
70
|
+
browsing works for `.org` too, no new UI.
|
|
71
|
+
- Touches: `lib/stream_weaver/canvas/reader.rb`, possibly `doc_store.rb`.
|
|
72
|
+
**Coordinate with `canvas-docs-discovery-export-fidelity` before
|
|
73
|
+
starting** -- that session is actively reworking org/rb export and
|
|
74
|
+
global/local save UX in this same neighborhood (message sent, awaiting
|
|
75
|
+
reply as of this doc's writing).
|
|
76
|
+
- Serves audience 1 (and the Emacs "cheap" recipe below, downstream).
|
|
77
|
+
|
|
78
|
+
### S2 -- Extension: local-file preview
|
|
79
|
+
A drag-drop or file-picker target on `viewer.html` feeding the existing
|
|
80
|
+
sandbox pipeline (`sandbox.js` doesn't care where `{source, name}` comes
|
|
81
|
+
from -- `content.js` is just today's only supplier).
|
|
82
|
+
|
|
83
|
+
- Cost: small. Zero renderer changes.
|
|
84
|
+
- Still requires "install the extension" as a one-time step -- real, if
|
|
85
|
+
small, friction, worth naming honestly rather than calling this
|
|
86
|
+
frictionless.
|
|
87
|
+
- Serves audience 3, no server/GitHub/Ruby required.
|
|
88
|
+
|
|
89
|
+
### S3 -- Extension: Gist support
|
|
90
|
+
Add `"https://gist.github.com/*"` to `manifest.json`'s `content_scripts`,
|
|
91
|
+
and a second detection path in `content.js` -- gist pages don't embed the
|
|
92
|
+
same `codeViewBlobLayoutRoute.StyledBlob` JSON a blob page does, so this
|
|
93
|
+
needs its own verification, not an assumption. Likely closer to the
|
|
94
|
+
existing raw-URL fallback (`rawUrlFromPage`) than the primary JSON scrape,
|
|
95
|
+
since gist raw content sits behind a predictable
|
|
96
|
+
`gist.githubusercontent.com/.../raw/...` URL.
|
|
97
|
+
|
|
98
|
+
- Distribution win: publishing a gist needs no repo, no push workflow, no
|
|
99
|
+
CI -- the lowest-friction *authoring* channel on this list. This is the
|
|
100
|
+
best "popularize the format" lever here: write a doc, paste as a gist,
|
|
101
|
+
share a URL, anyone with the extension sees it rendered in full glory.
|
|
102
|
+
- Cost: moderate -- mostly the second detection path, needs live
|
|
103
|
+
verification the way the GitHub path got (this repo does not accept
|
|
104
|
+
curl-level self-assessment for UI surfaces; browser-verify against a
|
|
105
|
+
real gist before calling it done).
|
|
106
|
+
- Serves audience 3/4 with the best adoption-per-effort ratio of anything
|
|
107
|
+
here.
|
|
108
|
+
|
|
109
|
+
### On OpenSpec
|
|
110
|
+
|
|
111
|
+
The prior draft of this doc said "scaffold an OpenSpec change" as the next
|
|
112
|
+
step, because `~/work/rstreamlit/CLAUDE.md` (a parent-directory file, not
|
|
113
|
+
part of this git repo -- `rstreamlit` itself has no `.git`) carried a
|
|
114
|
+
managed block routing any "new capability / architecture shift" request
|
|
115
|
+
through `openspec/AGENTS.md`. Investigated and removed:
|
|
116
|
+
|
|
117
|
+
- That file was created by `openspec init` on 2025-11-07, the project's
|
|
118
|
+
actual inception date (`openspec/changes/create-stream-weaver-gem` is the
|
|
119
|
+
original gem-bootstrapping proposal, same date).
|
|
120
|
+
- It was used exactly three times total across the project's life
|
|
121
|
+
(`create-stream-weaver-gem`, `add-route-tabs`, and an incomplete
|
|
122
|
+
`add-isomorphic-ruby` with no `proposal.md` at all).
|
|
123
|
+
- `openspec/specs/` -- the "current truth, built and deployed" directory
|
|
124
|
+
the three-stage workflow is supposed to graduate into -- is empty.
|
|
125
|
+
`openspec/changes/archive/` is empty too. Nothing has ever completed
|
|
126
|
+
OpenSpec's own lifecycle once.
|
|
127
|
+
- This repo's own `CLAUDE.md` mandates `bd` (beads) for all task tracking
|
|
128
|
+
in terms that directly conflict with OpenSpec's `proposal.md`/`tasks.md`
|
|
129
|
+
model ("do NOT use TodoWrite, TaskCreate, or markdown TODO lists").
|
|
130
|
+
Recent planning work (`features/route-tabs.feature`,
|
|
131
|
+
`*.context.md` files) is using a third, newer convention. Three
|
|
132
|
+
overlapping systems, only one (`bd`) actively enforced by this repo.
|
|
133
|
+
|
|
134
|
+
Removed `~/work/rstreamlit/CLAUDE.md` (the file was nothing but that one
|
|
135
|
+
managed block). Left `openspec/` itself untouched -- it holds real
|
|
136
|
+
historical design content (the route-tabs proposal in particular has a
|
|
137
|
+
genuine Codex review write-up worth keeping) -- ask if you also want that
|
|
138
|
+
directory cleaned up or archived somewhere; not doing that unprompted.
|
|
139
|
+
|
|
140
|
+
Planning for this initiative now follows this repo's actual convention:
|
|
141
|
+
`docs/plans/*.md` for design, `bd` issues for tracked work.
|
|
142
|
+
|
|
143
|
+
### S4 -- SharePoint ("my immediate use") -- NOT a new integration
|
|
144
|
+
SharePoint document libraries are architecturally unlike GitHub/gist: no
|
|
145
|
+
guaranteed raw-text-in-page-JSON, tenant-specific domains, Office-viewer
|
|
146
|
+
semantics, and enterprise extension-allowlisting is an IT decision, not
|
|
147
|
+
just an engineering one. Building a SharePoint content script would be
|
|
148
|
+
materially harder and more fragile than S3, for a worse cost/benefit.
|
|
149
|
+
|
|
150
|
+
`Reader#export`'s `?offline=1` mode already exists for exactly this case
|
|
151
|
+
(`reader.rb:286-289` -- the comment literally says "SharePoint's HTML
|
|
152
|
+
preview"): render once, inline mermaid, no CDN, no CSP violations, upload
|
|
153
|
+
the resulting static HTML like any other document. SharePoint's own
|
|
154
|
+
preview then just displays a file -- no extension, no content script, no
|
|
155
|
+
auth story.
|
|
156
|
+
|
|
157
|
+
- Verdict: don't build SharePoint integration now. If there's a gap it's
|
|
158
|
+
discoverability/automation of `/export?offline=1` -- e.g. a
|
|
159
|
+
`streamweaver export --offline` CLI surface, or a one-command
|
|
160
|
+
export-and-upload -- worth doing, kept in scope as a small follow-up.
|
|
161
|
+
- **Explicitly delayed, not rejected**: a SharePoint doc that stays
|
|
162
|
+
"alive" (round-trips edits back into the source, the way a `.org` file
|
|
163
|
+
in a repo does) is a materially bigger effort than static export --
|
|
164
|
+
it would need real read-back-and-reconcile logic against a format
|
|
165
|
+
SharePoint doesn't understand natively, not just a render pass. Worth
|
|
166
|
+
revisiting once the `.org` round-trip story elsewhere (Writer/Reader) is
|
|
167
|
+
more battle-tested, not now.
|
|
168
|
+
|
|
169
|
+
### S5 -- Opal-as-npm-package
|
|
170
|
+
Decouple "can render a StreamWeaver doc" from "has the extension" or "has
|
|
171
|
+
Ruby" -- a portable JS module any host could embed: a VS Code extension, an
|
|
172
|
+
Obsidian plugin, a static site generator, Emacs's `xwidget-webkit` (Emacs
|
|
173
|
+
28+, mac/linux builds with the right compile flags -- not universal), or a
|
|
174
|
+
bare `<script>` tag.
|
|
175
|
+
|
|
176
|
+
- Cost: real, not small. `sw-runtime.js` today is shaped for the
|
|
177
|
+
extension's specific constraints -- `#app-container`, the sandboxed-page
|
|
178
|
+
CSP split (`viewer.js`/`sandbox.js`'s two-frame dance exists
|
|
179
|
+
specifically to dodge MV3's `unsafe-eval` restriction, a constraint that
|
|
180
|
+
doesn't exist outside a Chrome extension). Packaging this as a general
|
|
181
|
+
module means defining a real embeddable API (something like
|
|
182
|
+
`StreamWeaverRender.render(source, {container, theme}) -> {html, css}`),
|
|
183
|
+
decoupling from the two-frame sandbox dance, and taking on real
|
|
184
|
+
versioning/publishing discipline. This is its own mini-project, not a
|
|
185
|
+
line item.
|
|
186
|
+
- Distribution win if pursued: the actual lever for "Windows users" and
|
|
187
|
+
broader popularity -- removes the Ruby-on-the-viewer requirement
|
|
188
|
+
entirely and stops being Chrome-only.
|
|
189
|
+
- Verdict: valuable, sequence LAST. Its ROI depends on S1-S3 actually
|
|
190
|
+
generating demand for wider distribution first -- textbook SDRD: don't
|
|
191
|
+
build the general platform before the specific uses prove the demand.
|
|
192
|
+
|
|
193
|
+
### S6 -- Emacs integration
|
|
194
|
+
Two different asks bundled under one name -- **revised: neither is gated
|
|
195
|
+
on S5**. The original draft assumed the "rich" version needed the npm
|
|
196
|
+
package to avoid shelling out to Ruby per keystroke; corrected -- anyone
|
|
197
|
+
running Emacs in this era can be assumed to have Ruby available, and
|
|
198
|
+
elisp can invoke it directly, no JS toolchain required for either variant:
|
|
199
|
+
|
|
200
|
+
- **(a) Cheap**: an elisp function shelling out to `streamweaver export
|
|
201
|
+
--offline` (once it exists) or a local canvas-read render, opening the
|
|
202
|
+
result via `browse-url`/`xwidget-webkit`. ~20 lines of elisp, doesn't
|
|
203
|
+
even live in this repo, near-free once S1 ships. Worth documenting as a
|
|
204
|
+
recipe, not worth writing StreamWeaver-side code for.
|
|
205
|
+
- **(b) Rich**: an `xwidget-webkit`-embedded preview pane that re-invokes
|
|
206
|
+
the same Ruby export/render on save and reloads the webview -- live-feeling
|
|
207
|
+
without needing a JS-native renderer. More elisp work than (a), but still
|
|
208
|
+
just elisp + the existing Ruby CLI, no dependency on S5.
|
|
209
|
+
- Verdict: (a) is a recipe to write once S1 ships. (b) is a real but
|
|
210
|
+
self-contained elisp project, independent of everything else on this
|
|
211
|
+
list -- can happen whenever, not blocked on S5.
|
|
212
|
+
|
|
213
|
+
## Decision (2026-08-17)
|
|
214
|
+
|
|
215
|
+
Build S1, S2, S3. S4 stays as-is (export/upload), with a small
|
|
216
|
+
export-automation follow-up in scope and the "alive" round-trip version
|
|
217
|
+
explicitly delayed. S5 stays out of scope until S1-S3 show demand. S6 is
|
|
218
|
+
a standalone elisp recipe/project, not blocked on anything above -- pick
|
|
219
|
+
up whenever, independent sequencing.
|
|
220
|
+
|
|
221
|
+
## Recommended sequencing (Pareto + SDRD)
|
|
222
|
+
|
|
223
|
+
1. **S1** -- cheapest, closes the daily personal gap, infrastructure for
|
|
224
|
+
S6(a). Coordination cleared with both peer sessions (see below).
|
|
225
|
+
2. **S2** -- cheap, independent of S1, unlocks "no Ruby, no GitHub"
|
|
226
|
+
preview immediately, stepping stone to S3.
|
|
227
|
+
3. **S3** -- best popularization-per-effort on this list; builds on S2's
|
|
228
|
+
detection logic and the extension's existing raw-URL fallback.
|
|
229
|
+
4. **S4 follow-up (optional, small)** -- CLI ergonomics /
|
|
230
|
+
export-and-upload automation for `/export --offline`, which already
|
|
231
|
+
ships. Not blocking S1-S3.
|
|
232
|
+
5. **S5** -- the one genuine platform bet here; sequence after S1-S3 show
|
|
233
|
+
real usage, not before.
|
|
234
|
+
6. **S6** -- pure elisp + existing Ruby CLI, no StreamWeaver-side code
|
|
235
|
+
needed either variant; can happen any time, independent of S1-S5.
|
|
236
|
+
|
|
237
|
+
## Design Triumvirate check
|
|
238
|
+
|
|
239
|
+
- **Matt's Law**: S1/S2/S3 all reuse existing, already-findable surfaces
|
|
240
|
+
(a directory browser, a drag target, a familiar gist URL) instead of
|
|
241
|
+
inventing new navigation.
|
|
242
|
+
- **Forrest's Law**: sequencing is explicitly zero-friction-first -- each
|
|
243
|
+
of S1-S3 converts an existing rendering capability into a single-action
|
|
244
|
+
trigger (open a folder / drop a file / click a gist link), no perk
|
|
245
|
+
hidden behind a new habit.
|
|
246
|
+
- **Gloria's Law**: none of S1-S3 introduce a "want-to" threshold --
|
|
247
|
+
they're one-shot actions, not new workflows to adopt.
|
|
248
|
+
|
|
249
|
+
## Coordination outcome
|
|
250
|
+
|
|
251
|
+
`canvas-docs-discovery-export-fidelity` replied: no overlap, no objection,
|
|
252
|
+
S1 is squarely out of their scope. Their in-progress work is `DocStore.save`
|
|
253
|
+
(a `scope:` param for global-vs-repo choice) and the Save-as-doc modal /
|
|
254
|
+
`POST /save-doc` routes -- none of it touches `.org` naming/detection,
|
|
255
|
+
which they say is already-merged prior work (not theirs, not currently
|
|
256
|
+
owned by anyone). They flagged one correction to this doc's S1 cost
|
|
257
|
+
estimate: `browse_entries` (`reader.rb:154`,
|
|
258
|
+
`files: rest.select { |e| e.end_with?('.rb') }`) is a fourth `.rb`-hardcoded
|
|
259
|
+
site, on top of `FileList.build`, `GET /open`'s guard, and `render_doc`
|
|
260
|
+
assuming Ruby syntax throughout (not just a filter -- `.org` needs its own
|
|
261
|
+
`Org::Reader.to_dsl` code path there, confirmed above). Practical note from
|
|
262
|
+
them: this checkout has been shared across sessions before and a commit
|
|
263
|
+
landed on the wrong branch once -- sanity-check `git branch --show-current`
|
|
264
|
+
+ `git log --oneline -3` before committing.
|
|
265
|
+
|
|
266
|
+
`export streamweaver doc to org` also replied: idle on this front -- their
|
|
267
|
+
org-export work (Writer/Reader library + CLI, Save-as-Org UI/DocStore `.org`
|
|
268
|
+
support) finished, merged, and pushed a couple days before this session
|
|
269
|
+
started (their `git log -1` shows this session's own `28bfb6c` as latest,
|
|
270
|
+
confirming nothing pending). Not touching `writer.rb`, `doc_store.rb`'s org
|
|
271
|
+
save branch, or any org-detection-for-rendering code, no plans to. Safe to
|
|
272
|
+
proceed. Two things they flagged to fold in rather than discover later:
|
|
273
|
+
|
|
274
|
+
1. If cross-surface preview UX ever cares about *where* a `.org` lives (not
|
|
275
|
+
just how it renders), that's `canvas-docs-discovery-export-fidelity`'s
|
|
276
|
+
repo-vs-`~/.streamweaver` save-location design doc to sync with --
|
|
277
|
+
roadmap only, not built yet, per that session's own earlier message.
|
|
278
|
+
Not a concern for S1/S2/S3 as scoped above (none of them relocate
|
|
279
|
+
files), but worth remembering if a later surface (e.g. a "browse my
|
|
280
|
+
saved docs" view) needs to resolve doc location.
|
|
281
|
+
2. **Constraint to hold going forward**: anything that touches saved `.org`
|
|
282
|
+
output must keep `#+STREAMWEAVER_DSL: 1` as the literal first line, or
|
|
283
|
+
detection breaks silently across every surface in this doc (`content.js`,
|
|
284
|
+
`sandbox.js`, and S1's planned `Reader` detection all key off it being
|
|
285
|
+
line one). This is the same class of bug `c1df5f6` already fixed once
|
|
286
|
+
(`DocStore.stamp` corrupting `.org`'s first line) -- any new save/rewrite
|
|
287
|
+
path for `.org` (S1's `Reader`, a future S5 embed API, etc.) needs the
|
|
288
|
+
same defense-in-depth guard `doc_store.rb:167` already has.
|
|
289
|
+
|
|
290
|
+
## Next step
|
|
291
|
+
|
|
292
|
+
Greenlit. Tracked as `bd` issues (see repo issue tracker), implementation
|
|
293
|
+
starting with S1.
|