scriptorium 0.6.1 → 0.7.2
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 +4 -4
- data/assets/icons/social/reddit.png +0 -0
- data/assets/icons/social/x-logo.png +0 -0
- data/assets/imagenotfound.jpg +0 -0
- data/bin/sblog +84 -5
- data/bin/scriptorium +1 -0
- data/doc/anti-amnesia/20250727-054000-scriptorium-overview.md +0 -1
- data/doc/anti-amnesia/20250727-123000-anti-amnesia-conventions.md +0 -29
- data/doc/anti-amnesia/20250727-172600-cursor-rbenv-ruby-version-mystery.md +0 -19
- data/doc/anti-amnesia/20250727-172900-ai-cognitive-assessment-capabilities.md +1 -1
- data/doc/anti-amnesia/20250728-124243-aaa-syntax-clarification.md +1 -1
- data/doc/anti-amnesia/20250729-210000-reddit-autopost-integration-complete.md +1 -1
- data/doc/anti-amnesia/20250804-190500-cognitive-loop-bug.md +0 -10
- data/doc/anti-amnesia/20250804-190700-anti-amnesia-timestamping-fix.md +1 -4
- data/doc/anti-amnesia/20250901-211714-codemirror-integration-and-web-tests.md +172 -0
- data/doc/anti-amnesia/20250902-002402-backup-restore-system.md +126 -0
- data/doc/anti-amnesia/20250907-203339-backup-metadata-implementation.md +66 -0
- data/doc/imported/0001-elixir-conf-2014/metadata.txt +7 -0
- data/doc/imported/0001-elixir-conf-2014/post.html +37 -0
- data/doc/imported/0001-elixir-conf-2014/source.lt3 +22 -0
- data/doc/imported/0002-programmers-and-word-processing/metadata.txt +7 -0
- data/doc/imported/0002-programmers-and-word-processing/post.html +192 -0
- data/doc/imported/0002-programmers-and-word-processing/source.lt3 +146 -0
- data/doc/imported/0003-how-to-turn-your-brain-sideways/metadata.txt +7 -0
- data/doc/imported/0003-how-to-turn-your-brain-sideways/post.html +60 -0
- data/doc/imported/0003-how-to-turn-your-brain-sideways/source.lt3 +40 -0
- data/doc/imported/0004-upcoming-lone-star-ruby-conference/metadata.txt +7 -0
- data/doc/imported/0004-upcoming-lone-star-ruby-conference/post.html +42 -0
- data/doc/imported/0004-upcoming-lone-star-ruby-conference/source.lt3 +24 -0
- data/doc/imported/0005-elixir-conf-2015-announced/metadata.txt +7 -0
- data/doc/imported/0005-elixir-conf-2015-announced/post.html +30 -0
- data/doc/imported/0005-elixir-conf-2015-announced/source.lt3 +16 -0
- data/doc/imported/0006-ruby-for-dinosaurs/metadata.txt +7 -0
- data/doc/imported/0006-ruby-for-dinosaurs/post.html +43 -0
- data/doc/imported/0006-ruby-for-dinosaurs/source.lt3 +27 -0
- data/doc/imported/0007-phoenix-isnt-rails/metadata.txt +7 -0
- data/doc/imported/0007-phoenix-isnt-rails/post.html +116 -0
- data/doc/imported/0007-phoenix-isnt-rails/source.lt3 +87 -0
- data/doc/imported/0008-concerning-the-term-monkeypatching/metadata.txt +7 -0
- data/doc/imported/0008-concerning-the-term-monkeypatching/post.html +129 -0
- data/doc/imported/0008-concerning-the-term-monkeypatching/source.lt3 +92 -0
- data/doc/imported/0009-announcement-coming-soon/metadata.txt +7 -0
- data/doc/imported/0009-announcement-coming-soon/post.html +33 -0
- data/doc/imported/0009-announcement-coming-soon/source.lt3 +19 -0
- data/doc/imported/0010-immutable-data-ditching-the-wax-tablet/metadata.txt +7 -0
- data/doc/imported/0010-immutable-data-ditching-the-wax-tablet/post.html +175 -0
- data/doc/imported/0010-immutable-data-ditching-the-wax-tablet/source.lt3 +139 -0
- data/doc/imported/0011-computer-science-as-a-lost-art/metadata.txt +7 -0
- data/doc/imported/0011-computer-science-as-a-lost-art/post.html +139 -0
- data/doc/imported/0011-computer-science-as-a-lost-art/source.lt3 +104 -0
- data/doc/imported/0012-ruby-day-in-turin-italy/metadata.txt +7 -0
- data/doc/imported/0012-ruby-day-in-turin-italy/post.html +42 -0
- data/doc/imported/0012-ruby-day-in-turin-italy/source.lt3 +24 -0
- data/doc/imported/0013-rubyday-was-a-success/metadata.txt +7 -0
- data/doc/imported/0013-rubyday-was-a-success/post.html +44 -0
- data/doc/imported/0013-rubyday-was-a-success/source.lt3 +27 -0
- data/doc/imported/0014-working-on-the-blogging-software/metadata.txt +7 -0
- data/doc/imported/0014-working-on-the-blogging-software/post.html +63 -0
- data/doc/imported/0014-working-on-the-blogging-software/source.lt3 +41 -0
- data/doc/imported/0015-ok-its-not-really-a-lost-art/metadata.txt +7 -0
- data/doc/imported/0015-ok-its-not-really-a-lost-art/post.html +172 -0
- data/doc/imported/0015-ok-its-not-really-a-lost-art/source.lt3 +134 -0
- data/doc/imported/0016-an-in-operator-for-ruby/metadata.txt +7 -0
- data/doc/imported/0016-an-in-operator-for-ruby/post.html +155 -0
- data/doc/imported/0016-an-in-operator-for-ruby/source.lt3 +106 -0
- data/doc/imported/0017-the-forgotten-mathematician/metadata.txt +7 -0
- data/doc/imported/0017-the-forgotten-mathematician/post.html +161 -0
- data/doc/imported/0017-the-forgotten-mathematician/source.lt3 +119 -0
- data/doc/imported/0018-ruby-puns/metadata.txt +7 -0
- data/doc/imported/0018-ruby-puns/post.html +46 -0
- data/doc/imported/0018-ruby-puns/source.lt3 +28 -0
- data/doc/imported/0019-custom-exceptions-via-metaprogramming/metadata.txt +7 -0
- data/doc/imported/0019-custom-exceptions-via-metaprogramming/post.html +138 -0
- data/doc/imported/0019-custom-exceptions-via-metaprogramming/source.lt3 +101 -0
- data/doc/imported/0020-fffff/metadata.txt +7 -0
- data/doc/imported/0020-fffff/post.html +24 -0
- data/doc/imported/0020-fffff/source.lt3 +12 -0
- data/doc/imported/0021-trying-ror-yet-again/metadata.txt +7 -0
- data/doc/imported/0021-trying-ror-yet-again/post.html +26 -0
- data/doc/imported/0021-trying-ror-yet-again/source.lt3 +12 -0
- data/doc/imported/0023-doctor-sleep/metadata.txt +7 -0
- data/doc/imported/0023-doctor-sleep/post.html +63 -0
- data/doc/imported/0023-doctor-sleep/source.lt3 +44 -0
- data/doc/imported/0024-just-a-test/metadata.txt +7 -0
- data/doc/imported/0024-just-a-test/post.html +24 -0
- data/doc/imported/0024-just-a-test/source.lt3 +12 -0
- data/doc/imported/import_summary.txt +98 -0
- data/doc/livetext-informal-spec.txt +65 -0
- data/doc/myuserdoc/ch-0.lt3 +31 -0
- data/doc/myuserdoc/ch-1.lt3 +37 -0
- data/doc/myuserdoc/ch-10.lt3 +22 -0
- data/doc/myuserdoc/ch-2.lt3 +37 -0
- data/doc/myuserdoc/ch-3.lt3 +19 -0
- data/doc/myuserdoc/ch-4.lt3 +43 -0
- data/doc/myuserdoc/ch-5.lt3 +22 -0
- data/doc/myuserdoc/ch-6.lt3 +19 -0
- data/doc/myuserdoc/ch-7.lt3 +16 -0
- data/doc/myuserdoc/ch-8.lt3 +13 -0
- data/doc/myuserdoc/ch-9.lt3 +19 -0
- data/doc/myuserdoc/tweak.rb +18 -0
- data/doc/{userdoc-toc.txt → myuserdoc/userdoc-toc.txt} +27 -27
- data/doc/old-posts/0001-elixir-conf-2014.lt3 +24 -0
- data/doc/old-posts/0002-programmers-and-word-processing.lt3 +150 -0
- data/doc/old-posts/0003-how-to-turn-your-brain-sideways.lt3 +43 -0
- data/doc/old-posts/0004-upcoming-lone-star-ruby-conference.lt3 +26 -0
- data/doc/old-posts/0005-elixir-conf-2015-announced.lt3 +17 -0
- data/doc/old-posts/0006-ruby-for-dinosaurs.lt3 +30 -0
- data/doc/old-posts/0007-phoenix-isnt-rails.lt3 +90 -0
- data/doc/old-posts/0008-concerning-the-term-monkeypatching.lt3 +105 -0
- data/doc/old-posts/0009-announcement-coming-soon.lt3 +20 -0
- data/doc/old-posts/0010-immutable-data-ditching-the-wax-tablet.lt3 +142 -0
- data/doc/old-posts/0011-computer-science-as-a-lost-art.lt3 +117 -0
- data/doc/old-posts/0012-ruby-day-in-turin-italy.lt3 +26 -0
- data/doc/old-posts/0013-rubyday-was-a-success.lt3 +28 -0
- data/doc/old-posts/0014-working-on-the-blogging-software.lt3 +42 -0
- data/doc/old-posts/0015-ok-its-not-really-a-lost-art.lt3 +137 -0
- data/doc/old-posts/0016-an-in-operator-for-ruby.lt3 +142 -0
- data/doc/old-posts/0017-the-forgotten-mathematician.lt3 +129 -0
- data/doc/old-posts/0018-ruby-puns.lt3 +31 -0
- data/doc/old-posts/0019-custom-exceptions-via-metaprogramming.lt3 +116 -0
- data/doc/old-posts/0021-trying-ror-yet-again.lt3 +35 -0
- data/doc/old-posts/0023-doctor-sleep.lt3 +43 -0
- data/doc/old-posts/0024-just-a-test.lt3 +12 -0
- data/doc/old-posts/0025-trying-another-post.lt3 +12 -0
- data/doc/old-repo +1 -0
- data/doc/reddit_integration.md +2 -2
- data/doc/user.lt3 +0 -3
- data/lib/scriptorium/api.rb +1811 -78
- data/lib/scriptorium/banner_svg.rb +55 -68
- data/lib/scriptorium/contract.rb +3 -2
- data/lib/scriptorium/exceptions.rb +133 -102
- data/lib/scriptorium/helpers.rb +282 -82
- data/lib/scriptorium/post.rb +81 -17
- data/lib/scriptorium/reddit.rb +1 -1
- data/lib/scriptorium/repo.rb +478 -164
- data/lib/scriptorium/standard_files.rb +30 -396
- data/lib/scriptorium/support/common_js/clipboard.js +35 -0
- data/lib/scriptorium/support/common_js/content-loader.js +187 -0
- data/lib/scriptorium/support/common_js/navigation.js +52 -0
- data/lib/scriptorium/support/common_js/syntax-highlighting.js +27 -0
- data/lib/scriptorium/support/config/reddit_template.txt +17 -0
- data/{test/scriptorium-TEST-1754622690-146/views/sample → lib/scriptorium/support}/config/social.txt +1 -0
- data/lib/scriptorium/support/highlight/css.txt +2 -0
- data/lib/scriptorium/support/highlight/custom.css +119 -0
- data/lib/scriptorium/support/highlight/js.txt +1 -0
- data/lib/scriptorium/support/post_index/config.txt +15 -0
- data/lib/scriptorium/support/post_index/style.css +55 -0
- data/lib/scriptorium/support/templates/index_entry.lt3 +16 -0
- data/{test/scriptorium-TEST-1754622690-146/themes/standard/initial/post.lt3 → lib/scriptorium/support/templates/initial_post.lt3} +5 -5
- data/lib/scriptorium/support/templates/post.lt3 +104 -0
- data/{test/scriptorium-TEST-1754622690-146/themes/standard/layout/config/header.txt → lib/scriptorium/support/theme/header.lt3} +1 -1
- data/lib/scriptorium/theme.rb +83 -70
- data/lib/scriptorium/version.rb +2 -2
- data/lib/scriptorium/view.rb +194 -149
- data/lib/scriptorium.rb +24 -1
- data/lib/skeleton.rb +4 -1
- data/scriptorium.gemspec +2 -1
- data/test/WEB_INTEGRATION_README.md +196 -0
- data/test/all +40 -0
- data/test/banner_svg/unit.rb +267 -35
- data/test/config/deployment.txt +5 -0
- data/test/integration/integration_test.rb +7 -7
- data/test/integration/preview_flow_test.rb +94 -0
- data/test/livetext_plugin_test.rb +453 -182
- data/test/manual/banner-tests/test01.html +82 -18
- data/test/manual/banner-tests/test02.html +82 -18
- data/test/manual/banner-tests/test03.html +82 -18
- data/test/manual/banner-tests/test04.html +89 -25
- data/test/manual/banner-tests/test05.html +89 -25
- data/test/manual/banner-tests/test06.html +89 -25
- data/test/manual/banner-tests/test07.html +89 -25
- data/test/manual/banner-tests/test08.html +82 -18
- data/test/manual/banner-tests/test09.html +82 -18
- data/test/manual/banner-tests/test10.html +82 -18
- data/test/manual/banner-tests/test11.html +82 -18
- data/test/manual/banner-tests/test12.html +82 -18
- data/test/manual/banner-tests/test13.html +82 -18
- data/test/manual/banner-tests/test14.html +82 -18
- data/test/manual/banner-tests/test15.html +82 -18
- data/test/manual/banner-tests/test16.html +82 -18
- data/test/manual/banner-tests/test17.html +82 -18
- data/test/manual/banner-tests/test18.html +90 -26
- data/test/manual/banner-tests/test19.html +90 -26
- data/test/manual/banner-tests/test20.html +90 -26
- data/test/manual/banner-tests/test21.html +90 -26
- data/test/manual/banner-tests/test22.html +90 -26
- data/test/manual/banner-tests/test23.html +90 -26
- data/test/manual/banner-tests/test24.html +90 -26
- data/test/manual/banner-tests/test25.html +89 -25
- data/test/manual/banner_environment.rb +15 -2
- data/test/manual/codemirror_demo.html +773 -0
- data/test/manual/create_posts_for_web.rb +114 -0
- data/test/manual/preview_manual_test.rb +129 -0
- data/test/manual/test_banner_features.rb +14 -14
- data/test/manual/test_banner_integration.rb +115 -0
- data/test/manual/test_banner_radial.rb +87 -0
- data/test/manual/test_syntax_highlighting.rb +60 -40
- data/test/support/preview_utils.rb +88 -0
- data/test/test_gem_assets.rb +48 -0
- data/test/test_helpers.rb +10 -0
- data/test/tui_editor_integration_test.rb +15 -15
- data/test/tui_integration_test.rb +687 -441
- data/test/unit/api.rb +757 -37
- data/test/unit/asset_management.rb +195 -221
- data/test/unit/backup_test.rb +451 -0
- data/test/unit/contract_test.rb +1 -23
- data/test/unit/core.rb +415 -61
- data/test/unit/deploy_config_test.rb +248 -0
- data/test/unit/deploy_test.rb +312 -21
- data/test/unit/edit_post_test.rb +168 -0
- data/test/unit/gem_asset_management.rb +36 -42
- data/test/unit/livetext_basic.rb +23 -35
- data/test/unit/livetext_compatibility.rb +7 -14
- data/test/unit/parse_cmd_test.rb +260 -0
- data/test/unit/{symlink_test.rb → permalink_copy_test.rb} +47 -49
- data/test/unit/post.rb +91 -26
- data/test/unit/post_index_config_test.rb +258 -0
- data/test/unit/post_state_helpers_test.rb +137 -0
- data/test/unit/read_commented_file_test.rb +8 -6
- data/test/unit/repo.rb +75 -54
- data/test/unit/social_test.rb +41 -44
- data/test/unit/syntax_highlighting.rb +70 -0
- data/test/unit/theme_management_test.rb +91 -0
- data/test/unit/view.rb +79 -12
- data/test/unit/widgets.rb +8 -8
- data/test/web_integration_test.rb +231 -0
- data/test/web_test_helper.rb +218 -0
- data/test/web_workflow_test.rb +527 -0
- data/ui/tui/bin/scriptorium +885 -415
- data/ui/web/app/app.rb +1398 -176
- data/ui/web/app/assets/livetext_mode.js +244 -0
- data/ui/web/app/error_helpers.rb +16 -16
- data/ui/web/app/views/advanced_config.erb +8 -2
- data/ui/web/app/views/asset_management.erb +56 -0
- data/ui/web/app/views/backup_management.erb +238 -0
- data/ui/web/app/views/config_widget.erb +232 -0
- data/ui/web/app/views/dashboard.erb +64 -72
- data/ui/web/app/views/deploy_config.erb +3 -0
- data/ui/web/app/views/edit_pages.erb +170 -2
- data/ui/web/app/views/edit_post.erb +130 -9
- data/ui/web/app/views/edit_theme.erb +73 -0
- data/ui/web/app/views/edit_theme_file.erb +74 -0
- data/ui/web/app/views/theme_management.erb +130 -0
- data/ui/web/app/views/view_dashboard.erb +666 -25
- data/ui/web/app/views/widgets.erb +249 -0
- data/ui/web/bin/scriptorium-web +35 -24
- data/ui/web/tmp/timing.log +17 -0
- data/ui/web/tmp/web_server.log +0 -5
- metadata +190 -116
- data/assets/back-icon.png +0 -0
- data/assets/icons/facebook.svg +0 -1
- data/assets/icons/github.svg +0 -1
- data/assets/icons/instagram.svg +0 -1
- data/assets/icons/reddit.svg +0 -1
- data/assets/icons/x.svg +0 -1
- data/assets/icons/youtube.svg +0 -1
- data/bin/scriptorium +0 -1511
- data/doc/anti-amnesia/20250727-060000-api-design-tui-planning.md +0 -34
- data/doc/anti-amnesia/20250727-061000-runeblog-tui-analysis.md +0 -50
- data/doc/anti-amnesia/20250727-154000-livetext-plugin-file-stats.md +0 -73
- data/doc/anti-amnesia/20250727-172600-unified-minitest-framework.md +0 -70
- data/doc/anti-amnesia/20250727-173000-widget-testing-achievement.md +0 -110
- data/doc/anti-amnesia/20250727-180000-post-id-num-refactoring.md +0 -73
- data/doc/anti-amnesia/20250728-124421-conversation-summary-concise.md +0 -124
- data/doc/anti-amnesia/20250729-190000-scriptorium-tui-testing-complete.md +0 -46
- data/doc/anti-amnesia/20250729-200000-scriptorium-tui-testing-edit-file-workflow.md +0 -97
- data/doc/anti-amnesia/20250729-211500-dependency-management-system.md +0 -211
- data/doc/anti-amnesia/20250729-213000-python-virtual-environment-setup.md +0 -141
- data/doc/anti-amnesia/20250729-214500-theme-management-commands.md +0 -211
- data/doc/anti-amnesia/20250729-215000-version-update-to-0.6.0.md +0 -134
- data/doc/anti-amnesia/20250729-220000-user-guide-complete.md +0 -41
- data/doc/anti-amnesia/20250804-213700-publishing-test-fix.md +0 -49
- data/doc/anti-amnesia/20250804-214400-additional-test-fixes.md +0 -46
- data/doc/anti-amnesia/20250804-220000-asset-function-logic-clarification.md +0 -41
- data/doc/anti-amnesia/20250806-202032-asset-function-logic-clarification.md +0 -41
- data/doc/anti-amnesia/20250813-082428-syntax-highlighting-and-navigation-improvements.md +0 -256
- data/lib/scriptorium/syntax_highlighter.rb +0 -234
- data/test/manual/deploy_symlink_demo.rb +0 -142
- data/test/manual/symlink_demo.rb +0 -117
- data/test/manual/test2.rb +0 -12
- data/test/manual/test_banner_from_file.rb +0 -150
- data/test/manual/test_banner_in_header.rb +0 -35
- data/test/manual/test_code_highlighting.rb +0 -68
- data/test/manual/test_complex_header.rb +0 -74
- data/test/manual/test_empty_header.rb +0 -32
- data/test/manual/test_radial_custom.rb +0 -58
- data/test/manual/test_radial_large_radius.rb +0 -52
- data/test/manual/test_svg_debug.rb +0 -47
- data/test/pages-demo/config/currentview.txt +0 -1
- data/test/pages-demo/views/demo/config/common.js +0 -57
- data/test/pages-demo/views/demo/config/footer.txt +0 -1
- data/test/pages-demo/views/demo/config/global-head.txt +0 -8
- data/test/pages-demo/views/demo/config/header.txt +0 -1
- data/test/pages-demo/views/demo/config/layout.txt +0 -1
- data/test/pages-demo/views/demo/config/left.txt +0 -1
- data/test/pages-demo/views/demo/config/main.txt +0 -1
- data/test/pages-demo/views/demo/config/right.txt +0 -1
- data/test/pages-demo/views/demo/config.txt +0 -3
- data/test/pages-demo/views/demo/output/panes/footer.html +0 -1
- data/test/pages-demo/views/demo/output/panes/header.html +0 -1
- data/test/pages-demo/views/demo/output/panes/left.html +0 -1
- data/test/pages-demo/views/demo/output/panes/main.html +0 -1
- data/test/pages-demo/views/demo/output/panes/right.html +0 -1
- data/test/scriptorium-TEST-1754622690-146/config/bootstrap_css.txt +0 -5
- data/test/scriptorium-TEST-1754622690-146/config/bootstrap_js.txt +0 -4
- data/test/scriptorium-TEST-1754622690-146/config/common.js +0 -57
- data/test/scriptorium-TEST-1754622690-146/config/currentview.txt +0 -1
- data/test/scriptorium-TEST-1754622690-146/config/global-head.txt +0 -9
- data/test/scriptorium-TEST-1754622690-146/config/last_post_num.txt +0 -1
- data/test/scriptorium-TEST-1754622690-146/config/os_helpers.rb +0 -4
- data/test/scriptorium-TEST-1754622690-146/config/widgets.txt +0 -3
- data/test/scriptorium-TEST-1754622690-146/posts/0001/meta.txt +0 -8
- data/test/scriptorium-TEST-1754622690-146/posts/0001/source.lt3 +0 -6
- data/test/scriptorium-TEST-1754622690-146/themes/standard/README.txt +0 -1
- data/test/scriptorium-TEST-1754622690-146/themes/standard/config.txt +0 -1
- data/test/scriptorium-TEST-1754622690-146/themes/standard/layout/gen/text.css +0 -1
- data/test/scriptorium-TEST-1754622690-146/themes/standard/templates/index.lt3 +0 -1
- data/test/scriptorium-TEST-1754622690-146/themes/standard/templates/index_entry.lt3 +0 -14
- data/test/scriptorium-TEST-1754622690-146/themes/standard/templates/post.lt3 +0 -13
- data/test/scriptorium-TEST-1754622690-146/themes/standard/templates/widget.lt3 +0 -1
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/bootstrap_css.txt +0 -5
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/bootstrap_js.txt +0 -4
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/common.js +0 -57
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/deploy.txt +0 -5
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/footer.txt +0 -2
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/global-head.txt +0 -9
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/header.txt +0 -4
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/layout.txt +0 -5
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/left.txt +0 -3
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/main.txt +0 -5
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/right.txt +0 -3
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/status.txt +0 -7
- data/test/scriptorium-TEST-1754622690-146/views/sample/config.txt +0 -3
- data/test/scriptorium-TEST-1754622690-146/views/sample/layout/footer.html +0 -3
- data/test/scriptorium-TEST-1754622690-146/views/sample/layout/header.html +0 -3
- data/test/scriptorium-TEST-1754622690-146/views/sample/layout/left.html +0 -3
- data/test/scriptorium-TEST-1754622690-146/views/sample/layout/main.html +0 -3
- data/test/scriptorium-TEST-1754622690-146/views/sample/layout/right.html +0 -3
- data/test/scriptorium-TEST-1754622690-146/views/sample/output/panes/footer.html +0 -1
- data/test/scriptorium-TEST-1754622690-146/views/sample/output/panes/header.html +0 -1
- data/test/scriptorium-TEST-1754622690-146/views/sample/output/panes/left.html +0 -1
- data/test/scriptorium-TEST-1754622690-146/views/sample/output/panes/main.html +0 -1
- data/test/scriptorium-TEST-1754622690-146/views/sample/output/panes/right.html +0 -1
- data/ui/web/tmp/web_server.pid +0 -1
- /data/{test/pages-demo/views/demo/config/bootstrap_css.txt → lib/scriptorium/support/bootstrap/css.txt} +0 -0
- /data/{test/pages-demo/views/demo/config/bootstrap_js.txt → lib/scriptorium/support/bootstrap/js.txt} +0 -0
- /data/{test/scriptorium-TEST-1754622690-146/views/sample → lib/scriptorium/support}/config/reddit.txt +0 -0
- /data/{test/scriptorium-TEST-1754622690-146/themes/standard/layout → lib/scriptorium/support/templates}/layout.txt +0 -0
- /data/{test/scriptorium-TEST-1754622690-146/themes/standard/layout/config/footer.txt → lib/scriptorium/support/theme/footer.lt3} +0 -0
- /data/{test/scriptorium-TEST-1754622690-146/themes/standard/layout/config/left.txt → lib/scriptorium/support/theme/left.lt3} +0 -0
- /data/{test/scriptorium-TEST-1754622690-146/themes/standard/layout/config/main.txt → lib/scriptorium/support/theme/main.lt3} +0 -0
- /data/{test/scriptorium-TEST-1754622690-146/themes/standard/layout/config/right.txt → lib/scriptorium/support/theme/right.lt3} +0 -0
- /data/test/manual/banner-tests/{config.txt → svg.txt} +0 -0
- /data/test/manual/{test6.rb → test_advanced_widgets.rb} +0 -0
- /data/test/manual/{test1.rb → test_basic_posts.rb} +0 -0
- /data/test/manual/{test4.rb → test_layout_widgets.rb} +0 -0
- /data/test/manual/{test5.rb → test_pagination.rb} +0 -0
- /data/test/manual/{test3.rb → test_random_posts.rb} +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a813abb831e8491645c51b9a63776c7dc6f6a9b43f1650a03ca165b8e1bd36f5
|
4
|
+
data.tar.gz: c244c1b74da19acac42e0cc8688c408e9ca75f9521be0c5a06bd4b5496d1620a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f4b7bcbd38cbf68d68efa0656260593c442aa72048b40b4bd866a292501c64f89058f13032753c67347997152348c9d2e3ed863b1c0751953a0bd73030d7becc
|
7
|
+
data.tar.gz: c8f12b213efa96276f9fd99f792bf9ba6693861a7b9b217bedec196a88e258e5f4103ab22cd6f86627afb17d5063d7f30a343b8fe58768c5873b05900c0aab1b
|
Binary file
|
Binary file
|
Binary file
|
data/bin/sblog
CHANGED
@@ -1,11 +1,90 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
require '
|
4
|
-
require '
|
3
|
+
require 'optparse'
|
4
|
+
require 'fileutils'
|
5
5
|
|
6
|
-
|
6
|
+
class ScriptoriumLauncher
|
7
|
+
def initialize
|
8
|
+
@script_dir = File.dirname(__FILE__)
|
9
|
+
@project_root = File.join(@script_dir, '..')
|
10
|
+
@tui_path = File.join(@project_root, 'ui', 'tui', 'bin', 'scriptorium')
|
11
|
+
@web_path = File.join(@project_root, 'ui', 'web', 'bin', 'scriptorium-web')
|
12
|
+
end
|
7
13
|
|
8
|
-
|
14
|
+
def run
|
15
|
+
command = ARGV.first
|
9
16
|
|
10
|
-
|
17
|
+
case command
|
18
|
+
when nil, 'tui'
|
19
|
+
launch_tui
|
20
|
+
when 'web'
|
21
|
+
launch_web(ARGV[1..-1])
|
22
|
+
when 'help', '--help', '-h'
|
23
|
+
show_help
|
24
|
+
else
|
25
|
+
puts "Unknown command: #{command}"
|
26
|
+
puts "Run 'sblog help' for usage information"
|
27
|
+
exit 1
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def launch_tui
|
34
|
+
exec(@tui_path, *ARGV)
|
35
|
+
end
|
36
|
+
|
37
|
+
def launch_web(args)
|
38
|
+
if args.empty?
|
39
|
+
exec(@web_path, 'start')
|
40
|
+
else
|
41
|
+
exec(@web_path, *args)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def show_help
|
46
|
+
puts <<~HELP
|
47
|
+
Scriptorium - A command-line blogging system
|
48
|
+
|
49
|
+
FLAGS:
|
50
|
+
--test - Use test repository (scriptorium-TEST)
|
51
|
+
- Default: production repository (~/.scriptorium)
|
52
|
+
|
53
|
+
USAGE:
|
54
|
+
sblog # Launch TUI (default)
|
55
|
+
sblog --test # Launch TUI in test mode
|
56
|
+
sblog tui # Launch TUI explicitly
|
57
|
+
sblog tui --test # Launch TUI in test mode
|
58
|
+
sblog web # Launch web app
|
59
|
+
sblog web --test # Launch web app in test mode
|
60
|
+
sblog web start # Start web server
|
61
|
+
sblog web start --test # Start web server in test mode
|
62
|
+
sblog web stop # Stop web server
|
63
|
+
sblog web status # Check web server status
|
64
|
+
sblog help # Show this help
|
65
|
+
|
66
|
+
INTERFACES:
|
67
|
+
TUI (Text User Interface):
|
68
|
+
- Command-line interface
|
69
|
+
- Full-featured management
|
70
|
+
- Preferred for daily use
|
71
|
+
- Runs in terminal
|
72
|
+
|
73
|
+
Web:
|
74
|
+
- Browser-based interface
|
75
|
+
- Visual management tools
|
76
|
+
- Good for occasional use
|
77
|
+
- Runs in web browser
|
78
|
+
|
79
|
+
EXAMPLES:
|
80
|
+
sblog # Start TUI
|
81
|
+
sblog new post "Title" # Create new post via TUI
|
82
|
+
sblog web start # Start web server
|
83
|
+
sblog web # Open web interface
|
84
|
+
HELP
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
# Run the launcher
|
89
|
+
ScriptoriumLauncher.new.run
|
11
90
|
|
data/bin/scriptorium
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
/Users/Hal/Dropbox/topx/git/scriptorium/ui/tui/bin/scriptorium
|
@@ -52,7 +52,6 @@
|
|
52
52
|
|
53
53
|
4. Some of my priorities are: - This must be useful, easy, flexible, and intuitive FOR ME. (It is possible no one else will ever use it.) - I believe in "convention over configuration" as DHH said. - Other mantras are: Abstract away complexity; hide unnecessary detail; take reasonable defaults; balance the tradeoff between ease of use and feature richness; wrap things as needed to simplify them; etc. - I am using a tool of my own called Livetext; more details on that later. It is a tool for processing its input format and generating arbitrary output (usually HTML in this case) as well as side effects. It has "dot" commands; includes; raw copy of files, variables and functions (both predefined and user-defined); user-defined dot commands; and a rudimentary plugin system. - I avoid Javascript when I can, and like to "hide" CSS mostly (at a high level). In output, I prefer CSS inline rather than in files (usually). - I believe that extensibilty is good in general. I believe that the 90% most common tasks should become trivial; hard things should be easy, but some very advanced things may be impossible; as in, if you want to do this sort of esoteric or arcane task, this probably isn't your tool."
|
54
54
|
|
55
|
-
5. Scriptorium is far less mature than Runeblog was, but is being rewritten to be FAR more sturdy and robust. The basics of the API are in place; we can create a repo, create a view, add posts to a view, modify a layout, add a "Links" widget, generate a front page. There is currently no UI, no deployment, etc. There are unit tests of about 770 assertions, as well as manual and semi-manual tests I am using Bootstrap a little (for widgets and the navbar); that is a fairly complex piece. I haven't added the navbar piece yet; that will come soon. Some next things I want to accomplish: a "convenience module" API; a TUI; a curses UI; at least two new widgets; better features in the Livetext "Scriptorium plugin"; etc. Probably will encapsulate the API soon so as to start UI development.
|
56
55
|
|
57
56
|
**ASST:**
|
58
57
|
[See above content] 2025-07-30 16:30:00 - TUI Test Refactoring Learnings
|
@@ -1,31 +1,2 @@
|
|
1
1
|
# Anti-Amnesia: Scriptorium Conventions and Decisions
|
2
2
|
|
3
|
-
## Runeblog TUI Post Creation Pattern
|
4
|
-
**Date**: 2025-07-27
|
5
|
-
**Context**: Understanding how Runeblog handled draft-to-post conversion
|
6
|
-
**Decision**: Runeblog automatically converted drafts to posts after editing, without a separate "finish draft" step. This provides a fast workflow: edit → save → post (local), with deployment making it public.
|
7
|
-
|
8
|
-
## Scriptorium Setup vs Runeblog
|
9
|
-
**Date**: 2025-07-27
|
10
|
-
**Context**: Comparing setup approaches between Scriptorium and Runeblog
|
11
|
-
**Decision**: Runeblog had a `get_started` method that ran automatically when creating a new repository. Scriptorium should follow this pattern for better user experience.
|
12
|
-
|
13
|
-
## Editor Discovery Implementation
|
14
|
-
**Date**: 2025-07-27
|
15
|
-
**Context**: Implementing editor discovery for TUI setup
|
16
|
-
**Decision**: Created a `which()` helper method that uses `File.which` (Ruby 3.2+) or falls back to `system("which")`. Prioritized editors for "get in, get out" single-file editing: nano, vim, emacs, vi, micro, subl, ed.
|
17
|
-
|
18
|
-
## File Operation Consistency
|
19
|
-
**Date**: 2025-07-27
|
20
|
-
**Context**: Ensuring consistent file operations across the project
|
21
|
-
**Decision**: Replaced `File.read` calls with the project's `read_file` helper for centralized error handling. This maintains consistency with the project's file operation patterns.
|
22
|
-
|
23
|
-
## Automatic Setup Implementation
|
24
|
-
**Date**: 2025-07-27
|
25
|
-
**Context**: Implementing Runeblog-style automatic setup when creating new repositories
|
26
|
-
**Decision**:
|
27
|
-
- Removed `setup` command from TUI (no longer needed)
|
28
|
-
- Modified `discover_repo` to call `create_new_repo` when no repository exists
|
29
|
-
- `create_new_repo` automatically calls `get_started` after creating repository
|
30
|
-
- This follows Runeblog's pattern: create repo → immediate setup → ready to use
|
31
|
-
- User experience: "Create new repository?" → "Yes" → automatic editor selection → ready to blog
|
@@ -41,24 +41,5 @@ ruby --version # Shows ruby 3.2.3
|
|
41
41
|
- **The fix is temporary** - needs to be done each time Cursor opens a new terminal
|
42
42
|
- **Permanent fix** would be to ensure rbenv init is in shell startup files
|
43
43
|
|
44
|
-
### After Fix
|
45
|
-
- **Ruby version**: Now correctly shows 3.2.3
|
46
|
-
- **Tests can load**: livetext gem dependency resolved
|
47
|
-
- **New issue discovered**: Syntax error in `temp_smart_concatenated_test.rb`
|
48
|
-
|
49
|
-
### Test Results After Fix
|
50
|
-
- **Core unit tests**: ✅ All passing (82 runs, 113 assertions)
|
51
|
-
- **Repo unit tests**: ✅ All passing (20 runs, 59 assertions)
|
52
|
-
- **View unit tests**: ✅ All passing (25 runs, 43 assertions)
|
53
|
-
- **Post unit tests**: ✅ All passing (36 runs, 45 assertions)
|
54
|
-
- **Total core tests**: ✅ 163 runs, 260 assertions, 0 failures
|
55
|
-
|
56
|
-
### Remaining Issues
|
57
|
-
- **test_experimental.rb**: Has duplicate method extraction causing syntax errors
|
58
|
-
- **temp_smart_concatenated_test.rb**: Generated file has duplicate `test_stats_command` methods
|
59
|
-
- **test/all script**: Fails due to experimental test file issues
|
60
|
-
|
61
44
|
### Next Steps
|
62
|
-
- Fix test_experimental.rb duplicate method extraction
|
63
45
|
- Consider permanent rbenv integration for Cursor
|
64
|
-
- Run full test suite once experimental issues are resolved
|
@@ -37,4 +37,4 @@ I once referred to this as "digital dementia" :) are you able to assess your own
|
|
37
37
|
The "digital dementia" analogy is spot-on - like human memory, AI performance can degrade with information overload, and AI is not always the best judge of its own cognitive state.
|
38
38
|
|
39
39
|
### Anti-Amnesia Value
|
40
|
-
This reinforces why the anti-amnesia documentation approach is valuable - it creates persistent, reliable reference that doesn't degrade with conversation length and helps maintain consistency across sessions.
|
40
|
+
This reinforces why the anti-amnesia documentation approach is valuable - it creates persistent, reliable reference that doesn't degrade with conversation length and helps maintain consistency across sessions.
|
@@ -155,4 +155,4 @@ Potential improvements identified:
|
|
155
155
|
- Python script is executable (`chmod +x scripts/reddit_autopost.py`)
|
156
156
|
- Credentials file should be added to `.gitignore` for security
|
157
157
|
- Integration follows existing Scriptorium patterns and conventions
|
158
|
-
- Error handling matches existing exception patterns in the codebase
|
158
|
+
- Error handling matches existing exception patterns in the codebase
|
@@ -33,13 +33,3 @@ The assistant was unable to break out of this pattern and make actual progress.
|
|
33
33
|
3. **User Intervention**: The AI should recognize when it needs to ask the user for help or a different approach
|
34
34
|
4. **Problem Restatement**: The AI should be able to step back and restate the problem in different terms
|
35
35
|
|
36
|
-
## Related Bug
|
37
|
-
The actual bug being investigated was:
|
38
|
-
- `test_072_create_post_with_generation_default` fails because `post.published` is being set to a timestamp during generation
|
39
|
-
- The assistant identified that `write_post_metadata` writes ALL `post.*` keys from the `vars` hash
|
40
|
-
- But the assistant could not determine where `post.published` was being set to a timestamp in the `vars` hash
|
41
|
-
|
42
|
-
## Status
|
43
|
-
- **Loop Issue**: Documented for future reference
|
44
|
-
- **Original Bug**: Still unsolved
|
45
|
-
- **User Response**: User correctly identified the loop and requested documentation
|
@@ -23,8 +23,5 @@ Renamed the file to use the correct current timestamp:
|
|
23
23
|
- Use `date +%Y%m%d-%H%M%S` format for consistent timestamping
|
24
24
|
- Verify timestamp accuracy before creating files
|
25
25
|
|
26
|
-
## Files Modified
|
27
|
-
- `doc/anti-amnesia/20250804-190500-cognitive-loop-bug.md` - Renamed with correct timestamp
|
28
|
-
|
29
26
|
## Key Takeaway
|
30
|
-
Always use current timestamps when creating anti-amnesia files to maintain accurate chronological order and prevent confusion.
|
27
|
+
Always use current timestamps when creating anti-amnesia files to maintain accurate chronological order and prevent confusion.
|
@@ -0,0 +1,172 @@
|
|
1
|
+
# CodeMirror Integration and Web Test Framework
|
2
|
+
|
3
|
+
**Date**: 2024-12-19 16:00:00
|
4
|
+
|
5
|
+
## CodeMirror Integration
|
6
|
+
|
7
|
+
### Overview
|
8
|
+
Integrated CodeMirror code editor into the web interface for enhanced post and page editing with LiveText syntax highlighting.
|
9
|
+
|
10
|
+
### Files Created/Modified
|
11
|
+
|
12
|
+
#### `test/manual/codemirror_demo.html`
|
13
|
+
- Standalone HTML demo showcasing CodeMirror with custom LiveText syntax highlighting
|
14
|
+
- Includes macro toolbar with buttons for common editing tasks
|
15
|
+
- Demonstrates LiveText-specific syntax rules (non-terminating markers, bracketed formatting, etc.)
|
16
|
+
- Features responsive SVG banner generation and theme switching
|
17
|
+
|
18
|
+
#### `ui/web/app/assets/livetext_mode.js`
|
19
|
+
- Custom CodeMirror mode definition for LiveText syntax
|
20
|
+
- Handles LiveText-specific constructs:
|
21
|
+
- Variables (`$foo`, `$foo.bar`) - stops at invalid characters
|
22
|
+
- Functions (`$$max`, `$$link:param`, `$$index[param]`)
|
23
|
+
- Markers (`*`, `_`, `` ` ``, `~`) - non-terminating, space/comma/period terminated
|
24
|
+
- Bracketed formatting (`*[bold text]`)
|
25
|
+
- Dot commands (`.h1`, `.list`, `.banner`, etc.)
|
26
|
+
- Block structures:
|
27
|
+
- `.raw`...`__RAW__` (plain text)
|
28
|
+
- `.comment`...`.end` (plain text)
|
29
|
+
- `.def`/`.func`...`.end` (Ruby code)
|
30
|
+
- `.code ruby`/`elixir`/`bash`...`.end` (language-specific highlighting)
|
31
|
+
|
32
|
+
#### `ui/web/app/views/edit_post.erb`
|
33
|
+
- Integrated CodeMirror for post editing
|
34
|
+
- Replaces textarea with enhanced editor
|
35
|
+
- Includes LiveText syntax highlighting
|
36
|
+
- Form submission syncs CodeMirror content back to hidden textarea
|
37
|
+
|
38
|
+
#### `ui/web/app/views/edit_pages.erb`
|
39
|
+
- Integrated CodeMirror for page editing
|
40
|
+
- Similar functionality to edit_post.erb
|
41
|
+
- Button-triggered save with explicit content syncing
|
42
|
+
|
43
|
+
#### `ui/web/app/app.rb`
|
44
|
+
- Added `/web_assets/*` route to serve CodeMirror assets
|
45
|
+
- Fixed post creation workflow to redirect to edit page
|
46
|
+
- Enhanced error handling and debugging
|
47
|
+
|
48
|
+
### Key Features
|
49
|
+
- **Syntax Highlighting**: Custom LiveText mode with accurate tokenization
|
50
|
+
- **Macro System**: Toolbar buttons for common editing tasks
|
51
|
+
- **Responsive Design**: Adapts to different screen sizes
|
52
|
+
- **Theme Support**: Light/dark mode switching
|
53
|
+
- **Content Syncing**: Seamless integration with existing form submission
|
54
|
+
|
55
|
+
## Web Test Framework
|
56
|
+
|
57
|
+
### Overview
|
58
|
+
Comprehensive automated testing framework for web interface functionality, covering complete user workflows.
|
59
|
+
|
60
|
+
### Files Created
|
61
|
+
|
62
|
+
#### `test/web_test_helper.rb`
|
63
|
+
- Shared helper module for web integration tests
|
64
|
+
- Provides methods for:
|
65
|
+
- Starting/stopping web server
|
66
|
+
- Making HTTP requests (GET, POST)
|
67
|
+
- Asserting response types (success, redirect)
|
68
|
+
- Managing test repository
|
69
|
+
- Silent operation (no debug output)
|
70
|
+
|
71
|
+
#### `test/web_integration_test.rb`
|
72
|
+
- Basic web integration tests
|
73
|
+
- Verifies core functionality and test mode
|
74
|
+
- Tests repository creation, view management, basic navigation
|
75
|
+
|
76
|
+
#### `test/web_workflow_test.rb`
|
77
|
+
- Comprehensive workflow tests covering:
|
78
|
+
- **Post Creation**: Create post via web interface, verify redirect to edit page
|
79
|
+
- **Post Editing**: Edit post content, save, verify file content matches
|
80
|
+
- **Publish/Unpublish**: Toggle post status, verify API response and HTML display
|
81
|
+
- **Delete/Restore**: Delete post (strikethrough), restore (normal display)
|
82
|
+
- **Asset Management**: Upload and manage assets
|
83
|
+
- **View Configuration**: Configure view settings
|
84
|
+
- **Deployment**: Deploy configuration workflow
|
85
|
+
- **Error Handling**: Edge cases and error conditions
|
86
|
+
|
87
|
+
#### `test/web_test_mode_simple_test.rb`
|
88
|
+
- Simple test to verify web app test mode functionality
|
89
|
+
- Uses curl-based verification of test repository usage
|
90
|
+
|
91
|
+
### Test Coverage
|
92
|
+
|
93
|
+
#### API Level Testing
|
94
|
+
- HTTP status codes (200, 302, 303, 404, 500)
|
95
|
+
- JSON response validation
|
96
|
+
- Redirect behavior verification
|
97
|
+
- Error handling and edge cases
|
98
|
+
|
99
|
+
#### UI Level Testing
|
100
|
+
- HTML content verification
|
101
|
+
- Visual state changes (published/unpublished status)
|
102
|
+
- Strikethrough styling for deleted posts
|
103
|
+
- Form submission and content persistence
|
104
|
+
|
105
|
+
#### Workflow Testing
|
106
|
+
- Complete user journeys from start to finish
|
107
|
+
- Cross-page navigation and state persistence
|
108
|
+
- File system verification (actual file content)
|
109
|
+
- Database/metadata verification
|
110
|
+
|
111
|
+
### Key Features
|
112
|
+
- **Fully Automated**: No manual intervention required
|
113
|
+
- **Silent Operation**: No debug output, only errors shown
|
114
|
+
- **Comprehensive Coverage**: Tests both API and UI layers
|
115
|
+
- **Real File Verification**: Checks actual file content, not just responses
|
116
|
+
- **Test Mode Support**: Uses separate test repository (`ui/web/scriptorium-TEST`)
|
117
|
+
- **Parallel Safe**: Each test creates fresh test environment
|
118
|
+
|
119
|
+
### Integration
|
120
|
+
- Added to `test/all` for inclusion in full test suite
|
121
|
+
- Follows existing project testing patterns (Minitest)
|
122
|
+
- Uses same helper patterns as TUI integration tests
|
123
|
+
- Maintains consistency with project coding standards
|
124
|
+
|
125
|
+
## Benefits
|
126
|
+
|
127
|
+
### CodeMirror Integration
|
128
|
+
- Enhanced editing experience with syntax highlighting
|
129
|
+
- Reduced editing errors through visual feedback
|
130
|
+
- Familiar code editor interface for users
|
131
|
+
- Extensible macro system for common tasks
|
132
|
+
|
133
|
+
### Web Test Framework
|
134
|
+
- Catches regressions in web interface functionality
|
135
|
+
- Verifies complete user workflows, not just individual components
|
136
|
+
- Provides confidence in web interface reliability
|
137
|
+
- Enables safe refactoring and feature additions
|
138
|
+
- Documents expected behavior through test cases
|
139
|
+
|
140
|
+
## Usage
|
141
|
+
|
142
|
+
### Running Web Tests
|
143
|
+
```bash
|
144
|
+
# Run all web tests
|
145
|
+
ruby test/web_workflow_test.rb
|
146
|
+
ruby test/web_integration_test.rb
|
147
|
+
|
148
|
+
# Run specific test
|
149
|
+
ruby test/web_workflow_test.rb -n test_004_post_editing_workflow
|
150
|
+
|
151
|
+
# Run as part of full test suite
|
152
|
+
ruby test/all
|
153
|
+
```
|
154
|
+
|
155
|
+
### CodeMirror Demo
|
156
|
+
Open `test/manual/codemirror_demo.html` in browser to see LiveText syntax highlighting and macro functionality.
|
157
|
+
|
158
|
+
## Technical Notes
|
159
|
+
|
160
|
+
### LiveText Syntax Rules
|
161
|
+
- Markers are non-terminating (unlike Markdown)
|
162
|
+
- Single vs. double markers differ only in termination (space vs. comma/period)
|
163
|
+
- Bracketed formatting allows multi-word formatting
|
164
|
+
- Variables and functions have specific naming rules
|
165
|
+
- Block structures have different body processing rules
|
166
|
+
|
167
|
+
### Test Architecture
|
168
|
+
- Uses `WebTestHelper` module for shared functionality
|
169
|
+
- Each test creates fresh test environment
|
170
|
+
- Tests verify both API responses and HTML content
|
171
|
+
- File system verification ensures actual persistence
|
172
|
+
- Silent operation focuses on genuine errors only
|
@@ -0,0 +1,126 @@
|
|
1
|
+
# Backup/Restore System Implementation
|
2
|
+
|
3
|
+
## Overview
|
4
|
+
Implemented a comprehensive backup and restore system for Scriptorium repositories with full/incremental backups, hybrid restore strategies, and 30-day retention.
|
5
|
+
|
6
|
+
## Architecture
|
7
|
+
|
8
|
+
### Storage Structure
|
9
|
+
```
|
10
|
+
repo/backups/
|
11
|
+
├── manifest.txt # Backup registry
|
12
|
+
└── data/ # Backup content
|
13
|
+
├── 20250902-120000-full/
|
14
|
+
├── 20250902-130000-incr/
|
15
|
+
└── 20250902-140000-incr/
|
16
|
+
```
|
17
|
+
|
18
|
+
### Manifest Format
|
19
|
+
```
|
20
|
+
20250902-120000-full Initial full backup
|
21
|
+
20250902-130000-incr Added new post
|
22
|
+
20250902-140000-incr Updated existing post
|
23
|
+
```
|
24
|
+
|
25
|
+
### Flat File Structure
|
26
|
+
Each backup directory contains files with full relative paths:
|
27
|
+
```
|
28
|
+
data/20250902-120000-full/
|
29
|
+
├── posts/0001/source.lt3
|
30
|
+
├── posts/0001/meta.txt
|
31
|
+
├── views/sample/config.txt
|
32
|
+
└── config/repo.txt
|
33
|
+
```
|
34
|
+
|
35
|
+
## Core Features
|
36
|
+
|
37
|
+
### Backup Types
|
38
|
+
- **Full Backup**: Complete repository snapshot
|
39
|
+
- **Incremental Backup**: Only changed files since last backup
|
40
|
+
|
41
|
+
### Change Detection
|
42
|
+
- Uses `File.mtime` to identify modified files
|
43
|
+
- 1-second sleep before backup creation ensures distinct timestamps
|
44
|
+
- Compares file modification times against last backup timestamp
|
45
|
+
|
46
|
+
### Restore Strategies
|
47
|
+
- **`:safe`** (default): Creates pre-restore backup, then restores
|
48
|
+
- **`:merge`**: Overlays backup content on existing files
|
49
|
+
- **`:destroy`**: Clears repository and restores from backup
|
50
|
+
|
51
|
+
### Dependency Management
|
52
|
+
- Always preserves most recent full backup (30-day retention)
|
53
|
+
- Restore finds most recent full backup before target
|
54
|
+
- Applies all subsequent incremental backups up to target
|
55
|
+
- Handles missing dependencies gracefully
|
56
|
+
|
57
|
+
## API Methods
|
58
|
+
|
59
|
+
### `create_backup(type: :full|:incr, description: nil)`
|
60
|
+
- Creates timestamped backup directory
|
61
|
+
- Records entry in manifest.txt
|
62
|
+
- Handles both full and incremental backups
|
63
|
+
|
64
|
+
### `list_backups()`
|
65
|
+
- Returns array of backup info: `{timestamp, type, description}`
|
66
|
+
- Parses manifest.txt entries
|
67
|
+
|
68
|
+
### `restore_backup(timestamp, strategy: :safe)`
|
69
|
+
- Implements hybrid restore strategies
|
70
|
+
- Finds dependency chain (full + incrementals)
|
71
|
+
- Preserves existing files in merge mode
|
72
|
+
|
73
|
+
### `delete_backup(timestamp)`
|
74
|
+
- Removes backup directory and manifest entry
|
75
|
+
- Enforces retention policy (keeps most recent full)
|
76
|
+
|
77
|
+
## Key Implementation Details
|
78
|
+
|
79
|
+
### Timestamp Precision
|
80
|
+
- Uses `Time.now.strftime("%Y%m%d-%H%M%S")` for directory names
|
81
|
+
- 1-second sleep before backup creation prevents sub-second conflicts
|
82
|
+
- Temporary directory creation + rename ensures atomic operations
|
83
|
+
|
84
|
+
### Error Handling
|
85
|
+
- Contract system validation (enabled in tests)
|
86
|
+
- Graceful handling of missing dependencies
|
87
|
+
- Clear error messages for invalid operations
|
88
|
+
|
89
|
+
### Test Coverage
|
90
|
+
- 16 comprehensive tests covering all scenarios
|
91
|
+
- Tests for full/incremental backups, restore strategies, edge cases
|
92
|
+
- 100% pass rate with proper contract system integration
|
93
|
+
|
94
|
+
## Usage Examples
|
95
|
+
|
96
|
+
```ruby
|
97
|
+
# Create full backup
|
98
|
+
api.create_backup(type: :full, description: "Before major changes")
|
99
|
+
|
100
|
+
# Create incremental backup
|
101
|
+
api.create_backup(type: :incr, description: "Added new post")
|
102
|
+
|
103
|
+
# List available backups
|
104
|
+
backups = api.list_backups
|
105
|
+
|
106
|
+
# Restore with safe strategy (default)
|
107
|
+
api.restore_backup("20250902-120000-full")
|
108
|
+
|
109
|
+
# Restore with merge strategy
|
110
|
+
api.restore_backup("20250902-130000-incr", strategy: :merge)
|
111
|
+
|
112
|
+
# Delete old backup
|
113
|
+
api.delete_backup("20250902-120000-full")
|
114
|
+
```
|
115
|
+
|
116
|
+
## Files Modified
|
117
|
+
- `lib/scriptorium/api.rb`: Core backup/restore implementation
|
118
|
+
- `test/unit/backup_test.rb`: Comprehensive test suite
|
119
|
+
- `test/all`: Added backup tests to full test suite
|
120
|
+
|
121
|
+
## Status
|
122
|
+
✅ **Complete and Production Ready**
|
123
|
+
- All 16 tests passing
|
124
|
+
- Full test suite integration
|
125
|
+
- Comprehensive error handling
|
126
|
+
- 30-day retention policy implemented
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# Backup Metadata Implementation - 2025-09-07 20:33:39
|
2
|
+
|
3
|
+
## Overview
|
4
|
+
Added per-backup metadata storage to track version information and backup statistics for better debugging, compatibility checking, and audit trails.
|
5
|
+
|
6
|
+
## Changes Made
|
7
|
+
|
8
|
+
### 1. Backup Location Change
|
9
|
+
- **Changed backup storage location** from `repo/backups/` to `backup-scriptorium/` (parallel to repo)
|
10
|
+
- **Test repositories** use `backup-scriptorium-TEST/`
|
11
|
+
- **Updated `get_backup_directory()` method** to handle both production and test environments
|
12
|
+
- **Made method public** (was private) to allow direct access without `api.send()`
|
13
|
+
|
14
|
+
### 2. Per-Backup Metadata File
|
15
|
+
- **Added `backup-info.txt`** to each backup directory (both full and incremental)
|
16
|
+
- **Contains essential metadata**:
|
17
|
+
- Scriptorium version (from `Scriptorium::VERSION`)
|
18
|
+
- LiveText version (from `livetext -v` command)
|
19
|
+
- Ruby version (from `RUBY_VERSION`)
|
20
|
+
- Backup type (full/incremental)
|
21
|
+
- Backup name (timestamp-type)
|
22
|
+
- Repository path (which repo was backed up)
|
23
|
+
- File count (number of files backed up)
|
24
|
+
- Total size (backup size in bytes)
|
25
|
+
- Platform (OS and Ruby engine)
|
26
|
+
- Git commit (first 8 characters, if available)
|
27
|
+
|
28
|
+
### 3. Implementation Details
|
29
|
+
- **`create_backup_info()` method** - Creates the metadata file
|
30
|
+
- **`get_livetext_version()` method** - Gets LiveText version via command line
|
31
|
+
- **`get_git_commit_hash()` method** - Gets git commit hash if available
|
32
|
+
- **`count_files_in_backup()` method** - Counts files in backup directory
|
33
|
+
- **`calculate_directory_size()` method** - Calculates total backup size
|
34
|
+
- **Called after backup creation** but before final directory rename
|
35
|
+
|
36
|
+
### 4. Test Updates
|
37
|
+
- **Added backup info file assertions** to both full and incremental backup tests
|
38
|
+
- **Verifies file existence** and content validation
|
39
|
+
- **All 16 backup tests pass** with new functionality
|
40
|
+
|
41
|
+
## Benefits
|
42
|
+
- **Restore validation** - Check compatibility before restoring
|
43
|
+
- **Debugging** - Know exactly what versions were used
|
44
|
+
- **Migration help** - Understand what needs updating
|
45
|
+
- **Audit trail** - Track backup environment over time
|
46
|
+
- **Better error diagnosis** - Version mismatch detection
|
47
|
+
|
48
|
+
## Files Modified
|
49
|
+
- `lib/scriptorium/api.rb` - Added backup metadata functionality
|
50
|
+
- `test/unit/backup_test.rb` - Added backup info file tests
|
51
|
+
|
52
|
+
## Example Backup Info File
|
53
|
+
```
|
54
|
+
# Scriptorium Backup Information
|
55
|
+
# Generated: 2025-09-07 20:32:33
|
56
|
+
scriptorium_version: 0.6.1
|
57
|
+
livetext_version: 0.9.60
|
58
|
+
ruby_version: 3.2.3
|
59
|
+
backup_type: full
|
60
|
+
backup_name: 20250907-203233-full
|
61
|
+
repository_path: test/scriptorium-TEST
|
62
|
+
file_count: 110
|
63
|
+
total_size: 138338
|
64
|
+
platform: x86_64-darwin22 ruby
|
65
|
+
git_commit: 3b5bcc67
|
66
|
+
```
|
@@ -0,0 +1,37 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta charset="utf-8">
|
5
|
+
<title>Elixir Conf 2014</title>
|
6
|
+
<meta name="generator" content="Scriptorium Import">
|
7
|
+
<meta property="og:title" content="Elixir Conf 2014">
|
8
|
+
<meta property="og:locale" content="en_US">
|
9
|
+
<meta property="og:type" content="article">
|
10
|
+
<meta property="article:published_time" content="2014-07-29">
|
11
|
+
</head>
|
12
|
+
<body>
|
13
|
+
<article>
|
14
|
+
<header>
|
15
|
+
<h1>Elixir Conf 2014</h1>
|
16
|
+
<time datetime="2014-07-29">July 29, 2014</time>
|
17
|
+
</header>
|
18
|
+
|
19
|
+
<div class="content">
|
20
|
+
<p>
|
21
|
+
Last week in Austin, I attended the world's first Elixir conference. It was very
|
22
|
+
energizing!
|
23
|
+
With only 105 people attending, the vibe was that of a Ruby conference 10 or more
|
24
|
+
years ago. Jose Valim, the language creator, was there; two Erlang heavyweights
|
25
|
+
were also in attendance -- Robert Virding and Francesco Cesarini.
|
26
|
+
|
27
|
+
<p>
|
28
|
+
There were many Rubyists there, of course, but I will only mention myself, Dave
|
29
|
+
Thomas, and Jim Freeze. The three of us were also at the first Ruby conference
|
30
|
+
in 2001.
|
31
|
+
|
32
|
+
<p>
|
33
|
+
This will be an exciting ride. I'll keep you informed.
|
34
|
+
</div>
|
35
|
+
</article>
|
36
|
+
</body>
|
37
|
+
</html>
|
@@ -0,0 +1,22 @@
|
|
1
|
+
.h1 Elixir Conf 2014
|
2
|
+
|
3
|
+
.set post.num = 0001
|
4
|
+
.set post.slug = elixir-conf-2014
|
5
|
+
.set post.date = 2014-07-29
|
6
|
+
.set post.title = Elixir Conf 2014
|
7
|
+
.set post.tags =
|
8
|
+
.set post.views = computing austin
|
9
|
+
.set post.published = yes
|
10
|
+
.set post.deployed = no
|
11
|
+
|
12
|
+
Last week in Austin, I attended the world's first Elixir conference. It was very
|
13
|
+
energizing!
|
14
|
+
With only 105 people attending, the vibe was that of a Ruby conference 10 or more
|
15
|
+
years ago. Jose Valim, the language creator, was there; two Erlang heavyweights
|
16
|
+
were also in attendance -- Robert Virding and Francesco Cesarini.
|
17
|
+
|
18
|
+
There were many Rubyists there, of course, but I will only mention myself, Dave
|
19
|
+
Thomas, and Jim Freeze. The three of us were also at the first Ruby conference
|
20
|
+
in 2001.
|
21
|
+
|
22
|
+
This will be an exciting ride. I'll keep you informed.
|