Skip to content
11 changes: 2 additions & 9 deletions .agents/skills/uloop-execute-dynamic-code/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@ Run focused C# snippets in the active Unity Editor with `uloop execute-dynamic-c

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, enable a source pause point on that line instead (`uloop enable-pause-point --file <file> --line <line>`, see the `uloop-pause-point` skill): the hit response's `CapturedVariables` already contains the locals, parameters, and instance fields at that line, with no code edit or recompile. `CapturedVariables` is a pre-line snapshot; this tool during the pause sees the interrupted method's post-interrupt state instead. While Unity stays paused on the hit, use `UloopPausePoint.TryGetCapturedValue(name)` (plus `GetCapturedNames()` / `GetCapturedPausePointId()`) for live captured references such as collections. Do not try to reconstruct pre-line locals with execute-dynamic-code alone.

The reverse combination also works: to freeze Unity on the first frame where a runtime condition holds (an animation peak, HP reaching zero, an enemy spawning), enable an id-only pause point, then use this tool to register an `EditorApplication.update` watcher that calls `UloopPausePoint.Pause(id)` when the condition is met, and return immediately. Wait with `uloop await-pause-point` on the CLI side — never poll or sleep inside the snippet itself, because the body runs synchronously on the main thread and frames stop advancing. See "Catching a Runtime Condition with a Dynamic-Code Trigger" in the `uloop-pause-point` skill.
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 — do not try to reconstruct them with this tool alone. When those values matter, follow the `uloop-pause-point` skill instead: a pause point's `CapturedVariables` already contains the locals, parameters, and instance fields at that line with no code edit or recompile, and while Unity stays paused `UloopPausePoint.TryGetCapturedValue(name)` gives this tool live captured references. That skill also covers the reverse combination — using this tool to register an `EditorApplication.update` watcher that freezes Unity on the first frame a runtime condition holds (never poll or sleep inside the snippet itself; the body runs synchronously on the main thread).

Live state injection: when a running PlayMode session is merely in the wrong state — a stuck end-to-end scenario, a camera angle from which a raycast can never hit, a private flag blocking the path you want to test — fix the state instead of the code: write the field directly from this tool (reflection reaches private fields) and steer the session onward. Nothing recompiles and no domain reload happens, so the session's in-memory state (component references, in-progress fixtures, accumulated counters) survives intact, where stopping Play mode to edit code would throw it all away. Because the snippet is a one-off diagnostic that never lands in the project's source files, using reflection here does not spread reflection through production code — a useful property even in projects whose coding rules restrict reflection.

Expand Down Expand Up @@ -44,12 +42,7 @@ Prefer terminal commands for file operations and keep snippets focused on Unity

## Shell Quoting

- zsh/bash: single-quote the whole snippet so C# double quotes pass through unchanged: `--code 'return "hi";'`. For a single quote inside the snippet, close and reopen the shell string with `'\''`.
- PowerShell 7 (`pwsh`): for multiline snippets, assign a single-quoted here-string (`$code = @'` ... `'@`) and pass `--code $code`. Inline, single-quoted arguments preserve C# double quotes; double an inner single quote (`''`).
- Windows PowerShell 5.1 removes unescaped double quotes from native command arguments: escape them as `\"`, or prefer `--code-file`.
- Pass `--parameters` as a single-quoted JSON object literal in both shells, for example `--parameters '{"param0":"value"}'`.
- On Windows, multiline `--code` requires the native `uloop.exe`. If `(Get-Command uloop).Source` resolves to a legacy `.cmd` shim, run `uloop install` and open a new terminal.
- If quoting still mangles the snippet, switch to `--code-file`.
In zsh/bash, single-quote the whole snippet so C# double quotes pass through unchanged: `--code 'return "hi";'`. If a snippet fails to parse, gets mangled by the shell, or you are on Windows/PowerShell, read [references/shell-quoting.md](references/shell-quoting.md) — or switch to `--code-file`.

## When To Use Input Simulation Tools Instead

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Shell Quoting for --code

Read this when an inline `--code` snippet fails to parse, gets mangled by the shell, or when running on Windows.

- zsh/bash: single-quote the whole snippet so C# double quotes pass through unchanged: `--code 'return "hi";'`. For a single quote inside the snippet, close and reopen the shell string with `'\''`.
- PowerShell 7 (`pwsh`): for multiline snippets, assign a single-quoted here-string (`$code = @'` ... `'@`) and pass `--code $code`. Inline, single-quoted arguments preserve C# double quotes; double an inner single quote (`''`).
- Windows PowerShell 5.1 removes unescaped double quotes from native command arguments: escape them as `\"`, or prefer `--code-file`.
- Pass `--parameters` as a single-quoted JSON object literal in both shells, for example `--parameters '{"param0":"value"}'`.
- On Windows, multiline `--code` requires the native `uloop.exe`. If `(Get-Command uloop).Source` resolves to a legacy `.cmd` shim, run `uloop install` and open a new terminal.
- If quoting still mangles the snippet, switch to `--code-file`.
Loading