From 21c6c45e3a13cb1340f8b6064671a610f6a3a142 Mon Sep 17 00:00:00 2001 From: hatayama Date: Thu, 29 Oct 2026 23:24:34 +0900 Subject: [PATCH 1/3] fix: Unity package now ships project runner 3.12.3, which reports MAIN_THREAD_BLOCKED and the stall notice Package 3.21.2 was cut before the project runner 3.12.3 release pull request merged, so its pin still resolves runner 3.12.2, which renders the blocked-main-thread fail-fast as UNITY_RPC_ERROR and has no stderr stall notice. Main already records 3.12.3 in the pin. This commit documents `status` and the blocked-main-thread behavior in the package docs, and exists so that release-please cuts the package release that carries the pin. --- Packages/src/Documentation~/tools.md | 11 +++++++++++ Packages/src/Documentation~/tools_ja.md | 11 +++++++++++ 2 files changed, 22 insertions(+) diff --git a/Packages/src/Documentation~/tools.md b/Packages/src/Documentation~/tools.md index bec2fe075..2bfbd1797 100644 --- a/Packages/src/Documentation~/tools.md +++ b/Packages/src/Documentation~/tools.md @@ -216,6 +216,17 @@ Replay recorded keyboard and mouse input during PlayMode. Loads a JSON recording → replay-input (Action: stop) ``` +### 18. status - Check Whether the Editor Can Take a Command +Use `uloop status` before sending commands when Unity may be starting, compiling, busy, or closed. It answers without side effects and reports one state per line: `Ready`, `Compiling`, `Busy` (with the running tool name), `MainThreadBlocked` (the main thread has not run for 5 seconds or more, usually a modal dialog), `NotResponding`, or `NotRunning`. + +A command sent while the main thread is blocked waits for it. Once the stall reaches 30 seconds before any of the command's code has run, Unity stops the wait, releases the command slot, and the command fails with `MAIN_THREAD_BLOCKED` and the stall seconds; nothing ran, so sending it again after the block clears is safe. The dedicated error code and its guidance are rendered by project runner 3.12.3 or newer, which this package pins; an older runner shows the same message under `UNITY_RPC_ERROR`. A command whose own code blocks the main thread is not stopped; the CLI prints a stall notice on stderr every 60 seconds instead and gives up after 5 minutes with `UNITY_EDITOR_UNRESPONSIVE`. + +```text +→ status +→ State: MainThreadBlocked, SecondsSinceLastMainThreadTick: 12.3 +→ Dismiss the dialog (or run focus-window to find it), then send the command once more +``` + Terminal-driven E2E coverage is available through one runner per shell family: ```bash diff --git a/Packages/src/Documentation~/tools_ja.md b/Packages/src/Documentation~/tools_ja.md index b104e6493..cbfec0f06 100644 --- a/Packages/src/Documentation~/tools_ja.md +++ b/Packages/src/Documentation~/tools_ja.md @@ -216,6 +216,17 @@ Input System経由でPlayMode中のキーボード入力をシミュレーショ → replay-input (Action: stop) ``` +### 18. status - Editor がコマンドを受けられるか確認 +Unity が起動中・コンパイル中・処理中・終了している可能性があるときは、コマンドを送る前に `uloop status` を使います。副作用なしで応答し、状態を 1 行で返します: `Ready`、`Compiling`、`Busy`(実行中のツール名付き)、`MainThreadBlocked`(main thread が 5 秒以上動いていない。多くはモーダルダイアログ)、`NotResponding`、`NotRunning`。 + +main thread がブロックされている間に送ったコマンドは、その解除を待ちます。コマンドのコードがまだ 1 行も動いていない状態で停止が 30 秒に達すると、Unity は待機をやめてコマンドの実行枠を解放し、コマンドは `MAIN_THREAD_BLOCKED` と停止秒数を返して失敗します。何も実行されていないので、ブロックが解けた後に送り直しても安全です。専用のエラーコードと案内を表示するのは project runner 3.12.3 以降で、このパッケージはそれを pin しています。古い runner では同じメッセージが `UNITY_RPC_ERROR` として表示されます。コマンド自身のコードが main thread をブロックしている場合は止めません。代わりに CLI が 60 秒ごとに stderr へ停止の通知を出し、5 分で `UNITY_EDITOR_UNRESPONSIVE` を返して諦めます。 + +```text +→ status +→ State: MainThreadBlocked, SecondsSinceLastMainThreadTick: 12.3 +→ Dismiss the dialog (or run focus-window to find it), then send the command once more +``` + terminal から uloop コマンドを実行するE2Eは、shell 系統ごとに1つのrunnerから実行します: ```bash From 6a8a2ddf22a6d4ef8588b8cb913a9fc1e215e0f9 Mon Sep 17 00:00:00 2001 From: hatayama Date: Thu, 29 Oct 2026 23:36:47 +0900 Subject: [PATCH 2/3] List every status state in the package docs The first paragraph read as an exhaustive list but named only six of the ten states, and said one state per line although status reports a single State field. List all ten in the skill table's order and describe the State field. --- Packages/src/Documentation~/tools.md | 2 +- Packages/src/Documentation~/tools_ja.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Packages/src/Documentation~/tools.md b/Packages/src/Documentation~/tools.md index 2bfbd1797..797128fa5 100644 --- a/Packages/src/Documentation~/tools.md +++ b/Packages/src/Documentation~/tools.md @@ -217,7 +217,7 @@ Replay recorded keyboard and mouse input during PlayMode. Loads a JSON recording ``` ### 18. status - Check Whether the Editor Can Take a Command -Use `uloop status` before sending commands when Unity may be starting, compiling, busy, or closed. It answers without side effects and reports one state per line: `Ready`, `Compiling`, `Busy` (with the running tool name), `MainThreadBlocked` (the main thread has not run for 5 seconds or more, usually a modal dialog), `NotResponding`, or `NotRunning`. +Use `uloop status` before sending commands when Unity may be starting, compiling, busy, or closed. It answers without side effects and reports exactly one state in its `State` field: `Busy` (a uloop command holds the command slot), `Starting`, `MainThreadBlocked` (the main thread has not run for 5 seconds or more, usually a modal dialog), `Compiling`, `ImportingAssets`, `Ready` (the only state that exits 0), `NotResponding`, `ServerUnavailable`, `NotRunning`, or `Unreachable`. A command sent while the main thread is blocked waits for it. Once the stall reaches 30 seconds before any of the command's code has run, Unity stops the wait, releases the command slot, and the command fails with `MAIN_THREAD_BLOCKED` and the stall seconds; nothing ran, so sending it again after the block clears is safe. The dedicated error code and its guidance are rendered by project runner 3.12.3 or newer, which this package pins; an older runner shows the same message under `UNITY_RPC_ERROR`. A command whose own code blocks the main thread is not stopped; the CLI prints a stall notice on stderr every 60 seconds instead and gives up after 5 minutes with `UNITY_EDITOR_UNRESPONSIVE`. diff --git a/Packages/src/Documentation~/tools_ja.md b/Packages/src/Documentation~/tools_ja.md index cbfec0f06..d2d61d8c7 100644 --- a/Packages/src/Documentation~/tools_ja.md +++ b/Packages/src/Documentation~/tools_ja.md @@ -217,7 +217,7 @@ Input System経由でPlayMode中のキーボード入力をシミュレーショ ``` ### 18. status - Editor がコマンドを受けられるか確認 -Unity が起動中・コンパイル中・処理中・終了している可能性があるときは、コマンドを送る前に `uloop status` を使います。副作用なしで応答し、状態を 1 行で返します: `Ready`、`Compiling`、`Busy`(実行中のツール名付き)、`MainThreadBlocked`(main thread が 5 秒以上動いていない。多くはモーダルダイアログ)、`NotResponding`、`NotRunning`。 +Unity が起動中・コンパイル中・処理中・終了している可能性があるときは、コマンドを送る前に `uloop status` を使います。副作用なしで応答し、`State` 欄に状態を 1 つだけ返します: `Busy`(uloop のコマンドが実行枠を持っている)、`Starting`、`MainThreadBlocked`(main thread が 5 秒以上動いていない。多くはモーダルダイアログ)、`Compiling`、`ImportingAssets`、`Ready`(exit code 0 になる唯一の状態)、`NotResponding`、`ServerUnavailable`、`NotRunning`、`Unreachable`。 main thread がブロックされている間に送ったコマンドは、その解除を待ちます。コマンドのコードがまだ 1 行も動いていない状態で停止が 30 秒に達すると、Unity は待機をやめてコマンドの実行枠を解放し、コマンドは `MAIN_THREAD_BLOCKED` と停止秒数を返して失敗します。何も実行されていないので、ブロックが解けた後に送り直しても安全です。専用のエラーコードと案内を表示するのは project runner 3.12.3 以降で、このパッケージはそれを pin しています。古い runner では同じメッセージが `UNITY_RPC_ERROR` として表示されます。コマンド自身のコードが main thread をブロックしている場合は止めません。代わりに CLI が 60 秒ごとに stderr へ停止の通知を出し、5 分で `UNITY_EDITOR_UNRESPONSIVE` を返して諦めます。 From 859810e95b8d868f4551424fd807a1e380c46969 Mon Sep 17 00:00:00 2001 From: hatayama Date: Thu, 29 Oct 2026 23:45:14 +0900 Subject: [PATCH 3/3] Give status its own docs section and note the execute-dynamic-code exception Inserted after replay-input, the status section fell under the PlayMode testing heading and pushed the E2E paragraph beneath it, so it now sits under its own heading at the end. The 5-minute UNITY_EDITOR_UNRESPONSIVE limit does not apply to execute-dynamic-code, whose snippet may block the main thread for as long as it runs; the package docs and the status skill now say so. --- .agents/skills/uloop-status/SKILL.md | 2 +- .claude/skills/uloop-status/SKILL.md | 2 +- Packages/src/Documentation~/tools.md | 22 ++++++++++--------- Packages/src/Documentation~/tools_ja.md | 22 ++++++++++--------- .../CliOnlyTools~/Status/Skill/SKILL.md | 2 +- 5 files changed, 27 insertions(+), 23 deletions(-) diff --git a/.agents/skills/uloop-status/SKILL.md b/.agents/skills/uloop-status/SKILL.md index 0c754c954..6ecf92583 100644 --- a/.agents/skills/uloop-status/SKILL.md +++ b/.agents/skills/uloop-status/SKILL.md @@ -57,4 +57,4 @@ Play Mode does not change the state: a paused Play Mode session is `Ready`, with - A sandboxed shell that cannot open the Unix socket gets an error, not NotRunning; run it outside the sandbox. - uloop cannot detect Safe Mode directly; ServerUnavailable that does not clear is the signal. - Before reporting MainThreadBlocked it wakes the Editor's main loop and asks again about a second later, so an Editor that is only idle in the background reads as Ready. -- A command sent while the main thread is blocked waits for it. Once the stall reaches 30 seconds before any of the command's code has run, Unity stops the wait and the command fails with `MAIN_THREAD_BLOCKED` (nothing ran, so running it again after the block clears is safe). A command whose own code blocks the main thread is not stopped; the CLI prints a stall notice on stderr every 60 seconds instead and gives up after 5 minutes with `UNITY_EDITOR_UNRESPONSIVE`. +- A command sent while the main thread is blocked waits for it. Once the stall reaches 30 seconds before any of the command's code has run, Unity stops the wait and the command fails with `MAIN_THREAD_BLOCKED` (nothing ran, so running it again after the block clears is safe). A command whose own code blocks the main thread is not stopped; the CLI prints a stall notice on stderr every 60 seconds instead and gives up after 5 minutes with `UNITY_EDITOR_UNRESPONSIVE`. `execute-dynamic-code` is the exception: its own snippet may block the main thread for as long as it runs. diff --git a/.claude/skills/uloop-status/SKILL.md b/.claude/skills/uloop-status/SKILL.md index 0c754c954..6ecf92583 100644 --- a/.claude/skills/uloop-status/SKILL.md +++ b/.claude/skills/uloop-status/SKILL.md @@ -57,4 +57,4 @@ Play Mode does not change the state: a paused Play Mode session is `Ready`, with - A sandboxed shell that cannot open the Unix socket gets an error, not NotRunning; run it outside the sandbox. - uloop cannot detect Safe Mode directly; ServerUnavailable that does not clear is the signal. - Before reporting MainThreadBlocked it wakes the Editor's main loop and asks again about a second later, so an Editor that is only idle in the background reads as Ready. -- A command sent while the main thread is blocked waits for it. Once the stall reaches 30 seconds before any of the command's code has run, Unity stops the wait and the command fails with `MAIN_THREAD_BLOCKED` (nothing ran, so running it again after the block clears is safe). A command whose own code blocks the main thread is not stopped; the CLI prints a stall notice on stderr every 60 seconds instead and gives up after 5 minutes with `UNITY_EDITOR_UNRESPONSIVE`. +- A command sent while the main thread is blocked waits for it. Once the stall reaches 30 seconds before any of the command's code has run, Unity stops the wait and the command fails with `MAIN_THREAD_BLOCKED` (nothing ran, so running it again after the block clears is safe). A command whose own code blocks the main thread is not stopped; the CLI prints a stall notice on stderr every 60 seconds instead and gives up after 5 minutes with `UNITY_EDITOR_UNRESPONSIVE`. `execute-dynamic-code` is the exception: its own snippet may block the main thread for as long as it runs. diff --git a/Packages/src/Documentation~/tools.md b/Packages/src/Documentation~/tools.md index 797128fa5..78bcc70f7 100644 --- a/Packages/src/Documentation~/tools.md +++ b/Packages/src/Documentation~/tools.md @@ -216,22 +216,24 @@ Replay recorded keyboard and mouse input during PlayMode. Loads a JSON recording → replay-input (Action: stop) ``` +Terminal-driven E2E coverage is available through one runner per shell family: + +```bash +sh scripts/run-posix-e2e.sh --project-path /path/to/unity-project +powershell -NoProfile -ExecutionPolicy Bypass -File .\scripts\run-windows-e2e.ps1 +``` + +`run-posix-e2e.sh` uses the built native CLI binary by default, passes an explicit `--project-path` to every `uloop` invocation, and runs CLI recovery/readiness, simulate-mouse UI coverage, and UI Toolkit screenshot annotation and click coverage in one sequence (skip the last with `--skip-uitoolkit-annotation`). To verify `replay-input` against a JSON created in the Recordings window, run `verify-replay-via-cli.sh` separately. + +## Editor Readiness Tools + ### 18. status - Check Whether the Editor Can Take a Command Use `uloop status` before sending commands when Unity may be starting, compiling, busy, or closed. It answers without side effects and reports exactly one state in its `State` field: `Busy` (a uloop command holds the command slot), `Starting`, `MainThreadBlocked` (the main thread has not run for 5 seconds or more, usually a modal dialog), `Compiling`, `ImportingAssets`, `Ready` (the only state that exits 0), `NotResponding`, `ServerUnavailable`, `NotRunning`, or `Unreachable`. -A command sent while the main thread is blocked waits for it. Once the stall reaches 30 seconds before any of the command's code has run, Unity stops the wait, releases the command slot, and the command fails with `MAIN_THREAD_BLOCKED` and the stall seconds; nothing ran, so sending it again after the block clears is safe. The dedicated error code and its guidance are rendered by project runner 3.12.3 or newer, which this package pins; an older runner shows the same message under `UNITY_RPC_ERROR`. A command whose own code blocks the main thread is not stopped; the CLI prints a stall notice on stderr every 60 seconds instead and gives up after 5 minutes with `UNITY_EDITOR_UNRESPONSIVE`. +A command sent while the main thread is blocked waits for it. Once the stall reaches 30 seconds before any of the command's code has run, Unity stops the wait, releases the command slot, and the command fails with `MAIN_THREAD_BLOCKED` and the stall seconds; nothing ran, so sending it again after the block clears is safe. The dedicated error code and its guidance are rendered by project runner 3.12.3 or newer, which this package pins; an older runner shows the same message under `UNITY_RPC_ERROR`. A command whose own code blocks the main thread is not stopped; the CLI prints a stall notice on stderr every 60 seconds instead and gives up after 5 minutes with `UNITY_EDITOR_UNRESPONSIVE`, except for `execute-dynamic-code`, whose snippet may block the main thread for as long as it runs. ```text → status → State: MainThreadBlocked, SecondsSinceLastMainThreadTick: 12.3 → Dismiss the dialog (or run focus-window to find it), then send the command once more ``` - -Terminal-driven E2E coverage is available through one runner per shell family: - -```bash -sh scripts/run-posix-e2e.sh --project-path /path/to/unity-project -powershell -NoProfile -ExecutionPolicy Bypass -File .\scripts\run-windows-e2e.ps1 -``` - -`run-posix-e2e.sh` uses the built native CLI binary by default, passes an explicit `--project-path` to every `uloop` invocation, and runs CLI recovery/readiness, simulate-mouse UI coverage, and UI Toolkit screenshot annotation and click coverage in one sequence (skip the last with `--skip-uitoolkit-annotation`). To verify `replay-input` against a JSON created in the Recordings window, run `verify-replay-via-cli.sh` separately. diff --git a/Packages/src/Documentation~/tools_ja.md b/Packages/src/Documentation~/tools_ja.md index d2d61d8c7..4844d837d 100644 --- a/Packages/src/Documentation~/tools_ja.md +++ b/Packages/src/Documentation~/tools_ja.md @@ -216,22 +216,24 @@ Input System経由でPlayMode中のキーボード入力をシミュレーショ → replay-input (Action: stop) ``` +terminal から uloop コマンドを実行するE2Eは、shell 系統ごとに1つのrunnerから実行します: + +```bash +sh scripts/run-posix-e2e.sh --project-path /path/to/unity-project +powershell -NoProfile -ExecutionPolicy Bypass -File .\scripts\run-windows-e2e.ps1 +``` + +`run-posix-e2e.sh` は、デフォルトでチェックイン済みのネイティブCLIバイナリを使い、すべての `uloop` 呼び出しに明示的な `--project-path` を渡します。CLI recovery/readiness、simulate-mouse UI、UI Toolkit のスクリーンショット注釈とクリックを1つの流れで検証します(最後のものは `--skip-uitoolkit-annotation` で省けます)。Recordingsウィンドウで作成したJSONの replay-input 検証は `verify-replay-via-cli.sh` を個別に実行します。 + +## Editor 状態確認ツール + ### 18. status - Editor がコマンドを受けられるか確認 Unity が起動中・コンパイル中・処理中・終了している可能性があるときは、コマンドを送る前に `uloop status` を使います。副作用なしで応答し、`State` 欄に状態を 1 つだけ返します: `Busy`(uloop のコマンドが実行枠を持っている)、`Starting`、`MainThreadBlocked`(main thread が 5 秒以上動いていない。多くはモーダルダイアログ)、`Compiling`、`ImportingAssets`、`Ready`(exit code 0 になる唯一の状態)、`NotResponding`、`ServerUnavailable`、`NotRunning`、`Unreachable`。 -main thread がブロックされている間に送ったコマンドは、その解除を待ちます。コマンドのコードがまだ 1 行も動いていない状態で停止が 30 秒に達すると、Unity は待機をやめてコマンドの実行枠を解放し、コマンドは `MAIN_THREAD_BLOCKED` と停止秒数を返して失敗します。何も実行されていないので、ブロックが解けた後に送り直しても安全です。専用のエラーコードと案内を表示するのは project runner 3.12.3 以降で、このパッケージはそれを pin しています。古い runner では同じメッセージが `UNITY_RPC_ERROR` として表示されます。コマンド自身のコードが main thread をブロックしている場合は止めません。代わりに CLI が 60 秒ごとに stderr へ停止の通知を出し、5 分で `UNITY_EDITOR_UNRESPONSIVE` を返して諦めます。 +main thread がブロックされている間に送ったコマンドは、その解除を待ちます。コマンドのコードがまだ 1 行も動いていない状態で停止が 30 秒に達すると、Unity は待機をやめてコマンドの実行枠を解放し、コマンドは `MAIN_THREAD_BLOCKED` と停止秒数を返して失敗します。何も実行されていないので、ブロックが解けた後に送り直しても安全です。専用のエラーコードと案内を表示するのは project runner 3.12.3 以降で、このパッケージはそれを pin しています。古い runner では同じメッセージが `UNITY_RPC_ERROR` として表示されます。コマンド自身のコードが main thread をブロックしている場合は止めません。代わりに CLI が 60 秒ごとに stderr へ停止の通知を出し、5 分で `UNITY_EDITOR_UNRESPONSIVE` を返して諦めます。ただし `execute-dynamic-code` は例外で、スニペットが main thread を塞いでいる間は打ち切りません。 ```text → status → State: MainThreadBlocked, SecondsSinceLastMainThreadTick: 12.3 → Dismiss the dialog (or run focus-window to find it), then send the command once more ``` - -terminal から uloop コマンドを実行するE2Eは、shell 系統ごとに1つのrunnerから実行します: - -```bash -sh scripts/run-posix-e2e.sh --project-path /path/to/unity-project -powershell -NoProfile -ExecutionPolicy Bypass -File .\scripts\run-windows-e2e.ps1 -``` - -`run-posix-e2e.sh` は、デフォルトでチェックイン済みのネイティブCLIバイナリを使い、すべての `uloop` 呼び出しに明示的な `--project-path` を渡します。CLI recovery/readiness、simulate-mouse UI、UI Toolkit のスクリーンショット注釈とクリックを1つの流れで検証します(最後のものは `--skip-uitoolkit-annotation` で省けます)。Recordingsウィンドウで作成したJSONの replay-input 検証は `verify-replay-via-cli.sh` を個別に実行します。 diff --git a/Packages/src/Editor/CliOnlyTools~/Status/Skill/SKILL.md b/Packages/src/Editor/CliOnlyTools~/Status/Skill/SKILL.md index 0c754c954..6ecf92583 100644 --- a/Packages/src/Editor/CliOnlyTools~/Status/Skill/SKILL.md +++ b/Packages/src/Editor/CliOnlyTools~/Status/Skill/SKILL.md @@ -57,4 +57,4 @@ Play Mode does not change the state: a paused Play Mode session is `Ready`, with - A sandboxed shell that cannot open the Unix socket gets an error, not NotRunning; run it outside the sandbox. - uloop cannot detect Safe Mode directly; ServerUnavailable that does not clear is the signal. - Before reporting MainThreadBlocked it wakes the Editor's main loop and asks again about a second later, so an Editor that is only idle in the background reads as Ready. -- A command sent while the main thread is blocked waits for it. Once the stall reaches 30 seconds before any of the command's code has run, Unity stops the wait and the command fails with `MAIN_THREAD_BLOCKED` (nothing ran, so running it again after the block clears is safe). A command whose own code blocks the main thread is not stopped; the CLI prints a stall notice on stderr every 60 seconds instead and gives up after 5 minutes with `UNITY_EDITOR_UNRESPONSIVE`. +- A command sent while the main thread is blocked waits for it. Once the stall reaches 30 seconds before any of the command's code has run, Unity stops the wait and the command fails with `MAIN_THREAD_BLOCKED` (nothing ran, so running it again after the block clears is safe). A command whose own code blocks the main thread is not stopped; the CLI prints a stall notice on stderr every 60 seconds instead and gives up after 5 minutes with `UNITY_EDITOR_UNRESPONSIVE`. `execute-dynamic-code` is the exception: its own snippet may block the main thread for as long as it runs.