Skip to content

feat: 甲子園拡張機能の本格対応 (Epic #738: MockClient + ゴールデン契約 + Ruby v2 + RemoteClient)#761

Merged
takaokouji merged 37 commits into
developfrom
topic/koshien-epic-738
Jun 30, 2026
Merged

feat: 甲子園拡張機能の本格対応 (Epic #738: MockClient + ゴールデン契約 + Ruby v2 + RemoteClient)#761
takaokouji merged 37 commits into
developfrom
topic/koshien-epic-738

Conversation

@smalruby3-editor-bot

@smalruby3-editor-bot smalruby3-editor-bot Bot commented Jun 28, 2026

Copy link
Copy Markdown

Summary

Epic #738「スモウルビー甲子園 拡張機能の本格対応」の取り込み PR。甲子園拡張機能を
「何もしないスタブ」から「未接続 = 意味のある固定値で動く / 接続 = 実ゲームサーバーと
実通信
」へ。差し替え可能な KoshienClient インターフェース + MockClient(オフライン)
/ RemoteClient(実サーバー HTTP)アーキテクチャ。

このトピックブランチ topic/koshien-epic-738 に、最新 develop(upstream v13.7.2 再整合
#749/#752 を含む)へ追従させた上で、以下 4 PR を順に統合済み。各 PR は develop 再整合後の
CI をすべて green で通している。

取り込んだ PR(マージ順)

Sub PR 内容
#739 #742 MockClient: オフラインで意味のある固定値/状態。実 17x17 マップ + fog-of-war + リセット
#740 #745 ゴールデン契約テスト基盤(実サーバー記録 fixture + 契約テスト)
#743 #744 Ruby v2 対応(when_connect_game イベント hat + リスト引数 $配列 構文)
#741 #746 RemoteClient: 実ゲームサーバー HTTP 通信 + 接続失敗時の MockClient フォールバック

develop 再整合への追従で行ったこと

4 PR は再整合(modern Blockly / scratch-blocks v2.1.19 への HAT/EVENT 描画作り直し)
develop に対して作られていたため、最新 develop を各ブランチに merge し直して CI を回した。
主な統合ポイント:

Test Coverage

Related Issues

Epic #738(Sub: #739 / #740 / #741 / #743

closes #738

takaokouji and others added 25 commits June 13, 2026 03:22
甲子園拡張機能のブロックがクリック/実行時に意味のある値を返すようにした。
KoshienClient をインターフェース化し、未接続時用の固定値クライアント
MockClient を実装してブロックメソッドを接続した(将来の RemoteClient と
差し替え可能な構造)。

- map=0(空間), mapAll=15x15 全空間文字列, mapFrom=マップ文字列をパース
- targetCoordinate: player=1:1 / goal=13:13 / other_player=enemy=7:7
- calcRoute/calcGoalRoute/locateObjects は指定リスト変数へ実際に書き込む
- getMapArea/moveTo/setItem/turnOver/setMessage は安全な no-op

Refs #739

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
甲子園拡張機能の calc_route / calc_goal_route / locate_objects は、リスト引数を
バージョン非依存で list("$名前") とハードコードしており、Ruby v2 では
「list() syntax is only available in Ruby version 1」エラーになっていた。

v2 ではリストはグローバル配列変数 $名前 で表現するため:
- generator: version === '2' のとき list("$名前") ではなく $名前 を出力
- converter: v2 では引数の配列変数 ($名前 = data_variable) を convertToListBlock で
  リスト化して受理 (v1 の list() ブロックと同じリスト名に解決)

v1 の挙動は不変 (既存 roundtrip テスト緑)。v2 roundtrip テストを追加。

Refs #743

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…al server

過去にゲームサーバー再実装が「仕様不明確」で頓挫した反省を踏まえ、実ゲームサーバーの
挙動をゴールデン JSON として記録し、クライアントが従うべき契約をテストで固定する基盤を
追加する (#740)。

- tmp/smalruby-koshien/game_server (Ruby 3.1) の in-process API ドライバ
  (SpecHelper::Server) を流用した記録ドライバで、決定的シナリオ (SK_RANDOM_SEED=1) を
  実行し各 API の返り値を fixture 化:
  - move_basic: move_to は予約で、座標は turnTransition 後に確定 (before [1,1] → after [2,1])
  - get_map_area: getMapArea は 15x15 の自分マップ (未探索 -1) + enemy + other_player を返す
  - two_actions: 1 ターン 2 行動 (move + getMapArea)
- test/unit/extensions/koshien_golden_contract.js (tap): 上記の実挙動を検証し、
  将来の RemoteClient (#741) が replay できる契約の基盤とする。
- 記録ドライバ/サーバー起動手順は notes/koshien に整備 (git 管理外)。

Refs #740 / Epic #738

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…th mock fallback

甲子園拡張機能が、設定された実ゲームサーバーと通信して実際にゲームを進められるよう
にする (#741)。未接続時は固定値の MockClient にフォールバックするため、サーバーに
つながなくても AI を作成できる。

- remote-client.js: ai_lib.rb の HTTP プロトコルを JS へ移植した RemoteClient。
  - 非同期: connectGame / getMapArea / moveTo / setDynamite / setBomb /
    setMessage / turnOver。返り値で my_map / x / y / goal / enemy / other_player を更新。
  - 同期レポーター: map / mapAll / mapFrom / targetCoordinate はキャッシュ状態を読む
    (ai_lib と同じく get_map_area が my_map を埋め、map(...) がそれを参照)。
  - calc_route はダイクストラ (壁=通行不可、水=重い、未探索=さらに重い) を移植。
    locate_objects は my_map 走査。
- index.js: runtime.getKoshienRemoteOptions() が endpoint を返せば RemoteClient、
  なければ MockClient を使う (オフラインで AI 作成可能)。
- テスト: #740 のゴールデン fixture (実サーバー応答) を注入 fetch で流し込み、
  RemoteClient が実応答を正しく解釈することを検証 (契約テスト)。バックエンド選択も検証。

ベース: #739 (MockClient) + #740 (ゴールデン) の上に構築。#741 は最後にマージ予定。

Refs #741 / Epic #738

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
v2 では甲子園プログラムをクラス表現 (class < Smalruby3::Sprite) の中に置くため、
ゲーム接続をフラットな文ではなく「ブロックを取るイベント hat」で表現する。

- generator: koshien_connectGame は v2 で
  `koshien.when_connect_game(name:) do ... end` を生成し、AI 本体を do...end の
  サブスタックに包む (block.isStatement=true → scrub_ が next 連鎖を字下げ + end)。
  v1 は従来どおりフラット `koshien.connect_game(name:)`。
- converter:
  - `koshien.when_connect_game(name:) do ... end` (v2) を hat + サブスタックとして解析。
  - フラット `koshien.connect_game(name:)` は v1 で statement、v2 ではエラー
    (when_connect_game を使うよう促す)。
- v2 roundtrip テスト (when_connect_game + リスト$配列) / v2 フラットエラー /
  v1 フラット維持 を追加。

ブロック opcode/構造は不変のため、既存 sb3 プロジェクトはそのまま読み込める。

Refs #743

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…llback

接続できれば実サーバー、できなければ Mock 値、という #741 の中核挙動を実装。

- コンストラクタ: MockClient を常に保持し、endpoint 設定時のみ RemoteClient を併設。
  起動時は RemoteClient (あれば) を使う。
- connectGame: remote のときは実サーバーへ非同期接続し、失敗 (到達不可/CORS/エラー)
  したら MockClient へフォールバック (つながなくても AI が動く)。mock のときは従来どおり同期接続。
- getMapArea / setItem / turnOver が client の結果 (remote では Promise) を返すように
  変更し、シーケンサが await して順序を保てるようにした。
- テスト: 接続成功で RemoteClient 維持 + 実座標、接続失敗で MockClient へフォールバック +
  固定値。tap 全 110 assert pass。

Refs #741

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
接続先は「プログラム」ではなく「Smalruby の設定」で行う方針 (#741) の土台。
接続設定 (接続先URL / プレイヤー側 / ゲームコード) を localStorage に保存し、
VM 拡張が読む contract `vm.runtime.getKoshienRemoteOptions()` を供給する。

- src/lib/koshien-connection.js:
  - load/saveKoshienConnection: localStorage 永続化 (side は 1/2 に正規化)。
  - buildKoshienRemoteOptions: endpoint 未設定なら null (= Mock)、設定時は
    {endpoint, side, gameCode, playerId(自動生成・安定)} を返す。
  - wireKoshienRemoteOptions(vm): runtime に getter を差し込む (拡張が読む)。
  - testKoshienConnection(endpoint): 設定モーダルの「接続テスト」用の到達性確認。
- 単体テスト (jest, 5 件) pass。

後続 (本 PR or 別 PR): 甲子園メニューに「接続設定」項目 + 設定モーダル UI
(URL/側/コード/テストボタン) + wireKoshienRemoteOptions の起動時呼び出し。

Refs #741

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
接続先を「Smalruby の設定」で行う方針 (#741) の UI を実装。甲子園拡張機能を有効にすると
表示される甲子園メニューに「接続設定」項目を追加し、設定モーダルで接続先 URL / プレイヤー側
(1/2) / ゲームコードを設定する。

- src/components/koshien-settings-modal/: 設定モーダル (URL/側/コード + 接続テストボタン)。
  保存で localStorage 永続化 + wireKoshienRemoteOptions(vm) を再実行。本文に不透明背景
  (modals ルール準拠)。
- reducers/modals.js: koshienSettingsModal の open/close を追加。
- menu-bar.jsx: 甲子園メニューに「接続設定」項目 + ハンドラ + Redux 接続。
- components/gui.jsx, containers/gui.jsx: モーダルのマウントと state/dispatch マッピング。
- vm-manager-hoc.jsx: VM 初期化時に wireKoshienRemoteOptions(vm) を呼び、起動時から
  保存済み設定を拡張が読めるようにする (Smalruby マーカー付き)。
- locales (ja/ja-Hira/en) + prettier ホワイトリスト + マーカー一覧を更新。
- 単体テスト: モーダルのフィールド描画 + 保存で localStorage 永続化 + runtime getter 設置。

注: 設定変更は次回の拡張機能ロード (リロード) 時に反映される (拡張は構築時に一度読む)。

Refs #741

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…oteClient HTTP test

test:unit は `tap ./test/unit/*.js`(再帰なし)のため、test/unit/extensions/ 配下の
koshien テストは CI で実行されていなかった。mesh と同じく top-level へ移動して確実に走らせる。

- test/unit/extensions/koshien_{golden_contract,remote_client}.js を test/unit/ へ移動
  (require パス修正)。
- RemoteClient の実 HTTP 経路を検証する統合テストを追加:
  - test/fixtures/koshien/mock-server.js: CORS 付き Koshien API モックサーバー
    (canned 応答, CLI 起動可: `npm run koshien:mock-server [port]`)。
  - test/unit/koshien_remote_client_http.js: in-process モックサーバーに対して
    RemoteClient を実 fetch で駆動(connect/getMapArea/move/turnOver)。
- prettier ホワイトリスト / マーカー一覧 / package.json スクリプトを更新。
- 全 koshien vm テスト 89 assert pass、lint 緑。

Refs #741

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…level)

test:unit は `tap ./test/unit/*.js`(再帰なし)のため test/unit/extensions/ 配下の
テストが CI で実行されていなかった。golden contract テストを top-level へ移動して
確実に走らせる(require パス修正・prettier ホワイトリスト/マーカー更新)。51 assert pass。

Refs #740

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…on loaded

甲子園拡張機能を v2 対応にしたため、「koshien 有効時は Ruby バージョンを変更できない」
という guard / アラートは不要になった。settings-menu と mobile-drawer の両方から削除し、
未使用になったメッセージ koshienCannotChangeRubyVersion とロケール(ja/ja-Hira/en)も除去。

v1↔v2 切替時の「v2機能(class/module)使用中は v1 に戻せない」guard は維持。

Refs #743

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…en blocks

When not connected to a real game server the koshien blocks previously
returned flat placeholders (all-zero map, [src,dst] route, fixed [7:7]).
During the first explanation a user is almost always disconnected, so
clicking a block gave no sense of what it really returns.

Now the mock derives every value from a single source of truth — a fixed,
believable 15x15 sample map (MOCK_MAP) with walls, water, a goal and
scattered items — via new pure helpers in map-utils.js (shared-ready so the
remote client can adopt the same Dijkstra/scan logic):

- map / map_all / map_from -> real cell codes from the sample map
- calc_goal_route / calc_route -> actual shortest path (multi-waypoint),
  honoring the EXCEPT_CELLS list
- locate_objects -> the items really present within range
- target_coordinate -> positions consistent with the map

Phase 2 (pseudo state): move_to moves the mock player, set_item marks the
map, turn_over advances a counter, so repeated runs feel alive.

Reset timing: the mock world resets to its initial state on green flag
(PROJECT_START), on stop (PROJECT_STOP_ALL), and when connect_game runs —
the natural "new game" moments, so a demo can be replayed cleanly.

Tests: rewrote extension_koshien.js expectations for the believable values
and added koshien_map_utils.js for the pure helpers (146 assertions, lint
clean).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The mock sample map was a hand-made 15x15 grid. The real Smalruby Koshien
field is 17x17 surrounded by an unbreakable wall border (verified against the
2024 default map "map_01": top/left edge = code 2, bottom/right edge = code 1;
breakable walls are 5).

- MOCK_MAP is now map_01 with its item layer merged into letters (a-e/A-D),
  exactly how the real server encodes my_map (ITEM_MARKS). Player starts (5,1)
  and (10,1), goal '3' at (8,9), enemy guards the goal.
- map-utils.locateObjects: sq_size is the full square side, not a radius
  (real game uses radius = (sq_size-1)/2); fixed an over-wide scan window.

Tests updated to the real map values + a new assertion that the whole field
is bordered by unbreakable walls.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The mock now mirrors the real game's exploration: the player's "my map"
starts fully unexplored (all -1) and is revealed 5x5 at a time by
get_map_area. map / map_all / calc_route / locate_objects all work off this
gradually-revealed my map, so locate_objects finds nothing until the area is
explored and calc_route plans through fog (unexplored = passable). moveTo
passability is checked against the ground-truth map, and set_item marks the
ground truth (visible once that cell is revealed). Reset clears the my map
back to fully unexplored.

map-utils gains createUnexploredGrid + revealArea (clamped window, matching
the server's getMapArea range). Tests reworked to the explore-then-read flow.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Selecting the Koshien extension while in Ruby v2 popped an alert
("only available for Ruby v1") and refused to load it. Now that koshien
supports v2 (class representation + when_connect_game), this guard is
obsolete. Removed the rubyVersion check, its message, the unused
rubyVersion prop/mapStateToProps, and the locale strings.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Switching to Ruby v2 with the koshien extension loaded is now allowed
(koshien supports v2), so the stale "shows alert / blocks the change" test
is replaced with one asserting the change goes through without an alert.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…client

feat(scratch-vm): 甲子園ブロックの固定値/状態実装(MockClient)
…golden-contract

# Conflicts:
#	packages/scratch-vm/.prettierignore
…n-contract

test(scratch-vm): 甲子園 実サーバーのゴールデン記録 + 契約テスト基盤
feat(scratch-gui): 甲子園 Ruby v2 対応(when_connect_game イベント hat + リスト引数 $配列構文)
…remote-client

# Conflicts:
#	.claude/rules/scratch-vm/smalruby-prettier-files.md
#	packages/scratch-gui/src/locales/en.js
#	packages/scratch-gui/src/locales/ja-Hira.js
#	packages/scratch-gui/src/locales/ja.js
#	packages/scratch-vm/.prettierignore
#	packages/scratch-vm/src/extensions/koshien/index.js
#	packages/scratch-vm/test/unit/extension_koshien.js
…e-client

feat(scratch-vm): 甲子園 実ゲームサーバー通信モード(RemoteClient)[Draft/最後にマージ]
@github-actions

Copy link
Copy Markdown

…s player1

The "Test AI" modal embedded the Koshien WEB viewer with no query params, so it
always ran the default AI. The viewer accepts `?player1=data:<base64(utf8)>`
(game_viewer/js/player-ai-client.js): a data: blob is decoded to Ruby source,
and with no param it falls back to the default AI.

- koshien-test-url.js: encodeAiToPlayerParam / buildKoshienTestUrl helpers
  (UTF-8-safe base64, blank code -> base URL so the default AI still runs).
- koshien-test-modal.jsx: connect to vm + rubyVersion, generate the current
  editing target's runnable Ruby (generatePreviewCode, current version) and pass
  it as player1. player2 stays the default AI. Regenerated on Reload.
- unit tests round-trip the param exactly as the game viewer decodes it.

Refs #762

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ai-param

feat(koshien): 「AIを試す」で現スプライト・現バージョンの生成AIをplayer1で渡す (#762)
@smalruby3-editor-bot smalruby3-editor-bot Bot added 🤖 autopilot autopilot(AI)が管理する PR/Issue(AI処理対象) 🙋 HITL 人間の対応待ち(レビュー/判断/マージ) labels Jun 28, 2026
@takaokouji

Copy link
Copy Markdown

update branch して、最新の develop に追従してください。
また、EPICのIssueの説明を更新して、checkboxを更新。さらに、もし、追加作業が発生していたら、それも追記してください。

そして、残作業を明確にしてください。
私が把握している残作業は、ゲームサーバー側の smalruby3 ライブラリの更新です。別レポジトリの作業ですが、smalruby3-editor レポジトリに Issue の有無を確認して、なければ作成する必要があります。

@takaokouji takaokouji self-requested a review June 28, 2026 19:13
@takaokouji takaokouji removed the 🙋 HITL 人間の対応待ち(レビュー/判断/マージ) label Jun 28, 2026
*/
async connectGame (playerName) {
if (playerName) this._playerName = playerName;
const url = `${this._endpoint}/api/manage/connectGame`;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

このクライアントが呼ぶ /api/manage/connectGame 等を実装するゲームサーバー側 smalruby3 ライブラリの更新が残作業です。smalruby3-editor に tracking Issue が無ければ作成してください。
あわせて #761 全体として: ① develop へ update branch、② EPIC #738 の説明・checkbox 更新(追加作業あれば追記)、③ 残作業の明確化 もお願いします(詳細: #issuecomment-4827119468)。

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ご指摘の残作業(ゲームサーバー側 smalruby3 ライブラリの更新)について、tracking Issue を本リポジトリに用意済みです:

あわせて #761 全体の 3 点も対応済みです(詳細は #761 (comment) の bot コメント参照):
develop へ update branch(マージ済み・0 commits behind)/② EPIC #738 本文の checkbox(#739/#740/#741/#743[x])+ 追加作業(#762)+ 残作業(#763/#764)セクション追記/③ 残作業の明確化。

editor 側(scratch-vm / scratch-gui)は本 Epic で実装完了です。実ゲーム進行には #763 / #764(別リポジトリ NaCl-Ltd/smalruby-koshien-web 側)がフォローアップとして残ります。

@smalruby3-editor-bot

Copy link
Copy Markdown
Author

@takaokouji レビューありがとうございます。3 点すべて対応しました。

① develop へ update branch

最新 develop を本ブランチへマージし push 済み(CI 再実行されます)。コンフリクトなし。

② EPIC #738 の説明・checkbox 更新

③ 残作業の明確化(ゲームサーバー側 smalruby3 ライブラリ更新)

ご指摘の「/api/manage/connectGame 等を実装するゲームサーバー側 smalruby3 ライブラリの更新」は、本リポジトリに tracking Issue が既に存在していました(新規作成不要):

editor 側(scratch-vm / scratch-gui)の実装は本 Epic で完了。実ゲーム進行には上記 #763 / #764(別リポジトリ NaCl-Ltd/smalruby-koshien-web 側の作業)が前提として残ります。EPIC #738 本文の「残作業」セクションにも明記しました。

@smalruby3-editor-bot smalruby3-editor-bot Bot added the 🙋 HITL 人間の対応待ち(レビュー/判断/マージ) label Jun 28, 2026
@smalruby3-editor-bot

Copy link
Copy Markdown
Author

🤖 autopilot status

field value
Status Review
AI Status
HITL Yes
Size

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

@takaokouji

Copy link
Copy Markdown

ゲームサーバー側を修正して新旧のAPIの両方で、本PRを使って動作確認できたら本 PR をマージする。

smalruby3-editor-bot Bot and others added 9 commits June 29, 2026 12:30
…-738

# Conflicts:
#	.claude/rules/scratch-gui/smalruby-prettier-files.md
#	.claude/rules/scratch-vm/smalruby-prettier-files.md
The smalruby-prettier-files.md mirrors were removed (#820/#822); .prettierignore
is now the single source of truth. Drop the dead doc references from the header
comments.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…s stage globals

「AIを試す」(koshien-test-modal) は編集中スプライト単体のみを Ruby に出力していたため、

「すべてのスプライトでつかう」グローバル変数/リスト(例 $最短経路)を使う koshien AI が

未初期化(nil)のまま実行され落ちていた。

generatePreviewCode をステージ + 編集中スプライトの2ターゲット出力に変更し、

ステージがグローバル変数/リストを初期化するようにした(v1/v2 両対応)。

また v2 でスクリプト無し・グローバル変数/リストありのステージが class Stage を生成せず

def initialize を出力しないバグを修正(_hasInitializableState で空コードでも wrap)。

Closes #827

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
feat(koshien): 「AIを試す」でステージ+スプライトを出力しグローバル初期化する (#827)
"AIを試す" wrapped the menu item in RubyDownloader and ran a save/download

before opening the modal. The modal builds a base64 `?player1=data:...` URL from

the current sprite + stage, so saving is unnecessary. Make the menu item open

the modal directly and drop getTestAIHandler / handleTestAISaveFinished.

"Save AI" / "Save AI as..." keep their save behavior.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…rray syntax

v1 generated plain array syntax ($name[N], 0-indexed) for all list element

and indexed operations, but the v1 Ruby->Blocks converter rejects array

syntax. Round-tripping a v1 program (e.g. the koshien AI list read

list("$最短経路")[2]) produced $最短経路[1], which fails to re-convert in v1.

Make data-list.js (and data_listcontents) version-aware: v1 emits the

list("$name") wrapper with 1-indexed access; v2 keeps $name[0-indexed].

Covers push/insert/delete_at/replace/item/index/length/include?/clear/empty?.

Aligns with the documented v1 spec (smalruby-language-spec-v1-diff).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
fix(ruby-generator): v1 でリスト操作を list() ラッパー記法で出力する (#839)
fix(koshien): 「AIを試す」で不要な保存処理が走る — モーダルを開くだけにする (#840)
@takaokouji takaokouji merged commit e5addf3 into develop Jun 30, 2026
9 checks passed
@takaokouji takaokouji deleted the topic/koshien-epic-738 branch June 30, 2026 13:27
github-actions Bot pushed a commit that referenced this pull request Jun 30, 2026
…-epic-738

feat: 甲子園拡張機能の本格対応 (Epic #738: MockClient + ゴールデン契約 + Ruby v2 + RemoteClient)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🤖 autopilot autopilot(AI)が管理する PR/Issue(AI処理対象) 🙋 HITL 人間の対応待ち(レビュー/判断/マージ)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: スモウルビー甲子園 拡張機能の本格対応(ブロック挙動 + 実サーバー通信)[Epic]

1 participant