From d66f1ed9a5a3b73d57f464a59c2bb93ae75217f5 Mon Sep 17 00:00:00 2001 From: hatayama Date: Tue, 9 Jun 2026 19:07:39 +0900 Subject: [PATCH 01/24] Clarify debug-break skill for uloop E2E validation Expand the skill trigger so agents use paused-frame proof not only for transient bugs, but also when validating uloop simulated input through major gameplay transitions. Keep ordinary persistent-state checks optional while preserving the warning that command success, logs, sleeps, counters, or time-scale changes are not paused-frame evidence. --- .agents/skills/uloop-wait-for-debug-break/SKILL.md | 13 +++++++++++-- .claude/skills/uloop-wait-for-debug-break/SKILL.md | 13 +++++++++++-- .../Editor/CliOnlyTools~/PausePoint/Skill/SKILL.md | 13 +++++++++++-- 3 files changed, 33 insertions(+), 6 deletions(-) diff --git a/.agents/skills/uloop-wait-for-debug-break/SKILL.md b/.agents/skills/uloop-wait-for-debug-break/SKILL.md index 1af3de1e2..13485752d 100644 --- a/.agents/skills/uloop-wait-for-debug-break/SKILL.md +++ b/.agents/skills/uloop-wait-for-debug-break/SKILL.md @@ -1,8 +1,17 @@ --- name: uloop-wait-for-debug-break -description: "Use this for Unity PlayMode/E2E checks when simulated input or gameplay events cause a state transition that a screenshot, durable state, or specific value log cannot prove. Pause at the natural transition point after the input/event is consumed and inspect the paused frame. Do not use simulate-* Success=true, generic action logs, sleeps/retries, testing-only counters, or Time.timeScale changes as substitutes for debug-break evidence of transient transitions." +description: "Use this as the breakpoint substitute for Unity PlayMode/E2E validation when uloop-simulated input drives a core gameplay transition. Pause at the natural transition point to inspect variables/state and prove input consumption or frame-specific behavior, even when logs, screenshots, or durable state can later confirm the result." --- +## When To Use + +- Use this when a state transition is transient, frame-specific, or hard to prove after the fact. +- Use this during uloop interaction or endurance validation when simulated input drives a core gameplay transition, even if durable state, logs, or screenshots can later confirm the final result. +- Good pause points include input consumed, jump velocity applied, hard drop locked, block placed, collision resolved, damage applied, lives decremented, or game over entered. +- Treat the pause like a lightweight breakpoint: combine nearby debug logs with paused-frame inspection to confirm the variables and component state at that point. +- Do not treat `simulate-* Success=true`, generic action logs, sleeps/retries, testing-only counters, or `Time.timeScale` changes as paused-frame proof. +- Skip this for ordinary persistent-state checks when you are not validating input delivery, event ordering, or transition-frame fidelity. + ## Workflow 1. Add a marker at the state you want to inspect: @@ -35,7 +44,7 @@ uloop wait-for-debug-break --id player-jumped --timeout-seconds 30 If this command times out, the marker line was not reached while the command waited. Inspect `error.details.status`, `hitCount`, `isPlaying`, `isPaused`, `elapsedSinceEnabledMilliseconds`, and `remainingMilliseconds` to distinguish input not being consumed, gameplay conditions not being met, an id mismatch, or Unity already being paused. `elapsedSinceEnabledMilliseconds` is measured from `enable-debug-break`, not from `wait-for-debug-break`. -7. While Unity is paused, inspect state with `uloop get-logs`, `uloop get-hierarchy`, `uloop find-game-objects`, screenshots, or `uloop execute-dynamic-code`. +7. While Unity is paused, inspect state with `uloop get-logs`, `uloop get-hierarchy`, `uloop find-game-objects`, screenshots, or `uloop execute-dynamic-code`. Add focused debug logs before the marker when local variables must be captured. 8. Clear the marker if you stop waiting: ```bash diff --git a/.claude/skills/uloop-wait-for-debug-break/SKILL.md b/.claude/skills/uloop-wait-for-debug-break/SKILL.md index 1af3de1e2..13485752d 100644 --- a/.claude/skills/uloop-wait-for-debug-break/SKILL.md +++ b/.claude/skills/uloop-wait-for-debug-break/SKILL.md @@ -1,8 +1,17 @@ --- name: uloop-wait-for-debug-break -description: "Use this for Unity PlayMode/E2E checks when simulated input or gameplay events cause a state transition that a screenshot, durable state, or specific value log cannot prove. Pause at the natural transition point after the input/event is consumed and inspect the paused frame. Do not use simulate-* Success=true, generic action logs, sleeps/retries, testing-only counters, or Time.timeScale changes as substitutes for debug-break evidence of transient transitions." +description: "Use this as the breakpoint substitute for Unity PlayMode/E2E validation when uloop-simulated input drives a core gameplay transition. Pause at the natural transition point to inspect variables/state and prove input consumption or frame-specific behavior, even when logs, screenshots, or durable state can later confirm the result." --- +## When To Use + +- Use this when a state transition is transient, frame-specific, or hard to prove after the fact. +- Use this during uloop interaction or endurance validation when simulated input drives a core gameplay transition, even if durable state, logs, or screenshots can later confirm the final result. +- Good pause points include input consumed, jump velocity applied, hard drop locked, block placed, collision resolved, damage applied, lives decremented, or game over entered. +- Treat the pause like a lightweight breakpoint: combine nearby debug logs with paused-frame inspection to confirm the variables and component state at that point. +- Do not treat `simulate-* Success=true`, generic action logs, sleeps/retries, testing-only counters, or `Time.timeScale` changes as paused-frame proof. +- Skip this for ordinary persistent-state checks when you are not validating input delivery, event ordering, or transition-frame fidelity. + ## Workflow 1. Add a marker at the state you want to inspect: @@ -35,7 +44,7 @@ uloop wait-for-debug-break --id player-jumped --timeout-seconds 30 If this command times out, the marker line was not reached while the command waited. Inspect `error.details.status`, `hitCount`, `isPlaying`, `isPaused`, `elapsedSinceEnabledMilliseconds`, and `remainingMilliseconds` to distinguish input not being consumed, gameplay conditions not being met, an id mismatch, or Unity already being paused. `elapsedSinceEnabledMilliseconds` is measured from `enable-debug-break`, not from `wait-for-debug-break`. -7. While Unity is paused, inspect state with `uloop get-logs`, `uloop get-hierarchy`, `uloop find-game-objects`, screenshots, or `uloop execute-dynamic-code`. +7. While Unity is paused, inspect state with `uloop get-logs`, `uloop get-hierarchy`, `uloop find-game-objects`, screenshots, or `uloop execute-dynamic-code`. Add focused debug logs before the marker when local variables must be captured. 8. Clear the marker if you stop waiting: ```bash diff --git a/Packages/src/Editor/CliOnlyTools~/PausePoint/Skill/SKILL.md b/Packages/src/Editor/CliOnlyTools~/PausePoint/Skill/SKILL.md index 1af3de1e2..13485752d 100644 --- a/Packages/src/Editor/CliOnlyTools~/PausePoint/Skill/SKILL.md +++ b/Packages/src/Editor/CliOnlyTools~/PausePoint/Skill/SKILL.md @@ -1,8 +1,17 @@ --- name: uloop-wait-for-debug-break -description: "Use this for Unity PlayMode/E2E checks when simulated input or gameplay events cause a state transition that a screenshot, durable state, or specific value log cannot prove. Pause at the natural transition point after the input/event is consumed and inspect the paused frame. Do not use simulate-* Success=true, generic action logs, sleeps/retries, testing-only counters, or Time.timeScale changes as substitutes for debug-break evidence of transient transitions." +description: "Use this as the breakpoint substitute for Unity PlayMode/E2E validation when uloop-simulated input drives a core gameplay transition. Pause at the natural transition point to inspect variables/state and prove input consumption or frame-specific behavior, even when logs, screenshots, or durable state can later confirm the result." --- +## When To Use + +- Use this when a state transition is transient, frame-specific, or hard to prove after the fact. +- Use this during uloop interaction or endurance validation when simulated input drives a core gameplay transition, even if durable state, logs, or screenshots can later confirm the final result. +- Good pause points include input consumed, jump velocity applied, hard drop locked, block placed, collision resolved, damage applied, lives decremented, or game over entered. +- Treat the pause like a lightweight breakpoint: combine nearby debug logs with paused-frame inspection to confirm the variables and component state at that point. +- Do not treat `simulate-* Success=true`, generic action logs, sleeps/retries, testing-only counters, or `Time.timeScale` changes as paused-frame proof. +- Skip this for ordinary persistent-state checks when you are not validating input delivery, event ordering, or transition-frame fidelity. + ## Workflow 1. Add a marker at the state you want to inspect: @@ -35,7 +44,7 @@ uloop wait-for-debug-break --id player-jumped --timeout-seconds 30 If this command times out, the marker line was not reached while the command waited. Inspect `error.details.status`, `hitCount`, `isPlaying`, `isPaused`, `elapsedSinceEnabledMilliseconds`, and `remainingMilliseconds` to distinguish input not being consumed, gameplay conditions not being met, an id mismatch, or Unity already being paused. `elapsedSinceEnabledMilliseconds` is measured from `enable-debug-break`, not from `wait-for-debug-break`. -7. While Unity is paused, inspect state with `uloop get-logs`, `uloop get-hierarchy`, `uloop find-game-objects`, screenshots, or `uloop execute-dynamic-code`. +7. While Unity is paused, inspect state with `uloop get-logs`, `uloop get-hierarchy`, `uloop find-game-objects`, screenshots, or `uloop execute-dynamic-code`. Add focused debug logs before the marker when local variables must be captured. 8. Clear the marker if you stop waiting: ```bash From 4b0c4f29b38ab906e164680f736ecd6590d0198b Mon Sep 17 00:00:00 2001 From: hatayama Date: Tue, 9 Jun 2026 19:21:32 +0900 Subject: [PATCH 02/24] Reset neighbor projects before refreshing skills Ensure refresh-neighbor-game-skills starts from a clean Git state in each sibling game project before quitting Unity, regenerating generated skill files, committing them, and relaunching the editors. The reset phase runs before any skill-dir cleanliness checks so stale local changes cannot block or contaminate the refresh workflow. --- scripts/refresh-neighbor-game-skills.sh | 50 ++++++++++++++++++------- 1 file changed, 37 insertions(+), 13 deletions(-) diff --git a/scripts/refresh-neighbor-game-skills.sh b/scripts/refresh-neighbor-game-skills.sh index 87a3c1092..2a9e5c754 100755 --- a/scripts/refresh-neighbor-game-skills.sh +++ b/scripts/refresh-neighbor-game-skills.sh @@ -1,9 +1,9 @@ #!/bin/sh # Development helper for refreshing generated uloop skill files in sibling Unity projects. # This is not an installed agent skill or a runtime command. It exists to support local -# uloop development by quitting each target Unity Editor, regenerating Claude/Agents -# skill copies, committing those generated files locally, removing Library after Unity -# has stopped, and relaunching each project. +# uloop development by resetting each target Git repository, quitting each target +# Unity Editor, regenerating Claude/Agents skill copies, committing those generated +# files locally, removing Library after Unity has stopped, and relaunching each project. set -eu skill_name="refresh-neighbor-game-skills" @@ -31,11 +31,12 @@ Usage: refresh-neighbor-game-skills.sh [--dry-run] [--uloop-root PATH] [--project PATH ...] Workflow for each target Unity project: - 0. Quit Unity if running - 1. Install uloop skills for Claude and Agents - 2. Commit generated skill changes without pushing - 3. Remove Library - 4. Launch Unity with launch-unity + 0. Reset Git state to HEAD and remove untracked files + 1. Quit Unity if running + 2. Install uloop skills for Claude and Agents + 3. Commit generated skill changes without pushing + 4. Remove Library + 5. Launch Unity with launch-unity USAGE } @@ -238,6 +239,24 @@ assert_project_count() { [ "$count" -eq "$expected_project_count" ] || fail "expected $expected_project_count sibling Unity projects, found $count" } +reset_git_state() { + project=$1 + log "Resetting Git state: $project" + run git -C "$project" reset --hard HEAD + run git -C "$project" clean -fd + + if [ "$dry_run" -eq 1 ]; then + log "[dry-run] assert Git state is clean for $project" + return 0 + fi + + dirty=$(git -C "$project" status --porcelain) + if [ -n "$dirty" ]; then + printf '%s\n' "$dirty" >&2 + fail "git state is not clean after reset: $project" + fi +} + assert_clean_skill_dirs() { project=$1 existing=$(git -C "$project" status --porcelain -- .claude/skills .agents/skills) @@ -334,11 +353,16 @@ while IFS= read -r project; do log " $project" done <"$project_file" +log "Phase 0/5: reset Git state" +while IFS= read -r project; do + reset_git_state "$project" +done <"$project_file" + while IFS= read -r project; do assert_clean_skill_dirs "$project" done <"$project_file" -log "Phase 0/4: quit Unity" +log "Phase 1/5: quit Unity" while IFS= read -r project; do quit_unity "$project" done <"$project_file" @@ -347,22 +371,22 @@ while IFS= read -r project; do assert_unity_stopped "$project" done <"$project_file" -log "Phase 1/4: install skills" +log "Phase 2/5: install skills" while IFS= read -r project; do install_skills "$project" done <"$project_file" -log "Phase 2/4: commit generated skills" +log "Phase 3/5: commit generated skills" while IFS= read -r project; do commit_generated_skills "$project" done <"$project_file" -log "Phase 3/4: remove Library" +log "Phase 4/5: remove Library" while IFS= read -r project; do remove_library "$project" done <"$project_file" -log "Phase 4/4: launch Unity" +log "Phase 5/5: launch Unity" while IFS= read -r project; do launch_project "$project" done <"$project_file" From 735823fe79ba6cba00b352d218c5cb211a78da8d Mon Sep 17 00:00:00 2001 From: hatayama Date: Tue, 9 Jun 2026 21:37:31 +0900 Subject: [PATCH 03/24] Make debug-break skill easier to trigger for quick checks Describe wait-for-debug-break as a quick breakpoint substitute and add a compact usage template so agents can try it without treating the workflow as heavyweight. --- .../skills/uloop-wait-for-debug-break/SKILL.md | 15 +++++++++++++-- .../skills/uloop-wait-for-debug-break/SKILL.md | 15 +++++++++++++-- .../CliOnlyTools~/PausePoint/Skill/SKILL.md | 15 +++++++++++++-- 3 files changed, 39 insertions(+), 6 deletions(-) diff --git a/.agents/skills/uloop-wait-for-debug-break/SKILL.md b/.agents/skills/uloop-wait-for-debug-break/SKILL.md index 13485752d..f2187f06d 100644 --- a/.agents/skills/uloop-wait-for-debug-break/SKILL.md +++ b/.agents/skills/uloop-wait-for-debug-break/SKILL.md @@ -1,6 +1,6 @@ --- name: uloop-wait-for-debug-break -description: "Use this as the breakpoint substitute for Unity PlayMode/E2E validation when uloop-simulated input drives a core gameplay transition. Pause at the natural transition point to inspect variables/state and prove input consumption or frame-specific behavior, even when logs, screenshots, or durable state can later confirm the result." +description: "Use this as a quick breakpoint substitute for Unity PlayMode/E2E when uloop-simulated input changes gameplay state. Add a marker, run wait-for-debug-break, and inspect paused variables/state; simulate-* success or InterruptedByDebugBreak alone is not proof." --- ## When To Use @@ -8,10 +8,21 @@ description: "Use this as the breakpoint substitute for Unity PlayMode/E2E valid - Use this when a state transition is transient, frame-specific, or hard to prove after the fact. - Use this during uloop interaction or endurance validation when simulated input drives a core gameplay transition, even if durable state, logs, or screenshots can later confirm the final result. - Good pause points include input consumed, jump velocity applied, hard drop locked, block placed, collision resolved, damage applied, lives decremented, or game over entered. -- Treat the pause like a lightweight breakpoint: combine nearby debug logs with paused-frame inspection to confirm the variables and component state at that point. +- Treat the pause like a lightweight breakpoint for one important transition: combine nearby debug logs with paused-frame inspection to confirm the variables and component state at that point. - Do not treat `simulate-* Success=true`, generic action logs, sleeps/retries, testing-only counters, or `Time.timeScale` changes as paused-frame proof. - Skip this for ordinary persistent-state checks when you are not validating input delivery, event ordering, or transition-frame fidelity. +## Quick Check Template + +Use this small loop for one transition you care about: + +1. Put `UnityCliLoopDebug.Break("player-jumped")` at the natural transition point. +2. Compile, enter PlayMode, then enable the marker with `uloop enable-debug-break --id player-jumped --timeout-seconds 30`. +3. Trigger the action with a `simulate-*` command. +4. Run `uloop wait-for-debug-break --id player-jumped --timeout-seconds 30`, even if the trigger command already returned `InterruptedByDebugBreak=true`. +5. While Unity is paused, capture focused evidence with `uloop execute-dynamic-code`, `uloop get-logs`, and one screenshot. +6. Clear the marker or stop PlayMode before moving on. + ## Workflow 1. Add a marker at the state you want to inspect: diff --git a/.claude/skills/uloop-wait-for-debug-break/SKILL.md b/.claude/skills/uloop-wait-for-debug-break/SKILL.md index 13485752d..f2187f06d 100644 --- a/.claude/skills/uloop-wait-for-debug-break/SKILL.md +++ b/.claude/skills/uloop-wait-for-debug-break/SKILL.md @@ -1,6 +1,6 @@ --- name: uloop-wait-for-debug-break -description: "Use this as the breakpoint substitute for Unity PlayMode/E2E validation when uloop-simulated input drives a core gameplay transition. Pause at the natural transition point to inspect variables/state and prove input consumption or frame-specific behavior, even when logs, screenshots, or durable state can later confirm the result." +description: "Use this as a quick breakpoint substitute for Unity PlayMode/E2E when uloop-simulated input changes gameplay state. Add a marker, run wait-for-debug-break, and inspect paused variables/state; simulate-* success or InterruptedByDebugBreak alone is not proof." --- ## When To Use @@ -8,10 +8,21 @@ description: "Use this as the breakpoint substitute for Unity PlayMode/E2E valid - Use this when a state transition is transient, frame-specific, or hard to prove after the fact. - Use this during uloop interaction or endurance validation when simulated input drives a core gameplay transition, even if durable state, logs, or screenshots can later confirm the final result. - Good pause points include input consumed, jump velocity applied, hard drop locked, block placed, collision resolved, damage applied, lives decremented, or game over entered. -- Treat the pause like a lightweight breakpoint: combine nearby debug logs with paused-frame inspection to confirm the variables and component state at that point. +- Treat the pause like a lightweight breakpoint for one important transition: combine nearby debug logs with paused-frame inspection to confirm the variables and component state at that point. - Do not treat `simulate-* Success=true`, generic action logs, sleeps/retries, testing-only counters, or `Time.timeScale` changes as paused-frame proof. - Skip this for ordinary persistent-state checks when you are not validating input delivery, event ordering, or transition-frame fidelity. +## Quick Check Template + +Use this small loop for one transition you care about: + +1. Put `UnityCliLoopDebug.Break("player-jumped")` at the natural transition point. +2. Compile, enter PlayMode, then enable the marker with `uloop enable-debug-break --id player-jumped --timeout-seconds 30`. +3. Trigger the action with a `simulate-*` command. +4. Run `uloop wait-for-debug-break --id player-jumped --timeout-seconds 30`, even if the trigger command already returned `InterruptedByDebugBreak=true`. +5. While Unity is paused, capture focused evidence with `uloop execute-dynamic-code`, `uloop get-logs`, and one screenshot. +6. Clear the marker or stop PlayMode before moving on. + ## Workflow 1. Add a marker at the state you want to inspect: diff --git a/Packages/src/Editor/CliOnlyTools~/PausePoint/Skill/SKILL.md b/Packages/src/Editor/CliOnlyTools~/PausePoint/Skill/SKILL.md index 13485752d..f2187f06d 100644 --- a/Packages/src/Editor/CliOnlyTools~/PausePoint/Skill/SKILL.md +++ b/Packages/src/Editor/CliOnlyTools~/PausePoint/Skill/SKILL.md @@ -1,6 +1,6 @@ --- name: uloop-wait-for-debug-break -description: "Use this as the breakpoint substitute for Unity PlayMode/E2E validation when uloop-simulated input drives a core gameplay transition. Pause at the natural transition point to inspect variables/state and prove input consumption or frame-specific behavior, even when logs, screenshots, or durable state can later confirm the result." +description: "Use this as a quick breakpoint substitute for Unity PlayMode/E2E when uloop-simulated input changes gameplay state. Add a marker, run wait-for-debug-break, and inspect paused variables/state; simulate-* success or InterruptedByDebugBreak alone is not proof." --- ## When To Use @@ -8,10 +8,21 @@ description: "Use this as the breakpoint substitute for Unity PlayMode/E2E valid - Use this when a state transition is transient, frame-specific, or hard to prove after the fact. - Use this during uloop interaction or endurance validation when simulated input drives a core gameplay transition, even if durable state, logs, or screenshots can later confirm the final result. - Good pause points include input consumed, jump velocity applied, hard drop locked, block placed, collision resolved, damage applied, lives decremented, or game over entered. -- Treat the pause like a lightweight breakpoint: combine nearby debug logs with paused-frame inspection to confirm the variables and component state at that point. +- Treat the pause like a lightweight breakpoint for one important transition: combine nearby debug logs with paused-frame inspection to confirm the variables and component state at that point. - Do not treat `simulate-* Success=true`, generic action logs, sleeps/retries, testing-only counters, or `Time.timeScale` changes as paused-frame proof. - Skip this for ordinary persistent-state checks when you are not validating input delivery, event ordering, or transition-frame fidelity. +## Quick Check Template + +Use this small loop for one transition you care about: + +1. Put `UnityCliLoopDebug.Break("player-jumped")` at the natural transition point. +2. Compile, enter PlayMode, then enable the marker with `uloop enable-debug-break --id player-jumped --timeout-seconds 30`. +3. Trigger the action with a `simulate-*` command. +4. Run `uloop wait-for-debug-break --id player-jumped --timeout-seconds 30`, even if the trigger command already returned `InterruptedByDebugBreak=true`. +5. While Unity is paused, capture focused evidence with `uloop execute-dynamic-code`, `uloop get-logs`, and one screenshot. +6. Clear the marker or stop PlayMode before moving on. + ## Workflow 1. Add a marker at the state you want to inspect: From 2c67a610ef0323b1fb0150f49e89ed9c59109035 Mon Sep 17 00:00:00 2001 From: hatayama Date: Tue, 9 Jun 2026 21:44:09 +0900 Subject: [PATCH 04/24] Generalize debug-break pause point examples Replace game-specific checkpoint examples with runtime-state wording so the skill applies across Unity PlayMode validation scenarios, not only particular game mechanics. --- .../uloop-wait-for-debug-break/SKILL.md | 32 +++++++++---------- .../uloop-wait-for-debug-break/SKILL.md | 32 +++++++++---------- .../CliOnlyTools~/PausePoint/Skill/SKILL.md | 32 +++++++++---------- 3 files changed, 48 insertions(+), 48 deletions(-) diff --git a/.agents/skills/uloop-wait-for-debug-break/SKILL.md b/.agents/skills/uloop-wait-for-debug-break/SKILL.md index f2187f06d..6d41cb1d1 100644 --- a/.agents/skills/uloop-wait-for-debug-break/SKILL.md +++ b/.agents/skills/uloop-wait-for-debug-break/SKILL.md @@ -1,13 +1,13 @@ --- name: uloop-wait-for-debug-break -description: "Use this as a quick breakpoint substitute for Unity PlayMode/E2E when uloop-simulated input changes gameplay state. Add a marker, run wait-for-debug-break, and inspect paused variables/state; simulate-* success or InterruptedByDebugBreak alone is not proof." +description: "Use this as a quick breakpoint substitute for Unity PlayMode/E2E when uloop-simulated input changes runtime state. Add a marker, run wait-for-debug-break, and inspect paused variables/state; simulate-* success or InterruptedByDebugBreak alone is not proof." --- ## When To Use -- Use this when a state transition is transient, frame-specific, or hard to prove after the fact. -- Use this during uloop interaction or endurance validation when simulated input drives a core gameplay transition, even if durable state, logs, or screenshots can later confirm the final result. -- Good pause points include input consumed, jump velocity applied, hard drop locked, block placed, collision resolved, damage applied, lives decremented, or game over entered. +- Use this when a state transition is transient, frame-specific, or difficult to prove after the fact. +- Use this during uloop interaction or endurance validation when simulated input drives a core runtime transition, even if durable state, logs, or screenshots can later confirm the final result. +- Good pause points include after input is consumed, a command is accepted, a state mutation is committed, an evaluation step resolves, a tracked value changes, a UI/domain state syncs, or a success/failure/end condition is entered. - Treat the pause like a lightweight breakpoint for one important transition: combine nearby debug logs with paused-frame inspection to confirm the variables and component state at that point. - Do not treat `simulate-* Success=true`, generic action logs, sleeps/retries, testing-only counters, or `Time.timeScale` changes as paused-frame proof. - Skip this for ordinary persistent-state checks when you are not validating input delivery, event ordering, or transition-frame fidelity. @@ -16,10 +16,10 @@ description: "Use this as a quick breakpoint substitute for Unity PlayMode/E2E w Use this small loop for one transition you care about: -1. Put `UnityCliLoopDebug.Break("player-jumped")` at the natural transition point. -2. Compile, enter PlayMode, then enable the marker with `uloop enable-debug-break --id player-jumped --timeout-seconds 30`. +1. Put `UnityCliLoopDebug.Break("state-transition-applied")` at the natural transition point. +2. Compile, enter PlayMode, then enable the marker with `uloop enable-debug-break --id state-transition-applied --timeout-seconds 30`. 3. Trigger the action with a `simulate-*` command. -4. Run `uloop wait-for-debug-break --id player-jumped --timeout-seconds 30`, even if the trigger command already returned `InterruptedByDebugBreak=true`. +4. Run `uloop wait-for-debug-break --id state-transition-applied --timeout-seconds 30`, even if the trigger command already returned `InterruptedByDebugBreak=true`. 5. While Unity is paused, capture focused evidence with `uloop execute-dynamic-code`, `uloop get-logs`, and one screenshot. 6. Clear the marker or stop PlayMode before moving on. @@ -30,45 +30,45 @@ Use this small loop for one transition you care about: ```csharp using io.github.hatayama.UnityCliLoop.Runtime; -UnityCliLoopDebug.Break("player-jumped"); +UnityCliLoopDebug.Break("state-transition-applied"); ``` 2. Compile the project. 3. Enable the marker before triggering the target code path: ```bash -uloop enable-debug-break --id player-jumped --timeout-seconds 30 +uloop enable-debug-break --id state-transition-applied --timeout-seconds 30 ``` 4. Check marker state if needed: ```bash -uloop debug-break-status --id player-jumped +uloop debug-break-status --id state-transition-applied ``` 5. Trigger the behavior with `simulate-keyboard`, `simulate-mouse-input`, UI interaction, dynamic code, or similar commands. 6. Wait for the marker: ```bash -uloop wait-for-debug-break --id player-jumped --timeout-seconds 30 +uloop wait-for-debug-break --id state-transition-applied --timeout-seconds 30 ``` -If this command times out, the marker line was not reached while the command waited. Inspect `error.details.status`, `hitCount`, `isPlaying`, `isPaused`, `elapsedSinceEnabledMilliseconds`, and `remainingMilliseconds` to distinguish input not being consumed, gameplay conditions not being met, an id mismatch, or Unity already being paused. `elapsedSinceEnabledMilliseconds` is measured from `enable-debug-break`, not from `wait-for-debug-break`. +If this command times out, the marker line was not reached while the command waited. Inspect `error.details.status`, `hitCount`, `isPlaying`, `isPaused`, `elapsedSinceEnabledMilliseconds`, and `remainingMilliseconds` to distinguish input not being consumed, runtime conditions not being met, an id mismatch, or Unity already being paused. `elapsedSinceEnabledMilliseconds` is measured from `enable-debug-break`, not from `wait-for-debug-break`. 7. While Unity is paused, inspect state with `uloop get-logs`, `uloop get-hierarchy`, `uloop find-game-objects`, screenshots, or `uloop execute-dynamic-code`. Add focused debug logs before the marker when local variables must be captured. 8. Clear the marker if you stop waiting: ```bash -uloop clear-debug-break --id player-jumped +uloop clear-debug-break --id state-transition-applied ``` ## Marker Placement -- Prefer natural gameplay points or state-transition points after input has been consumed, such as after jump velocity or state changes, physics contact, or damage application. +- Prefer natural runtime points after input has been consumed, such as after a command is accepted, a state value changes, an evaluation step resolves, or a dependent component is updated. - For frame-specific bugs, place the marker on the suspicious state branch or immediately after the state mutation you need to freeze. - To avoid Domain Reload loss or tool Busy states, enable markers after Play Mode is running, and prefer checkpoints reached after the triggering input command can return. -- Avoid placing the marker immediately after issuing simulated input unless that exact input handling line is the state you need to inspect. Immediate markers can interrupt the input command before the resulting gameplay state settles. -- Use separate ids for strict phases, for example `jump-input-read`, `jump-velocity-applied`, and `jump-landed`, instead of reusing one broad marker. +- Avoid placing the marker immediately after issuing simulated input unless that exact input handling line is the state you need to inspect. Immediate markers can interrupt the input command before the resulting runtime state settles. +- Use separate ids for strict phases, for example `input-read`, `state-updated`, and `result-committed`, instead of reusing one broad marker. ## Safety diff --git a/.claude/skills/uloop-wait-for-debug-break/SKILL.md b/.claude/skills/uloop-wait-for-debug-break/SKILL.md index f2187f06d..6d41cb1d1 100644 --- a/.claude/skills/uloop-wait-for-debug-break/SKILL.md +++ b/.claude/skills/uloop-wait-for-debug-break/SKILL.md @@ -1,13 +1,13 @@ --- name: uloop-wait-for-debug-break -description: "Use this as a quick breakpoint substitute for Unity PlayMode/E2E when uloop-simulated input changes gameplay state. Add a marker, run wait-for-debug-break, and inspect paused variables/state; simulate-* success or InterruptedByDebugBreak alone is not proof." +description: "Use this as a quick breakpoint substitute for Unity PlayMode/E2E when uloop-simulated input changes runtime state. Add a marker, run wait-for-debug-break, and inspect paused variables/state; simulate-* success or InterruptedByDebugBreak alone is not proof." --- ## When To Use -- Use this when a state transition is transient, frame-specific, or hard to prove after the fact. -- Use this during uloop interaction or endurance validation when simulated input drives a core gameplay transition, even if durable state, logs, or screenshots can later confirm the final result. -- Good pause points include input consumed, jump velocity applied, hard drop locked, block placed, collision resolved, damage applied, lives decremented, or game over entered. +- Use this when a state transition is transient, frame-specific, or difficult to prove after the fact. +- Use this during uloop interaction or endurance validation when simulated input drives a core runtime transition, even if durable state, logs, or screenshots can later confirm the final result. +- Good pause points include after input is consumed, a command is accepted, a state mutation is committed, an evaluation step resolves, a tracked value changes, a UI/domain state syncs, or a success/failure/end condition is entered. - Treat the pause like a lightweight breakpoint for one important transition: combine nearby debug logs with paused-frame inspection to confirm the variables and component state at that point. - Do not treat `simulate-* Success=true`, generic action logs, sleeps/retries, testing-only counters, or `Time.timeScale` changes as paused-frame proof. - Skip this for ordinary persistent-state checks when you are not validating input delivery, event ordering, or transition-frame fidelity. @@ -16,10 +16,10 @@ description: "Use this as a quick breakpoint substitute for Unity PlayMode/E2E w Use this small loop for one transition you care about: -1. Put `UnityCliLoopDebug.Break("player-jumped")` at the natural transition point. -2. Compile, enter PlayMode, then enable the marker with `uloop enable-debug-break --id player-jumped --timeout-seconds 30`. +1. Put `UnityCliLoopDebug.Break("state-transition-applied")` at the natural transition point. +2. Compile, enter PlayMode, then enable the marker with `uloop enable-debug-break --id state-transition-applied --timeout-seconds 30`. 3. Trigger the action with a `simulate-*` command. -4. Run `uloop wait-for-debug-break --id player-jumped --timeout-seconds 30`, even if the trigger command already returned `InterruptedByDebugBreak=true`. +4. Run `uloop wait-for-debug-break --id state-transition-applied --timeout-seconds 30`, even if the trigger command already returned `InterruptedByDebugBreak=true`. 5. While Unity is paused, capture focused evidence with `uloop execute-dynamic-code`, `uloop get-logs`, and one screenshot. 6. Clear the marker or stop PlayMode before moving on. @@ -30,45 +30,45 @@ Use this small loop for one transition you care about: ```csharp using io.github.hatayama.UnityCliLoop.Runtime; -UnityCliLoopDebug.Break("player-jumped"); +UnityCliLoopDebug.Break("state-transition-applied"); ``` 2. Compile the project. 3. Enable the marker before triggering the target code path: ```bash -uloop enable-debug-break --id player-jumped --timeout-seconds 30 +uloop enable-debug-break --id state-transition-applied --timeout-seconds 30 ``` 4. Check marker state if needed: ```bash -uloop debug-break-status --id player-jumped +uloop debug-break-status --id state-transition-applied ``` 5. Trigger the behavior with `simulate-keyboard`, `simulate-mouse-input`, UI interaction, dynamic code, or similar commands. 6. Wait for the marker: ```bash -uloop wait-for-debug-break --id player-jumped --timeout-seconds 30 +uloop wait-for-debug-break --id state-transition-applied --timeout-seconds 30 ``` -If this command times out, the marker line was not reached while the command waited. Inspect `error.details.status`, `hitCount`, `isPlaying`, `isPaused`, `elapsedSinceEnabledMilliseconds`, and `remainingMilliseconds` to distinguish input not being consumed, gameplay conditions not being met, an id mismatch, or Unity already being paused. `elapsedSinceEnabledMilliseconds` is measured from `enable-debug-break`, not from `wait-for-debug-break`. +If this command times out, the marker line was not reached while the command waited. Inspect `error.details.status`, `hitCount`, `isPlaying`, `isPaused`, `elapsedSinceEnabledMilliseconds`, and `remainingMilliseconds` to distinguish input not being consumed, runtime conditions not being met, an id mismatch, or Unity already being paused. `elapsedSinceEnabledMilliseconds` is measured from `enable-debug-break`, not from `wait-for-debug-break`. 7. While Unity is paused, inspect state with `uloop get-logs`, `uloop get-hierarchy`, `uloop find-game-objects`, screenshots, or `uloop execute-dynamic-code`. Add focused debug logs before the marker when local variables must be captured. 8. Clear the marker if you stop waiting: ```bash -uloop clear-debug-break --id player-jumped +uloop clear-debug-break --id state-transition-applied ``` ## Marker Placement -- Prefer natural gameplay points or state-transition points after input has been consumed, such as after jump velocity or state changes, physics contact, or damage application. +- Prefer natural runtime points after input has been consumed, such as after a command is accepted, a state value changes, an evaluation step resolves, or a dependent component is updated. - For frame-specific bugs, place the marker on the suspicious state branch or immediately after the state mutation you need to freeze. - To avoid Domain Reload loss or tool Busy states, enable markers after Play Mode is running, and prefer checkpoints reached after the triggering input command can return. -- Avoid placing the marker immediately after issuing simulated input unless that exact input handling line is the state you need to inspect. Immediate markers can interrupt the input command before the resulting gameplay state settles. -- Use separate ids for strict phases, for example `jump-input-read`, `jump-velocity-applied`, and `jump-landed`, instead of reusing one broad marker. +- Avoid placing the marker immediately after issuing simulated input unless that exact input handling line is the state you need to inspect. Immediate markers can interrupt the input command before the resulting runtime state settles. +- Use separate ids for strict phases, for example `input-read`, `state-updated`, and `result-committed`, instead of reusing one broad marker. ## Safety diff --git a/Packages/src/Editor/CliOnlyTools~/PausePoint/Skill/SKILL.md b/Packages/src/Editor/CliOnlyTools~/PausePoint/Skill/SKILL.md index f2187f06d..6d41cb1d1 100644 --- a/Packages/src/Editor/CliOnlyTools~/PausePoint/Skill/SKILL.md +++ b/Packages/src/Editor/CliOnlyTools~/PausePoint/Skill/SKILL.md @@ -1,13 +1,13 @@ --- name: uloop-wait-for-debug-break -description: "Use this as a quick breakpoint substitute for Unity PlayMode/E2E when uloop-simulated input changes gameplay state. Add a marker, run wait-for-debug-break, and inspect paused variables/state; simulate-* success or InterruptedByDebugBreak alone is not proof." +description: "Use this as a quick breakpoint substitute for Unity PlayMode/E2E when uloop-simulated input changes runtime state. Add a marker, run wait-for-debug-break, and inspect paused variables/state; simulate-* success or InterruptedByDebugBreak alone is not proof." --- ## When To Use -- Use this when a state transition is transient, frame-specific, or hard to prove after the fact. -- Use this during uloop interaction or endurance validation when simulated input drives a core gameplay transition, even if durable state, logs, or screenshots can later confirm the final result. -- Good pause points include input consumed, jump velocity applied, hard drop locked, block placed, collision resolved, damage applied, lives decremented, or game over entered. +- Use this when a state transition is transient, frame-specific, or difficult to prove after the fact. +- Use this during uloop interaction or endurance validation when simulated input drives a core runtime transition, even if durable state, logs, or screenshots can later confirm the final result. +- Good pause points include after input is consumed, a command is accepted, a state mutation is committed, an evaluation step resolves, a tracked value changes, a UI/domain state syncs, or a success/failure/end condition is entered. - Treat the pause like a lightweight breakpoint for one important transition: combine nearby debug logs with paused-frame inspection to confirm the variables and component state at that point. - Do not treat `simulate-* Success=true`, generic action logs, sleeps/retries, testing-only counters, or `Time.timeScale` changes as paused-frame proof. - Skip this for ordinary persistent-state checks when you are not validating input delivery, event ordering, or transition-frame fidelity. @@ -16,10 +16,10 @@ description: "Use this as a quick breakpoint substitute for Unity PlayMode/E2E w Use this small loop for one transition you care about: -1. Put `UnityCliLoopDebug.Break("player-jumped")` at the natural transition point. -2. Compile, enter PlayMode, then enable the marker with `uloop enable-debug-break --id player-jumped --timeout-seconds 30`. +1. Put `UnityCliLoopDebug.Break("state-transition-applied")` at the natural transition point. +2. Compile, enter PlayMode, then enable the marker with `uloop enable-debug-break --id state-transition-applied --timeout-seconds 30`. 3. Trigger the action with a `simulate-*` command. -4. Run `uloop wait-for-debug-break --id player-jumped --timeout-seconds 30`, even if the trigger command already returned `InterruptedByDebugBreak=true`. +4. Run `uloop wait-for-debug-break --id state-transition-applied --timeout-seconds 30`, even if the trigger command already returned `InterruptedByDebugBreak=true`. 5. While Unity is paused, capture focused evidence with `uloop execute-dynamic-code`, `uloop get-logs`, and one screenshot. 6. Clear the marker or stop PlayMode before moving on. @@ -30,45 +30,45 @@ Use this small loop for one transition you care about: ```csharp using io.github.hatayama.UnityCliLoop.Runtime; -UnityCliLoopDebug.Break("player-jumped"); +UnityCliLoopDebug.Break("state-transition-applied"); ``` 2. Compile the project. 3. Enable the marker before triggering the target code path: ```bash -uloop enable-debug-break --id player-jumped --timeout-seconds 30 +uloop enable-debug-break --id state-transition-applied --timeout-seconds 30 ``` 4. Check marker state if needed: ```bash -uloop debug-break-status --id player-jumped +uloop debug-break-status --id state-transition-applied ``` 5. Trigger the behavior with `simulate-keyboard`, `simulate-mouse-input`, UI interaction, dynamic code, or similar commands. 6. Wait for the marker: ```bash -uloop wait-for-debug-break --id player-jumped --timeout-seconds 30 +uloop wait-for-debug-break --id state-transition-applied --timeout-seconds 30 ``` -If this command times out, the marker line was not reached while the command waited. Inspect `error.details.status`, `hitCount`, `isPlaying`, `isPaused`, `elapsedSinceEnabledMilliseconds`, and `remainingMilliseconds` to distinguish input not being consumed, gameplay conditions not being met, an id mismatch, or Unity already being paused. `elapsedSinceEnabledMilliseconds` is measured from `enable-debug-break`, not from `wait-for-debug-break`. +If this command times out, the marker line was not reached while the command waited. Inspect `error.details.status`, `hitCount`, `isPlaying`, `isPaused`, `elapsedSinceEnabledMilliseconds`, and `remainingMilliseconds` to distinguish input not being consumed, runtime conditions not being met, an id mismatch, or Unity already being paused. `elapsedSinceEnabledMilliseconds` is measured from `enable-debug-break`, not from `wait-for-debug-break`. 7. While Unity is paused, inspect state with `uloop get-logs`, `uloop get-hierarchy`, `uloop find-game-objects`, screenshots, or `uloop execute-dynamic-code`. Add focused debug logs before the marker when local variables must be captured. 8. Clear the marker if you stop waiting: ```bash -uloop clear-debug-break --id player-jumped +uloop clear-debug-break --id state-transition-applied ``` ## Marker Placement -- Prefer natural gameplay points or state-transition points after input has been consumed, such as after jump velocity or state changes, physics contact, or damage application. +- Prefer natural runtime points after input has been consumed, such as after a command is accepted, a state value changes, an evaluation step resolves, or a dependent component is updated. - For frame-specific bugs, place the marker on the suspicious state branch or immediately after the state mutation you need to freeze. - To avoid Domain Reload loss or tool Busy states, enable markers after Play Mode is running, and prefer checkpoints reached after the triggering input command can return. -- Avoid placing the marker immediately after issuing simulated input unless that exact input handling line is the state you need to inspect. Immediate markers can interrupt the input command before the resulting gameplay state settles. -- Use separate ids for strict phases, for example `jump-input-read`, `jump-velocity-applied`, and `jump-landed`, instead of reusing one broad marker. +- Avoid placing the marker immediately after issuing simulated input unless that exact input handling line is the state you need to inspect. Immediate markers can interrupt the input command before the resulting runtime state settles. +- Use separate ids for strict phases, for example `input-read`, `state-updated`, and `result-committed`, instead of reusing one broad marker. ## Safety From 04fd27a864efa37b2b0cf616694130260828f326 Mon Sep 17 00:00:00 2001 From: hatayama Date: Tue, 9 Jun 2026 21:47:38 +0900 Subject: [PATCH 05/24] Move debug-break quick check template first Show the lightweight usage loop before detailed guidance so agents see the practical wait-for-debug-break workflow immediately after the skill triggers. --- .../skills/uloop-wait-for-debug-break/SKILL.md | 18 +++++++++--------- .../skills/uloop-wait-for-debug-break/SKILL.md | 18 +++++++++--------- .../CliOnlyTools~/PausePoint/Skill/SKILL.md | 18 +++++++++--------- 3 files changed, 27 insertions(+), 27 deletions(-) diff --git a/.agents/skills/uloop-wait-for-debug-break/SKILL.md b/.agents/skills/uloop-wait-for-debug-break/SKILL.md index 6d41cb1d1..311942393 100644 --- a/.agents/skills/uloop-wait-for-debug-break/SKILL.md +++ b/.agents/skills/uloop-wait-for-debug-break/SKILL.md @@ -3,15 +3,6 @@ name: uloop-wait-for-debug-break description: "Use this as a quick breakpoint substitute for Unity PlayMode/E2E when uloop-simulated input changes runtime state. Add a marker, run wait-for-debug-break, and inspect paused variables/state; simulate-* success or InterruptedByDebugBreak alone is not proof." --- -## When To Use - -- Use this when a state transition is transient, frame-specific, or difficult to prove after the fact. -- Use this during uloop interaction or endurance validation when simulated input drives a core runtime transition, even if durable state, logs, or screenshots can later confirm the final result. -- Good pause points include after input is consumed, a command is accepted, a state mutation is committed, an evaluation step resolves, a tracked value changes, a UI/domain state syncs, or a success/failure/end condition is entered. -- Treat the pause like a lightweight breakpoint for one important transition: combine nearby debug logs with paused-frame inspection to confirm the variables and component state at that point. -- Do not treat `simulate-* Success=true`, generic action logs, sleeps/retries, testing-only counters, or `Time.timeScale` changes as paused-frame proof. -- Skip this for ordinary persistent-state checks when you are not validating input delivery, event ordering, or transition-frame fidelity. - ## Quick Check Template Use this small loop for one transition you care about: @@ -23,6 +14,15 @@ Use this small loop for one transition you care about: 5. While Unity is paused, capture focused evidence with `uloop execute-dynamic-code`, `uloop get-logs`, and one screenshot. 6. Clear the marker or stop PlayMode before moving on. +## When To Use + +- Use this when a state transition is transient, frame-specific, or difficult to prove after the fact. +- Use this during uloop interaction or endurance validation when simulated input drives a core runtime transition, even if durable state, logs, or screenshots can later confirm the final result. +- Good pause points include after input is consumed, a command is accepted, a state mutation is committed, an evaluation step resolves, a tracked value changes, a UI/domain state syncs, or a success/failure/end condition is entered. +- Treat the pause like a lightweight breakpoint for one important transition: combine nearby debug logs with paused-frame inspection to confirm the variables and component state at that point. +- Do not treat `simulate-* Success=true`, generic action logs, sleeps/retries, testing-only counters, or `Time.timeScale` changes as paused-frame proof. +- Skip this for ordinary persistent-state checks when you are not validating input delivery, event ordering, or transition-frame fidelity. + ## Workflow 1. Add a marker at the state you want to inspect: diff --git a/.claude/skills/uloop-wait-for-debug-break/SKILL.md b/.claude/skills/uloop-wait-for-debug-break/SKILL.md index 6d41cb1d1..311942393 100644 --- a/.claude/skills/uloop-wait-for-debug-break/SKILL.md +++ b/.claude/skills/uloop-wait-for-debug-break/SKILL.md @@ -3,15 +3,6 @@ name: uloop-wait-for-debug-break description: "Use this as a quick breakpoint substitute for Unity PlayMode/E2E when uloop-simulated input changes runtime state. Add a marker, run wait-for-debug-break, and inspect paused variables/state; simulate-* success or InterruptedByDebugBreak alone is not proof." --- -## When To Use - -- Use this when a state transition is transient, frame-specific, or difficult to prove after the fact. -- Use this during uloop interaction or endurance validation when simulated input drives a core runtime transition, even if durable state, logs, or screenshots can later confirm the final result. -- Good pause points include after input is consumed, a command is accepted, a state mutation is committed, an evaluation step resolves, a tracked value changes, a UI/domain state syncs, or a success/failure/end condition is entered. -- Treat the pause like a lightweight breakpoint for one important transition: combine nearby debug logs with paused-frame inspection to confirm the variables and component state at that point. -- Do not treat `simulate-* Success=true`, generic action logs, sleeps/retries, testing-only counters, or `Time.timeScale` changes as paused-frame proof. -- Skip this for ordinary persistent-state checks when you are not validating input delivery, event ordering, or transition-frame fidelity. - ## Quick Check Template Use this small loop for one transition you care about: @@ -23,6 +14,15 @@ Use this small loop for one transition you care about: 5. While Unity is paused, capture focused evidence with `uloop execute-dynamic-code`, `uloop get-logs`, and one screenshot. 6. Clear the marker or stop PlayMode before moving on. +## When To Use + +- Use this when a state transition is transient, frame-specific, or difficult to prove after the fact. +- Use this during uloop interaction or endurance validation when simulated input drives a core runtime transition, even if durable state, logs, or screenshots can later confirm the final result. +- Good pause points include after input is consumed, a command is accepted, a state mutation is committed, an evaluation step resolves, a tracked value changes, a UI/domain state syncs, or a success/failure/end condition is entered. +- Treat the pause like a lightweight breakpoint for one important transition: combine nearby debug logs with paused-frame inspection to confirm the variables and component state at that point. +- Do not treat `simulate-* Success=true`, generic action logs, sleeps/retries, testing-only counters, or `Time.timeScale` changes as paused-frame proof. +- Skip this for ordinary persistent-state checks when you are not validating input delivery, event ordering, or transition-frame fidelity. + ## Workflow 1. Add a marker at the state you want to inspect: diff --git a/Packages/src/Editor/CliOnlyTools~/PausePoint/Skill/SKILL.md b/Packages/src/Editor/CliOnlyTools~/PausePoint/Skill/SKILL.md index 6d41cb1d1..311942393 100644 --- a/Packages/src/Editor/CliOnlyTools~/PausePoint/Skill/SKILL.md +++ b/Packages/src/Editor/CliOnlyTools~/PausePoint/Skill/SKILL.md @@ -3,15 +3,6 @@ name: uloop-wait-for-debug-break description: "Use this as a quick breakpoint substitute for Unity PlayMode/E2E when uloop-simulated input changes runtime state. Add a marker, run wait-for-debug-break, and inspect paused variables/state; simulate-* success or InterruptedByDebugBreak alone is not proof." --- -## When To Use - -- Use this when a state transition is transient, frame-specific, or difficult to prove after the fact. -- Use this during uloop interaction or endurance validation when simulated input drives a core runtime transition, even if durable state, logs, or screenshots can later confirm the final result. -- Good pause points include after input is consumed, a command is accepted, a state mutation is committed, an evaluation step resolves, a tracked value changes, a UI/domain state syncs, or a success/failure/end condition is entered. -- Treat the pause like a lightweight breakpoint for one important transition: combine nearby debug logs with paused-frame inspection to confirm the variables and component state at that point. -- Do not treat `simulate-* Success=true`, generic action logs, sleeps/retries, testing-only counters, or `Time.timeScale` changes as paused-frame proof. -- Skip this for ordinary persistent-state checks when you are not validating input delivery, event ordering, or transition-frame fidelity. - ## Quick Check Template Use this small loop for one transition you care about: @@ -23,6 +14,15 @@ Use this small loop for one transition you care about: 5. While Unity is paused, capture focused evidence with `uloop execute-dynamic-code`, `uloop get-logs`, and one screenshot. 6. Clear the marker or stop PlayMode before moving on. +## When To Use + +- Use this when a state transition is transient, frame-specific, or difficult to prove after the fact. +- Use this during uloop interaction or endurance validation when simulated input drives a core runtime transition, even if durable state, logs, or screenshots can later confirm the final result. +- Good pause points include after input is consumed, a command is accepted, a state mutation is committed, an evaluation step resolves, a tracked value changes, a UI/domain state syncs, or a success/failure/end condition is entered. +- Treat the pause like a lightweight breakpoint for one important transition: combine nearby debug logs with paused-frame inspection to confirm the variables and component state at that point. +- Do not treat `simulate-* Success=true`, generic action logs, sleeps/retries, testing-only counters, or `Time.timeScale` changes as paused-frame proof. +- Skip this for ordinary persistent-state checks when you are not validating input delivery, event ordering, or transition-frame fidelity. + ## Workflow 1. Add a marker at the state you want to inspect: From 269fdb914f2feb1a4551815cdfa31c124dacc8ef Mon Sep 17 00:00:00 2001 From: hatayama Date: Tue, 9 Jun 2026 21:51:31 +0900 Subject: [PATCH 06/24] Remove duplicate debug-break workflow section Fold the essential commands into the quick check template and keep only timeout-specific guidance separately so the skill does not repeat the same workflow twice. --- .../uloop-wait-for-debug-break/SKILL.md | 51 ++++++------------- .../uloop-wait-for-debug-break/SKILL.md | 51 ++++++------------- .../CliOnlyTools~/PausePoint/Skill/SKILL.md | 51 ++++++------------- 3 files changed, 45 insertions(+), 108 deletions(-) diff --git a/.agents/skills/uloop-wait-for-debug-break/SKILL.md b/.agents/skills/uloop-wait-for-debug-break/SKILL.md index 311942393..34bd11bd7 100644 --- a/.agents/skills/uloop-wait-for-debug-break/SKILL.md +++ b/.agents/skills/uloop-wait-for-debug-break/SKILL.md @@ -7,25 +7,7 @@ description: "Use this as a quick breakpoint substitute for Unity PlayMode/E2E w Use this small loop for one transition you care about: -1. Put `UnityCliLoopDebug.Break("state-transition-applied")` at the natural transition point. -2. Compile, enter PlayMode, then enable the marker with `uloop enable-debug-break --id state-transition-applied --timeout-seconds 30`. -3. Trigger the action with a `simulate-*` command. -4. Run `uloop wait-for-debug-break --id state-transition-applied --timeout-seconds 30`, even if the trigger command already returned `InterruptedByDebugBreak=true`. -5. While Unity is paused, capture focused evidence with `uloop execute-dynamic-code`, `uloop get-logs`, and one screenshot. -6. Clear the marker or stop PlayMode before moving on. - -## When To Use - -- Use this when a state transition is transient, frame-specific, or difficult to prove after the fact. -- Use this during uloop interaction or endurance validation when simulated input drives a core runtime transition, even if durable state, logs, or screenshots can later confirm the final result. -- Good pause points include after input is consumed, a command is accepted, a state mutation is committed, an evaluation step resolves, a tracked value changes, a UI/domain state syncs, or a success/failure/end condition is entered. -- Treat the pause like a lightweight breakpoint for one important transition: combine nearby debug logs with paused-frame inspection to confirm the variables and component state at that point. -- Do not treat `simulate-* Success=true`, generic action logs, sleeps/retries, testing-only counters, or `Time.timeScale` changes as paused-frame proof. -- Skip this for ordinary persistent-state checks when you are not validating input delivery, event ordering, or transition-frame fidelity. - -## Workflow - -1. Add a marker at the state you want to inspect: +1. Put a marker at the natural transition point: ```csharp using io.github.hatayama.UnityCliLoop.Runtime; @@ -33,34 +15,31 @@ using io.github.hatayama.UnityCliLoop.Runtime; UnityCliLoopDebug.Break("state-transition-applied"); ``` -2. Compile the project. -3. Enable the marker before triggering the target code path: +2. Compile, enter PlayMode, then enable the marker: ```bash uloop enable-debug-break --id state-transition-applied --timeout-seconds 30 ``` -4. Check marker state if needed: +3. Trigger the action with a `simulate-*` command. +4. Run `uloop wait-for-debug-break --id state-transition-applied --timeout-seconds 30`, even if the trigger command already returned `InterruptedByDebugBreak=true`. +5. While Unity is paused, capture focused evidence with `uloop execute-dynamic-code`, `uloop get-logs`, `uloop get-hierarchy`, `uloop find-game-objects`, and one screenshot. +6. Clear the marker with `uloop clear-debug-break --id state-transition-applied` or stop PlayMode before moving on. -```bash -uloop debug-break-status --id state-transition-applied -``` +## When To Use -5. Trigger the behavior with `simulate-keyboard`, `simulate-mouse-input`, UI interaction, dynamic code, or similar commands. -6. Wait for the marker: +- Use this when a state transition is transient, frame-specific, or difficult to prove after the fact. +- Use this during uloop interaction or endurance validation when simulated input drives a core runtime transition, even if durable state, logs, or screenshots can later confirm the final result. +- Good pause points include after input is consumed, a command is accepted, a state mutation is committed, an evaluation step resolves, a tracked value changes, a UI/domain state syncs, or a success/failure/end condition is entered. +- Treat the pause like a lightweight breakpoint for one important transition: combine nearby debug logs with paused-frame inspection to confirm the variables and component state at that point. +- Do not treat `simulate-* Success=true`, generic action logs, sleeps/retries, testing-only counters, or `Time.timeScale` changes as paused-frame proof. +- Skip this for ordinary persistent-state checks when you are not validating input delivery, event ordering, or transition-frame fidelity. -```bash -uloop wait-for-debug-break --id state-transition-applied --timeout-seconds 30 -``` +## Timeout Checks If this command times out, the marker line was not reached while the command waited. Inspect `error.details.status`, `hitCount`, `isPlaying`, `isPaused`, `elapsedSinceEnabledMilliseconds`, and `remainingMilliseconds` to distinguish input not being consumed, runtime conditions not being met, an id mismatch, or Unity already being paused. `elapsedSinceEnabledMilliseconds` is measured from `enable-debug-break`, not from `wait-for-debug-break`. -7. While Unity is paused, inspect state with `uloop get-logs`, `uloop get-hierarchy`, `uloop find-game-objects`, screenshots, or `uloop execute-dynamic-code`. Add focused debug logs before the marker when local variables must be captured. -8. Clear the marker if you stop waiting: - -```bash -uloop clear-debug-break --id state-transition-applied -``` +Use `uloop debug-break-status --id state-transition-applied` only when you need to confirm the marker is armed or inspect the current hit state. Add focused debug logs before the marker when local variables must be captured. ## Marker Placement diff --git a/.claude/skills/uloop-wait-for-debug-break/SKILL.md b/.claude/skills/uloop-wait-for-debug-break/SKILL.md index 311942393..34bd11bd7 100644 --- a/.claude/skills/uloop-wait-for-debug-break/SKILL.md +++ b/.claude/skills/uloop-wait-for-debug-break/SKILL.md @@ -7,25 +7,7 @@ description: "Use this as a quick breakpoint substitute for Unity PlayMode/E2E w Use this small loop for one transition you care about: -1. Put `UnityCliLoopDebug.Break("state-transition-applied")` at the natural transition point. -2. Compile, enter PlayMode, then enable the marker with `uloop enable-debug-break --id state-transition-applied --timeout-seconds 30`. -3. Trigger the action with a `simulate-*` command. -4. Run `uloop wait-for-debug-break --id state-transition-applied --timeout-seconds 30`, even if the trigger command already returned `InterruptedByDebugBreak=true`. -5. While Unity is paused, capture focused evidence with `uloop execute-dynamic-code`, `uloop get-logs`, and one screenshot. -6. Clear the marker or stop PlayMode before moving on. - -## When To Use - -- Use this when a state transition is transient, frame-specific, or difficult to prove after the fact. -- Use this during uloop interaction or endurance validation when simulated input drives a core runtime transition, even if durable state, logs, or screenshots can later confirm the final result. -- Good pause points include after input is consumed, a command is accepted, a state mutation is committed, an evaluation step resolves, a tracked value changes, a UI/domain state syncs, or a success/failure/end condition is entered. -- Treat the pause like a lightweight breakpoint for one important transition: combine nearby debug logs with paused-frame inspection to confirm the variables and component state at that point. -- Do not treat `simulate-* Success=true`, generic action logs, sleeps/retries, testing-only counters, or `Time.timeScale` changes as paused-frame proof. -- Skip this for ordinary persistent-state checks when you are not validating input delivery, event ordering, or transition-frame fidelity. - -## Workflow - -1. Add a marker at the state you want to inspect: +1. Put a marker at the natural transition point: ```csharp using io.github.hatayama.UnityCliLoop.Runtime; @@ -33,34 +15,31 @@ using io.github.hatayama.UnityCliLoop.Runtime; UnityCliLoopDebug.Break("state-transition-applied"); ``` -2. Compile the project. -3. Enable the marker before triggering the target code path: +2. Compile, enter PlayMode, then enable the marker: ```bash uloop enable-debug-break --id state-transition-applied --timeout-seconds 30 ``` -4. Check marker state if needed: +3. Trigger the action with a `simulate-*` command. +4. Run `uloop wait-for-debug-break --id state-transition-applied --timeout-seconds 30`, even if the trigger command already returned `InterruptedByDebugBreak=true`. +5. While Unity is paused, capture focused evidence with `uloop execute-dynamic-code`, `uloop get-logs`, `uloop get-hierarchy`, `uloop find-game-objects`, and one screenshot. +6. Clear the marker with `uloop clear-debug-break --id state-transition-applied` or stop PlayMode before moving on. -```bash -uloop debug-break-status --id state-transition-applied -``` +## When To Use -5. Trigger the behavior with `simulate-keyboard`, `simulate-mouse-input`, UI interaction, dynamic code, or similar commands. -6. Wait for the marker: +- Use this when a state transition is transient, frame-specific, or difficult to prove after the fact. +- Use this during uloop interaction or endurance validation when simulated input drives a core runtime transition, even if durable state, logs, or screenshots can later confirm the final result. +- Good pause points include after input is consumed, a command is accepted, a state mutation is committed, an evaluation step resolves, a tracked value changes, a UI/domain state syncs, or a success/failure/end condition is entered. +- Treat the pause like a lightweight breakpoint for one important transition: combine nearby debug logs with paused-frame inspection to confirm the variables and component state at that point. +- Do not treat `simulate-* Success=true`, generic action logs, sleeps/retries, testing-only counters, or `Time.timeScale` changes as paused-frame proof. +- Skip this for ordinary persistent-state checks when you are not validating input delivery, event ordering, or transition-frame fidelity. -```bash -uloop wait-for-debug-break --id state-transition-applied --timeout-seconds 30 -``` +## Timeout Checks If this command times out, the marker line was not reached while the command waited. Inspect `error.details.status`, `hitCount`, `isPlaying`, `isPaused`, `elapsedSinceEnabledMilliseconds`, and `remainingMilliseconds` to distinguish input not being consumed, runtime conditions not being met, an id mismatch, or Unity already being paused. `elapsedSinceEnabledMilliseconds` is measured from `enable-debug-break`, not from `wait-for-debug-break`. -7. While Unity is paused, inspect state with `uloop get-logs`, `uloop get-hierarchy`, `uloop find-game-objects`, screenshots, or `uloop execute-dynamic-code`. Add focused debug logs before the marker when local variables must be captured. -8. Clear the marker if you stop waiting: - -```bash -uloop clear-debug-break --id state-transition-applied -``` +Use `uloop debug-break-status --id state-transition-applied` only when you need to confirm the marker is armed or inspect the current hit state. Add focused debug logs before the marker when local variables must be captured. ## Marker Placement diff --git a/Packages/src/Editor/CliOnlyTools~/PausePoint/Skill/SKILL.md b/Packages/src/Editor/CliOnlyTools~/PausePoint/Skill/SKILL.md index 311942393..34bd11bd7 100644 --- a/Packages/src/Editor/CliOnlyTools~/PausePoint/Skill/SKILL.md +++ b/Packages/src/Editor/CliOnlyTools~/PausePoint/Skill/SKILL.md @@ -7,25 +7,7 @@ description: "Use this as a quick breakpoint substitute for Unity PlayMode/E2E w Use this small loop for one transition you care about: -1. Put `UnityCliLoopDebug.Break("state-transition-applied")` at the natural transition point. -2. Compile, enter PlayMode, then enable the marker with `uloop enable-debug-break --id state-transition-applied --timeout-seconds 30`. -3. Trigger the action with a `simulate-*` command. -4. Run `uloop wait-for-debug-break --id state-transition-applied --timeout-seconds 30`, even if the trigger command already returned `InterruptedByDebugBreak=true`. -5. While Unity is paused, capture focused evidence with `uloop execute-dynamic-code`, `uloop get-logs`, and one screenshot. -6. Clear the marker or stop PlayMode before moving on. - -## When To Use - -- Use this when a state transition is transient, frame-specific, or difficult to prove after the fact. -- Use this during uloop interaction or endurance validation when simulated input drives a core runtime transition, even if durable state, logs, or screenshots can later confirm the final result. -- Good pause points include after input is consumed, a command is accepted, a state mutation is committed, an evaluation step resolves, a tracked value changes, a UI/domain state syncs, or a success/failure/end condition is entered. -- Treat the pause like a lightweight breakpoint for one important transition: combine nearby debug logs with paused-frame inspection to confirm the variables and component state at that point. -- Do not treat `simulate-* Success=true`, generic action logs, sleeps/retries, testing-only counters, or `Time.timeScale` changes as paused-frame proof. -- Skip this for ordinary persistent-state checks when you are not validating input delivery, event ordering, or transition-frame fidelity. - -## Workflow - -1. Add a marker at the state you want to inspect: +1. Put a marker at the natural transition point: ```csharp using io.github.hatayama.UnityCliLoop.Runtime; @@ -33,34 +15,31 @@ using io.github.hatayama.UnityCliLoop.Runtime; UnityCliLoopDebug.Break("state-transition-applied"); ``` -2. Compile the project. -3. Enable the marker before triggering the target code path: +2. Compile, enter PlayMode, then enable the marker: ```bash uloop enable-debug-break --id state-transition-applied --timeout-seconds 30 ``` -4. Check marker state if needed: +3. Trigger the action with a `simulate-*` command. +4. Run `uloop wait-for-debug-break --id state-transition-applied --timeout-seconds 30`, even if the trigger command already returned `InterruptedByDebugBreak=true`. +5. While Unity is paused, capture focused evidence with `uloop execute-dynamic-code`, `uloop get-logs`, `uloop get-hierarchy`, `uloop find-game-objects`, and one screenshot. +6. Clear the marker with `uloop clear-debug-break --id state-transition-applied` or stop PlayMode before moving on. -```bash -uloop debug-break-status --id state-transition-applied -``` +## When To Use -5. Trigger the behavior with `simulate-keyboard`, `simulate-mouse-input`, UI interaction, dynamic code, or similar commands. -6. Wait for the marker: +- Use this when a state transition is transient, frame-specific, or difficult to prove after the fact. +- Use this during uloop interaction or endurance validation when simulated input drives a core runtime transition, even if durable state, logs, or screenshots can later confirm the final result. +- Good pause points include after input is consumed, a command is accepted, a state mutation is committed, an evaluation step resolves, a tracked value changes, a UI/domain state syncs, or a success/failure/end condition is entered. +- Treat the pause like a lightweight breakpoint for one important transition: combine nearby debug logs with paused-frame inspection to confirm the variables and component state at that point. +- Do not treat `simulate-* Success=true`, generic action logs, sleeps/retries, testing-only counters, or `Time.timeScale` changes as paused-frame proof. +- Skip this for ordinary persistent-state checks when you are not validating input delivery, event ordering, or transition-frame fidelity. -```bash -uloop wait-for-debug-break --id state-transition-applied --timeout-seconds 30 -``` +## Timeout Checks If this command times out, the marker line was not reached while the command waited. Inspect `error.details.status`, `hitCount`, `isPlaying`, `isPaused`, `elapsedSinceEnabledMilliseconds`, and `remainingMilliseconds` to distinguish input not being consumed, runtime conditions not being met, an id mismatch, or Unity already being paused. `elapsedSinceEnabledMilliseconds` is measured from `enable-debug-break`, not from `wait-for-debug-break`. -7. While Unity is paused, inspect state with `uloop get-logs`, `uloop get-hierarchy`, `uloop find-game-objects`, screenshots, or `uloop execute-dynamic-code`. Add focused debug logs before the marker when local variables must be captured. -8. Clear the marker if you stop waiting: - -```bash -uloop clear-debug-break --id state-transition-applied -``` +Use `uloop debug-break-status --id state-transition-applied` only when you need to confirm the marker is armed or inspect the current hit state. Add focused debug logs before the marker when local variables must be captured. ## Marker Placement From 41de17ea673817d7e5e69092aac00dce2020fd5e Mon Sep 17 00:00:00 2001 From: hatayama Date: Tue, 9 Jun 2026 22:39:51 +0900 Subject: [PATCH 07/24] Guide simulated input skills toward debug-break checks Add a lightweight representative-transition prompt to simulated input skills so agents naturally pair state-changing E2E input with UnityCliLoopDebug.Break and wait-for-debug-break instead of relying only on final logs, screenshots, or durable state. --- .../skills/uloop-simulate-keyboard/SKILL.md | 30 +++++++------ .../uloop-simulate-mouse-input/SKILL.md | 44 ++++++++++--------- .../skills/uloop-simulate-mouse-ui/SKILL.md | 19 +++++--- .../uloop-wait-for-debug-break/SKILL.md | 7 +-- .../skills/uloop-simulate-keyboard/SKILL.md | 30 +++++++------ .../uloop-simulate-mouse-input/SKILL.md | 44 ++++++++++--------- .../skills/uloop-simulate-mouse-ui/SKILL.md | 19 +++++--- .../uloop-wait-for-debug-break/SKILL.md | 7 +-- .../CliOnlyTools~/PausePoint/Skill/SKILL.md | 7 +-- .../SimulateKeyboard/Skill/SKILL.md | 30 +++++++------ .../SimulateMouseInput/Skill/SKILL.md | 44 ++++++++++--------- .../SimulateMouseUi/Skill/SKILL.md | 19 +++++--- 12 files changed, 171 insertions(+), 129 deletions(-) diff --git a/.agents/skills/uloop-simulate-keyboard/SKILL.md b/.agents/skills/uloop-simulate-keyboard/SKILL.md index fc6596887..a3e1c69d2 100644 --- a/.agents/skills/uloop-simulate-keyboard/SKILL.md +++ b/.agents/skills/uloop-simulate-keyboard/SKILL.md @@ -1,7 +1,7 @@ --- name: uloop-simulate-keyboard toolName: simulate-keyboard -description: "Simulate keyboard input in PlayMode through Unity Input System. Use for key presses, holds, releases, and game controls such as WASD or Space." +description: "Simulate keyboard input in PlayMode through Unity Input System. Use for key presses, holds, releases, and state-changing E2E checks; pair one representative transition with uloop-wait-for-debug-break when input delivery matters." context: fork --- @@ -12,10 +12,11 @@ Simulate keyboard input on Unity PlayMode: $ARGUMENTS ## Workflow 1. Ensure Unity is in PlayMode (use `uloop control-play-mode --action Play` if not) -2. Execute the appropriate `uloop simulate-keyboard` command -3. Take a screenshot to verify the result: `uloop screenshot --capture-mode rendering` -4. If the screenshot cannot prove the gameplay state, place and enable a `UnityCliLoopDebug.Break("")` marker with `uloop enable-debug-break`, run the input again, then inspect while Unity is paused -5. Report what happened +2. If this is a state-changing E2E check, pick one representative transition for paused proof before relying on logs, screenshots, or durable state +3. For that representative transition, place and enable a `UnityCliLoopDebug.Break("")` marker, then run the input and inspect while Unity is paused +4. Execute any remaining `uloop simulate-keyboard` commands +5. Take a screenshot to verify the visible result: `uloop screenshot --capture-mode rendering` +6. Report what happened ## Tool Reference @@ -39,17 +40,18 @@ uloop simulate-keyboard --action --key [options] | `KeyDown` | KeyDown only (held until KeyUp) | Start continuous movement, hold sprint | | `KeyUp` | KeyUp only (release held key) | Stop movement, release sprint | -Use `Press` for edge-triggered gameplay code such as `Keyboard.current.spaceKey.wasPressedThisFrame`. +Use `Press` for edge-triggered keyboard code such as `Keyboard.current.spaceKey.wasPressedThisFrame`. `KeyDown` emits one initial press edge, then only keeps the key held. It does not keep `wasPressedThisFrame` true while the key remains held. -If a successful `Press` or `KeyDown` leaves `Keyboard.current..isPressed` true but the game state does not change, do not immediately rewrite the user's gameplay code to `isPressed`. First verify that the gameplay component is active during the command, that it polls input in the configured Input System update phase, and that a missed `KeyDown` edge is followed by `KeyUp` before retrying. +If a successful `Press` or `KeyDown` leaves `Keyboard.current..isPressed` true but runtime state does not change, do not immediately rewrite the user's runtime code to `isPressed`. First verify that the target component is active during the command, that it polls input in the configured Input System update phase, and that a missed `KeyDown` edge is followed by `KeyUp` before retrying. Use `KeyDown` / `KeyUp` when the scenario intentionally needs a held key. ### Debug Break verification -- Use `UnityCliLoopDebug.Break("")` when a screenshot cannot prove that the keyboard input changed gameplay state, such as jump, sprint, or interaction. -- Put the marker at a natural state transition after the game consumed the key, such as after jump velocity is applied, not immediately after sending `simulate-keyboard`. +- Prefer one `UnityCliLoopDebug.Break("")` marker for a representative keyboard input that changes runtime state. This is useful even when final logs or screenshots later show the outcome, because it proves the transition frame and input consumption. +- Put the marker at a natural state transition after the app consumed the key, such as after a command is accepted, a state mutation is committed, an evaluation step resolves, or a dependent component is updated. Do not place it immediately after sending `simulate-keyboard`. +- Treat `simulate-keyboard Success=true`, generic action logs, and final durable counters as useful evidence, but not as paused-frame proof. - If the response has `InterruptedByDebugBreak: true`, Unity is paused for inspection and the tool released its held input bookkeeping. If a `UnityCliLoopDebug.Break` marker caused the pause, `DebugBreakId` and `DebugBreakHitCount` identify it. Use `get-logs`, `get-hierarchy`, `find-game-objects`, or `execute-dynamic-code` before resuming. -- Use distinct marker ids for strict phases, for example `jump-key-read` and `jump-velocity-applied`. +- Use distinct marker ids for strict phases, for example `input-read`, `state-updated`, and `result-committed`. ### KeyDown/KeyUp Rules @@ -68,16 +70,16 @@ Use `KeyDown` / `KeyUp` when the scenario intentionally needs a held key. ## Examples ```bash -# One-shot key press (tap W once) +# One-shot key press uloop simulate-keyboard --action Press --key W -# Jump (tap Space) +# One-shot action key uloop simulate-keyboard --action Press --key Space -# Hold W for 2 seconds (move forward) +# Hold a key for 2 seconds uloop simulate-keyboard --action Press --key W --duration 2.0 -# Sprint forward (hold Shift + W, then release) +# Hold two keys, then release them uloop simulate-keyboard --action KeyDown --key LeftShift uloop simulate-keyboard --action KeyDown --key W uloop screenshot --capture-mode rendering diff --git a/.agents/skills/uloop-simulate-mouse-input/SKILL.md b/.agents/skills/uloop-simulate-mouse-input/SKILL.md index 78b3f0fa8..04aa53d87 100644 --- a/.agents/skills/uloop-simulate-mouse-input/SKILL.md +++ b/.agents/skills/uloop-simulate-mouse-input/SKILL.md @@ -1,7 +1,7 @@ --- name: uloop-simulate-mouse-input toolName: simulate-mouse-input -description: "Simulate Mouse.current input in PlayMode through Unity Input System. Use for gameplay clicks, mouse delta, or scroll; use simulate-mouse-ui for EventSystem UI elements." +description: "Simulate Mouse.current input in PlayMode through Unity Input System. Use for runtime clicks, mouse delta, or scroll; pair one representative state-changing E2E transition with uloop-wait-for-debug-break when input delivery matters. Use simulate-mouse-ui for EventSystem UI elements." context: fork --- @@ -13,10 +13,11 @@ Simulate mouse input via Input System in Unity PlayMode: $ARGUMENTS 1. Ensure Unity is in PlayMode (use `uloop control-play-mode --action Play` if not) 2. For Click/LongPress: determine the target screen position (use `uloop screenshot` to find coordinates) -3. Execute the appropriate `uloop simulate-mouse-input` command -4. Take a screenshot to verify the result: `uloop screenshot --capture-mode rendering` -5. If the screenshot cannot prove the gameplay state, place and enable a `UnityCliLoopDebug.Break("")` marker with `uloop enable-debug-break`, run the input again, then inspect while Unity is paused -6. Report what happened +3. If this is a state-changing E2E check, pick one representative transition for paused proof before relying on logs, screenshots, or durable state +4. For that representative transition, place and enable a `UnityCliLoopDebug.Break("")` marker, then run the input and inspect while Unity is paused +5. Execute any remaining `uloop simulate-mouse-input` commands +6. Take a screenshot to verify the visible result: `uloop screenshot --capture-mode rendering` +7. Report what happened ## Tool Reference @@ -42,18 +43,19 @@ uloop simulate-mouse-input --action [options] | Action | What it injects | Description | |--------|----------------|-------------| -| `Click` | Mouse.current button press → release | Inject a button click so game logic detects `wasPressedThisFrame` | +| `Click` | Mouse.current button press → release | Inject a button click so runtime logic detects `wasPressedThisFrame` | | `LongPress` | Mouse.current button press → hold → release | Hold a button for `--duration` seconds | -| `MoveDelta` | Mouse.current.delta | Inject mouse movement delta one-shot (e.g. for FPS camera look) | +| `MoveDelta` | Mouse.current.delta | Inject mouse movement delta one-shot | | `SmoothDelta` | Mouse.current.delta (per-frame) | Inject mouse delta smoothly over `--duration` seconds (human-like camera pan) | -| `Scroll` | Mouse.current.scroll | Inject scroll wheel input (e.g. for hotbar or zoom) | +| `Scroll` | Mouse.current.scroll | Inject scroll wheel input | ### Debug Break verification -- Use `UnityCliLoopDebug.Break("")` when a screenshot cannot prove that mouse input changed gameplay state, such as block hit, camera turn, or item placement. -- Put the marker at a natural state transition after the game consumed the mouse input, such as after a raycast hit, damage application, placement, or camera rotation update, not immediately after sending `simulate-mouse-input`. +- Prefer one `UnityCliLoopDebug.Break("")` marker for a representative mouse input that changes runtime state. This is useful even when final logs or screenshots later show the outcome, because it proves the transition frame and input consumption. +- Put the marker at a natural state transition after the app consumed the mouse input, such as after a command is accepted, a state mutation is committed, an evaluation step resolves, a tracked value changes, or a dependent component is updated. Do not place it immediately after sending `simulate-mouse-input`. +- Treat `simulate-mouse-input Success=true`, generic action logs, and final durable counters as useful evidence, but not as paused-frame proof. - If the response has `InterruptedByDebugBreak: true`, Unity is paused for inspection and the tool released its held input bookkeeping. If a `UnityCliLoopDebug.Break` marker caused the pause, `DebugBreakId` and `DebugBreakHitCount` identify it. Use `get-logs`, `get-hierarchy`, `find-game-objects`, or `execute-dynamic-code` before resuming. -- Use distinct marker ids for strict phases, for example `block-raycast-hit` and `block-damage-applied`. +- Use distinct marker ids for strict phases, for example `input-read`, `state-updated`, and `result-committed`. ### Global Options (optional) @@ -67,31 +69,31 @@ uloop simulate-mouse-input --action [options] | Scenario | Tool | |----------|------| | Click a Unity UI Button (IPointerClickHandler) | `simulate-mouse-ui` | -| Destroy a block in Minecraft (reads `Mouse.current.leftButton`) | `simulate-mouse-input` when the project uses the New Input System | -| Place a block with right-click | `simulate-mouse-input --button Right` when the project uses the New Input System | +| Runtime logic reads `Mouse.current.leftButton` | `simulate-mouse-input` when the project uses the New Input System | +| Runtime logic reads right-click | `simulate-mouse-input --button Right` when the project uses the New Input System | | Drag a UI slider | `simulate-mouse-ui --action Drag` | -| Look around with mouse (FPS camera) | `simulate-mouse-input --action MoveDelta` when the project uses the New Input System | -| Scroll hotbar slots | `simulate-mouse-input --action Scroll` when the project uses the New Input System | +| Runtime logic reads `Mouse.current.delta` | `simulate-mouse-input --action MoveDelta` when the project uses the New Input System | +| Runtime logic reads `Mouse.current.scroll` | `simulate-mouse-input --action Scroll` when the project uses the New Input System | ## Examples ```bash -# Left-click at screen center (for game logic) +# Left-click at screen center for runtime input uloop simulate-mouse-input --action Click --x 400 --y 300 -# Right-click at screen center (e.g. place block) +# Right-click at screen center uloop simulate-mouse-input --action Click --x 400 --y 300 --button Right -# Hold left-click for 2 seconds (e.g. mine block) +# Hold left-click for 2 seconds uloop simulate-mouse-input --action LongPress --x 400 --y 300 --duration 2.0 -# Look right (FPS camera) +# Send a one-shot mouse delta uloop simulate-mouse-input --action MoveDelta --delta-x 100 --delta-y 0 -# Scroll up (e.g. previous hotbar slot) +# Scroll up uloop simulate-mouse-input --action Scroll --scroll-y 120 -# Scroll down (e.g. next hotbar slot) +# Scroll down uloop simulate-mouse-input --action Scroll --scroll-y -120 # Smooth camera pan right over 0.5 seconds diff --git a/.agents/skills/uloop-simulate-mouse-ui/SKILL.md b/.agents/skills/uloop-simulate-mouse-ui/SKILL.md index 54e34d693..75794a754 100644 --- a/.agents/skills/uloop-simulate-mouse-ui/SKILL.md +++ b/.agents/skills/uloop-simulate-mouse-ui/SKILL.md @@ -1,7 +1,7 @@ --- name: uloop-simulate-mouse-ui toolName: simulate-mouse-ui -description: "Simulate PlayMode EventSystem UI mouse actions using screen coordinates. Use for UI clicks, long-presses, or drags from annotated screenshots." +description: "Simulate PlayMode EventSystem UI mouse actions using screen coordinates. Use for UI clicks, long-presses, or drags from annotated screenshots; pair one representative state-changing UI action with uloop-wait-for-debug-break when input delivery matters." context: fork --- @@ -14,9 +14,11 @@ Simulate mouse interaction on Unity PlayMode UI: $ARGUMENTS 1. Ensure Unity is in PlayMode (use `uloop control-play-mode --action Play` if not) 2. Get UI element info: `uloop screenshot --capture-mode rendering --annotate-elements --elements-only` 3. Use the `AnnotatedElements` array to find the target element by `Label`, `Name`, or `Path` (A=frontmost, B=next, ...). Use `Interaction` to distinguish click targets from drag/drop/text targets, then use `SimX`/`SimY` directly as `--x`/`--y` coordinates. -4. Execute the appropriate `uloop simulate-mouse-ui` command -5. Take a screenshot to verify the result: `uloop screenshot --capture-mode rendering --annotate-elements` -6. Report what happened +4. If this UI action changes runtime state, pick one representative transition for paused proof before relying on logs, screenshots, or durable state +5. For that representative transition, place and enable a `UnityCliLoopDebug.Break("")` marker, then run the UI action and inspect while Unity is paused +6. Execute any remaining `uloop simulate-mouse-ui` commands +7. Take a screenshot to verify the visible result: `uloop screenshot --capture-mode rendering --annotate-elements` +8. Report what happened ## Tool Reference @@ -75,6 +77,13 @@ uloop simulate-mouse-ui --action --x --y [options] - `--bypass-raycast` still uses coordinates for pointer event positions, but chooses the clicked, long-pressed, or dragged GameObject by `--target-path` - If `--target-path` or `--drop-target-path` matches multiple active GameObjects, the command fails instead of choosing an arbitrary duplicate +## Debug Break Verification + +- Prefer one `UnityCliLoopDebug.Break("")` marker for a representative UI action that changes runtime state. This is useful even when final logs or screenshots later show the outcome, because it proves the transition frame and input consumption. +- Put the marker at a natural transition after the app consumed the UI event, such as after a command is accepted, a state mutation is committed, a tracked value changes, a UI/domain state syncs, or a success/failure/end condition is entered. +- Treat `simulate-mouse-ui Success=true`, generic action logs, and final durable counters as useful evidence, but not as paused-frame proof. +- If a `UnityCliLoopDebug.Break` marker pauses Unity, inspect with `get-logs`, `get-hierarchy`, `find-game-objects`, or `execute-dynamic-code` before resuming. + ## Examples ```bash @@ -114,7 +123,7 @@ uloop simulate-mouse-ui --action DragEnd --x 600 --y 300 - Unity must be in **PlayMode** - Target scene must have an **EventSystem** GameObject - UI elements must have a **GraphicRaycaster** on their Canvas -- If you need gameplay mouse input rather than UI pointer events, `simulate-mouse-input` assumes the project uses the New Input System; otherwise prefer `execute-dynamic-code` +- If you need runtime mouse input rather than UI pointer events, `simulate-mouse-input` assumes the project uses the New Input System; otherwise prefer `execute-dynamic-code` ## Output diff --git a/.agents/skills/uloop-wait-for-debug-break/SKILL.md b/.agents/skills/uloop-wait-for-debug-break/SKILL.md index 34bd11bd7..e3b9415af 100644 --- a/.agents/skills/uloop-wait-for-debug-break/SKILL.md +++ b/.agents/skills/uloop-wait-for-debug-break/SKILL.md @@ -1,11 +1,11 @@ --- name: uloop-wait-for-debug-break -description: "Use this as a quick breakpoint substitute for Unity PlayMode/E2E when uloop-simulated input changes runtime state. Add a marker, run wait-for-debug-break, and inspect paused variables/state; simulate-* success or InterruptedByDebugBreak alone is not proof." +description: "Use this as a quick breakpoint substitute for Unity PlayMode/E2E when uloop-simulated input is expected to change runtime state. Add one marker at a representative transition, run wait-for-debug-break, and inspect paused variables/state; final logs, screenshots, or simulate-* success alone are not input-consumption proof." --- ## Quick Check Template -Use this small loop for one transition you care about: +Use this small loop for one representative transition you care about: 1. Put a marker at the natural transition point: @@ -30,10 +30,11 @@ uloop enable-debug-break --id state-transition-applied --timeout-seconds 30 - Use this when a state transition is transient, frame-specific, or difficult to prove after the fact. - Use this during uloop interaction or endurance validation when simulated input drives a core runtime transition, even if durable state, logs, or screenshots can later confirm the final result. +- A useful default is to check one representative input-driven transition per E2E pass, then use logs, screenshots, and durable state for the rest. - Good pause points include after input is consumed, a command is accepted, a state mutation is committed, an evaluation step resolves, a tracked value changes, a UI/domain state syncs, or a success/failure/end condition is entered. - Treat the pause like a lightweight breakpoint for one important transition: combine nearby debug logs with paused-frame inspection to confirm the variables and component state at that point. - Do not treat `simulate-* Success=true`, generic action logs, sleeps/retries, testing-only counters, or `Time.timeScale` changes as paused-frame proof. -- Skip this for ordinary persistent-state checks when you are not validating input delivery, event ordering, or transition-frame fidelity. +- Skip this only for ordinary persistent-state checks when you are not validating simulated input delivery, event ordering, or transition-frame fidelity. ## Timeout Checks diff --git a/.claude/skills/uloop-simulate-keyboard/SKILL.md b/.claude/skills/uloop-simulate-keyboard/SKILL.md index fc6596887..a3e1c69d2 100644 --- a/.claude/skills/uloop-simulate-keyboard/SKILL.md +++ b/.claude/skills/uloop-simulate-keyboard/SKILL.md @@ -1,7 +1,7 @@ --- name: uloop-simulate-keyboard toolName: simulate-keyboard -description: "Simulate keyboard input in PlayMode through Unity Input System. Use for key presses, holds, releases, and game controls such as WASD or Space." +description: "Simulate keyboard input in PlayMode through Unity Input System. Use for key presses, holds, releases, and state-changing E2E checks; pair one representative transition with uloop-wait-for-debug-break when input delivery matters." context: fork --- @@ -12,10 +12,11 @@ Simulate keyboard input on Unity PlayMode: $ARGUMENTS ## Workflow 1. Ensure Unity is in PlayMode (use `uloop control-play-mode --action Play` if not) -2. Execute the appropriate `uloop simulate-keyboard` command -3. Take a screenshot to verify the result: `uloop screenshot --capture-mode rendering` -4. If the screenshot cannot prove the gameplay state, place and enable a `UnityCliLoopDebug.Break("")` marker with `uloop enable-debug-break`, run the input again, then inspect while Unity is paused -5. Report what happened +2. If this is a state-changing E2E check, pick one representative transition for paused proof before relying on logs, screenshots, or durable state +3. For that representative transition, place and enable a `UnityCliLoopDebug.Break("")` marker, then run the input and inspect while Unity is paused +4. Execute any remaining `uloop simulate-keyboard` commands +5. Take a screenshot to verify the visible result: `uloop screenshot --capture-mode rendering` +6. Report what happened ## Tool Reference @@ -39,17 +40,18 @@ uloop simulate-keyboard --action --key [options] | `KeyDown` | KeyDown only (held until KeyUp) | Start continuous movement, hold sprint | | `KeyUp` | KeyUp only (release held key) | Stop movement, release sprint | -Use `Press` for edge-triggered gameplay code such as `Keyboard.current.spaceKey.wasPressedThisFrame`. +Use `Press` for edge-triggered keyboard code such as `Keyboard.current.spaceKey.wasPressedThisFrame`. `KeyDown` emits one initial press edge, then only keeps the key held. It does not keep `wasPressedThisFrame` true while the key remains held. -If a successful `Press` or `KeyDown` leaves `Keyboard.current..isPressed` true but the game state does not change, do not immediately rewrite the user's gameplay code to `isPressed`. First verify that the gameplay component is active during the command, that it polls input in the configured Input System update phase, and that a missed `KeyDown` edge is followed by `KeyUp` before retrying. +If a successful `Press` or `KeyDown` leaves `Keyboard.current..isPressed` true but runtime state does not change, do not immediately rewrite the user's runtime code to `isPressed`. First verify that the target component is active during the command, that it polls input in the configured Input System update phase, and that a missed `KeyDown` edge is followed by `KeyUp` before retrying. Use `KeyDown` / `KeyUp` when the scenario intentionally needs a held key. ### Debug Break verification -- Use `UnityCliLoopDebug.Break("")` when a screenshot cannot prove that the keyboard input changed gameplay state, such as jump, sprint, or interaction. -- Put the marker at a natural state transition after the game consumed the key, such as after jump velocity is applied, not immediately after sending `simulate-keyboard`. +- Prefer one `UnityCliLoopDebug.Break("")` marker for a representative keyboard input that changes runtime state. This is useful even when final logs or screenshots later show the outcome, because it proves the transition frame and input consumption. +- Put the marker at a natural state transition after the app consumed the key, such as after a command is accepted, a state mutation is committed, an evaluation step resolves, or a dependent component is updated. Do not place it immediately after sending `simulate-keyboard`. +- Treat `simulate-keyboard Success=true`, generic action logs, and final durable counters as useful evidence, but not as paused-frame proof. - If the response has `InterruptedByDebugBreak: true`, Unity is paused for inspection and the tool released its held input bookkeeping. If a `UnityCliLoopDebug.Break` marker caused the pause, `DebugBreakId` and `DebugBreakHitCount` identify it. Use `get-logs`, `get-hierarchy`, `find-game-objects`, or `execute-dynamic-code` before resuming. -- Use distinct marker ids for strict phases, for example `jump-key-read` and `jump-velocity-applied`. +- Use distinct marker ids for strict phases, for example `input-read`, `state-updated`, and `result-committed`. ### KeyDown/KeyUp Rules @@ -68,16 +70,16 @@ Use `KeyDown` / `KeyUp` when the scenario intentionally needs a held key. ## Examples ```bash -# One-shot key press (tap W once) +# One-shot key press uloop simulate-keyboard --action Press --key W -# Jump (tap Space) +# One-shot action key uloop simulate-keyboard --action Press --key Space -# Hold W for 2 seconds (move forward) +# Hold a key for 2 seconds uloop simulate-keyboard --action Press --key W --duration 2.0 -# Sprint forward (hold Shift + W, then release) +# Hold two keys, then release them uloop simulate-keyboard --action KeyDown --key LeftShift uloop simulate-keyboard --action KeyDown --key W uloop screenshot --capture-mode rendering diff --git a/.claude/skills/uloop-simulate-mouse-input/SKILL.md b/.claude/skills/uloop-simulate-mouse-input/SKILL.md index 78b3f0fa8..04aa53d87 100644 --- a/.claude/skills/uloop-simulate-mouse-input/SKILL.md +++ b/.claude/skills/uloop-simulate-mouse-input/SKILL.md @@ -1,7 +1,7 @@ --- name: uloop-simulate-mouse-input toolName: simulate-mouse-input -description: "Simulate Mouse.current input in PlayMode through Unity Input System. Use for gameplay clicks, mouse delta, or scroll; use simulate-mouse-ui for EventSystem UI elements." +description: "Simulate Mouse.current input in PlayMode through Unity Input System. Use for runtime clicks, mouse delta, or scroll; pair one representative state-changing E2E transition with uloop-wait-for-debug-break when input delivery matters. Use simulate-mouse-ui for EventSystem UI elements." context: fork --- @@ -13,10 +13,11 @@ Simulate mouse input via Input System in Unity PlayMode: $ARGUMENTS 1. Ensure Unity is in PlayMode (use `uloop control-play-mode --action Play` if not) 2. For Click/LongPress: determine the target screen position (use `uloop screenshot` to find coordinates) -3. Execute the appropriate `uloop simulate-mouse-input` command -4. Take a screenshot to verify the result: `uloop screenshot --capture-mode rendering` -5. If the screenshot cannot prove the gameplay state, place and enable a `UnityCliLoopDebug.Break("")` marker with `uloop enable-debug-break`, run the input again, then inspect while Unity is paused -6. Report what happened +3. If this is a state-changing E2E check, pick one representative transition for paused proof before relying on logs, screenshots, or durable state +4. For that representative transition, place and enable a `UnityCliLoopDebug.Break("")` marker, then run the input and inspect while Unity is paused +5. Execute any remaining `uloop simulate-mouse-input` commands +6. Take a screenshot to verify the visible result: `uloop screenshot --capture-mode rendering` +7. Report what happened ## Tool Reference @@ -42,18 +43,19 @@ uloop simulate-mouse-input --action [options] | Action | What it injects | Description | |--------|----------------|-------------| -| `Click` | Mouse.current button press → release | Inject a button click so game logic detects `wasPressedThisFrame` | +| `Click` | Mouse.current button press → release | Inject a button click so runtime logic detects `wasPressedThisFrame` | | `LongPress` | Mouse.current button press → hold → release | Hold a button for `--duration` seconds | -| `MoveDelta` | Mouse.current.delta | Inject mouse movement delta one-shot (e.g. for FPS camera look) | +| `MoveDelta` | Mouse.current.delta | Inject mouse movement delta one-shot | | `SmoothDelta` | Mouse.current.delta (per-frame) | Inject mouse delta smoothly over `--duration` seconds (human-like camera pan) | -| `Scroll` | Mouse.current.scroll | Inject scroll wheel input (e.g. for hotbar or zoom) | +| `Scroll` | Mouse.current.scroll | Inject scroll wheel input | ### Debug Break verification -- Use `UnityCliLoopDebug.Break("")` when a screenshot cannot prove that mouse input changed gameplay state, such as block hit, camera turn, or item placement. -- Put the marker at a natural state transition after the game consumed the mouse input, such as after a raycast hit, damage application, placement, or camera rotation update, not immediately after sending `simulate-mouse-input`. +- Prefer one `UnityCliLoopDebug.Break("")` marker for a representative mouse input that changes runtime state. This is useful even when final logs or screenshots later show the outcome, because it proves the transition frame and input consumption. +- Put the marker at a natural state transition after the app consumed the mouse input, such as after a command is accepted, a state mutation is committed, an evaluation step resolves, a tracked value changes, or a dependent component is updated. Do not place it immediately after sending `simulate-mouse-input`. +- Treat `simulate-mouse-input Success=true`, generic action logs, and final durable counters as useful evidence, but not as paused-frame proof. - If the response has `InterruptedByDebugBreak: true`, Unity is paused for inspection and the tool released its held input bookkeeping. If a `UnityCliLoopDebug.Break` marker caused the pause, `DebugBreakId` and `DebugBreakHitCount` identify it. Use `get-logs`, `get-hierarchy`, `find-game-objects`, or `execute-dynamic-code` before resuming. -- Use distinct marker ids for strict phases, for example `block-raycast-hit` and `block-damage-applied`. +- Use distinct marker ids for strict phases, for example `input-read`, `state-updated`, and `result-committed`. ### Global Options (optional) @@ -67,31 +69,31 @@ uloop simulate-mouse-input --action [options] | Scenario | Tool | |----------|------| | Click a Unity UI Button (IPointerClickHandler) | `simulate-mouse-ui` | -| Destroy a block in Minecraft (reads `Mouse.current.leftButton`) | `simulate-mouse-input` when the project uses the New Input System | -| Place a block with right-click | `simulate-mouse-input --button Right` when the project uses the New Input System | +| Runtime logic reads `Mouse.current.leftButton` | `simulate-mouse-input` when the project uses the New Input System | +| Runtime logic reads right-click | `simulate-mouse-input --button Right` when the project uses the New Input System | | Drag a UI slider | `simulate-mouse-ui --action Drag` | -| Look around with mouse (FPS camera) | `simulate-mouse-input --action MoveDelta` when the project uses the New Input System | -| Scroll hotbar slots | `simulate-mouse-input --action Scroll` when the project uses the New Input System | +| Runtime logic reads `Mouse.current.delta` | `simulate-mouse-input --action MoveDelta` when the project uses the New Input System | +| Runtime logic reads `Mouse.current.scroll` | `simulate-mouse-input --action Scroll` when the project uses the New Input System | ## Examples ```bash -# Left-click at screen center (for game logic) +# Left-click at screen center for runtime input uloop simulate-mouse-input --action Click --x 400 --y 300 -# Right-click at screen center (e.g. place block) +# Right-click at screen center uloop simulate-mouse-input --action Click --x 400 --y 300 --button Right -# Hold left-click for 2 seconds (e.g. mine block) +# Hold left-click for 2 seconds uloop simulate-mouse-input --action LongPress --x 400 --y 300 --duration 2.0 -# Look right (FPS camera) +# Send a one-shot mouse delta uloop simulate-mouse-input --action MoveDelta --delta-x 100 --delta-y 0 -# Scroll up (e.g. previous hotbar slot) +# Scroll up uloop simulate-mouse-input --action Scroll --scroll-y 120 -# Scroll down (e.g. next hotbar slot) +# Scroll down uloop simulate-mouse-input --action Scroll --scroll-y -120 # Smooth camera pan right over 0.5 seconds diff --git a/.claude/skills/uloop-simulate-mouse-ui/SKILL.md b/.claude/skills/uloop-simulate-mouse-ui/SKILL.md index 54e34d693..75794a754 100644 --- a/.claude/skills/uloop-simulate-mouse-ui/SKILL.md +++ b/.claude/skills/uloop-simulate-mouse-ui/SKILL.md @@ -1,7 +1,7 @@ --- name: uloop-simulate-mouse-ui toolName: simulate-mouse-ui -description: "Simulate PlayMode EventSystem UI mouse actions using screen coordinates. Use for UI clicks, long-presses, or drags from annotated screenshots." +description: "Simulate PlayMode EventSystem UI mouse actions using screen coordinates. Use for UI clicks, long-presses, or drags from annotated screenshots; pair one representative state-changing UI action with uloop-wait-for-debug-break when input delivery matters." context: fork --- @@ -14,9 +14,11 @@ Simulate mouse interaction on Unity PlayMode UI: $ARGUMENTS 1. Ensure Unity is in PlayMode (use `uloop control-play-mode --action Play` if not) 2. Get UI element info: `uloop screenshot --capture-mode rendering --annotate-elements --elements-only` 3. Use the `AnnotatedElements` array to find the target element by `Label`, `Name`, or `Path` (A=frontmost, B=next, ...). Use `Interaction` to distinguish click targets from drag/drop/text targets, then use `SimX`/`SimY` directly as `--x`/`--y` coordinates. -4. Execute the appropriate `uloop simulate-mouse-ui` command -5. Take a screenshot to verify the result: `uloop screenshot --capture-mode rendering --annotate-elements` -6. Report what happened +4. If this UI action changes runtime state, pick one representative transition for paused proof before relying on logs, screenshots, or durable state +5. For that representative transition, place and enable a `UnityCliLoopDebug.Break("")` marker, then run the UI action and inspect while Unity is paused +6. Execute any remaining `uloop simulate-mouse-ui` commands +7. Take a screenshot to verify the visible result: `uloop screenshot --capture-mode rendering --annotate-elements` +8. Report what happened ## Tool Reference @@ -75,6 +77,13 @@ uloop simulate-mouse-ui --action --x --y [options] - `--bypass-raycast` still uses coordinates for pointer event positions, but chooses the clicked, long-pressed, or dragged GameObject by `--target-path` - If `--target-path` or `--drop-target-path` matches multiple active GameObjects, the command fails instead of choosing an arbitrary duplicate +## Debug Break Verification + +- Prefer one `UnityCliLoopDebug.Break("")` marker for a representative UI action that changes runtime state. This is useful even when final logs or screenshots later show the outcome, because it proves the transition frame and input consumption. +- Put the marker at a natural transition after the app consumed the UI event, such as after a command is accepted, a state mutation is committed, a tracked value changes, a UI/domain state syncs, or a success/failure/end condition is entered. +- Treat `simulate-mouse-ui Success=true`, generic action logs, and final durable counters as useful evidence, but not as paused-frame proof. +- If a `UnityCliLoopDebug.Break` marker pauses Unity, inspect with `get-logs`, `get-hierarchy`, `find-game-objects`, or `execute-dynamic-code` before resuming. + ## Examples ```bash @@ -114,7 +123,7 @@ uloop simulate-mouse-ui --action DragEnd --x 600 --y 300 - Unity must be in **PlayMode** - Target scene must have an **EventSystem** GameObject - UI elements must have a **GraphicRaycaster** on their Canvas -- If you need gameplay mouse input rather than UI pointer events, `simulate-mouse-input` assumes the project uses the New Input System; otherwise prefer `execute-dynamic-code` +- If you need runtime mouse input rather than UI pointer events, `simulate-mouse-input` assumes the project uses the New Input System; otherwise prefer `execute-dynamic-code` ## Output diff --git a/.claude/skills/uloop-wait-for-debug-break/SKILL.md b/.claude/skills/uloop-wait-for-debug-break/SKILL.md index 34bd11bd7..e3b9415af 100644 --- a/.claude/skills/uloop-wait-for-debug-break/SKILL.md +++ b/.claude/skills/uloop-wait-for-debug-break/SKILL.md @@ -1,11 +1,11 @@ --- name: uloop-wait-for-debug-break -description: "Use this as a quick breakpoint substitute for Unity PlayMode/E2E when uloop-simulated input changes runtime state. Add a marker, run wait-for-debug-break, and inspect paused variables/state; simulate-* success or InterruptedByDebugBreak alone is not proof." +description: "Use this as a quick breakpoint substitute for Unity PlayMode/E2E when uloop-simulated input is expected to change runtime state. Add one marker at a representative transition, run wait-for-debug-break, and inspect paused variables/state; final logs, screenshots, or simulate-* success alone are not input-consumption proof." --- ## Quick Check Template -Use this small loop for one transition you care about: +Use this small loop for one representative transition you care about: 1. Put a marker at the natural transition point: @@ -30,10 +30,11 @@ uloop enable-debug-break --id state-transition-applied --timeout-seconds 30 - Use this when a state transition is transient, frame-specific, or difficult to prove after the fact. - Use this during uloop interaction or endurance validation when simulated input drives a core runtime transition, even if durable state, logs, or screenshots can later confirm the final result. +- A useful default is to check one representative input-driven transition per E2E pass, then use logs, screenshots, and durable state for the rest. - Good pause points include after input is consumed, a command is accepted, a state mutation is committed, an evaluation step resolves, a tracked value changes, a UI/domain state syncs, or a success/failure/end condition is entered. - Treat the pause like a lightweight breakpoint for one important transition: combine nearby debug logs with paused-frame inspection to confirm the variables and component state at that point. - Do not treat `simulate-* Success=true`, generic action logs, sleeps/retries, testing-only counters, or `Time.timeScale` changes as paused-frame proof. -- Skip this for ordinary persistent-state checks when you are not validating input delivery, event ordering, or transition-frame fidelity. +- Skip this only for ordinary persistent-state checks when you are not validating simulated input delivery, event ordering, or transition-frame fidelity. ## Timeout Checks diff --git a/Packages/src/Editor/CliOnlyTools~/PausePoint/Skill/SKILL.md b/Packages/src/Editor/CliOnlyTools~/PausePoint/Skill/SKILL.md index 34bd11bd7..e3b9415af 100644 --- a/Packages/src/Editor/CliOnlyTools~/PausePoint/Skill/SKILL.md +++ b/Packages/src/Editor/CliOnlyTools~/PausePoint/Skill/SKILL.md @@ -1,11 +1,11 @@ --- name: uloop-wait-for-debug-break -description: "Use this as a quick breakpoint substitute for Unity PlayMode/E2E when uloop-simulated input changes runtime state. Add a marker, run wait-for-debug-break, and inspect paused variables/state; simulate-* success or InterruptedByDebugBreak alone is not proof." +description: "Use this as a quick breakpoint substitute for Unity PlayMode/E2E when uloop-simulated input is expected to change runtime state. Add one marker at a representative transition, run wait-for-debug-break, and inspect paused variables/state; final logs, screenshots, or simulate-* success alone are not input-consumption proof." --- ## Quick Check Template -Use this small loop for one transition you care about: +Use this small loop for one representative transition you care about: 1. Put a marker at the natural transition point: @@ -30,10 +30,11 @@ uloop enable-debug-break --id state-transition-applied --timeout-seconds 30 - Use this when a state transition is transient, frame-specific, or difficult to prove after the fact. - Use this during uloop interaction or endurance validation when simulated input drives a core runtime transition, even if durable state, logs, or screenshots can later confirm the final result. +- A useful default is to check one representative input-driven transition per E2E pass, then use logs, screenshots, and durable state for the rest. - Good pause points include after input is consumed, a command is accepted, a state mutation is committed, an evaluation step resolves, a tracked value changes, a UI/domain state syncs, or a success/failure/end condition is entered. - Treat the pause like a lightweight breakpoint for one important transition: combine nearby debug logs with paused-frame inspection to confirm the variables and component state at that point. - Do not treat `simulate-* Success=true`, generic action logs, sleeps/retries, testing-only counters, or `Time.timeScale` changes as paused-frame proof. -- Skip this for ordinary persistent-state checks when you are not validating input delivery, event ordering, or transition-frame fidelity. +- Skip this only for ordinary persistent-state checks when you are not validating simulated input delivery, event ordering, or transition-frame fidelity. ## Timeout Checks diff --git a/Packages/src/Editor/FirstPartyTools/SimulateKeyboard/Skill/SKILL.md b/Packages/src/Editor/FirstPartyTools/SimulateKeyboard/Skill/SKILL.md index fc6596887..a3e1c69d2 100644 --- a/Packages/src/Editor/FirstPartyTools/SimulateKeyboard/Skill/SKILL.md +++ b/Packages/src/Editor/FirstPartyTools/SimulateKeyboard/Skill/SKILL.md @@ -1,7 +1,7 @@ --- name: uloop-simulate-keyboard toolName: simulate-keyboard -description: "Simulate keyboard input in PlayMode through Unity Input System. Use for key presses, holds, releases, and game controls such as WASD or Space." +description: "Simulate keyboard input in PlayMode through Unity Input System. Use for key presses, holds, releases, and state-changing E2E checks; pair one representative transition with uloop-wait-for-debug-break when input delivery matters." context: fork --- @@ -12,10 +12,11 @@ Simulate keyboard input on Unity PlayMode: $ARGUMENTS ## Workflow 1. Ensure Unity is in PlayMode (use `uloop control-play-mode --action Play` if not) -2. Execute the appropriate `uloop simulate-keyboard` command -3. Take a screenshot to verify the result: `uloop screenshot --capture-mode rendering` -4. If the screenshot cannot prove the gameplay state, place and enable a `UnityCliLoopDebug.Break("")` marker with `uloop enable-debug-break`, run the input again, then inspect while Unity is paused -5. Report what happened +2. If this is a state-changing E2E check, pick one representative transition for paused proof before relying on logs, screenshots, or durable state +3. For that representative transition, place and enable a `UnityCliLoopDebug.Break("")` marker, then run the input and inspect while Unity is paused +4. Execute any remaining `uloop simulate-keyboard` commands +5. Take a screenshot to verify the visible result: `uloop screenshot --capture-mode rendering` +6. Report what happened ## Tool Reference @@ -39,17 +40,18 @@ uloop simulate-keyboard --action --key [options] | `KeyDown` | KeyDown only (held until KeyUp) | Start continuous movement, hold sprint | | `KeyUp` | KeyUp only (release held key) | Stop movement, release sprint | -Use `Press` for edge-triggered gameplay code such as `Keyboard.current.spaceKey.wasPressedThisFrame`. +Use `Press` for edge-triggered keyboard code such as `Keyboard.current.spaceKey.wasPressedThisFrame`. `KeyDown` emits one initial press edge, then only keeps the key held. It does not keep `wasPressedThisFrame` true while the key remains held. -If a successful `Press` or `KeyDown` leaves `Keyboard.current..isPressed` true but the game state does not change, do not immediately rewrite the user's gameplay code to `isPressed`. First verify that the gameplay component is active during the command, that it polls input in the configured Input System update phase, and that a missed `KeyDown` edge is followed by `KeyUp` before retrying. +If a successful `Press` or `KeyDown` leaves `Keyboard.current..isPressed` true but runtime state does not change, do not immediately rewrite the user's runtime code to `isPressed`. First verify that the target component is active during the command, that it polls input in the configured Input System update phase, and that a missed `KeyDown` edge is followed by `KeyUp` before retrying. Use `KeyDown` / `KeyUp` when the scenario intentionally needs a held key. ### Debug Break verification -- Use `UnityCliLoopDebug.Break("")` when a screenshot cannot prove that the keyboard input changed gameplay state, such as jump, sprint, or interaction. -- Put the marker at a natural state transition after the game consumed the key, such as after jump velocity is applied, not immediately after sending `simulate-keyboard`. +- Prefer one `UnityCliLoopDebug.Break("")` marker for a representative keyboard input that changes runtime state. This is useful even when final logs or screenshots later show the outcome, because it proves the transition frame and input consumption. +- Put the marker at a natural state transition after the app consumed the key, such as after a command is accepted, a state mutation is committed, an evaluation step resolves, or a dependent component is updated. Do not place it immediately after sending `simulate-keyboard`. +- Treat `simulate-keyboard Success=true`, generic action logs, and final durable counters as useful evidence, but not as paused-frame proof. - If the response has `InterruptedByDebugBreak: true`, Unity is paused for inspection and the tool released its held input bookkeeping. If a `UnityCliLoopDebug.Break` marker caused the pause, `DebugBreakId` and `DebugBreakHitCount` identify it. Use `get-logs`, `get-hierarchy`, `find-game-objects`, or `execute-dynamic-code` before resuming. -- Use distinct marker ids for strict phases, for example `jump-key-read` and `jump-velocity-applied`. +- Use distinct marker ids for strict phases, for example `input-read`, `state-updated`, and `result-committed`. ### KeyDown/KeyUp Rules @@ -68,16 +70,16 @@ Use `KeyDown` / `KeyUp` when the scenario intentionally needs a held key. ## Examples ```bash -# One-shot key press (tap W once) +# One-shot key press uloop simulate-keyboard --action Press --key W -# Jump (tap Space) +# One-shot action key uloop simulate-keyboard --action Press --key Space -# Hold W for 2 seconds (move forward) +# Hold a key for 2 seconds uloop simulate-keyboard --action Press --key W --duration 2.0 -# Sprint forward (hold Shift + W, then release) +# Hold two keys, then release them uloop simulate-keyboard --action KeyDown --key LeftShift uloop simulate-keyboard --action KeyDown --key W uloop screenshot --capture-mode rendering diff --git a/Packages/src/Editor/FirstPartyTools/SimulateMouseInput/Skill/SKILL.md b/Packages/src/Editor/FirstPartyTools/SimulateMouseInput/Skill/SKILL.md index 78b3f0fa8..04aa53d87 100644 --- a/Packages/src/Editor/FirstPartyTools/SimulateMouseInput/Skill/SKILL.md +++ b/Packages/src/Editor/FirstPartyTools/SimulateMouseInput/Skill/SKILL.md @@ -1,7 +1,7 @@ --- name: uloop-simulate-mouse-input toolName: simulate-mouse-input -description: "Simulate Mouse.current input in PlayMode through Unity Input System. Use for gameplay clicks, mouse delta, or scroll; use simulate-mouse-ui for EventSystem UI elements." +description: "Simulate Mouse.current input in PlayMode through Unity Input System. Use for runtime clicks, mouse delta, or scroll; pair one representative state-changing E2E transition with uloop-wait-for-debug-break when input delivery matters. Use simulate-mouse-ui for EventSystem UI elements." context: fork --- @@ -13,10 +13,11 @@ Simulate mouse input via Input System in Unity PlayMode: $ARGUMENTS 1. Ensure Unity is in PlayMode (use `uloop control-play-mode --action Play` if not) 2. For Click/LongPress: determine the target screen position (use `uloop screenshot` to find coordinates) -3. Execute the appropriate `uloop simulate-mouse-input` command -4. Take a screenshot to verify the result: `uloop screenshot --capture-mode rendering` -5. If the screenshot cannot prove the gameplay state, place and enable a `UnityCliLoopDebug.Break("")` marker with `uloop enable-debug-break`, run the input again, then inspect while Unity is paused -6. Report what happened +3. If this is a state-changing E2E check, pick one representative transition for paused proof before relying on logs, screenshots, or durable state +4. For that representative transition, place and enable a `UnityCliLoopDebug.Break("")` marker, then run the input and inspect while Unity is paused +5. Execute any remaining `uloop simulate-mouse-input` commands +6. Take a screenshot to verify the visible result: `uloop screenshot --capture-mode rendering` +7. Report what happened ## Tool Reference @@ -42,18 +43,19 @@ uloop simulate-mouse-input --action [options] | Action | What it injects | Description | |--------|----------------|-------------| -| `Click` | Mouse.current button press → release | Inject a button click so game logic detects `wasPressedThisFrame` | +| `Click` | Mouse.current button press → release | Inject a button click so runtime logic detects `wasPressedThisFrame` | | `LongPress` | Mouse.current button press → hold → release | Hold a button for `--duration` seconds | -| `MoveDelta` | Mouse.current.delta | Inject mouse movement delta one-shot (e.g. for FPS camera look) | +| `MoveDelta` | Mouse.current.delta | Inject mouse movement delta one-shot | | `SmoothDelta` | Mouse.current.delta (per-frame) | Inject mouse delta smoothly over `--duration` seconds (human-like camera pan) | -| `Scroll` | Mouse.current.scroll | Inject scroll wheel input (e.g. for hotbar or zoom) | +| `Scroll` | Mouse.current.scroll | Inject scroll wheel input | ### Debug Break verification -- Use `UnityCliLoopDebug.Break("")` when a screenshot cannot prove that mouse input changed gameplay state, such as block hit, camera turn, or item placement. -- Put the marker at a natural state transition after the game consumed the mouse input, such as after a raycast hit, damage application, placement, or camera rotation update, not immediately after sending `simulate-mouse-input`. +- Prefer one `UnityCliLoopDebug.Break("")` marker for a representative mouse input that changes runtime state. This is useful even when final logs or screenshots later show the outcome, because it proves the transition frame and input consumption. +- Put the marker at a natural state transition after the app consumed the mouse input, such as after a command is accepted, a state mutation is committed, an evaluation step resolves, a tracked value changes, or a dependent component is updated. Do not place it immediately after sending `simulate-mouse-input`. +- Treat `simulate-mouse-input Success=true`, generic action logs, and final durable counters as useful evidence, but not as paused-frame proof. - If the response has `InterruptedByDebugBreak: true`, Unity is paused for inspection and the tool released its held input bookkeeping. If a `UnityCliLoopDebug.Break` marker caused the pause, `DebugBreakId` and `DebugBreakHitCount` identify it. Use `get-logs`, `get-hierarchy`, `find-game-objects`, or `execute-dynamic-code` before resuming. -- Use distinct marker ids for strict phases, for example `block-raycast-hit` and `block-damage-applied`. +- Use distinct marker ids for strict phases, for example `input-read`, `state-updated`, and `result-committed`. ### Global Options (optional) @@ -67,31 +69,31 @@ uloop simulate-mouse-input --action [options] | Scenario | Tool | |----------|------| | Click a Unity UI Button (IPointerClickHandler) | `simulate-mouse-ui` | -| Destroy a block in Minecraft (reads `Mouse.current.leftButton`) | `simulate-mouse-input` when the project uses the New Input System | -| Place a block with right-click | `simulate-mouse-input --button Right` when the project uses the New Input System | +| Runtime logic reads `Mouse.current.leftButton` | `simulate-mouse-input` when the project uses the New Input System | +| Runtime logic reads right-click | `simulate-mouse-input --button Right` when the project uses the New Input System | | Drag a UI slider | `simulate-mouse-ui --action Drag` | -| Look around with mouse (FPS camera) | `simulate-mouse-input --action MoveDelta` when the project uses the New Input System | -| Scroll hotbar slots | `simulate-mouse-input --action Scroll` when the project uses the New Input System | +| Runtime logic reads `Mouse.current.delta` | `simulate-mouse-input --action MoveDelta` when the project uses the New Input System | +| Runtime logic reads `Mouse.current.scroll` | `simulate-mouse-input --action Scroll` when the project uses the New Input System | ## Examples ```bash -# Left-click at screen center (for game logic) +# Left-click at screen center for runtime input uloop simulate-mouse-input --action Click --x 400 --y 300 -# Right-click at screen center (e.g. place block) +# Right-click at screen center uloop simulate-mouse-input --action Click --x 400 --y 300 --button Right -# Hold left-click for 2 seconds (e.g. mine block) +# Hold left-click for 2 seconds uloop simulate-mouse-input --action LongPress --x 400 --y 300 --duration 2.0 -# Look right (FPS camera) +# Send a one-shot mouse delta uloop simulate-mouse-input --action MoveDelta --delta-x 100 --delta-y 0 -# Scroll up (e.g. previous hotbar slot) +# Scroll up uloop simulate-mouse-input --action Scroll --scroll-y 120 -# Scroll down (e.g. next hotbar slot) +# Scroll down uloop simulate-mouse-input --action Scroll --scroll-y -120 # Smooth camera pan right over 0.5 seconds diff --git a/Packages/src/Editor/FirstPartyTools/SimulateMouseUi/Skill/SKILL.md b/Packages/src/Editor/FirstPartyTools/SimulateMouseUi/Skill/SKILL.md index 54e34d693..75794a754 100644 --- a/Packages/src/Editor/FirstPartyTools/SimulateMouseUi/Skill/SKILL.md +++ b/Packages/src/Editor/FirstPartyTools/SimulateMouseUi/Skill/SKILL.md @@ -1,7 +1,7 @@ --- name: uloop-simulate-mouse-ui toolName: simulate-mouse-ui -description: "Simulate PlayMode EventSystem UI mouse actions using screen coordinates. Use for UI clicks, long-presses, or drags from annotated screenshots." +description: "Simulate PlayMode EventSystem UI mouse actions using screen coordinates. Use for UI clicks, long-presses, or drags from annotated screenshots; pair one representative state-changing UI action with uloop-wait-for-debug-break when input delivery matters." context: fork --- @@ -14,9 +14,11 @@ Simulate mouse interaction on Unity PlayMode UI: $ARGUMENTS 1. Ensure Unity is in PlayMode (use `uloop control-play-mode --action Play` if not) 2. Get UI element info: `uloop screenshot --capture-mode rendering --annotate-elements --elements-only` 3. Use the `AnnotatedElements` array to find the target element by `Label`, `Name`, or `Path` (A=frontmost, B=next, ...). Use `Interaction` to distinguish click targets from drag/drop/text targets, then use `SimX`/`SimY` directly as `--x`/`--y` coordinates. -4. Execute the appropriate `uloop simulate-mouse-ui` command -5. Take a screenshot to verify the result: `uloop screenshot --capture-mode rendering --annotate-elements` -6. Report what happened +4. If this UI action changes runtime state, pick one representative transition for paused proof before relying on logs, screenshots, or durable state +5. For that representative transition, place and enable a `UnityCliLoopDebug.Break("")` marker, then run the UI action and inspect while Unity is paused +6. Execute any remaining `uloop simulate-mouse-ui` commands +7. Take a screenshot to verify the visible result: `uloop screenshot --capture-mode rendering --annotate-elements` +8. Report what happened ## Tool Reference @@ -75,6 +77,13 @@ uloop simulate-mouse-ui --action --x --y [options] - `--bypass-raycast` still uses coordinates for pointer event positions, but chooses the clicked, long-pressed, or dragged GameObject by `--target-path` - If `--target-path` or `--drop-target-path` matches multiple active GameObjects, the command fails instead of choosing an arbitrary duplicate +## Debug Break Verification + +- Prefer one `UnityCliLoopDebug.Break("")` marker for a representative UI action that changes runtime state. This is useful even when final logs or screenshots later show the outcome, because it proves the transition frame and input consumption. +- Put the marker at a natural transition after the app consumed the UI event, such as after a command is accepted, a state mutation is committed, a tracked value changes, a UI/domain state syncs, or a success/failure/end condition is entered. +- Treat `simulate-mouse-ui Success=true`, generic action logs, and final durable counters as useful evidence, but not as paused-frame proof. +- If a `UnityCliLoopDebug.Break` marker pauses Unity, inspect with `get-logs`, `get-hierarchy`, `find-game-objects`, or `execute-dynamic-code` before resuming. + ## Examples ```bash @@ -114,7 +123,7 @@ uloop simulate-mouse-ui --action DragEnd --x 600 --y 300 - Unity must be in **PlayMode** - Target scene must have an **EventSystem** GameObject - UI elements must have a **GraphicRaycaster** on their Canvas -- If you need gameplay mouse input rather than UI pointer events, `simulate-mouse-input` assumes the project uses the New Input System; otherwise prefer `execute-dynamic-code` +- If you need runtime mouse input rather than UI pointer events, `simulate-mouse-input` assumes the project uses the New Input System; otherwise prefer `execute-dynamic-code` ## Output From 47ed98bfea706861779db45a90776b457977ae39 Mon Sep 17 00:00:00 2001 From: hatayama Date: Wed, 10 Jun 2026 00:24:59 +0900 Subject: [PATCH 08/24] Strengthen debug-break frame proof guidance Make the wait-for-debug-break and simulate input skill descriptions explicit that state-changing PlayMode/E2E checks should pause at least one representative frame. This addresses agents treating durable state, screenshots, Time.timeScale, sleeps, or after-the-fact inspection as substitutes for breakpoint-like frame proof. --- .agents/skills/uloop-simulate-keyboard/SKILL.md | 7 ++++--- .agents/skills/uloop-simulate-mouse-input/SKILL.md | 7 ++++--- .agents/skills/uloop-simulate-mouse-ui/SKILL.md | 7 ++++--- .agents/skills/uloop-wait-for-debug-break/SKILL.md | 10 +++++----- .claude/skills/uloop-simulate-keyboard/SKILL.md | 7 ++++--- .claude/skills/uloop-simulate-mouse-input/SKILL.md | 7 ++++--- .claude/skills/uloop-simulate-mouse-ui/SKILL.md | 7 ++++--- .claude/skills/uloop-wait-for-debug-break/SKILL.md | 10 +++++----- .../src/Editor/CliOnlyTools~/PausePoint/Skill/SKILL.md | 10 +++++----- .../FirstPartyTools/SimulateKeyboard/Skill/SKILL.md | 7 ++++--- .../FirstPartyTools/SimulateMouseInput/Skill/SKILL.md | 7 ++++--- .../FirstPartyTools/SimulateMouseUi/Skill/SKILL.md | 7 ++++--- 12 files changed, 51 insertions(+), 42 deletions(-) diff --git a/.agents/skills/uloop-simulate-keyboard/SKILL.md b/.agents/skills/uloop-simulate-keyboard/SKILL.md index a3e1c69d2..3529cb432 100644 --- a/.agents/skills/uloop-simulate-keyboard/SKILL.md +++ b/.agents/skills/uloop-simulate-keyboard/SKILL.md @@ -1,7 +1,7 @@ --- name: uloop-simulate-keyboard toolName: simulate-keyboard -description: "Simulate keyboard input in PlayMode through Unity Input System. Use for key presses, holds, releases, and state-changing E2E checks; pair one representative transition with uloop-wait-for-debug-break when input delivery matters." +description: "Simulate keyboard input in PlayMode through Unity Input System. For state-changing PlayMode/E2E input, also use uloop-wait-for-debug-break on at least one representative frame; Time.timeScale, sleeps, screenshots, or after-the-fact checks are not substitutes." context: fork --- @@ -12,7 +12,7 @@ Simulate keyboard input on Unity PlayMode: $ARGUMENTS ## Workflow 1. Ensure Unity is in PlayMode (use `uloop control-play-mode --action Play` if not) -2. If this is a state-changing E2E check, pick one representative transition for paused proof before relying on logs, screenshots, or durable state +2. If this is a state-changing E2E check, pick one representative frame for paused variable/state proof before relying on logs, screenshots, or durable state 3. For that representative transition, place and enable a `UnityCliLoopDebug.Break("")` marker, then run the input and inspect while Unity is paused 4. Execute any remaining `uloop simulate-keyboard` commands 5. Take a screenshot to verify the visible result: `uloop screenshot --capture-mode rendering` @@ -47,7 +47,8 @@ Use `KeyDown` / `KeyUp` when the scenario intentionally needs a held key. ### Debug Break verification -- Prefer one `UnityCliLoopDebug.Break("")` marker for a representative keyboard input that changes runtime state. This is useful even when final logs or screenshots later show the outcome, because it proves the transition frame and input consumption. +- Use one `UnityCliLoopDebug.Break("")` marker for at least one representative keyboard input that changes runtime state. This applies even when final logs, screenshots, or durable state later show the outcome, because it pauses the exact frame where variables/state can prove input consumption. +- Use the marker before slowing time, sleeping, polling, or rewriting runtime code to work around a missed input frame. Treat those checks as supplements, not substitutes. - Put the marker at a natural state transition after the app consumed the key, such as after a command is accepted, a state mutation is committed, an evaluation step resolves, or a dependent component is updated. Do not place it immediately after sending `simulate-keyboard`. - Treat `simulate-keyboard Success=true`, generic action logs, and final durable counters as useful evidence, but not as paused-frame proof. - If the response has `InterruptedByDebugBreak: true`, Unity is paused for inspection and the tool released its held input bookkeeping. If a `UnityCliLoopDebug.Break` marker caused the pause, `DebugBreakId` and `DebugBreakHitCount` identify it. Use `get-logs`, `get-hierarchy`, `find-game-objects`, or `execute-dynamic-code` before resuming. diff --git a/.agents/skills/uloop-simulate-mouse-input/SKILL.md b/.agents/skills/uloop-simulate-mouse-input/SKILL.md index 04aa53d87..b970f76c0 100644 --- a/.agents/skills/uloop-simulate-mouse-input/SKILL.md +++ b/.agents/skills/uloop-simulate-mouse-input/SKILL.md @@ -1,7 +1,7 @@ --- name: uloop-simulate-mouse-input toolName: simulate-mouse-input -description: "Simulate Mouse.current input in PlayMode through Unity Input System. Use for runtime clicks, mouse delta, or scroll; pair one representative state-changing E2E transition with uloop-wait-for-debug-break when input delivery matters. Use simulate-mouse-ui for EventSystem UI elements." +description: "Simulate Mouse.current input in PlayMode through Unity Input System. For state-changing PlayMode/E2E mouse input, also use uloop-wait-for-debug-break on at least one representative frame; Time.timeScale, sleeps, screenshots, or after-the-fact checks are not substitutes. Use simulate-mouse-ui for UI." context: fork --- @@ -13,7 +13,7 @@ Simulate mouse input via Input System in Unity PlayMode: $ARGUMENTS 1. Ensure Unity is in PlayMode (use `uloop control-play-mode --action Play` if not) 2. For Click/LongPress: determine the target screen position (use `uloop screenshot` to find coordinates) -3. If this is a state-changing E2E check, pick one representative transition for paused proof before relying on logs, screenshots, or durable state +3. If this is a state-changing E2E check, pick one representative frame for paused variable/state proof before relying on logs, screenshots, or durable state 4. For that representative transition, place and enable a `UnityCliLoopDebug.Break("")` marker, then run the input and inspect while Unity is paused 5. Execute any remaining `uloop simulate-mouse-input` commands 6. Take a screenshot to verify the visible result: `uloop screenshot --capture-mode rendering` @@ -51,7 +51,8 @@ uloop simulate-mouse-input --action [options] ### Debug Break verification -- Prefer one `UnityCliLoopDebug.Break("")` marker for a representative mouse input that changes runtime state. This is useful even when final logs or screenshots later show the outcome, because it proves the transition frame and input consumption. +- Use one `UnityCliLoopDebug.Break("")` marker for at least one representative mouse input that changes runtime state. This applies even when final logs, screenshots, or durable state later show the outcome, because it pauses the exact frame where variables/state can prove input consumption. +- Use the marker before slowing time, sleeping, polling, or rewriting runtime code to work around a missed input frame. Treat those checks as supplements, not substitutes. - Put the marker at a natural state transition after the app consumed the mouse input, such as after a command is accepted, a state mutation is committed, an evaluation step resolves, a tracked value changes, or a dependent component is updated. Do not place it immediately after sending `simulate-mouse-input`. - Treat `simulate-mouse-input Success=true`, generic action logs, and final durable counters as useful evidence, but not as paused-frame proof. - If the response has `InterruptedByDebugBreak: true`, Unity is paused for inspection and the tool released its held input bookkeeping. If a `UnityCliLoopDebug.Break` marker caused the pause, `DebugBreakId` and `DebugBreakHitCount` identify it. Use `get-logs`, `get-hierarchy`, `find-game-objects`, or `execute-dynamic-code` before resuming. diff --git a/.agents/skills/uloop-simulate-mouse-ui/SKILL.md b/.agents/skills/uloop-simulate-mouse-ui/SKILL.md index 75794a754..094befa47 100644 --- a/.agents/skills/uloop-simulate-mouse-ui/SKILL.md +++ b/.agents/skills/uloop-simulate-mouse-ui/SKILL.md @@ -1,7 +1,7 @@ --- name: uloop-simulate-mouse-ui toolName: simulate-mouse-ui -description: "Simulate PlayMode EventSystem UI mouse actions using screen coordinates. Use for UI clicks, long-presses, or drags from annotated screenshots; pair one representative state-changing UI action with uloop-wait-for-debug-break when input delivery matters." +description: "Simulate PlayMode EventSystem UI mouse actions using screen coordinates. For state-changing PlayMode/E2E UI actions, also use uloop-wait-for-debug-break on at least one representative frame; Time.timeScale, sleeps, screenshots, or after-the-fact checks are not substitutes." context: fork --- @@ -14,7 +14,7 @@ Simulate mouse interaction on Unity PlayMode UI: $ARGUMENTS 1. Ensure Unity is in PlayMode (use `uloop control-play-mode --action Play` if not) 2. Get UI element info: `uloop screenshot --capture-mode rendering --annotate-elements --elements-only` 3. Use the `AnnotatedElements` array to find the target element by `Label`, `Name`, or `Path` (A=frontmost, B=next, ...). Use `Interaction` to distinguish click targets from drag/drop/text targets, then use `SimX`/`SimY` directly as `--x`/`--y` coordinates. -4. If this UI action changes runtime state, pick one representative transition for paused proof before relying on logs, screenshots, or durable state +4. If this UI action changes runtime state, pick one representative frame for paused variable/state proof before relying on logs, screenshots, or durable state 5. For that representative transition, place and enable a `UnityCliLoopDebug.Break("")` marker, then run the UI action and inspect while Unity is paused 6. Execute any remaining `uloop simulate-mouse-ui` commands 7. Take a screenshot to verify the visible result: `uloop screenshot --capture-mode rendering --annotate-elements` @@ -79,7 +79,8 @@ uloop simulate-mouse-ui --action --x --y [options] ## Debug Break Verification -- Prefer one `UnityCliLoopDebug.Break("")` marker for a representative UI action that changes runtime state. This is useful even when final logs or screenshots later show the outcome, because it proves the transition frame and input consumption. +- Use one `UnityCliLoopDebug.Break("")` marker for at least one representative UI action that changes runtime state. This applies even when final logs, screenshots, or durable state later show the outcome, because it pauses the exact frame where variables/state can prove input consumption. +- Use the marker before slowing time, sleeping, polling, or rewriting runtime code to work around a missed input frame. Treat those checks as supplements, not substitutes. - Put the marker at a natural transition after the app consumed the UI event, such as after a command is accepted, a state mutation is committed, a tracked value changes, a UI/domain state syncs, or a success/failure/end condition is entered. - Treat `simulate-mouse-ui Success=true`, generic action logs, and final durable counters as useful evidence, but not as paused-frame proof. - If a `UnityCliLoopDebug.Break` marker pauses Unity, inspect with `get-logs`, `get-hierarchy`, `find-game-objects`, or `execute-dynamic-code` before resuming. diff --git a/.agents/skills/uloop-wait-for-debug-break/SKILL.md b/.agents/skills/uloop-wait-for-debug-break/SKILL.md index e3b9415af..3290cb839 100644 --- a/.agents/skills/uloop-wait-for-debug-break/SKILL.md +++ b/.agents/skills/uloop-wait-for-debug-break/SKILL.md @@ -1,11 +1,11 @@ --- name: uloop-wait-for-debug-break -description: "Use this as a quick breakpoint substitute for Unity PlayMode/E2E when uloop-simulated input is expected to change runtime state. Add one marker at a representative transition, run wait-for-debug-break, and inspect paused variables/state; final logs, screenshots, or simulate-* success alone are not input-consumption proof." +description: "Use this as the standard frame proof for Unity PlayMode/E2E: pause one representative state-changing input, physics, or UI transition and inspect variables/GameObjects/state like an IDE breakpoint. Time.timeScale, sleeps, screenshots, or after-the-fact execute-dynamic-code are not substitutes." --- ## Quick Check Template -Use this small loop for one representative transition you care about: +Use this small loop for one representative frame you care about: 1. Put a marker at the natural transition point: @@ -28,9 +28,9 @@ uloop enable-debug-break --id state-transition-applied --timeout-seconds 30 ## When To Use -- Use this when a state transition is transient, frame-specific, or difficult to prove after the fact. -- Use this during uloop interaction or endurance validation when simulated input drives a core runtime transition, even if durable state, logs, or screenshots can later confirm the final result. -- A useful default is to check one representative input-driven transition per E2E pass, then use logs, screenshots, and durable state for the rest. +- Use this as the standard frame proof for state-changing PlayMode/E2E simulated input, physics, or UI transitions. +- Pause at least one representative transition per E2E pass, even if durable state, logs, or screenshots can later confirm the final result. +- Use this before reaching for `Time.timeScale`, sleeps, repeated polling, or after-the-fact `execute-dynamic-code`; those checks can supplement the paused-frame proof, but they are not substitutes. - Good pause points include after input is consumed, a command is accepted, a state mutation is committed, an evaluation step resolves, a tracked value changes, a UI/domain state syncs, or a success/failure/end condition is entered. - Treat the pause like a lightweight breakpoint for one important transition: combine nearby debug logs with paused-frame inspection to confirm the variables and component state at that point. - Do not treat `simulate-* Success=true`, generic action logs, sleeps/retries, testing-only counters, or `Time.timeScale` changes as paused-frame proof. diff --git a/.claude/skills/uloop-simulate-keyboard/SKILL.md b/.claude/skills/uloop-simulate-keyboard/SKILL.md index a3e1c69d2..3529cb432 100644 --- a/.claude/skills/uloop-simulate-keyboard/SKILL.md +++ b/.claude/skills/uloop-simulate-keyboard/SKILL.md @@ -1,7 +1,7 @@ --- name: uloop-simulate-keyboard toolName: simulate-keyboard -description: "Simulate keyboard input in PlayMode through Unity Input System. Use for key presses, holds, releases, and state-changing E2E checks; pair one representative transition with uloop-wait-for-debug-break when input delivery matters." +description: "Simulate keyboard input in PlayMode through Unity Input System. For state-changing PlayMode/E2E input, also use uloop-wait-for-debug-break on at least one representative frame; Time.timeScale, sleeps, screenshots, or after-the-fact checks are not substitutes." context: fork --- @@ -12,7 +12,7 @@ Simulate keyboard input on Unity PlayMode: $ARGUMENTS ## Workflow 1. Ensure Unity is in PlayMode (use `uloop control-play-mode --action Play` if not) -2. If this is a state-changing E2E check, pick one representative transition for paused proof before relying on logs, screenshots, or durable state +2. If this is a state-changing E2E check, pick one representative frame for paused variable/state proof before relying on logs, screenshots, or durable state 3. For that representative transition, place and enable a `UnityCliLoopDebug.Break("")` marker, then run the input and inspect while Unity is paused 4. Execute any remaining `uloop simulate-keyboard` commands 5. Take a screenshot to verify the visible result: `uloop screenshot --capture-mode rendering` @@ -47,7 +47,8 @@ Use `KeyDown` / `KeyUp` when the scenario intentionally needs a held key. ### Debug Break verification -- Prefer one `UnityCliLoopDebug.Break("")` marker for a representative keyboard input that changes runtime state. This is useful even when final logs or screenshots later show the outcome, because it proves the transition frame and input consumption. +- Use one `UnityCliLoopDebug.Break("")` marker for at least one representative keyboard input that changes runtime state. This applies even when final logs, screenshots, or durable state later show the outcome, because it pauses the exact frame where variables/state can prove input consumption. +- Use the marker before slowing time, sleeping, polling, or rewriting runtime code to work around a missed input frame. Treat those checks as supplements, not substitutes. - Put the marker at a natural state transition after the app consumed the key, such as after a command is accepted, a state mutation is committed, an evaluation step resolves, or a dependent component is updated. Do not place it immediately after sending `simulate-keyboard`. - Treat `simulate-keyboard Success=true`, generic action logs, and final durable counters as useful evidence, but not as paused-frame proof. - If the response has `InterruptedByDebugBreak: true`, Unity is paused for inspection and the tool released its held input bookkeeping. If a `UnityCliLoopDebug.Break` marker caused the pause, `DebugBreakId` and `DebugBreakHitCount` identify it. Use `get-logs`, `get-hierarchy`, `find-game-objects`, or `execute-dynamic-code` before resuming. diff --git a/.claude/skills/uloop-simulate-mouse-input/SKILL.md b/.claude/skills/uloop-simulate-mouse-input/SKILL.md index 04aa53d87..b970f76c0 100644 --- a/.claude/skills/uloop-simulate-mouse-input/SKILL.md +++ b/.claude/skills/uloop-simulate-mouse-input/SKILL.md @@ -1,7 +1,7 @@ --- name: uloop-simulate-mouse-input toolName: simulate-mouse-input -description: "Simulate Mouse.current input in PlayMode through Unity Input System. Use for runtime clicks, mouse delta, or scroll; pair one representative state-changing E2E transition with uloop-wait-for-debug-break when input delivery matters. Use simulate-mouse-ui for EventSystem UI elements." +description: "Simulate Mouse.current input in PlayMode through Unity Input System. For state-changing PlayMode/E2E mouse input, also use uloop-wait-for-debug-break on at least one representative frame; Time.timeScale, sleeps, screenshots, or after-the-fact checks are not substitutes. Use simulate-mouse-ui for UI." context: fork --- @@ -13,7 +13,7 @@ Simulate mouse input via Input System in Unity PlayMode: $ARGUMENTS 1. Ensure Unity is in PlayMode (use `uloop control-play-mode --action Play` if not) 2. For Click/LongPress: determine the target screen position (use `uloop screenshot` to find coordinates) -3. If this is a state-changing E2E check, pick one representative transition for paused proof before relying on logs, screenshots, or durable state +3. If this is a state-changing E2E check, pick one representative frame for paused variable/state proof before relying on logs, screenshots, or durable state 4. For that representative transition, place and enable a `UnityCliLoopDebug.Break("")` marker, then run the input and inspect while Unity is paused 5. Execute any remaining `uloop simulate-mouse-input` commands 6. Take a screenshot to verify the visible result: `uloop screenshot --capture-mode rendering` @@ -51,7 +51,8 @@ uloop simulate-mouse-input --action [options] ### Debug Break verification -- Prefer one `UnityCliLoopDebug.Break("")` marker for a representative mouse input that changes runtime state. This is useful even when final logs or screenshots later show the outcome, because it proves the transition frame and input consumption. +- Use one `UnityCliLoopDebug.Break("")` marker for at least one representative mouse input that changes runtime state. This applies even when final logs, screenshots, or durable state later show the outcome, because it pauses the exact frame where variables/state can prove input consumption. +- Use the marker before slowing time, sleeping, polling, or rewriting runtime code to work around a missed input frame. Treat those checks as supplements, not substitutes. - Put the marker at a natural state transition after the app consumed the mouse input, such as after a command is accepted, a state mutation is committed, an evaluation step resolves, a tracked value changes, or a dependent component is updated. Do not place it immediately after sending `simulate-mouse-input`. - Treat `simulate-mouse-input Success=true`, generic action logs, and final durable counters as useful evidence, but not as paused-frame proof. - If the response has `InterruptedByDebugBreak: true`, Unity is paused for inspection and the tool released its held input bookkeeping. If a `UnityCliLoopDebug.Break` marker caused the pause, `DebugBreakId` and `DebugBreakHitCount` identify it. Use `get-logs`, `get-hierarchy`, `find-game-objects`, or `execute-dynamic-code` before resuming. diff --git a/.claude/skills/uloop-simulate-mouse-ui/SKILL.md b/.claude/skills/uloop-simulate-mouse-ui/SKILL.md index 75794a754..094befa47 100644 --- a/.claude/skills/uloop-simulate-mouse-ui/SKILL.md +++ b/.claude/skills/uloop-simulate-mouse-ui/SKILL.md @@ -1,7 +1,7 @@ --- name: uloop-simulate-mouse-ui toolName: simulate-mouse-ui -description: "Simulate PlayMode EventSystem UI mouse actions using screen coordinates. Use for UI clicks, long-presses, or drags from annotated screenshots; pair one representative state-changing UI action with uloop-wait-for-debug-break when input delivery matters." +description: "Simulate PlayMode EventSystem UI mouse actions using screen coordinates. For state-changing PlayMode/E2E UI actions, also use uloop-wait-for-debug-break on at least one representative frame; Time.timeScale, sleeps, screenshots, or after-the-fact checks are not substitutes." context: fork --- @@ -14,7 +14,7 @@ Simulate mouse interaction on Unity PlayMode UI: $ARGUMENTS 1. Ensure Unity is in PlayMode (use `uloop control-play-mode --action Play` if not) 2. Get UI element info: `uloop screenshot --capture-mode rendering --annotate-elements --elements-only` 3. Use the `AnnotatedElements` array to find the target element by `Label`, `Name`, or `Path` (A=frontmost, B=next, ...). Use `Interaction` to distinguish click targets from drag/drop/text targets, then use `SimX`/`SimY` directly as `--x`/`--y` coordinates. -4. If this UI action changes runtime state, pick one representative transition for paused proof before relying on logs, screenshots, or durable state +4. If this UI action changes runtime state, pick one representative frame for paused variable/state proof before relying on logs, screenshots, or durable state 5. For that representative transition, place and enable a `UnityCliLoopDebug.Break("")` marker, then run the UI action and inspect while Unity is paused 6. Execute any remaining `uloop simulate-mouse-ui` commands 7. Take a screenshot to verify the visible result: `uloop screenshot --capture-mode rendering --annotate-elements` @@ -79,7 +79,8 @@ uloop simulate-mouse-ui --action --x --y [options] ## Debug Break Verification -- Prefer one `UnityCliLoopDebug.Break("")` marker for a representative UI action that changes runtime state. This is useful even when final logs or screenshots later show the outcome, because it proves the transition frame and input consumption. +- Use one `UnityCliLoopDebug.Break("")` marker for at least one representative UI action that changes runtime state. This applies even when final logs, screenshots, or durable state later show the outcome, because it pauses the exact frame where variables/state can prove input consumption. +- Use the marker before slowing time, sleeping, polling, or rewriting runtime code to work around a missed input frame. Treat those checks as supplements, not substitutes. - Put the marker at a natural transition after the app consumed the UI event, such as after a command is accepted, a state mutation is committed, a tracked value changes, a UI/domain state syncs, or a success/failure/end condition is entered. - Treat `simulate-mouse-ui Success=true`, generic action logs, and final durable counters as useful evidence, but not as paused-frame proof. - If a `UnityCliLoopDebug.Break` marker pauses Unity, inspect with `get-logs`, `get-hierarchy`, `find-game-objects`, or `execute-dynamic-code` before resuming. diff --git a/.claude/skills/uloop-wait-for-debug-break/SKILL.md b/.claude/skills/uloop-wait-for-debug-break/SKILL.md index e3b9415af..3290cb839 100644 --- a/.claude/skills/uloop-wait-for-debug-break/SKILL.md +++ b/.claude/skills/uloop-wait-for-debug-break/SKILL.md @@ -1,11 +1,11 @@ --- name: uloop-wait-for-debug-break -description: "Use this as a quick breakpoint substitute for Unity PlayMode/E2E when uloop-simulated input is expected to change runtime state. Add one marker at a representative transition, run wait-for-debug-break, and inspect paused variables/state; final logs, screenshots, or simulate-* success alone are not input-consumption proof." +description: "Use this as the standard frame proof for Unity PlayMode/E2E: pause one representative state-changing input, physics, or UI transition and inspect variables/GameObjects/state like an IDE breakpoint. Time.timeScale, sleeps, screenshots, or after-the-fact execute-dynamic-code are not substitutes." --- ## Quick Check Template -Use this small loop for one representative transition you care about: +Use this small loop for one representative frame you care about: 1. Put a marker at the natural transition point: @@ -28,9 +28,9 @@ uloop enable-debug-break --id state-transition-applied --timeout-seconds 30 ## When To Use -- Use this when a state transition is transient, frame-specific, or difficult to prove after the fact. -- Use this during uloop interaction or endurance validation when simulated input drives a core runtime transition, even if durable state, logs, or screenshots can later confirm the final result. -- A useful default is to check one representative input-driven transition per E2E pass, then use logs, screenshots, and durable state for the rest. +- Use this as the standard frame proof for state-changing PlayMode/E2E simulated input, physics, or UI transitions. +- Pause at least one representative transition per E2E pass, even if durable state, logs, or screenshots can later confirm the final result. +- Use this before reaching for `Time.timeScale`, sleeps, repeated polling, or after-the-fact `execute-dynamic-code`; those checks can supplement the paused-frame proof, but they are not substitutes. - Good pause points include after input is consumed, a command is accepted, a state mutation is committed, an evaluation step resolves, a tracked value changes, a UI/domain state syncs, or a success/failure/end condition is entered. - Treat the pause like a lightweight breakpoint for one important transition: combine nearby debug logs with paused-frame inspection to confirm the variables and component state at that point. - Do not treat `simulate-* Success=true`, generic action logs, sleeps/retries, testing-only counters, or `Time.timeScale` changes as paused-frame proof. diff --git a/Packages/src/Editor/CliOnlyTools~/PausePoint/Skill/SKILL.md b/Packages/src/Editor/CliOnlyTools~/PausePoint/Skill/SKILL.md index e3b9415af..3290cb839 100644 --- a/Packages/src/Editor/CliOnlyTools~/PausePoint/Skill/SKILL.md +++ b/Packages/src/Editor/CliOnlyTools~/PausePoint/Skill/SKILL.md @@ -1,11 +1,11 @@ --- name: uloop-wait-for-debug-break -description: "Use this as a quick breakpoint substitute for Unity PlayMode/E2E when uloop-simulated input is expected to change runtime state. Add one marker at a representative transition, run wait-for-debug-break, and inspect paused variables/state; final logs, screenshots, or simulate-* success alone are not input-consumption proof." +description: "Use this as the standard frame proof for Unity PlayMode/E2E: pause one representative state-changing input, physics, or UI transition and inspect variables/GameObjects/state like an IDE breakpoint. Time.timeScale, sleeps, screenshots, or after-the-fact execute-dynamic-code are not substitutes." --- ## Quick Check Template -Use this small loop for one representative transition you care about: +Use this small loop for one representative frame you care about: 1. Put a marker at the natural transition point: @@ -28,9 +28,9 @@ uloop enable-debug-break --id state-transition-applied --timeout-seconds 30 ## When To Use -- Use this when a state transition is transient, frame-specific, or difficult to prove after the fact. -- Use this during uloop interaction or endurance validation when simulated input drives a core runtime transition, even if durable state, logs, or screenshots can later confirm the final result. -- A useful default is to check one representative input-driven transition per E2E pass, then use logs, screenshots, and durable state for the rest. +- Use this as the standard frame proof for state-changing PlayMode/E2E simulated input, physics, or UI transitions. +- Pause at least one representative transition per E2E pass, even if durable state, logs, or screenshots can later confirm the final result. +- Use this before reaching for `Time.timeScale`, sleeps, repeated polling, or after-the-fact `execute-dynamic-code`; those checks can supplement the paused-frame proof, but they are not substitutes. - Good pause points include after input is consumed, a command is accepted, a state mutation is committed, an evaluation step resolves, a tracked value changes, a UI/domain state syncs, or a success/failure/end condition is entered. - Treat the pause like a lightweight breakpoint for one important transition: combine nearby debug logs with paused-frame inspection to confirm the variables and component state at that point. - Do not treat `simulate-* Success=true`, generic action logs, sleeps/retries, testing-only counters, or `Time.timeScale` changes as paused-frame proof. diff --git a/Packages/src/Editor/FirstPartyTools/SimulateKeyboard/Skill/SKILL.md b/Packages/src/Editor/FirstPartyTools/SimulateKeyboard/Skill/SKILL.md index a3e1c69d2..3529cb432 100644 --- a/Packages/src/Editor/FirstPartyTools/SimulateKeyboard/Skill/SKILL.md +++ b/Packages/src/Editor/FirstPartyTools/SimulateKeyboard/Skill/SKILL.md @@ -1,7 +1,7 @@ --- name: uloop-simulate-keyboard toolName: simulate-keyboard -description: "Simulate keyboard input in PlayMode through Unity Input System. Use for key presses, holds, releases, and state-changing E2E checks; pair one representative transition with uloop-wait-for-debug-break when input delivery matters." +description: "Simulate keyboard input in PlayMode through Unity Input System. For state-changing PlayMode/E2E input, also use uloop-wait-for-debug-break on at least one representative frame; Time.timeScale, sleeps, screenshots, or after-the-fact checks are not substitutes." context: fork --- @@ -12,7 +12,7 @@ Simulate keyboard input on Unity PlayMode: $ARGUMENTS ## Workflow 1. Ensure Unity is in PlayMode (use `uloop control-play-mode --action Play` if not) -2. If this is a state-changing E2E check, pick one representative transition for paused proof before relying on logs, screenshots, or durable state +2. If this is a state-changing E2E check, pick one representative frame for paused variable/state proof before relying on logs, screenshots, or durable state 3. For that representative transition, place and enable a `UnityCliLoopDebug.Break("")` marker, then run the input and inspect while Unity is paused 4. Execute any remaining `uloop simulate-keyboard` commands 5. Take a screenshot to verify the visible result: `uloop screenshot --capture-mode rendering` @@ -47,7 +47,8 @@ Use `KeyDown` / `KeyUp` when the scenario intentionally needs a held key. ### Debug Break verification -- Prefer one `UnityCliLoopDebug.Break("")` marker for a representative keyboard input that changes runtime state. This is useful even when final logs or screenshots later show the outcome, because it proves the transition frame and input consumption. +- Use one `UnityCliLoopDebug.Break("")` marker for at least one representative keyboard input that changes runtime state. This applies even when final logs, screenshots, or durable state later show the outcome, because it pauses the exact frame where variables/state can prove input consumption. +- Use the marker before slowing time, sleeping, polling, or rewriting runtime code to work around a missed input frame. Treat those checks as supplements, not substitutes. - Put the marker at a natural state transition after the app consumed the key, such as after a command is accepted, a state mutation is committed, an evaluation step resolves, or a dependent component is updated. Do not place it immediately after sending `simulate-keyboard`. - Treat `simulate-keyboard Success=true`, generic action logs, and final durable counters as useful evidence, but not as paused-frame proof. - If the response has `InterruptedByDebugBreak: true`, Unity is paused for inspection and the tool released its held input bookkeeping. If a `UnityCliLoopDebug.Break` marker caused the pause, `DebugBreakId` and `DebugBreakHitCount` identify it. Use `get-logs`, `get-hierarchy`, `find-game-objects`, or `execute-dynamic-code` before resuming. diff --git a/Packages/src/Editor/FirstPartyTools/SimulateMouseInput/Skill/SKILL.md b/Packages/src/Editor/FirstPartyTools/SimulateMouseInput/Skill/SKILL.md index 04aa53d87..b970f76c0 100644 --- a/Packages/src/Editor/FirstPartyTools/SimulateMouseInput/Skill/SKILL.md +++ b/Packages/src/Editor/FirstPartyTools/SimulateMouseInput/Skill/SKILL.md @@ -1,7 +1,7 @@ --- name: uloop-simulate-mouse-input toolName: simulate-mouse-input -description: "Simulate Mouse.current input in PlayMode through Unity Input System. Use for runtime clicks, mouse delta, or scroll; pair one representative state-changing E2E transition with uloop-wait-for-debug-break when input delivery matters. Use simulate-mouse-ui for EventSystem UI elements." +description: "Simulate Mouse.current input in PlayMode through Unity Input System. For state-changing PlayMode/E2E mouse input, also use uloop-wait-for-debug-break on at least one representative frame; Time.timeScale, sleeps, screenshots, or after-the-fact checks are not substitutes. Use simulate-mouse-ui for UI." context: fork --- @@ -13,7 +13,7 @@ Simulate mouse input via Input System in Unity PlayMode: $ARGUMENTS 1. Ensure Unity is in PlayMode (use `uloop control-play-mode --action Play` if not) 2. For Click/LongPress: determine the target screen position (use `uloop screenshot` to find coordinates) -3. If this is a state-changing E2E check, pick one representative transition for paused proof before relying on logs, screenshots, or durable state +3. If this is a state-changing E2E check, pick one representative frame for paused variable/state proof before relying on logs, screenshots, or durable state 4. For that representative transition, place and enable a `UnityCliLoopDebug.Break("")` marker, then run the input and inspect while Unity is paused 5. Execute any remaining `uloop simulate-mouse-input` commands 6. Take a screenshot to verify the visible result: `uloop screenshot --capture-mode rendering` @@ -51,7 +51,8 @@ uloop simulate-mouse-input --action [options] ### Debug Break verification -- Prefer one `UnityCliLoopDebug.Break("")` marker for a representative mouse input that changes runtime state. This is useful even when final logs or screenshots later show the outcome, because it proves the transition frame and input consumption. +- Use one `UnityCliLoopDebug.Break("")` marker for at least one representative mouse input that changes runtime state. This applies even when final logs, screenshots, or durable state later show the outcome, because it pauses the exact frame where variables/state can prove input consumption. +- Use the marker before slowing time, sleeping, polling, or rewriting runtime code to work around a missed input frame. Treat those checks as supplements, not substitutes. - Put the marker at a natural state transition after the app consumed the mouse input, such as after a command is accepted, a state mutation is committed, an evaluation step resolves, a tracked value changes, or a dependent component is updated. Do not place it immediately after sending `simulate-mouse-input`. - Treat `simulate-mouse-input Success=true`, generic action logs, and final durable counters as useful evidence, but not as paused-frame proof. - If the response has `InterruptedByDebugBreak: true`, Unity is paused for inspection and the tool released its held input bookkeeping. If a `UnityCliLoopDebug.Break` marker caused the pause, `DebugBreakId` and `DebugBreakHitCount` identify it. Use `get-logs`, `get-hierarchy`, `find-game-objects`, or `execute-dynamic-code` before resuming. diff --git a/Packages/src/Editor/FirstPartyTools/SimulateMouseUi/Skill/SKILL.md b/Packages/src/Editor/FirstPartyTools/SimulateMouseUi/Skill/SKILL.md index 75794a754..094befa47 100644 --- a/Packages/src/Editor/FirstPartyTools/SimulateMouseUi/Skill/SKILL.md +++ b/Packages/src/Editor/FirstPartyTools/SimulateMouseUi/Skill/SKILL.md @@ -1,7 +1,7 @@ --- name: uloop-simulate-mouse-ui toolName: simulate-mouse-ui -description: "Simulate PlayMode EventSystem UI mouse actions using screen coordinates. Use for UI clicks, long-presses, or drags from annotated screenshots; pair one representative state-changing UI action with uloop-wait-for-debug-break when input delivery matters." +description: "Simulate PlayMode EventSystem UI mouse actions using screen coordinates. For state-changing PlayMode/E2E UI actions, also use uloop-wait-for-debug-break on at least one representative frame; Time.timeScale, sleeps, screenshots, or after-the-fact checks are not substitutes." context: fork --- @@ -14,7 +14,7 @@ Simulate mouse interaction on Unity PlayMode UI: $ARGUMENTS 1. Ensure Unity is in PlayMode (use `uloop control-play-mode --action Play` if not) 2. Get UI element info: `uloop screenshot --capture-mode rendering --annotate-elements --elements-only` 3. Use the `AnnotatedElements` array to find the target element by `Label`, `Name`, or `Path` (A=frontmost, B=next, ...). Use `Interaction` to distinguish click targets from drag/drop/text targets, then use `SimX`/`SimY` directly as `--x`/`--y` coordinates. -4. If this UI action changes runtime state, pick one representative transition for paused proof before relying on logs, screenshots, or durable state +4. If this UI action changes runtime state, pick one representative frame for paused variable/state proof before relying on logs, screenshots, or durable state 5. For that representative transition, place and enable a `UnityCliLoopDebug.Break("")` marker, then run the UI action and inspect while Unity is paused 6. Execute any remaining `uloop simulate-mouse-ui` commands 7. Take a screenshot to verify the visible result: `uloop screenshot --capture-mode rendering --annotate-elements` @@ -79,7 +79,8 @@ uloop simulate-mouse-ui --action --x --y [options] ## Debug Break Verification -- Prefer one `UnityCliLoopDebug.Break("")` marker for a representative UI action that changes runtime state. This is useful even when final logs or screenshots later show the outcome, because it proves the transition frame and input consumption. +- Use one `UnityCliLoopDebug.Break("")` marker for at least one representative UI action that changes runtime state. This applies even when final logs, screenshots, or durable state later show the outcome, because it pauses the exact frame where variables/state can prove input consumption. +- Use the marker before slowing time, sleeping, polling, or rewriting runtime code to work around a missed input frame. Treat those checks as supplements, not substitutes. - Put the marker at a natural transition after the app consumed the UI event, such as after a command is accepted, a state mutation is committed, a tracked value changes, a UI/domain state syncs, or a success/failure/end condition is entered. - Treat `simulate-mouse-ui Success=true`, generic action logs, and final durable counters as useful evidence, but not as paused-frame proof. - If a `UnityCliLoopDebug.Break` marker pauses Unity, inspect with `get-logs`, `get-hierarchy`, `find-game-objects`, or `execute-dynamic-code` before resuming. From 0f9349897e4c7ac675d2248b7ab4fff5bf517ea4 Mon Sep 17 00:00:00 2001 From: hatayama Date: Wed, 10 Jun 2026 01:55:58 +0900 Subject: [PATCH 09/24] Guide debug-break checks to log frame-local values Clarify that execute-dynamic-code cannot inspect method locals from an already-running frame, and point agents to add focused Debug.Log entries immediately before debug-break markers. Update generated skill copies so input simulation, log inspection, dynamic-code inspection, and wait-for-debug-break guidance all reinforce the paused-frame workflow. --- .agents/skills/uloop-execute-dynamic-code/SKILL.md | 4 +++- .agents/skills/uloop-get-logs/SKILL.md | 4 +++- .agents/skills/uloop-simulate-keyboard/SKILL.md | 3 ++- .agents/skills/uloop-simulate-mouse-input/SKILL.md | 3 ++- .agents/skills/uloop-simulate-mouse-ui/SKILL.md | 3 ++- .agents/skills/uloop-wait-for-debug-break/SKILL.md | 9 ++++++--- .claude/skills/uloop-execute-dynamic-code/SKILL.md | 4 +++- .claude/skills/uloop-get-logs/SKILL.md | 4 +++- .claude/skills/uloop-simulate-keyboard/SKILL.md | 3 ++- .claude/skills/uloop-simulate-mouse-input/SKILL.md | 3 ++- .claude/skills/uloop-simulate-mouse-ui/SKILL.md | 3 ++- .claude/skills/uloop-wait-for-debug-break/SKILL.md | 9 ++++++--- .../src/Editor/CliOnlyTools~/PausePoint/Skill/SKILL.md | 9 ++++++--- .../FirstPartyTools/ExecuteDynamicCode/Skill/SKILL.md | 4 +++- .../src/Editor/FirstPartyTools/GetLogs/Skill/SKILL.md | 4 +++- .../FirstPartyTools/SimulateKeyboard/Skill/SKILL.md | 3 ++- .../FirstPartyTools/SimulateMouseInput/Skill/SKILL.md | 3 ++- .../FirstPartyTools/SimulateMouseUi/Skill/SKILL.md | 3 ++- 18 files changed, 54 insertions(+), 24 deletions(-) diff --git a/.agents/skills/uloop-execute-dynamic-code/SKILL.md b/.agents/skills/uloop-execute-dynamic-code/SKILL.md index d29fcdc9c..b494abc5d 100644 --- a/.agents/skills/uloop-execute-dynamic-code/SKILL.md +++ b/.agents/skills/uloop-execute-dynamic-code/SKILL.md @@ -1,7 +1,7 @@ --- name: uloop-execute-dynamic-code toolName: execute-dynamic-code -description: "Execute C# with Unity APIs when existing uloop tools cannot inspect or edit enough. Use for scene, prefab, SerializedObject, AssetDatabase refresh/.meta generation, menu, or PlayMode automation." +description: "Execute C# with Unity APIs when existing uloop tools cannot inspect or edit enough. Use for reachable scene/component state, scene/prefab/menu automation, and PlayMode checks. It cannot see method locals from an already-running frame; for those, add focused Debug.Log before a debug-break marker and read get-logs while paused." context: fork --- @@ -11,6 +11,8 @@ Execute the following request using `uloop execute-dynamic-code`: $ARGUMENTS For basic selected GameObject discovery or property inspection, use `find-game-objects --search-mode Selected` before this tool. Use this tool after the built-in inspection tools are not enough or when you need to modify Unity state. +This tool can inspect reachable Unity state, such as GameObjects, components, public properties, static values, and method results. It cannot directly read local variables or intermediate calculations inside an already-running method. When those values matter, add a focused `Debug.Log` immediately before `UnityCliLoopDebug.Break("")`, then read `get-logs` while Unity is paused. + ## Workflow 1. Read the relevant reference file(s) from the Code Examples section below diff --git a/.agents/skills/uloop-get-logs/SKILL.md b/.agents/skills/uloop-get-logs/SKILL.md index a74e55532..078262e1f 100644 --- a/.agents/skills/uloop-get-logs/SKILL.md +++ b/.agents/skills/uloop-get-logs/SKILL.md @@ -1,13 +1,15 @@ --- name: uloop-get-logs toolName: get-logs -description: "Read current Unity Console entries from a running Editor. Use during bug investigation after compile, tests, PlayMode, or dynamic code to inspect logs, warnings, errors, and stack traces." +description: "Read current Unity Console entries from a running Editor. Use during bug investigation after compile, tests, PlayMode, dynamic code, or a debug-break pause; especially read focused Debug.Log output for local/intermediate values that execute-dynamic-code cannot inspect." --- # uloop get-logs Retrieve logs from Unity Console. +When a debug-break marker pauses Unity and the value you need is a method local, intermediate calculation, or branch reason, read the focused `Debug.Log` entry added immediately before the marker. Use `--search-text ` when the Console has unrelated entries. + ## Usage ```bash diff --git a/.agents/skills/uloop-simulate-keyboard/SKILL.md b/.agents/skills/uloop-simulate-keyboard/SKILL.md index 3529cb432..57a2d2f51 100644 --- a/.agents/skills/uloop-simulate-keyboard/SKILL.md +++ b/.agents/skills/uloop-simulate-keyboard/SKILL.md @@ -1,7 +1,7 @@ --- name: uloop-simulate-keyboard toolName: simulate-keyboard -description: "Simulate keyboard input in PlayMode through Unity Input System. For state-changing PlayMode/E2E input, also use uloop-wait-for-debug-break on at least one representative frame; Time.timeScale, sleeps, screenshots, or after-the-fact checks are not substitutes." +description: "Simulate keyboard input in PlayMode through Unity Input System. For state-changing PlayMode/E2E input, also use uloop-wait-for-debug-break on at least one representative frame; if local values are hard to inspect later, add focused Debug.Log next to the marker." context: fork --- @@ -49,6 +49,7 @@ Use `KeyDown` / `KeyUp` when the scenario intentionally needs a held key. - Use one `UnityCliLoopDebug.Break("")` marker for at least one representative keyboard input that changes runtime state. This applies even when final logs, screenshots, or durable state later show the outcome, because it pauses the exact frame where variables/state can prove input consumption. - Use the marker before slowing time, sleeping, polling, or rewriting runtime code to work around a missed input frame. Treat those checks as supplements, not substitutes. +- If the key handler has local variables, intermediate calculations, or branch reasons that `execute-dynamic-code` cannot inspect after the fact, log just those values with `Debug.Log` immediately before the marker and read them with `get-logs` while Unity is paused. - Put the marker at a natural state transition after the app consumed the key, such as after a command is accepted, a state mutation is committed, an evaluation step resolves, or a dependent component is updated. Do not place it immediately after sending `simulate-keyboard`. - Treat `simulate-keyboard Success=true`, generic action logs, and final durable counters as useful evidence, but not as paused-frame proof. - If the response has `InterruptedByDebugBreak: true`, Unity is paused for inspection and the tool released its held input bookkeeping. If a `UnityCliLoopDebug.Break` marker caused the pause, `DebugBreakId` and `DebugBreakHitCount` identify it. Use `get-logs`, `get-hierarchy`, `find-game-objects`, or `execute-dynamic-code` before resuming. diff --git a/.agents/skills/uloop-simulate-mouse-input/SKILL.md b/.agents/skills/uloop-simulate-mouse-input/SKILL.md index b970f76c0..d1ba1acab 100644 --- a/.agents/skills/uloop-simulate-mouse-input/SKILL.md +++ b/.agents/skills/uloop-simulate-mouse-input/SKILL.md @@ -1,7 +1,7 @@ --- name: uloop-simulate-mouse-input toolName: simulate-mouse-input -description: "Simulate Mouse.current input in PlayMode through Unity Input System. For state-changing PlayMode/E2E mouse input, also use uloop-wait-for-debug-break on at least one representative frame; Time.timeScale, sleeps, screenshots, or after-the-fact checks are not substitutes. Use simulate-mouse-ui for UI." +description: "Simulate Mouse.current input in PlayMode through Unity Input System. For state-changing PlayMode/E2E mouse input, also use uloop-wait-for-debug-break on at least one representative frame; if local values are hard to inspect later, add focused Debug.Log next to the marker. Use simulate-mouse-ui for UI." context: fork --- @@ -53,6 +53,7 @@ uloop simulate-mouse-input --action [options] - Use one `UnityCliLoopDebug.Break("")` marker for at least one representative mouse input that changes runtime state. This applies even when final logs, screenshots, or durable state later show the outcome, because it pauses the exact frame where variables/state can prove input consumption. - Use the marker before slowing time, sleeping, polling, or rewriting runtime code to work around a missed input frame. Treat those checks as supplements, not substitutes. +- If the mouse handler has local variables, intermediate calculations, or branch reasons that `execute-dynamic-code` cannot inspect after the fact, log just those values with `Debug.Log` immediately before the marker and read them with `get-logs` while Unity is paused. - Put the marker at a natural state transition after the app consumed the mouse input, such as after a command is accepted, a state mutation is committed, an evaluation step resolves, a tracked value changes, or a dependent component is updated. Do not place it immediately after sending `simulate-mouse-input`. - Treat `simulate-mouse-input Success=true`, generic action logs, and final durable counters as useful evidence, but not as paused-frame proof. - If the response has `InterruptedByDebugBreak: true`, Unity is paused for inspection and the tool released its held input bookkeeping. If a `UnityCliLoopDebug.Break` marker caused the pause, `DebugBreakId` and `DebugBreakHitCount` identify it. Use `get-logs`, `get-hierarchy`, `find-game-objects`, or `execute-dynamic-code` before resuming. diff --git a/.agents/skills/uloop-simulate-mouse-ui/SKILL.md b/.agents/skills/uloop-simulate-mouse-ui/SKILL.md index 094befa47..fe476ff57 100644 --- a/.agents/skills/uloop-simulate-mouse-ui/SKILL.md +++ b/.agents/skills/uloop-simulate-mouse-ui/SKILL.md @@ -1,7 +1,7 @@ --- name: uloop-simulate-mouse-ui toolName: simulate-mouse-ui -description: "Simulate PlayMode EventSystem UI mouse actions using screen coordinates. For state-changing PlayMode/E2E UI actions, also use uloop-wait-for-debug-break on at least one representative frame; Time.timeScale, sleeps, screenshots, or after-the-fact checks are not substitutes." +description: "Simulate PlayMode EventSystem UI mouse actions using screen coordinates. For state-changing PlayMode/E2E UI actions, also use uloop-wait-for-debug-break on at least one representative frame; if local values are hard to inspect later, add focused Debug.Log next to the marker." context: fork --- @@ -81,6 +81,7 @@ uloop simulate-mouse-ui --action --x --y [options] - Use one `UnityCliLoopDebug.Break("")` marker for at least one representative UI action that changes runtime state. This applies even when final logs, screenshots, or durable state later show the outcome, because it pauses the exact frame where variables/state can prove input consumption. - Use the marker before slowing time, sleeping, polling, or rewriting runtime code to work around a missed input frame. Treat those checks as supplements, not substitutes. +- If the UI handler has local variables, intermediate calculations, or branch reasons that `execute-dynamic-code` cannot inspect after the fact, log just those values with `Debug.Log` immediately before the marker and read them with `get-logs` while Unity is paused. - Put the marker at a natural transition after the app consumed the UI event, such as after a command is accepted, a state mutation is committed, a tracked value changes, a UI/domain state syncs, or a success/failure/end condition is entered. - Treat `simulate-mouse-ui Success=true`, generic action logs, and final durable counters as useful evidence, but not as paused-frame proof. - If a `UnityCliLoopDebug.Break` marker pauses Unity, inspect with `get-logs`, `get-hierarchy`, `find-game-objects`, or `execute-dynamic-code` before resuming. diff --git a/.agents/skills/uloop-wait-for-debug-break/SKILL.md b/.agents/skills/uloop-wait-for-debug-break/SKILL.md index 3290cb839..97aab8cf5 100644 --- a/.agents/skills/uloop-wait-for-debug-break/SKILL.md +++ b/.agents/skills/uloop-wait-for-debug-break/SKILL.md @@ -1,17 +1,19 @@ --- name: uloop-wait-for-debug-break -description: "Use this as the standard frame proof for Unity PlayMode/E2E: pause one representative state-changing input, physics, or UI transition and inspect variables/GameObjects/state like an IDE breakpoint. Time.timeScale, sleeps, screenshots, or after-the-fact execute-dynamic-code are not substitutes." +description: "Use this as the standard frame proof for Unity PlayMode/E2E: pause one representative state-changing input, physics, or UI transition and inspect variables/GameObjects/state like an IDE breakpoint. If local/intermediate values are hard to inspect later, log them just before the marker and read get-logs while paused." --- ## Quick Check Template Use this small loop for one representative frame you care about: -1. Put a marker at the natural transition point: +1. Put a focused log and marker at the natural transition point. Log only local/intermediate values that will be hard to inspect later: ```csharp +using UnityEngine; using io.github.hatayama.UnityCliLoop.Runtime; +Debug.Log($"state-transition-applied localValue={localValue} reason={reason}"); UnityCliLoopDebug.Break("state-transition-applied"); ``` @@ -23,7 +25,7 @@ uloop enable-debug-break --id state-transition-applied --timeout-seconds 30 3. Trigger the action with a `simulate-*` command. 4. Run `uloop wait-for-debug-break --id state-transition-applied --timeout-seconds 30`, even if the trigger command already returned `InterruptedByDebugBreak=true`. -5. While Unity is paused, capture focused evidence with `uloop execute-dynamic-code`, `uloop get-logs`, `uloop get-hierarchy`, `uloop find-game-objects`, and one screenshot. +5. While Unity is paused, capture focused evidence with `uloop get-logs`, `uloop execute-dynamic-code`, `uloop get-hierarchy`, `uloop find-game-objects`, and one screenshot. 6. Clear the marker with `uloop clear-debug-break --id state-transition-applied` or stop PlayMode before moving on. ## When To Use @@ -31,6 +33,7 @@ uloop enable-debug-break --id state-transition-applied --timeout-seconds 30 - Use this as the standard frame proof for state-changing PlayMode/E2E simulated input, physics, or UI transitions. - Pause at least one representative transition per E2E pass, even if durable state, logs, or screenshots can later confirm the final result. - Use this before reaching for `Time.timeScale`, sleeps, repeated polling, or after-the-fact `execute-dynamic-code`; those checks can supplement the paused-frame proof, but they are not substitutes. +- If the value you need is a method local, an intermediate calculation, or a branch reason that `execute-dynamic-code` cannot reach, add a focused `Debug.Log` immediately before the marker and read it with `get-logs` while paused. - Good pause points include after input is consumed, a command is accepted, a state mutation is committed, an evaluation step resolves, a tracked value changes, a UI/domain state syncs, or a success/failure/end condition is entered. - Treat the pause like a lightweight breakpoint for one important transition: combine nearby debug logs with paused-frame inspection to confirm the variables and component state at that point. - Do not treat `simulate-* Success=true`, generic action logs, sleeps/retries, testing-only counters, or `Time.timeScale` changes as paused-frame proof. diff --git a/.claude/skills/uloop-execute-dynamic-code/SKILL.md b/.claude/skills/uloop-execute-dynamic-code/SKILL.md index d29fcdc9c..b494abc5d 100644 --- a/.claude/skills/uloop-execute-dynamic-code/SKILL.md +++ b/.claude/skills/uloop-execute-dynamic-code/SKILL.md @@ -1,7 +1,7 @@ --- name: uloop-execute-dynamic-code toolName: execute-dynamic-code -description: "Execute C# with Unity APIs when existing uloop tools cannot inspect or edit enough. Use for scene, prefab, SerializedObject, AssetDatabase refresh/.meta generation, menu, or PlayMode automation." +description: "Execute C# with Unity APIs when existing uloop tools cannot inspect or edit enough. Use for reachable scene/component state, scene/prefab/menu automation, and PlayMode checks. It cannot see method locals from an already-running frame; for those, add focused Debug.Log before a debug-break marker and read get-logs while paused." context: fork --- @@ -11,6 +11,8 @@ Execute the following request using `uloop execute-dynamic-code`: $ARGUMENTS For basic selected GameObject discovery or property inspection, use `find-game-objects --search-mode Selected` before this tool. Use this tool after the built-in inspection tools are not enough or when you need to modify Unity state. +This tool can inspect reachable Unity state, such as GameObjects, components, public properties, static values, and method results. It cannot directly read local variables or intermediate calculations inside an already-running method. When those values matter, add a focused `Debug.Log` immediately before `UnityCliLoopDebug.Break("")`, then read `get-logs` while Unity is paused. + ## Workflow 1. Read the relevant reference file(s) from the Code Examples section below diff --git a/.claude/skills/uloop-get-logs/SKILL.md b/.claude/skills/uloop-get-logs/SKILL.md index a74e55532..078262e1f 100644 --- a/.claude/skills/uloop-get-logs/SKILL.md +++ b/.claude/skills/uloop-get-logs/SKILL.md @@ -1,13 +1,15 @@ --- name: uloop-get-logs toolName: get-logs -description: "Read current Unity Console entries from a running Editor. Use during bug investigation after compile, tests, PlayMode, or dynamic code to inspect logs, warnings, errors, and stack traces." +description: "Read current Unity Console entries from a running Editor. Use during bug investigation after compile, tests, PlayMode, dynamic code, or a debug-break pause; especially read focused Debug.Log output for local/intermediate values that execute-dynamic-code cannot inspect." --- # uloop get-logs Retrieve logs from Unity Console. +When a debug-break marker pauses Unity and the value you need is a method local, intermediate calculation, or branch reason, read the focused `Debug.Log` entry added immediately before the marker. Use `--search-text ` when the Console has unrelated entries. + ## Usage ```bash diff --git a/.claude/skills/uloop-simulate-keyboard/SKILL.md b/.claude/skills/uloop-simulate-keyboard/SKILL.md index 3529cb432..57a2d2f51 100644 --- a/.claude/skills/uloop-simulate-keyboard/SKILL.md +++ b/.claude/skills/uloop-simulate-keyboard/SKILL.md @@ -1,7 +1,7 @@ --- name: uloop-simulate-keyboard toolName: simulate-keyboard -description: "Simulate keyboard input in PlayMode through Unity Input System. For state-changing PlayMode/E2E input, also use uloop-wait-for-debug-break on at least one representative frame; Time.timeScale, sleeps, screenshots, or after-the-fact checks are not substitutes." +description: "Simulate keyboard input in PlayMode through Unity Input System. For state-changing PlayMode/E2E input, also use uloop-wait-for-debug-break on at least one representative frame; if local values are hard to inspect later, add focused Debug.Log next to the marker." context: fork --- @@ -49,6 +49,7 @@ Use `KeyDown` / `KeyUp` when the scenario intentionally needs a held key. - Use one `UnityCliLoopDebug.Break("")` marker for at least one representative keyboard input that changes runtime state. This applies even when final logs, screenshots, or durable state later show the outcome, because it pauses the exact frame where variables/state can prove input consumption. - Use the marker before slowing time, sleeping, polling, or rewriting runtime code to work around a missed input frame. Treat those checks as supplements, not substitutes. +- If the key handler has local variables, intermediate calculations, or branch reasons that `execute-dynamic-code` cannot inspect after the fact, log just those values with `Debug.Log` immediately before the marker and read them with `get-logs` while Unity is paused. - Put the marker at a natural state transition after the app consumed the key, such as after a command is accepted, a state mutation is committed, an evaluation step resolves, or a dependent component is updated. Do not place it immediately after sending `simulate-keyboard`. - Treat `simulate-keyboard Success=true`, generic action logs, and final durable counters as useful evidence, but not as paused-frame proof. - If the response has `InterruptedByDebugBreak: true`, Unity is paused for inspection and the tool released its held input bookkeeping. If a `UnityCliLoopDebug.Break` marker caused the pause, `DebugBreakId` and `DebugBreakHitCount` identify it. Use `get-logs`, `get-hierarchy`, `find-game-objects`, or `execute-dynamic-code` before resuming. diff --git a/.claude/skills/uloop-simulate-mouse-input/SKILL.md b/.claude/skills/uloop-simulate-mouse-input/SKILL.md index b970f76c0..d1ba1acab 100644 --- a/.claude/skills/uloop-simulate-mouse-input/SKILL.md +++ b/.claude/skills/uloop-simulate-mouse-input/SKILL.md @@ -1,7 +1,7 @@ --- name: uloop-simulate-mouse-input toolName: simulate-mouse-input -description: "Simulate Mouse.current input in PlayMode through Unity Input System. For state-changing PlayMode/E2E mouse input, also use uloop-wait-for-debug-break on at least one representative frame; Time.timeScale, sleeps, screenshots, or after-the-fact checks are not substitutes. Use simulate-mouse-ui for UI." +description: "Simulate Mouse.current input in PlayMode through Unity Input System. For state-changing PlayMode/E2E mouse input, also use uloop-wait-for-debug-break on at least one representative frame; if local values are hard to inspect later, add focused Debug.Log next to the marker. Use simulate-mouse-ui for UI." context: fork --- @@ -53,6 +53,7 @@ uloop simulate-mouse-input --action [options] - Use one `UnityCliLoopDebug.Break("")` marker for at least one representative mouse input that changes runtime state. This applies even when final logs, screenshots, or durable state later show the outcome, because it pauses the exact frame where variables/state can prove input consumption. - Use the marker before slowing time, sleeping, polling, or rewriting runtime code to work around a missed input frame. Treat those checks as supplements, not substitutes. +- If the mouse handler has local variables, intermediate calculations, or branch reasons that `execute-dynamic-code` cannot inspect after the fact, log just those values with `Debug.Log` immediately before the marker and read them with `get-logs` while Unity is paused. - Put the marker at a natural state transition after the app consumed the mouse input, such as after a command is accepted, a state mutation is committed, an evaluation step resolves, a tracked value changes, or a dependent component is updated. Do not place it immediately after sending `simulate-mouse-input`. - Treat `simulate-mouse-input Success=true`, generic action logs, and final durable counters as useful evidence, but not as paused-frame proof. - If the response has `InterruptedByDebugBreak: true`, Unity is paused for inspection and the tool released its held input bookkeeping. If a `UnityCliLoopDebug.Break` marker caused the pause, `DebugBreakId` and `DebugBreakHitCount` identify it. Use `get-logs`, `get-hierarchy`, `find-game-objects`, or `execute-dynamic-code` before resuming. diff --git a/.claude/skills/uloop-simulate-mouse-ui/SKILL.md b/.claude/skills/uloop-simulate-mouse-ui/SKILL.md index 094befa47..fe476ff57 100644 --- a/.claude/skills/uloop-simulate-mouse-ui/SKILL.md +++ b/.claude/skills/uloop-simulate-mouse-ui/SKILL.md @@ -1,7 +1,7 @@ --- name: uloop-simulate-mouse-ui toolName: simulate-mouse-ui -description: "Simulate PlayMode EventSystem UI mouse actions using screen coordinates. For state-changing PlayMode/E2E UI actions, also use uloop-wait-for-debug-break on at least one representative frame; Time.timeScale, sleeps, screenshots, or after-the-fact checks are not substitutes." +description: "Simulate PlayMode EventSystem UI mouse actions using screen coordinates. For state-changing PlayMode/E2E UI actions, also use uloop-wait-for-debug-break on at least one representative frame; if local values are hard to inspect later, add focused Debug.Log next to the marker." context: fork --- @@ -81,6 +81,7 @@ uloop simulate-mouse-ui --action --x --y [options] - Use one `UnityCliLoopDebug.Break("")` marker for at least one representative UI action that changes runtime state. This applies even when final logs, screenshots, or durable state later show the outcome, because it pauses the exact frame where variables/state can prove input consumption. - Use the marker before slowing time, sleeping, polling, or rewriting runtime code to work around a missed input frame. Treat those checks as supplements, not substitutes. +- If the UI handler has local variables, intermediate calculations, or branch reasons that `execute-dynamic-code` cannot inspect after the fact, log just those values with `Debug.Log` immediately before the marker and read them with `get-logs` while Unity is paused. - Put the marker at a natural transition after the app consumed the UI event, such as after a command is accepted, a state mutation is committed, a tracked value changes, a UI/domain state syncs, or a success/failure/end condition is entered. - Treat `simulate-mouse-ui Success=true`, generic action logs, and final durable counters as useful evidence, but not as paused-frame proof. - If a `UnityCliLoopDebug.Break` marker pauses Unity, inspect with `get-logs`, `get-hierarchy`, `find-game-objects`, or `execute-dynamic-code` before resuming. diff --git a/.claude/skills/uloop-wait-for-debug-break/SKILL.md b/.claude/skills/uloop-wait-for-debug-break/SKILL.md index 3290cb839..97aab8cf5 100644 --- a/.claude/skills/uloop-wait-for-debug-break/SKILL.md +++ b/.claude/skills/uloop-wait-for-debug-break/SKILL.md @@ -1,17 +1,19 @@ --- name: uloop-wait-for-debug-break -description: "Use this as the standard frame proof for Unity PlayMode/E2E: pause one representative state-changing input, physics, or UI transition and inspect variables/GameObjects/state like an IDE breakpoint. Time.timeScale, sleeps, screenshots, or after-the-fact execute-dynamic-code are not substitutes." +description: "Use this as the standard frame proof for Unity PlayMode/E2E: pause one representative state-changing input, physics, or UI transition and inspect variables/GameObjects/state like an IDE breakpoint. If local/intermediate values are hard to inspect later, log them just before the marker and read get-logs while paused." --- ## Quick Check Template Use this small loop for one representative frame you care about: -1. Put a marker at the natural transition point: +1. Put a focused log and marker at the natural transition point. Log only local/intermediate values that will be hard to inspect later: ```csharp +using UnityEngine; using io.github.hatayama.UnityCliLoop.Runtime; +Debug.Log($"state-transition-applied localValue={localValue} reason={reason}"); UnityCliLoopDebug.Break("state-transition-applied"); ``` @@ -23,7 +25,7 @@ uloop enable-debug-break --id state-transition-applied --timeout-seconds 30 3. Trigger the action with a `simulate-*` command. 4. Run `uloop wait-for-debug-break --id state-transition-applied --timeout-seconds 30`, even if the trigger command already returned `InterruptedByDebugBreak=true`. -5. While Unity is paused, capture focused evidence with `uloop execute-dynamic-code`, `uloop get-logs`, `uloop get-hierarchy`, `uloop find-game-objects`, and one screenshot. +5. While Unity is paused, capture focused evidence with `uloop get-logs`, `uloop execute-dynamic-code`, `uloop get-hierarchy`, `uloop find-game-objects`, and one screenshot. 6. Clear the marker with `uloop clear-debug-break --id state-transition-applied` or stop PlayMode before moving on. ## When To Use @@ -31,6 +33,7 @@ uloop enable-debug-break --id state-transition-applied --timeout-seconds 30 - Use this as the standard frame proof for state-changing PlayMode/E2E simulated input, physics, or UI transitions. - Pause at least one representative transition per E2E pass, even if durable state, logs, or screenshots can later confirm the final result. - Use this before reaching for `Time.timeScale`, sleeps, repeated polling, or after-the-fact `execute-dynamic-code`; those checks can supplement the paused-frame proof, but they are not substitutes. +- If the value you need is a method local, an intermediate calculation, or a branch reason that `execute-dynamic-code` cannot reach, add a focused `Debug.Log` immediately before the marker and read it with `get-logs` while paused. - Good pause points include after input is consumed, a command is accepted, a state mutation is committed, an evaluation step resolves, a tracked value changes, a UI/domain state syncs, or a success/failure/end condition is entered. - Treat the pause like a lightweight breakpoint for one important transition: combine nearby debug logs with paused-frame inspection to confirm the variables and component state at that point. - Do not treat `simulate-* Success=true`, generic action logs, sleeps/retries, testing-only counters, or `Time.timeScale` changes as paused-frame proof. diff --git a/Packages/src/Editor/CliOnlyTools~/PausePoint/Skill/SKILL.md b/Packages/src/Editor/CliOnlyTools~/PausePoint/Skill/SKILL.md index 3290cb839..97aab8cf5 100644 --- a/Packages/src/Editor/CliOnlyTools~/PausePoint/Skill/SKILL.md +++ b/Packages/src/Editor/CliOnlyTools~/PausePoint/Skill/SKILL.md @@ -1,17 +1,19 @@ --- name: uloop-wait-for-debug-break -description: "Use this as the standard frame proof for Unity PlayMode/E2E: pause one representative state-changing input, physics, or UI transition and inspect variables/GameObjects/state like an IDE breakpoint. Time.timeScale, sleeps, screenshots, or after-the-fact execute-dynamic-code are not substitutes." +description: "Use this as the standard frame proof for Unity PlayMode/E2E: pause one representative state-changing input, physics, or UI transition and inspect variables/GameObjects/state like an IDE breakpoint. If local/intermediate values are hard to inspect later, log them just before the marker and read get-logs while paused." --- ## Quick Check Template Use this small loop for one representative frame you care about: -1. Put a marker at the natural transition point: +1. Put a focused log and marker at the natural transition point. Log only local/intermediate values that will be hard to inspect later: ```csharp +using UnityEngine; using io.github.hatayama.UnityCliLoop.Runtime; +Debug.Log($"state-transition-applied localValue={localValue} reason={reason}"); UnityCliLoopDebug.Break("state-transition-applied"); ``` @@ -23,7 +25,7 @@ uloop enable-debug-break --id state-transition-applied --timeout-seconds 30 3. Trigger the action with a `simulate-*` command. 4. Run `uloop wait-for-debug-break --id state-transition-applied --timeout-seconds 30`, even if the trigger command already returned `InterruptedByDebugBreak=true`. -5. While Unity is paused, capture focused evidence with `uloop execute-dynamic-code`, `uloop get-logs`, `uloop get-hierarchy`, `uloop find-game-objects`, and one screenshot. +5. While Unity is paused, capture focused evidence with `uloop get-logs`, `uloop execute-dynamic-code`, `uloop get-hierarchy`, `uloop find-game-objects`, and one screenshot. 6. Clear the marker with `uloop clear-debug-break --id state-transition-applied` or stop PlayMode before moving on. ## When To Use @@ -31,6 +33,7 @@ uloop enable-debug-break --id state-transition-applied --timeout-seconds 30 - Use this as the standard frame proof for state-changing PlayMode/E2E simulated input, physics, or UI transitions. - Pause at least one representative transition per E2E pass, even if durable state, logs, or screenshots can later confirm the final result. - Use this before reaching for `Time.timeScale`, sleeps, repeated polling, or after-the-fact `execute-dynamic-code`; those checks can supplement the paused-frame proof, but they are not substitutes. +- If the value you need is a method local, an intermediate calculation, or a branch reason that `execute-dynamic-code` cannot reach, add a focused `Debug.Log` immediately before the marker and read it with `get-logs` while paused. - Good pause points include after input is consumed, a command is accepted, a state mutation is committed, an evaluation step resolves, a tracked value changes, a UI/domain state syncs, or a success/failure/end condition is entered. - Treat the pause like a lightweight breakpoint for one important transition: combine nearby debug logs with paused-frame inspection to confirm the variables and component state at that point. - Do not treat `simulate-* Success=true`, generic action logs, sleeps/retries, testing-only counters, or `Time.timeScale` changes as paused-frame proof. diff --git a/Packages/src/Editor/FirstPartyTools/ExecuteDynamicCode/Skill/SKILL.md b/Packages/src/Editor/FirstPartyTools/ExecuteDynamicCode/Skill/SKILL.md index d29fcdc9c..b494abc5d 100644 --- a/Packages/src/Editor/FirstPartyTools/ExecuteDynamicCode/Skill/SKILL.md +++ b/Packages/src/Editor/FirstPartyTools/ExecuteDynamicCode/Skill/SKILL.md @@ -1,7 +1,7 @@ --- name: uloop-execute-dynamic-code toolName: execute-dynamic-code -description: "Execute C# with Unity APIs when existing uloop tools cannot inspect or edit enough. Use for scene, prefab, SerializedObject, AssetDatabase refresh/.meta generation, menu, or PlayMode automation." +description: "Execute C# with Unity APIs when existing uloop tools cannot inspect or edit enough. Use for reachable scene/component state, scene/prefab/menu automation, and PlayMode checks. It cannot see method locals from an already-running frame; for those, add focused Debug.Log before a debug-break marker and read get-logs while paused." context: fork --- @@ -11,6 +11,8 @@ Execute the following request using `uloop execute-dynamic-code`: $ARGUMENTS For basic selected GameObject discovery or property inspection, use `find-game-objects --search-mode Selected` before this tool. Use this tool after the built-in inspection tools are not enough or when you need to modify Unity state. +This tool can inspect reachable Unity state, such as GameObjects, components, public properties, static values, and method results. It cannot directly read local variables or intermediate calculations inside an already-running method. When those values matter, add a focused `Debug.Log` immediately before `UnityCliLoopDebug.Break("")`, then read `get-logs` while Unity is paused. + ## Workflow 1. Read the relevant reference file(s) from the Code Examples section below diff --git a/Packages/src/Editor/FirstPartyTools/GetLogs/Skill/SKILL.md b/Packages/src/Editor/FirstPartyTools/GetLogs/Skill/SKILL.md index a74e55532..078262e1f 100644 --- a/Packages/src/Editor/FirstPartyTools/GetLogs/Skill/SKILL.md +++ b/Packages/src/Editor/FirstPartyTools/GetLogs/Skill/SKILL.md @@ -1,13 +1,15 @@ --- name: uloop-get-logs toolName: get-logs -description: "Read current Unity Console entries from a running Editor. Use during bug investigation after compile, tests, PlayMode, or dynamic code to inspect logs, warnings, errors, and stack traces." +description: "Read current Unity Console entries from a running Editor. Use during bug investigation after compile, tests, PlayMode, dynamic code, or a debug-break pause; especially read focused Debug.Log output for local/intermediate values that execute-dynamic-code cannot inspect." --- # uloop get-logs Retrieve logs from Unity Console. +When a debug-break marker pauses Unity and the value you need is a method local, intermediate calculation, or branch reason, read the focused `Debug.Log` entry added immediately before the marker. Use `--search-text ` when the Console has unrelated entries. + ## Usage ```bash diff --git a/Packages/src/Editor/FirstPartyTools/SimulateKeyboard/Skill/SKILL.md b/Packages/src/Editor/FirstPartyTools/SimulateKeyboard/Skill/SKILL.md index 3529cb432..57a2d2f51 100644 --- a/Packages/src/Editor/FirstPartyTools/SimulateKeyboard/Skill/SKILL.md +++ b/Packages/src/Editor/FirstPartyTools/SimulateKeyboard/Skill/SKILL.md @@ -1,7 +1,7 @@ --- name: uloop-simulate-keyboard toolName: simulate-keyboard -description: "Simulate keyboard input in PlayMode through Unity Input System. For state-changing PlayMode/E2E input, also use uloop-wait-for-debug-break on at least one representative frame; Time.timeScale, sleeps, screenshots, or after-the-fact checks are not substitutes." +description: "Simulate keyboard input in PlayMode through Unity Input System. For state-changing PlayMode/E2E input, also use uloop-wait-for-debug-break on at least one representative frame; if local values are hard to inspect later, add focused Debug.Log next to the marker." context: fork --- @@ -49,6 +49,7 @@ Use `KeyDown` / `KeyUp` when the scenario intentionally needs a held key. - Use one `UnityCliLoopDebug.Break("")` marker for at least one representative keyboard input that changes runtime state. This applies even when final logs, screenshots, or durable state later show the outcome, because it pauses the exact frame where variables/state can prove input consumption. - Use the marker before slowing time, sleeping, polling, or rewriting runtime code to work around a missed input frame. Treat those checks as supplements, not substitutes. +- If the key handler has local variables, intermediate calculations, or branch reasons that `execute-dynamic-code` cannot inspect after the fact, log just those values with `Debug.Log` immediately before the marker and read them with `get-logs` while Unity is paused. - Put the marker at a natural state transition after the app consumed the key, such as after a command is accepted, a state mutation is committed, an evaluation step resolves, or a dependent component is updated. Do not place it immediately after sending `simulate-keyboard`. - Treat `simulate-keyboard Success=true`, generic action logs, and final durable counters as useful evidence, but not as paused-frame proof. - If the response has `InterruptedByDebugBreak: true`, Unity is paused for inspection and the tool released its held input bookkeeping. If a `UnityCliLoopDebug.Break` marker caused the pause, `DebugBreakId` and `DebugBreakHitCount` identify it. Use `get-logs`, `get-hierarchy`, `find-game-objects`, or `execute-dynamic-code` before resuming. diff --git a/Packages/src/Editor/FirstPartyTools/SimulateMouseInput/Skill/SKILL.md b/Packages/src/Editor/FirstPartyTools/SimulateMouseInput/Skill/SKILL.md index b970f76c0..d1ba1acab 100644 --- a/Packages/src/Editor/FirstPartyTools/SimulateMouseInput/Skill/SKILL.md +++ b/Packages/src/Editor/FirstPartyTools/SimulateMouseInput/Skill/SKILL.md @@ -1,7 +1,7 @@ --- name: uloop-simulate-mouse-input toolName: simulate-mouse-input -description: "Simulate Mouse.current input in PlayMode through Unity Input System. For state-changing PlayMode/E2E mouse input, also use uloop-wait-for-debug-break on at least one representative frame; Time.timeScale, sleeps, screenshots, or after-the-fact checks are not substitutes. Use simulate-mouse-ui for UI." +description: "Simulate Mouse.current input in PlayMode through Unity Input System. For state-changing PlayMode/E2E mouse input, also use uloop-wait-for-debug-break on at least one representative frame; if local values are hard to inspect later, add focused Debug.Log next to the marker. Use simulate-mouse-ui for UI." context: fork --- @@ -53,6 +53,7 @@ uloop simulate-mouse-input --action [options] - Use one `UnityCliLoopDebug.Break("")` marker for at least one representative mouse input that changes runtime state. This applies even when final logs, screenshots, or durable state later show the outcome, because it pauses the exact frame where variables/state can prove input consumption. - Use the marker before slowing time, sleeping, polling, or rewriting runtime code to work around a missed input frame. Treat those checks as supplements, not substitutes. +- If the mouse handler has local variables, intermediate calculations, or branch reasons that `execute-dynamic-code` cannot inspect after the fact, log just those values with `Debug.Log` immediately before the marker and read them with `get-logs` while Unity is paused. - Put the marker at a natural state transition after the app consumed the mouse input, such as after a command is accepted, a state mutation is committed, an evaluation step resolves, a tracked value changes, or a dependent component is updated. Do not place it immediately after sending `simulate-mouse-input`. - Treat `simulate-mouse-input Success=true`, generic action logs, and final durable counters as useful evidence, but not as paused-frame proof. - If the response has `InterruptedByDebugBreak: true`, Unity is paused for inspection and the tool released its held input bookkeeping. If a `UnityCliLoopDebug.Break` marker caused the pause, `DebugBreakId` and `DebugBreakHitCount` identify it. Use `get-logs`, `get-hierarchy`, `find-game-objects`, or `execute-dynamic-code` before resuming. diff --git a/Packages/src/Editor/FirstPartyTools/SimulateMouseUi/Skill/SKILL.md b/Packages/src/Editor/FirstPartyTools/SimulateMouseUi/Skill/SKILL.md index 094befa47..fe476ff57 100644 --- a/Packages/src/Editor/FirstPartyTools/SimulateMouseUi/Skill/SKILL.md +++ b/Packages/src/Editor/FirstPartyTools/SimulateMouseUi/Skill/SKILL.md @@ -1,7 +1,7 @@ --- name: uloop-simulate-mouse-ui toolName: simulate-mouse-ui -description: "Simulate PlayMode EventSystem UI mouse actions using screen coordinates. For state-changing PlayMode/E2E UI actions, also use uloop-wait-for-debug-break on at least one representative frame; Time.timeScale, sleeps, screenshots, or after-the-fact checks are not substitutes." +description: "Simulate PlayMode EventSystem UI mouse actions using screen coordinates. For state-changing PlayMode/E2E UI actions, also use uloop-wait-for-debug-break on at least one representative frame; if local values are hard to inspect later, add focused Debug.Log next to the marker." context: fork --- @@ -81,6 +81,7 @@ uloop simulate-mouse-ui --action --x --y [options] - Use one `UnityCliLoopDebug.Break("")` marker for at least one representative UI action that changes runtime state. This applies even when final logs, screenshots, or durable state later show the outcome, because it pauses the exact frame where variables/state can prove input consumption. - Use the marker before slowing time, sleeping, polling, or rewriting runtime code to work around a missed input frame. Treat those checks as supplements, not substitutes. +- If the UI handler has local variables, intermediate calculations, or branch reasons that `execute-dynamic-code` cannot inspect after the fact, log just those values with `Debug.Log` immediately before the marker and read them with `get-logs` while Unity is paused. - Put the marker at a natural transition after the app consumed the UI event, such as after a command is accepted, a state mutation is committed, a tracked value changes, a UI/domain state syncs, or a success/failure/end condition is entered. - Treat `simulate-mouse-ui Success=true`, generic action logs, and final durable counters as useful evidence, but not as paused-frame proof. - If a `UnityCliLoopDebug.Break` marker pauses Unity, inspect with `get-logs`, `get-hierarchy`, `find-game-objects`, or `execute-dynamic-code` before resuming. From 31b88294724e395cf23a28265dc82f191d0efd0c Mon Sep 17 00:00:00 2001 From: hatayama Date: Wed, 10 Jun 2026 02:23:09 +0900 Subject: [PATCH 10/24] Require log reads for frame-local debug breaks Marker-only debug-break checks do not prove method locals, intermediate calculations, or branch reasons. Require focused Debug.Log output next to the marker and a matching get-logs read before resuming PlayMode. --- .agents/skills/uloop-execute-dynamic-code/SKILL.md | 4 ++-- .agents/skills/uloop-get-logs/SKILL.md | 4 ++-- .agents/skills/uloop-simulate-keyboard/SKILL.md | 4 ++-- .agents/skills/uloop-simulate-mouse-input/SKILL.md | 4 ++-- .agents/skills/uloop-simulate-mouse-ui/SKILL.md | 4 ++-- .agents/skills/uloop-wait-for-debug-break/SKILL.md | 14 ++++++++++---- .claude/skills/uloop-execute-dynamic-code/SKILL.md | 4 ++-- .claude/skills/uloop-get-logs/SKILL.md | 4 ++-- .claude/skills/uloop-simulate-keyboard/SKILL.md | 4 ++-- .claude/skills/uloop-simulate-mouse-input/SKILL.md | 4 ++-- .claude/skills/uloop-simulate-mouse-ui/SKILL.md | 4 ++-- .claude/skills/uloop-wait-for-debug-break/SKILL.md | 14 ++++++++++---- .../Editor/CliOnlyTools~/PausePoint/Skill/SKILL.md | 14 ++++++++++---- .../ExecuteDynamicCode/Skill/SKILL.md | 4 ++-- .../Editor/FirstPartyTools/GetLogs/Skill/SKILL.md | 4 ++-- .../SimulateKeyboard/Skill/SKILL.md | 4 ++-- .../SimulateMouseInput/Skill/SKILL.md | 4 ++-- .../FirstPartyTools/SimulateMouseUi/Skill/SKILL.md | 4 ++-- 18 files changed, 60 insertions(+), 42 deletions(-) diff --git a/.agents/skills/uloop-execute-dynamic-code/SKILL.md b/.agents/skills/uloop-execute-dynamic-code/SKILL.md index b494abc5d..49b149a0f 100644 --- a/.agents/skills/uloop-execute-dynamic-code/SKILL.md +++ b/.agents/skills/uloop-execute-dynamic-code/SKILL.md @@ -1,7 +1,7 @@ --- name: uloop-execute-dynamic-code toolName: execute-dynamic-code -description: "Execute C# with Unity APIs when existing uloop tools cannot inspect or edit enough. Use for reachable scene/component state, scene/prefab/menu automation, and PlayMode checks. It cannot see method locals from an already-running frame; for those, add focused Debug.Log before a debug-break marker and read get-logs while paused." +description: "Execute C# with Unity APIs when existing uloop tools cannot inspect or edit enough. Use for reachable scene/component state, scene/prefab/menu automation, and PlayMode checks. It cannot see method locals from an already-running frame; use focused Debug.Log plus get-logs during a debug-break pause for those." context: fork --- @@ -11,7 +11,7 @@ Execute the following request using `uloop execute-dynamic-code`: $ARGUMENTS For basic selected GameObject discovery or property inspection, use `find-game-objects --search-mode Selected` before this tool. Use this tool after the built-in inspection tools are not enough or when you need to modify Unity state. -This tool can inspect reachable Unity state, such as GameObjects, components, public properties, static values, and method results. It cannot directly read local variables or intermediate calculations inside an already-running method. When those values matter, add a focused `Debug.Log` immediately before `UnityCliLoopDebug.Break("")`, then read `get-logs` while Unity is paused. +This tool can inspect reachable Unity state, such as GameObjects, components, public properties, static values, and method results. It cannot directly read local variables or intermediate calculations inside an already-running method. When those values matter, add a focused `Debug.Log` immediately before `UnityCliLoopDebug.Break("")`, then run `get-logs --search-text ` while Unity is paused. Do not replace that log read with execute-dynamic-code. ## Workflow diff --git a/.agents/skills/uloop-get-logs/SKILL.md b/.agents/skills/uloop-get-logs/SKILL.md index 078262e1f..bfb53e585 100644 --- a/.agents/skills/uloop-get-logs/SKILL.md +++ b/.agents/skills/uloop-get-logs/SKILL.md @@ -1,14 +1,14 @@ --- name: uloop-get-logs toolName: get-logs -description: "Read current Unity Console entries from a running Editor. Use during bug investigation after compile, tests, PlayMode, dynamic code, or a debug-break pause; especially read focused Debug.Log output for local/intermediate values that execute-dynamic-code cannot inspect." +description: "Read current Unity Console entries from a running Editor. Use during bug investigation after compile, tests, PlayMode, dynamic code, or immediately after wait-for-debug-break; read focused Debug.Log output for frame-local values before resuming." --- # uloop get-logs Retrieve logs from Unity Console. -When a debug-break marker pauses Unity and the value you need is a method local, intermediate calculation, or branch reason, read the focused `Debug.Log` entry added immediately before the marker. Use `--search-text ` when the Console has unrelated entries. +When a debug-break marker pauses Unity and the value you need is a method local, intermediate calculation, or branch reason, read the focused `Debug.Log` entry added immediately before the marker before resuming PlayMode. Use `--search-text ` so the marker and its log are checked as one breakpoint-style proof. ## Usage diff --git a/.agents/skills/uloop-simulate-keyboard/SKILL.md b/.agents/skills/uloop-simulate-keyboard/SKILL.md index 57a2d2f51..058ad6997 100644 --- a/.agents/skills/uloop-simulate-keyboard/SKILL.md +++ b/.agents/skills/uloop-simulate-keyboard/SKILL.md @@ -1,7 +1,7 @@ --- name: uloop-simulate-keyboard toolName: simulate-keyboard -description: "Simulate keyboard input in PlayMode through Unity Input System. For state-changing PlayMode/E2E input, also use uloop-wait-for-debug-break on at least one representative frame; if local values are hard to inspect later, add focused Debug.Log next to the marker." +description: "Simulate keyboard input in PlayMode through Unity Input System. For state-changing PlayMode/E2E input, also use uloop-wait-for-debug-break; when frame-local values matter, pair the marker with focused Debug.Log and get-logs before resuming." context: fork --- @@ -49,7 +49,7 @@ Use `KeyDown` / `KeyUp` when the scenario intentionally needs a held key. - Use one `UnityCliLoopDebug.Break("")` marker for at least one representative keyboard input that changes runtime state. This applies even when final logs, screenshots, or durable state later show the outcome, because it pauses the exact frame where variables/state can prove input consumption. - Use the marker before slowing time, sleeping, polling, or rewriting runtime code to work around a missed input frame. Treat those checks as supplements, not substitutes. -- If the key handler has local variables, intermediate calculations, or branch reasons that `execute-dynamic-code` cannot inspect after the fact, log just those values with `Debug.Log` immediately before the marker and read them with `get-logs` while Unity is paused. +- If the key handler has local variables, intermediate calculations, or branch reasons that `execute-dynamic-code` cannot inspect after the fact, log just those values with `Debug.Log` immediately before the marker and read them with `get-logs` while Unity is paused. A marker-only check proves the line was reached, not the frame-local values. - Put the marker at a natural state transition after the app consumed the key, such as after a command is accepted, a state mutation is committed, an evaluation step resolves, or a dependent component is updated. Do not place it immediately after sending `simulate-keyboard`. - Treat `simulate-keyboard Success=true`, generic action logs, and final durable counters as useful evidence, but not as paused-frame proof. - If the response has `InterruptedByDebugBreak: true`, Unity is paused for inspection and the tool released its held input bookkeeping. If a `UnityCliLoopDebug.Break` marker caused the pause, `DebugBreakId` and `DebugBreakHitCount` identify it. Use `get-logs`, `get-hierarchy`, `find-game-objects`, or `execute-dynamic-code` before resuming. diff --git a/.agents/skills/uloop-simulate-mouse-input/SKILL.md b/.agents/skills/uloop-simulate-mouse-input/SKILL.md index d1ba1acab..ffb1a54c4 100644 --- a/.agents/skills/uloop-simulate-mouse-input/SKILL.md +++ b/.agents/skills/uloop-simulate-mouse-input/SKILL.md @@ -1,7 +1,7 @@ --- name: uloop-simulate-mouse-input toolName: simulate-mouse-input -description: "Simulate Mouse.current input in PlayMode through Unity Input System. For state-changing PlayMode/E2E mouse input, also use uloop-wait-for-debug-break on at least one representative frame; if local values are hard to inspect later, add focused Debug.Log next to the marker. Use simulate-mouse-ui for UI." +description: "Simulate Mouse.current input in PlayMode through Unity Input System. For state-changing PlayMode/E2E mouse input, also use uloop-wait-for-debug-break; when frame-local values matter, pair the marker with focused Debug.Log and get-logs before resuming. Use simulate-mouse-ui for UI." context: fork --- @@ -53,7 +53,7 @@ uloop simulate-mouse-input --action [options] - Use one `UnityCliLoopDebug.Break("")` marker for at least one representative mouse input that changes runtime state. This applies even when final logs, screenshots, or durable state later show the outcome, because it pauses the exact frame where variables/state can prove input consumption. - Use the marker before slowing time, sleeping, polling, or rewriting runtime code to work around a missed input frame. Treat those checks as supplements, not substitutes. -- If the mouse handler has local variables, intermediate calculations, or branch reasons that `execute-dynamic-code` cannot inspect after the fact, log just those values with `Debug.Log` immediately before the marker and read them with `get-logs` while Unity is paused. +- If the mouse handler has local variables, intermediate calculations, or branch reasons that `execute-dynamic-code` cannot inspect after the fact, log just those values with `Debug.Log` immediately before the marker and read them with `get-logs` while Unity is paused. A marker-only check proves the line was reached, not the frame-local values. - Put the marker at a natural state transition after the app consumed the mouse input, such as after a command is accepted, a state mutation is committed, an evaluation step resolves, a tracked value changes, or a dependent component is updated. Do not place it immediately after sending `simulate-mouse-input`. - Treat `simulate-mouse-input Success=true`, generic action logs, and final durable counters as useful evidence, but not as paused-frame proof. - If the response has `InterruptedByDebugBreak: true`, Unity is paused for inspection and the tool released its held input bookkeeping. If a `UnityCliLoopDebug.Break` marker caused the pause, `DebugBreakId` and `DebugBreakHitCount` identify it. Use `get-logs`, `get-hierarchy`, `find-game-objects`, or `execute-dynamic-code` before resuming. diff --git a/.agents/skills/uloop-simulate-mouse-ui/SKILL.md b/.agents/skills/uloop-simulate-mouse-ui/SKILL.md index fe476ff57..14b590409 100644 --- a/.agents/skills/uloop-simulate-mouse-ui/SKILL.md +++ b/.agents/skills/uloop-simulate-mouse-ui/SKILL.md @@ -1,7 +1,7 @@ --- name: uloop-simulate-mouse-ui toolName: simulate-mouse-ui -description: "Simulate PlayMode EventSystem UI mouse actions using screen coordinates. For state-changing PlayMode/E2E UI actions, also use uloop-wait-for-debug-break on at least one representative frame; if local values are hard to inspect later, add focused Debug.Log next to the marker." +description: "Simulate PlayMode EventSystem UI mouse actions using screen coordinates. For state-changing PlayMode/E2E UI actions, also use uloop-wait-for-debug-break; when frame-local values matter, pair the marker with focused Debug.Log and get-logs before resuming." context: fork --- @@ -81,7 +81,7 @@ uloop simulate-mouse-ui --action --x --y [options] - Use one `UnityCliLoopDebug.Break("")` marker for at least one representative UI action that changes runtime state. This applies even when final logs, screenshots, or durable state later show the outcome, because it pauses the exact frame where variables/state can prove input consumption. - Use the marker before slowing time, sleeping, polling, or rewriting runtime code to work around a missed input frame. Treat those checks as supplements, not substitutes. -- If the UI handler has local variables, intermediate calculations, or branch reasons that `execute-dynamic-code` cannot inspect after the fact, log just those values with `Debug.Log` immediately before the marker and read them with `get-logs` while Unity is paused. +- If the UI handler has local variables, intermediate calculations, or branch reasons that `execute-dynamic-code` cannot inspect after the fact, log just those values with `Debug.Log` immediately before the marker and read them with `get-logs` while Unity is paused. A marker-only check proves the line was reached, not the frame-local values. - Put the marker at a natural transition after the app consumed the UI event, such as after a command is accepted, a state mutation is committed, a tracked value changes, a UI/domain state syncs, or a success/failure/end condition is entered. - Treat `simulate-mouse-ui Success=true`, generic action logs, and final durable counters as useful evidence, but not as paused-frame proof. - If a `UnityCliLoopDebug.Break` marker pauses Unity, inspect with `get-logs`, `get-hierarchy`, `find-game-objects`, or `execute-dynamic-code` before resuming. diff --git a/.agents/skills/uloop-wait-for-debug-break/SKILL.md b/.agents/skills/uloop-wait-for-debug-break/SKILL.md index 97aab8cf5..ab9d4e602 100644 --- a/.agents/skills/uloop-wait-for-debug-break/SKILL.md +++ b/.agents/skills/uloop-wait-for-debug-break/SKILL.md @@ -1,6 +1,6 @@ --- name: uloop-wait-for-debug-break -description: "Use this as the standard frame proof for Unity PlayMode/E2E: pause one representative state-changing input, physics, or UI transition and inspect variables/GameObjects/state like an IDE breakpoint. If local/intermediate values are hard to inspect later, log them just before the marker and read get-logs while paused." +description: "Use this as the standard frame proof for Unity PlayMode/E2E: pause one representative transition like an IDE breakpoint. For frame-local/intermediate values, marker-only proof is incomplete: add focused Debug.Log before the marker and read get-logs while paused." --- ## Quick Check Template @@ -25,15 +25,21 @@ uloop enable-debug-break --id state-transition-applied --timeout-seconds 30 3. Trigger the action with a `simulate-*` command. 4. Run `uloop wait-for-debug-break --id state-transition-applied --timeout-seconds 30`, even if the trigger command already returned `InterruptedByDebugBreak=true`. -5. While Unity is paused, capture focused evidence with `uloop get-logs`, `uloop execute-dynamic-code`, `uloop get-hierarchy`, `uloop find-game-objects`, and one screenshot. -6. Clear the marker with `uloop clear-debug-break --id state-transition-applied` or stop PlayMode before moving on. +5. Before resuming, read the focused log for the same marker id: + +```bash +uloop get-logs --search-text state-transition-applied --max-count 20 +``` + +6. While Unity is still paused, capture any additional evidence with `uloop execute-dynamic-code`, `uloop get-hierarchy`, `uloop find-game-objects`, and one screenshot. +7. Clear the marker with `uloop clear-debug-break --id state-transition-applied` or stop PlayMode before moving on. ## When To Use - Use this as the standard frame proof for state-changing PlayMode/E2E simulated input, physics, or UI transitions. - Pause at least one representative transition per E2E pass, even if durable state, logs, or screenshots can later confirm the final result. - Use this before reaching for `Time.timeScale`, sleeps, repeated polling, or after-the-fact `execute-dynamic-code`; those checks can supplement the paused-frame proof, but they are not substitutes. -- If the value you need is a method local, an intermediate calculation, or a branch reason that `execute-dynamic-code` cannot reach, add a focused `Debug.Log` immediately before the marker and read it with `get-logs` while paused. +- If the value you need is a method local, an intermediate calculation, or a branch reason that `execute-dynamic-code` cannot reach, add a focused `Debug.Log` immediately before the marker and read it with `get-logs` while paused. Do not count the breakpoint check complete until the matching log has been read. - Good pause points include after input is consumed, a command is accepted, a state mutation is committed, an evaluation step resolves, a tracked value changes, a UI/domain state syncs, or a success/failure/end condition is entered. - Treat the pause like a lightweight breakpoint for one important transition: combine nearby debug logs with paused-frame inspection to confirm the variables and component state at that point. - Do not treat `simulate-* Success=true`, generic action logs, sleeps/retries, testing-only counters, or `Time.timeScale` changes as paused-frame proof. diff --git a/.claude/skills/uloop-execute-dynamic-code/SKILL.md b/.claude/skills/uloop-execute-dynamic-code/SKILL.md index b494abc5d..49b149a0f 100644 --- a/.claude/skills/uloop-execute-dynamic-code/SKILL.md +++ b/.claude/skills/uloop-execute-dynamic-code/SKILL.md @@ -1,7 +1,7 @@ --- name: uloop-execute-dynamic-code toolName: execute-dynamic-code -description: "Execute C# with Unity APIs when existing uloop tools cannot inspect or edit enough. Use for reachable scene/component state, scene/prefab/menu automation, and PlayMode checks. It cannot see method locals from an already-running frame; for those, add focused Debug.Log before a debug-break marker and read get-logs while paused." +description: "Execute C# with Unity APIs when existing uloop tools cannot inspect or edit enough. Use for reachable scene/component state, scene/prefab/menu automation, and PlayMode checks. It cannot see method locals from an already-running frame; use focused Debug.Log plus get-logs during a debug-break pause for those." context: fork --- @@ -11,7 +11,7 @@ Execute the following request using `uloop execute-dynamic-code`: $ARGUMENTS For basic selected GameObject discovery or property inspection, use `find-game-objects --search-mode Selected` before this tool. Use this tool after the built-in inspection tools are not enough or when you need to modify Unity state. -This tool can inspect reachable Unity state, such as GameObjects, components, public properties, static values, and method results. It cannot directly read local variables or intermediate calculations inside an already-running method. When those values matter, add a focused `Debug.Log` immediately before `UnityCliLoopDebug.Break("")`, then read `get-logs` while Unity is paused. +This tool can inspect reachable Unity state, such as GameObjects, components, public properties, static values, and method results. It cannot directly read local variables or intermediate calculations inside an already-running method. When those values matter, add a focused `Debug.Log` immediately before `UnityCliLoopDebug.Break("")`, then run `get-logs --search-text ` while Unity is paused. Do not replace that log read with execute-dynamic-code. ## Workflow diff --git a/.claude/skills/uloop-get-logs/SKILL.md b/.claude/skills/uloop-get-logs/SKILL.md index 078262e1f..bfb53e585 100644 --- a/.claude/skills/uloop-get-logs/SKILL.md +++ b/.claude/skills/uloop-get-logs/SKILL.md @@ -1,14 +1,14 @@ --- name: uloop-get-logs toolName: get-logs -description: "Read current Unity Console entries from a running Editor. Use during bug investigation after compile, tests, PlayMode, dynamic code, or a debug-break pause; especially read focused Debug.Log output for local/intermediate values that execute-dynamic-code cannot inspect." +description: "Read current Unity Console entries from a running Editor. Use during bug investigation after compile, tests, PlayMode, dynamic code, or immediately after wait-for-debug-break; read focused Debug.Log output for frame-local values before resuming." --- # uloop get-logs Retrieve logs from Unity Console. -When a debug-break marker pauses Unity and the value you need is a method local, intermediate calculation, or branch reason, read the focused `Debug.Log` entry added immediately before the marker. Use `--search-text ` when the Console has unrelated entries. +When a debug-break marker pauses Unity and the value you need is a method local, intermediate calculation, or branch reason, read the focused `Debug.Log` entry added immediately before the marker before resuming PlayMode. Use `--search-text ` so the marker and its log are checked as one breakpoint-style proof. ## Usage diff --git a/.claude/skills/uloop-simulate-keyboard/SKILL.md b/.claude/skills/uloop-simulate-keyboard/SKILL.md index 57a2d2f51..058ad6997 100644 --- a/.claude/skills/uloop-simulate-keyboard/SKILL.md +++ b/.claude/skills/uloop-simulate-keyboard/SKILL.md @@ -1,7 +1,7 @@ --- name: uloop-simulate-keyboard toolName: simulate-keyboard -description: "Simulate keyboard input in PlayMode through Unity Input System. For state-changing PlayMode/E2E input, also use uloop-wait-for-debug-break on at least one representative frame; if local values are hard to inspect later, add focused Debug.Log next to the marker." +description: "Simulate keyboard input in PlayMode through Unity Input System. For state-changing PlayMode/E2E input, also use uloop-wait-for-debug-break; when frame-local values matter, pair the marker with focused Debug.Log and get-logs before resuming." context: fork --- @@ -49,7 +49,7 @@ Use `KeyDown` / `KeyUp` when the scenario intentionally needs a held key. - Use one `UnityCliLoopDebug.Break("")` marker for at least one representative keyboard input that changes runtime state. This applies even when final logs, screenshots, or durable state later show the outcome, because it pauses the exact frame where variables/state can prove input consumption. - Use the marker before slowing time, sleeping, polling, or rewriting runtime code to work around a missed input frame. Treat those checks as supplements, not substitutes. -- If the key handler has local variables, intermediate calculations, or branch reasons that `execute-dynamic-code` cannot inspect after the fact, log just those values with `Debug.Log` immediately before the marker and read them with `get-logs` while Unity is paused. +- If the key handler has local variables, intermediate calculations, or branch reasons that `execute-dynamic-code` cannot inspect after the fact, log just those values with `Debug.Log` immediately before the marker and read them with `get-logs` while Unity is paused. A marker-only check proves the line was reached, not the frame-local values. - Put the marker at a natural state transition after the app consumed the key, such as after a command is accepted, a state mutation is committed, an evaluation step resolves, or a dependent component is updated. Do not place it immediately after sending `simulate-keyboard`. - Treat `simulate-keyboard Success=true`, generic action logs, and final durable counters as useful evidence, but not as paused-frame proof. - If the response has `InterruptedByDebugBreak: true`, Unity is paused for inspection and the tool released its held input bookkeeping. If a `UnityCliLoopDebug.Break` marker caused the pause, `DebugBreakId` and `DebugBreakHitCount` identify it. Use `get-logs`, `get-hierarchy`, `find-game-objects`, or `execute-dynamic-code` before resuming. diff --git a/.claude/skills/uloop-simulate-mouse-input/SKILL.md b/.claude/skills/uloop-simulate-mouse-input/SKILL.md index d1ba1acab..ffb1a54c4 100644 --- a/.claude/skills/uloop-simulate-mouse-input/SKILL.md +++ b/.claude/skills/uloop-simulate-mouse-input/SKILL.md @@ -1,7 +1,7 @@ --- name: uloop-simulate-mouse-input toolName: simulate-mouse-input -description: "Simulate Mouse.current input in PlayMode through Unity Input System. For state-changing PlayMode/E2E mouse input, also use uloop-wait-for-debug-break on at least one representative frame; if local values are hard to inspect later, add focused Debug.Log next to the marker. Use simulate-mouse-ui for UI." +description: "Simulate Mouse.current input in PlayMode through Unity Input System. For state-changing PlayMode/E2E mouse input, also use uloop-wait-for-debug-break; when frame-local values matter, pair the marker with focused Debug.Log and get-logs before resuming. Use simulate-mouse-ui for UI." context: fork --- @@ -53,7 +53,7 @@ uloop simulate-mouse-input --action [options] - Use one `UnityCliLoopDebug.Break("")` marker for at least one representative mouse input that changes runtime state. This applies even when final logs, screenshots, or durable state later show the outcome, because it pauses the exact frame where variables/state can prove input consumption. - Use the marker before slowing time, sleeping, polling, or rewriting runtime code to work around a missed input frame. Treat those checks as supplements, not substitutes. -- If the mouse handler has local variables, intermediate calculations, or branch reasons that `execute-dynamic-code` cannot inspect after the fact, log just those values with `Debug.Log` immediately before the marker and read them with `get-logs` while Unity is paused. +- If the mouse handler has local variables, intermediate calculations, or branch reasons that `execute-dynamic-code` cannot inspect after the fact, log just those values with `Debug.Log` immediately before the marker and read them with `get-logs` while Unity is paused. A marker-only check proves the line was reached, not the frame-local values. - Put the marker at a natural state transition after the app consumed the mouse input, such as after a command is accepted, a state mutation is committed, an evaluation step resolves, a tracked value changes, or a dependent component is updated. Do not place it immediately after sending `simulate-mouse-input`. - Treat `simulate-mouse-input Success=true`, generic action logs, and final durable counters as useful evidence, but not as paused-frame proof. - If the response has `InterruptedByDebugBreak: true`, Unity is paused for inspection and the tool released its held input bookkeeping. If a `UnityCliLoopDebug.Break` marker caused the pause, `DebugBreakId` and `DebugBreakHitCount` identify it. Use `get-logs`, `get-hierarchy`, `find-game-objects`, or `execute-dynamic-code` before resuming. diff --git a/.claude/skills/uloop-simulate-mouse-ui/SKILL.md b/.claude/skills/uloop-simulate-mouse-ui/SKILL.md index fe476ff57..14b590409 100644 --- a/.claude/skills/uloop-simulate-mouse-ui/SKILL.md +++ b/.claude/skills/uloop-simulate-mouse-ui/SKILL.md @@ -1,7 +1,7 @@ --- name: uloop-simulate-mouse-ui toolName: simulate-mouse-ui -description: "Simulate PlayMode EventSystem UI mouse actions using screen coordinates. For state-changing PlayMode/E2E UI actions, also use uloop-wait-for-debug-break on at least one representative frame; if local values are hard to inspect later, add focused Debug.Log next to the marker." +description: "Simulate PlayMode EventSystem UI mouse actions using screen coordinates. For state-changing PlayMode/E2E UI actions, also use uloop-wait-for-debug-break; when frame-local values matter, pair the marker with focused Debug.Log and get-logs before resuming." context: fork --- @@ -81,7 +81,7 @@ uloop simulate-mouse-ui --action --x --y [options] - Use one `UnityCliLoopDebug.Break("")` marker for at least one representative UI action that changes runtime state. This applies even when final logs, screenshots, or durable state later show the outcome, because it pauses the exact frame where variables/state can prove input consumption. - Use the marker before slowing time, sleeping, polling, or rewriting runtime code to work around a missed input frame. Treat those checks as supplements, not substitutes. -- If the UI handler has local variables, intermediate calculations, or branch reasons that `execute-dynamic-code` cannot inspect after the fact, log just those values with `Debug.Log` immediately before the marker and read them with `get-logs` while Unity is paused. +- If the UI handler has local variables, intermediate calculations, or branch reasons that `execute-dynamic-code` cannot inspect after the fact, log just those values with `Debug.Log` immediately before the marker and read them with `get-logs` while Unity is paused. A marker-only check proves the line was reached, not the frame-local values. - Put the marker at a natural transition after the app consumed the UI event, such as after a command is accepted, a state mutation is committed, a tracked value changes, a UI/domain state syncs, or a success/failure/end condition is entered. - Treat `simulate-mouse-ui Success=true`, generic action logs, and final durable counters as useful evidence, but not as paused-frame proof. - If a `UnityCliLoopDebug.Break` marker pauses Unity, inspect with `get-logs`, `get-hierarchy`, `find-game-objects`, or `execute-dynamic-code` before resuming. diff --git a/.claude/skills/uloop-wait-for-debug-break/SKILL.md b/.claude/skills/uloop-wait-for-debug-break/SKILL.md index 97aab8cf5..ab9d4e602 100644 --- a/.claude/skills/uloop-wait-for-debug-break/SKILL.md +++ b/.claude/skills/uloop-wait-for-debug-break/SKILL.md @@ -1,6 +1,6 @@ --- name: uloop-wait-for-debug-break -description: "Use this as the standard frame proof for Unity PlayMode/E2E: pause one representative state-changing input, physics, or UI transition and inspect variables/GameObjects/state like an IDE breakpoint. If local/intermediate values are hard to inspect later, log them just before the marker and read get-logs while paused." +description: "Use this as the standard frame proof for Unity PlayMode/E2E: pause one representative transition like an IDE breakpoint. For frame-local/intermediate values, marker-only proof is incomplete: add focused Debug.Log before the marker and read get-logs while paused." --- ## Quick Check Template @@ -25,15 +25,21 @@ uloop enable-debug-break --id state-transition-applied --timeout-seconds 30 3. Trigger the action with a `simulate-*` command. 4. Run `uloop wait-for-debug-break --id state-transition-applied --timeout-seconds 30`, even if the trigger command already returned `InterruptedByDebugBreak=true`. -5. While Unity is paused, capture focused evidence with `uloop get-logs`, `uloop execute-dynamic-code`, `uloop get-hierarchy`, `uloop find-game-objects`, and one screenshot. -6. Clear the marker with `uloop clear-debug-break --id state-transition-applied` or stop PlayMode before moving on. +5. Before resuming, read the focused log for the same marker id: + +```bash +uloop get-logs --search-text state-transition-applied --max-count 20 +``` + +6. While Unity is still paused, capture any additional evidence with `uloop execute-dynamic-code`, `uloop get-hierarchy`, `uloop find-game-objects`, and one screenshot. +7. Clear the marker with `uloop clear-debug-break --id state-transition-applied` or stop PlayMode before moving on. ## When To Use - Use this as the standard frame proof for state-changing PlayMode/E2E simulated input, physics, or UI transitions. - Pause at least one representative transition per E2E pass, even if durable state, logs, or screenshots can later confirm the final result. - Use this before reaching for `Time.timeScale`, sleeps, repeated polling, or after-the-fact `execute-dynamic-code`; those checks can supplement the paused-frame proof, but they are not substitutes. -- If the value you need is a method local, an intermediate calculation, or a branch reason that `execute-dynamic-code` cannot reach, add a focused `Debug.Log` immediately before the marker and read it with `get-logs` while paused. +- If the value you need is a method local, an intermediate calculation, or a branch reason that `execute-dynamic-code` cannot reach, add a focused `Debug.Log` immediately before the marker and read it with `get-logs` while paused. Do not count the breakpoint check complete until the matching log has been read. - Good pause points include after input is consumed, a command is accepted, a state mutation is committed, an evaluation step resolves, a tracked value changes, a UI/domain state syncs, or a success/failure/end condition is entered. - Treat the pause like a lightweight breakpoint for one important transition: combine nearby debug logs with paused-frame inspection to confirm the variables and component state at that point. - Do not treat `simulate-* Success=true`, generic action logs, sleeps/retries, testing-only counters, or `Time.timeScale` changes as paused-frame proof. diff --git a/Packages/src/Editor/CliOnlyTools~/PausePoint/Skill/SKILL.md b/Packages/src/Editor/CliOnlyTools~/PausePoint/Skill/SKILL.md index 97aab8cf5..ab9d4e602 100644 --- a/Packages/src/Editor/CliOnlyTools~/PausePoint/Skill/SKILL.md +++ b/Packages/src/Editor/CliOnlyTools~/PausePoint/Skill/SKILL.md @@ -1,6 +1,6 @@ --- name: uloop-wait-for-debug-break -description: "Use this as the standard frame proof for Unity PlayMode/E2E: pause one representative state-changing input, physics, or UI transition and inspect variables/GameObjects/state like an IDE breakpoint. If local/intermediate values are hard to inspect later, log them just before the marker and read get-logs while paused." +description: "Use this as the standard frame proof for Unity PlayMode/E2E: pause one representative transition like an IDE breakpoint. For frame-local/intermediate values, marker-only proof is incomplete: add focused Debug.Log before the marker and read get-logs while paused." --- ## Quick Check Template @@ -25,15 +25,21 @@ uloop enable-debug-break --id state-transition-applied --timeout-seconds 30 3. Trigger the action with a `simulate-*` command. 4. Run `uloop wait-for-debug-break --id state-transition-applied --timeout-seconds 30`, even if the trigger command already returned `InterruptedByDebugBreak=true`. -5. While Unity is paused, capture focused evidence with `uloop get-logs`, `uloop execute-dynamic-code`, `uloop get-hierarchy`, `uloop find-game-objects`, and one screenshot. -6. Clear the marker with `uloop clear-debug-break --id state-transition-applied` or stop PlayMode before moving on. +5. Before resuming, read the focused log for the same marker id: + +```bash +uloop get-logs --search-text state-transition-applied --max-count 20 +``` + +6. While Unity is still paused, capture any additional evidence with `uloop execute-dynamic-code`, `uloop get-hierarchy`, `uloop find-game-objects`, and one screenshot. +7. Clear the marker with `uloop clear-debug-break --id state-transition-applied` or stop PlayMode before moving on. ## When To Use - Use this as the standard frame proof for state-changing PlayMode/E2E simulated input, physics, or UI transitions. - Pause at least one representative transition per E2E pass, even if durable state, logs, or screenshots can later confirm the final result. - Use this before reaching for `Time.timeScale`, sleeps, repeated polling, or after-the-fact `execute-dynamic-code`; those checks can supplement the paused-frame proof, but they are not substitutes. -- If the value you need is a method local, an intermediate calculation, or a branch reason that `execute-dynamic-code` cannot reach, add a focused `Debug.Log` immediately before the marker and read it with `get-logs` while paused. +- If the value you need is a method local, an intermediate calculation, or a branch reason that `execute-dynamic-code` cannot reach, add a focused `Debug.Log` immediately before the marker and read it with `get-logs` while paused. Do not count the breakpoint check complete until the matching log has been read. - Good pause points include after input is consumed, a command is accepted, a state mutation is committed, an evaluation step resolves, a tracked value changes, a UI/domain state syncs, or a success/failure/end condition is entered. - Treat the pause like a lightweight breakpoint for one important transition: combine nearby debug logs with paused-frame inspection to confirm the variables and component state at that point. - Do not treat `simulate-* Success=true`, generic action logs, sleeps/retries, testing-only counters, or `Time.timeScale` changes as paused-frame proof. diff --git a/Packages/src/Editor/FirstPartyTools/ExecuteDynamicCode/Skill/SKILL.md b/Packages/src/Editor/FirstPartyTools/ExecuteDynamicCode/Skill/SKILL.md index b494abc5d..49b149a0f 100644 --- a/Packages/src/Editor/FirstPartyTools/ExecuteDynamicCode/Skill/SKILL.md +++ b/Packages/src/Editor/FirstPartyTools/ExecuteDynamicCode/Skill/SKILL.md @@ -1,7 +1,7 @@ --- name: uloop-execute-dynamic-code toolName: execute-dynamic-code -description: "Execute C# with Unity APIs when existing uloop tools cannot inspect or edit enough. Use for reachable scene/component state, scene/prefab/menu automation, and PlayMode checks. It cannot see method locals from an already-running frame; for those, add focused Debug.Log before a debug-break marker and read get-logs while paused." +description: "Execute C# with Unity APIs when existing uloop tools cannot inspect or edit enough. Use for reachable scene/component state, scene/prefab/menu automation, and PlayMode checks. It cannot see method locals from an already-running frame; use focused Debug.Log plus get-logs during a debug-break pause for those." context: fork --- @@ -11,7 +11,7 @@ Execute the following request using `uloop execute-dynamic-code`: $ARGUMENTS For basic selected GameObject discovery or property inspection, use `find-game-objects --search-mode Selected` before this tool. Use this tool after the built-in inspection tools are not enough or when you need to modify Unity state. -This tool can inspect reachable Unity state, such as GameObjects, components, public properties, static values, and method results. It cannot directly read local variables or intermediate calculations inside an already-running method. When those values matter, add a focused `Debug.Log` immediately before `UnityCliLoopDebug.Break("")`, then read `get-logs` while Unity is paused. +This tool can inspect reachable Unity state, such as GameObjects, components, public properties, static values, and method results. It cannot directly read local variables or intermediate calculations inside an already-running method. When those values matter, add a focused `Debug.Log` immediately before `UnityCliLoopDebug.Break("")`, then run `get-logs --search-text ` while Unity is paused. Do not replace that log read with execute-dynamic-code. ## Workflow diff --git a/Packages/src/Editor/FirstPartyTools/GetLogs/Skill/SKILL.md b/Packages/src/Editor/FirstPartyTools/GetLogs/Skill/SKILL.md index 078262e1f..bfb53e585 100644 --- a/Packages/src/Editor/FirstPartyTools/GetLogs/Skill/SKILL.md +++ b/Packages/src/Editor/FirstPartyTools/GetLogs/Skill/SKILL.md @@ -1,14 +1,14 @@ --- name: uloop-get-logs toolName: get-logs -description: "Read current Unity Console entries from a running Editor. Use during bug investigation after compile, tests, PlayMode, dynamic code, or a debug-break pause; especially read focused Debug.Log output for local/intermediate values that execute-dynamic-code cannot inspect." +description: "Read current Unity Console entries from a running Editor. Use during bug investigation after compile, tests, PlayMode, dynamic code, or immediately after wait-for-debug-break; read focused Debug.Log output for frame-local values before resuming." --- # uloop get-logs Retrieve logs from Unity Console. -When a debug-break marker pauses Unity and the value you need is a method local, intermediate calculation, or branch reason, read the focused `Debug.Log` entry added immediately before the marker. Use `--search-text ` when the Console has unrelated entries. +When a debug-break marker pauses Unity and the value you need is a method local, intermediate calculation, or branch reason, read the focused `Debug.Log` entry added immediately before the marker before resuming PlayMode. Use `--search-text ` so the marker and its log are checked as one breakpoint-style proof. ## Usage diff --git a/Packages/src/Editor/FirstPartyTools/SimulateKeyboard/Skill/SKILL.md b/Packages/src/Editor/FirstPartyTools/SimulateKeyboard/Skill/SKILL.md index 57a2d2f51..058ad6997 100644 --- a/Packages/src/Editor/FirstPartyTools/SimulateKeyboard/Skill/SKILL.md +++ b/Packages/src/Editor/FirstPartyTools/SimulateKeyboard/Skill/SKILL.md @@ -1,7 +1,7 @@ --- name: uloop-simulate-keyboard toolName: simulate-keyboard -description: "Simulate keyboard input in PlayMode through Unity Input System. For state-changing PlayMode/E2E input, also use uloop-wait-for-debug-break on at least one representative frame; if local values are hard to inspect later, add focused Debug.Log next to the marker." +description: "Simulate keyboard input in PlayMode through Unity Input System. For state-changing PlayMode/E2E input, also use uloop-wait-for-debug-break; when frame-local values matter, pair the marker with focused Debug.Log and get-logs before resuming." context: fork --- @@ -49,7 +49,7 @@ Use `KeyDown` / `KeyUp` when the scenario intentionally needs a held key. - Use one `UnityCliLoopDebug.Break("")` marker for at least one representative keyboard input that changes runtime state. This applies even when final logs, screenshots, or durable state later show the outcome, because it pauses the exact frame where variables/state can prove input consumption. - Use the marker before slowing time, sleeping, polling, or rewriting runtime code to work around a missed input frame. Treat those checks as supplements, not substitutes. -- If the key handler has local variables, intermediate calculations, or branch reasons that `execute-dynamic-code` cannot inspect after the fact, log just those values with `Debug.Log` immediately before the marker and read them with `get-logs` while Unity is paused. +- If the key handler has local variables, intermediate calculations, or branch reasons that `execute-dynamic-code` cannot inspect after the fact, log just those values with `Debug.Log` immediately before the marker and read them with `get-logs` while Unity is paused. A marker-only check proves the line was reached, not the frame-local values. - Put the marker at a natural state transition after the app consumed the key, such as after a command is accepted, a state mutation is committed, an evaluation step resolves, or a dependent component is updated. Do not place it immediately after sending `simulate-keyboard`. - Treat `simulate-keyboard Success=true`, generic action logs, and final durable counters as useful evidence, but not as paused-frame proof. - If the response has `InterruptedByDebugBreak: true`, Unity is paused for inspection and the tool released its held input bookkeeping. If a `UnityCliLoopDebug.Break` marker caused the pause, `DebugBreakId` and `DebugBreakHitCount` identify it. Use `get-logs`, `get-hierarchy`, `find-game-objects`, or `execute-dynamic-code` before resuming. diff --git a/Packages/src/Editor/FirstPartyTools/SimulateMouseInput/Skill/SKILL.md b/Packages/src/Editor/FirstPartyTools/SimulateMouseInput/Skill/SKILL.md index d1ba1acab..ffb1a54c4 100644 --- a/Packages/src/Editor/FirstPartyTools/SimulateMouseInput/Skill/SKILL.md +++ b/Packages/src/Editor/FirstPartyTools/SimulateMouseInput/Skill/SKILL.md @@ -1,7 +1,7 @@ --- name: uloop-simulate-mouse-input toolName: simulate-mouse-input -description: "Simulate Mouse.current input in PlayMode through Unity Input System. For state-changing PlayMode/E2E mouse input, also use uloop-wait-for-debug-break on at least one representative frame; if local values are hard to inspect later, add focused Debug.Log next to the marker. Use simulate-mouse-ui for UI." +description: "Simulate Mouse.current input in PlayMode through Unity Input System. For state-changing PlayMode/E2E mouse input, also use uloop-wait-for-debug-break; when frame-local values matter, pair the marker with focused Debug.Log and get-logs before resuming. Use simulate-mouse-ui for UI." context: fork --- @@ -53,7 +53,7 @@ uloop simulate-mouse-input --action [options] - Use one `UnityCliLoopDebug.Break("")` marker for at least one representative mouse input that changes runtime state. This applies even when final logs, screenshots, or durable state later show the outcome, because it pauses the exact frame where variables/state can prove input consumption. - Use the marker before slowing time, sleeping, polling, or rewriting runtime code to work around a missed input frame. Treat those checks as supplements, not substitutes. -- If the mouse handler has local variables, intermediate calculations, or branch reasons that `execute-dynamic-code` cannot inspect after the fact, log just those values with `Debug.Log` immediately before the marker and read them with `get-logs` while Unity is paused. +- If the mouse handler has local variables, intermediate calculations, or branch reasons that `execute-dynamic-code` cannot inspect after the fact, log just those values with `Debug.Log` immediately before the marker and read them with `get-logs` while Unity is paused. A marker-only check proves the line was reached, not the frame-local values. - Put the marker at a natural state transition after the app consumed the mouse input, such as after a command is accepted, a state mutation is committed, an evaluation step resolves, a tracked value changes, or a dependent component is updated. Do not place it immediately after sending `simulate-mouse-input`. - Treat `simulate-mouse-input Success=true`, generic action logs, and final durable counters as useful evidence, but not as paused-frame proof. - If the response has `InterruptedByDebugBreak: true`, Unity is paused for inspection and the tool released its held input bookkeeping. If a `UnityCliLoopDebug.Break` marker caused the pause, `DebugBreakId` and `DebugBreakHitCount` identify it. Use `get-logs`, `get-hierarchy`, `find-game-objects`, or `execute-dynamic-code` before resuming. diff --git a/Packages/src/Editor/FirstPartyTools/SimulateMouseUi/Skill/SKILL.md b/Packages/src/Editor/FirstPartyTools/SimulateMouseUi/Skill/SKILL.md index fe476ff57..14b590409 100644 --- a/Packages/src/Editor/FirstPartyTools/SimulateMouseUi/Skill/SKILL.md +++ b/Packages/src/Editor/FirstPartyTools/SimulateMouseUi/Skill/SKILL.md @@ -1,7 +1,7 @@ --- name: uloop-simulate-mouse-ui toolName: simulate-mouse-ui -description: "Simulate PlayMode EventSystem UI mouse actions using screen coordinates. For state-changing PlayMode/E2E UI actions, also use uloop-wait-for-debug-break on at least one representative frame; if local values are hard to inspect later, add focused Debug.Log next to the marker." +description: "Simulate PlayMode EventSystem UI mouse actions using screen coordinates. For state-changing PlayMode/E2E UI actions, also use uloop-wait-for-debug-break; when frame-local values matter, pair the marker with focused Debug.Log and get-logs before resuming." context: fork --- @@ -81,7 +81,7 @@ uloop simulate-mouse-ui --action --x --y [options] - Use one `UnityCliLoopDebug.Break("")` marker for at least one representative UI action that changes runtime state. This applies even when final logs, screenshots, or durable state later show the outcome, because it pauses the exact frame where variables/state can prove input consumption. - Use the marker before slowing time, sleeping, polling, or rewriting runtime code to work around a missed input frame. Treat those checks as supplements, not substitutes. -- If the UI handler has local variables, intermediate calculations, or branch reasons that `execute-dynamic-code` cannot inspect after the fact, log just those values with `Debug.Log` immediately before the marker and read them with `get-logs` while Unity is paused. +- If the UI handler has local variables, intermediate calculations, or branch reasons that `execute-dynamic-code` cannot inspect after the fact, log just those values with `Debug.Log` immediately before the marker and read them with `get-logs` while Unity is paused. A marker-only check proves the line was reached, not the frame-local values. - Put the marker at a natural transition after the app consumed the UI event, such as after a command is accepted, a state mutation is committed, a tracked value changes, a UI/domain state syncs, or a success/failure/end condition is entered. - Treat `simulate-mouse-ui Success=true`, generic action logs, and final durable counters as useful evidence, but not as paused-frame proof. - If a `UnityCliLoopDebug.Break` marker pauses Unity, inspect with `get-logs`, `get-hierarchy`, `find-game-objects`, or `execute-dynamic-code` before resuming. From e87b05cdc9b7c5c6d940d22a14b95a3365105b9c Mon Sep 17 00:00:00 2001 From: hatayama Date: Wed, 10 Jun 2026 10:26:25 +0900 Subject: [PATCH 11/24] Focus debug-break skill description on breakpoint use Keep the trigger description centered on IDE-style frame inspection so agents choose the skill for specific-frame variable and state checks. Leave the Debug.Log workflow details in the skill body instead of the metadata. --- .agents/skills/uloop-wait-for-debug-break/SKILL.md | 2 +- .claude/skills/uloop-wait-for-debug-break/SKILL.md | 2 +- Packages/src/Editor/CliOnlyTools~/PausePoint/Skill/SKILL.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.agents/skills/uloop-wait-for-debug-break/SKILL.md b/.agents/skills/uloop-wait-for-debug-break/SKILL.md index ab9d4e602..e4106e44f 100644 --- a/.agents/skills/uloop-wait-for-debug-break/SKILL.md +++ b/.agents/skills/uloop-wait-for-debug-break/SKILL.md @@ -1,6 +1,6 @@ --- name: uloop-wait-for-debug-break -description: "Use this as the standard frame proof for Unity PlayMode/E2E: pause one representative transition like an IDE breakpoint. For frame-local/intermediate values, marker-only proof is incomplete: add focused Debug.Log before the marker and read get-logs while paused." +description: "Use this like an IDE breakpoint for Unity PlayMode/E2E when you need to pause a specific frame and inspect variables, GameObjects, or runtime state." --- ## Quick Check Template diff --git a/.claude/skills/uloop-wait-for-debug-break/SKILL.md b/.claude/skills/uloop-wait-for-debug-break/SKILL.md index ab9d4e602..e4106e44f 100644 --- a/.claude/skills/uloop-wait-for-debug-break/SKILL.md +++ b/.claude/skills/uloop-wait-for-debug-break/SKILL.md @@ -1,6 +1,6 @@ --- name: uloop-wait-for-debug-break -description: "Use this as the standard frame proof for Unity PlayMode/E2E: pause one representative transition like an IDE breakpoint. For frame-local/intermediate values, marker-only proof is incomplete: add focused Debug.Log before the marker and read get-logs while paused." +description: "Use this like an IDE breakpoint for Unity PlayMode/E2E when you need to pause a specific frame and inspect variables, GameObjects, or runtime state." --- ## Quick Check Template diff --git a/Packages/src/Editor/CliOnlyTools~/PausePoint/Skill/SKILL.md b/Packages/src/Editor/CliOnlyTools~/PausePoint/Skill/SKILL.md index ab9d4e602..e4106e44f 100644 --- a/Packages/src/Editor/CliOnlyTools~/PausePoint/Skill/SKILL.md +++ b/Packages/src/Editor/CliOnlyTools~/PausePoint/Skill/SKILL.md @@ -1,6 +1,6 @@ --- name: uloop-wait-for-debug-break -description: "Use this as the standard frame proof for Unity PlayMode/E2E: pause one representative transition like an IDE breakpoint. For frame-local/intermediate values, marker-only proof is incomplete: add focused Debug.Log before the marker and read get-logs while paused." +description: "Use this like an IDE breakpoint for Unity PlayMode/E2E when you need to pause a specific frame and inspect variables, GameObjects, or runtime state." --- ## Quick Check Template From 6e26f833eb6a505d8aa7f69afc21fc202c237739 Mon Sep 17 00:00:00 2001 From: hatayama Date: Wed, 10 Jun 2026 11:33:05 +0900 Subject: [PATCH 12/24] Clarify optional input skill evidence guidance Make the keyboard and mouse input workflows clear that debug-break checks and screenshots are optional evidence choices. Spell out the concrete uloop wait-for-debug-break and get-logs commands for method-local inspection guidance. --- .agents/skills/uloop-execute-dynamic-code/SKILL.md | 2 +- .agents/skills/uloop-simulate-keyboard/SKILL.md | 10 +++++----- .agents/skills/uloop-simulate-mouse-input/SKILL.md | 12 ++++++------ .claude/skills/uloop-execute-dynamic-code/SKILL.md | 2 +- .claude/skills/uloop-simulate-keyboard/SKILL.md | 10 +++++----- .claude/skills/uloop-simulate-mouse-input/SKILL.md | 12 ++++++------ .../ExecuteDynamicCode/Skill/SKILL.md | 2 +- .../FirstPartyTools/SimulateKeyboard/Skill/SKILL.md | 10 +++++----- .../SimulateMouseInput/Skill/SKILL.md | 12 ++++++------ 9 files changed, 36 insertions(+), 36 deletions(-) diff --git a/.agents/skills/uloop-execute-dynamic-code/SKILL.md b/.agents/skills/uloop-execute-dynamic-code/SKILL.md index 49b149a0f..d89d61512 100644 --- a/.agents/skills/uloop-execute-dynamic-code/SKILL.md +++ b/.agents/skills/uloop-execute-dynamic-code/SKILL.md @@ -1,7 +1,7 @@ --- name: uloop-execute-dynamic-code toolName: execute-dynamic-code -description: "Execute C# with Unity APIs when existing uloop tools cannot inspect or edit enough. Use for reachable scene/component state, scene/prefab/menu automation, and PlayMode checks. It cannot see method locals from an already-running frame; use focused Debug.Log plus get-logs during a debug-break pause for those." +description: "Execute C# with Unity APIs when existing uloop tools cannot inspect or edit enough. Use for reachable scene/component state, scene/prefab/menu automation, and PlayMode checks. It cannot see method locals from an already-running frame; use `uloop wait-for-debug-break` with focused Debug.Log and `uloop get-logs` for those." context: fork --- diff --git a/.agents/skills/uloop-simulate-keyboard/SKILL.md b/.agents/skills/uloop-simulate-keyboard/SKILL.md index 058ad6997..d865b0adf 100644 --- a/.agents/skills/uloop-simulate-keyboard/SKILL.md +++ b/.agents/skills/uloop-simulate-keyboard/SKILL.md @@ -12,10 +12,10 @@ Simulate keyboard input on Unity PlayMode: $ARGUMENTS ## Workflow 1. Ensure Unity is in PlayMode (use `uloop control-play-mode --action Play` if not) -2. If this is a state-changing E2E check, pick one representative frame for paused variable/state proof before relying on logs, screenshots, or durable state -3. For that representative transition, place and enable a `UnityCliLoopDebug.Break("")` marker, then run the input and inspect while Unity is paused -4. Execute any remaining `uloop simulate-keyboard` commands -5. Take a screenshot to verify the visible result: `uloop screenshot --capture-mode rendering` +2. If exact-frame proof would reduce uncertainty for a state-changing E2E check, pick one representative frame for paused variable/state inspection +3. For that optional representative transition, place and enable a `UnityCliLoopDebug.Break("")` marker, then run the input and inspect while Unity is paused +4. Execute the needed `uloop simulate-keyboard` commands +5. If visible output matters, capture a screenshot: `uloop screenshot --capture-mode rendering` 6. Report what happened ## Tool Reference @@ -47,7 +47,7 @@ Use `KeyDown` / `KeyUp` when the scenario intentionally needs a held key. ### Debug Break verification -- Use one `UnityCliLoopDebug.Break("")` marker for at least one representative keyboard input that changes runtime state. This applies even when final logs, screenshots, or durable state later show the outcome, because it pauses the exact frame where variables/state can prove input consumption. +- Consider one `UnityCliLoopDebug.Break("")` marker when a representative keyboard input changes runtime state and exact-frame evidence would reduce uncertainty. Final logs, screenshots, or durable state may be enough for simpler checks. - Use the marker before slowing time, sleeping, polling, or rewriting runtime code to work around a missed input frame. Treat those checks as supplements, not substitutes. - If the key handler has local variables, intermediate calculations, or branch reasons that `execute-dynamic-code` cannot inspect after the fact, log just those values with `Debug.Log` immediately before the marker and read them with `get-logs` while Unity is paused. A marker-only check proves the line was reached, not the frame-local values. - Put the marker at a natural state transition after the app consumed the key, such as after a command is accepted, a state mutation is committed, an evaluation step resolves, or a dependent component is updated. Do not place it immediately after sending `simulate-keyboard`. diff --git a/.agents/skills/uloop-simulate-mouse-input/SKILL.md b/.agents/skills/uloop-simulate-mouse-input/SKILL.md index ffb1a54c4..a2c16e0a3 100644 --- a/.agents/skills/uloop-simulate-mouse-input/SKILL.md +++ b/.agents/skills/uloop-simulate-mouse-input/SKILL.md @@ -7,16 +7,16 @@ context: fork # Task -Simulate mouse input via Input System in Unity PlayMode: $ARGUMENTS +Simulate mouse input via Input System in Unity PlayMode. ## Workflow 1. Ensure Unity is in PlayMode (use `uloop control-play-mode --action Play` if not) 2. For Click/LongPress: determine the target screen position (use `uloop screenshot` to find coordinates) -3. If this is a state-changing E2E check, pick one representative frame for paused variable/state proof before relying on logs, screenshots, or durable state -4. For that representative transition, place and enable a `UnityCliLoopDebug.Break("")` marker, then run the input and inspect while Unity is paused -5. Execute any remaining `uloop simulate-mouse-input` commands -6. Take a screenshot to verify the visible result: `uloop screenshot --capture-mode rendering` +3. If exact-frame proof would reduce uncertainty for a state-changing E2E check, pick one representative frame for paused variable/state inspection +4. For that optional representative transition, place and enable a `UnityCliLoopDebug.Break("")` marker, then run the input and inspect while Unity is paused +5. Execute the needed `uloop simulate-mouse-input` commands +6. If visible output matters, capture a screenshot: `uloop screenshot --capture-mode rendering` 7. Report what happened ## Tool Reference @@ -51,7 +51,7 @@ uloop simulate-mouse-input --action [options] ### Debug Break verification -- Use one `UnityCliLoopDebug.Break("")` marker for at least one representative mouse input that changes runtime state. This applies even when final logs, screenshots, or durable state later show the outcome, because it pauses the exact frame where variables/state can prove input consumption. +- Consider one `UnityCliLoopDebug.Break("")` marker when a representative mouse input changes runtime state and exact-frame evidence would reduce uncertainty. Final logs, screenshots, or durable state may be enough for simpler checks. - Use the marker before slowing time, sleeping, polling, or rewriting runtime code to work around a missed input frame. Treat those checks as supplements, not substitutes. - If the mouse handler has local variables, intermediate calculations, or branch reasons that `execute-dynamic-code` cannot inspect after the fact, log just those values with `Debug.Log` immediately before the marker and read them with `get-logs` while Unity is paused. A marker-only check proves the line was reached, not the frame-local values. - Put the marker at a natural state transition after the app consumed the mouse input, such as after a command is accepted, a state mutation is committed, an evaluation step resolves, a tracked value changes, or a dependent component is updated. Do not place it immediately after sending `simulate-mouse-input`. diff --git a/.claude/skills/uloop-execute-dynamic-code/SKILL.md b/.claude/skills/uloop-execute-dynamic-code/SKILL.md index 49b149a0f..d89d61512 100644 --- a/.claude/skills/uloop-execute-dynamic-code/SKILL.md +++ b/.claude/skills/uloop-execute-dynamic-code/SKILL.md @@ -1,7 +1,7 @@ --- name: uloop-execute-dynamic-code toolName: execute-dynamic-code -description: "Execute C# with Unity APIs when existing uloop tools cannot inspect or edit enough. Use for reachable scene/component state, scene/prefab/menu automation, and PlayMode checks. It cannot see method locals from an already-running frame; use focused Debug.Log plus get-logs during a debug-break pause for those." +description: "Execute C# with Unity APIs when existing uloop tools cannot inspect or edit enough. Use for reachable scene/component state, scene/prefab/menu automation, and PlayMode checks. It cannot see method locals from an already-running frame; use `uloop wait-for-debug-break` with focused Debug.Log and `uloop get-logs` for those." context: fork --- diff --git a/.claude/skills/uloop-simulate-keyboard/SKILL.md b/.claude/skills/uloop-simulate-keyboard/SKILL.md index 058ad6997..d865b0adf 100644 --- a/.claude/skills/uloop-simulate-keyboard/SKILL.md +++ b/.claude/skills/uloop-simulate-keyboard/SKILL.md @@ -12,10 +12,10 @@ Simulate keyboard input on Unity PlayMode: $ARGUMENTS ## Workflow 1. Ensure Unity is in PlayMode (use `uloop control-play-mode --action Play` if not) -2. If this is a state-changing E2E check, pick one representative frame for paused variable/state proof before relying on logs, screenshots, or durable state -3. For that representative transition, place and enable a `UnityCliLoopDebug.Break("")` marker, then run the input and inspect while Unity is paused -4. Execute any remaining `uloop simulate-keyboard` commands -5. Take a screenshot to verify the visible result: `uloop screenshot --capture-mode rendering` +2. If exact-frame proof would reduce uncertainty for a state-changing E2E check, pick one representative frame for paused variable/state inspection +3. For that optional representative transition, place and enable a `UnityCliLoopDebug.Break("")` marker, then run the input and inspect while Unity is paused +4. Execute the needed `uloop simulate-keyboard` commands +5. If visible output matters, capture a screenshot: `uloop screenshot --capture-mode rendering` 6. Report what happened ## Tool Reference @@ -47,7 +47,7 @@ Use `KeyDown` / `KeyUp` when the scenario intentionally needs a held key. ### Debug Break verification -- Use one `UnityCliLoopDebug.Break("")` marker for at least one representative keyboard input that changes runtime state. This applies even when final logs, screenshots, or durable state later show the outcome, because it pauses the exact frame where variables/state can prove input consumption. +- Consider one `UnityCliLoopDebug.Break("")` marker when a representative keyboard input changes runtime state and exact-frame evidence would reduce uncertainty. Final logs, screenshots, or durable state may be enough for simpler checks. - Use the marker before slowing time, sleeping, polling, or rewriting runtime code to work around a missed input frame. Treat those checks as supplements, not substitutes. - If the key handler has local variables, intermediate calculations, or branch reasons that `execute-dynamic-code` cannot inspect after the fact, log just those values with `Debug.Log` immediately before the marker and read them with `get-logs` while Unity is paused. A marker-only check proves the line was reached, not the frame-local values. - Put the marker at a natural state transition after the app consumed the key, such as after a command is accepted, a state mutation is committed, an evaluation step resolves, or a dependent component is updated. Do not place it immediately after sending `simulate-keyboard`. diff --git a/.claude/skills/uloop-simulate-mouse-input/SKILL.md b/.claude/skills/uloop-simulate-mouse-input/SKILL.md index ffb1a54c4..a2c16e0a3 100644 --- a/.claude/skills/uloop-simulate-mouse-input/SKILL.md +++ b/.claude/skills/uloop-simulate-mouse-input/SKILL.md @@ -7,16 +7,16 @@ context: fork # Task -Simulate mouse input via Input System in Unity PlayMode: $ARGUMENTS +Simulate mouse input via Input System in Unity PlayMode. ## Workflow 1. Ensure Unity is in PlayMode (use `uloop control-play-mode --action Play` if not) 2. For Click/LongPress: determine the target screen position (use `uloop screenshot` to find coordinates) -3. If this is a state-changing E2E check, pick one representative frame for paused variable/state proof before relying on logs, screenshots, or durable state -4. For that representative transition, place and enable a `UnityCliLoopDebug.Break("")` marker, then run the input and inspect while Unity is paused -5. Execute any remaining `uloop simulate-mouse-input` commands -6. Take a screenshot to verify the visible result: `uloop screenshot --capture-mode rendering` +3. If exact-frame proof would reduce uncertainty for a state-changing E2E check, pick one representative frame for paused variable/state inspection +4. For that optional representative transition, place and enable a `UnityCliLoopDebug.Break("")` marker, then run the input and inspect while Unity is paused +5. Execute the needed `uloop simulate-mouse-input` commands +6. If visible output matters, capture a screenshot: `uloop screenshot --capture-mode rendering` 7. Report what happened ## Tool Reference @@ -51,7 +51,7 @@ uloop simulate-mouse-input --action [options] ### Debug Break verification -- Use one `UnityCliLoopDebug.Break("")` marker for at least one representative mouse input that changes runtime state. This applies even when final logs, screenshots, or durable state later show the outcome, because it pauses the exact frame where variables/state can prove input consumption. +- Consider one `UnityCliLoopDebug.Break("")` marker when a representative mouse input changes runtime state and exact-frame evidence would reduce uncertainty. Final logs, screenshots, or durable state may be enough for simpler checks. - Use the marker before slowing time, sleeping, polling, or rewriting runtime code to work around a missed input frame. Treat those checks as supplements, not substitutes. - If the mouse handler has local variables, intermediate calculations, or branch reasons that `execute-dynamic-code` cannot inspect after the fact, log just those values with `Debug.Log` immediately before the marker and read them with `get-logs` while Unity is paused. A marker-only check proves the line was reached, not the frame-local values. - Put the marker at a natural state transition after the app consumed the mouse input, such as after a command is accepted, a state mutation is committed, an evaluation step resolves, a tracked value changes, or a dependent component is updated. Do not place it immediately after sending `simulate-mouse-input`. diff --git a/Packages/src/Editor/FirstPartyTools/ExecuteDynamicCode/Skill/SKILL.md b/Packages/src/Editor/FirstPartyTools/ExecuteDynamicCode/Skill/SKILL.md index 49b149a0f..d89d61512 100644 --- a/Packages/src/Editor/FirstPartyTools/ExecuteDynamicCode/Skill/SKILL.md +++ b/Packages/src/Editor/FirstPartyTools/ExecuteDynamicCode/Skill/SKILL.md @@ -1,7 +1,7 @@ --- name: uloop-execute-dynamic-code toolName: execute-dynamic-code -description: "Execute C# with Unity APIs when existing uloop tools cannot inspect or edit enough. Use for reachable scene/component state, scene/prefab/menu automation, and PlayMode checks. It cannot see method locals from an already-running frame; use focused Debug.Log plus get-logs during a debug-break pause for those." +description: "Execute C# with Unity APIs when existing uloop tools cannot inspect or edit enough. Use for reachable scene/component state, scene/prefab/menu automation, and PlayMode checks. It cannot see method locals from an already-running frame; use `uloop wait-for-debug-break` with focused Debug.Log and `uloop get-logs` for those." context: fork --- diff --git a/Packages/src/Editor/FirstPartyTools/SimulateKeyboard/Skill/SKILL.md b/Packages/src/Editor/FirstPartyTools/SimulateKeyboard/Skill/SKILL.md index 058ad6997..d865b0adf 100644 --- a/Packages/src/Editor/FirstPartyTools/SimulateKeyboard/Skill/SKILL.md +++ b/Packages/src/Editor/FirstPartyTools/SimulateKeyboard/Skill/SKILL.md @@ -12,10 +12,10 @@ Simulate keyboard input on Unity PlayMode: $ARGUMENTS ## Workflow 1. Ensure Unity is in PlayMode (use `uloop control-play-mode --action Play` if not) -2. If this is a state-changing E2E check, pick one representative frame for paused variable/state proof before relying on logs, screenshots, or durable state -3. For that representative transition, place and enable a `UnityCliLoopDebug.Break("")` marker, then run the input and inspect while Unity is paused -4. Execute any remaining `uloop simulate-keyboard` commands -5. Take a screenshot to verify the visible result: `uloop screenshot --capture-mode rendering` +2. If exact-frame proof would reduce uncertainty for a state-changing E2E check, pick one representative frame for paused variable/state inspection +3. For that optional representative transition, place and enable a `UnityCliLoopDebug.Break("")` marker, then run the input and inspect while Unity is paused +4. Execute the needed `uloop simulate-keyboard` commands +5. If visible output matters, capture a screenshot: `uloop screenshot --capture-mode rendering` 6. Report what happened ## Tool Reference @@ -47,7 +47,7 @@ Use `KeyDown` / `KeyUp` when the scenario intentionally needs a held key. ### Debug Break verification -- Use one `UnityCliLoopDebug.Break("")` marker for at least one representative keyboard input that changes runtime state. This applies even when final logs, screenshots, or durable state later show the outcome, because it pauses the exact frame where variables/state can prove input consumption. +- Consider one `UnityCliLoopDebug.Break("")` marker when a representative keyboard input changes runtime state and exact-frame evidence would reduce uncertainty. Final logs, screenshots, or durable state may be enough for simpler checks. - Use the marker before slowing time, sleeping, polling, or rewriting runtime code to work around a missed input frame. Treat those checks as supplements, not substitutes. - If the key handler has local variables, intermediate calculations, or branch reasons that `execute-dynamic-code` cannot inspect after the fact, log just those values with `Debug.Log` immediately before the marker and read them with `get-logs` while Unity is paused. A marker-only check proves the line was reached, not the frame-local values. - Put the marker at a natural state transition after the app consumed the key, such as after a command is accepted, a state mutation is committed, an evaluation step resolves, or a dependent component is updated. Do not place it immediately after sending `simulate-keyboard`. diff --git a/Packages/src/Editor/FirstPartyTools/SimulateMouseInput/Skill/SKILL.md b/Packages/src/Editor/FirstPartyTools/SimulateMouseInput/Skill/SKILL.md index ffb1a54c4..a2c16e0a3 100644 --- a/Packages/src/Editor/FirstPartyTools/SimulateMouseInput/Skill/SKILL.md +++ b/Packages/src/Editor/FirstPartyTools/SimulateMouseInput/Skill/SKILL.md @@ -7,16 +7,16 @@ context: fork # Task -Simulate mouse input via Input System in Unity PlayMode: $ARGUMENTS +Simulate mouse input via Input System in Unity PlayMode. ## Workflow 1. Ensure Unity is in PlayMode (use `uloop control-play-mode --action Play` if not) 2. For Click/LongPress: determine the target screen position (use `uloop screenshot` to find coordinates) -3. If this is a state-changing E2E check, pick one representative frame for paused variable/state proof before relying on logs, screenshots, or durable state -4. For that representative transition, place and enable a `UnityCliLoopDebug.Break("")` marker, then run the input and inspect while Unity is paused -5. Execute any remaining `uloop simulate-mouse-input` commands -6. Take a screenshot to verify the visible result: `uloop screenshot --capture-mode rendering` +3. If exact-frame proof would reduce uncertainty for a state-changing E2E check, pick one representative frame for paused variable/state inspection +4. For that optional representative transition, place and enable a `UnityCliLoopDebug.Break("")` marker, then run the input and inspect while Unity is paused +5. Execute the needed `uloop simulate-mouse-input` commands +6. If visible output matters, capture a screenshot: `uloop screenshot --capture-mode rendering` 7. Report what happened ## Tool Reference @@ -51,7 +51,7 @@ uloop simulate-mouse-input --action [options] ### Debug Break verification -- Use one `UnityCliLoopDebug.Break("")` marker for at least one representative mouse input that changes runtime state. This applies even when final logs, screenshots, or durable state later show the outcome, because it pauses the exact frame where variables/state can prove input consumption. +- Consider one `UnityCliLoopDebug.Break("")` marker when a representative mouse input changes runtime state and exact-frame evidence would reduce uncertainty. Final logs, screenshots, or durable state may be enough for simpler checks. - Use the marker before slowing time, sleeping, polling, or rewriting runtime code to work around a missed input frame. Treat those checks as supplements, not substitutes. - If the mouse handler has local variables, intermediate calculations, or branch reasons that `execute-dynamic-code` cannot inspect after the fact, log just those values with `Debug.Log` immediately before the marker and read them with `get-logs` while Unity is paused. A marker-only check proves the line was reached, not the frame-local values. - Put the marker at a natural state transition after the app consumed the mouse input, such as after a command is accepted, a state mutation is committed, an evaluation step resolves, a tracked value changes, or a dependent component is updated. Do not place it immediately after sending `simulate-mouse-input`. From c4576e911c1f129c1a46a720c71f6f91a707f760 Mon Sep 17 00:00:00 2001 From: hatayama Date: Wed, 10 Jun 2026 12:12:04 +0900 Subject: [PATCH 13/24] Open the sample scene after refreshing game skills Launches each neighboring Unity project, waits for uloop to respond, and opens Assets/Scenes/SampleScene.unity so the refreshed projects land in the expected scene after Library cleanup. --- scripts/refresh-neighbor-game-skills.sh | 64 ++++++++++++++++++++++--- 1 file changed, 57 insertions(+), 7 deletions(-) diff --git a/scripts/refresh-neighbor-game-skills.sh b/scripts/refresh-neighbor-game-skills.sh index 2a9e5c754..29e3705e5 100755 --- a/scripts/refresh-neighbor-game-skills.sh +++ b/scripts/refresh-neighbor-game-skills.sh @@ -3,11 +3,13 @@ # This is not an installed agent skill or a runtime command. It exists to support local # uloop development by resetting each target Git repository, quitting each target # Unity Editor, regenerating Claude/Agents skill copies, committing those generated -# files locally, removing Library after Unity has stopped, and relaunching each project. +# files locally, removing Library after Unity has stopped, relaunching each project, +# and opening the sample scene. set -eu skill_name="refresh-neighbor-game-skills" expected_project_count=3 +sample_scene_path="Assets/Scenes/SampleScene.unity" dry_run=0 uloop_root="${ULOOP_ROOT:-}" project_file="$(mktemp "${TMPDIR:-/tmp}/${skill_name}.projects.XXXXXX")" @@ -37,6 +39,7 @@ Workflow for each target Unity project: 3. Commit generated skill changes without pushing 4. Remove Library 5. Launch Unity with launch-unity + 6. Open Assets/Scenes/SampleScene.unity USAGE } @@ -339,6 +342,48 @@ launch_project() { run launch-unity "$project" } +wait_for_unity_ready() { + project=$1 + timeout_seconds=$2 + elapsed_seconds=0 + + if [ "$dry_run" -eq 1 ]; then + log "[dry-run] wait until Unity responds to uloop for $project" + return 0 + fi + + while [ "$elapsed_seconds" -lt "$timeout_seconds" ]; do + if "$uloop_bin" --project-path "$project" get-logs --max-count 1 >/dev/null 2>&1; then + return 0 + fi + + sleep 2 + elapsed_seconds=$((elapsed_seconds + 2)) + done + + fail "Unity did not become ready after launch: $project" +} + +open_sample_scene() { + project=$1 + [ -f "$project/$sample_scene_path" ] || fail "sample scene not found: $project/$sample_scene_path" + + wait_for_unity_ready "$project" 300 + code=" +using UnityEditor.SceneManagement; +using UnityEngine.SceneManagement; + +string scenePath = \"$sample_scene_path\"; +if (SceneManager.GetActiveScene().path != scenePath) +{ + EditorSceneManager.OpenScene(scenePath, OpenSceneMode.Single); +} + +return SceneManager.GetActiveScene().path; +" + run "$uloop_bin" --project-path "$project" execute-dynamic-code --code "$code" +} + parse_args "$@" resolve_uloop_root discover_projects @@ -353,7 +398,7 @@ while IFS= read -r project; do log " $project" done <"$project_file" -log "Phase 0/5: reset Git state" +log "Phase 0/6: reset Git state" while IFS= read -r project; do reset_git_state "$project" done <"$project_file" @@ -362,7 +407,7 @@ while IFS= read -r project; do assert_clean_skill_dirs "$project" done <"$project_file" -log "Phase 1/5: quit Unity" +log "Phase 1/6: quit Unity" while IFS= read -r project; do quit_unity "$project" done <"$project_file" @@ -371,24 +416,29 @@ while IFS= read -r project; do assert_unity_stopped "$project" done <"$project_file" -log "Phase 2/5: install skills" +log "Phase 2/6: install skills" while IFS= read -r project; do install_skills "$project" done <"$project_file" -log "Phase 3/5: commit generated skills" +log "Phase 3/6: commit generated skills" while IFS= read -r project; do commit_generated_skills "$project" done <"$project_file" -log "Phase 4/5: remove Library" +log "Phase 4/6: remove Library" while IFS= read -r project; do remove_library "$project" done <"$project_file" -log "Phase 5/5: launch Unity" +log "Phase 5/6: launch Unity" while IFS= read -r project; do launch_project "$project" done <"$project_file" +log "Phase 6/6: open sample scene" +while IFS= read -r project; do + open_sample_scene "$project" +done <"$project_file" + log "Done." From a04591933549c3cbe811f9ecc7c979ea2a93988d Mon Sep 17 00:00:00 2001 From: hatayama Date: Wed, 10 Jun 2026 12:21:26 +0900 Subject: [PATCH 14/24] Trim get-logs skill trigger description Keep the focused Debug.Log guidance in the skill body while removing duplicate frame-local inspection wording from the frontmatter description. --- .agents/skills/uloop-get-logs/SKILL.md | 2 +- .claude/skills/uloop-get-logs/SKILL.md | 2 +- Packages/src/Editor/FirstPartyTools/GetLogs/Skill/SKILL.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.agents/skills/uloop-get-logs/SKILL.md b/.agents/skills/uloop-get-logs/SKILL.md index bfb53e585..9b24b4094 100644 --- a/.agents/skills/uloop-get-logs/SKILL.md +++ b/.agents/skills/uloop-get-logs/SKILL.md @@ -1,7 +1,7 @@ --- name: uloop-get-logs toolName: get-logs -description: "Read current Unity Console entries from a running Editor. Use during bug investigation after compile, tests, PlayMode, dynamic code, or immediately after wait-for-debug-break; read focused Debug.Log output for frame-local values before resuming." +description: "Read current Unity Console entries from a running Editor. Use during bug investigation after compile, tests, PlayMode, dynamic code, or immediately after `uloop wait-for-debug-break`." --- # uloop get-logs diff --git a/.claude/skills/uloop-get-logs/SKILL.md b/.claude/skills/uloop-get-logs/SKILL.md index bfb53e585..9b24b4094 100644 --- a/.claude/skills/uloop-get-logs/SKILL.md +++ b/.claude/skills/uloop-get-logs/SKILL.md @@ -1,7 +1,7 @@ --- name: uloop-get-logs toolName: get-logs -description: "Read current Unity Console entries from a running Editor. Use during bug investigation after compile, tests, PlayMode, dynamic code, or immediately after wait-for-debug-break; read focused Debug.Log output for frame-local values before resuming." +description: "Read current Unity Console entries from a running Editor. Use during bug investigation after compile, tests, PlayMode, dynamic code, or immediately after `uloop wait-for-debug-break`." --- # uloop get-logs diff --git a/Packages/src/Editor/FirstPartyTools/GetLogs/Skill/SKILL.md b/Packages/src/Editor/FirstPartyTools/GetLogs/Skill/SKILL.md index bfb53e585..9b24b4094 100644 --- a/Packages/src/Editor/FirstPartyTools/GetLogs/Skill/SKILL.md +++ b/Packages/src/Editor/FirstPartyTools/GetLogs/Skill/SKILL.md @@ -1,7 +1,7 @@ --- name: uloop-get-logs toolName: get-logs -description: "Read current Unity Console entries from a running Editor. Use during bug investigation after compile, tests, PlayMode, dynamic code, or immediately after wait-for-debug-break; read focused Debug.Log output for frame-local values before resuming." +description: "Read current Unity Console entries from a running Editor. Use during bug investigation after compile, tests, PlayMode, dynamic code, or immediately after `uloop wait-for-debug-break`." --- # uloop get-logs From 4295e2811cde483c16fc8f024f20a0668cdded76 Mon Sep 17 00:00:00 2001 From: hatayama Date: Wed, 10 Jun 2026 12:23:58 +0900 Subject: [PATCH 15/24] update --- .../Editor/FirstPartyTools/ExecuteDynamicCode/Skill/SKILL.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Packages/src/Editor/FirstPartyTools/ExecuteDynamicCode/Skill/SKILL.md b/Packages/src/Editor/FirstPartyTools/ExecuteDynamicCode/Skill/SKILL.md index d89d61512..af6c40f69 100644 --- a/Packages/src/Editor/FirstPartyTools/ExecuteDynamicCode/Skill/SKILL.md +++ b/Packages/src/Editor/FirstPartyTools/ExecuteDynamicCode/Skill/SKILL.md @@ -1,7 +1,7 @@ --- name: uloop-execute-dynamic-code toolName: execute-dynamic-code -description: "Execute C# with Unity APIs when existing uloop tools cannot inspect or edit enough. Use for reachable scene/component state, scene/prefab/menu automation, and PlayMode checks. It cannot see method locals from an already-running frame; use `uloop wait-for-debug-break` with focused Debug.Log and `uloop get-logs` for those." +description: "Execute C# with Unity APIs when existing uloop tools cannot inspect or edit enough. Use for reachable scene/component state, scene/prefab/menu automation, and PlayMode checks" context: fork --- From 309218d6fda185303a45090a77eb7b35ca4de2a9 Mon Sep 17 00:00:00 2001 From: hatayama Date: Wed, 10 Jun 2026 16:28:57 +0900 Subject: [PATCH 16/24] Remove generated skill copies from PR Restore installed skill copies to the base branch so this PR only carries source skill and helper-script changes. Generated skill directories can be refreshed separately later. --- .../uloop-execute-dynamic-code/SKILL.md | 4 +- .agents/skills/uloop-get-logs/SKILL.md | 4 +- .../skills/uloop-simulate-keyboard/SKILL.md | 32 +++++------ .../uloop-simulate-mouse-input/SKILL.md | 48 ++++++++-------- .../skills/uloop-simulate-mouse-ui/SKILL.md | 21 ++----- .../uloop-wait-for-debug-break/SKILL.md | 55 ++++++++----------- .../uloop-execute-dynamic-code/SKILL.md | 4 +- .claude/skills/uloop-get-logs/SKILL.md | 4 +- .../skills/uloop-simulate-keyboard/SKILL.md | 32 +++++------ .../uloop-simulate-mouse-input/SKILL.md | 48 ++++++++-------- .../skills/uloop-simulate-mouse-ui/SKILL.md | 21 ++----- .../uloop-wait-for-debug-break/SKILL.md | 55 ++++++++----------- 12 files changed, 132 insertions(+), 196 deletions(-) diff --git a/.agents/skills/uloop-execute-dynamic-code/SKILL.md b/.agents/skills/uloop-execute-dynamic-code/SKILL.md index d89d61512..d29fcdc9c 100644 --- a/.agents/skills/uloop-execute-dynamic-code/SKILL.md +++ b/.agents/skills/uloop-execute-dynamic-code/SKILL.md @@ -1,7 +1,7 @@ --- name: uloop-execute-dynamic-code toolName: execute-dynamic-code -description: "Execute C# with Unity APIs when existing uloop tools cannot inspect or edit enough. Use for reachable scene/component state, scene/prefab/menu automation, and PlayMode checks. It cannot see method locals from an already-running frame; use `uloop wait-for-debug-break` with focused Debug.Log and `uloop get-logs` for those." +description: "Execute C# with Unity APIs when existing uloop tools cannot inspect or edit enough. Use for scene, prefab, SerializedObject, AssetDatabase refresh/.meta generation, menu, or PlayMode automation." context: fork --- @@ -11,8 +11,6 @@ Execute the following request using `uloop execute-dynamic-code`: $ARGUMENTS For basic selected GameObject discovery or property inspection, use `find-game-objects --search-mode Selected` before this tool. Use this tool after the built-in inspection tools are not enough or when you need to modify Unity state. -This tool can inspect reachable Unity state, such as GameObjects, components, public properties, static values, and method results. It cannot directly read local variables or intermediate calculations inside an already-running method. When those values matter, add a focused `Debug.Log` immediately before `UnityCliLoopDebug.Break("")`, then run `get-logs --search-text ` while Unity is paused. Do not replace that log read with execute-dynamic-code. - ## Workflow 1. Read the relevant reference file(s) from the Code Examples section below diff --git a/.agents/skills/uloop-get-logs/SKILL.md b/.agents/skills/uloop-get-logs/SKILL.md index 9b24b4094..a74e55532 100644 --- a/.agents/skills/uloop-get-logs/SKILL.md +++ b/.agents/skills/uloop-get-logs/SKILL.md @@ -1,15 +1,13 @@ --- name: uloop-get-logs toolName: get-logs -description: "Read current Unity Console entries from a running Editor. Use during bug investigation after compile, tests, PlayMode, dynamic code, or immediately after `uloop wait-for-debug-break`." +description: "Read current Unity Console entries from a running Editor. Use during bug investigation after compile, tests, PlayMode, or dynamic code to inspect logs, warnings, errors, and stack traces." --- # uloop get-logs Retrieve logs from Unity Console. -When a debug-break marker pauses Unity and the value you need is a method local, intermediate calculation, or branch reason, read the focused `Debug.Log` entry added immediately before the marker before resuming PlayMode. Use `--search-text ` so the marker and its log are checked as one breakpoint-style proof. - ## Usage ```bash diff --git a/.agents/skills/uloop-simulate-keyboard/SKILL.md b/.agents/skills/uloop-simulate-keyboard/SKILL.md index d865b0adf..fc6596887 100644 --- a/.agents/skills/uloop-simulate-keyboard/SKILL.md +++ b/.agents/skills/uloop-simulate-keyboard/SKILL.md @@ -1,7 +1,7 @@ --- name: uloop-simulate-keyboard toolName: simulate-keyboard -description: "Simulate keyboard input in PlayMode through Unity Input System. For state-changing PlayMode/E2E input, also use uloop-wait-for-debug-break; when frame-local values matter, pair the marker with focused Debug.Log and get-logs before resuming." +description: "Simulate keyboard input in PlayMode through Unity Input System. Use for key presses, holds, releases, and game controls such as WASD or Space." context: fork --- @@ -12,11 +12,10 @@ Simulate keyboard input on Unity PlayMode: $ARGUMENTS ## Workflow 1. Ensure Unity is in PlayMode (use `uloop control-play-mode --action Play` if not) -2. If exact-frame proof would reduce uncertainty for a state-changing E2E check, pick one representative frame for paused variable/state inspection -3. For that optional representative transition, place and enable a `UnityCliLoopDebug.Break("")` marker, then run the input and inspect while Unity is paused -4. Execute the needed `uloop simulate-keyboard` commands -5. If visible output matters, capture a screenshot: `uloop screenshot --capture-mode rendering` -6. Report what happened +2. Execute the appropriate `uloop simulate-keyboard` command +3. Take a screenshot to verify the result: `uloop screenshot --capture-mode rendering` +4. If the screenshot cannot prove the gameplay state, place and enable a `UnityCliLoopDebug.Break("")` marker with `uloop enable-debug-break`, run the input again, then inspect while Unity is paused +5. Report what happened ## Tool Reference @@ -40,20 +39,17 @@ uloop simulate-keyboard --action --key [options] | `KeyDown` | KeyDown only (held until KeyUp) | Start continuous movement, hold sprint | | `KeyUp` | KeyUp only (release held key) | Stop movement, release sprint | -Use `Press` for edge-triggered keyboard code such as `Keyboard.current.spaceKey.wasPressedThisFrame`. +Use `Press` for edge-triggered gameplay code such as `Keyboard.current.spaceKey.wasPressedThisFrame`. `KeyDown` emits one initial press edge, then only keeps the key held. It does not keep `wasPressedThisFrame` true while the key remains held. -If a successful `Press` or `KeyDown` leaves `Keyboard.current..isPressed` true but runtime state does not change, do not immediately rewrite the user's runtime code to `isPressed`. First verify that the target component is active during the command, that it polls input in the configured Input System update phase, and that a missed `KeyDown` edge is followed by `KeyUp` before retrying. +If a successful `Press` or `KeyDown` leaves `Keyboard.current..isPressed` true but the game state does not change, do not immediately rewrite the user's gameplay code to `isPressed`. First verify that the gameplay component is active during the command, that it polls input in the configured Input System update phase, and that a missed `KeyDown` edge is followed by `KeyUp` before retrying. Use `KeyDown` / `KeyUp` when the scenario intentionally needs a held key. ### Debug Break verification -- Consider one `UnityCliLoopDebug.Break("")` marker when a representative keyboard input changes runtime state and exact-frame evidence would reduce uncertainty. Final logs, screenshots, or durable state may be enough for simpler checks. -- Use the marker before slowing time, sleeping, polling, or rewriting runtime code to work around a missed input frame. Treat those checks as supplements, not substitutes. -- If the key handler has local variables, intermediate calculations, or branch reasons that `execute-dynamic-code` cannot inspect after the fact, log just those values with `Debug.Log` immediately before the marker and read them with `get-logs` while Unity is paused. A marker-only check proves the line was reached, not the frame-local values. -- Put the marker at a natural state transition after the app consumed the key, such as after a command is accepted, a state mutation is committed, an evaluation step resolves, or a dependent component is updated. Do not place it immediately after sending `simulate-keyboard`. -- Treat `simulate-keyboard Success=true`, generic action logs, and final durable counters as useful evidence, but not as paused-frame proof. +- Use `UnityCliLoopDebug.Break("")` when a screenshot cannot prove that the keyboard input changed gameplay state, such as jump, sprint, or interaction. +- Put the marker at a natural state transition after the game consumed the key, such as after jump velocity is applied, not immediately after sending `simulate-keyboard`. - If the response has `InterruptedByDebugBreak: true`, Unity is paused for inspection and the tool released its held input bookkeeping. If a `UnityCliLoopDebug.Break` marker caused the pause, `DebugBreakId` and `DebugBreakHitCount` identify it. Use `get-logs`, `get-hierarchy`, `find-game-objects`, or `execute-dynamic-code` before resuming. -- Use distinct marker ids for strict phases, for example `input-read`, `state-updated`, and `result-committed`. +- Use distinct marker ids for strict phases, for example `jump-key-read` and `jump-velocity-applied`. ### KeyDown/KeyUp Rules @@ -72,16 +68,16 @@ Use `KeyDown` / `KeyUp` when the scenario intentionally needs a held key. ## Examples ```bash -# One-shot key press +# One-shot key press (tap W once) uloop simulate-keyboard --action Press --key W -# One-shot action key +# Jump (tap Space) uloop simulate-keyboard --action Press --key Space -# Hold a key for 2 seconds +# Hold W for 2 seconds (move forward) uloop simulate-keyboard --action Press --key W --duration 2.0 -# Hold two keys, then release them +# Sprint forward (hold Shift + W, then release) uloop simulate-keyboard --action KeyDown --key LeftShift uloop simulate-keyboard --action KeyDown --key W uloop screenshot --capture-mode rendering diff --git a/.agents/skills/uloop-simulate-mouse-input/SKILL.md b/.agents/skills/uloop-simulate-mouse-input/SKILL.md index a2c16e0a3..78b3f0fa8 100644 --- a/.agents/skills/uloop-simulate-mouse-input/SKILL.md +++ b/.agents/skills/uloop-simulate-mouse-input/SKILL.md @@ -1,23 +1,22 @@ --- name: uloop-simulate-mouse-input toolName: simulate-mouse-input -description: "Simulate Mouse.current input in PlayMode through Unity Input System. For state-changing PlayMode/E2E mouse input, also use uloop-wait-for-debug-break; when frame-local values matter, pair the marker with focused Debug.Log and get-logs before resuming. Use simulate-mouse-ui for UI." +description: "Simulate Mouse.current input in PlayMode through Unity Input System. Use for gameplay clicks, mouse delta, or scroll; use simulate-mouse-ui for EventSystem UI elements." context: fork --- # Task -Simulate mouse input via Input System in Unity PlayMode. +Simulate mouse input via Input System in Unity PlayMode: $ARGUMENTS ## Workflow 1. Ensure Unity is in PlayMode (use `uloop control-play-mode --action Play` if not) 2. For Click/LongPress: determine the target screen position (use `uloop screenshot` to find coordinates) -3. If exact-frame proof would reduce uncertainty for a state-changing E2E check, pick one representative frame for paused variable/state inspection -4. For that optional representative transition, place and enable a `UnityCliLoopDebug.Break("")` marker, then run the input and inspect while Unity is paused -5. Execute the needed `uloop simulate-mouse-input` commands -6. If visible output matters, capture a screenshot: `uloop screenshot --capture-mode rendering` -7. Report what happened +3. Execute the appropriate `uloop simulate-mouse-input` command +4. Take a screenshot to verify the result: `uloop screenshot --capture-mode rendering` +5. If the screenshot cannot prove the gameplay state, place and enable a `UnityCliLoopDebug.Break("")` marker with `uloop enable-debug-break`, run the input again, then inspect while Unity is paused +6. Report what happened ## Tool Reference @@ -43,21 +42,18 @@ uloop simulate-mouse-input --action [options] | Action | What it injects | Description | |--------|----------------|-------------| -| `Click` | Mouse.current button press → release | Inject a button click so runtime logic detects `wasPressedThisFrame` | +| `Click` | Mouse.current button press → release | Inject a button click so game logic detects `wasPressedThisFrame` | | `LongPress` | Mouse.current button press → hold → release | Hold a button for `--duration` seconds | -| `MoveDelta` | Mouse.current.delta | Inject mouse movement delta one-shot | +| `MoveDelta` | Mouse.current.delta | Inject mouse movement delta one-shot (e.g. for FPS camera look) | | `SmoothDelta` | Mouse.current.delta (per-frame) | Inject mouse delta smoothly over `--duration` seconds (human-like camera pan) | -| `Scroll` | Mouse.current.scroll | Inject scroll wheel input | +| `Scroll` | Mouse.current.scroll | Inject scroll wheel input (e.g. for hotbar or zoom) | ### Debug Break verification -- Consider one `UnityCliLoopDebug.Break("")` marker when a representative mouse input changes runtime state and exact-frame evidence would reduce uncertainty. Final logs, screenshots, or durable state may be enough for simpler checks. -- Use the marker before slowing time, sleeping, polling, or rewriting runtime code to work around a missed input frame. Treat those checks as supplements, not substitutes. -- If the mouse handler has local variables, intermediate calculations, or branch reasons that `execute-dynamic-code` cannot inspect after the fact, log just those values with `Debug.Log` immediately before the marker and read them with `get-logs` while Unity is paused. A marker-only check proves the line was reached, not the frame-local values. -- Put the marker at a natural state transition after the app consumed the mouse input, such as after a command is accepted, a state mutation is committed, an evaluation step resolves, a tracked value changes, or a dependent component is updated. Do not place it immediately after sending `simulate-mouse-input`. -- Treat `simulate-mouse-input Success=true`, generic action logs, and final durable counters as useful evidence, but not as paused-frame proof. +- Use `UnityCliLoopDebug.Break("")` when a screenshot cannot prove that mouse input changed gameplay state, such as block hit, camera turn, or item placement. +- Put the marker at a natural state transition after the game consumed the mouse input, such as after a raycast hit, damage application, placement, or camera rotation update, not immediately after sending `simulate-mouse-input`. - If the response has `InterruptedByDebugBreak: true`, Unity is paused for inspection and the tool released its held input bookkeeping. If a `UnityCliLoopDebug.Break` marker caused the pause, `DebugBreakId` and `DebugBreakHitCount` identify it. Use `get-logs`, `get-hierarchy`, `find-game-objects`, or `execute-dynamic-code` before resuming. -- Use distinct marker ids for strict phases, for example `input-read`, `state-updated`, and `result-committed`. +- Use distinct marker ids for strict phases, for example `block-raycast-hit` and `block-damage-applied`. ### Global Options (optional) @@ -71,31 +67,31 @@ uloop simulate-mouse-input --action [options] | Scenario | Tool | |----------|------| | Click a Unity UI Button (IPointerClickHandler) | `simulate-mouse-ui` | -| Runtime logic reads `Mouse.current.leftButton` | `simulate-mouse-input` when the project uses the New Input System | -| Runtime logic reads right-click | `simulate-mouse-input --button Right` when the project uses the New Input System | +| Destroy a block in Minecraft (reads `Mouse.current.leftButton`) | `simulate-mouse-input` when the project uses the New Input System | +| Place a block with right-click | `simulate-mouse-input --button Right` when the project uses the New Input System | | Drag a UI slider | `simulate-mouse-ui --action Drag` | -| Runtime logic reads `Mouse.current.delta` | `simulate-mouse-input --action MoveDelta` when the project uses the New Input System | -| Runtime logic reads `Mouse.current.scroll` | `simulate-mouse-input --action Scroll` when the project uses the New Input System | +| Look around with mouse (FPS camera) | `simulate-mouse-input --action MoveDelta` when the project uses the New Input System | +| Scroll hotbar slots | `simulate-mouse-input --action Scroll` when the project uses the New Input System | ## Examples ```bash -# Left-click at screen center for runtime input +# Left-click at screen center (for game logic) uloop simulate-mouse-input --action Click --x 400 --y 300 -# Right-click at screen center +# Right-click at screen center (e.g. place block) uloop simulate-mouse-input --action Click --x 400 --y 300 --button Right -# Hold left-click for 2 seconds +# Hold left-click for 2 seconds (e.g. mine block) uloop simulate-mouse-input --action LongPress --x 400 --y 300 --duration 2.0 -# Send a one-shot mouse delta +# Look right (FPS camera) uloop simulate-mouse-input --action MoveDelta --delta-x 100 --delta-y 0 -# Scroll up +# Scroll up (e.g. previous hotbar slot) uloop simulate-mouse-input --action Scroll --scroll-y 120 -# Scroll down +# Scroll down (e.g. next hotbar slot) uloop simulate-mouse-input --action Scroll --scroll-y -120 # Smooth camera pan right over 0.5 seconds diff --git a/.agents/skills/uloop-simulate-mouse-ui/SKILL.md b/.agents/skills/uloop-simulate-mouse-ui/SKILL.md index 14b590409..54e34d693 100644 --- a/.agents/skills/uloop-simulate-mouse-ui/SKILL.md +++ b/.agents/skills/uloop-simulate-mouse-ui/SKILL.md @@ -1,7 +1,7 @@ --- name: uloop-simulate-mouse-ui toolName: simulate-mouse-ui -description: "Simulate PlayMode EventSystem UI mouse actions using screen coordinates. For state-changing PlayMode/E2E UI actions, also use uloop-wait-for-debug-break; when frame-local values matter, pair the marker with focused Debug.Log and get-logs before resuming." +description: "Simulate PlayMode EventSystem UI mouse actions using screen coordinates. Use for UI clicks, long-presses, or drags from annotated screenshots." context: fork --- @@ -14,11 +14,9 @@ Simulate mouse interaction on Unity PlayMode UI: $ARGUMENTS 1. Ensure Unity is in PlayMode (use `uloop control-play-mode --action Play` if not) 2. Get UI element info: `uloop screenshot --capture-mode rendering --annotate-elements --elements-only` 3. Use the `AnnotatedElements` array to find the target element by `Label`, `Name`, or `Path` (A=frontmost, B=next, ...). Use `Interaction` to distinguish click targets from drag/drop/text targets, then use `SimX`/`SimY` directly as `--x`/`--y` coordinates. -4. If this UI action changes runtime state, pick one representative frame for paused variable/state proof before relying on logs, screenshots, or durable state -5. For that representative transition, place and enable a `UnityCliLoopDebug.Break("")` marker, then run the UI action and inspect while Unity is paused -6. Execute any remaining `uloop simulate-mouse-ui` commands -7. Take a screenshot to verify the visible result: `uloop screenshot --capture-mode rendering --annotate-elements` -8. Report what happened +4. Execute the appropriate `uloop simulate-mouse-ui` command +5. Take a screenshot to verify the result: `uloop screenshot --capture-mode rendering --annotate-elements` +6. Report what happened ## Tool Reference @@ -77,15 +75,6 @@ uloop simulate-mouse-ui --action --x --y [options] - `--bypass-raycast` still uses coordinates for pointer event positions, but chooses the clicked, long-pressed, or dragged GameObject by `--target-path` - If `--target-path` or `--drop-target-path` matches multiple active GameObjects, the command fails instead of choosing an arbitrary duplicate -## Debug Break Verification - -- Use one `UnityCliLoopDebug.Break("")` marker for at least one representative UI action that changes runtime state. This applies even when final logs, screenshots, or durable state later show the outcome, because it pauses the exact frame where variables/state can prove input consumption. -- Use the marker before slowing time, sleeping, polling, or rewriting runtime code to work around a missed input frame. Treat those checks as supplements, not substitutes. -- If the UI handler has local variables, intermediate calculations, or branch reasons that `execute-dynamic-code` cannot inspect after the fact, log just those values with `Debug.Log` immediately before the marker and read them with `get-logs` while Unity is paused. A marker-only check proves the line was reached, not the frame-local values. -- Put the marker at a natural transition after the app consumed the UI event, such as after a command is accepted, a state mutation is committed, a tracked value changes, a UI/domain state syncs, or a success/failure/end condition is entered. -- Treat `simulate-mouse-ui Success=true`, generic action logs, and final durable counters as useful evidence, but not as paused-frame proof. -- If a `UnityCliLoopDebug.Break` marker pauses Unity, inspect with `get-logs`, `get-hierarchy`, `find-game-objects`, or `execute-dynamic-code` before resuming. - ## Examples ```bash @@ -125,7 +114,7 @@ uloop simulate-mouse-ui --action DragEnd --x 600 --y 300 - Unity must be in **PlayMode** - Target scene must have an **EventSystem** GameObject - UI elements must have a **GraphicRaycaster** on their Canvas -- If you need runtime mouse input rather than UI pointer events, `simulate-mouse-input` assumes the project uses the New Input System; otherwise prefer `execute-dynamic-code` +- If you need gameplay mouse input rather than UI pointer events, `simulate-mouse-input` assumes the project uses the New Input System; otherwise prefer `execute-dynamic-code` ## Output diff --git a/.agents/skills/uloop-wait-for-debug-break/SKILL.md b/.agents/skills/uloop-wait-for-debug-break/SKILL.md index e4106e44f..1af3de1e2 100644 --- a/.agents/skills/uloop-wait-for-debug-break/SKILL.md +++ b/.agents/skills/uloop-wait-for-debug-break/SKILL.md @@ -1,63 +1,54 @@ --- name: uloop-wait-for-debug-break -description: "Use this like an IDE breakpoint for Unity PlayMode/E2E when you need to pause a specific frame and inspect variables, GameObjects, or runtime state." +description: "Use this for Unity PlayMode/E2E checks when simulated input or gameplay events cause a state transition that a screenshot, durable state, or specific value log cannot prove. Pause at the natural transition point after the input/event is consumed and inspect the paused frame. Do not use simulate-* Success=true, generic action logs, sleeps/retries, testing-only counters, or Time.timeScale changes as substitutes for debug-break evidence of transient transitions." --- -## Quick Check Template +## Workflow -Use this small loop for one representative frame you care about: - -1. Put a focused log and marker at the natural transition point. Log only local/intermediate values that will be hard to inspect later: +1. Add a marker at the state you want to inspect: ```csharp -using UnityEngine; using io.github.hatayama.UnityCliLoop.Runtime; -Debug.Log($"state-transition-applied localValue={localValue} reason={reason}"); -UnityCliLoopDebug.Break("state-transition-applied"); +UnityCliLoopDebug.Break("player-jumped"); ``` -2. Compile, enter PlayMode, then enable the marker: +2. Compile the project. +3. Enable the marker before triggering the target code path: ```bash -uloop enable-debug-break --id state-transition-applied --timeout-seconds 30 +uloop enable-debug-break --id player-jumped --timeout-seconds 30 ``` -3. Trigger the action with a `simulate-*` command. -4. Run `uloop wait-for-debug-break --id state-transition-applied --timeout-seconds 30`, even if the trigger command already returned `InterruptedByDebugBreak=true`. -5. Before resuming, read the focused log for the same marker id: +4. Check marker state if needed: ```bash -uloop get-logs --search-text state-transition-applied --max-count 20 +uloop debug-break-status --id player-jumped ``` -6. While Unity is still paused, capture any additional evidence with `uloop execute-dynamic-code`, `uloop get-hierarchy`, `uloop find-game-objects`, and one screenshot. -7. Clear the marker with `uloop clear-debug-break --id state-transition-applied` or stop PlayMode before moving on. - -## When To Use +5. Trigger the behavior with `simulate-keyboard`, `simulate-mouse-input`, UI interaction, dynamic code, or similar commands. +6. Wait for the marker: -- Use this as the standard frame proof for state-changing PlayMode/E2E simulated input, physics, or UI transitions. -- Pause at least one representative transition per E2E pass, even if durable state, logs, or screenshots can later confirm the final result. -- Use this before reaching for `Time.timeScale`, sleeps, repeated polling, or after-the-fact `execute-dynamic-code`; those checks can supplement the paused-frame proof, but they are not substitutes. -- If the value you need is a method local, an intermediate calculation, or a branch reason that `execute-dynamic-code` cannot reach, add a focused `Debug.Log` immediately before the marker and read it with `get-logs` while paused. Do not count the breakpoint check complete until the matching log has been read. -- Good pause points include after input is consumed, a command is accepted, a state mutation is committed, an evaluation step resolves, a tracked value changes, a UI/domain state syncs, or a success/failure/end condition is entered. -- Treat the pause like a lightweight breakpoint for one important transition: combine nearby debug logs with paused-frame inspection to confirm the variables and component state at that point. -- Do not treat `simulate-* Success=true`, generic action logs, sleeps/retries, testing-only counters, or `Time.timeScale` changes as paused-frame proof. -- Skip this only for ordinary persistent-state checks when you are not validating simulated input delivery, event ordering, or transition-frame fidelity. +```bash +uloop wait-for-debug-break --id player-jumped --timeout-seconds 30 +``` -## Timeout Checks +If this command times out, the marker line was not reached while the command waited. Inspect `error.details.status`, `hitCount`, `isPlaying`, `isPaused`, `elapsedSinceEnabledMilliseconds`, and `remainingMilliseconds` to distinguish input not being consumed, gameplay conditions not being met, an id mismatch, or Unity already being paused. `elapsedSinceEnabledMilliseconds` is measured from `enable-debug-break`, not from `wait-for-debug-break`. -If this command times out, the marker line was not reached while the command waited. Inspect `error.details.status`, `hitCount`, `isPlaying`, `isPaused`, `elapsedSinceEnabledMilliseconds`, and `remainingMilliseconds` to distinguish input not being consumed, runtime conditions not being met, an id mismatch, or Unity already being paused. `elapsedSinceEnabledMilliseconds` is measured from `enable-debug-break`, not from `wait-for-debug-break`. +7. While Unity is paused, inspect state with `uloop get-logs`, `uloop get-hierarchy`, `uloop find-game-objects`, screenshots, or `uloop execute-dynamic-code`. +8. Clear the marker if you stop waiting: -Use `uloop debug-break-status --id state-transition-applied` only when you need to confirm the marker is armed or inspect the current hit state. Add focused debug logs before the marker when local variables must be captured. +```bash +uloop clear-debug-break --id player-jumped +``` ## Marker Placement -- Prefer natural runtime points after input has been consumed, such as after a command is accepted, a state value changes, an evaluation step resolves, or a dependent component is updated. +- Prefer natural gameplay points or state-transition points after input has been consumed, such as after jump velocity or state changes, physics contact, or damage application. - For frame-specific bugs, place the marker on the suspicious state branch or immediately after the state mutation you need to freeze. - To avoid Domain Reload loss or tool Busy states, enable markers after Play Mode is running, and prefer checkpoints reached after the triggering input command can return. -- Avoid placing the marker immediately after issuing simulated input unless that exact input handling line is the state you need to inspect. Immediate markers can interrupt the input command before the resulting runtime state settles. -- Use separate ids for strict phases, for example `input-read`, `state-updated`, and `result-committed`, instead of reusing one broad marker. +- Avoid placing the marker immediately after issuing simulated input unless that exact input handling line is the state you need to inspect. Immediate markers can interrupt the input command before the resulting gameplay state settles. +- Use separate ids for strict phases, for example `jump-input-read`, `jump-velocity-applied`, and `jump-landed`, instead of reusing one broad marker. ## Safety diff --git a/.claude/skills/uloop-execute-dynamic-code/SKILL.md b/.claude/skills/uloop-execute-dynamic-code/SKILL.md index d89d61512..d29fcdc9c 100644 --- a/.claude/skills/uloop-execute-dynamic-code/SKILL.md +++ b/.claude/skills/uloop-execute-dynamic-code/SKILL.md @@ -1,7 +1,7 @@ --- name: uloop-execute-dynamic-code toolName: execute-dynamic-code -description: "Execute C# with Unity APIs when existing uloop tools cannot inspect or edit enough. Use for reachable scene/component state, scene/prefab/menu automation, and PlayMode checks. It cannot see method locals from an already-running frame; use `uloop wait-for-debug-break` with focused Debug.Log and `uloop get-logs` for those." +description: "Execute C# with Unity APIs when existing uloop tools cannot inspect or edit enough. Use for scene, prefab, SerializedObject, AssetDatabase refresh/.meta generation, menu, or PlayMode automation." context: fork --- @@ -11,8 +11,6 @@ Execute the following request using `uloop execute-dynamic-code`: $ARGUMENTS For basic selected GameObject discovery or property inspection, use `find-game-objects --search-mode Selected` before this tool. Use this tool after the built-in inspection tools are not enough or when you need to modify Unity state. -This tool can inspect reachable Unity state, such as GameObjects, components, public properties, static values, and method results. It cannot directly read local variables or intermediate calculations inside an already-running method. When those values matter, add a focused `Debug.Log` immediately before `UnityCliLoopDebug.Break("")`, then run `get-logs --search-text ` while Unity is paused. Do not replace that log read with execute-dynamic-code. - ## Workflow 1. Read the relevant reference file(s) from the Code Examples section below diff --git a/.claude/skills/uloop-get-logs/SKILL.md b/.claude/skills/uloop-get-logs/SKILL.md index 9b24b4094..a74e55532 100644 --- a/.claude/skills/uloop-get-logs/SKILL.md +++ b/.claude/skills/uloop-get-logs/SKILL.md @@ -1,15 +1,13 @@ --- name: uloop-get-logs toolName: get-logs -description: "Read current Unity Console entries from a running Editor. Use during bug investigation after compile, tests, PlayMode, dynamic code, or immediately after `uloop wait-for-debug-break`." +description: "Read current Unity Console entries from a running Editor. Use during bug investigation after compile, tests, PlayMode, or dynamic code to inspect logs, warnings, errors, and stack traces." --- # uloop get-logs Retrieve logs from Unity Console. -When a debug-break marker pauses Unity and the value you need is a method local, intermediate calculation, or branch reason, read the focused `Debug.Log` entry added immediately before the marker before resuming PlayMode. Use `--search-text ` so the marker and its log are checked as one breakpoint-style proof. - ## Usage ```bash diff --git a/.claude/skills/uloop-simulate-keyboard/SKILL.md b/.claude/skills/uloop-simulate-keyboard/SKILL.md index d865b0adf..fc6596887 100644 --- a/.claude/skills/uloop-simulate-keyboard/SKILL.md +++ b/.claude/skills/uloop-simulate-keyboard/SKILL.md @@ -1,7 +1,7 @@ --- name: uloop-simulate-keyboard toolName: simulate-keyboard -description: "Simulate keyboard input in PlayMode through Unity Input System. For state-changing PlayMode/E2E input, also use uloop-wait-for-debug-break; when frame-local values matter, pair the marker with focused Debug.Log and get-logs before resuming." +description: "Simulate keyboard input in PlayMode through Unity Input System. Use for key presses, holds, releases, and game controls such as WASD or Space." context: fork --- @@ -12,11 +12,10 @@ Simulate keyboard input on Unity PlayMode: $ARGUMENTS ## Workflow 1. Ensure Unity is in PlayMode (use `uloop control-play-mode --action Play` if not) -2. If exact-frame proof would reduce uncertainty for a state-changing E2E check, pick one representative frame for paused variable/state inspection -3. For that optional representative transition, place and enable a `UnityCliLoopDebug.Break("")` marker, then run the input and inspect while Unity is paused -4. Execute the needed `uloop simulate-keyboard` commands -5. If visible output matters, capture a screenshot: `uloop screenshot --capture-mode rendering` -6. Report what happened +2. Execute the appropriate `uloop simulate-keyboard` command +3. Take a screenshot to verify the result: `uloop screenshot --capture-mode rendering` +4. If the screenshot cannot prove the gameplay state, place and enable a `UnityCliLoopDebug.Break("")` marker with `uloop enable-debug-break`, run the input again, then inspect while Unity is paused +5. Report what happened ## Tool Reference @@ -40,20 +39,17 @@ uloop simulate-keyboard --action --key [options] | `KeyDown` | KeyDown only (held until KeyUp) | Start continuous movement, hold sprint | | `KeyUp` | KeyUp only (release held key) | Stop movement, release sprint | -Use `Press` for edge-triggered keyboard code such as `Keyboard.current.spaceKey.wasPressedThisFrame`. +Use `Press` for edge-triggered gameplay code such as `Keyboard.current.spaceKey.wasPressedThisFrame`. `KeyDown` emits one initial press edge, then only keeps the key held. It does not keep `wasPressedThisFrame` true while the key remains held. -If a successful `Press` or `KeyDown` leaves `Keyboard.current..isPressed` true but runtime state does not change, do not immediately rewrite the user's runtime code to `isPressed`. First verify that the target component is active during the command, that it polls input in the configured Input System update phase, and that a missed `KeyDown` edge is followed by `KeyUp` before retrying. +If a successful `Press` or `KeyDown` leaves `Keyboard.current..isPressed` true but the game state does not change, do not immediately rewrite the user's gameplay code to `isPressed`. First verify that the gameplay component is active during the command, that it polls input in the configured Input System update phase, and that a missed `KeyDown` edge is followed by `KeyUp` before retrying. Use `KeyDown` / `KeyUp` when the scenario intentionally needs a held key. ### Debug Break verification -- Consider one `UnityCliLoopDebug.Break("")` marker when a representative keyboard input changes runtime state and exact-frame evidence would reduce uncertainty. Final logs, screenshots, or durable state may be enough for simpler checks. -- Use the marker before slowing time, sleeping, polling, or rewriting runtime code to work around a missed input frame. Treat those checks as supplements, not substitutes. -- If the key handler has local variables, intermediate calculations, or branch reasons that `execute-dynamic-code` cannot inspect after the fact, log just those values with `Debug.Log` immediately before the marker and read them with `get-logs` while Unity is paused. A marker-only check proves the line was reached, not the frame-local values. -- Put the marker at a natural state transition after the app consumed the key, such as after a command is accepted, a state mutation is committed, an evaluation step resolves, or a dependent component is updated. Do not place it immediately after sending `simulate-keyboard`. -- Treat `simulate-keyboard Success=true`, generic action logs, and final durable counters as useful evidence, but not as paused-frame proof. +- Use `UnityCliLoopDebug.Break("")` when a screenshot cannot prove that the keyboard input changed gameplay state, such as jump, sprint, or interaction. +- Put the marker at a natural state transition after the game consumed the key, such as after jump velocity is applied, not immediately after sending `simulate-keyboard`. - If the response has `InterruptedByDebugBreak: true`, Unity is paused for inspection and the tool released its held input bookkeeping. If a `UnityCliLoopDebug.Break` marker caused the pause, `DebugBreakId` and `DebugBreakHitCount` identify it. Use `get-logs`, `get-hierarchy`, `find-game-objects`, or `execute-dynamic-code` before resuming. -- Use distinct marker ids for strict phases, for example `input-read`, `state-updated`, and `result-committed`. +- Use distinct marker ids for strict phases, for example `jump-key-read` and `jump-velocity-applied`. ### KeyDown/KeyUp Rules @@ -72,16 +68,16 @@ Use `KeyDown` / `KeyUp` when the scenario intentionally needs a held key. ## Examples ```bash -# One-shot key press +# One-shot key press (tap W once) uloop simulate-keyboard --action Press --key W -# One-shot action key +# Jump (tap Space) uloop simulate-keyboard --action Press --key Space -# Hold a key for 2 seconds +# Hold W for 2 seconds (move forward) uloop simulate-keyboard --action Press --key W --duration 2.0 -# Hold two keys, then release them +# Sprint forward (hold Shift + W, then release) uloop simulate-keyboard --action KeyDown --key LeftShift uloop simulate-keyboard --action KeyDown --key W uloop screenshot --capture-mode rendering diff --git a/.claude/skills/uloop-simulate-mouse-input/SKILL.md b/.claude/skills/uloop-simulate-mouse-input/SKILL.md index a2c16e0a3..78b3f0fa8 100644 --- a/.claude/skills/uloop-simulate-mouse-input/SKILL.md +++ b/.claude/skills/uloop-simulate-mouse-input/SKILL.md @@ -1,23 +1,22 @@ --- name: uloop-simulate-mouse-input toolName: simulate-mouse-input -description: "Simulate Mouse.current input in PlayMode through Unity Input System. For state-changing PlayMode/E2E mouse input, also use uloop-wait-for-debug-break; when frame-local values matter, pair the marker with focused Debug.Log and get-logs before resuming. Use simulate-mouse-ui for UI." +description: "Simulate Mouse.current input in PlayMode through Unity Input System. Use for gameplay clicks, mouse delta, or scroll; use simulate-mouse-ui for EventSystem UI elements." context: fork --- # Task -Simulate mouse input via Input System in Unity PlayMode. +Simulate mouse input via Input System in Unity PlayMode: $ARGUMENTS ## Workflow 1. Ensure Unity is in PlayMode (use `uloop control-play-mode --action Play` if not) 2. For Click/LongPress: determine the target screen position (use `uloop screenshot` to find coordinates) -3. If exact-frame proof would reduce uncertainty for a state-changing E2E check, pick one representative frame for paused variable/state inspection -4. For that optional representative transition, place and enable a `UnityCliLoopDebug.Break("")` marker, then run the input and inspect while Unity is paused -5. Execute the needed `uloop simulate-mouse-input` commands -6. If visible output matters, capture a screenshot: `uloop screenshot --capture-mode rendering` -7. Report what happened +3. Execute the appropriate `uloop simulate-mouse-input` command +4. Take a screenshot to verify the result: `uloop screenshot --capture-mode rendering` +5. If the screenshot cannot prove the gameplay state, place and enable a `UnityCliLoopDebug.Break("")` marker with `uloop enable-debug-break`, run the input again, then inspect while Unity is paused +6. Report what happened ## Tool Reference @@ -43,21 +42,18 @@ uloop simulate-mouse-input --action [options] | Action | What it injects | Description | |--------|----------------|-------------| -| `Click` | Mouse.current button press → release | Inject a button click so runtime logic detects `wasPressedThisFrame` | +| `Click` | Mouse.current button press → release | Inject a button click so game logic detects `wasPressedThisFrame` | | `LongPress` | Mouse.current button press → hold → release | Hold a button for `--duration` seconds | -| `MoveDelta` | Mouse.current.delta | Inject mouse movement delta one-shot | +| `MoveDelta` | Mouse.current.delta | Inject mouse movement delta one-shot (e.g. for FPS camera look) | | `SmoothDelta` | Mouse.current.delta (per-frame) | Inject mouse delta smoothly over `--duration` seconds (human-like camera pan) | -| `Scroll` | Mouse.current.scroll | Inject scroll wheel input | +| `Scroll` | Mouse.current.scroll | Inject scroll wheel input (e.g. for hotbar or zoom) | ### Debug Break verification -- Consider one `UnityCliLoopDebug.Break("")` marker when a representative mouse input changes runtime state and exact-frame evidence would reduce uncertainty. Final logs, screenshots, or durable state may be enough for simpler checks. -- Use the marker before slowing time, sleeping, polling, or rewriting runtime code to work around a missed input frame. Treat those checks as supplements, not substitutes. -- If the mouse handler has local variables, intermediate calculations, or branch reasons that `execute-dynamic-code` cannot inspect after the fact, log just those values with `Debug.Log` immediately before the marker and read them with `get-logs` while Unity is paused. A marker-only check proves the line was reached, not the frame-local values. -- Put the marker at a natural state transition after the app consumed the mouse input, such as after a command is accepted, a state mutation is committed, an evaluation step resolves, a tracked value changes, or a dependent component is updated. Do not place it immediately after sending `simulate-mouse-input`. -- Treat `simulate-mouse-input Success=true`, generic action logs, and final durable counters as useful evidence, but not as paused-frame proof. +- Use `UnityCliLoopDebug.Break("")` when a screenshot cannot prove that mouse input changed gameplay state, such as block hit, camera turn, or item placement. +- Put the marker at a natural state transition after the game consumed the mouse input, such as after a raycast hit, damage application, placement, or camera rotation update, not immediately after sending `simulate-mouse-input`. - If the response has `InterruptedByDebugBreak: true`, Unity is paused for inspection and the tool released its held input bookkeeping. If a `UnityCliLoopDebug.Break` marker caused the pause, `DebugBreakId` and `DebugBreakHitCount` identify it. Use `get-logs`, `get-hierarchy`, `find-game-objects`, or `execute-dynamic-code` before resuming. -- Use distinct marker ids for strict phases, for example `input-read`, `state-updated`, and `result-committed`. +- Use distinct marker ids for strict phases, for example `block-raycast-hit` and `block-damage-applied`. ### Global Options (optional) @@ -71,31 +67,31 @@ uloop simulate-mouse-input --action [options] | Scenario | Tool | |----------|------| | Click a Unity UI Button (IPointerClickHandler) | `simulate-mouse-ui` | -| Runtime logic reads `Mouse.current.leftButton` | `simulate-mouse-input` when the project uses the New Input System | -| Runtime logic reads right-click | `simulate-mouse-input --button Right` when the project uses the New Input System | +| Destroy a block in Minecraft (reads `Mouse.current.leftButton`) | `simulate-mouse-input` when the project uses the New Input System | +| Place a block with right-click | `simulate-mouse-input --button Right` when the project uses the New Input System | | Drag a UI slider | `simulate-mouse-ui --action Drag` | -| Runtime logic reads `Mouse.current.delta` | `simulate-mouse-input --action MoveDelta` when the project uses the New Input System | -| Runtime logic reads `Mouse.current.scroll` | `simulate-mouse-input --action Scroll` when the project uses the New Input System | +| Look around with mouse (FPS camera) | `simulate-mouse-input --action MoveDelta` when the project uses the New Input System | +| Scroll hotbar slots | `simulate-mouse-input --action Scroll` when the project uses the New Input System | ## Examples ```bash -# Left-click at screen center for runtime input +# Left-click at screen center (for game logic) uloop simulate-mouse-input --action Click --x 400 --y 300 -# Right-click at screen center +# Right-click at screen center (e.g. place block) uloop simulate-mouse-input --action Click --x 400 --y 300 --button Right -# Hold left-click for 2 seconds +# Hold left-click for 2 seconds (e.g. mine block) uloop simulate-mouse-input --action LongPress --x 400 --y 300 --duration 2.0 -# Send a one-shot mouse delta +# Look right (FPS camera) uloop simulate-mouse-input --action MoveDelta --delta-x 100 --delta-y 0 -# Scroll up +# Scroll up (e.g. previous hotbar slot) uloop simulate-mouse-input --action Scroll --scroll-y 120 -# Scroll down +# Scroll down (e.g. next hotbar slot) uloop simulate-mouse-input --action Scroll --scroll-y -120 # Smooth camera pan right over 0.5 seconds diff --git a/.claude/skills/uloop-simulate-mouse-ui/SKILL.md b/.claude/skills/uloop-simulate-mouse-ui/SKILL.md index 14b590409..54e34d693 100644 --- a/.claude/skills/uloop-simulate-mouse-ui/SKILL.md +++ b/.claude/skills/uloop-simulate-mouse-ui/SKILL.md @@ -1,7 +1,7 @@ --- name: uloop-simulate-mouse-ui toolName: simulate-mouse-ui -description: "Simulate PlayMode EventSystem UI mouse actions using screen coordinates. For state-changing PlayMode/E2E UI actions, also use uloop-wait-for-debug-break; when frame-local values matter, pair the marker with focused Debug.Log and get-logs before resuming." +description: "Simulate PlayMode EventSystem UI mouse actions using screen coordinates. Use for UI clicks, long-presses, or drags from annotated screenshots." context: fork --- @@ -14,11 +14,9 @@ Simulate mouse interaction on Unity PlayMode UI: $ARGUMENTS 1. Ensure Unity is in PlayMode (use `uloop control-play-mode --action Play` if not) 2. Get UI element info: `uloop screenshot --capture-mode rendering --annotate-elements --elements-only` 3. Use the `AnnotatedElements` array to find the target element by `Label`, `Name`, or `Path` (A=frontmost, B=next, ...). Use `Interaction` to distinguish click targets from drag/drop/text targets, then use `SimX`/`SimY` directly as `--x`/`--y` coordinates. -4. If this UI action changes runtime state, pick one representative frame for paused variable/state proof before relying on logs, screenshots, or durable state -5. For that representative transition, place and enable a `UnityCliLoopDebug.Break("")` marker, then run the UI action and inspect while Unity is paused -6. Execute any remaining `uloop simulate-mouse-ui` commands -7. Take a screenshot to verify the visible result: `uloop screenshot --capture-mode rendering --annotate-elements` -8. Report what happened +4. Execute the appropriate `uloop simulate-mouse-ui` command +5. Take a screenshot to verify the result: `uloop screenshot --capture-mode rendering --annotate-elements` +6. Report what happened ## Tool Reference @@ -77,15 +75,6 @@ uloop simulate-mouse-ui --action --x --y [options] - `--bypass-raycast` still uses coordinates for pointer event positions, but chooses the clicked, long-pressed, or dragged GameObject by `--target-path` - If `--target-path` or `--drop-target-path` matches multiple active GameObjects, the command fails instead of choosing an arbitrary duplicate -## Debug Break Verification - -- Use one `UnityCliLoopDebug.Break("")` marker for at least one representative UI action that changes runtime state. This applies even when final logs, screenshots, or durable state later show the outcome, because it pauses the exact frame where variables/state can prove input consumption. -- Use the marker before slowing time, sleeping, polling, or rewriting runtime code to work around a missed input frame. Treat those checks as supplements, not substitutes. -- If the UI handler has local variables, intermediate calculations, or branch reasons that `execute-dynamic-code` cannot inspect after the fact, log just those values with `Debug.Log` immediately before the marker and read them with `get-logs` while Unity is paused. A marker-only check proves the line was reached, not the frame-local values. -- Put the marker at a natural transition after the app consumed the UI event, such as after a command is accepted, a state mutation is committed, a tracked value changes, a UI/domain state syncs, or a success/failure/end condition is entered. -- Treat `simulate-mouse-ui Success=true`, generic action logs, and final durable counters as useful evidence, but not as paused-frame proof. -- If a `UnityCliLoopDebug.Break` marker pauses Unity, inspect with `get-logs`, `get-hierarchy`, `find-game-objects`, or `execute-dynamic-code` before resuming. - ## Examples ```bash @@ -125,7 +114,7 @@ uloop simulate-mouse-ui --action DragEnd --x 600 --y 300 - Unity must be in **PlayMode** - Target scene must have an **EventSystem** GameObject - UI elements must have a **GraphicRaycaster** on their Canvas -- If you need runtime mouse input rather than UI pointer events, `simulate-mouse-input` assumes the project uses the New Input System; otherwise prefer `execute-dynamic-code` +- If you need gameplay mouse input rather than UI pointer events, `simulate-mouse-input` assumes the project uses the New Input System; otherwise prefer `execute-dynamic-code` ## Output diff --git a/.claude/skills/uloop-wait-for-debug-break/SKILL.md b/.claude/skills/uloop-wait-for-debug-break/SKILL.md index e4106e44f..1af3de1e2 100644 --- a/.claude/skills/uloop-wait-for-debug-break/SKILL.md +++ b/.claude/skills/uloop-wait-for-debug-break/SKILL.md @@ -1,63 +1,54 @@ --- name: uloop-wait-for-debug-break -description: "Use this like an IDE breakpoint for Unity PlayMode/E2E when you need to pause a specific frame and inspect variables, GameObjects, or runtime state." +description: "Use this for Unity PlayMode/E2E checks when simulated input or gameplay events cause a state transition that a screenshot, durable state, or specific value log cannot prove. Pause at the natural transition point after the input/event is consumed and inspect the paused frame. Do not use simulate-* Success=true, generic action logs, sleeps/retries, testing-only counters, or Time.timeScale changes as substitutes for debug-break evidence of transient transitions." --- -## Quick Check Template +## Workflow -Use this small loop for one representative frame you care about: - -1. Put a focused log and marker at the natural transition point. Log only local/intermediate values that will be hard to inspect later: +1. Add a marker at the state you want to inspect: ```csharp -using UnityEngine; using io.github.hatayama.UnityCliLoop.Runtime; -Debug.Log($"state-transition-applied localValue={localValue} reason={reason}"); -UnityCliLoopDebug.Break("state-transition-applied"); +UnityCliLoopDebug.Break("player-jumped"); ``` -2. Compile, enter PlayMode, then enable the marker: +2. Compile the project. +3. Enable the marker before triggering the target code path: ```bash -uloop enable-debug-break --id state-transition-applied --timeout-seconds 30 +uloop enable-debug-break --id player-jumped --timeout-seconds 30 ``` -3. Trigger the action with a `simulate-*` command. -4. Run `uloop wait-for-debug-break --id state-transition-applied --timeout-seconds 30`, even if the trigger command already returned `InterruptedByDebugBreak=true`. -5. Before resuming, read the focused log for the same marker id: +4. Check marker state if needed: ```bash -uloop get-logs --search-text state-transition-applied --max-count 20 +uloop debug-break-status --id player-jumped ``` -6. While Unity is still paused, capture any additional evidence with `uloop execute-dynamic-code`, `uloop get-hierarchy`, `uloop find-game-objects`, and one screenshot. -7. Clear the marker with `uloop clear-debug-break --id state-transition-applied` or stop PlayMode before moving on. - -## When To Use +5. Trigger the behavior with `simulate-keyboard`, `simulate-mouse-input`, UI interaction, dynamic code, or similar commands. +6. Wait for the marker: -- Use this as the standard frame proof for state-changing PlayMode/E2E simulated input, physics, or UI transitions. -- Pause at least one representative transition per E2E pass, even if durable state, logs, or screenshots can later confirm the final result. -- Use this before reaching for `Time.timeScale`, sleeps, repeated polling, or after-the-fact `execute-dynamic-code`; those checks can supplement the paused-frame proof, but they are not substitutes. -- If the value you need is a method local, an intermediate calculation, or a branch reason that `execute-dynamic-code` cannot reach, add a focused `Debug.Log` immediately before the marker and read it with `get-logs` while paused. Do not count the breakpoint check complete until the matching log has been read. -- Good pause points include after input is consumed, a command is accepted, a state mutation is committed, an evaluation step resolves, a tracked value changes, a UI/domain state syncs, or a success/failure/end condition is entered. -- Treat the pause like a lightweight breakpoint for one important transition: combine nearby debug logs with paused-frame inspection to confirm the variables and component state at that point. -- Do not treat `simulate-* Success=true`, generic action logs, sleeps/retries, testing-only counters, or `Time.timeScale` changes as paused-frame proof. -- Skip this only for ordinary persistent-state checks when you are not validating simulated input delivery, event ordering, or transition-frame fidelity. +```bash +uloop wait-for-debug-break --id player-jumped --timeout-seconds 30 +``` -## Timeout Checks +If this command times out, the marker line was not reached while the command waited. Inspect `error.details.status`, `hitCount`, `isPlaying`, `isPaused`, `elapsedSinceEnabledMilliseconds`, and `remainingMilliseconds` to distinguish input not being consumed, gameplay conditions not being met, an id mismatch, or Unity already being paused. `elapsedSinceEnabledMilliseconds` is measured from `enable-debug-break`, not from `wait-for-debug-break`. -If this command times out, the marker line was not reached while the command waited. Inspect `error.details.status`, `hitCount`, `isPlaying`, `isPaused`, `elapsedSinceEnabledMilliseconds`, and `remainingMilliseconds` to distinguish input not being consumed, runtime conditions not being met, an id mismatch, or Unity already being paused. `elapsedSinceEnabledMilliseconds` is measured from `enable-debug-break`, not from `wait-for-debug-break`. +7. While Unity is paused, inspect state with `uloop get-logs`, `uloop get-hierarchy`, `uloop find-game-objects`, screenshots, or `uloop execute-dynamic-code`. +8. Clear the marker if you stop waiting: -Use `uloop debug-break-status --id state-transition-applied` only when you need to confirm the marker is armed or inspect the current hit state. Add focused debug logs before the marker when local variables must be captured. +```bash +uloop clear-debug-break --id player-jumped +``` ## Marker Placement -- Prefer natural runtime points after input has been consumed, such as after a command is accepted, a state value changes, an evaluation step resolves, or a dependent component is updated. +- Prefer natural gameplay points or state-transition points after input has been consumed, such as after jump velocity or state changes, physics contact, or damage application. - For frame-specific bugs, place the marker on the suspicious state branch or immediately after the state mutation you need to freeze. - To avoid Domain Reload loss or tool Busy states, enable markers after Play Mode is running, and prefer checkpoints reached after the triggering input command can return. -- Avoid placing the marker immediately after issuing simulated input unless that exact input handling line is the state you need to inspect. Immediate markers can interrupt the input command before the resulting runtime state settles. -- Use separate ids for strict phases, for example `input-read`, `state-updated`, and `result-committed`, instead of reusing one broad marker. +- Avoid placing the marker immediately after issuing simulated input unless that exact input handling line is the state you need to inspect. Immediate markers can interrupt the input command before the resulting gameplay state settles. +- Use separate ids for strict phases, for example `jump-input-read`, `jump-velocity-applied`, and `jump-landed`, instead of reusing one broad marker. ## Safety From 88fc7c748c750d4e03febda8c8c59e3fc12460b7 Mon Sep 17 00:00:00 2001 From: hatayama Date: Wed, 10 Jun 2026 16:29:54 +0900 Subject: [PATCH 17/24] Remove trailing whitespace from skill description Keeps the PR diff check clean after the source skill description was shortened. --- .../Editor/FirstPartyTools/ExecuteDynamicCode/Skill/SKILL.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Packages/src/Editor/FirstPartyTools/ExecuteDynamicCode/Skill/SKILL.md b/Packages/src/Editor/FirstPartyTools/ExecuteDynamicCode/Skill/SKILL.md index af6c40f69..bfd3f4e0a 100644 --- a/Packages/src/Editor/FirstPartyTools/ExecuteDynamicCode/Skill/SKILL.md +++ b/Packages/src/Editor/FirstPartyTools/ExecuteDynamicCode/Skill/SKILL.md @@ -1,7 +1,7 @@ --- name: uloop-execute-dynamic-code toolName: execute-dynamic-code -description: "Execute C# with Unity APIs when existing uloop tools cannot inspect or edit enough. Use for reachable scene/component state, scene/prefab/menu automation, and PlayMode checks" +description: "Execute C# with Unity APIs when existing uloop tools cannot inspect or edit enough. Use for reachable scene/component state, scene/prefab/menu automation, and PlayMode checks" context: fork --- From ae1dad0fd447d5456d6d0d173efa20e88c227938 Mon Sep 17 00:00:00 2001 From: hatayama Date: Wed, 10 Jun 2026 16:32:03 +0900 Subject: [PATCH 18/24] Use skill name in get-logs trigger hint Updates the source get-logs skill description to refer to the wait-for-debug-break skill name while leaving generated skill copies out of the PR. --- Packages/src/Editor/FirstPartyTools/GetLogs/Skill/SKILL.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Packages/src/Editor/FirstPartyTools/GetLogs/Skill/SKILL.md b/Packages/src/Editor/FirstPartyTools/GetLogs/Skill/SKILL.md index 9b24b4094..2ad7bd92a 100644 --- a/Packages/src/Editor/FirstPartyTools/GetLogs/Skill/SKILL.md +++ b/Packages/src/Editor/FirstPartyTools/GetLogs/Skill/SKILL.md @@ -1,7 +1,7 @@ --- name: uloop-get-logs toolName: get-logs -description: "Read current Unity Console entries from a running Editor. Use during bug investigation after compile, tests, PlayMode, dynamic code, or immediately after `uloop wait-for-debug-break`." +description: "Read current Unity Console entries from a running Editor. Use during bug investigation after compile, tests, PlayMode, dynamic code, or immediately after `uloop-wait-for-debug-break`." --- # uloop get-logs From 6c2bbecab0598f7799d2f490a50f3d9cecaa3756 Mon Sep 17 00:00:00 2001 From: hatayama Date: Wed, 10 Jun 2026 16:41:13 +0900 Subject: [PATCH 19/24] Clarify mouse input debug-break guidance Softens the source simulate-mouse-input skill so wait-for-debug-break is presented as optional help when paired with UnityCliLoopDebug.Break, and removes marker-style wording from the workflow, inspection guidance, and output notes. --- .../SimulateMouseInput/Skill/SKILL.md | 29 +++++++++---------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/Packages/src/Editor/FirstPartyTools/SimulateMouseInput/Skill/SKILL.md b/Packages/src/Editor/FirstPartyTools/SimulateMouseInput/Skill/SKILL.md index a2c16e0a3..2b5892662 100644 --- a/Packages/src/Editor/FirstPartyTools/SimulateMouseInput/Skill/SKILL.md +++ b/Packages/src/Editor/FirstPartyTools/SimulateMouseInput/Skill/SKILL.md @@ -1,7 +1,7 @@ --- name: uloop-simulate-mouse-input toolName: simulate-mouse-input -description: "Simulate Mouse.current input in PlayMode through Unity Input System. For state-changing PlayMode/E2E mouse input, also use uloop-wait-for-debug-break; when frame-local values matter, pair the marker with focused Debug.Log and get-logs before resuming. Use simulate-mouse-ui for UI." +description: "Simulate Mouse.current input in PlayMode through Unity Input System for gameplay clicks, movement delta, or scroll. For state-changing PlayMode/E2E mouse input, uloop-wait-for-debug-break can help when paired with UnityCliLoopDebug.Break(\"id\") to pause an inspectable frame; use uloop-get-logs if you also logged local/intermediate values. Use simulate-mouse-ui for UI." context: fork --- @@ -13,11 +13,11 @@ Simulate mouse input via Input System in Unity PlayMode. 1. Ensure Unity is in PlayMode (use `uloop control-play-mode --action Play` if not) 2. For Click/LongPress: determine the target screen position (use `uloop screenshot` to find coordinates) -3. If exact-frame proof would reduce uncertainty for a state-changing E2E check, pick one representative frame for paused variable/state inspection -4. For that optional representative transition, place and enable a `UnityCliLoopDebug.Break("")` marker, then run the input and inspect while Unity is paused -5. Execute the needed `uloop simulate-mouse-input` commands +3. Execute the needed `uloop simulate-mouse-input` commands +4. If exact-frame proof would reduce uncertainty, optionally pair the scenario with `UnityCliLoopDebug.Break("")` and `uloop-wait-for-debug-break`, then inspect while Unity is paused +5. If local or intermediate values matter, log only those values near the break and read them with `uloop-get-logs` 6. If visible output matters, capture a screenshot: `uloop screenshot --capture-mode rendering` -7. Report what happened +7. Report what happened and which evidence was used ## Tool Reference @@ -49,15 +49,14 @@ uloop simulate-mouse-input --action [options] | `SmoothDelta` | Mouse.current.delta (per-frame) | Inject mouse delta smoothly over `--duration` seconds (human-like camera pan) | | `Scroll` | Mouse.current.scroll | Inject scroll wheel input | -### Debug Break verification +### Optional Debug Break Inspection -- Consider one `UnityCliLoopDebug.Break("")` marker when a representative mouse input changes runtime state and exact-frame evidence would reduce uncertainty. Final logs, screenshots, or durable state may be enough for simpler checks. -- Use the marker before slowing time, sleeping, polling, or rewriting runtime code to work around a missed input frame. Treat those checks as supplements, not substitutes. -- If the mouse handler has local variables, intermediate calculations, or branch reasons that `execute-dynamic-code` cannot inspect after the fact, log just those values with `Debug.Log` immediately before the marker and read them with `get-logs` while Unity is paused. A marker-only check proves the line was reached, not the frame-local values. -- Put the marker at a natural state transition after the app consumed the mouse input, such as after a command is accepted, a state mutation is committed, an evaluation step resolves, a tracked value changes, or a dependent component is updated. Do not place it immediately after sending `simulate-mouse-input`. -- Treat `simulate-mouse-input Success=true`, generic action logs, and final durable counters as useful evidence, but not as paused-frame proof. -- If the response has `InterruptedByDebugBreak: true`, Unity is paused for inspection and the tool released its held input bookkeeping. If a `UnityCliLoopDebug.Break` marker caused the pause, `DebugBreakId` and `DebugBreakHitCount` identify it. Use `get-logs`, `get-hierarchy`, `find-game-objects`, or `execute-dynamic-code` before resuming. -- Use distinct marker ids for strict phases, for example `input-read`, `state-updated`, and `result-committed`. +- Use `UnityCliLoopDebug.Break("")` with `uloop-wait-for-debug-break` only when exact-frame evidence would reduce uncertainty. Final logs, screenshots, or durable state may be enough for simpler checks. +- Place the break at a natural state transition after the app consumed the mouse input, such as after a command is accepted, a state mutation is committed, an evaluation step resolves, a tracked value changes, or a dependent component is updated. Do not place it immediately after sending `simulate-mouse-input`. +- If the mouse handler has local variables, intermediate calculations, or branch reasons that `execute-dynamic-code` cannot inspect after the fact, log just those values near `UnityCliLoopDebug.Break("")` and read them with `uloop-get-logs` while Unity is paused. A break hit proves the line was reached, not the frame-local values. +- If the response has `InterruptedByDebugBreak: true`, Unity is paused for inspection and the tool released its held input bookkeeping. `DebugBreakId` and `DebugBreakHitCount` identify the break that paused Unity. Use `get-logs`, `get-hierarchy`, `find-game-objects`, or `execute-dynamic-code` before resuming. +- Use distinct ids for strict phases, for example `input-read`, `state-updated`, and `result-committed`. +- Remove temporary break/log instrumentation before final validation when it was added only for inspection. ### Global Options (optional) @@ -119,7 +118,7 @@ Returns JSON with: - `PositionX`: Target X coordinate (nullable float; populated for `Click` / `LongPress`) - `PositionY`: Target Y coordinate (nullable float; populated for `Click` / `LongPress`) - `InterruptedByDebugBreak`: True when Unity paused during Debug Break inspection and the input bookkeeping was safely released -- `DebugBreakId`: The marker id when a `UnityCliLoopDebug.Break` marker caused the interruption -- `DebugBreakHitCount`: The marker hit count when a `UnityCliLoopDebug.Break` marker caused the interruption +- `DebugBreakId`: The id from `UnityCliLoopDebug.Break("")` when it caused the interruption +- `DebugBreakHitCount`: The hit count for that `UnityCliLoopDebug.Break("")` There is no `DeltaX`, `DeltaY`, `ScrollX`, `ScrollY`, `Duration`, or hit-element field in the response — only the issued action, button, target position, and Debug Break interruption state are echoed back. Verify visual outcome with a follow-up screenshot. From f9745b244aee364c76c1339c31c953d1c2392043 Mon Sep 17 00:00:00 2001 From: hatayama Date: Wed, 10 Jun 2026 16:49:23 +0900 Subject: [PATCH 20/24] update --- .../Editor/FirstPartyTools/SimulateMouseInput/Skill/SKILL.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Packages/src/Editor/FirstPartyTools/SimulateMouseInput/Skill/SKILL.md b/Packages/src/Editor/FirstPartyTools/SimulateMouseInput/Skill/SKILL.md index 2b5892662..3bd239544 100644 --- a/Packages/src/Editor/FirstPartyTools/SimulateMouseInput/Skill/SKILL.md +++ b/Packages/src/Editor/FirstPartyTools/SimulateMouseInput/Skill/SKILL.md @@ -1,7 +1,7 @@ --- name: uloop-simulate-mouse-input toolName: simulate-mouse-input -description: "Simulate Mouse.current input in PlayMode through Unity Input System for gameplay clicks, movement delta, or scroll. For state-changing PlayMode/E2E mouse input, uloop-wait-for-debug-break can help when paired with UnityCliLoopDebug.Break(\"id\") to pause an inspectable frame; use uloop-get-logs if you also logged local/intermediate values. Use simulate-mouse-ui for UI." +description: "Simulates Mouse.current input in the PlayMode environment using the Unity Input System. Supports click actions, changes in movement speed, and scrolling during gameplay. When used in conjunction with UnityCliLoopDebug.Break(\"id\"), it allows pausing inspectable frames. For logging local values and intermediate values, please use uloop-get-logs. For UI interactions, use simulate-mouse-ui instead." context: fork --- From f8dc37a3fdafe3aa749c7cc3458f6245f074bbfe Mon Sep 17 00:00:00 2001 From: hatayama Date: Wed, 10 Jun 2026 16:55:52 +0900 Subject: [PATCH 21/24] Make mouse input debug-break guidance optional Removes Debug.Break wording from the simulate-mouse-input description and keeps Debug Break inspection as an optional follow-up in the workflow instead of the default path. --- .../FirstPartyTools/SimulateMouseInput/Skill/SKILL.md | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/Packages/src/Editor/FirstPartyTools/SimulateMouseInput/Skill/SKILL.md b/Packages/src/Editor/FirstPartyTools/SimulateMouseInput/Skill/SKILL.md index 3bd239544..0e6816841 100644 --- a/Packages/src/Editor/FirstPartyTools/SimulateMouseInput/Skill/SKILL.md +++ b/Packages/src/Editor/FirstPartyTools/SimulateMouseInput/Skill/SKILL.md @@ -1,7 +1,7 @@ --- name: uloop-simulate-mouse-input toolName: simulate-mouse-input -description: "Simulates Mouse.current input in the PlayMode environment using the Unity Input System. Supports click actions, changes in movement speed, and scrolling during gameplay. When used in conjunction with UnityCliLoopDebug.Break(\"id\"), it allows pausing inspectable frames. For logging local values and intermediate values, please use uloop-get-logs. For UI interactions, use simulate-mouse-ui instead." +description: "Simulate Mouse.current input in PlayMode through Unity Input System. Use for gameplay mouse clicks, held button input, movement delta, or scroll when runtime code reads Mouse.current. Use simulate-mouse-ui for UI." context: fork --- @@ -14,10 +14,9 @@ Simulate mouse input via Input System in Unity PlayMode. 1. Ensure Unity is in PlayMode (use `uloop control-play-mode --action Play` if not) 2. For Click/LongPress: determine the target screen position (use `uloop screenshot` to find coordinates) 3. Execute the needed `uloop simulate-mouse-input` commands -4. If exact-frame proof would reduce uncertainty, optionally pair the scenario with `UnityCliLoopDebug.Break("")` and `uloop-wait-for-debug-break`, then inspect while Unity is paused -5. If local or intermediate values matter, log only those values near the break and read them with `uloop-get-logs` -6. If visible output matters, capture a screenshot: `uloop screenshot --capture-mode rendering` -7. Report what happened and which evidence was used +4. Inspect the result with the lightest useful evidence: runtime state, logs, or a screenshot +5. If exact-frame proof would reduce uncertainty, treat Debug Break inspection as an optional follow-up using the section below +6. Report what happened and which evidence was used ## Tool Reference @@ -51,7 +50,7 @@ uloop simulate-mouse-input --action [options] ### Optional Debug Break Inspection -- Use `UnityCliLoopDebug.Break("")` with `uloop-wait-for-debug-break` only when exact-frame evidence would reduce uncertainty. Final logs, screenshots, or durable state may be enough for simpler checks. +- This is optional. Use `UnityCliLoopDebug.Break("")` with `uloop-wait-for-debug-break` only when exact-frame evidence would reduce uncertainty. Final logs, screenshots, or durable state may be enough for simpler checks. - Place the break at a natural state transition after the app consumed the mouse input, such as after a command is accepted, a state mutation is committed, an evaluation step resolves, a tracked value changes, or a dependent component is updated. Do not place it immediately after sending `simulate-mouse-input`. - If the mouse handler has local variables, intermediate calculations, or branch reasons that `execute-dynamic-code` cannot inspect after the fact, log just those values near `UnityCliLoopDebug.Break("")` and read them with `uloop-get-logs` while Unity is paused. A break hit proves the line was reached, not the frame-local values. - If the response has `InterruptedByDebugBreak: true`, Unity is paused for inspection and the tool released its held input bookkeeping. `DebugBreakId` and `DebugBreakHitCount` identify the break that paused Unity. Use `get-logs`, `get-hierarchy`, `find-game-objects`, or `execute-dynamic-code` before resuming. From 5ab933b2b581e5fa192eb6cb0527e5d7b25722ec Mon Sep 17 00:00:00 2001 From: hatayama Date: Wed, 10 Jun 2026 17:00:32 +0900 Subject: [PATCH 22/24] Simplify mouse input skill wording Remove redundant optional phrasing and keep the simulate-mouse-input description focused on the command's mouse input use case. --- .../Editor/FirstPartyTools/SimulateMouseInput/Skill/SKILL.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Packages/src/Editor/FirstPartyTools/SimulateMouseInput/Skill/SKILL.md b/Packages/src/Editor/FirstPartyTools/SimulateMouseInput/Skill/SKILL.md index 0e6816841..8bb19ad24 100644 --- a/Packages/src/Editor/FirstPartyTools/SimulateMouseInput/Skill/SKILL.md +++ b/Packages/src/Editor/FirstPartyTools/SimulateMouseInput/Skill/SKILL.md @@ -1,7 +1,7 @@ --- name: uloop-simulate-mouse-input toolName: simulate-mouse-input -description: "Simulate Mouse.current input in PlayMode through Unity Input System. Use for gameplay mouse clicks, held button input, movement delta, or scroll when runtime code reads Mouse.current. Use simulate-mouse-ui for UI." +description: "Simulate Mouse.current input in PlayMode through Unity Input System. Use for gameplay mouse clicks, held button input, movement delta, or scroll. Use simulate-mouse-ui for UI." context: fork --- @@ -50,7 +50,7 @@ uloop simulate-mouse-input --action [options] ### Optional Debug Break Inspection -- This is optional. Use `UnityCliLoopDebug.Break("")` with `uloop-wait-for-debug-break` only when exact-frame evidence would reduce uncertainty. Final logs, screenshots, or durable state may be enough for simpler checks. +- Use `UnityCliLoopDebug.Break("")` with `uloop-wait-for-debug-break` only when exact-frame evidence would reduce uncertainty. Final logs, screenshots, or durable state may be enough for simpler checks. - Place the break at a natural state transition after the app consumed the mouse input, such as after a command is accepted, a state mutation is committed, an evaluation step resolves, a tracked value changes, or a dependent component is updated. Do not place it immediately after sending `simulate-mouse-input`. - If the mouse handler has local variables, intermediate calculations, or branch reasons that `execute-dynamic-code` cannot inspect after the fact, log just those values near `UnityCliLoopDebug.Break("")` and read them with `uloop-get-logs` while Unity is paused. A break hit proves the line was reached, not the frame-local values. - If the response has `InterruptedByDebugBreak: true`, Unity is paused for inspection and the tool released its held input bookkeeping. `DebugBreakId` and `DebugBreakHitCount` identify the break that paused Unity. Use `get-logs`, `get-hierarchy`, `find-game-objects`, or `execute-dynamic-code` before resuming. From 02aa18a3f38b6a8cace0f62cde581b34a1eecf95 Mon Sep 17 00:00:00 2001 From: hatayama Date: Wed, 10 Jun 2026 17:03:44 +0900 Subject: [PATCH 23/24] Make mouse UI debug break guidance optional Remove debug-break triggering language from the simulate-mouse-ui description, make paused-frame inspection an optional follow-up in the workflow, and remove the unresolved task argument placeholder. --- .../SimulateMouseUi/Skill/SKILL.md | 27 +++++++++---------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/Packages/src/Editor/FirstPartyTools/SimulateMouseUi/Skill/SKILL.md b/Packages/src/Editor/FirstPartyTools/SimulateMouseUi/Skill/SKILL.md index 14b590409..3629eeff8 100644 --- a/Packages/src/Editor/FirstPartyTools/SimulateMouseUi/Skill/SKILL.md +++ b/Packages/src/Editor/FirstPartyTools/SimulateMouseUi/Skill/SKILL.md @@ -1,24 +1,23 @@ --- name: uloop-simulate-mouse-ui toolName: simulate-mouse-ui -description: "Simulate PlayMode EventSystem UI mouse actions using screen coordinates. For state-changing PlayMode/E2E UI actions, also use uloop-wait-for-debug-break; when frame-local values matter, pair the marker with focused Debug.Log and get-logs before resuming." +description: "Simulate PlayMode EventSystem UI mouse actions using screen coordinates. Use for UI clicks, long-presses, or drags from annotated screenshots." context: fork --- # Task -Simulate mouse interaction on Unity PlayMode UI: $ARGUMENTS +Simulate mouse interaction on Unity PlayMode UI. ## Workflow 1. Ensure Unity is in PlayMode (use `uloop control-play-mode --action Play` if not) 2. Get UI element info: `uloop screenshot --capture-mode rendering --annotate-elements --elements-only` 3. Use the `AnnotatedElements` array to find the target element by `Label`, `Name`, or `Path` (A=frontmost, B=next, ...). Use `Interaction` to distinguish click targets from drag/drop/text targets, then use `SimX`/`SimY` directly as `--x`/`--y` coordinates. -4. If this UI action changes runtime state, pick one representative frame for paused variable/state proof before relying on logs, screenshots, or durable state -5. For that representative transition, place and enable a `UnityCliLoopDebug.Break("")` marker, then run the UI action and inspect while Unity is paused -6. Execute any remaining `uloop simulate-mouse-ui` commands -7. Take a screenshot to verify the visible result: `uloop screenshot --capture-mode rendering --annotate-elements` -8. Report what happened +4. Execute the needed `uloop simulate-mouse-ui` commands +5. Inspect the result with the lightest useful evidence: runtime state, logs, or a screenshot +6. If exact-frame proof would reduce uncertainty, treat Debug Break inspection as an optional follow-up using the section below +7. Report what happened and which evidence was used ## Tool Reference @@ -77,14 +76,14 @@ uloop simulate-mouse-ui --action --x --y [options] - `--bypass-raycast` still uses coordinates for pointer event positions, but chooses the clicked, long-pressed, or dragged GameObject by `--target-path` - If `--target-path` or `--drop-target-path` matches multiple active GameObjects, the command fails instead of choosing an arbitrary duplicate -## Debug Break Verification +## Optional Debug Break Inspection -- Use one `UnityCliLoopDebug.Break("")` marker for at least one representative UI action that changes runtime state. This applies even when final logs, screenshots, or durable state later show the outcome, because it pauses the exact frame where variables/state can prove input consumption. -- Use the marker before slowing time, sleeping, polling, or rewriting runtime code to work around a missed input frame. Treat those checks as supplements, not substitutes. -- If the UI handler has local variables, intermediate calculations, or branch reasons that `execute-dynamic-code` cannot inspect after the fact, log just those values with `Debug.Log` immediately before the marker and read them with `get-logs` while Unity is paused. A marker-only check proves the line was reached, not the frame-local values. -- Put the marker at a natural transition after the app consumed the UI event, such as after a command is accepted, a state mutation is committed, a tracked value changes, a UI/domain state syncs, or a success/failure/end condition is entered. -- Treat `simulate-mouse-ui Success=true`, generic action logs, and final durable counters as useful evidence, but not as paused-frame proof. -- If a `UnityCliLoopDebug.Break` marker pauses Unity, inspect with `get-logs`, `get-hierarchy`, `find-game-objects`, or `execute-dynamic-code` before resuming. +- Use `UnityCliLoopDebug.Break("")` with `uloop-wait-for-debug-break` only when exact-frame evidence would reduce uncertainty. Final logs, screenshots, or durable state may be enough for simpler checks. +- Place the break at a natural transition after the app consumed the UI event, such as after a command is accepted, a state mutation is committed, a tracked value changes, a UI/domain state syncs, or a success/failure/end condition is entered. +- If the UI handler has local variables, intermediate calculations, or branch reasons that `execute-dynamic-code` cannot inspect after the fact, log just those values near `UnityCliLoopDebug.Break("")` and read them with `uloop-get-logs` while Unity is paused. A break hit proves the line was reached, not the frame-local values. +- Treat `simulate-mouse-ui Success=true`, generic action logs, and final durable counters as useful evidence, not paused-frame proof. +- If a `UnityCliLoopDebug.Break` pauses Unity, inspect with `get-logs`, `get-hierarchy`, `find-game-objects`, or `execute-dynamic-code` before resuming. +- Remove temporary break/log instrumentation before final validation when it was added only for inspection. ## Examples From 75c5323a75c5e6c2e9a086ec1c0b5bc1e7ca50cd Mon Sep 17 00:00:00 2001 From: hatayama Date: Wed, 10 Jun 2026 17:16:30 +0900 Subject: [PATCH 24/24] Address keyboard workflow review feedback Make the simulate-keyboard debug-break guidance an optional follow-up after normal input execution, and validate the execute-dynamic-code response when opening the sample scene. --- .../SimulateKeyboard/Skill/SKILL.md | 18 ++++++++---------- scripts/refresh-neighbor-game-skills.sh | 17 ++++++++++++++++- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/Packages/src/Editor/FirstPartyTools/SimulateKeyboard/Skill/SKILL.md b/Packages/src/Editor/FirstPartyTools/SimulateKeyboard/Skill/SKILL.md index d865b0adf..210b8cc58 100644 --- a/Packages/src/Editor/FirstPartyTools/SimulateKeyboard/Skill/SKILL.md +++ b/Packages/src/Editor/FirstPartyTools/SimulateKeyboard/Skill/SKILL.md @@ -1,7 +1,7 @@ --- name: uloop-simulate-keyboard toolName: simulate-keyboard -description: "Simulate keyboard input in PlayMode through Unity Input System. For state-changing PlayMode/E2E input, also use uloop-wait-for-debug-break; when frame-local values matter, pair the marker with focused Debug.Log and get-logs before resuming." +description: "Simulate keyboard input in PlayMode through Unity Input System. Use for key presses, holds, releases, and game controls such as WASD or Space." context: fork --- @@ -12,11 +12,10 @@ Simulate keyboard input on Unity PlayMode: $ARGUMENTS ## Workflow 1. Ensure Unity is in PlayMode (use `uloop control-play-mode --action Play` if not) -2. If exact-frame proof would reduce uncertainty for a state-changing E2E check, pick one representative frame for paused variable/state inspection -3. For that optional representative transition, place and enable a `UnityCliLoopDebug.Break("")` marker, then run the input and inspect while Unity is paused -4. Execute the needed `uloop simulate-keyboard` commands -5. If visible output matters, capture a screenshot: `uloop screenshot --capture-mode rendering` -6. Report what happened +2. Execute the needed `uloop simulate-keyboard` commands +3. Inspect the result with the lightest useful evidence: runtime state, logs, or a screenshot +4. If exact-frame proof would reduce uncertainty, treat Debug Break inspection as an optional follow-up using the section below +5. Report what happened and which evidence was used ## Tool Reference @@ -45,12 +44,11 @@ Use `Press` for edge-triggered keyboard code such as `Keyboard.current.spaceKey. If a successful `Press` or `KeyDown` leaves `Keyboard.current..isPressed` true but runtime state does not change, do not immediately rewrite the user's runtime code to `isPressed`. First verify that the target component is active during the command, that it polls input in the configured Input System update phase, and that a missed `KeyDown` edge is followed by `KeyUp` before retrying. Use `KeyDown` / `KeyUp` when the scenario intentionally needs a held key. -### Debug Break verification +### Optional Debug Break Inspection -- Consider one `UnityCliLoopDebug.Break("")` marker when a representative keyboard input changes runtime state and exact-frame evidence would reduce uncertainty. Final logs, screenshots, or durable state may be enough for simpler checks. -- Use the marker before slowing time, sleeping, polling, or rewriting runtime code to work around a missed input frame. Treat those checks as supplements, not substitutes. -- If the key handler has local variables, intermediate calculations, or branch reasons that `execute-dynamic-code` cannot inspect after the fact, log just those values with `Debug.Log` immediately before the marker and read them with `get-logs` while Unity is paused. A marker-only check proves the line was reached, not the frame-local values. +- Use `UnityCliLoopDebug.Break("")` with `uloop-wait-for-debug-break` only when exact-frame evidence would reduce uncertainty. Final logs, screenshots, or durable state may be enough for simpler checks. - Put the marker at a natural state transition after the app consumed the key, such as after a command is accepted, a state mutation is committed, an evaluation step resolves, or a dependent component is updated. Do not place it immediately after sending `simulate-keyboard`. +- If the key handler has local variables, intermediate calculations, or branch reasons that `execute-dynamic-code` cannot inspect after the fact, log just those values near `UnityCliLoopDebug.Break("")` and read them with `uloop-get-logs` while Unity is paused. A break hit proves the line was reached, not the frame-local values. - Treat `simulate-keyboard Success=true`, generic action logs, and final durable counters as useful evidence, but not as paused-frame proof. - If the response has `InterruptedByDebugBreak: true`, Unity is paused for inspection and the tool released its held input bookkeeping. If a `UnityCliLoopDebug.Break` marker caused the pause, `DebugBreakId` and `DebugBreakHitCount` identify it. Use `get-logs`, `get-hierarchy`, `find-game-objects`, or `execute-dynamic-code` before resuming. - Use distinct marker ids for strict phases, for example `input-read`, `state-updated`, and `result-committed`. diff --git a/scripts/refresh-neighbor-game-skills.sh b/scripts/refresh-neighbor-game-skills.sh index 29e3705e5..e84b8e0f5 100755 --- a/scripts/refresh-neighbor-game-skills.sh +++ b/scripts/refresh-neighbor-game-skills.sh @@ -381,7 +381,22 @@ if (SceneManager.GetActiveScene().path != scenePath) return SceneManager.GetActiveScene().path; " - run "$uloop_bin" --project-path "$project" execute-dynamic-code --code "$code" + if [ "$dry_run" -eq 1 ]; then + run "$uloop_bin" --project-path "$project" execute-dynamic-code --code "$code" + return 0 + fi + + command -v jq >/dev/null 2>&1 || fail "jq is not available on PATH" + response='' + if ! response=$("$uloop_bin" --project-path "$project" execute-dynamic-code --code "$code"); then + [ -z "$response" ] || printf '%s\n' "$response" >&2 + fail "failed to execute sample scene open command: $project" + fi + + if ! printf '%s\n' "$response" | jq -e --arg scene_path "$sample_scene_path" '.Success == true and .Result == $scene_path' >/dev/null; then + printf '%s\n' "$response" >&2 + fail "failed to open sample scene: $project" + fi } parse_args "$@"