@tutorialkit-rb/cli 0.1.5 → 0.1.7

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.
Files changed (185) hide show
  1. package/dist/index.js +1 -1
  2. package/package.json +1 -1
  3. package/template/.claude/skills/rails-file-management/SKILL.md +211 -0
  4. package/template/.claude/skills/rails-lesson-recipes/SKILL.md +415 -0
  5. package/template/.claude/skills/rails-wasm-author-constraints/SKILL.md +181 -0
  6. package/template/.claude/skills/tutorial-content-structure/SKILL.md +377 -0
  7. package/template/.claude/skills/tutorial-lesson-config/SKILL.md +389 -0
  8. package/template/.claude/skills/tutorial-quickstart/SKILL.md +440 -0
  9. package/template/.github/workflows/deploy.yml +85 -0
  10. package/template/.gitignore +10 -0
  11. package/template/CLAUDE.md +47 -0
  12. package/template/astro.config.ts +12 -0
  13. package/template/bin/build-pack +84 -0
  14. package/template/bin/build-ruby-base +180 -0
  15. package/template/bin/link-local +13 -0
  16. package/template/bin/unlink-local +7 -0
  17. package/template/cors-proxy/README.md +63 -0
  18. package/template/cors-proxy/package-lock.json +1504 -0
  19. package/template/cors-proxy/package.json +12 -0
  20. package/template/cors-proxy/src/index.ts +87 -0
  21. package/template/cors-proxy/wrangler.toml +7 -0
  22. package/template/netlify.toml +9 -0
  23. package/template/package.json +12 -4
  24. package/template/ruby-wasm/Gemfile +6 -0
  25. package/template/ruby-wasm/Gemfile.base +19 -0
  26. package/template/ruby-wasm/Gemfile.base.lock +50 -0
  27. package/template/ruby-wasm/Gemfile.lock +8 -0
  28. package/template/ruby-wasm/bin/pack-gems +368 -0
  29. package/template/ruby-wasm/package.json +6 -0
  30. package/template/src/components/FileManager.tsx +33 -0
  31. package/template/src/components/HeadTags.astro +6 -6
  32. package/template/src/components/HelpDropdown.tsx +1 -1
  33. package/template/src/components/RailsPathLinkHandler.tsx +2 -2
  34. package/template/src/components/ShellConfigurator.tsx +6 -1
  35. package/template/src/content/tutorial/1-getting-started/1-creating-your-first-rails-app/content.md +4 -4
  36. package/template/src/content/tutorial/1-getting-started/2-rails-console/content.md +4 -4
  37. package/template/src/content/tutorial/2-controllers/2-crud-operations/content.md +2 -2
  38. package/template/src/content/tutorial/9-outbound-http/1-making-http-requests/_files/.tk-config.json +3 -0
  39. package/template/src/content/tutorial/9-outbound-http/1-making-http-requests/_files/workspace/app/controllers/http_demo_controller.rb +65 -0
  40. package/template/src/content/tutorial/9-outbound-http/1-making-http-requests/_files/workspace/app/views/http_demo/index.html.erb +172 -0
  41. package/template/src/content/tutorial/9-outbound-http/1-making-http-requests/_files/workspace/config/routes.rb +8 -0
  42. package/template/src/content/tutorial/9-outbound-http/1-making-http-requests/content.md +97 -0
  43. package/template/src/content/tutorial/9-outbound-http/meta.md +4 -0
  44. package/template/src/content/tutorial/meta.md +5 -0
  45. package/template/src/middleware.ts +14 -0
  46. package/template/src/templates/default/lib/boot-progress.js +49 -0
  47. package/template/src/templates/default/lib/http-bridge.js +55 -0
  48. package/template/src/templates/default/lib/patches/http_bridge.rb +167 -0
  49. package/template/src/templates/default/lib/rails.js +52 -5
  50. package/template/src/templates/default/lib/server.js +33 -1
  51. package/template/src/templates/default/package.json +4 -1
  52. package/template/src/templates/default/scripts/rails.js +1 -1
  53. package/template/src/templates/default/scripts/smoke-test.js +349 -0
  54. package/template/src/templates/default/scripts/wasi-loader.mjs +10 -0
  55. package/template/src/templates/default/workspace/_debug_app/.github/dependabot.yml +12 -0
  56. package/template/src/templates/default/workspace/_debug_app/.github/workflows/ci.yml +51 -0
  57. package/template/src/templates/default/workspace/_debug_app/.ruby-version +1 -0
  58. package/template/src/templates/default/workspace/_debug_app/Gemfile +37 -0
  59. package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/app/views/layouts/application.html.erb +1 -2
  60. package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/app/views/pwa/manifest.json.erb +2 -2
  61. package/template/src/templates/default/workspace/_debug_app/bin/dev +2 -0
  62. package/template/src/templates/default/workspace/_debug_app/bin/rake +4 -0
  63. package/template/src/templates/default/workspace/_debug_app/bin/setup +34 -0
  64. package/template/src/templates/default/workspace/_debug_app/config/application.rb +30 -0
  65. package/template/src/templates/default/workspace/_debug_app/config/cable.yml +10 -0
  66. package/template/src/templates/default/workspace/_debug_app/config/credentials.yml.enc +1 -0
  67. package/template/src/templates/default/workspace/_debug_app/config/master.key +1 -0
  68. package/template/src/templates/default/workspace/_debug_app/config/routes.rb +14 -0
  69. package/template/src/templates/default/workspace/_debug_app/test/models/.keep +0 -0
  70. package/template/src/templates/default/workspace/_debug_app/test/test_helper.rb +15 -0
  71. package/template/src/templates/default/workspace/_debug_app/tmp/.keep +0 -0
  72. package/template/src/templates/default/workspace/_debug_app/tmp/pids/.keep +0 -0
  73. package/template/src/templates/default/workspace/_debug_app/tmp/storage/.keep +0 -0
  74. package/template/src/templates/default/workspace/_debug_app/vendor/.keep +0 -0
  75. package/template/src/templates/rails-app/workspace/README.md +24 -0
  76. package/template/src/templates/rails-app/workspace/Rakefile +6 -0
  77. package/template/src/templates/rails-app/workspace/app/assets/images/.keep +0 -0
  78. package/template/src/templates/rails-app/workspace/app/assets/stylesheets/application.css +534 -0
  79. package/template/src/templates/rails-app/workspace/app/controllers/application_controller.rb +2 -0
  80. package/template/src/templates/rails-app/workspace/app/helpers/application_helper.rb +2 -0
  81. package/template/src/templates/rails-app/workspace/app/jobs/application_job.rb +7 -0
  82. package/template/src/templates/rails-app/workspace/app/mailers/application_mailer.rb +4 -0
  83. package/template/src/templates/rails-app/workspace/app/models/application_record.rb +3 -0
  84. package/template/src/templates/rails-app/workspace/app/models/concerns/.keep +0 -0
  85. package/template/src/templates/rails-app/workspace/app/views/layouts/application.html.erb +38 -0
  86. package/template/src/templates/rails-app/workspace/app/views/layouts/mailer.html.erb +13 -0
  87. package/template/src/templates/rails-app/workspace/app/views/layouts/mailer.text.erb +1 -0
  88. package/template/src/templates/rails-app/workspace/bin/rails +4 -0
  89. package/template/src/templates/rails-app/workspace/{store/config → config}/application.rb +1 -1
  90. package/template/src/templates/rails-app/workspace/config/boot.rb +3 -0
  91. package/template/src/templates/rails-app/workspace/config/database.yml +32 -0
  92. package/template/src/templates/rails-app/workspace/config/environment.rb +5 -0
  93. package/template/src/templates/rails-app/workspace/config/environments/development.rb +69 -0
  94. package/template/src/templates/rails-app/workspace/config/environments/production.rb +89 -0
  95. package/template/src/templates/rails-app/workspace/config/environments/test.rb +54 -0
  96. package/template/src/templates/rails-app/workspace/config/initializers/assets.rb +7 -0
  97. package/template/src/templates/rails-app/workspace/config/initializers/content_security_policy.rb +25 -0
  98. package/template/src/templates/rails-app/workspace/config/initializers/filter_parameter_logging.rb +8 -0
  99. package/template/src/templates/rails-app/workspace/config/initializers/inflections.rb +16 -0
  100. package/template/src/templates/rails-app/workspace/config/locales/en.yml +31 -0
  101. package/template/src/templates/rails-app/workspace/config/puma.rb +41 -0
  102. package/template/src/templates/rails-app/workspace/{store/config → config}/routes.rb +1 -1
  103. package/template/src/templates/rails-app/workspace/config/storage.yml +34 -0
  104. package/template/src/templates/rails-app/workspace/config.ru +6 -0
  105. package/template/src/templates/rails-app/workspace/db/seeds.rb +9 -0
  106. package/template/src/templates/rails-app/workspace/log/.keep +0 -0
  107. package/template/src/templates/rails-app/workspace/public/400.html +114 -0
  108. package/template/src/templates/rails-app/workspace/public/404.html +114 -0
  109. package/template/src/templates/rails-app/workspace/public/406-unsupported-browser.html +114 -0
  110. package/template/src/templates/rails-app/workspace/public/422.html +114 -0
  111. package/template/src/templates/rails-app/workspace/public/500.html +114 -0
  112. package/template/src/templates/rails-app/workspace/public/icon.png +0 -0
  113. package/template/src/templates/rails-app/workspace/public/icon.svg +3 -0
  114. package/template/src/templates/rails-app/workspace/public/robots.txt +1 -0
  115. package/template/src/templates/rails-app/workspace/script/.keep +0 -0
  116. package/template/src/templates/rails-app/workspace/storage/.keep +0 -0
  117. package/template/src/templates/rails-app/workspace/test/controllers/.keep +0 -0
  118. package/template/src/templates/rails-app/workspace/test/helpers/.keep +0 -0
  119. package/template/src/templates/rails-app/workspace/test/integration/.keep +0 -0
  120. package/template/src/templates/rails-app/workspace/tmp/.keep +0 -0
  121. package/template/src/templates/rails-app/workspace/tmp/cache/.keep +0 -0
  122. package/template/src/templates/rails-app/workspace/tmp/pids/.keep +0 -0
  123. package/template/src/templates/rails-app/workspace/tmp/sockets/.keep +0 -0
  124. package/template/src/templates/rails-app/workspace/tmp/storage/.keep +0 -0
  125. package/template/src/templates/rails-app/workspace/vendor/javascripts/.keep +0 -0
  126. package/template/tsconfig.json +3 -1
  127. package/template/uno.config.ts +17 -0
  128. /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/README.md +0 -0
  129. /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/Rakefile +0 -0
  130. /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/app/assets/images/.keep +0 -0
  131. /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/app/assets/stylesheets/application.css +0 -0
  132. /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/app/controllers/application_controller.rb +0 -0
  133. /package/template/src/templates/{rails-app/workspace/store/app/models → default/workspace/_debug_app/app/controllers}/concerns/.keep +0 -0
  134. /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/app/helpers/application_helper.rb +0 -0
  135. /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/app/jobs/application_job.rb +0 -0
  136. /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/app/mailers/application_mailer.rb +0 -0
  137. /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/app/models/application_record.rb +0 -0
  138. /package/template/src/templates/{rails-app/workspace/store/log → default/workspace/_debug_app/app/models/concerns}/.keep +0 -0
  139. /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/app/views/layouts/mailer.html.erb +0 -0
  140. /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/app/views/layouts/mailer.text.erb +0 -0
  141. /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/app/views/pwa/service-worker.js +0 -0
  142. /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/bin/rails +0 -0
  143. /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/config/boot.rb +0 -0
  144. /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/config/database.yml +0 -0
  145. /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/config/environment.rb +0 -0
  146. /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/config/environments/development.rb +0 -0
  147. /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/config/environments/production.rb +0 -0
  148. /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/config/environments/test.rb +0 -0
  149. /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/config/initializers/assets.rb +0 -0
  150. /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/config/initializers/content_security_policy.rb +0 -0
  151. /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/config/initializers/filter_parameter_logging.rb +0 -0
  152. /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/config/initializers/inflections.rb +0 -0
  153. /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/config/locales/en.yml +0 -0
  154. /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/config/puma.rb +0 -0
  155. /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/config/storage.yml +0 -0
  156. /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/config.ru +0 -0
  157. /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/db/seeds.rb +0 -0
  158. /package/template/src/templates/{rails-app/workspace/store/script → default/workspace/_debug_app/lib/tasks}/.keep +0 -0
  159. /package/template/src/templates/{rails-app/workspace/store/storage → default/workspace/_debug_app/log}/.keep +0 -0
  160. /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/public/400.html +0 -0
  161. /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/public/404.html +0 -0
  162. /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/public/406-unsupported-browser.html +0 -0
  163. /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/public/422.html +0 -0
  164. /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/public/500.html +0 -0
  165. /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/public/icon.png +0 -0
  166. /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/public/icon.svg +0 -0
  167. /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/public/robots.txt +0 -0
  168. /package/template/src/templates/{rails-app/workspace/store/test/controllers → default/workspace/_debug_app/script}/.keep +0 -0
  169. /package/template/src/templates/{rails-app/workspace/store/test/helpers → default/workspace/_debug_app/storage}/.keep +0 -0
  170. /package/template/src/templates/{rails-app/workspace/store/test/integration → default/workspace/_debug_app/test/controllers}/.keep +0 -0
  171. /package/template/src/templates/{rails-app/workspace/store/tmp → default/workspace/_debug_app/test/fixtures/files}/.keep +0 -0
  172. /package/template/src/templates/{rails-app/workspace/store/tmp/pids → default/workspace/_debug_app/test/helpers}/.keep +0 -0
  173. /package/template/src/templates/{rails-app/workspace/store/tmp/storage → default/workspace/_debug_app/test/integration}/.keep +0 -0
  174. /package/template/src/templates/{rails-app/workspace/store/vendor/javascripts → default/workspace/_debug_app/test/mailers}/.keep +0 -0
  175. /package/template/src/templates/rails-app/workspace/{store/.ruby-version → .ruby-version} +0 -0
  176. /package/template/src/templates/rails-app/workspace/{store/Gemfile → Gemfile} +0 -0
  177. /package/template/src/templates/rails-app/workspace/{store/app → app}/javascript/application.js +0 -0
  178. /package/template/src/templates/rails-app/workspace/{store/app → app}/javascript/controllers/application.js +0 -0
  179. /package/template/src/templates/rails-app/workspace/{store/app → app}/javascript/controllers/index.js +0 -0
  180. /package/template/src/templates/rails-app/workspace/{store/bin → bin}/importmap +0 -0
  181. /package/template/src/templates/rails-app/workspace/{store/config → config}/cable.yml +0 -0
  182. /package/template/src/templates/rails-app/workspace/{store/config → config}/credentials.yml.enc +0 -0
  183. /package/template/src/templates/rails-app/workspace/{store/config → config}/importmap.rb +0 -0
  184. /package/template/src/templates/rails-app/workspace/{store/config → config}/master.key +0 -0
  185. /package/template/src/templates/rails-app/workspace/{store/test → test}/test_helper.rb +0 -0
@@ -0,0 +1,180 @@
1
+ #!/bin/bash
2
+
3
+ set -e
4
+
5
+ # Build a custom Ruby 3.3 WASM base binary with JS interop support.
6
+ #
7
+ # Uses Gemfile.base (contains only `gem "js"`) so that the `js` gem's native
8
+ # C extension is statically linked into the binary. This provides:
9
+ # - Component model ABI exports (canonical_abi_drop_rb-abi-value, etc.)
10
+ # - Reactor adapter (_initialize instead of _start)
11
+ # - __wasi_vfs_rt_init call path (activates wasi-vfs packed data at startup)
12
+ #
13
+ # The js gem's extconf.rb unconditionally sets -DJS_ENABLE_COMPONENT_MODEL=1,
14
+ # so these exports appear in the output even without RUBY_WASM_EXPERIMENTAL_COMPONENT_MODEL.
15
+ # The output is a core WASM module (not a component), compatible with both
16
+ # wasi-vfs pack and @ruby/wasm-wasi's RubyVM.instantiateModule.
17
+ #
18
+ # This is a one-time build (5-20 minutes). The resulting binary is used
19
+ # by bin/build-pack as the base for dynamic gem packing.
20
+ #
21
+ # Prerequisites:
22
+ # - Ruby 3.3+
23
+ # - ruby_wasm gem (gem install ruby_wasm)
24
+ # - Rust toolchain (for ruby_wasm native extension)
25
+ # - WASI SDK (auto-downloaded by rbwasm if WASI_SDK_PATH not set)
26
+ # - ~2GB disk space for build artifacts
27
+ #
28
+ # Usage: ./bin/build-ruby-base
29
+
30
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
31
+ TEMPLATE_DIR="$(dirname "$SCRIPT_DIR")"
32
+ RUBY_WASM_DIR="$TEMPLATE_DIR/ruby-wasm"
33
+ OUTPUT="$RUBY_WASM_DIR/dist/ruby-base.wasm"
34
+
35
+ echo "=== Building custom Ruby WASM base binary (with JS interop) ==="
36
+ echo
37
+
38
+ # --- Preflight checks --------------------------------------------------------
39
+
40
+ if ! command -v rbwasm &> /dev/null; then
41
+ echo "Error: rbwasm CLI not found"
42
+ echo "Install it with: gem install ruby_wasm"
43
+ exit 1
44
+ fi
45
+
46
+ # --- Prepare Gemfile.base lockfile -------------------------------------------
47
+
48
+ echo "Resolving Gemfile.base dependencies..."
49
+ export BUNDLE_GEMFILE="$RUBY_WASM_DIR/Gemfile.base"
50
+ bundle lock --add-platform wasm32-wasi 2>/dev/null || bundle lock
51
+ echo
52
+
53
+ echo "Installing Gemfile.base gems (ensures js gem is available for static linking)..."
54
+ bundle install
55
+ echo
56
+
57
+ # --- Build -------------------------------------------------------------------
58
+
59
+ echo "Building Ruby 3.3 for wasm32-unknown-wasip1..."
60
+ echo " --build-profile full (all stdlib C extensions)"
61
+ echo " Gemfile.base: gem \"js\" (provides ABI exports + reactor adapter)"
62
+ echo
63
+ echo "This will take 5-20 minutes on first run."
64
+ echo
65
+
66
+ mkdir -p "$(dirname "$OUTPUT")"
67
+
68
+ # IMPORTANT: Use `bundle exec` so that Bundler is loaded in the rbwasm process.
69
+ # Without it, rbwasm's `defined?(Bundler)` check returns nil, causing it to
70
+ # skip gem resolution entirely — the js gem won't be statically linked, and
71
+ # the binary will be missing ABI exports (_initialize, canonical_abi_drop_rb-abi-value).
72
+ #
73
+ # We invoke rbwasm via a Ruby wrapper instead of the CLI directly, because
74
+ # ruby_wasm hardcodes the Ruby tarball URL for `--ruby-version 3.3` as 3.3.3.
75
+ # The monolithic pipeline uses wasmify-rails which monkey-patches this to 3.3.8.
76
+ # We apply the same monkey-patch here to ensure version parity.
77
+ # See: wasmify-rails-0.4.0/lib/wasmify/rails/builder.rb:9-16
78
+ bundle exec ruby -e '
79
+ require "ruby_wasm"
80
+ require "ruby_wasm/cli"
81
+
82
+ # Monkey-patch: override Ruby 3.3 tarball URL to 3.3.8 (matches wasmify-rails)
83
+ RubyWasm::CLI.singleton_class.prepend(Module.new do
84
+ def build_source_aliases(root)
85
+ super.tap do |sources|
86
+ sources["3.3"][:url] = "https://cache.ruby-lang.org/pub/ruby/3.3/ruby-3.3.8.tar.gz"
87
+ end
88
+ end
89
+ end)
90
+
91
+ RubyWasm::CLI.new(stdout: $stdout, stderr: $stderr).run(ARGV)
92
+ ' -- build \
93
+ --ruby-version 3.3 \
94
+ --target wasm32-unknown-wasip1 \
95
+ --build-profile full \
96
+ -o "$OUTPUT"
97
+
98
+ # --- Use raw pre-VFS binary (Strategy A) -----------------------------------
99
+ # rbwasm build outputs a VFS-packed binary (stdlib + js gem embedded).
100
+ # Using that as input to a second wasi-vfs pack causes double-packing, which
101
+ # crashes in WebContainer. Instead, we use the raw pre-VFS binary that rbwasm
102
+ # left in its rubies/ directory and do a single wasi-vfs pack in pack-gems.
103
+
104
+ RAW_BINARY=$(find "$RUBY_WASM_DIR/rubies" -name "ruby" -path "*/usr/local/bin/ruby" -type f 2>/dev/null | head -1)
105
+
106
+ if [ -z "$RAW_BINARY" ]; then
107
+ echo
108
+ echo "ERROR: Could not find raw pre-VFS binary in rubies/ directory."
109
+ echo "Expected: $RUBY_WASM_DIR/rubies/ruby-3.3-wasm32-unknown-wasip1-full-*/usr/local/bin/ruby"
110
+ echo
111
+ echo "The rbwasm build may have failed or cleaned up its build directory."
112
+ exit 1
113
+ fi
114
+
115
+ echo "Found raw pre-VFS binary: $RAW_BINARY"
116
+
117
+ # Record the usr/ directory path so pack-gems can map /usr in the single pack
118
+ # RAW_BINARY is at .../usr/local/bin/ruby — go up 3 levels to get .../usr/
119
+ USR_DIR="$(dirname "$(dirname "$(dirname "$RAW_BINARY")")")"
120
+ echo "$USR_DIR" > "$RUBY_WASM_DIR/dist/usr-dir.txt"
121
+ echo "Saved usr/ path to dist/usr-dir.txt: $USR_DIR"
122
+
123
+ # Overwrite the VFS-packed output with the raw binary
124
+ cp "$RAW_BINARY" "$OUTPUT"
125
+ echo "Replaced VFS-packed output with raw pre-VFS binary (single-pack strategy)"
126
+
127
+ SIZE=$(du -h "$OUTPUT" | cut -f1)
128
+
129
+ # --- Post-build verification ------------------------------------------------
130
+ # Verify the binary has the required exports for @ruby/wasm-wasi JS bindings.
131
+ # Without these, the binary will fail at runtime with a cryptic
132
+ # "FinalizationRegistry: cleanup must be callable" error.
133
+
134
+ echo "Verifying binary exports..."
135
+ # Temporarily disable set -e so we can capture the exit code and show a helpful message
136
+ set +e
137
+ VERIFY_RESULT=$(node -e "
138
+ const fs = require('fs');
139
+ const buf = fs.readFileSync('$OUTPUT');
140
+ WebAssembly.compile(buf).then(mod => {
141
+ const names = WebAssembly.Module.exports(mod).map(e => e.name);
142
+ const checks = {
143
+ '_initialize': names.includes('_initialize'),
144
+ 'canonical_abi_drop_rb-abi-value': names.includes('canonical_abi_drop_rb-abi-value'),
145
+ 'wasi_vfs_pack_fs': names.includes('wasi_vfs_pack_fs'),
146
+ };
147
+ const failed = Object.entries(checks).filter(([,v]) => !v).map(([k]) => k);
148
+ if (failed.length > 0) {
149
+ console.error('MISSING: ' + failed.join(', '));
150
+ process.exit(1);
151
+ }
152
+ console.log('OK: _initialize, canonical_abi_drop_rb-abi-value, wasi_vfs_pack_fs');
153
+ });
154
+ " 2>&1)
155
+ VERIFY_EXIT=$?
156
+ set -e
157
+
158
+ if [ $VERIFY_EXIT -ne 0 ]; then
159
+ echo
160
+ echo "ERROR: Binary is missing required exports!"
161
+ echo " $VERIFY_RESULT"
162
+ echo
163
+ echo "This usually means the 'js' gem was not statically linked."
164
+ echo "Check that 'bundle install' with Gemfile.base succeeded and that"
165
+ echo "the js gem version in Gemfile.base.lock matches what rbwasm resolved."
166
+ echo
167
+ echo "Try: rm -rf build/ rubies/ ruby-wasm/dist/ && re-run this script."
168
+ exit 1
169
+ fi
170
+
171
+ echo " $VERIFY_RESULT"
172
+
173
+ echo
174
+ echo "=== Build Complete ==="
175
+ echo " Output: $OUTPUT (raw pre-VFS binary)"
176
+ echo " Size: $SIZE"
177
+ echo " usr dir: $USR_DIR"
178
+ echo
179
+ echo "Now run 'npm run build:wasm:pack' to cross-compile gems and pack the final binary."
180
+ echo "(pack-gems will map /usr from the rubies/ directory for a single wasi-vfs pack)"
@@ -0,0 +1,13 @@
1
+ #!/bin/bash
2
+ set -e
3
+
4
+ TUTORIALKIT_PATH="${TUTORIALKIT_PATH:-../tutorialkit.rb}"
5
+
6
+ cat > pnpm-workspace.yaml << EOF
7
+ overrides:
8
+ '@tutorialkit-rb/runtime': link:${TUTORIALKIT_PATH}/packages/runtime
9
+ EOF
10
+
11
+ echo "Created pnpm-workspace.yaml with link to $TUTORIALKIT_PATH/packages/runtime"
12
+ pnpm install
13
+ echo "Local runtime linked. Remember to run 'npm run unlink:local' before committing."
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -e
3
+
4
+ rm -f pnpm-workspace.yaml
5
+ git checkout pnpm-lock.yaml 2>/dev/null || true
6
+ pnpm install
7
+ echo "Local packages unlinked. Lockfile restored."
@@ -0,0 +1,63 @@
1
+ # CORS Proxy for TutorialKit.rb
2
+
3
+ A minimal Cloudflare Worker that proxies HTTP requests and adds CORS headers. Use this when your tutorial needs to call APIs that don't include CORS headers in their responses.
4
+
5
+ ## Usage
6
+
7
+ Target URL is passed as the query string:
8
+
9
+ ```
10
+ GET https://your-proxy.workers.dev/proxy?https://api.example.com/data
11
+ POST https://your-proxy.workers.dev/proxy?https://api.example.com/submit
12
+ ```
13
+
14
+ ## Setup
15
+
16
+ ```bash
17
+ cd cors-proxy
18
+ npm install
19
+ ```
20
+
21
+ ## Development
22
+
23
+ ```bash
24
+ npm run dev
25
+ ```
26
+
27
+ ## Deployment
28
+
29
+ ### Manual
30
+
31
+ ```bash
32
+ npx wrangler login # one-time Cloudflare auth
33
+ npm run deploy
34
+ ```
35
+
36
+ ### GitHub Actions
37
+
38
+ The repository includes a `deploy-cors-proxy` workflow (manual trigger). It requires two repository secrets:
39
+
40
+ - `CLOUDFLARE_API_TOKEN` — API token with Workers write permissions
41
+ - `CLOUDFLARE_ACCOUNT_ID` — your Cloudflare account ID
42
+
43
+ ## Configuration
44
+
45
+ Set `ALLOWED_HOSTS` in `wrangler.toml` or via `wrangler secret` to restrict which target hosts can be proxied:
46
+
47
+ ```toml
48
+ [vars]
49
+ ALLOWED_HOSTS = "api.example.com,api.openai.com"
50
+ ```
51
+
52
+ Leave empty to allow all hosts.
53
+
54
+ ## Connecting to Your Tutorial
55
+
56
+ In a Rails initializer or environment config:
57
+
58
+ ```ruby
59
+ WasmHTTP::Connection.proxy_url = "https://your-proxy.workers.dev/proxy?"
60
+ WasmHTTP::Connection.proxy_hosts = ["api.example.com", "api.openai.com"]
61
+ ```
62
+
63
+ Requests to matching hosts will be routed through the proxy. All other requests go direct.