Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .agents/skills/uloop-compile/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Execute Unity project compilation.
## Usage

```bash
uloop compile [--force-recompile] [--no-wait-for-domain-reload] [--stop-on-external-scene-changes]
uloop compile [--force-recompile] [--no-wait-for-domain-reload] [--stop-on-external-scene-changes] [--compile-wait-timeout-seconds <seconds>]
```

## Parameters
Expand All @@ -21,6 +21,7 @@ uloop compile [--force-recompile] [--no-wait-for-domain-reload] [--stop-on-exter
| `--force-recompile` | flag | - | Full recompile plus domain reload. Almost never needed: a plain compile already detects externally edited files, and the forced reload can freeze large projects and come back as `COMPILE_RESULT_UNKNOWN`. |
| `--no-wait-for-domain-reload` | flag | - | Return before Domain Reload completion |
| `--stop-on-external-scene-changes` | flag | - | Stop before compilation if open Scene files changed externally instead of auto-reloading them |
| `--compile-wait-timeout-seconds` | integer | 600 | Maximum seconds the CLI waits for the compile to finish before returning COMPILE_WAIT_TIMEOUT (default 600). Values above 1200 exceed the Unity-side result retention window (20 minutes) and weaken post-timeout recovery. |

## When to use --force-recompile

Expand Down
3 changes: 2 additions & 1 deletion .claude/skills/uloop-compile/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Execute Unity project compilation.
## Usage

```bash
uloop compile [--force-recompile] [--no-wait-for-domain-reload] [--stop-on-external-scene-changes]
uloop compile [--force-recompile] [--no-wait-for-domain-reload] [--stop-on-external-scene-changes] [--compile-wait-timeout-seconds <seconds>]
```

## Parameters
Expand All @@ -21,6 +21,7 @@ uloop compile [--force-recompile] [--no-wait-for-domain-reload] [--stop-on-exter
| `--force-recompile` | flag | - | Full recompile plus domain reload. Almost never needed: a plain compile already detects externally edited files, and the forced reload can freeze large projects and come back as `COMPILE_RESULT_UNKNOWN`. |
| `--no-wait-for-domain-reload` | flag | - | Return before Domain Reload completion |
| `--stop-on-external-scene-changes` | flag | - | Stop before compilation if open Scene files changed externally instead of auto-reloading them |
| `--compile-wait-timeout-seconds` | integer | 600 | Maximum seconds the CLI waits for the compile to finish before returning COMPILE_WAIT_TIMEOUT (default 600). Values above 1200 exceed the Unity-side result retention window (20 minutes) and weaken post-timeout recovery. |

## When to use --force-recompile

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/dead-code.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,4 @@ jobs:
--include-kept false
--format table
--fail-on high-confidence
--max-public-candidates 22
--max-public-candidates 23
7 changes: 7 additions & 0 deletions Packages/src/Editor/FirstPartyTools/Compile/CompileSchema.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@ public class CompileSchema : UnityCliLoopToolSchema
/// </summary>
public bool ReloadExternalSceneChanges { get; set; } = true;

/// <summary>
/// How long the CLI waits for compilation to complete, in seconds.
/// Unity ignores this value; it is consumed by the CLI.
/// </summary>
[Description("How long the CLI waits for compilation to complete, in seconds. Unity ignores this value; it is consumed by the CLI.")]
public int CompileWaitTimeoutSeconds { get; set; } = 600;

/// <summary>
/// Internal request identifier used for delayed result recovery across domain reload.
/// </summary>
Expand Down
3 changes: 2 additions & 1 deletion Packages/src/Editor/FirstPartyTools/Compile/Skill/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Execute Unity project compilation.
## Usage

```bash
uloop compile [--force-recompile] [--no-wait-for-domain-reload] [--stop-on-external-scene-changes]
uloop compile [--force-recompile] [--no-wait-for-domain-reload] [--stop-on-external-scene-changes] [--compile-wait-timeout-seconds <seconds>]
```

## Parameters
Expand All @@ -21,6 +21,7 @@ uloop compile [--force-recompile] [--no-wait-for-domain-reload] [--stop-on-exter
| `--force-recompile` | flag | - | Full recompile plus domain reload. Almost never needed: a plain compile already detects externally edited files, and the forced reload can freeze large projects and come back as `COMPILE_RESULT_UNKNOWN`. |
| `--no-wait-for-domain-reload` | flag | - | Return before Domain Reload completion |
| `--stop-on-external-scene-changes` | flag | - | Stop before compilation if open Scene files changed externally instead of auto-reloading them |
| `--compile-wait-timeout-seconds` | integer | 600 | Maximum seconds the CLI waits for the compile to finish before returning COMPILE_WAIT_TIMEOUT (default 600). Values above 1200 exceed the Unity-side result retention window (20 minutes) and weaken post-timeout recovery. |

## When to use --force-recompile

Expand Down
10 changes: 10 additions & 0 deletions cli/common/errors/busy_editor_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,16 @@ func unityServerBusyNextActions(data map[string]any) []string {
actions...)
}

// Why only runningToolName == "compile": attach recovery requires a local pending
// record from this client's own COMPILE_WAIT_TIMEOUT. Editor-state "unity-compile"
// busy and other clients' compiles must not promise reattach.
if rpcStringData(data, "runningToolName") == "compile" {
actions = append(
actions,
"A compile can take several minutes on large projects. Wait for it to finish, then retry. If your own `uloop compile` previously failed with COMPILE_WAIT_TIMEOUT, re-running `uloop compile` reattaches to that compile instead of starting a new one.",
)
}

if stallSeconds, ok := rpcFloatData(data, "secondsSinceLastMainThreadTick"); ok &&
stallSeconds >= unityServerBusyResponsivenessStallThresholdSeconds {
actions = append(
Expand Down
36 changes: 36 additions & 0 deletions cli/common/errors/busy_editor_state_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,42 @@ func TestUnityServerBusyNextActions_WhenCompiling_IncludesCompileGuidance(t *tes
}
}

// Verifies a busy compile tool adds reattach guidance that only applies after the
// caller's own COMPILE_WAIT_TIMEOUT (not for unrelated clients or unity-compile).
func TestUnityServerBusyNextActions_WhenRunningCompileTool_IncludesReattachGuidance(t *testing.T) {
data := map[string]any{
"runningToolName": "compile",
}

actions := unityServerBusyNextActions(data)
expected := "A compile can take several minutes on large projects. Wait for it to finish, then retry. If your own `uloop compile` previously failed with COMPILE_WAIT_TIMEOUT, re-running `uloop compile` reattaches to that compile instead of starting a new one."
found := false
for _, action := range actions {
if action == expected {
found = true
break
}
}
if !found {
t.Fatalf("compile reattach guidance missing: %#v", actions)
}
}

// Verifies editor-state unity-compile busy does not promise uloop compile reattach.
func TestUnityServerBusyNextActions_WhenRunningUnityCompile_OmitsReattachGuidance(t *testing.T) {
data := map[string]any{
"runningToolName": "unity-compile",
"isCompiling": true,
}

actions := unityServerBusyNextActions(data)
for _, action := range actions {
if action == "A compile can take several minutes on large projects. Wait for it to finish, then retry. If your own `uloop compile` previously failed with COMPILE_WAIT_TIMEOUT, re-running `uloop compile` reattaches to that compile instead of starting a new one." {
t.Fatalf("unity-compile busy must not promise reattach: %#v", actions)
}
}
}

// Verifies stalled main-thread ticks add a lightweight responsiveness check action.
func TestUnityServerBusyNextActions_WhenMainThreadStalled_IncludesResponsivenessCheck(t *testing.T) {
data := map[string]any{
Expand Down
5 changes: 5 additions & 0 deletions cli/common/tools/default-tools.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@
"type": "boolean",
"description": "Stop before compilation if open Scene files changed externally instead of auto-reloading them",
"default": true
},
"CompileWaitTimeoutSeconds": {
"type": "integer",
"description": "Maximum seconds the CLI waits for the compile to finish before returning COMPILE_WAIT_TIMEOUT (default 600). Values above 1200 exceed the Unity-side result retention window (20 minutes) and weaken post-timeout recovery.",
"default": 600
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion cli/dispatcher/shared-inputs-stamp.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"schemaVersion": 1,
"sharedInputsHash": "8735819857e8be16e1a53dadd643bf92995ea65c"
"sharedInputsHash": "050e25b77113c7d2cb24bd904463acda2e7f0087"
}
Loading
Loading