Skip to content

feat(tutorial): dnclBasics 前半 3 deck (display / variables / conditionals) (#964) - #1154

Open
smalruby3-editor-bot[bot] wants to merge 2 commits into
developfrom
topic/autopilot-964
Open

feat(tutorial): dnclBasics 前半 3 deck (display / variables / conditionals) (#964)#1154
smalruby3-editor-bot[bot] wants to merge 2 commits into
developfrom
topic/autopilot-964

Conversation

@smalruby3-editor-bot

Copy link
Copy Markdown

Summary

DNCL 軸(Phase 4, #681)の前半として dnclBasics カテゴリを新設し、3 deck を追加しました。

deck 学ぶこと
dncl-basics-1-display 表示する(...) で文字・数字・計算結果を表示する
dncl-basics-2-variables 変数への代入(= / )と、変数を使った計算・表示
dncl-basics-3-conditionals もし ... ならば / そうでなければ / そうでなくもし ... ならば

各 deck は setup.rubyMode: 'dncl' を持つので、開くと Ruby タブが日本語モードで開きます(利用者が先に「日本語(DNCL)」ボタンを探す必要がない)。

Changes Made

  • tutorial-tags.js: CATEGORIES.dnclBasicsdncl フィルタタグを追加
  • tag-messages.js / library.jsx / locales/{ja,ja-Hira,en}.js: カテゴリ・タグのラベル
  • categories/dncl.jsx / dncl.locale.js: stub を 3 deck ぶんの定義と locale で実装
  • step 画像 15 枚 + サムネイル 3 枚を追加、再生成スクリプト tools/playwright-verify/generate-dncl-basics-1-3-steps.mjs を同梱(ruby-basics の生成スクリプトと同じカードデザイン)
  • docs: docs/dncl/README.md(チュートリアル節を追加)/ docs/tutorial/README.md(主要ファイル)/ docs/tutorial/progress.md(Phase 4 を進行中に)/ tools/playwright-verify/README.md

設計上のポイント

deck の codeRuby のままで、エディタ側が rubyToDncl で日本語表記に変換して見せます。そのため deck の Ruby は puts("...") のように括弧付きの呼び出しで書いています(括弧なしの puts "..."表示する(...) に変換されず、日本語モードなのに英語が残ってしまう)。この不変条件はユニットテストで固定しました。

Test Coverage

新規 test/unit/lib/libraries/decks/dncl-basics-decks.test.js(TDD、RED → GREEN):

  1. deck 配線(カテゴリ / setup が DNCL モード / タグ / urlId / 画像)
  2. locale 網羅(すべての message id が ja / ja-Hira / en で解決)
  3. 実行可能性(各 step の code がエラーなくブロックに変換される)
  4. DNCL 可読性(Ruby スニペットが 表示する に変換され puts が残らない、DNCL → Ruby 往復がエラーなし)

tutorial-categories-refactor.test.js#932 の stub ガード)は dncl が stub でなくなったことに追従させました。

  • npm exec jest test/unit/lib/libraries/decks/ → 73 passed
  • npm run lint → scratch-gui 0 error / 0 warning(scratch-vm の 3 warning は既存・本 PR 対象外)、prettier OK

⚠️ 未実施: ブラウザでの起動・進行確認

Issue の DoD にある「Playwright で該当 deck の起動・進行を確認」は未実施です。本 worktree で dev server を起動しようとしたところ、同一コンテナで別 worktree の webpack が動いており OOM(exit 137)で起動できませんでした。レビュー / DoD フェーズでメモリに余裕のあるタイミングで、tipsLibrary に「DNCL のきほん」カテゴリが表示され、deck を開くと Ruby タブが DNCL モードになり、コード挿入 → 実行まで進めることを確認してください。

Related Issues

Closes #964
Refs #681

…tionals)

DNCL 軸 (Phase 4, #681) の前半として dnclBasics カテゴリを新設し、3 deck を追加する。

- tutorial-tags.js に CATEGORIES.dnclBasics と dncl フィルタタグを追加
- tag-messages.js / library.jsx / locales 3 ファイルにカテゴリ・タグのラベルを追加
- categories/dncl.jsx の stub を 3 deck で実装 (setup.rubyMode='dncl' で
  Ruby タブを日本語モードで開く)
- deck の code は Ruby のままエディタが rubyToDncl で日本語表示に変換するため、
  puts(...) は括弧付きで書く (括弧なしは 表示する(...) に変換されない)
- step 画像 15 枚 + サムネイル 3 枚を追加し、生成スクリプトを
  tools/playwright-verify/generate-dncl-basics-1-3-steps.mjs として残す
- deck 構造 / locale 網羅 / ブロック変換 / DNCL 往復のユニットテストを追加し、
  #932 の stub ガードテストを追従させた

Refs: #681
Closes #964

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@smalruby3-editor-bot smalruby3-editor-bot Bot added the 🤖 autopilot autopilot が処理対象にした Issue/PR(daemon が付与) label Aug 29, 2026
@smalruby3-editor-bot

smalruby3-editor-bot Bot commented Aug 29, 2026

Copy link
Copy Markdown
Author

🤖 autopilot status

field value
Status Review
AI Status
HITL Yes
Size middle

Linked issue #964. Maintained by autopilot (single writer); do not edit.

@github-actions

Copy link
Copy Markdown

🚀 Preview deployed: https://smalruby.jp/smalruby3-editor/topic/autopilot-964/

… works

DNCL モードの deck が挿入していた `when_flag_clicked do ... end` は DNCL 表記を
持たない。`rubyToDncl` は識別子を素通しし、逆方向の `dnclToRuby` はそれを変数と
解釈して `@when_flag_clicked do` に戻すため、ruby-tab がキー入力ごとに再変換する
(`dispatchCode`) 時点で構文エラーになり、ブロックが 1 つも生成されなくなる。
各 deck の最終ステップは「値を変えてみよう」と編集を促すので、チュートリアルの
中心動作がそのまま壊れていた。モード切替バリデータが `when_flag_clicked` を
弾いているのと同じ制約 (dncl-validation.test.js)。

- 9 つの snippet からハットを外し、トップレベルのスクリプトにする
- step3 の説明を緑の旗から ▶「すべて実行」に変更 (ja / ja-Hira / en)
- 効かない deck 単位の allowedBlocks を削除 (DNCL のパレットフィルタが優先され、
  DNCL を抜けたときだけ変数・演算子ブロックを隠す方向に食い違う)
- Ruby → DNCL → Ruby が恒等であること、ハットを含まないこと、allowedBlocks を
  持たないことを回帰テストで固定
- step 画像・サムネイルを生成スクリプトごと更新し、docs に制約を明記

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@smalruby3-editor-bot

Copy link
Copy Markdown
Author

[Must] deck の snippet が when_flag_clicked do ... end を使っており、利用者が 1 文字編集した瞬間にチュートリアルが壊れる(修正済み: 073c7e9

ハットブロックには DNCL 表記が無い。rubyToDncl は識別子をそのまま素通しするので画面上は
when_flag_clicked do のまま表示されるが、逆方向の dnclToRuby はそれを変数と解釈して
@ を付ける
。ruby-tab は DNCL モードではキー入力のたびにエディタのテキストから Ruby を
作り直す(containers/ruby-tab.jsxdispatchCodednclToRubyonChange)ため、
編集した瞬間に不正な Ruby が VM 側に渡る。

実際に確認した挙動(dncl-basics-1-display step2 の snippet で、文字列を「やあ」に変えただけ):

--- エディタ表示 (DNCL) ---
when_flag_clicked do
  表示する("やあ")
を実行する
--- dnclToRuby の出力 ---
@when_flag_clicked do
  puts("やあ")
end
--- RubyToBlocksConverter ---
result=false
errors=[{"text":"unexpected 'do', expecting end-of-input"},
        {"text":"unexpected 'do', ignoring it"},
        {"text":"Extra `end` found.\nRemove the unnecessary `end`."}]
blocks=[]

つまりブロックが 1 つも生成されず、赤エラーが出る。各 deck の最終ステップは
「ことばや数字を好きなものに変えて…」「変数の名前や値を変えて…」と編集を促している
ので、
チュートリアルの中心動作がそのまま壊れていた。

これは既知の制約でもある。test/unit/lib/dncl/dncl-validation.test.js
when_flag_clicked breaks in DNCL round-trip があり、エディタ自身は
when_flag_clicked を含むコードの DNCL モード切替を拒否する
。deck はその「モードが
受け付けないコード」を挿入していたことになる。

修正内容

  • 9 つの snippet からハットを外してトップレベルスクリプトにした。ハット無しの DNCL は
    round trip が恒等になり(tensuu = 80@tensuu = 80)、ブロック変換も通る
    data_setvariableto / looks_sayforsecs / … を確認)
  • ハット無しスクリプトの実行導線は緑の旗ではなく Ruby ツールバーの
    ▶「すべて実行」(DNCL モードでは handleExecuteLine が全トップレベルスクリプトを
    stackClick で実行する)なので、各 deck step3 の説明を ▶ に変更(ja / ja-Hira / en)
  • step 画像・サムネイルを生成スクリプトごと更新(カードの表示も実際の
    rubyToDncl 出力と一致させた)
  • docs/dncl/README.md / docs/tutorial/README.md に「ハットを書かない」制約を明記
  • 回帰テストを追加: Ruby → DNCL → Ruby が恒等であること、snippet が when_*
    含まないこと

@smalruby3-editor-bot

Copy link
Copy Markdown
Author

[Question] deck 単位の allowedBlocks が「DNCL のパレットフィルタと一致」というコメントと食い違っていた(修正済み: 073c7e9、方針は要確認)

元の DNCL_ALLOWED_BLOCKS

// DNCL programs only need "say" (表示する) and the green-flag hat; keeping the
// palette this small matches the DNCL block filter the editor applies in DNCL mode.

とあるが、実際の DNCL フィルタ(src/lib/dncl/dncl-block-filter.js)とは一致していない:

deck の allowedBlocks dncl-block-filter.js
event_whenflagclicked ✅ 含む ❌ 含まない
looks_say ✅ 含む ❌(looks_sayforsecs のみ)
operator_* ❌ 空 ✅ 全部
data_*(変数) ❌ 無し ✅ 全部

さらに containers/blocks.jsx では dnclMode のフィルタが tutorialAllowedBlocks より
絶対優先
if (this.props.dnclMode) { onlyBlocks = DNCL_ALLOWED_BLOCKS.join(',') } が先に
効き、if (!onlyBlocks && this.props.tutorialAllowedBlocks) は走らない)。つまりこのリストは
チュートリアル中は完全に無効で、利用者が DNCL モードを抜けたときだけ効き、そのときは
deck 2/3 が生成する変数・演算子ブロックをパレットから隠す方向に食い違う。

deck 定義から削除し、テストで「持たないこと」を固定した。もし将来 DNCL モードを抜けた
状態でも deck ごとにパレットを絞りたい意図があるなら
、この判断は差し戻して
dncl-block-filter.js に揃えたリストを置く形にしてほしい(ruby-basics 系が同じ形の
allowedBlocks を持っているので、それに合わせる選択もありうる)。

@smalruby3-editor-bot

Copy link
Copy Markdown
Author

[Question] Issue #964 の DoD「Playwright で該当 deck の起動・進行を確認」の証跡が無い(未対応 / 人間の判断に委ねる)

  • 追加された tools/playwright-verify/generate-dncl-basics-1-3-steps.mjs は README にも
    「検証ではなく素材生成」と書かれているとおり画像生成スクリプトで、deck の
    起動・進行を確認するものではない。
  • したがって「deck を開く → setup.rubyMode: 'dncl' で Ruby タブが日本語モードになる →
    コード挿入ボタンで snippet が入る → ▶ で実行できる」という一連の流れを実機で通した
    記録が無い
    。上の [Must] は、まさにこの通し確認をしていれば最初に踏むはずの不具合だった。

このレビューでは代替として、実物の rubyToDncl / dnclToRuby / RubyToBlocksConverter
使った unit レベルで挿入 → 表示 → 編集 → ブロック変換の経路を確認し、恒等 round trip を
回帰テストに固定した。ただし UI の通し確認そのものは行えていない: 8601 で動いている
dev server はこのブランチを配信しておらず(gui.jsdncl-basics-1-display が含まれない)、
このワークツリー用にもう 1 つ webpack dev server を立てると、稼働中のものと重い
ビルドが競合するため見送った。

対応コストの判断(別ポートで dev server を立てるか、CI に組み込むか)は人間にお願いしたい。

@smalruby3-editor-bot

Copy link
Copy Markdown
Author

[FYI] ja-steps.js のコメントが en-steps.js からのコピペのまま

packages/scratch-gui/src/lib/libraries/decks/ja-steps.js:

// DNCL Basics 1-3 (issue #964). The DNCL decks are Japanese-only content, so
// the en bundle reuses the same cards.

「the en bundle reuses the same cards」は en-steps.js 側の説明なので、ja 側に
そのまま置かれていると読み手が混乱する(ja 側は「流用元」であって「流用先」ではない)。
コードには影響しないので今回は触っていない。

[FYI] en-steps.js / ja-steps.js の末尾エントリだけ trailing comma になっている

dnclBasics3Step5: dnclBasics3Step5, と、直前まで(rubyBasics7TryRuby など)が
末尾カンマ無しなのに対してスタイルが混在している。これらのファイルは
.prettierignore のホワイトリスト外(src/lib/libraries/decks/*categories/
green-flag-icon.jsx だけが対象)なので Prettier が正規化してくれず、差分として残る。
eslint は通るので今回は触っていない。

[FYI] locale 完全性の assertion がやや遠回り

test/unit/lib/libraries/decks/dncl-basics-decks.test.js:

expect(`${locale}:${table[id] || ''}`.length).toBeGreaterThan(locale.length + 1);

「値が空文字でない」ことを言いたいだけなら expect(table[id]).not.toBe('') の方が
意図が読める(失敗時のメッセージも直接的)。動作は正しいので今回は触っていない。

@smalruby3-editor-bot

Copy link
Copy Markdown
Author

🤖 敵対的レビュー完了。指摘 6 件(Must 1 / Question 2 / FYI 3)。Must は修正済み(073c7e90b7)。Question のうち allowedBlocks は同コミットで対応済み(方針の是非のみ要確認)、Playwright 通し確認は未対応で人間の判断に委ねる。FYI 3 件はコード変更なし。lint / prettier 緑、test/unit/lib/libraries/decks/ 82 件・test/unit/lib/dncl 系 364 件 pass。

@smalruby3-editor-bot smalruby3-editor-bot Bot added the 🙋 HITL 人間の対応待ち(Project HITL=Yes の投影) label Aug 29, 2026
@smalruby3-editor-bot
smalruby3-editor-bot Bot marked this pull request as ready for review August 29, 2026 04:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🤖 autopilot autopilot が処理対象にした Issue/PR(daemon が付与) 🙋 HITL 人間の対応待ち(Project HITL=Yes の投影)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(tutorial): dnclBasics 前半 (display / variables / conditionals)

0 participants