@tutorialkit-rb/cli 0.1.5 → 0.1.8
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.
- package/dist/index.js +47 -38
- package/package.json +1 -1
- package/template/.claude/skills/rails-file-management/SKILL.md +211 -0
- package/template/.claude/skills/rails-lesson-recipes/SKILL.md +415 -0
- package/template/.claude/skills/rails-wasm-author-constraints/SKILL.md +181 -0
- package/template/.claude/skills/tutorial-content-structure/SKILL.md +377 -0
- package/template/.claude/skills/tutorial-lesson-config/SKILL.md +389 -0
- package/template/.claude/skills/tutorial-quickstart/SKILL.md +440 -0
- package/template/.github/workflows/deploy.yml +85 -0
- package/template/.gitignore +10 -0
- package/template/CLAUDE.md +47 -0
- package/template/astro.config.ts +12 -0
- package/template/bin/build-pack +84 -0
- package/template/bin/build-ruby-base +180 -0
- package/template/bin/link-local +13 -0
- package/template/bin/unlink-local +7 -0
- package/template/cors-proxy/README.md +63 -0
- package/template/cors-proxy/package-lock.json +1504 -0
- package/template/cors-proxy/package.json +12 -0
- package/template/cors-proxy/src/index.ts +87 -0
- package/template/cors-proxy/wrangler.toml +7 -0
- package/template/netlify.toml +9 -0
- package/template/package.json +12 -4
- package/template/ruby-wasm/Gemfile +6 -0
- package/template/ruby-wasm/Gemfile.base +19 -0
- package/template/ruby-wasm/Gemfile.base.lock +50 -0
- package/template/ruby-wasm/Gemfile.lock +8 -0
- package/template/ruby-wasm/bin/pack-gems +368 -0
- package/template/ruby-wasm/package.json +6 -0
- package/template/src/components/FileManager.tsx +33 -0
- package/template/src/components/HeadTags.astro +6 -6
- package/template/src/components/HelpDropdown.tsx +1 -1
- package/template/src/components/RailsPathLinkHandler.tsx +2 -2
- package/template/src/components/ShellConfigurator.tsx +6 -1
- package/template/src/content/tutorial/1-getting-started/1-creating-your-first-rails-app/content.md +4 -4
- package/template/src/content/tutorial/1-getting-started/2-rails-console/content.md +4 -4
- package/template/src/content/tutorial/2-controllers/2-crud-operations/content.md +2 -2
- package/template/src/content/tutorial/9-outbound-http/1-making-http-requests/_files/.tk-config.json +3 -0
- package/template/src/content/tutorial/9-outbound-http/1-making-http-requests/_files/workspace/app/controllers/http_demo_controller.rb +65 -0
- package/template/src/content/tutorial/9-outbound-http/1-making-http-requests/_files/workspace/app/views/http_demo/index.html.erb +172 -0
- package/template/src/content/tutorial/9-outbound-http/1-making-http-requests/_files/workspace/config/routes.rb +8 -0
- package/template/src/content/tutorial/9-outbound-http/1-making-http-requests/content.md +97 -0
- package/template/src/content/tutorial/9-outbound-http/meta.md +4 -0
- package/template/src/content/tutorial/meta.md +5 -0
- package/template/src/middleware.ts +14 -0
- package/template/src/templates/default/lib/boot-progress.js +49 -0
- package/template/src/templates/default/lib/http-bridge.js +55 -0
- package/template/src/templates/default/lib/patches/http_bridge.rb +167 -0
- package/template/src/templates/default/lib/rails.js +52 -5
- package/template/src/templates/default/lib/server.js +33 -1
- package/template/src/templates/default/package.json +4 -1
- package/template/src/templates/default/scripts/rails.js +1 -1
- package/template/src/templates/default/scripts/smoke-test.js +349 -0
- package/template/src/templates/default/scripts/wasi-loader.mjs +10 -0
- package/template/src/templates/default/workspace/_debug_app/.github/dependabot.yml +12 -0
- package/template/src/templates/default/workspace/_debug_app/.github/workflows/ci.yml +51 -0
- package/template/src/templates/default/workspace/_debug_app/.ruby-version +1 -0
- package/template/src/templates/default/workspace/_debug_app/Gemfile +37 -0
- package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/app/views/layouts/application.html.erb +1 -2
- package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/app/views/pwa/manifest.json.erb +2 -2
- package/template/src/templates/default/workspace/_debug_app/bin/dev +2 -0
- package/template/src/templates/default/workspace/_debug_app/bin/rake +4 -0
- package/template/src/templates/default/workspace/_debug_app/bin/setup +34 -0
- package/template/src/templates/default/workspace/_debug_app/config/application.rb +30 -0
- package/template/src/templates/default/workspace/_debug_app/config/cable.yml +10 -0
- package/template/src/templates/default/workspace/_debug_app/config/credentials.yml.enc +1 -0
- package/template/src/templates/default/workspace/_debug_app/config/master.key +1 -0
- package/template/src/templates/default/workspace/_debug_app/config/routes.rb +14 -0
- package/template/src/templates/default/workspace/_debug_app/test/models/.keep +0 -0
- package/template/src/templates/default/workspace/_debug_app/test/test_helper.rb +15 -0
- package/template/src/templates/default/workspace/_debug_app/tmp/.keep +0 -0
- package/template/src/templates/default/workspace/_debug_app/tmp/pids/.keep +0 -0
- package/template/src/templates/default/workspace/_debug_app/tmp/storage/.keep +0 -0
- package/template/src/templates/default/workspace/_debug_app/vendor/.keep +0 -0
- package/template/src/templates/rails-app/workspace/README.md +24 -0
- package/template/src/templates/rails-app/workspace/Rakefile +6 -0
- package/template/src/templates/rails-app/workspace/app/assets/images/.keep +0 -0
- package/template/src/templates/rails-app/workspace/app/assets/stylesheets/application.css +534 -0
- package/template/src/templates/rails-app/workspace/app/controllers/application_controller.rb +2 -0
- package/template/src/templates/rails-app/workspace/app/helpers/application_helper.rb +2 -0
- package/template/src/templates/rails-app/workspace/app/jobs/application_job.rb +7 -0
- package/template/src/templates/rails-app/workspace/app/mailers/application_mailer.rb +4 -0
- package/template/src/templates/rails-app/workspace/app/models/application_record.rb +3 -0
- package/template/src/templates/rails-app/workspace/app/models/concerns/.keep +0 -0
- package/template/src/templates/rails-app/workspace/app/views/layouts/application.html.erb +38 -0
- package/template/src/templates/rails-app/workspace/app/views/layouts/mailer.html.erb +13 -0
- package/template/src/templates/rails-app/workspace/app/views/layouts/mailer.text.erb +1 -0
- package/template/src/templates/rails-app/workspace/bin/rails +4 -0
- package/template/src/templates/rails-app/workspace/{store/config → config}/application.rb +1 -1
- package/template/src/templates/rails-app/workspace/config/boot.rb +3 -0
- package/template/src/templates/rails-app/workspace/config/database.yml +32 -0
- package/template/src/templates/rails-app/workspace/config/environment.rb +5 -0
- package/template/src/templates/rails-app/workspace/config/environments/development.rb +69 -0
- package/template/src/templates/rails-app/workspace/config/environments/production.rb +89 -0
- package/template/src/templates/rails-app/workspace/config/environments/test.rb +54 -0
- package/template/src/templates/rails-app/workspace/config/initializers/assets.rb +7 -0
- package/template/src/templates/rails-app/workspace/config/initializers/content_security_policy.rb +25 -0
- package/template/src/templates/rails-app/workspace/config/initializers/filter_parameter_logging.rb +8 -0
- package/template/src/templates/rails-app/workspace/config/initializers/inflections.rb +16 -0
- package/template/src/templates/rails-app/workspace/config/locales/en.yml +31 -0
- package/template/src/templates/rails-app/workspace/config/puma.rb +41 -0
- package/template/src/templates/rails-app/workspace/{store/config → config}/routes.rb +1 -1
- package/template/src/templates/rails-app/workspace/config/storage.yml +34 -0
- package/template/src/templates/rails-app/workspace/config.ru +6 -0
- package/template/src/templates/rails-app/workspace/db/seeds.rb +9 -0
- package/template/src/templates/rails-app/workspace/log/.keep +0 -0
- package/template/src/templates/rails-app/workspace/public/400.html +114 -0
- package/template/src/templates/rails-app/workspace/public/404.html +114 -0
- package/template/src/templates/rails-app/workspace/public/406-unsupported-browser.html +114 -0
- package/template/src/templates/rails-app/workspace/public/422.html +114 -0
- package/template/src/templates/rails-app/workspace/public/500.html +114 -0
- package/template/src/templates/rails-app/workspace/public/icon.png +0 -0
- package/template/src/templates/rails-app/workspace/public/icon.svg +3 -0
- package/template/src/templates/rails-app/workspace/public/robots.txt +1 -0
- package/template/src/templates/rails-app/workspace/script/.keep +0 -0
- package/template/src/templates/rails-app/workspace/storage/.keep +0 -0
- package/template/src/templates/rails-app/workspace/test/controllers/.keep +0 -0
- package/template/src/templates/rails-app/workspace/test/helpers/.keep +0 -0
- package/template/src/templates/rails-app/workspace/test/integration/.keep +0 -0
- package/template/src/templates/rails-app/workspace/tmp/.keep +0 -0
- package/template/src/templates/rails-app/workspace/tmp/cache/.keep +0 -0
- package/template/src/templates/rails-app/workspace/tmp/pids/.keep +0 -0
- package/template/src/templates/rails-app/workspace/tmp/sockets/.keep +0 -0
- package/template/src/templates/rails-app/workspace/tmp/storage/.keep +0 -0
- package/template/src/templates/rails-app/workspace/vendor/javascripts/.keep +0 -0
- package/template/tsconfig.json +3 -1
- package/template/uno.config.ts +17 -0
- /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/README.md +0 -0
- /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/Rakefile +0 -0
- /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/app/assets/images/.keep +0 -0
- /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/app/assets/stylesheets/application.css +0 -0
- /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/app/controllers/application_controller.rb +0 -0
- /package/template/src/templates/{rails-app/workspace/store/app/models → default/workspace/_debug_app/app/controllers}/concerns/.keep +0 -0
- /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/app/helpers/application_helper.rb +0 -0
- /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/app/jobs/application_job.rb +0 -0
- /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/app/mailers/application_mailer.rb +0 -0
- /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/app/models/application_record.rb +0 -0
- /package/template/src/templates/{rails-app/workspace/store/log → default/workspace/_debug_app/app/models/concerns}/.keep +0 -0
- /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/app/views/layouts/mailer.html.erb +0 -0
- /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/app/views/layouts/mailer.text.erb +0 -0
- /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/app/views/pwa/service-worker.js +0 -0
- /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/bin/rails +0 -0
- /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/config/boot.rb +0 -0
- /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/config/database.yml +0 -0
- /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/config/environment.rb +0 -0
- /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/config/environments/development.rb +0 -0
- /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/config/environments/production.rb +0 -0
- /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/config/environments/test.rb +0 -0
- /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/config/initializers/assets.rb +0 -0
- /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/config/initializers/content_security_policy.rb +0 -0
- /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/config/initializers/filter_parameter_logging.rb +0 -0
- /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/config/initializers/inflections.rb +0 -0
- /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/config/locales/en.yml +0 -0
- /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/config/puma.rb +0 -0
- /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/config/storage.yml +0 -0
- /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/config.ru +0 -0
- /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/db/seeds.rb +0 -0
- /package/template/src/templates/{rails-app/workspace/store/script → default/workspace/_debug_app/lib/tasks}/.keep +0 -0
- /package/template/src/templates/{rails-app/workspace/store/storage → default/workspace/_debug_app/log}/.keep +0 -0
- /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/public/400.html +0 -0
- /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/public/404.html +0 -0
- /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/public/406-unsupported-browser.html +0 -0
- /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/public/422.html +0 -0
- /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/public/500.html +0 -0
- /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/public/icon.png +0 -0
- /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/public/icon.svg +0 -0
- /package/template/src/templates/{rails-app/workspace/store → default/workspace/_debug_app}/public/robots.txt +0 -0
- /package/template/src/templates/{rails-app/workspace/store/test/controllers → default/workspace/_debug_app/script}/.keep +0 -0
- /package/template/src/templates/{rails-app/workspace/store/test/helpers → default/workspace/_debug_app/storage}/.keep +0 -0
- /package/template/src/templates/{rails-app/workspace/store/test/integration → default/workspace/_debug_app/test/controllers}/.keep +0 -0
- /package/template/src/templates/{rails-app/workspace/store/tmp → default/workspace/_debug_app/test/fixtures/files}/.keep +0 -0
- /package/template/src/templates/{rails-app/workspace/store/tmp/pids → default/workspace/_debug_app/test/helpers}/.keep +0 -0
- /package/template/src/templates/{rails-app/workspace/store/tmp/storage → default/workspace/_debug_app/test/integration}/.keep +0 -0
- /package/template/src/templates/{rails-app/workspace/store/vendor/javascripts → default/workspace/_debug_app/test/mailers}/.keep +0 -0
- /package/template/src/templates/rails-app/workspace/{store/.ruby-version → .ruby-version} +0 -0
- /package/template/src/templates/rails-app/workspace/{store/Gemfile → Gemfile} +0 -0
- /package/template/src/templates/rails-app/workspace/{store/app → app}/javascript/application.js +0 -0
- /package/template/src/templates/rails-app/workspace/{store/app → app}/javascript/controllers/application.js +0 -0
- /package/template/src/templates/rails-app/workspace/{store/app → app}/javascript/controllers/index.js +0 -0
- /package/template/src/templates/rails-app/workspace/{store/bin → bin}/importmap +0 -0
- /package/template/src/templates/rails-app/workspace/{store/config → config}/cable.yml +0 -0
- /package/template/src/templates/rails-app/workspace/{store/config → config}/credentials.yml.enc +0 -0
- /package/template/src/templates/rails-app/workspace/{store/config → config}/importmap.rb +0 -0
- /package/template/src/templates/rails-app/workspace/{store/config → config}/master.key +0 -0
- /package/template/src/templates/rails-app/workspace/{store/test → test}/test_helper.rb +0 -0
|
@@ -0,0 +1,440 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: tutorial-quickstart
|
|
3
|
+
description: |
|
|
4
|
+
Use this skill whenever starting a new tutorial project, understanding the end-to-end
|
|
5
|
+
workflow from scaffold to deployment, or working with the rails-app template's built-in
|
|
6
|
+
features. Trigger when the user says 'new tutorial', 'create tutorial', 'getting started',
|
|
7
|
+
'npx create-tutorialkit-rb', 'scaffold', 'first lesson', 'deploy tutorial', 'build:wasm',
|
|
8
|
+
'COEP headers', 'COOP headers', 'hosting setup', 'CSS classes', 'BEM components',
|
|
9
|
+
'design system', 'application.css', 'customize demo app', 'rails-app template',
|
|
10
|
+
'branding', 'logo', 'favicon', 'accent color', 'theme color', 'look and feel',
|
|
11
|
+
'customize colors', or asks how to set up, build, style, brand, or deploy a Rails
|
|
12
|
+
tutorial from scratch — even if they don't explicitly mention quickstart. This skill
|
|
13
|
+
provides the exact CLI commands, project structure, WASM build steps, rails-app template
|
|
14
|
+
features (CSS design system, layout), branding customization (logos, favicons, accent
|
|
15
|
+
colors, top bar title, component colors), demo app customization steps, deployment header
|
|
16
|
+
configuration, and common issue troubleshooting. Do NOT attempt project setup or deployment
|
|
17
|
+
without this skill. Do NOT use for detailed frontmatter reference (use tutorial-lesson-config)
|
|
18
|
+
or WASM compatibility questions (use rails-wasm-author-constraints).
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
# Tutorial Quickstart
|
|
22
|
+
|
|
23
|
+
End-to-end guide: scaffold a project, write your first lesson, and deploy.
|
|
24
|
+
|
|
25
|
+
## Step 1: Scaffold
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
npx create-tutorialkit-rb my-tutorial
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
The CLI prompts for:
|
|
32
|
+
|
|
33
|
+
| Prompt | Default | Notes |
|
|
34
|
+
|--------|---------|-------|
|
|
35
|
+
| Tutorial name | random (e.g., "fierce-turtle") | Used as `package.json` name |
|
|
36
|
+
| Directory | `./{name}` | Where files are created |
|
|
37
|
+
| Hosting provider | Skip | Vercel, Netlify, or Cloudflare — adds COEP/COOP headers |
|
|
38
|
+
| Package manager | npm | npm, yarn, pnpm, or bun |
|
|
39
|
+
| Init git repo? | Yes | Creates initial commit |
|
|
40
|
+
| Edit Gemfile? | Yes | Opens `ruby-wasm/Gemfile` in `$EDITOR` |
|
|
41
|
+
|
|
42
|
+
Skip all prompts with `--defaults`, or pass flags directly:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
npx create-tutorialkit-rb my-tutorial -p pnpm --provider netlify --git
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### What Gets Created
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
my-tutorial/
|
|
52
|
+
├── src/
|
|
53
|
+
│ ├── content/tutorial/ ← Your tutorial content goes here
|
|
54
|
+
│ │ ├── meta.md ← Tutorial root config (already set up)
|
|
55
|
+
│ │ └── 1-getting-started/ ← Sample part with starter lessons
|
|
56
|
+
│ ├── templates/default/ ← WebContainer runtime (don't modify)
|
|
57
|
+
│ └── components/ ← UI components
|
|
58
|
+
├── ruby-wasm/
|
|
59
|
+
│ └── Gemfile ← Add gems here, then rebuild WASM
|
|
60
|
+
├── bin/build-wasm ← Rebuilds the WASM binary
|
|
61
|
+
├── astro.config.ts
|
|
62
|
+
└── package.json
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Step 2: Add Your Gems
|
|
66
|
+
|
|
67
|
+
Edit `ruby-wasm/Gemfile` to include the gems your tutorial needs:
|
|
68
|
+
|
|
69
|
+
```ruby
|
|
70
|
+
# ruby-wasm/Gemfile
|
|
71
|
+
source "https://rubygems.org"
|
|
72
|
+
|
|
73
|
+
gem "wasmify-rails", "~> 0.4.0"
|
|
74
|
+
gem "rails", "~> 8.0.0"
|
|
75
|
+
|
|
76
|
+
# Your tutorial's gems
|
|
77
|
+
gem "action_policy"
|
|
78
|
+
gem "devise"
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Then build the WASM binary:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
npm run build:wasm # Takes up to 20 minutes on first run
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Subsequent rebuilds are faster thanks to caching, but still take a few minutes.
|
|
88
|
+
|
|
89
|
+
## Step 3: Start the Dev Server
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
npm run dev # Starts at http://localhost:4321/
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
The sample tutorial loads immediately. You'll see the starter lessons from the scaffold.
|
|
96
|
+
|
|
97
|
+
## Step 4: Write Your First Lesson
|
|
98
|
+
|
|
99
|
+
### 4a. Create the Directory Structure
|
|
100
|
+
|
|
101
|
+
```
|
|
102
|
+
src/content/tutorial/
|
|
103
|
+
├── meta.md ← Already exists (tutorial root)
|
|
104
|
+
└── 1-basics/
|
|
105
|
+
├── meta.md ← Part metadata
|
|
106
|
+
└── 1-hello-rails/
|
|
107
|
+
├── content.md ← Your lesson
|
|
108
|
+
├── _files/ ← Starting code
|
|
109
|
+
│ └── workspace/
|
|
110
|
+
│ └── app/
|
|
111
|
+
│ └── controllers/
|
|
112
|
+
│ └── pages_controller.rb
|
|
113
|
+
└── _solution/ ← Solution code
|
|
114
|
+
└── workspace/
|
|
115
|
+
└── app/
|
|
116
|
+
└── controllers/
|
|
117
|
+
└── pages_controller.rb
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### 4b. Write the Part Metadata
|
|
121
|
+
|
|
122
|
+
```yaml
|
|
123
|
+
# src/content/tutorial/1-basics/meta.md
|
|
124
|
+
---
|
|
125
|
+
type: part
|
|
126
|
+
title: The Basics
|
|
127
|
+
---
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### 4c. Write the Lesson
|
|
131
|
+
|
|
132
|
+
```yaml
|
|
133
|
+
# src/content/tutorial/1-basics/1-hello-rails/content.md
|
|
134
|
+
---
|
|
135
|
+
type: lesson
|
|
136
|
+
title: Hello Rails
|
|
137
|
+
focus: /workspace/app/controllers/pages_controller.rb
|
|
138
|
+
previews: [3000]
|
|
139
|
+
mainCommand: ['node scripts/rails.js server', 'Starting Rails server']
|
|
140
|
+
prepareCommands:
|
|
141
|
+
- ['npm install', 'Preparing Ruby runtime']
|
|
142
|
+
- ['node scripts/rails.js db:prepare', 'Prepare development database']
|
|
143
|
+
terminalBlockingPrepareCommandsCount: 2
|
|
144
|
+
custom:
|
|
145
|
+
shell:
|
|
146
|
+
workdir: '/workspace'
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
# Hello Rails
|
|
150
|
+
|
|
151
|
+
Open `app/controllers/pages_controller.rb` and add a `home` action:
|
|
152
|
+
|
|
153
|
+
\`\`\`ruby title="app/controllers/pages_controller.rb" ins={2-4}
|
|
154
|
+
class PagesController < ApplicationController
|
|
155
|
+
def home
|
|
156
|
+
render plain: "Hello from Rails on WebAssembly!"
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
\`\`\`
|
|
160
|
+
|
|
161
|
+
Visit the preview to see your message.
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### 4d. Add Starting Files
|
|
165
|
+
|
|
166
|
+
Put a skeleton file in `_files/`:
|
|
167
|
+
|
|
168
|
+
```ruby
|
|
169
|
+
# _files/workspace/app/controllers/pages_controller.rb
|
|
170
|
+
class PagesController < ApplicationController
|
|
171
|
+
# Add your action here
|
|
172
|
+
end
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### 4e. Add Solution Files
|
|
176
|
+
|
|
177
|
+
Put the completed code in `_solution/`:
|
|
178
|
+
|
|
179
|
+
```ruby
|
|
180
|
+
# _solution/workspace/app/controllers/pages_controller.rb
|
|
181
|
+
class PagesController < ApplicationController
|
|
182
|
+
def home
|
|
183
|
+
render plain: "Hello from Rails on WebAssembly!"
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### 4f. Delete the Sample Content
|
|
189
|
+
|
|
190
|
+
Remove the scaffold's starter lessons once you have your own:
|
|
191
|
+
|
|
192
|
+
```bash
|
|
193
|
+
rm -rf src/content/tutorial/1-getting-started/
|
|
194
|
+
rm -rf src/content/tutorial/2-controllers/
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
## The `rails-app` Template
|
|
198
|
+
|
|
199
|
+
The scaffold includes a pre-built `rails-app` template at `src/templates/rails-app/` with a minimal Rails app skeleton and CSS design system. Most tutorials should extend this template rather than building from scratch.
|
|
200
|
+
|
|
201
|
+
### What's Included
|
|
202
|
+
|
|
203
|
+
- **CSS design system** — modern BEM-based stylesheet with CSS custom properties
|
|
204
|
+
- **Layout** — nav bar with brand name; flash messages; `.container` wrapper
|
|
205
|
+
- **Minimal app skeleton** — `ApplicationController`, basic layout, empty routes and seeds
|
|
206
|
+
|
|
207
|
+
The template is intentionally minimal. Tutorial-specific features like authentication, models, controllers, and views should be added via lesson `_files/` overlays or custom templates that extend `rails-app`.
|
|
208
|
+
|
|
209
|
+
### CSS Design System
|
|
210
|
+
|
|
211
|
+
The template's `application.css` uses pure CSS with custom properties and BEM naming. Use these classes in your lesson ERB files — no extra setup needed.
|
|
212
|
+
|
|
213
|
+
**CSS Custom Properties (`:root` variables):**
|
|
214
|
+
|
|
215
|
+
| Category | Variables | Example |
|
|
216
|
+
|----------|-----------|---------|
|
|
217
|
+
| Colors | `--color-primary`, `--color-danger`, `--color-success`, `--color-warning`, `--color-info` | `color: var(--color-primary)` |
|
|
218
|
+
| Text | `--color-text`, `--color-text-muted`, `--color-text-inverse` | `color: var(--color-text-muted)` |
|
|
219
|
+
| Background | `--color-bg`, `--color-bg-white`, `--color-border` | `background: var(--color-bg)` |
|
|
220
|
+
| Spacing | `--space-xs` through `--space-2xl` | `padding: var(--space-md)` |
|
|
221
|
+
| Typography | `--font-sans`, `--font-mono`, `--font-size-sm` through `--font-size-3xl` | `font-size: var(--font-size-lg)` |
|
|
222
|
+
| Radius | `--radius-sm` through `--radius-xl` | `border-radius: var(--radius-md)` |
|
|
223
|
+
| Shadows | `--shadow-sm`, `--shadow-md` | `box-shadow: var(--shadow-sm)` |
|
|
224
|
+
|
|
225
|
+
**BEM Components:**
|
|
226
|
+
|
|
227
|
+
| Component | Classes | Usage |
|
|
228
|
+
|-----------|---------|-------|
|
|
229
|
+
| Button | `.btn`, `.btn--primary`, `.btn--danger`, `.btn--small`, `.btn--link` | Links, submits, actions |
|
|
230
|
+
| Input | `.input`, `.input--error` | Text fields, selects, textareas |
|
|
231
|
+
| Card | `.card`, `.card__header`, `.card__body`, `.card__footer` | Content containers |
|
|
232
|
+
| Alert | `.alert`, `.alert--error`, `.alert--success`, `.alert--info`, `.alert--warning` | Flash messages, notices |
|
|
233
|
+
| Badge | `.badge`, `.badge--primary`, `.badge--success`, `.badge--danger`, `.badge--warning` | Status labels, role tags |
|
|
234
|
+
| Nav | `.nav`, `.nav__brand`, `.nav__link`, `.nav__user` | Top navigation (in layout) |
|
|
235
|
+
| Form | `.form__group`, `.form__label`, `.form__hint`, `.form__errors`, `.form__actions` | Form layout |
|
|
236
|
+
| Table | `.table` | Data tables with hover rows |
|
|
237
|
+
| Page header | `.page-header` | Title + action button row |
|
|
238
|
+
| Hero | `.hero`, `.hero__title`, `.hero__subtitle`, `.hero__actions` | Landing/home pages |
|
|
239
|
+
| Utility | `.text-muted`, `.text-sm`, `.mt-md`, `.mb-md`, `.inline-actions`, `.container` | Spacing, text helpers |
|
|
240
|
+
|
|
241
|
+
### Customizing the Demo App for Your Domain
|
|
242
|
+
|
|
243
|
+
To turn the generic demo app into your tutorial's domain (e.g., a Help Desk, a Store, etc.):
|
|
244
|
+
|
|
245
|
+
**1. Rename the app module** in `config/application.rb`:
|
|
246
|
+
|
|
247
|
+
```ruby
|
|
248
|
+
module Helpdesk # was DemoApp
|
|
249
|
+
class Application < Rails::Application
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
**2. Add your models.** Create migrations in `db/migrate/` and models in `app/models/`. Update `db/schema.rb` to match.
|
|
253
|
+
|
|
254
|
+
**3. Add controllers and views.** Put CRUD controllers in `app/controllers/` and ERB views in `app/views/`. Use the BEM classes from the CSS design system.
|
|
255
|
+
|
|
256
|
+
**4. Update routes** in `config/routes.rb`.
|
|
257
|
+
|
|
258
|
+
**5. Update seeds** in `db/seeds.rb` with sample data for your domain.
|
|
259
|
+
|
|
260
|
+
**6. Update the layout** — change the brand name in `app/views/layouts/application.html.erb`, add nav links for your resources.
|
|
261
|
+
|
|
262
|
+
## Step 5: Use a Template for Pre-Built State
|
|
263
|
+
|
|
264
|
+
If your lesson needs an existing Rails app (not just an empty workspace), create a template:
|
|
265
|
+
|
|
266
|
+
```
|
|
267
|
+
src/templates/my-app/
|
|
268
|
+
├── .tk-config.json → { "extends": "../default" }
|
|
269
|
+
└── workspace/
|
|
270
|
+
├── app/
|
|
271
|
+
├── config/
|
|
272
|
+
├── db/
|
|
273
|
+
└── ...
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
Then reference it from your lesson's `_files/.tk-config.json`:
|
|
277
|
+
|
|
278
|
+
```json
|
|
279
|
+
{
|
|
280
|
+
"extends": "../../../../../templates/my-app"
|
|
281
|
+
}
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
See the `rails-file-management` skill for details on template inheritance.
|
|
285
|
+
|
|
286
|
+
## Step 6: Deploy
|
|
287
|
+
|
|
288
|
+
Tutorials need **Cross-Origin-Embedder-Policy** and **Cross-Origin-Opener-Policy** headers for WebContainers to work. If you chose a hosting provider during scaffold, these are already configured.
|
|
289
|
+
|
|
290
|
+
### Build for Production
|
|
291
|
+
|
|
292
|
+
```bash
|
|
293
|
+
npm run build # Produces a static site in dist/
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
### Manual Header Configuration
|
|
297
|
+
|
|
298
|
+
If you didn't choose a provider during scaffold, add these headers to every response:
|
|
299
|
+
|
|
300
|
+
```
|
|
301
|
+
Cross-Origin-Embedder-Policy: require-corp
|
|
302
|
+
Cross-Origin-Opener-Policy: same-origin
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
#### Vercel (`vercel.json`)
|
|
306
|
+
|
|
307
|
+
```json
|
|
308
|
+
{
|
|
309
|
+
"headers": [
|
|
310
|
+
{
|
|
311
|
+
"source": "/(.*)",
|
|
312
|
+
"headers": [
|
|
313
|
+
{ "key": "Cross-Origin-Embedder-Policy", "value": "require-corp" },
|
|
314
|
+
{ "key": "Cross-Origin-Opener-Policy", "value": "same-origin" }
|
|
315
|
+
]
|
|
316
|
+
}
|
|
317
|
+
]
|
|
318
|
+
}
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
#### Netlify (`netlify.toml`)
|
|
322
|
+
|
|
323
|
+
```toml
|
|
324
|
+
[[headers]]
|
|
325
|
+
for = "/*"
|
|
326
|
+
[headers.values]
|
|
327
|
+
Cross-Origin-Embedder-Policy = "require-corp"
|
|
328
|
+
Cross-Origin-Opener-Policy = "same-origin"
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
#### Cloudflare (`public/_headers`)
|
|
332
|
+
|
|
333
|
+
```
|
|
334
|
+
/*
|
|
335
|
+
Cross-Origin-Embedder-Policy: require-corp
|
|
336
|
+
Cross-Origin-Opener-Policy: same-origin
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
## Customizing Look & Feel (Branding)
|
|
340
|
+
|
|
341
|
+
To match your tutorial's branding to your project's documentation site, update these files:
|
|
342
|
+
|
|
343
|
+
### Logos
|
|
344
|
+
|
|
345
|
+
Replace `public/logo.svg` (light mode) and `public/logo-dark.svg` (dark mode) with your project's logo SVG. Use a dark fill (e.g., `#0F4D8A`) for the light-mode version and a light fill (e.g., `#E4E6E9`) for the dark-mode version.
|
|
346
|
+
|
|
347
|
+
### Title in Top Bar
|
|
348
|
+
|
|
349
|
+
Edit `src/components/TopBar.astro` — add a `<span>` after the logo images inside the `<a>` tag:
|
|
350
|
+
|
|
351
|
+
```html
|
|
352
|
+
<span class="ml-2 text-sm font-medium text-tk-elements-topBar-iconButton-iconColor whitespace-nowrap">
|
|
353
|
+
Your Tutorial Title
|
|
354
|
+
</span>
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
### Favicon
|
|
358
|
+
|
|
359
|
+
Replace `public/favicon.svg` with your project's icon. Optionally add a `public/favicon.ico` for broader browser support.
|
|
360
|
+
|
|
361
|
+
### Accent Colors (UnoCSS Theme)
|
|
362
|
+
|
|
363
|
+
Override the `accent` palette in `uno.config.ts` to change buttons, links, active tabs, and badges site-wide:
|
|
364
|
+
|
|
365
|
+
```ts
|
|
366
|
+
import { defineConfig } from '@tutorialkit-rb/theme';
|
|
367
|
+
|
|
368
|
+
export default defineConfig({
|
|
369
|
+
theme: {
|
|
370
|
+
colors: {
|
|
371
|
+
accent: {
|
|
372
|
+
50: '#EFF6FF',
|
|
373
|
+
100: '#E5F0FF',
|
|
374
|
+
200: '#B6D4FF',
|
|
375
|
+
300: '#75B5FF',
|
|
376
|
+
400: '#4DA6FF', // dark mode accent
|
|
377
|
+
500: '#0E7EF1', // primary interactive
|
|
378
|
+
600: '#0F4D8A', // primary brand
|
|
379
|
+
700: '#0C3F72',
|
|
380
|
+
800: '#09325A',
|
|
381
|
+
900: '#072848',
|
|
382
|
+
950: '#041A30',
|
|
383
|
+
},
|
|
384
|
+
},
|
|
385
|
+
},
|
|
386
|
+
content: {
|
|
387
|
+
pipeline: { include: '**' },
|
|
388
|
+
},
|
|
389
|
+
});
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
Generate your scale from your brand's primary color. The `600` slot is the main brand color; `500` is for hover/interactive states; `400` is used in dark mode.
|
|
393
|
+
|
|
394
|
+
### Component Hardcoded Colors
|
|
395
|
+
|
|
396
|
+
Some components use hardcoded Tailwind color classes instead of theme tokens. Search for and replace these:
|
|
397
|
+
|
|
398
|
+
- **`src/components/HelpDropdown.tsx`** — Reload button uses `bg-blue-600`. Change to `bg-accent-600 hover:bg-accent-700`.
|
|
399
|
+
- **`src/components/HeadTags.astro`** — Rails path link colors. Update hex values to match your brand.
|
|
400
|
+
|
|
401
|
+
### Rails Demo App CSS
|
|
402
|
+
|
|
403
|
+
Update the primary color in `src/templates/rails-app/workspace/app/assets/stylesheets/application.css`:
|
|
404
|
+
|
|
405
|
+
```css
|
|
406
|
+
:root {
|
|
407
|
+
--color-primary: #0F4D8A; /* your brand color */
|
|
408
|
+
--color-primary-hover: #0C3F72; /* darker shade */
|
|
409
|
+
--color-primary-light: #EFF6FF; /* tinted background */
|
|
410
|
+
}
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
### GitHub Link
|
|
414
|
+
|
|
415
|
+
Update the repo URL in `src/components/GitHubLink.astro`:
|
|
416
|
+
|
|
417
|
+
```html
|
|
418
|
+
<a href="https://github.com/your-org/your-repo" ...>
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
## Common Issues
|
|
422
|
+
|
|
423
|
+
| Problem | Cause | Fix |
|
|
424
|
+
|---------|-------|-----|
|
|
425
|
+
| `build:wasm` fails | Missing WASI SDK or build tools | Check `rbwasm` prerequisites |
|
|
426
|
+
| Preview shows nothing | Server not started | Add `mainCommand: ['node scripts/rails.js server', ...]` |
|
|
427
|
+
| Terminal stuck on "Preparing" | WASM binary not built | Run `npm run build:wasm` first |
|
|
428
|
+
| Files not appearing in editor | Wrong path | All Rails files must be under `workspace/<app>/` |
|
|
429
|
+
| Database empty | No `db:prepare` in prepareCommands | Add `['node scripts/rails.js db:prepare', '...']` |
|
|
430
|
+
| Deploy fails with blank page | Missing COEP/COOP headers | Add headers per provider instructions above |
|
|
431
|
+
|
|
432
|
+
## Next Steps
|
|
433
|
+
|
|
434
|
+
| Want to... | See skill |
|
|
435
|
+
|------------|-----------|
|
|
436
|
+
| Structure parts, chapters, lessons | `tutorial-content-structure` |
|
|
437
|
+
| Configure frontmatter options | `tutorial-lesson-config` |
|
|
438
|
+
| Organize Rails files properly | `rails-file-management` |
|
|
439
|
+
| Check if a feature works in WASM | `rails-wasm-author-constraints` |
|
|
440
|
+
| Get a recipe for a specific lesson type | `rails-lesson-recipes` |
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
name: Deploy Tutorial
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
|
|
8
|
+
concurrency:
|
|
9
|
+
group: deploy
|
|
10
|
+
cancel-in-progress: false
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
build:
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
|
|
18
|
+
- uses: actions-rust-lang/setup-rust-toolchain@v1
|
|
19
|
+
with:
|
|
20
|
+
toolchain: 1.74.0
|
|
21
|
+
|
|
22
|
+
- name: Install wasi-vfs
|
|
23
|
+
env:
|
|
24
|
+
WASI_VFS_VERSION: 0.5.4
|
|
25
|
+
run: |
|
|
26
|
+
curl -LO "https://github.com/kateinoigakukun/wasi-vfs/releases/download/v${WASI_VFS_VERSION}/wasi-vfs-cli-x86_64-unknown-linux-gnu.zip"
|
|
27
|
+
unzip wasi-vfs-cli-x86_64-unknown-linux-gnu.zip
|
|
28
|
+
mv wasi-vfs /usr/local/bin/wasi-vfs
|
|
29
|
+
|
|
30
|
+
- uses: ruby/setup-ruby@v1
|
|
31
|
+
env:
|
|
32
|
+
BUNDLE_GEMFILE: ruby-wasm/Gemfile
|
|
33
|
+
BUNDLE_PATH: ruby-wasm/vendor
|
|
34
|
+
with:
|
|
35
|
+
ruby-version: 3.3
|
|
36
|
+
bundler-cache: true
|
|
37
|
+
|
|
38
|
+
- uses: actions/setup-node@v4
|
|
39
|
+
with:
|
|
40
|
+
node-version: 20
|
|
41
|
+
cache: npm
|
|
42
|
+
|
|
43
|
+
- name: Cache ruby.wasm build artifacts
|
|
44
|
+
uses: actions/cache@v4
|
|
45
|
+
with:
|
|
46
|
+
path: |
|
|
47
|
+
ruby-wasm/build
|
|
48
|
+
ruby-wasm/rubies
|
|
49
|
+
key: ${{ runner.os }}-ruby-wasm-${{ hashFiles('ruby-wasm/Gemfile.lock') }}
|
|
50
|
+
restore-keys: |
|
|
51
|
+
${{ runner.os }}-ruby-wasm-
|
|
52
|
+
|
|
53
|
+
- name: Build ruby.wasm
|
|
54
|
+
run: npm run build:wasm
|
|
55
|
+
|
|
56
|
+
- name: Build tutorial
|
|
57
|
+
run: |
|
|
58
|
+
npm install
|
|
59
|
+
npm run build
|
|
60
|
+
|
|
61
|
+
- name: Upload dist
|
|
62
|
+
uses: actions/upload-artifact@v4
|
|
63
|
+
with:
|
|
64
|
+
name: tutorial-dist
|
|
65
|
+
path: ./dist
|
|
66
|
+
|
|
67
|
+
deploy:
|
|
68
|
+
needs: build
|
|
69
|
+
runs-on: ubuntu-latest
|
|
70
|
+
steps:
|
|
71
|
+
- uses: actions/checkout@v4
|
|
72
|
+
|
|
73
|
+
- uses: actions/download-artifact@v4
|
|
74
|
+
with:
|
|
75
|
+
name: tutorial-dist
|
|
76
|
+
path: dist
|
|
77
|
+
|
|
78
|
+
- uses: nwtgck/actions-netlify@v3
|
|
79
|
+
with:
|
|
80
|
+
publish-dir: ./dist
|
|
81
|
+
netlify-config-path: ./netlify.toml
|
|
82
|
+
production-deploy: true
|
|
83
|
+
env:
|
|
84
|
+
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
|
|
85
|
+
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}
|
package/template/.gitignore
CHANGED
|
@@ -12,3 +12,13 @@ pnpm-debug.log*
|
|
|
12
12
|
|
|
13
13
|
public/ruby.wasm
|
|
14
14
|
public/ruby.wasm.hash
|
|
15
|
+
|
|
16
|
+
ruby-wasm/build
|
|
17
|
+
ruby-wasm/dist
|
|
18
|
+
ruby-wasm/tmp
|
|
19
|
+
ruby-wasm/vendor
|
|
20
|
+
ruby-wasm/.bundle
|
|
21
|
+
ruby-wasm/rubies
|
|
22
|
+
|
|
23
|
+
# Local development linking (created by npm run link:local)
|
|
24
|
+
pnpm-workspace.yaml
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Tutorial Authoring Guide
|
|
2
|
+
|
|
3
|
+
You are authoring an interactive Ruby on Rails tutorial that runs entirely in the browser using WebAssembly. Tutorial content lives in `src/content/tutorial/`. The Rails WASM runtime, templates, and infrastructure are already set up — your job is to write lessons.
|
|
4
|
+
|
|
5
|
+
## Project Layout
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
src/content/tutorial/ ← Your tutorial content (lessons, parts, chapters)
|
|
9
|
+
src/templates/ ← WebContainer file templates (base app states)
|
|
10
|
+
ruby-wasm/Gemfile ← Gems compiled into the WASM binary
|
|
11
|
+
bin/build-wasm ← Rebuild WASM after Gemfile changes
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Key Constraints
|
|
15
|
+
|
|
16
|
+
- **All Rails app files go under `workspace/`** — this is the WASI filesystem boundary
|
|
17
|
+
- **Each lesson should be self-contained** — don't rely on user actions from previous lessons persisting
|
|
18
|
+
- **Gems require a WASM rebuild** — edit `ruby-wasm/Gemfile`, then run `bin/build-wasm`
|
|
19
|
+
- **Outbound HTTP works** (`Net::HTTP`, Faraday, etc.) via JS fetch bridge — CORS restrictions apply, see `rails-wasm-author-constraints`
|
|
20
|
+
- **No threading or process spawning** from Ruby — see `rails-wasm-author-constraints`
|
|
21
|
+
- **Database resets on page reload** — use `prepareCommands` with `db:prepare` for lessons that need data
|
|
22
|
+
- **Use `node scripts/rails.js <cmd>`** in frontmatter commands, not bare `rails <cmd>`
|
|
23
|
+
|
|
24
|
+
## Development
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
npm install # Install dependencies (or pnpm/yarn/bun — whichever this project uses)
|
|
28
|
+
npm run dev # Start dev server at http://localhost:4321/
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Before Creating or Modifying Lessons
|
|
32
|
+
|
|
33
|
+
**MANDATORY:** Always invoke these skills before writing any lesson content:
|
|
34
|
+
|
|
35
|
+
- `rails-lesson-recipes` — lesson patterns, directory structures, and post-creation checklist
|
|
36
|
+
- `rails-file-management` — `_files/`, `_solution/`, template organization, and the file layering model
|
|
37
|
+
- `tutorial-lesson-config` — frontmatter options, inheritance rules, and invalid-combination constraints
|
|
38
|
+
|
|
39
|
+
Do NOT create lessons without loading these skills first. Incorrect structure causes silent runtime failures.
|
|
40
|
+
|
|
41
|
+
## Additional Skills
|
|
42
|
+
|
|
43
|
+
| Question | Skill |
|
|
44
|
+
|----------|-------|
|
|
45
|
+
| How do I start a new tutorial from scratch? | `tutorial-quickstart` |
|
|
46
|
+
| How do I structure parts, chapters, and lessons? | `tutorial-content-structure` |
|
|
47
|
+
| Can I teach feature X in WASM? | `rails-wasm-author-constraints` |
|
package/template/astro.config.ts
CHANGED
|
@@ -6,6 +6,18 @@ export default defineConfig({
|
|
|
6
6
|
devToolbar: {
|
|
7
7
|
enabled: false,
|
|
8
8
|
},
|
|
9
|
+
vite: {
|
|
10
|
+
server: {
|
|
11
|
+
watch: {
|
|
12
|
+
ignored: ['**/ruby-wasm/**'],
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
build: {
|
|
16
|
+
rollupOptions: {
|
|
17
|
+
external: [/ruby-wasm/],
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
},
|
|
9
21
|
integrations: [
|
|
10
22
|
tutorialkit({
|
|
11
23
|
components: {
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
set -e
|
|
4
|
+
|
|
5
|
+
# Dynamic gem packing: cross-compile gems and pack them into a pre-built
|
|
6
|
+
# Ruby WASM base binary via wasi-vfs.
|
|
7
|
+
#
|
|
8
|
+
# This is the fast path (~30s) compared to the monolithic `bin/build-wasm`
|
|
9
|
+
# (~5-20min). Requires a pre-built base binary (from bin/build-ruby-base
|
|
10
|
+
# or the @tutorialkit-rb/ruby-3.3 npm package).
|
|
11
|
+
#
|
|
12
|
+
# Usage: ./bin/build-pack
|
|
13
|
+
|
|
14
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
15
|
+
TEMPLATE_DIR="$(dirname "$SCRIPT_DIR")"
|
|
16
|
+
RUBY_WASM_DIR="$TEMPLATE_DIR/ruby-wasm"
|
|
17
|
+
|
|
18
|
+
echo "=== Dynamic gem packing ==="
|
|
19
|
+
echo
|
|
20
|
+
|
|
21
|
+
# --- Preflight checks --------------------------------------------------------
|
|
22
|
+
|
|
23
|
+
if ! command -v wasi-vfs &> /dev/null; then
|
|
24
|
+
echo "Error: wasi-vfs CLI not found"
|
|
25
|
+
echo "Install it with: cargo install wasi-vfs-cli"
|
|
26
|
+
echo "See: https://github.com/aspect-build/aspect-workflows/tree/main/packages/wasi-vfs"
|
|
27
|
+
exit 1
|
|
28
|
+
fi
|
|
29
|
+
|
|
30
|
+
# --- Resolve base binary -----------------------------------------------------
|
|
31
|
+
|
|
32
|
+
echo "Resolving base binary..."
|
|
33
|
+
BASE_WASM=""
|
|
34
|
+
|
|
35
|
+
# 1. Local build
|
|
36
|
+
if [ -f "$RUBY_WASM_DIR/dist/ruby-base.wasm" ]; then
|
|
37
|
+
BASE_WASM="$RUBY_WASM_DIR/dist/ruby-base.wasm"
|
|
38
|
+
echo " Found: local build (dist/ruby-base.wasm)"
|
|
39
|
+
fi
|
|
40
|
+
|
|
41
|
+
# 2. npm package fallback
|
|
42
|
+
if [ -z "$BASE_WASM" ]; then
|
|
43
|
+
NPM_BASE="$RUBY_WASM_DIR/node_modules/@tutorialkit-rb/ruby-3.3/dist/ruby-base.wasm"
|
|
44
|
+
if [ -f "$NPM_BASE" ]; then
|
|
45
|
+
BASE_WASM="$NPM_BASE"
|
|
46
|
+
echo " Found: @tutorialkit-rb/ruby-3.3 npm package"
|
|
47
|
+
fi
|
|
48
|
+
fi
|
|
49
|
+
|
|
50
|
+
if [ -z "$BASE_WASM" ]; then
|
|
51
|
+
echo
|
|
52
|
+
echo "Error: No base WASM binary found."
|
|
53
|
+
echo "Either run 'bin/build-ruby-base' to build one,"
|
|
54
|
+
echo "or install @tutorialkit-rb/ruby-3.3 npm package."
|
|
55
|
+
exit 1
|
|
56
|
+
fi
|
|
57
|
+
|
|
58
|
+
echo
|
|
59
|
+
|
|
60
|
+
# --- Cross-compile gems + pack -----------------------------------------------
|
|
61
|
+
|
|
62
|
+
echo "Installing host gems for cross-compilation..."
|
|
63
|
+
cd "$RUBY_WASM_DIR"
|
|
64
|
+
bundle install --path vendor/bundle
|
|
65
|
+
echo
|
|
66
|
+
|
|
67
|
+
echo "Running pack-gems..."
|
|
68
|
+
bundle exec ruby bin/pack-gems
|
|
69
|
+
echo
|
|
70
|
+
|
|
71
|
+
# --- Copy output to public/ --------------------------------------------------
|
|
72
|
+
|
|
73
|
+
echo "Copying ruby.wasm to public directory..."
|
|
74
|
+
cp "$RUBY_WASM_DIR/dist/ruby.wasm" "$TEMPLATE_DIR/public/ruby.wasm"
|
|
75
|
+
echo " ruby.wasm → public/"
|
|
76
|
+
|
|
77
|
+
# Generate hash of Gemfile.lock for cache versioning
|
|
78
|
+
GEMFILE_HASH=$(shasum -a 256 "$RUBY_WASM_DIR/Gemfile.lock" | cut -c1-16)
|
|
79
|
+
echo "$GEMFILE_HASH" > "$TEMPLATE_DIR/public/ruby.wasm.hash"
|
|
80
|
+
echo " ruby.wasm.hash: $GEMFILE_HASH"
|
|
81
|
+
|
|
82
|
+
echo
|
|
83
|
+
echo "=== Done ==="
|
|
84
|
+
echo "Run 'npm run dev' to test your tutorial."
|