Skip to content

feat: Debug.Break pauses can now be inspected with uloop - #1279

Closed
hatayama wants to merge 9 commits into
v3-betafrom
feature/hatayama/wait-for-debug-break
Closed

feat: Debug.Break pauses can now be inspected with uloop#1279
hatayama wants to merge 9 commits into
v3-betafrom
feature/hatayama/wait-for-debug-break

Conversation

@hatayama

@hatayama hatayama commented Jun 2, 2026

Copy link
Copy Markdown
Owner

Summary

  • Adds a wait command for Debug.Break so agents can pause at a planned runtime moment and inspect Unity state while PlayMode is frozen.
  • Documents how scheduled Debug.Break checks can verify keyboard, gameplay mouse, and UI mouse input when screenshots are not enough.

User Impact

  • Agents no longer need to infer runtime state only from noisy live logs or screenshots after simulated input.
  • After an action such as jumping with Space, placing an object with mouse input, or clicking UI, agents can wait for the planned pause and inspect logs, hierarchy, and component state before resuming PlayMode.

Changes

  • Adds the native uloop wait-for-debug-break command and a lightweight internal PlayMode state bridge.
  • Adds control-play-mode --action NextFrame for paused PlayMode frame inspection.
  • Updates the CLI version contract and minimum required CLI version to 3.0.0-beta.25.
  • Adds and regenerates agent skill documentation for Debug.Break inspection workflows.

Verification

  • scripts/check-go-cli.sh
  • cli/dist/darwin-arm64/uloop compile --project-path "$(git rev-parse --show-toplevel)"
  • cli/dist/darwin-arm64/uloop run-tests --project-path "$(git rev-parse --show-toplevel)" --test-mode EditMode --filter-type regex --filter-value "ControlPlayModeUseCaseTests|JsonRpcProcessorCliVersionGateTests|PlayModeStateBridgeCommandTests|CliSetupApplicationServiceTests"
  • git diff --check
  • codex-review v3-beta

hatayama added 5 commits June 2, 2026 22:08
Add a native wait command that polls Unity pause state so agents can stop at Debug.Break without relying on noisy logs. Expose a lightweight play mode state bridge, add one-frame stepping for paused PlayMode inspection, and require the CLI version that contains the new command.
Add the wait-for-debug-break skill and update control-play-mode guidance so agents know how to step paused PlayMode frames and resume after Debug.Break inspection.
Explain how execute-dynamic-code can schedule a Debug.Break from runtime inspection code and pair it with wait-for-debug-break for frozen-state investigation.
Update generated agent skill copies after documenting scheduled Debug.Break inspection in the source execute-dynamic-code skill.
Explain how keyboard, gameplay mouse, and UI mouse simulations can pair with scheduled Debug.Break waits when screenshots cannot prove that input changed runtime state.
@coderabbitai

coderabbitai Bot commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 6bc93554-5cd0-4e15-b38b-c07cf835be44

📥 Commits

Reviewing files that changed from the base of the PR and between b1ea5f9 and 5fed63b.

📒 Files selected for processing (15)
  • .agents/skills/uloop-simulate-keyboard/SKILL.md
  • .agents/skills/uloop-simulate-mouse-input/SKILL.md
  • .agents/skills/uloop-simulate-mouse-ui/SKILL.md
  • .claude/skills/uloop-simulate-keyboard/SKILL.md
  • .claude/skills/uloop-simulate-mouse-input/SKILL.md
  • .claude/skills/uloop-simulate-mouse-ui/SKILL.md
  • Packages/src/Editor/FirstPartyTools/SimulateKeyboard/Skill/SKILL.md
  • Packages/src/Editor/FirstPartyTools/SimulateMouseInput/Skill/SKILL.md
  • Packages/src/Editor/FirstPartyTools/SimulateMouseUi/Skill/SKILL.md
  • cli/internal/cli/error_envelope.go
  • cli/internal/cli/wait_for_debug_break.go
  • cli/internal/cli/wait_for_debug_break_test.go
  • scripts/check-build-link-go-cli.sh
  • scripts/test-use-local-uloop.sh
  • scripts/use-local-uloop.sh
✅ Files skipped from review due to trivial changes (6)
  • .claude/skills/uloop-simulate-mouse-input/SKILL.md
  • Packages/src/Editor/FirstPartyTools/SimulateMouseInput/Skill/SKILL.md
  • Packages/src/Editor/FirstPartyTools/SimulateMouseUi/Skill/SKILL.md
  • .agents/skills/uloop-simulate-mouse-input/SKILL.md
  • .agents/skills/uloop-simulate-mouse-ui/SKILL.md
  • .claude/skills/uloop-simulate-keyboard/SKILL.md
🚧 Files skipped from review as they are similar to previous changes (3)
  • .claude/skills/uloop-simulate-mouse-ui/SKILL.md
  • cli/internal/cli/error_envelope.go
  • .agents/skills/uloop-simulate-keyboard/SKILL.md

📝 Walkthrough

Walkthrough

Adds PlayModeAction.NextFrame with one-frame stepping when paused; introduces an internal get-play-mode-state bridge and GetPlayModeStateResponse; implements a native wait-for-debug-break command that polls until Unity pauses; updates skill docs with Debug.Break verification workflows and bumps CLI/contract versions; adjusts local CLI install scripts to copy binaries.

Changes

Debug.Break inspection and frame-stepping features

Layer / File(s) Summary
NextFrame play-mode action
Packages/src/Editor/FirstPartyTools/ControlPlayMode/ControlPlayModeSchema.cs, Packages/src/Editor/FirstPartyTools/ControlPlayMode/ControlPlayModeUseCase.cs, Assets/Tests/Editor/ControlPlayModeUseCaseTests.cs, cli/internal/cli/control_play_mode_wait_test.go, Packages/src/Editor/FirstPartyTools/ControlPlayMode/Skill/SKILL.md, .agents/skills/uloop-control-play-mode/SKILL.md, .claude/skills/uloop-control-play-mode/SKILL.md, cli/internal/tools/default-tools.json
PlayModeAction.NextFrame enum advances exactly one frame only when Unity is playing and paused; implementation calls EditorApplication.Step() in that case and returns "Next frame ignored" otherwise; CLI wait logic does not treat NextFrame as a waitable transition.
Play mode state bridge command
Packages/src/Editor/Infrastructure/Api/GetPlayModeStateResponse.cs, Packages/src/Editor/ToolContracts/UnityCliLoopConstants.cs, Packages/src/Editor/Infrastructure/Api/PlayModeStateBridgeCommand.cs, Packages/src/Editor/Infrastructure/Api/InternalBridgeCommandRouter.cs, Assets/Tests/Editor/PlayModeStateBridgeCommandTests.cs, Assets/Tests/Editor/JsonRpcProcessorCliVersionGateTests.cs
Adds get-play-mode-state internal bridge command, response DTO with IsPlaying/IsPaused/Message, router handling, and tests verifying response content and bridge execution while a tool slot is busy.
Wait-for-debug-break CLI command and integration
cli/internal/cli/wait_for_debug_break.go, cli/internal/cli/wait_for_debug_break_test.go, cli/internal/cli/command_registry.go, cli/internal/cli/command_help.go, cli/internal/cli/run.go, cli/internal/cli/error_envelope.go, cli/internal/cli/error_envelope_test.go, cli/internal/cli/completion_test.go, Packages/src/Editor/CliOnlyTools~/WaitForDebugBreak/Skill/SKILL.md, .agents/skills/uloop-wait-for-debug-break/SKILL.md, .claude/skills/uloop-wait-for-debug-break/SKILL.md
Implements wait-for-debug-break native command that polls internal bridge until Unity pauses; exits early with structured retryable errors when Unity is already paused or not playing; integrated into CLI registry, help, routing, completion, and includes comprehensive unit tests and skill docs.
Documentation for Debug.Break verification in simulation tools
Packages/src/Editor/FirstPartyTools/ExecuteDynamicCode/Skill/SKILL.md, Packages/src/Editor/FirstPartyTools/ExecuteDynamicCode/Skill/references/playmode-inspection.md, Packages/src/Editor/FirstPartyTools/SimulateKeyboard/Skill/SKILL.md, Packages/src/Editor/FirstPartyTools/SimulateMouseInput/Skill/SKILL.md, Packages/src/Editor/FirstPartyTools/SimulateMouseUi/Skill/SKILL.md, .agents/skills/uloop-execute-dynamic-code/*, .agents/skills/uloop-simulate-*/SKILL.md, .claude/skills/uloop-execute-dynamic-code/*, .claude/skills/uloop-simulate-*/SKILL.md
Adds scheduled Debug.Break examples and a Debug.Break Verification Workflow to simulation and dynamic-code docs: schedule a delayed Debug.Break() (log state), run uloop wait-for-debug-break in another session, trigger input during delay, inspect frozen state, then resume PlayMode.
CLI version constant and contract updates
Packages/src/Editor/Domain/CliConstants.cs, cli/contract.json, Assets/Tests/Editor/CliSetupApplicationServiceTests.cs, cli/internal/tools/default-tools.json
Bumps minimum required CLI version and default-tools package version to 3.0.0-beta.25, updates tests and default tool schema to include NextFrame option for control-play-mode.
Local CLI copy/link script changes
scripts/check-build-link-go-cli.sh, scripts/test-use-local-uloop.sh, scripts/use-local-uloop.sh
Switches local CLI linking from symlink semantics to copying the rebuilt uloop binary into global bins (temp-file + mv), updates tests to compare binary contents, and disables restore behavior in the helper script.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 21.28% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat: Debug.Break pauses can now be inspected with uloop' accurately and specifically summarizes the main feature addition: enabling inspection of PlayMode during Debug.Break pauses using the uloop command.
Description check ✅ Passed The description thoroughly explains the changes, user impact, implementation details, and verification steps—all directly related to the changeset covering Debug.Break inspection, NextFrame action, CLI version updates, and documentation.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/hatayama/wait-for-debug-break

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@cli/internal/cli/wait_for_debug_break.go`:
- Around line 65-72: The guard only checks initialState.IsPaused but should also
reject when Unity is not in PlayMode (initialState.IsPlaying == false &&
initialState.IsPaused == false) to avoid hanging in waitForDebugBreak; update
the logic around initialState (before spinner.Update/Waiting) to stop the
spinner, surface a clear error via writeErrorEnvelope (or add a new error helper
like debugBreakNotPlayingError) and return a non-zero exit code when neither
IsPlaying nor IsPaused is true, otherwise proceed to call waitForDebugBreak as
before.
- Around line 114-135: The polling loop in waitForDebugBreak currently drops
errors from queryPlayModeState and only returns ctx.Err() on context expiry;
preserve the most recent query error (e.g., add a variable lastErr updated
whenever queryPlayModeState returns a non-nil err) and when the context is done
return lastErr (or lastState, lastErr) instead of always returning ctx.Err();
update the select branch to return lastState and lastErr if lastErr != nil,
otherwise return ctx.Err() to keep existing behavior when no query errors
occurred.
- Around line 37-43: The overall wait currently can block indefinitely because
runWaitForDebugBreak passes a background context through to waitForDebugBreak;
wrap the incoming ctx in runWaitForDebugBreak with a context.WithTimeout using a
new total timeout constant (e.g., waitForDebugBreakOverallTimeout) and defer
cancel(), then pass that derived ctx into waitForDebugBreak so the whole
operation has a deadline while preserving per-probe timeouts
(waitForDebugBreakStatusProbeTimeout) used inside waitForDebugBreak; ensure you
handle the ctx.Err()/deadline-exceeded case and return an appropriate non-zero
exit code.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: d61434ca-d7d3-49a3-a518-f1104d59069e

📥 Commits

Reviewing files that changed from the base of the PR and between b0608f3 and b1ea5f9.

⛔ Files ignored due to path filters (3)
  • Assets/Tests/Editor/PlayModeStateBridgeCommandTests.cs.meta is excluded by none and included by none
  • Packages/src/Editor/Infrastructure/Api/GetPlayModeStateResponse.cs.meta is excluded by none and included by none
  • Packages/src/Editor/Infrastructure/Api/PlayModeStateBridgeCommand.cs.meta is excluded by none and included by none
📒 Files selected for processing (43)
  • .agents/skills/uloop-control-play-mode/SKILL.md
  • .agents/skills/uloop-execute-dynamic-code/SKILL.md
  • .agents/skills/uloop-execute-dynamic-code/references/playmode-inspection.md
  • .agents/skills/uloop-simulate-keyboard/SKILL.md
  • .agents/skills/uloop-simulate-mouse-input/SKILL.md
  • .agents/skills/uloop-simulate-mouse-ui/SKILL.md
  • .agents/skills/uloop-wait-for-debug-break/SKILL.md
  • .claude/skills/uloop-control-play-mode/SKILL.md
  • .claude/skills/uloop-execute-dynamic-code/SKILL.md
  • .claude/skills/uloop-execute-dynamic-code/references/playmode-inspection.md
  • .claude/skills/uloop-simulate-keyboard/SKILL.md
  • .claude/skills/uloop-simulate-mouse-input/SKILL.md
  • .claude/skills/uloop-simulate-mouse-ui/SKILL.md
  • .claude/skills/uloop-wait-for-debug-break/SKILL.md
  • Assets/Tests/Editor/CliSetupApplicationServiceTests.cs
  • Assets/Tests/Editor/ControlPlayModeUseCaseTests.cs
  • Assets/Tests/Editor/JsonRpcProcessorCliVersionGateTests.cs
  • Assets/Tests/Editor/PlayModeStateBridgeCommandTests.cs
  • Packages/src/Editor/CliOnlyTools~/WaitForDebugBreak/Skill/SKILL.md
  • Packages/src/Editor/Domain/CliConstants.cs
  • Packages/src/Editor/FirstPartyTools/ControlPlayMode/ControlPlayModeSchema.cs
  • Packages/src/Editor/FirstPartyTools/ControlPlayMode/ControlPlayModeUseCase.cs
  • Packages/src/Editor/FirstPartyTools/ControlPlayMode/Skill/SKILL.md
  • Packages/src/Editor/FirstPartyTools/ExecuteDynamicCode/Skill/SKILL.md
  • Packages/src/Editor/FirstPartyTools/ExecuteDynamicCode/Skill/references/playmode-inspection.md
  • Packages/src/Editor/FirstPartyTools/SimulateKeyboard/Skill/SKILL.md
  • Packages/src/Editor/FirstPartyTools/SimulateMouseInput/Skill/SKILL.md
  • Packages/src/Editor/FirstPartyTools/SimulateMouseUi/Skill/SKILL.md
  • Packages/src/Editor/Infrastructure/Api/GetPlayModeStateResponse.cs
  • Packages/src/Editor/Infrastructure/Api/InternalBridgeCommandRouter.cs
  • Packages/src/Editor/Infrastructure/Api/PlayModeStateBridgeCommand.cs
  • Packages/src/Editor/ToolContracts/UnityCliLoopConstants.cs
  • cli/contract.json
  • cli/internal/cli/command_help.go
  • cli/internal/cli/command_registry.go
  • cli/internal/cli/completion_test.go
  • cli/internal/cli/control_play_mode_wait_test.go
  • cli/internal/cli/error_envelope.go
  • cli/internal/cli/error_envelope_test.go
  • cli/internal/cli/run.go
  • cli/internal/cli/wait_for_debug_break.go
  • cli/internal/cli/wait_for_debug_break_test.go
  • cli/internal/tools/default-tools.json

Comment thread cli/internal/cli/wait_for_debug_break.go
Comment thread cli/internal/cli/wait_for_debug_break.go
Comment thread cli/internal/cli/wait_for_debug_break.go
Make local CLI activation overwrite the global uloop executable with the current checkout binary so stale backups or symlink targets do not block development workflows.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

2 issues found across 46 files

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread cli/internal/cli/wait_for_debug_break.go
Comment thread Packages/src/Editor/FirstPartyTools/SimulateKeyboard/Skill/SKILL.md Outdated
hatayama added 2 commits June 2, 2026 22:44
Fast-fail wait-for-debug-break when Unity is not in PlayMode and preserve the last polling error so users see the underlying probe failure instead of only a generic cancellation.
Avoid directing input simulation skills to execute dynamic code directly while preserving the Debug.Break verification workflow through temporary project markers.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

2 issues found across 15 files (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread scripts/use-local-uloop.sh Outdated
Comment thread scripts/check-build-link-go-cli.sh Outdated
Copy local CLI binaries to temporary files before replacing the global uloop executable so a failed copy does not remove the working command.
@hatayama hatayama closed this Jun 3, 2026
@hatayama
hatayama deleted the feature/hatayama/wait-for-debug-break branch July 10, 2026 12:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant