@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,389 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: tutorial-lesson-config
|
|
3
|
+
description: |
|
|
4
|
+
Use this skill whenever configuring lesson frontmatter or checking inheritance rules.
|
|
5
|
+
Trigger on: 'frontmatter', 'prepareCommands', 'mainCommand', 'editor config', 'terminal
|
|
6
|
+
config', 'preview config', 'configuration inheritance', 'focus file', 'i18n', 'allowEdits',
|
|
7
|
+
'previews', 'autoReload', 'scope', 'defaults', 'what inherits', 'does X inherit',
|
|
8
|
+
'invalid combination', 'constraint', or any YAML frontmatter question — even without
|
|
9
|
+
mentioning configuration. Authoritative reference for all frontmatter options, inheritance
|
|
10
|
+
rules, defaults, and invalid-combination constraints with Rails-specific patterns. Do NOT
|
|
11
|
+
guess frontmatter without this skill. Do NOT use for content hierarchy
|
|
12
|
+
(use tutorial-content-structure) or file organization (use rails-file-management).
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# Tutorial Lesson Configuration
|
|
16
|
+
|
|
17
|
+
Complete reference for configuring lessons, with Rails-specific defaults and patterns.
|
|
18
|
+
|
|
19
|
+
## Configuration Cascade
|
|
20
|
+
|
|
21
|
+
Configuration **inherits downward**: Tutorial > Part > Chapter > Lesson. Set shared defaults at the tutorial level; override per-lesson as needed.
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
meta.md (type: tutorial) ← base defaults for all lessons
|
|
25
|
+
meta.md (type: part) ← overrides for this part's lessons
|
|
26
|
+
meta.md (type: chapter) ← overrides for this chapter's lessons
|
|
27
|
+
content.md (type: lesson) ← final per-lesson overrides
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
**Rails convention:** Set these once in the tutorial root `meta.md`:
|
|
31
|
+
|
|
32
|
+
```yaml
|
|
33
|
+
prepareCommands:
|
|
34
|
+
- ['npm install', 'Preparing Ruby runtime']
|
|
35
|
+
terminalBlockingPrepareCommandsCount: 1
|
|
36
|
+
previews: false
|
|
37
|
+
filesystem:
|
|
38
|
+
watch: ['/*.json', '/workspace/**/*']
|
|
39
|
+
terminal:
|
|
40
|
+
open: true
|
|
41
|
+
panels:
|
|
42
|
+
- type: terminal
|
|
43
|
+
id: 'cmds'
|
|
44
|
+
title: 'Command Line'
|
|
45
|
+
allowRedirects: true
|
|
46
|
+
- ['output', 'Setup Logs']
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Then override only what changes per-lesson (e.g., enable `previews: [3000]` for lessons with a running server).
|
|
50
|
+
|
|
51
|
+
## Inheritance Rules
|
|
52
|
+
|
|
53
|
+
### Properties That Inherit (via cascade)
|
|
54
|
+
|
|
55
|
+
These properties are resolved through the cascade (Tutorial → Part → Chapter → Lesson). The **most specific** (lesson-level) value wins. For plain objects, child and parent are deep-merged; for arrays and primitives, the child **replaces** the parent entirely.
|
|
56
|
+
|
|
57
|
+
| Property | Merge behavior |
|
|
58
|
+
|----------|---------------|
|
|
59
|
+
| `mainCommand` | Replace |
|
|
60
|
+
| `prepareCommands` | **Replace** (not merge — if a lesson sets this, it completely overrides the parent) |
|
|
61
|
+
| `terminalBlockingPrepareCommandsCount` | Replace |
|
|
62
|
+
| `previews` | Replace |
|
|
63
|
+
| `autoReload` | Replace |
|
|
64
|
+
| `template` | Replace |
|
|
65
|
+
| `terminal` | Deep-merge if both are objects; replace if either is a primitive (`true`/`false`) |
|
|
66
|
+
| `editor` | Deep-merge if both are objects; replace if either is a primitive |
|
|
67
|
+
| `focus` | Replace |
|
|
68
|
+
| `i18n` | Deep-merge (lesson keys override parent keys; unset keys fall through) |
|
|
69
|
+
| `meta` | Deep-merge |
|
|
70
|
+
| `editPageLink` | Replace |
|
|
71
|
+
| `openInStackBlitz` | Replace |
|
|
72
|
+
| `downloadAsZip` | Replace |
|
|
73
|
+
| `filesystem` | Deep-merge |
|
|
74
|
+
|
|
75
|
+
### Properties That Do NOT Inherit
|
|
76
|
+
|
|
77
|
+
These are **per-lesson only** and must be set on each lesson that needs them:
|
|
78
|
+
|
|
79
|
+
| Property | Why no inheritance |
|
|
80
|
+
|----------|-------------------|
|
|
81
|
+
| `custom` (including `custom.shell.workdir`) | Not in the cascade — set it on every lesson |
|
|
82
|
+
| `scope` | Lesson-specific file tree filter |
|
|
83
|
+
| `hideRoot` | Lesson-specific file tree option |
|
|
84
|
+
|
|
85
|
+
**Critical:** `custom.shell.workdir` must be set on **every lesson** that needs a custom terminal working directory. It will NOT be inherited from a part or tutorial `meta.md`.
|
|
86
|
+
|
|
87
|
+
**Critical:** When a lesson overrides `prepareCommands`, it **replaces** the entire array from the parent. If the tutorial root sets `prepareCommands: [['npm install', 'Preparing Ruby runtime']]` and a lesson needs to add `db:prepare`, the lesson must include **both** commands:
|
|
88
|
+
|
|
89
|
+
```yaml
|
|
90
|
+
# WRONG — npm install is lost
|
|
91
|
+
prepareCommands:
|
|
92
|
+
- ['node scripts/rails.js db:prepare', 'Prepare database']
|
|
93
|
+
|
|
94
|
+
# CORRECT — include all commands
|
|
95
|
+
prepareCommands:
|
|
96
|
+
- ['npm install', 'Preparing Ruby runtime']
|
|
97
|
+
- ['node scripts/rails.js db:prepare', 'Prepare database']
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Editor Configuration
|
|
101
|
+
|
|
102
|
+
### Show/Hide Editor
|
|
103
|
+
|
|
104
|
+
```yaml
|
|
105
|
+
editor: false # Hide editor entirely (terminal-only lessons)
|
|
106
|
+
editor: true # Show editor (default)
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### File Tree Options
|
|
110
|
+
|
|
111
|
+
```yaml
|
|
112
|
+
editor:
|
|
113
|
+
fileTree: false # Hide file tree, show only editor tabs
|
|
114
|
+
fileTree:
|
|
115
|
+
allowEdits: true # Allow creating files/folders anywhere
|
|
116
|
+
allowEdits: "/workspace/**" # Allow edits matching glob
|
|
117
|
+
allowEdits: # Multiple glob patterns
|
|
118
|
+
- "/workspace/app/**"
|
|
119
|
+
- "/workspace/config/**"
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Focus File
|
|
123
|
+
|
|
124
|
+
Auto-open a specific file in the editor when the lesson loads:
|
|
125
|
+
|
|
126
|
+
```yaml
|
|
127
|
+
focus: /workspace/app/controllers/products_controller.rb
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
**Path must be absolute** from the WebContainer root. For Rails apps, this is typically `/workspace/<app-name>/...`.
|
|
131
|
+
|
|
132
|
+
### File Tree Scope and Root
|
|
133
|
+
|
|
134
|
+
```yaml
|
|
135
|
+
scope: /workspace # Only show files under this path in the tree
|
|
136
|
+
hideRoot: true # Hide the "/" root node (default: true)
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
`scope` is useful to avoid exposing infrastructure files (`bin/`, `lib/`, `scripts/`) to tutorial users.
|
|
140
|
+
|
|
141
|
+
## Terminal Configuration
|
|
142
|
+
|
|
143
|
+
### Basic
|
|
144
|
+
|
|
145
|
+
```yaml
|
|
146
|
+
terminal: false # Hide terminal entirely
|
|
147
|
+
terminal: true # Show with defaults
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Panel Configuration
|
|
151
|
+
|
|
152
|
+
```yaml
|
|
153
|
+
terminal:
|
|
154
|
+
open: true # Open terminal panel by default
|
|
155
|
+
activePanel: 0 # Which tab is active (0-indexed)
|
|
156
|
+
panels:
|
|
157
|
+
- type: terminal # Interactive terminal
|
|
158
|
+
id: 'cmds' # Persistent session ID (survives lesson navigation)
|
|
159
|
+
title: 'Command Line'
|
|
160
|
+
allowRedirects: true
|
|
161
|
+
allowCommands: # Restrict allowed commands (optional)
|
|
162
|
+
- rails
|
|
163
|
+
- ruby
|
|
164
|
+
- node
|
|
165
|
+
- type: output # Read-only output panel (max 1 per lesson)
|
|
166
|
+
title: 'Setup Logs'
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
**Shorthand panel syntax:**
|
|
170
|
+
|
|
171
|
+
```yaml
|
|
172
|
+
panels:
|
|
173
|
+
- terminal # Interactive terminal, default title
|
|
174
|
+
- output # Read-only output, default title
|
|
175
|
+
- [terminal, "Rails Console"] # Interactive with custom title
|
|
176
|
+
- ['output', 'Setup Logs'] # Read-only with custom title
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
**Persistent sessions:** Use `id` to keep terminal state across lesson navigation. The user's terminal history and running processes persist when they switch between lessons that share the same `id`.
|
|
180
|
+
|
|
181
|
+
### Output Panel
|
|
182
|
+
|
|
183
|
+
Only **one** `output` panel is allowed per lesson. It captures output from `prepareCommands` and `mainCommand`.
|
|
184
|
+
|
|
185
|
+
## Preview Configuration
|
|
186
|
+
|
|
187
|
+
### Basic
|
|
188
|
+
|
|
189
|
+
```yaml
|
|
190
|
+
previews: false # No preview panel
|
|
191
|
+
previews: true # Auto-detect preview
|
|
192
|
+
previews: [3000] # Show preview for port 3000
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### Advanced
|
|
196
|
+
|
|
197
|
+
```yaml
|
|
198
|
+
previews:
|
|
199
|
+
- 3000 # Port only
|
|
200
|
+
- "3000/products" # Port with pathname
|
|
201
|
+
- [3000, "Rails App"] # Port with title
|
|
202
|
+
- [3000, "Rails App", "/products"] # Port, title, pathname
|
|
203
|
+
- { port: 3000, title: "App", pathname: "/products" } # Object form
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### Auto-Reload
|
|
207
|
+
|
|
208
|
+
```yaml
|
|
209
|
+
autoReload: true # Force preview reload when navigating to this lesson
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
Useful for lessons where the preview state may be stale from a previous lesson.
|
|
213
|
+
|
|
214
|
+
## Commands
|
|
215
|
+
|
|
216
|
+
### prepareCommands
|
|
217
|
+
|
|
218
|
+
Commands that run **before** the lesson is interactive. Shown as progress steps to the user:
|
|
219
|
+
|
|
220
|
+
```yaml
|
|
221
|
+
prepareCommands:
|
|
222
|
+
- 'npm install' # String form
|
|
223
|
+
- ['npm install', 'Preparing Ruby runtime'] # [command, label]
|
|
224
|
+
- { command: 'node scripts/rails.js db:prepare', title: 'Preparing database' } # Object form
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
**Rails patterns:**
|
|
228
|
+
|
|
229
|
+
```yaml
|
|
230
|
+
# Basic — just install WASM runtime (set at tutorial level)
|
|
231
|
+
prepareCommands:
|
|
232
|
+
- ['npm install', 'Preparing Ruby runtime']
|
|
233
|
+
|
|
234
|
+
# With database — for lessons that need migrations/seeds
|
|
235
|
+
prepareCommands:
|
|
236
|
+
- ['npm install', 'Preparing Ruby runtime']
|
|
237
|
+
- ['node scripts/rails.js db:prepare', 'Prepare development database']
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
### terminalBlockingPrepareCommandsCount
|
|
241
|
+
|
|
242
|
+
How many `prepareCommands` must finish before the terminal becomes interactive:
|
|
243
|
+
|
|
244
|
+
```yaml
|
|
245
|
+
terminalBlockingPrepareCommandsCount: 1 # Block until npm install finishes
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
### mainCommand
|
|
249
|
+
|
|
250
|
+
The primary long-running process (usually the dev server). Runs after all `prepareCommands` complete:
|
|
251
|
+
|
|
252
|
+
```yaml
|
|
253
|
+
mainCommand: ['node scripts/rails.js server', 'Starting Rails server']
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
**Important:** Use `node scripts/rails.js server` — not `rails server` — because the Rails CLI dispatches through Node.js wrapper scripts in this WASM environment.
|
|
257
|
+
|
|
258
|
+
## Filesystem Watching
|
|
259
|
+
|
|
260
|
+
```yaml
|
|
261
|
+
filesystem:
|
|
262
|
+
watch: true # Watch all files
|
|
263
|
+
watch: ['/*.json', '/workspace/**/*'] # Watch specific patterns
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
For Rails tutorials, watch `/workspace/**/*` so the preview reflects file changes in the Rails app.
|
|
267
|
+
|
|
268
|
+
## Defaults
|
|
269
|
+
|
|
270
|
+
When a property is not set at any level in the cascade, these defaults apply:
|
|
271
|
+
|
|
272
|
+
| Property | Default | Effect |
|
|
273
|
+
|----------|---------|--------|
|
|
274
|
+
| `template` | `'default'` | Uses the base Rails WASM runtime template |
|
|
275
|
+
| `editor` | (unset) | Editor is shown with default file tree |
|
|
276
|
+
| `terminal` | (unset) | One read-only "Output" panel, initially closed |
|
|
277
|
+
| `previews` | `true` | Auto-detect: shows preview for the first port that opens |
|
|
278
|
+
| `autoReload` | (unset) | Preview is not force-reloaded on navigation |
|
|
279
|
+
| `focus` | (unset) | No file auto-opened in editor |
|
|
280
|
+
| `openInStackBlitz` | `true` | "Open in StackBlitz" button shown |
|
|
281
|
+
| `downloadAsZip` | `false` | Download button hidden |
|
|
282
|
+
| `mainCommand` | (unset) | No long-running process started |
|
|
283
|
+
| `prepareCommands` | (unset) | No preparation steps |
|
|
284
|
+
| `filesystem.watch` | (unset) | No file watching |
|
|
285
|
+
| `scope` | (unset) | All files visible in tree |
|
|
286
|
+
| `hideRoot` | `true` | Root "/" node hidden in file tree |
|
|
287
|
+
| `custom` | (unset) | No custom fields |
|
|
288
|
+
|
|
289
|
+
## Constraints
|
|
290
|
+
|
|
291
|
+
Invalid or problematic frontmatter combinations that cause silent failures:
|
|
292
|
+
|
|
293
|
+
| Combination | Problem | Fix |
|
|
294
|
+
|-------------|---------|-----|
|
|
295
|
+
| `focus: /path/...` with `editor: false` | Focus is silently ignored — no editor to open the file in | Remove `focus` or set `editor: true` |
|
|
296
|
+
| `previews: [3000]` without `mainCommand` | Nothing starts a server on port 3000 — preview stays blank | Add `mainCommand: ['node scripts/rails.js server', 'Starting Rails server']` |
|
|
297
|
+
| `mainCommand: 'rails server'` | Bare `rails` won't work — commands must go through the Node.js wrapper | Use `mainCommand: ['node scripts/rails.js server', 'Starting Rails server']` |
|
|
298
|
+
| Lesson `prepareCommands` without `npm install` | WASM runtime never loads — everything else fails | Always include `['npm install', 'Preparing Ruby runtime']` as the first prepare command |
|
|
299
|
+
| `previews` without `prepareCommands` including `npm install` | Runtime not loaded, server can't start | Add `prepareCommands` with `npm install` (or inherit from tutorial root) |
|
|
300
|
+
| `terminal: false` with `mainCommand` set | Terminal hidden but `mainCommand` still runs — output is invisible | Either show terminal or remove `mainCommand` |
|
|
301
|
+
| `custom.shell.workdir` set only in `meta.md` | `custom` doesn't inherit — terminal won't cd in lessons | Set `custom.shell.workdir` on each lesson's `content.md` |
|
|
302
|
+
|
|
303
|
+
## Other Options
|
|
304
|
+
|
|
305
|
+
### Custom Shell Working Directory
|
|
306
|
+
|
|
307
|
+
```yaml
|
|
308
|
+
custom:
|
|
309
|
+
shell:
|
|
310
|
+
workdir: "/workspace"
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
Sets the terminal's working directory by sending `cd /home/tutorial<workdir> && clear` to the first terminal panel on lesson load. The path is constructed by prepending `/home/tutorial` to the `workdir` value, so `workdir: "/workspace"` sends `cd /home/tutorial/workspace && clear`. This is a **Rails-tutorial-specific** feature (implemented via `ShellConfigurator` in this template, not upstream TutorialKit). Essential for Rails tutorials where the app lives at `/workspace`.
|
|
314
|
+
|
|
315
|
+
**Does not inherit.** Must be set on every lesson that needs it (see Inheritance Rules above).
|
|
316
|
+
|
|
317
|
+
### Template Selection
|
|
318
|
+
|
|
319
|
+
```yaml
|
|
320
|
+
template: default # Use the default (base Rails) template
|
|
321
|
+
template: rails-app # Use a template with pre-generated Rails app
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
Templates live in `src/templates/`. Each lesson can also override via `_files/.tk-config.json`.
|
|
325
|
+
|
|
326
|
+
### Download and StackBlitz
|
|
327
|
+
|
|
328
|
+
```yaml
|
|
329
|
+
openInStackBlitz: false # Hide "Open in StackBlitz" button (default: true)
|
|
330
|
+
openInStackBlitz: # Object form with project customization
|
|
331
|
+
projectTitle: "My Rails Tutorial"
|
|
332
|
+
projectDescription: "A Rails CRUD app"
|
|
333
|
+
projectTemplate: "node" # html | node | angular-cli | create-react-app | javascript | polymer | typescript | vue
|
|
334
|
+
downloadAsZip: true # Allow downloading lesson code (default: false)
|
|
335
|
+
downloadAsZip:
|
|
336
|
+
filename: "rails-crud-app" # Custom zip filename
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
### Edit Page Link
|
|
340
|
+
|
|
341
|
+
```yaml
|
|
342
|
+
editPageLink: "https://github.com/your-org/your-tutorial/edit/main/src/content/tutorial/${path}"
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
### Meta Tags
|
|
346
|
+
|
|
347
|
+
```yaml
|
|
348
|
+
meta:
|
|
349
|
+
title: "Learn Rails CRUD Operations"
|
|
350
|
+
description: "Build a product catalog with full CRUD in Ruby on Rails"
|
|
351
|
+
image: "/og-image.png"
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
## i18n — Customize UI Text
|
|
355
|
+
|
|
356
|
+
Override any UI label at any level in the cascade:
|
|
357
|
+
|
|
358
|
+
```yaml
|
|
359
|
+
i18n:
|
|
360
|
+
solveButtonText: "Show Answer"
|
|
361
|
+
resetButtonText: "Start Over"
|
|
362
|
+
prepareEnvironmentTitleText: "Setting Up Rails"
|
|
363
|
+
toggleTerminalButtonText: "Terminal"
|
|
364
|
+
defaultPreviewTitleText: "Rails App"
|
|
365
|
+
startWebContainerText: "Launch Tutorial"
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
All available keys:
|
|
369
|
+
|
|
370
|
+
| Key | Default |
|
|
371
|
+
|-----|---------|
|
|
372
|
+
| `partTemplate` | `"Part ${index}: ${title}"` |
|
|
373
|
+
| `editPageText` | `"Edit this page"` |
|
|
374
|
+
| `webcontainerLinkText` | `"Powered by WebContainers"` |
|
|
375
|
+
| `startWebContainerText` | `"Run this tutorial"` |
|
|
376
|
+
| `noPreviewNorStepsText` | `"No preview to run nor steps to show"` |
|
|
377
|
+
| `filesTitleText` | `"Files"` |
|
|
378
|
+
| `fileTreeCreateFileText` | `"Create file"` |
|
|
379
|
+
| `fileTreeCreateFolderText` | `"Create folder"` |
|
|
380
|
+
| `fileTreeActionNotAllowedText` | `"This action is not allowed"` |
|
|
381
|
+
| `fileTreeFileExistsAlreadyText` | `"File exists on filesystem already"` |
|
|
382
|
+
| `fileTreeAllowedPatternsText` | `"Created files and folders must match following patterns:"` |
|
|
383
|
+
| `confirmationText` | `"OK"` |
|
|
384
|
+
| `prepareEnvironmentTitleText` | `"Preparing Environment"` |
|
|
385
|
+
| `defaultPreviewTitleText` | `"Preview"` |
|
|
386
|
+
| `reloadPreviewTitle` | `"Reload Preview"` |
|
|
387
|
+
| `toggleTerminalButtonText` | `"Toggle Terminal"` |
|
|
388
|
+
| `solveButtonText` | `"Solve"` |
|
|
389
|
+
| `resetButtonText` | `"Reset"` |
|